// Path: compiler/src/main/java/pl/edu/radomski/navigator/exceptions/NotAllFieldsAreAnnotatedForResultException.java
// public class NotAllFieldsAreAnnotatedForResultException extends RuntimeException {
//     public NotAllFieldsAreAnnotatedForResultException(String message) {
//         super(message);
//     }
// }
// 
// Path: compiler/src/main/java/pl/edu/radomski/navigator/navigable/NavigableAnnotatedClass.java
// public class NavigableAnnotatedClass {
// 
// 
//     public static NavigableAnnotatedClass from(TypeElement typeElement) throws VariableElementValidationException {
// 
//         Navigable annotation = typeElement.getAnnotation(Navigable.class);
// 
//         NavigableAnnotatedClass navigableAnnotatedClass = new NavigableAnnotatedClass(typeElement, annotation.group());
//         HashMap<String, List<VariableElement>> paramAnnotatedFields = new HashMap<>();
//         HashMap<String, List<VariableElement>> resultAnnotatedFields = new HashMap<>();
//         ArrayList<String> errors;
//         Param paramAnnotation;
//         Result resultAnnotation;
//         for (Element element : typeElement.getEnclosedElements()) {
//             if (!(element instanceof VariableElement)) {
//                 continue;
//             }
//             VariableElement variableElement = (VariableElement) element;
//             if (AnnotationValidator.isAnnotated(variableElement, Param.class)) {
//                 paramAnnotation = variableElement.getAnnotation(Param.class);
//                 errors = ParamAnnotatedVariableElementValidator.isValid(variableElement);
//                 if (errors.size() == 0) {
//                     CollectionUtils.addToHashMapWithList(paramAnnotatedFields, paramAnnotation.group(), variableElement);
//                 } else {
//                     throw new VariableElementValidationException(errors);
//                 }
//             }
//             if (AnnotationValidator.isAnnotated(variableElement, Result.class)) {
//                 resultAnnotation = variableElement.getAnnotation(Result.class);
//                 errors = ParamAnnotatedVariableElementValidator.isValid(variableElement);
//                 if (errors.size() == 0) {
//                     CollectionUtils.addToHashMapWithList(resultAnnotatedFields, resultAnnotation.group(), variableElement);
//                 } else {
//                     throw new VariableElementValidationException(errors);
//                 }
//             }
//         }
// 
//         navigableAnnotatedClass.paramAnnotatedFields = paramAnnotatedFields;
//         navigableAnnotatedClass.resultAnnotatedFields = resultAnnotatedFields;
//         navigableAnnotatedClass.navigableAnnotation = annotation;
// 
//         return navigableAnnotatedClass;
//     }
// 
//     private HashMap<String, List<VariableElement>> paramAnnotatedFields = new HashMap<>();
//     private HashMap<String, List<VariableElement>> resultAnnotatedFields = new HashMap<>();
//     private final String annotatedClassName;
//     private final TypeElement typeElement;
//     private final String group;
//     private Navigable navigableAnnotation;
// 
// 
//     public NavigableAnnotatedClass(TypeElement typeElement, String group) {
//         this.annotatedClassName = typeElement.getSimpleName().toString();
//         this.typeElement = typeElement;
//         this.group = group;
// 
//     }
// 
//     public HashMap<String, List<VariableElement>> getParamAnnotatedFields() {
//         return paramAnnotatedFields;
//     }
// 
//     public HashMap<String, List<VariableElement>> getResultAnnotatedFields() {
//         return resultAnnotatedFields;
//     }
// 
//     public String getAnnotatedClassName() {
//         return annotatedClassName;
//     }
// 
//     public TypeElement getTypeElement() {
//         return typeElement;
//     }
// 
//     public String getGroup() {
//         return group;
//     }
// 
//     public Navigable getNavigableAnnotation() {
//         return navigableAnnotation;
//     }
// }


import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.TypeName;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.mockito.Mock;
import org.mockito.Mockito;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import javax.annotation.processing.Filer;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.Name;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeMirror;
import pl.edu.radomski.navigator.exceptions.NotAllFieldsAreAnnotatedForResultException;
import pl.edu.radomski.navigator.navigable.NavigableAnnotatedClass;
import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
package pl.edu.radomski.navigator;







/**
 * Created by adam on 1/9/16.
 */
@RunWith(Parameterized.class)
public class NavigatorCodeGeneratorParameterizedTest {

    @Mock
    NavigableAnnotatedClass navigableAnnotatedClass;
    private NavigatorCodeGenerator navigatorCodeGenerator;

    @Parameterized.Parameters(name = "{index}: {0}, {1}, {2}")
    public static Collection<Object[]> data() {
        return Arrays.asList(new Object[][]{
                {0, new ArrayList<VariableElement>() {{
                    add(generateVariableElementMock(true, "aaaa"));
                    add(generateVariableElementMock(true, "bbbb"));
                }}, null},
                {0, new ArrayList<VariableElement>() {{
                    add(generateVariableElementMock(true, "aaaa"));
                    add(generateVariableElementMock(false, "bbbb"));
// Path: compiler/src/main/java/pl/edu/radomski/navigator/exceptions/NotAllFieldsAreAnnotatedForResultException.java
// public class NotAllFieldsAreAnnotatedForResultException extends RuntimeException {
//     public NotAllFieldsAreAnnotatedForResultException(String message) {
//         super(message);
//     }
// }
// 
// Path: compiler/src/main/java/pl/edu/radomski/navigator/navigable/NavigableAnnotatedClass.java
// public class NavigableAnnotatedClass {
// 
// 
//     public static NavigableAnnotatedClass from(TypeElement typeElement) throws VariableElementValidationException {
// 
//         Navigable annotation = typeElement.getAnnotation(Navigable.class);
// 
//         NavigableAnnotatedClass navigableAnnotatedClass = new NavigableAnnotatedClass(typeElement, annotation.group());
//         HashMap<String, List<VariableElement>> paramAnnotatedFields = new HashMap<>();
//         HashMap<String, List<VariableElement>> resultAnnotatedFields = new HashMap<>();
//         ArrayList<String> errors;
//         Param paramAnnotation;
//         Result resultAnnotation;
//         for (Element element : typeElement.getEnclosedElements()) {
//             if (!(element instanceof VariableElement)) {
//                 continue;
//             }
//             VariableElement variableElement = (VariableElement) element;
//             if (AnnotationValidator.isAnnotated(variableElement, Param.class)) {
//                 paramAnnotation = variableElement.getAnnotation(Param.class);
//                 errors = ParamAnnotatedVariableElementValidator.isValid(variableElement);
//                 if (errors.size() == 0) {
//                     CollectionUtils.addToHashMapWithList(paramAnnotatedFields, paramAnnotation.group(), variableElement);
//                 } else {
//                     throw new VariableElementValidationException(errors);
//                 }
//             }
//             if (AnnotationValidator.isAnnotated(variableElement, Result.class)) {
//                 resultAnnotation = variableElement.getAnnotation(Result.class);
//                 errors = ParamAnnotatedVariableElementValidator.isValid(variableElement);
//                 if (errors.size() == 0) {
//                     CollectionUtils.addToHashMapWithList(resultAnnotatedFields, resultAnnotation.group(), variableElement);
//                 } else {
//                     throw new VariableElementValidationException(errors);
//                 }
//             }
//         }
// 
//         navigableAnnotatedClass.paramAnnotatedFields = paramAnnotatedFields;
//         navigableAnnotatedClass.resultAnnotatedFields = resultAnnotatedFields;
//         navigableAnnotatedClass.navigableAnnotation = annotation;
// 
//         return navigableAnnotatedClass;
//     }
// 
//     private HashMap<String, List<VariableElement>> paramAnnotatedFields = new HashMap<>();
//     private HashMap<String, List<VariableElement>> resultAnnotatedFields = new HashMap<>();
//     private final String annotatedClassName;
//     private final TypeElement typeElement;
//     private final String group;
//     private Navigable navigableAnnotation;
// 
// 
//     public NavigableAnnotatedClass(TypeElement typeElement, String group) {
//         this.annotatedClassName = typeElement.getSimpleName().toString();
//         this.typeElement = typeElement;
//         this.group = group;
// 
//     }
// 
//     public HashMap<String, List<VariableElement>> getParamAnnotatedFields() {
//         return paramAnnotatedFields;
//     }
// 
//     public HashMap<String, List<VariableElement>> getResultAnnotatedFields() {
//         return resultAnnotatedFields;
//     }
// 
//     public String getAnnotatedClassName() {
//         return annotatedClassName;
//     }
// 
//     public TypeElement getTypeElement() {
//         return typeElement;
//     }
// 
//     public String getGroup() {
//         return group;
//     }
// 
//     public Navigable getNavigableAnnotation() {
//         return navigableAnnotation;
//     }
// }


// Path: compiler/src/test/java/pl/edu/radomski/navigator/NavigatorCodeGeneratorParameterizedTest.java
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.TypeName;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.mockito.Mock;
import org.mockito.Mockito;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import javax.annotation.processing.Filer;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.Name;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeMirror;
import pl.edu.radomski.navigator.exceptions.NotAllFieldsAreAnnotatedForResultException;
import pl.edu.radomski.navigator.navigable.NavigableAnnotatedClass;
import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;

package pl.edu.radomski.navigator;







/**
 * Created by adam on 1/9/16.
 */
@RunWith(Parameterized.class)
public class NavigatorCodeGeneratorParameterizedTest {

    @Mock
    NavigableAnnotatedClass navigableAnnotatedClass;
    private NavigatorCodeGenerator navigatorCodeGenerator;

    @Parameterized.Parameters(name = "{index}: {0}, {1}, {2}")
    public static Collection<Object[]> data() {
        return Arrays.asList(new Object[][]{
                {0, new ArrayList<VariableElement>() {{
                    add(generateVariableElementMock(true, "aaaa"));
                    add(generateVariableElementMock(true, "bbbb"));
                }}, null},
                {0, new ArrayList<VariableElement>() {{
                    add(generateVariableElementMock(true, "aaaa"));
                    add(generateVariableElementMock(false, "bbbb"));
                }}, NotAllFieldsAreAnnotatedForResultException.class}