// Path: static-mustache/src/main/java/com/github/sviperll/staticmustache/MustacheToken.java
// public abstract class MustacheToken {
//     public static MustacheToken beginSection(final String name) {
//         return new MustacheToken() {
//             @Override
//             public <R, E extends Exception> R accept(Visitor<R, E> visitor) throws E {
//                 return visitor.beginSection(name);
//             }
//         };
//     }
//     public static MustacheToken beginInvertedSection(final String name) {
//         return new MustacheToken() {
//             @Override
//             public <R, E extends Exception> R accept(Visitor<R, E> visitor) throws E {
//                 return visitor.beginInvertedSection(name);
//             }
//         };
//     }
//     public static MustacheToken endSection(final String name) {
//         return new MustacheToken() {
//             @Override
//             public <R, E extends Exception> R accept(Visitor<R, E> visitor) throws E {
//                 return visitor.endSection(name);
//             }
//         };
//     }
//     public static MustacheToken variable(final String name) {
//         return new MustacheToken() {
//             @Override
//             public <R, E extends Exception> R accept(Visitor<R, E> visitor) throws E {
//                 return visitor.variable(name);
//             }
//         };
//     }
//     public static MustacheToken unescapedVariable(final String name) {
//         return new MustacheToken() {
//             @Override
//             public <R, E extends Exception> R accept(Visitor<R, E> visitor) throws E {
//                 return visitor.unescapedVariable(name);
//             }
//         };
//     }
//     public static MustacheToken specialCharacter(final char c) {
//         return new MustacheToken() {
//             @Override
//             public <R, E extends Exception> R accept(Visitor<R, E> visitor) throws E {
//                 return visitor.specialCharacter(c);
//             }
//         };
//     }
//     public static MustacheToken text(final String s) {
//         return new MustacheToken() {
//             @Override
//             public <R, E extends Exception> R accept(Visitor<R, E> visitor) throws E {
//                 return visitor.text(s);
//             }
//         };
//     }
//     public static MustacheToken endOfFile() {
//         return new MustacheToken() {
//             @Override
//             public <R, E extends Exception> R accept(Visitor<R, E> visitor) throws E {
//                 return visitor.endOfFile();
//             }
//         };
//     }
// 
//     public abstract <R, E extends Exception> R accept(Visitor<R, E> visitor) throws E;
// 
//     private MustacheToken() {
//     }
//     public interface Visitor<R, E extends Exception> {
//         R beginSection(String name) throws E;
//         R beginInvertedSection(String name) throws E;
//         R endSection(String name) throws E;
//         R variable(String name) throws E;
//         R unescapedVariable(String name) throws E;
//         R specialCharacter(char c) throws E;
//         R text(String s) throws E;
//         R endOfFile() throws E;
//     }
// }
// 
// Path: static-mustache/src/main/java/com/github/sviperll/staticmustache/ProcessingException.java
// @SuppressWarnings("serial")
// public class ProcessingException extends Exception {
//     private final Position position;
// 
//     private ProcessingException(Position position, String message, Throwable cause) {
//         super(message, cause);
//         this.position = position;
//     }
// 
//     public ProcessingException(Position position, String message) {
//         this(position, message, null);
//     }
// 
//     public ProcessingException(Position position, ContextException contextException) {
//         this(position, contextException.getMessage(), contextException);
//     }
// 
//     public Position position() {
//         return position;
//     }
// }


import com.github.sviperll.staticmustache.ProcessingException;
import com.github.sviperll.staticmustache.MustacheToken;
    public Void character(char c) throws ProcessingException {
        if (Character.isWhitespace(c)) {
            boolean expectsThree = kind == MustacheTagKind.UNESCAPED_VARIABLE_THREE_BRACES;
            tokenizer.setState(new EndMustacheTokenizerState(tokenizer, expectsThree));
        } else {
            name.append(c);
        }
        return null;
    }

    @Override
    public Void endOfFile() throws ProcessingException {
        tokenizer.error("Unclosed field at the end of file");
        return null;
    }

    @Override
    public void beforeStateChange() throws ProcessingException {
        String nameString = name.toString();
        switch (kind) {
            case VARIABLE:
                tokenizer.emitToken(MustacheToken.variable(nameString));
                break;
            case UNESCAPED_VARIABLE_TWO_BRACES:
            case UNESCAPED_VARIABLE_THREE_BRACES:
                tokenizer.emitToken(MustacheToken.unescapedVariable(nameString));
                break;
            case BEGIN_SECTION:
                tokenizer.emitToken(MustacheToken.beginSection(nameString));
                break;
// Path: static-mustache/src/main/java/com/github/sviperll/staticmustache/MustacheToken.java
// public abstract class MustacheToken {
//     public static MustacheToken beginSection(final String name) {
//         return new MustacheToken() {
//             @Override
//             public <R, E extends Exception> R accept(Visitor<R, E> visitor) throws E {
//                 return visitor.beginSection(name);
//             }
//         };
//     }
//     public static MustacheToken beginInvertedSection(final String name) {
//         return new MustacheToken() {
//             @Override
//             public <R, E extends Exception> R accept(Visitor<R, E> visitor) throws E {
//                 return visitor.beginInvertedSection(name);
//             }
//         };
//     }
//     public static MustacheToken endSection(final String name) {
//         return new MustacheToken() {
//             @Override
//             public <R, E extends Exception> R accept(Visitor<R, E> visitor) throws E {
//                 return visitor.endSection(name);
//             }
//         };
//     }
//     public static MustacheToken variable(final String name) {
//         return new MustacheToken() {
//             @Override
//             public <R, E extends Exception> R accept(Visitor<R, E> visitor) throws E {
//                 return visitor.variable(name);
//             }
//         };
//     }
//     public static MustacheToken unescapedVariable(final String name) {
//         return new MustacheToken() {
//             @Override
//             public <R, E extends Exception> R accept(Visitor<R, E> visitor) throws E {
//                 return visitor.unescapedVariable(name);
//             }
//         };
//     }
//     public static MustacheToken specialCharacter(final char c) {
//         return new MustacheToken() {
//             @Override
//             public <R, E extends Exception> R accept(Visitor<R, E> visitor) throws E {
//                 return visitor.specialCharacter(c);
//             }
//         };
//     }
//     public static MustacheToken text(final String s) {
//         return new MustacheToken() {
//             @Override
//             public <R, E extends Exception> R accept(Visitor<R, E> visitor) throws E {
//                 return visitor.text(s);
//             }
//         };
//     }
//     public static MustacheToken endOfFile() {
//         return new MustacheToken() {
//             @Override
//             public <R, E extends Exception> R accept(Visitor<R, E> visitor) throws E {
//                 return visitor.endOfFile();
//             }
//         };
//     }
// 
//     public abstract <R, E extends Exception> R accept(Visitor<R, E> visitor) throws E;
// 
//     private MustacheToken() {
//     }
//     public interface Visitor<R, E extends Exception> {
//         R beginSection(String name) throws E;
//         R beginInvertedSection(String name) throws E;
//         R endSection(String name) throws E;
//         R variable(String name) throws E;
//         R unescapedVariable(String name) throws E;
//         R specialCharacter(char c) throws E;
//         R text(String s) throws E;
//         R endOfFile() throws E;
//     }
// }
// 
// Path: static-mustache/src/main/java/com/github/sviperll/staticmustache/ProcessingException.java
// @SuppressWarnings("serial")
// public class ProcessingException extends Exception {
//     private final Position position;
// 
//     private ProcessingException(Position position, String message, Throwable cause) {
//         super(message, cause);
//         this.position = position;
//     }
// 
//     public ProcessingException(Position position, String message) {
//         this(position, message, null);
//     }
// 
//     public ProcessingException(Position position, ContextException contextException) {
//         this(position, contextException.getMessage(), contextException);
//     }
// 
//     public Position position() {
//         return position;
//     }
// }


// Path: static-mustache/src/main/java/com/github/sviperll/staticmustache/token/IdentifierMustacheTokenizerState.java
import com.github.sviperll.staticmustache.ProcessingException;
import com.github.sviperll.staticmustache.MustacheToken;

    public Void character(char c) throws ProcessingException {
        if (Character.isWhitespace(c)) {
            boolean expectsThree = kind == MustacheTagKind.UNESCAPED_VARIABLE_THREE_BRACES;
            tokenizer.setState(new EndMustacheTokenizerState(tokenizer, expectsThree));
        } else {
            name.append(c);
        }
        return null;
    }

    @Override
    public Void endOfFile() throws ProcessingException {
        tokenizer.error("Unclosed field at the end of file");
        return null;
    }

    @Override
    public void beforeStateChange() throws ProcessingException {
        String nameString = name.toString();
        switch (kind) {
            case VARIABLE:
                tokenizer.emitToken(MustacheToken.variable(nameString));
                break;
            case UNESCAPED_VARIABLE_TWO_BRACES:
            case UNESCAPED_VARIABLE_THREE_BRACES:
                tokenizer.emitToken(MustacheToken.unescapedVariable(nameString));
                break;
            case BEGIN_SECTION:
                tokenizer.emitToken(MustacheToken.beginSection(nameString));
                break;
            case BEGIN_INVERTED_SECTION: