I was refactoring some old code of a simple script file parser when I came across the following code:
StringReader reader = new StringReader(scriptTextToProcess);
StringBuilder scope = new StringBuilder();
string line = reader.ReadLine();
while (line != null)
{
    switch (line[0])
    {
        case '$':
            // Process the entire "line" as a variable, 
            // i.e. add it to a collection of KeyValuePair.
            AddToVariables(line);
            break;
        case '!':
            // Depending of what comes after the '!' character, 
            // process the entire "scope" and/or the command in "line".
            if (line == "!execute")
                ExecuteScope(scope);
            else if (line.StartsWith("!custom_command"))
                RunCustomCommand(line, scope);
            else if (line == "!single_line_directive")
                ProcessDirective(line);
            scope = new StringBuilder();
            break;
        default:
            // No processing directive, i.e. add the "line" 
            // to the current scope.
            scope.Append(line);
            break;
    }
    line = reader.ReadLine();
}
This simple script processor seems to me like a good candidate for refactoring by applying the "open closed principle". The lines beginning with a $ will probably never be handled differently. But, what if new directives beginning with a ! needs to be added? Or new processing identifiers (e.g. new switch-cases) are needed?
The problem is, I could not figure out how to easily and correctly add more directives and processors without breaking OCP. The !-case using scope and/or line makes it a bit tricky, as does the default-case.
Any suggestions?