// Path: kratos-compiler/src/main/java/kratos/compiler/binding/KBooleanBinding.java
// public class KBooleanBinding implements KBindingGeneric {
// 
//     private String methodName;
//     private String[] parameterTypes;
//     private static final ClassName ONUPDATELISTENER_KBOOLEAN = ClassName.get("kratos.internal.KBoolean", "OnUpdateListener");
//     private static final ClassName VIEW = ClassName.get("android.view", "View");
// 
//     public KBooleanBinding(String methodName, String[] parameterTypes) {
//         this.methodName = methodName;
//         this.parameterTypes = parameterTypes;
//     }
// 
//     @Override
//     public String getMethodName() {
//         return methodName;
//     }
// 
//     @Override
//     public String[] getParameterTypes() {
//         return parameterTypes;
//     }
// 
//     @Override
//     public void addGenericCode(MethodSpec.Builder result, String key) {
//         TypeSpec update = TypeSpec.anonymousClassBuilder("")
//                 .addSuperinterface(ONUPDATELISTENER_KBOOLEAN)
//                 .addMethod(MethodSpec.methodBuilder("update")
//                         .addAnnotation(Override.class)
//                         .addModifiers(Modifier.PUBLIC)
//                         .addParameter(VIEW, "v")
//                         .addParameter(boolean.class, "s")
//                         .returns(void.class)
//                         .addStatement("target.$L(($L)$N, $N)", getMethodName(), getParameterTypes()[0], "v", "s")
//                         .build())
//                 .build();
//         result.addStatement("target.getData().$L.setOnUpdateListener($L)", key, update);
//     }
// }
// 
// Path: kratos-compiler/src/main/java/kratos/compiler/binding/KStringBinding.java
// public class KStringBinding implements KBindingGeneric {
// 
//     private String methodName;
//     private String[] parameterTypes;
//     private static final ClassName ONUPDATELISTENER_KSTRING = ClassName.get("kratos.internal.KString", "OnUpdateListener");
//     private static final ClassName VIEW = ClassName.get("android.view", "View");
// 
//     public KStringBinding(String methodName, String[] parameterTypes) {
//         this.methodName = methodName;
//         this.parameterTypes = parameterTypes;
//     }
// 
//     @Override
//     public void addGenericCode(MethodSpec.Builder result, String key) {
//         TypeSpec update = TypeSpec.anonymousClassBuilder("")
//                 .addSuperinterface(ONUPDATELISTENER_KSTRING)
//                 .addMethod(MethodSpec.methodBuilder("update")
//                         .addAnnotation(Override.class)
//                         .addModifiers(Modifier.PUBLIC)
//                         .addParameter(VIEW, "v")
//                         .addParameter(String.class, "s")
//                         .returns(void.class)
//                         .addStatement("target.$L(($L)$N, $N)", getMethodName(), getParameterTypes()[0], "v", "s")
//                         .build())
//                 .build();
//         result.addStatement("target.getData().$L.setOnUpdateListener($L)", key, update);
// 
//     }
// 
//     @Override
//     public String getMethodName() {
//         return methodName;
//     }
// 
//     @Override
//     public String[] getParameterTypes() {
//         return parameterTypes;
//     }
// 
// }


import com.google.auto.common.SuperficialValidation;
import com.google.auto.service.AutoService;
import com.squareup.javapoet.TypeName;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.annotation.Annotation;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Filer;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.Processor;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.type.TypeVariable;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
import kratos.Bind;
import kratos.BindLayout;
import kratos.BindText;
import kratos.Binds;
import kratos.LBindLayout;
import kratos.LBindText;
import kratos.OnKBooleanChanged;
import kratos.OnKStringChanged;
import kratos.PackageName;
import kratos.compiler.binding.KBooleanBinding;
import kratos.compiler.binding.KStringBinding;
import static javax.lang.model.SourceVersion.latestSupported;
import static javax.tools.Diagnostic.Kind.ERROR;
        return targetClassMap;
    }

    private void parseOnChangedTarget(RoundEnvironment env, Map<TypeElement, BindingClass> targetClassMap, Set<String> erasedTargetNames, Class... annotationClasses) {
        for (Class clazz : annotationClasses) {
            for (Element element : env.getElementsAnnotatedWith(clazz)) {
                if (!SuperficialValidation.validateElement(element)) continue;
                try {
                    parseOnChanged(element, targetClassMap, erasedTargetNames, clazz);
                } catch (Exception e) {
                    logParsingError(element, clazz, e);
                }
            }
        }
    }

    private void parseOnChanged(Element element, Map<TypeElement, BindingClass> targetClassMap,
                                Set<String> erasedTargetNames, Class annotationClass) {
        TypeElement enclosingElement = (TypeElement) element.getEnclosingElement();
        BindingClass bindingClass = getOrCreateTargetClass(targetClassMap, enclosingElement, false, false);
        TypeMirror mirror = element.asType();
        if (!(mirror.getKind() == TypeKind.EXECUTABLE))
            return;
        String method = element.toString().trim();
        String methodName = method.substring(0, method.indexOf("("));
        Matcher m = Pattern.compile("\\(([^)]+)\\)").matcher(method);
        if (m.find()) {
            String[] methodTypes = m.group(1).split(",");
            String key = null;
            if (annotationClass.equals(OnKStringChanged.class)) {
// Path: kratos-compiler/src/main/java/kratos/compiler/binding/KBooleanBinding.java
// public class KBooleanBinding implements KBindingGeneric {
// 
//     private String methodName;
//     private String[] parameterTypes;
//     private static final ClassName ONUPDATELISTENER_KBOOLEAN = ClassName.get("kratos.internal.KBoolean", "OnUpdateListener");
//     private static final ClassName VIEW = ClassName.get("android.view", "View");
// 
//     public KBooleanBinding(String methodName, String[] parameterTypes) {
//         this.methodName = methodName;
//         this.parameterTypes = parameterTypes;
//     }
// 
//     @Override
//     public String getMethodName() {
//         return methodName;
//     }
// 
//     @Override
//     public String[] getParameterTypes() {
//         return parameterTypes;
//     }
// 
//     @Override
//     public void addGenericCode(MethodSpec.Builder result, String key) {
//         TypeSpec update = TypeSpec.anonymousClassBuilder("")
//                 .addSuperinterface(ONUPDATELISTENER_KBOOLEAN)
//                 .addMethod(MethodSpec.methodBuilder("update")
//                         .addAnnotation(Override.class)
//                         .addModifiers(Modifier.PUBLIC)
//                         .addParameter(VIEW, "v")
//                         .addParameter(boolean.class, "s")
//                         .returns(void.class)
//                         .addStatement("target.$L(($L)$N, $N)", getMethodName(), getParameterTypes()[0], "v", "s")
//                         .build())
//                 .build();
//         result.addStatement("target.getData().$L.setOnUpdateListener($L)", key, update);
//     }
// }
// 
// Path: kratos-compiler/src/main/java/kratos/compiler/binding/KStringBinding.java
// public class KStringBinding implements KBindingGeneric {
// 
//     private String methodName;
//     private String[] parameterTypes;
//     private static final ClassName ONUPDATELISTENER_KSTRING = ClassName.get("kratos.internal.KString", "OnUpdateListener");
//     private static final ClassName VIEW = ClassName.get("android.view", "View");
// 
//     public KStringBinding(String methodName, String[] parameterTypes) {
//         this.methodName = methodName;
//         this.parameterTypes = parameterTypes;
//     }
// 
//     @Override
//     public void addGenericCode(MethodSpec.Builder result, String key) {
//         TypeSpec update = TypeSpec.anonymousClassBuilder("")
//                 .addSuperinterface(ONUPDATELISTENER_KSTRING)
//                 .addMethod(MethodSpec.methodBuilder("update")
//                         .addAnnotation(Override.class)
//                         .addModifiers(Modifier.PUBLIC)
//                         .addParameter(VIEW, "v")
//                         .addParameter(String.class, "s")
//                         .returns(void.class)
//                         .addStatement("target.$L(($L)$N, $N)", getMethodName(), getParameterTypes()[0], "v", "s")
//                         .build())
//                 .build();
//         result.addStatement("target.getData().$L.setOnUpdateListener($L)", key, update);
// 
//     }
// 
//     @Override
//     public String getMethodName() {
//         return methodName;
//     }
// 
//     @Override
//     public String[] getParameterTypes() {
//         return parameterTypes;
//     }
// 
// }


// Path: kratos-compiler/src/main/java/kratos/compiler/KratosProcessor.java
import com.google.auto.common.SuperficialValidation;
import com.google.auto.service.AutoService;
import com.squareup.javapoet.TypeName;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.annotation.Annotation;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Filer;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.Processor;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.type.TypeVariable;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
import kratos.Bind;
import kratos.BindLayout;
import kratos.BindText;
import kratos.Binds;
import kratos.LBindLayout;
import kratos.LBindText;
import kratos.OnKBooleanChanged;
import kratos.OnKStringChanged;
import kratos.PackageName;
import kratos.compiler.binding.KBooleanBinding;
import kratos.compiler.binding.KStringBinding;
import static javax.lang.model.SourceVersion.latestSupported;
import static javax.tools.Diagnostic.Kind.ERROR;

        return targetClassMap;
    }

    private void parseOnChangedTarget(RoundEnvironment env, Map<TypeElement, BindingClass> targetClassMap, Set<String> erasedTargetNames, Class... annotationClasses) {
        for (Class clazz : annotationClasses) {
            for (Element element : env.getElementsAnnotatedWith(clazz)) {
                if (!SuperficialValidation.validateElement(element)) continue;
                try {
                    parseOnChanged(element, targetClassMap, erasedTargetNames, clazz);
                } catch (Exception e) {
                    logParsingError(element, clazz, e);
                }
            }
        }
    }

    private void parseOnChanged(Element element, Map<TypeElement, BindingClass> targetClassMap,
                                Set<String> erasedTargetNames, Class annotationClass) {
        TypeElement enclosingElement = (TypeElement) element.getEnclosingElement();
        BindingClass bindingClass = getOrCreateTargetClass(targetClassMap, enclosingElement, false, false);
        TypeMirror mirror = element.asType();
        if (!(mirror.getKind() == TypeKind.EXECUTABLE))
            return;
        String method = element.toString().trim();
        String methodName = method.substring(0, method.indexOf("("));
        Matcher m = Pattern.compile("\\(([^)]+)\\)").matcher(method);
        if (m.find()) {
            String[] methodTypes = m.group(1).split(",");
            String key = null;
            if (annotationClass.equals(OnKStringChanged.class)) {
                KStringBinding binding = new KStringBinding(methodName, methodTypes);