// 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;
package com.github.webdriverextensions.internal.generator;


public class WebRepositoryBuilder implements Builder<Boolean> {

    // Input Elements
    final private ProcessingEnvironment processingEnv;
    final private Set<TypeElement> webSiteElements;
    final private Set<TypeElement> webPageElements;
    final private Set<TypeElement> webRepositoryElements;
    final private Set<TypeElement> otherElements;
    final private JCodeModel codeModel;
    // JClasses
    private JDefinedClass generatedWebRepositoryClass;

    public WebRepositoryBuilder(ProcessingEnvironment processingEnv, Set<TypeElement> webSiteElements,
            Set<TypeElement> webPageElements, Set<TypeElement> webRepositoryElements, Set<TypeElement> otherElements) {
        this.processingEnv = processingEnv;
        this.webSiteElements = webSiteElements;
        this.webPageElements = webPageElements;
        this.webRepositoryElements = webRepositoryElements;
        this.otherElements = otherElements;
        this.codeModel = new JCodeModel();
    }

    @Override
    public Boolean build() {
        try {
            createClass();
            createFields();
            generate();
            return true;
        } catch (IOException|JClassAlreadyExistsException ex) {
// 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;

package com.github.webdriverextensions.internal.generator;


public class WebRepositoryBuilder implements Builder<Boolean> {

    // Input Elements
    final private ProcessingEnvironment processingEnv;
    final private Set<TypeElement> webSiteElements;
    final private Set<TypeElement> webPageElements;
    final private Set<TypeElement> webRepositoryElements;
    final private Set<TypeElement> otherElements;
    final private JCodeModel codeModel;
    // JClasses
    private JDefinedClass generatedWebRepositoryClass;

    public WebRepositoryBuilder(ProcessingEnvironment processingEnv, Set<TypeElement> webSiteElements,
            Set<TypeElement> webPageElements, Set<TypeElement> webRepositoryElements, Set<TypeElement> otherElements) {
        this.processingEnv = processingEnv;
        this.webSiteElements = webSiteElements;
        this.webPageElements = webPageElements;
        this.webRepositoryElements = webRepositoryElements;
        this.otherElements = otherElements;
        this.codeModel = new JCodeModel();
    }

    @Override
    public Boolean build() {
        try {
            createClass();
            createFields();
            generate();
            return true;
        } catch (IOException|JClassAlreadyExistsException ex) {
            error("Failed to generate GeneratedWebRepository!", processingEnv);