// Path: src/main/java/com/github/webdriverextensions/WebRepository.java
// public abstract class WebRepository {
// 
//     public void initElements() {
//         PageFactory.initElements(new WebDriverExtensionFieldDecorator(WebDriverExtensionsContext.getDriver()), this);
//     }
// 
//     public void initElements(WebDriver driver) {
//         PageFactory.initElements(new WebDriverExtensionFieldDecorator(driver), this);
//     }
// 
//     public void initElements(FieldDecorator decorator) {
//         PageFactory.initElements(decorator, this);
//     }
// }
// 
// Path: src/main/java/com/github/webdriverextensions/internal/generator/GeneratorUtils.java
// public static void annotateFieldWithFindByAnnotation(JFieldVar field, AnnotationMirror findBy) {
//     JAnnotationUse annotation = field.annotate(FindBy.class);
//     setFindByAnnotationValues(annotation, findBy);
// }
// 
// Path: src/main/java/com/github/webdriverextensions/internal/generator/GeneratorUtils.java
// public static void annotateFieldWithFindBysAnnotation(JFieldVar field, AnnotationMirror findBys) {
//     JAnnotationUse findBysAnnotation = field.annotate(FindBys.class);
//     JAnnotationArrayMember findBysAnnotationValues = findBysAnnotation.paramArray("value");
//     for (AnnotationMirror findBy : (List<AnnotationMirror>) findBys.getElementValues().values().iterator().next().getValue() ) {
//         JAnnotationUse findByAnnotation = findBysAnnotationValues.annotate(FindBy.class);
//         setFindByAnnotationValues(findByAnnotation, findBy);
//     }
// }
// 
// Path: src/main/java/com/github/webdriverextensions/internal/generator/GeneratorUtils.java
// public static void error(String msg, ProcessingEnvironment processingEnv) {
//     processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, msg);
// }
// 
// Path: src/main/java/com/github/webdriverextensions/internal/generator/GeneratorUtils.java
// public static String getFieldName(Element element) {
//     String className = element.getSimpleName().toString();
//     return StringUtils.uncapitalize(className);
// }
// 
// Path: src/main/java/com/github/webdriverextensions/internal/generator/GeneratorUtils.java
// public static AnnotationMirror getFindByAnnotation(TypeElement element) {
//     for (AnnotationMirror annotationMirror : element.getAnnotationMirrors()) {
//         if (annotationMirror.getAnnotationType().toString().equals("org.openqa.selenium.support.FindBy")) {
//             return annotationMirror;
//         }
//     }
//     return null;
// }
// 
// Path: src/main/java/com/github/webdriverextensions/internal/generator/GeneratorUtils.java
// public static AnnotationMirror getFindBysAnnotation(TypeElement element) {
//     for (AnnotationMirror annotationMirror : element.getAnnotationMirrors()) {
//         if (annotationMirror.getAnnotationType().toString().equals("org.openqa.selenium.support.FindBys")) {
//             return annotationMirror;
//         }
//     }
//     return null;
// }
// 
// Path: src/main/java/com/github/webdriverextensions/internal/generator/GeneratorUtils.java
// public static boolean hasFindByAnnotation(TypeElement element) {
//     return getFindByAnnotation(element) != null;
// }
// 
// Path: src/main/java/com/github/webdriverextensions/internal/generator/GeneratorUtils.java
// public static boolean hasFindBysAnnotation(TypeElement element) {
//     return getFindBysAnnotation(element) != null;
// }


import com.github.webdriverextensions.WebRepository;
import static com.github.webdriverextensions.internal.generator.GeneratorUtils.annotateFieldWithFindByAnnotation;
import static com.github.webdriverextensions.internal.generator.GeneratorUtils.annotateFieldWithFindBysAnnotation;
import static com.github.webdriverextensions.internal.generator.GeneratorUtils.error;
import static com.github.webdriverextensions.internal.generator.GeneratorUtils.getFieldName;
import static com.github.webdriverextensions.internal.generator.GeneratorUtils.getFindByAnnotation;
import static com.github.webdriverextensions.internal.generator.GeneratorUtils.getFindBysAnnotation;
import static com.github.webdriverextensions.internal.generator.GeneratorUtils.hasFindByAnnotation;
import static com.github.webdriverextensions.internal.generator.GeneratorUtils.hasFindBysAnnotation;
import com.sun.codemodel.ClassType;
import com.sun.codemodel.CodeWriter;
import com.sun.codemodel.JClass;
import com.sun.codemodel.JClassAlreadyExistsException;
import com.sun.codemodel.JCodeModel;
import com.sun.codemodel.JDefinedClass;
import com.sun.codemodel.JFieldVar;
import com.sun.codemodel.JMod;
import java.io.IOException;
import java.util.Set;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.TypeElement;
import org.apache.commons.lang3.builder.Builder;
import org.apache.commons.lang3.exception.ExceptionUtils;
            createFields();
            generate();
            return true;
        } catch (IOException|JClassAlreadyExistsException ex) {
            error("Failed to generate GeneratedWebRepository!", processingEnv);
            error(ExceptionUtils.getStackTrace(ex), processingEnv);
            return false;
        }

    }

    private void createClass() throws JClassAlreadyExistsException {
        generatedWebRepositoryClass = codeModel._class(JMod.PUBLIC | JMod.ABSTRACT, "com.github.webdriverextensions.generator.GeneratedWebRepository", ClassType.CLASS);
        generatedWebRepositoryClass._extends(codeModel.ref(WebRepository.class));
    }

    private void createFields() {
        // Declare WebSites
        for (TypeElement webSiteElement : webSiteElements) {
            JClass webSiteClass = codeModel.ref(webSiteElement.getQualifiedName().toString());
            generatedWebRepositoryClass.field(JMod.PUBLIC, webSiteClass, getFieldName(webSiteElement));
        }

        // Declare WebPages
        for (TypeElement webPageElement : webPageElements) {
            JClass webPageClass = codeModel.ref(webPageElement.getQualifiedName().toString());
            generatedWebRepositoryClass.field(JMod.PUBLIC, webPageClass, getFieldName(webPageElement));
        }

        // Declare WebRepositories
// Path: src/main/java/com/github/webdriverextensions/WebRepository.java
// public abstract class WebRepository {
// 
//     public void initElements() {
//         PageFactory.initElements(new WebDriverExtensionFieldDecorator(WebDriverExtensionsContext.getDriver()), this);
//     }
// 
//     public void initElements(WebDriver driver) {
//         PageFactory.initElements(new WebDriverExtensionFieldDecorator(driver), this);
//     }
// 
//     public void initElements(FieldDecorator decorator) {
//         PageFactory.initElements(decorator, this);
//     }
// }
// 
// Path: src/main/java/com/github/webdriverextensions/internal/generator/GeneratorUtils.java
// public static void annotateFieldWithFindByAnnotation(JFieldVar field, AnnotationMirror findBy) {
//     JAnnotationUse annotation = field.annotate(FindBy.class);
//     setFindByAnnotationValues(annotation, findBy);
// }
// 
// Path: src/main/java/com/github/webdriverextensions/internal/generator/GeneratorUtils.java
// public static void annotateFieldWithFindBysAnnotation(JFieldVar field, AnnotationMirror findBys) {
//     JAnnotationUse findBysAnnotation = field.annotate(FindBys.class);
//     JAnnotationArrayMember findBysAnnotationValues = findBysAnnotation.paramArray("value");
//     for (AnnotationMirror findBy : (List<AnnotationMirror>) findBys.getElementValues().values().iterator().next().getValue() ) {
//         JAnnotationUse findByAnnotation = findBysAnnotationValues.annotate(FindBy.class);
//         setFindByAnnotationValues(findByAnnotation, findBy);
//     }
// }
// 
// Path: src/main/java/com/github/webdriverextensions/internal/generator/GeneratorUtils.java
// public static void error(String msg, ProcessingEnvironment processingEnv) {
//     processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, msg);
// }
// 
// Path: src/main/java/com/github/webdriverextensions/internal/generator/GeneratorUtils.java
// public static String getFieldName(Element element) {
//     String className = element.getSimpleName().toString();
//     return StringUtils.uncapitalize(className);
// }
// 
// Path: src/main/java/com/github/webdriverextensions/internal/generator/GeneratorUtils.java
// public static AnnotationMirror getFindByAnnotation(TypeElement element) {
//     for (AnnotationMirror annotationMirror : element.getAnnotationMirrors()) {
//         if (annotationMirror.getAnnotationType().toString().equals("org.openqa.selenium.support.FindBy")) {
//             return annotationMirror;
//         }
//     }
//     return null;
// }
// 
// Path: src/main/java/com/github/webdriverextensions/internal/generator/GeneratorUtils.java
// public static AnnotationMirror getFindBysAnnotation(TypeElement element) {
//     for (AnnotationMirror annotationMirror : element.getAnnotationMirrors()) {
//         if (annotationMirror.getAnnotationType().toString().equals("org.openqa.selenium.support.FindBys")) {
//             return annotationMirror;
//         }
//     }
//     return null;
// }
// 
// Path: src/main/java/com/github/webdriverextensions/internal/generator/GeneratorUtils.java
// public static boolean hasFindByAnnotation(TypeElement element) {
//     return getFindByAnnotation(element) != null;
// }
// 
// Path: src/main/java/com/github/webdriverextensions/internal/generator/GeneratorUtils.java
// public static boolean hasFindBysAnnotation(TypeElement element) {
//     return getFindBysAnnotation(element) != null;
// }


// Path: src/main/java/com/github/webdriverextensions/internal/generator/WebRepositoryBuilder.java
import com.github.webdriverextensions.WebRepository;
import static com.github.webdriverextensions.internal.generator.GeneratorUtils.annotateFieldWithFindByAnnotation;
import static com.github.webdriverextensions.internal.generator.GeneratorUtils.annotateFieldWithFindBysAnnotation;
import static com.github.webdriverextensions.internal.generator.GeneratorUtils.error;
import static com.github.webdriverextensions.internal.generator.GeneratorUtils.getFieldName;
import static com.github.webdriverextensions.internal.generator.GeneratorUtils.getFindByAnnotation;
import static com.github.webdriverextensions.internal.generator.GeneratorUtils.getFindBysAnnotation;
import static com.github.webdriverextensions.internal.generator.GeneratorUtils.hasFindByAnnotation;
import static com.github.webdriverextensions.internal.generator.GeneratorUtils.hasFindBysAnnotation;
import com.sun.codemodel.ClassType;
import com.sun.codemodel.CodeWriter;
import com.sun.codemodel.JClass;
import com.sun.codemodel.JClassAlreadyExistsException;
import com.sun.codemodel.JCodeModel;
import com.sun.codemodel.JDefinedClass;
import com.sun.codemodel.JFieldVar;
import com.sun.codemodel.JMod;
import java.io.IOException;
import java.util.Set;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.TypeElement;
import org.apache.commons.lang3.builder.Builder;
import org.apache.commons.lang3.exception.ExceptionUtils;

            createFields();
            generate();
            return true;
        } catch (IOException|JClassAlreadyExistsException ex) {
            error("Failed to generate GeneratedWebRepository!", processingEnv);
            error(ExceptionUtils.getStackTrace(ex), processingEnv);
            return false;
        }

    }

    private void createClass() throws JClassAlreadyExistsException {
        generatedWebRepositoryClass = codeModel._class(JMod.PUBLIC | JMod.ABSTRACT, "com.github.webdriverextensions.generator.GeneratedWebRepository", ClassType.CLASS);
        generatedWebRepositoryClass._extends(codeModel.ref(WebRepository.class));
    }

    private void createFields() {
        // Declare WebSites
        for (TypeElement webSiteElement : webSiteElements) {
            JClass webSiteClass = codeModel.ref(webSiteElement.getQualifiedName().toString());
            generatedWebRepositoryClass.field(JMod.PUBLIC, webSiteClass, getFieldName(webSiteElement));
        }

        // Declare WebPages
        for (TypeElement webPageElement : webPageElements) {
            JClass webPageClass = codeModel.ref(webPageElement.getQualifiedName().toString());
            generatedWebRepositoryClass.field(JMod.PUBLIC, webPageClass, getFieldName(webPageElement));
        }

        // Declare WebRepositories
        for (TypeElement webRepositoryElement : webRepositoryElements) {