modules: extraction of the model module
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/SourceFileInfoExtractor.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/SourceFileInfoExtractor.java
index 7125986..02e73e0 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/SourceFileInfoExtractor.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/SourceFileInfoExtractor.java
@@ -13,8 +13,9 @@
 import com.github.javaparser.ast.stmt.Statement;
 import me.tomassetti.symbolsolver.model.declarations.TypeDeclaration;
 import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsage;
+import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsageImpl;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.resolution.javaparser.JavaParserFacade;
 
 import java.io.File;
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/logic/AbstractClassDeclaration.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/logic/AbstractClassDeclaration.java
index 7bc9bdd..758ff50 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/logic/AbstractClassDeclaration.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/logic/AbstractClassDeclaration.java
@@ -3,8 +3,9 @@
 import me.tomassetti.symbolsolver.model.declarations.ClassDeclaration;
 import me.tomassetti.symbolsolver.model.declarations.InterfaceDeclaration;
 import me.tomassetti.symbolsolver.model.declarations.TypeDeclaration;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsage;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
+import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsageImpl;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -33,7 +34,7 @@
             }
         }
         TypeDeclaration objectType = typeSolver().solveType(Object.class.getCanonicalName());
-        ReferenceTypeUsage objectRef = new ReferenceTypeUsage(objectType, typeSolver());
+        ReferenceTypeUsage objectRef = new ReferenceTypeUsageImpl(objectType, typeSolver());
         superclasses.add(objectRef);
         return superclasses.stream().filter((s) -> s.getTypeDeclaration().isClass()).collect(Collectors.toList());
     }
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/logic/AbstractTypeDeclaration.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/logic/AbstractTypeDeclaration.java
index 0d5d76a..8690efb 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/logic/AbstractTypeDeclaration.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/logic/AbstractTypeDeclaration.java
@@ -2,9 +2,9 @@
 
 import me.tomassetti.symbolsolver.model.declarations.MethodDeclaration;
 import me.tomassetti.symbolsolver.model.declarations.TypeDeclaration;
+import me.tomassetti.symbolsolver.model.resolution.SymbolReference;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
-import me.tomassetti.symbolsolver.resolution.SymbolReference;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
 
 import java.util.List;
 
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/logic/MethodResolutionLogic.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/logic/MethodResolutionLogic.java
index 2e2ef8d..8e41e2c 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/logic/MethodResolutionLogic.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/logic/MethodResolutionLogic.java
@@ -3,11 +3,12 @@
 import me.tomassetti.symbolsolver.model.declarations.MethodAmbiguityException;
 import me.tomassetti.symbolsolver.model.declarations.MethodDeclaration;
 import me.tomassetti.symbolsolver.model.invokations.MethodUsage;
+import me.tomassetti.symbolsolver.model.resolution.SymbolReference;
+import me.tomassetti.symbolsolver.model.resolution.TypeParameter;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsage;
+import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsageImpl;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
-import me.tomassetti.symbolsolver.resolution.SymbolReference;
-import me.tomassetti.symbolsolver.resolution.TypeParameter;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.reflectionmodel.ReflectionClassDeclaration;
 
 import java.util.HashMap;
@@ -110,7 +111,7 @@
                 } else if (bounds.size() == 1) {
                     return bounds.get(0).getType();
                 } else {
-                    return new ReferenceTypeUsage(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver);
+                    return new ReferenceTypeUsageImpl(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver);
                 }
             }
         }
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/declarations/ClassDeclaration.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/declarations/ClassDeclaration.java
deleted file mode 100644
index f16598e..0000000
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/declarations/ClassDeclaration.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package me.tomassetti.symbolsolver.model.declarations;
-
-import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsage;
-
-import java.util.List;
-
-/**
- * Declaration of a Class (not an interface or an enum).
- */
-public interface ClassDeclaration extends TypeDeclaration, TypeParametrized {
-
-    @Override
-    default boolean isClass() {
-        return true;
-    }
-
-    /**
-     * This is a ReferenceTypeUsage because it could contain type parameters.
-     * For example: class A extends B<Integer, String>.
-     * <p/>
-     * Note that only the Object class should not have a superclass and therefore
-     * return null.
-     */
-    ReferenceTypeUsage getSuperClass();
-
-    /**
-     * Return all the interfaces implemented directly by this class.
-     * It does not include the interfaces implemented by superclasses or extended
-     * by the interfaces implemented.
-     */
-    List<InterfaceDeclaration> getInterfaces();
-
-    List<ReferenceTypeUsage> getAllSuperClasses();
-
-    List<InterfaceDeclaration> getAllInterfaces();
-
-}
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/declarations/Declaration.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/declarations/Declaration.java
deleted file mode 100644
index 507f4e2..0000000
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/declarations/Declaration.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package me.tomassetti.symbolsolver.model.declarations;
-
-/**
- * A generic declaration.
- */
-public interface Declaration {
-
-    /**
-     * Anonymous classes do not have a name, for example.
-     */
-    default boolean hasName() {
-        return true;
-    }
-
-    String getName();
-
-    default boolean isField() {
-        return false;
-    }
-
-    default boolean isParameter() {
-        return false;
-    }
-
-    default boolean isVariable() {
-        return false;
-    }
-
-    default boolean isType() {
-        return false;
-    }
-
-    default boolean isMethod() {
-        return false;
-    }
-
-    default FieldDeclaration asField() {
-        throw new UnsupportedOperationException();
-    }
-
-    default ParameterDeclaration asParameter() {
-        throw new UnsupportedOperationException();
-    }
-
-    default TypeDeclaration asType() {
-        throw new UnsupportedOperationException();
-    }
-
-    default MethodDeclaration asMethod() {
-        throw new UnsupportedOperationException();
-    }
-}
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/declarations/EnumDeclaration.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/declarations/EnumDeclaration.java
deleted file mode 100644
index d4ab0ff..0000000
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/declarations/EnumDeclaration.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package me.tomassetti.symbolsolver.model.declarations;
-
-/**
- * @author Federico Tomassetti
- */
-public interface EnumDeclaration extends TypeDeclaration {
-
-    @Override
-    default boolean isEnum() {
-        return true;
-    }
-}
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/declarations/FieldDeclaration.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/declarations/FieldDeclaration.java
deleted file mode 100644
index 8f3a638..0000000
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/declarations/FieldDeclaration.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package me.tomassetti.symbolsolver.model.declarations;
-
-import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
-
-/**
- * @author Federico Tomassetti
- */
-public interface FieldDeclaration extends ValueDeclaration {
-
-    @Override
-    default boolean isField() {
-        return true;
-    }
-
-    @Override
-    default FieldDeclaration asField() {
-        return this;
-    }
-
-    default FieldDeclaration replaceType(TypeUsage fieldType) {
-        throw new UnsupportedOperationException();
-    }
-}
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/declarations/InterfaceDeclaration.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/declarations/InterfaceDeclaration.java
deleted file mode 100644
index 158b659..0000000
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/declarations/InterfaceDeclaration.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package me.tomassetti.symbolsolver.model.declarations;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * An interface declaration.
- */
-public interface InterfaceDeclaration extends TypeDeclaration, TypeParametrized {
-
-    @Override
-    default boolean isInterface() {
-        return true;
-    }
-
-    List<InterfaceDeclaration> getInterfacesExtended();
-
-    default List<InterfaceDeclaration> getAllInterfacesExtended() {
-        List<InterfaceDeclaration> interfaces = new ArrayList<>();
-        for (InterfaceDeclaration interfaceDeclaration : getInterfacesExtended()) {
-            interfaces.add(interfaceDeclaration);
-            interfaces.addAll(interfaceDeclaration.getAllInterfacesExtended());
-        }
-        return interfaces;
-    }
-}
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/declarations/MethodAmbiguityException.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/declarations/MethodAmbiguityException.java
deleted file mode 100644
index 3d8d9ab..0000000
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/declarations/MethodAmbiguityException.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package me.tomassetti.symbolsolver.model.declarations;
-
-/**
- * It is not possible to decide how to resolve a method invocation.
- *
- * @author Federico Tomassetti
- */
-public class MethodAmbiguityException extends RuntimeException {
-
-    public MethodAmbiguityException(String description) {
-        super(description);
-    }
-
-}
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/declarations/MethodDeclaration.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/declarations/MethodDeclaration.java
deleted file mode 100644
index 419d921..0000000
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/declarations/MethodDeclaration.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package me.tomassetti.symbolsolver.model.declarations;
-
-import me.tomassetti.symbolsolver.model.invokations.MethodUsage;
-import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
-import me.tomassetti.symbolsolver.resolution.Context;
-
-import java.util.List;
-
-/**
- * A declaration of a method (either in an interface, a class or an enum).
- */
-public interface MethodDeclaration extends Declaration, TypeParametrized {
-
-    /**
-     * The type in which the method is declared.
-     *
-     * @return
-     */
-    TypeDeclaration declaringType();
-
-    TypeUsage getReturnType();
-
-    int getNoParams();
-
-    ParameterDeclaration getParam(int i);
-
-    /**
-     * Create the MethodUsage corresponding to this declaration with all generic types solved in the given
-     * context.
-     */
-    @Deprecated
-    MethodUsage resolveTypeVariables(Context context, List<TypeUsage> parameterTypes);
-
-    @Deprecated
-    Context getContext();
-}
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/declarations/ParameterDeclaration.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/declarations/ParameterDeclaration.java
deleted file mode 100644
index c69b170..0000000
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/declarations/ParameterDeclaration.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package me.tomassetti.symbolsolver.model.declarations;
-
-/**
- * @author Federico Tomassetti
- */
-public interface ParameterDeclaration extends ValueDeclaration {
-
-    @Override
-    default boolean isParameter() {
-        return true;
-    }
-
-}
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/declarations/TypeDeclaration.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/declarations/TypeDeclaration.java
deleted file mode 100644
index 9f769cf..0000000
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/declarations/TypeDeclaration.java
+++ /dev/null
@@ -1,101 +0,0 @@
-package me.tomassetti.symbolsolver.model.declarations;
-
-import me.tomassetti.symbolsolver.model.invokations.MethodUsage;
-import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsage;
-import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
-import me.tomassetti.symbolsolver.resolution.Context;
-import me.tomassetti.symbolsolver.resolution.SymbolReference;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
-
-import java.util.List;
-import java.util.Optional;
-
-/**
- * A declaration of a type. It could be a primitive type, an enum, a class, an interface or a type variable.
- * It cannot be an annotation or an array.
- *
- * @author Federico Tomassetti
- */
-public interface TypeDeclaration extends Declaration, TypeParametrized {
-    String getQualifiedName();
-
-    @Deprecated
-    Context getContext();
-
-    SymbolReference<MethodDeclaration> solveMethod(String name, List<TypeUsage> parameterTypes);
-
-    @Deprecated
-    default Optional<MethodUsage> solveMethodAsUsage(String name, List<TypeUsage> parameterTypes, TypeSolver typeSolver, Context invokationContext, List<TypeUsage> typeParameterValues) {
-        return getContext().solveMethodAsUsage(name, parameterTypes, typeSolver);
-    }
-
-    boolean isAssignableBy(TypeUsage typeUsage);
-
-    default boolean canBeAssignedTo(TypeDeclaration other) {
-        return other.isAssignableBy(this);
-    }
-
-    /**
-     * Note that the type of the field should be expressed using the type variables of this particular type.
-     * Consider for example:
-     *
-     * class Foo<E> { E field; }
-     *
-     * class Bar extends Foo<String> { }
-     *
-     * When calling getField("field") on Foo I should get a FieldDeclaration with type E, while calling it on
-     * Bar I should get a FieldDeclaration with type String.
-     */
-    FieldDeclaration getField(String name);
-
-    boolean hasField(String name);
-
-    boolean isAssignableBy(TypeDeclaration other);
-
-    SymbolReference<? extends ValueDeclaration> solveSymbol(String substring, TypeSolver typeSolver);
-
-    /**
-     * Try to solve a symbol just in the declaration, it does not delegate to the container.
-     *
-     * @param substring
-     * @param typeSolver
-     * @return
-     */
-    SymbolReference<TypeDeclaration> solveType(String substring, TypeSolver typeSolver);
-
-    List<ReferenceTypeUsage> getAllAncestors();
-
-    default boolean isClass() {
-        return false;
-    }
-
-    default boolean isInterface() {
-        return false;
-    }
-
-    default boolean isEnum() {
-        return false;
-    }
-
-    default boolean isTypeVariable() {
-        return false;
-    }
-
-    @Override
-    default boolean isType() {
-        return true;
-    }
-
-    @Override
-    default TypeDeclaration asType() {
-        return this;
-    }
-
-    default ClassDeclaration asClass() {
-        throw new UnsupportedOperationException(this.getClass().getCanonicalName());
-    }
-
-    default InterfaceDeclaration asInterface() {
-        throw new UnsupportedOperationException(this.getClass().getCanonicalName());
-    }
-}
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/declarations/TypeParametrized.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/declarations/TypeParametrized.java
deleted file mode 100644
index b77c187..0000000
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/declarations/TypeParametrized.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package me.tomassetti.symbolsolver.model.declarations;
-
-import me.tomassetti.symbolsolver.resolution.TypeParameter;
-
-import java.util.List;
-
-/**
- * @author Federico Tomassetti
- */
-public interface TypeParametrized {
-
-    public List<TypeParameter> getTypeParameters();
-
-}
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/declarations/ValueDeclaration.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/declarations/ValueDeclaration.java
deleted file mode 100644
index 29ffc1c..0000000
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/declarations/ValueDeclaration.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package me.tomassetti.symbolsolver.model.declarations;
-
-import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
-
-/**
- * @author Federico Tomassetti
- */
-public interface ValueDeclaration extends Declaration {
-
-    TypeUsage getType();
-
-}
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/invokations/MethodUsage.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/invokations/MethodUsage.java
deleted file mode 100644
index a629243..0000000
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/invokations/MethodUsage.java
+++ /dev/null
@@ -1,111 +0,0 @@
-package me.tomassetti.symbolsolver.model.invokations;
-
-import me.tomassetti.symbolsolver.model.declarations.MethodDeclaration;
-import me.tomassetti.symbolsolver.model.declarations.TypeDeclaration;
-import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
-
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-
-public class MethodUsage {
-    private MethodDeclaration declaration;
-    private List<TypeUsage> paramTypes = new ArrayList<>();
-    private TypeUsage returnType;
-
-    public MethodUsage(MethodDeclaration declaration, TypeSolver typeSolver) {
-        this.declaration = declaration;
-        for (int i = 0; i < declaration.getNoParams(); i++) {
-            paramTypes.add(declaration.getParam(i).getType());
-        }
-        returnType = declaration.getReturnType();
-    }
-
-    public MethodUsage(MethodDeclaration declaration, List<TypeUsage> paramTypes, TypeUsage returnType) {
-        this.declaration = declaration;
-        this.paramTypes = paramTypes;
-        this.returnType = returnType;
-    }
-
-    private static TypeUsage replaceNameParam(String name, TypeUsage newValue, TypeUsage typeToBeExamined) {
-        if (typeToBeExamined.isTypeVariable()) {
-            if (typeToBeExamined.describe().equals(name)) {
-                return newValue;
-            } else {
-                return typeToBeExamined;
-            }
-        }
-        int i = 0;
-
-        return typeToBeExamined;
-    }
-
-    @Override
-    public String toString() {
-        return "MethodUsage{" +
-                "declaration=" + declaration +
-                ", paramTypes=" + paramTypes +
-                '}';
-    }
-
-    public MethodDeclaration getDeclaration() {
-        return declaration;
-    }
-
-    public String getName() {
-        return declaration.getName();
-    }
-
-    public TypeDeclaration declaringType() {
-        return declaration.declaringType();
-    }
-
-    public TypeUsage returnType() {
-        return returnType;
-    }
-
-    public List<TypeUsage> getParamTypes() {
-        return paramTypes;
-    }
-
-    public MethodUsage replaceParamType(int i, TypeUsage replaced) {
-        if (paramTypes.get(i) == replaced) {
-            return this;
-        }
-        List<TypeUsage> newParams = new LinkedList<>(paramTypes);
-        newParams.set(i, replaced);
-        return new MethodUsage(declaration, newParams, returnType);
-    }
-
-    public MethodUsage replaceReturnType(TypeUsage returnType) {
-        if (returnType == this.returnType) {
-            return this;
-        } else {
-            return new MethodUsage(declaration, paramTypes, returnType);
-        }
-    }
-
-    public int getNoParams() {
-        return paramTypes.size();
-    }
-
-    public TypeUsage getParamType(int i, TypeSolver typeSolver) {
-        //TypeUsage typeUsage = declaration.getParam(i).getType(typeSolver);
-        //return typeUsage;
-        return paramTypes.get(i);
-    }
-
-    public MethodUsage replaceNameParam(String name, TypeUsage typeUsage) {
-        // TODO if the method declaration has a type param with that name ignore this call
-        MethodUsage res = this;
-        for (int i = 0; i < paramTypes.size(); i++) {
-            TypeUsage originalParamType = paramTypes.get(i);
-            TypeUsage newParamType = originalParamType.replaceParam(name, typeUsage);
-            //TypeUsage newParamType = replaceNameParam(name, typeUsage, originalParamType);
-            res = res.replaceParamType(i, newParamType);
-        }
-        res = res.replaceReturnType(replaceNameParam(name, typeUsage, res.returnType));
-        return res;
-    }
-}
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/typesystem/ArrayTypeUsage.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/typesystem/ArrayTypeUsage.java
deleted file mode 100644
index cdf71e4..0000000
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/typesystem/ArrayTypeUsage.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package me.tomassetti.symbolsolver.model.typesystem;
-
-public class ArrayTypeUsage implements TypeUsage {
-
-    private TypeUsage baseType;
-
-    public ArrayTypeUsage(TypeUsage baseType) {
-        this.baseType = baseType;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-
-        ArrayTypeUsage that = (ArrayTypeUsage) o;
-
-        if (!baseType.equals(that.baseType)) return false;
-
-        return true;
-    }
-
-    @Override
-    public String toString() {
-        return "ArrayTypeUsage{" +
-                "baseType=" + baseType +
-                '}';
-    }
-
-    @Override
-    public ArrayTypeUsage asArrayTypeUsage() {
-        return this;
-    }
-
-    @Override
-    public int hashCode() {
-        return baseType.hashCode();
-    }
-
-    @Override
-    public boolean isArray() {
-        return true;
-    }
-
-    @Override
-    public String describe() {
-        return baseType.describe() + "[]";
-    }
-
-    public TypeUsage getComponentType() {
-        return baseType;
-    }
-
-    @Override
-    public TypeUsage replaceParam(String name, TypeUsage replaced) {
-        TypeUsage baseTypeReplaced = baseType.replaceParam(name, replaced);
-        if (baseTypeReplaced == baseType) {
-            return this;
-        } else {
-            return new ArrayTypeUsage(baseTypeReplaced);
-        }
-    }
-
-    @Override
-    public boolean isAssignableBy(TypeUsage other) {
-        if (other instanceof ArrayTypeUsage) {
-            return baseType.equals(((ArrayTypeUsage) other).getComponentType());
-        } else {
-            return false;
-        }
-    }
-
-}
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/typesystem/NullTypeUsage.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/typesystem/NullTypeUsage.java
deleted file mode 100644
index c9fb631..0000000
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/typesystem/NullTypeUsage.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package me.tomassetti.symbolsolver.model.typesystem;
-
-/**
- * This is a virtual type used to represent null values.
- */
-public class NullTypeUsage implements TypeUsage {
-
-    public static final NullTypeUsage INSTANCE = new NullTypeUsage();
-
-    private NullTypeUsage() {
-
-    }
-
-    @Override
-    public boolean isArray() {
-        return false;
-    }
-
-    @Override
-    public boolean isPrimitive() {
-        return false;
-    }
-
-    public boolean isNull() {
-        return true;
-    }
-
-    @Override
-    public boolean isReferenceType() {
-        return false;
-    }
-
-    @Override
-    public String describe() {
-        return "null";
-    }
-
-    @Override
-    public boolean isTypeVariable() {
-        return false;
-    }
-
-    @Override
-    public boolean isAssignableBy(TypeUsage other) {
-        throw new UnsupportedOperationException("It does not make sense to assign a value to null, it can only be assigned");
-    }
-}
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/typesystem/PrimitiveTypeUsage.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/typesystem/PrimitiveTypeUsage.java
deleted file mode 100644
index d97e09f..0000000
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/typesystem/PrimitiveTypeUsage.java
+++ /dev/null
@@ -1,93 +0,0 @@
-package me.tomassetti.symbolsolver.model.typesystem;
-
-import com.google.common.collect.ImmutableList;
-
-import java.util.List;
-
-public class PrimitiveTypeUsage implements TypeUsage {
-
-    public static final PrimitiveTypeUsage BYTE = new PrimitiveTypeUsage("byte", Byte.class.getCanonicalName(), ImmutableList.of());
-    public static final PrimitiveTypeUsage SHORT = new PrimitiveTypeUsage("short", Short.class.getCanonicalName(), ImmutableList.of(BYTE));
-    public static final PrimitiveTypeUsage INT = new PrimitiveTypeUsage("int", Integer.class.getCanonicalName(), ImmutableList.of(BYTE, SHORT));
-    public static final PrimitiveTypeUsage LONG = new PrimitiveTypeUsage("long", Long.class.getCanonicalName(), ImmutableList.of(BYTE, SHORT, INT));
-    public static final PrimitiveTypeUsage CHAR = new PrimitiveTypeUsage("char", Character.class.getCanonicalName(), ImmutableList.of());
-    public static final PrimitiveTypeUsage BOOLEAN = new PrimitiveTypeUsage("boolean", Boolean.class.getCanonicalName(), ImmutableList.of());
-    public static final PrimitiveTypeUsage FLOAT = new PrimitiveTypeUsage("float", Float.class.getCanonicalName(), ImmutableList.of());
-    public static final PrimitiveTypeUsage DOUBLE = new PrimitiveTypeUsage("double", Double.class.getCanonicalName(), ImmutableList.of(FLOAT));
-    public static final List<PrimitiveTypeUsage> ALL = ImmutableList.of(INT, BOOLEAN, LONG, CHAR, FLOAT, DOUBLE, SHORT, BYTE);
-    private String name;
-    private String boxTypeQName;
-    private List<PrimitiveTypeUsage> promotionTypes;
-
-    private PrimitiveTypeUsage(String name, String boxTypeQName, List<PrimitiveTypeUsage> promotionTypes) {
-        this.name = name;
-        this.boxTypeQName = boxTypeQName;
-        this.promotionTypes = promotionTypes;
-    }
-
-    public static TypeUsage byName(String name) {
-        name = name.toLowerCase();
-        for (PrimitiveTypeUsage ptu : ALL) {
-            if (ptu.describe().equals(name)) {
-                return ptu;
-            }
-        }
-        throw new IllegalArgumentException("Name " + name);
-    }
-
-    @Override
-    public String toString() {
-        return "PrimitiveTypeUsage{" +
-                "name='" + name + '\'' +
-                '}';
-    }
-
-    public PrimitiveTypeUsage asPrimitive() {
-        return this;
-    }
-
-    @Override
-    public boolean isArray() {
-        return false;
-    }
-
-    @Override
-    public boolean isPrimitive() {
-        return true;
-    }
-
-    @Override
-    public boolean isReferenceType() {
-        return false;
-    }
-
-    @Override
-    public String describe() {
-        return name;
-    }
-
-    @Override
-    public boolean isTypeVariable() {
-        return false;
-    }
-
-    @Override
-    public boolean isAssignableBy(TypeUsage other) {
-        if (other.isPrimitive()) {
-            return this == other || promotionTypes.contains(other);
-        } else if (other.isReferenceType()) {
-            if (other.asReferenceTypeUsage().getQualifiedName().equals(boxTypeQName)) {
-                return true;
-            }
-            for (PrimitiveTypeUsage promotion : promotionTypes) {
-                if (other.asReferenceTypeUsage().getQualifiedName().equals(promotion.boxTypeQName)) {
-                    return true;
-                }
-            }
-            return false;
-        } else {
-            return false;
-        }
-    }
-
-}
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/typesystem/ReferenceTypeUsage.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/typesystem/ReferenceTypeUsage.java
deleted file mode 100644
index 35c53b6..0000000
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/typesystem/ReferenceTypeUsage.java
+++ /dev/null
@@ -1,368 +0,0 @@
-package me.tomassetti.symbolsolver.model.typesystem;
-
-import me.tomassetti.symbolsolver.model.declarations.MethodDeclaration;
-import me.tomassetti.symbolsolver.model.declarations.TypeDeclaration;
-import me.tomassetti.symbolsolver.resolution.SymbolReference;
-import me.tomassetti.symbolsolver.resolution.TypeParameter;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
-import me.tomassetti.symbolsolver.resolution.javaparser.LambdaArgumentTypeUsagePlaceholder;
-import me.tomassetti.symbolsolver.resolution.javaparser.declarations.JavaParserTypeVariableDeclaration;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-import java.util.function.Function;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
-
-// TODO Remove references to typeSolver: it is needed to instantiate other instances of ReferenceTypeUsage
-//      and to get the Object type declaration
-public class ReferenceTypeUsage implements TypeUsage {
-
-    private TypeDeclaration typeDeclaration;
-    private List<TypeUsage> typeParameters;
-    private TypeSolver typeSolver;
-
-    public ReferenceTypeUsage(TypeDeclaration typeDeclaration, TypeSolver typeSolver) {
-        this(typeDeclaration, deriveParams(typeDeclaration), typeSolver);
-        if (this.typeDeclaration.isTypeVariable()) {
-            throw new IllegalArgumentException();
-        }
-        this.typeSolver = typeSolver;
-    }
-
-    public ReferenceTypeUsage(TypeDeclaration typeDeclaration, List<TypeUsage> typeParameters, TypeSolver typeSolver) {
-        this.typeDeclaration = typeDeclaration;
-        this.typeParameters = typeParameters;
-        if (this.typeDeclaration.isTypeVariable()) {
-            throw new IllegalArgumentException();
-        }
-        this.typeSolver = typeSolver;
-    }
-
-    private static List<TypeUsage> deriveParams(TypeDeclaration typeDeclaration) {
-        return typeDeclaration.getTypeParameters().stream().map((tp) -> new TypeParameterUsage(tp)).collect(Collectors.toList());
-    }
-
-    public ReferenceTypeUsage asReferenceTypeUsage() {
-        return this;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-
-        ReferenceTypeUsage that = (ReferenceTypeUsage) o;
-
-        if (!typeDeclaration.equals(that.typeDeclaration)) return false;
-        if (!typeParameters.equals(that.typeParameters)) return false;
-
-        return true;
-    }
-
-    @Override
-    public int hashCode() {
-        int result = typeDeclaration.hashCode();
-        result = 31 * result + typeParameters.hashCode();
-        return result;
-    }
-
-    public final TypeDeclaration getTypeDeclaration() {
-        return typeDeclaration;
-    }
-
-    @Override
-    public final boolean isArray() {
-        return false;
-    }
-
-    @Override
-    public final boolean isPrimitive() {
-        return false;
-    }
-
-    @Override
-    public final boolean isReferenceType() {
-        return true;
-    }
-
-    @Override
-    public String toString() {
-        return "ReferenceTypeUsage{" +
-                "declaration=" + typeDeclaration +
-                ", typeParameters=" + typeParameters +
-                '}';
-    }
-
-    private Optional<TypeUsage> typeParamByName(String name) {
-        List<TypeUsage> typeParameters = this.typeParameters;
-        TypeDeclaration objectType = typeSolver.solveType(Object.class.getCanonicalName());
-        ReferenceTypeUsage objectRef = new ReferenceTypeUsage(objectType, typeSolver);
-        if (typeDeclaration.getTypeParameters().size() != typeParameters.size()) {
-            if (typeParameters.size() > 0) {
-                throw new UnsupportedOperationException();
-            }
-            // type parameters not specified, default to Object
-            typeParameters = new ArrayList<>();
-            for (int i = 0; i < typeDeclaration.getTypeParameters().size(); i++) {
-                typeParameters.add(objectRef);
-            }
-        }
-        int i = 0;
-        for (TypeParameter tp : typeDeclaration.getTypeParameters()) {
-            if (tp.getName().equals(name)) {
-                return Optional.of(typeParameters.get(i));
-            }
-            i++;
-        }
-        return Optional.empty();
-    }
-
-    /**
-     * The type of the field could be different from the one in the corresponding FieldDeclaration because
-     * type variables would be solved.
-     */
-    public Optional<TypeUsage> getFieldType(String name) {
-        if (!typeDeclaration.hasField(name)) {
-            return Optional.empty();
-        }
-        TypeUsage typeUsage = typeDeclaration.getField(name).getType();
-        typeUsage = replaceTypeParams(typeUsage);
-        return Optional.of(typeUsage);
-    }
-
-    /**
-     * Get the type associated with the type parameter with the given name.
-     * It returns Optional.empty unless the type declaration declares a type parameter with the given name.
-     */
-    public Optional<TypeUsage> getGenericParameterByName(String name) {
-        int i = 0;
-        for (TypeParameter tp : typeDeclaration.getTypeParameters()) {
-            if (tp.getName().equals(name)) {
-                return Optional.of(this.typeParameters.get(i));
-            }
-            i++;
-        }
-        return Optional.empty();
-    }
-
-    /**
-     * Create a copy of the value with the type parameter changed.
-     */
-    @Deprecated
-    public TypeUsage replaceParam(int i, TypeUsage replaced) {
-        ArrayList<TypeUsage> typeParametersCorrected = new ArrayList<>(typeParameters);
-        typeParametersCorrected.set(i, replaced);
-        return new ReferenceTypeUsage(typeDeclaration, typeParametersCorrected, typeSolver);
-    }
-
-    @Override
-    public TypeUsage replaceParam(String name, TypeUsage replaced) {
-        List<TypeUsage> newParams = typeParameters.stream().map((tp) -> tp.replaceParam(name, replaced)).collect(Collectors.toList());
-        if (typeParameters.equals(newParams)) {
-            return this;
-        } else {
-            return new ReferenceTypeUsage(typeDeclaration, newParams, typeSolver);
-        }
-    }
-
-    /**
-     * Return all ancestors, that means all superclasses and interfaces.
-     * This list should always include Object (unless this is a reference to Object).
-     * The type parameters should be expressed in terms of this type parameters.
-     *
-     * For example, given:
-     *
-     * class Foo<A, B> {}
-     * class Bar<C> extends Foo<C, String> {}
-     *
-     * a call to getAllAncestors on a reference to Bar having type parameter Boolean should include
-     * Foo<Boolean, String>.
-     */
-    public List<ReferenceTypeUsage> getAllAncestors() {
-        List<ReferenceTypeUsage> ancestors = typeDeclaration.getAllAncestors();
-
-        TypeDeclaration objectType = typeSolver.solveType(Object.class.getCanonicalName());
-        ReferenceTypeUsage objectRef = new ReferenceTypeUsage(objectType, typeSolver);
-
-        ancestors = ancestors.stream().map((a) -> replaceTypeParams(a).asReferenceTypeUsage()).collect(Collectors.toList());
-        // TODO replace type parameters
-
-        for (int i = 0; i < ancestors.size(); i++) {
-            if (ancestors.get(i).getQualifiedName().equals(Object.class.getCanonicalName())) {
-                ancestors.remove(i);
-                i--;
-            }
-        }
-        ancestors.add(objectRef);
-        return ancestors;
-    }
-
-    public TypeUsage replaceTypeParams(TypeUsage typeUsage) {
-        if (typeUsage.isTypeVariable()) {
-            TypeParameter typeParameter = typeUsage.asTypeParameter();
-            if (typeParameter.declaredOnClass()) {
-                Optional<TypeUsage> typeParam = typeParamByName(typeParameter.getName());
-                if (typeParam.isPresent()) {
-                    typeUsage = typeParam.get();
-                }
-            }
-        }
-
-        if (typeUsage.isReferenceType()) {
-            for (int i = 0; i < typeUsage.asReferenceTypeUsage().parameters().size(); i++) {
-                TypeUsage replaced = replaceTypeParams(typeUsage.asReferenceTypeUsage().parameters().get(i));
-                // Identity comparison on purpose
-                if (replaced != typeUsage.asReferenceTypeUsage().parameters().get(i)) {
-                    typeUsage = typeUsage.asReferenceTypeUsage().replaceParam(i, replaced);
-                }
-            }
-        }
-
-        return typeUsage;
-    }
-
-    @Override
-    public String describe() {
-        StringBuffer sb = new StringBuffer();
-        if (hasName()) {
-            sb.append(typeDeclaration.getQualifiedName());
-        } else {
-            sb.append("<anonymous class>");
-        }
-        if (parameters().size() > 0) {
-            sb.append("<");
-            boolean first = true;
-            for (TypeUsage param : parameters()) {
-                if (first) {
-                    first = false;
-                } else {
-                    sb.append(", ");
-                }
-                sb.append(param.describe());
-            }
-            sb.append(">");
-        }
-        return sb.toString();
-    }
-
-    public SymbolReference<MethodDeclaration> solveMethod(String name, List<TypeUsage> parameterTypes) {
-        return typeDeclaration.solveMethod(name, parameterTypes);
-    }
-
-    public List<TypeUsage> parameters() {
-        return typeParameters;
-    }
-
-    @Override
-    public TypeParameter asTypeParameter() {
-        if (this.typeDeclaration instanceof JavaParserTypeVariableDeclaration) {
-            JavaParserTypeVariableDeclaration javaParserTypeVariableDeclaration = (JavaParserTypeVariableDeclaration) this.typeDeclaration;
-            return javaParserTypeVariableDeclaration.asTypeParameter();
-        }
-        throw new UnsupportedOperationException(this.typeDeclaration.getClass().getCanonicalName());
-    }
-
-    @Override
-    public boolean isTypeVariable() {
-        return typeDeclaration.isTypeVariable();
-    }
-
-    @Override
-    public boolean isAssignableBy(TypeUsage other) {
-        if (other instanceof NullTypeUsage) {
-            return !this.isPrimitive();
-        }
-        // consider boxing
-        if (other.isPrimitive()) {
-            if (this.getQualifiedName().equals(Object.class.getCanonicalName())) {
-                return true;
-            } else {
-                return isCorrespondingBoxingType(other.describe());
-            }
-        }
-        if (other instanceof LambdaArgumentTypeUsagePlaceholder) {
-            return this.getQualifiedName().equals(Predicate.class.getCanonicalName()) || this.getQualifiedName().equals(Function.class.getCanonicalName());
-        } else if (other instanceof ReferenceTypeUsage) {
-            ReferenceTypeUsage otherRef = (ReferenceTypeUsage) other;
-            if (compareConsideringTypeParameters(otherRef)) {
-                return true;
-            }
-            for (ReferenceTypeUsage otherAncestor : otherRef.getAllAncestors()) {
-                if (compareConsideringTypeParameters(otherAncestor)) {
-                    return true;
-                }
-            }
-            return false;
-        } else if (other.isTypeVariable()) {
-            // TODO look bounds...
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    public boolean hasName() {
-        return typeDeclaration.hasName();
-    }
-
-    private boolean compareConsideringTypeParameters(ReferenceTypeUsage other) {
-        if (other.equals(this)) {
-            return true;
-        }
-        if (this.getQualifiedName().equals(other.getQualifiedName())) {
-            if (this.parameters().size() != other.parameters().size()) {
-                throw new IllegalStateException();
-            }
-            for (int i = 0; i < parameters().size(); i++) {
-                TypeUsage thisParam = parameters().get(i);
-                TypeUsage otherParam = other.parameters().get(i);
-                if (!thisParam.equals(otherParam)) {
-                    if (thisParam instanceof WildcardUsage) {
-                        WildcardUsage thisParamAsWildcard = (WildcardUsage) thisParam;
-                        if (thisParamAsWildcard.isSuper() && thisParamAsWildcard.getBoundedType().equals(otherParam)) {
-                            // ok
-                        } else if (thisParamAsWildcard.isExtends() && thisParamAsWildcard.getBoundedType().isAssignableBy(otherParam)) {
-                            // ok
-                        } else {
-                            return false;
-                        }
-                    } else {
-                        return false;
-                    }
-                }
-            }
-            return true;
-        }
-        return false;
-    }
-
-    private boolean isCorrespondingBoxingType(String typeName) {
-        switch (typeName) {
-            case "boolean":
-                return getQualifiedName().equals(Boolean.class.getCanonicalName());
-            case "char":
-                return getQualifiedName().equals(Character.class.getCanonicalName());
-            case "byte":
-                return getQualifiedName().equals(Byte.class.getCanonicalName());
-            case "short":
-                return getQualifiedName().equals(Short.class.getCanonicalName());
-            case "int":
-                return getQualifiedName().equals(Integer.class.getCanonicalName());
-            case "long":
-                return getQualifiedName().equals(Long.class.getCanonicalName());
-            case "float":
-                return getQualifiedName().equals(Float.class.getCanonicalName());
-            case "double":
-                return getQualifiedName().equals(Double.class.getCanonicalName());
-            default:
-                throw new UnsupportedOperationException(typeName);
-        }
-    }
-
-    public String getQualifiedName() {
-        return typeDeclaration.getQualifiedName();
-    }
-
-}
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/typesystem/ReferenceTypeUsageImpl.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/typesystem/ReferenceTypeUsageImpl.java
new file mode 100644
index 0000000..ffcdc2b
--- /dev/null
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/typesystem/ReferenceTypeUsageImpl.java
@@ -0,0 +1,79 @@
+package me.tomassetti.symbolsolver.model.typesystem;
+
+import me.tomassetti.symbolsolver.model.declarations.TypeDeclaration;
+import me.tomassetti.symbolsolver.model.resolution.TypeParameter;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
+import me.tomassetti.symbolsolver.resolution.javaparser.LambdaArgumentTypeUsagePlaceholder;
+import me.tomassetti.symbolsolver.resolution.javaparser.declarations.JavaParserTypeVariableDeclaration;
+
+import java.util.List;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+// TODO Remove references to typeSolver: it is needed to instantiate other instances of ReferenceTypeUsage
+//      and to get the Object type declaration
+public class ReferenceTypeUsageImpl extends ReferenceTypeUsage {
+
+    @Override
+    protected ReferenceTypeUsage create(TypeDeclaration typeDeclaration, List<TypeUsage> typeParametersCorrected, TypeSolver typeSolver) {
+        return new ReferenceTypeUsageImpl(typeDeclaration, typeParametersCorrected, typeSolver);
+    }
+
+    @Override
+    protected ReferenceTypeUsage create(TypeDeclaration typeDeclaration, TypeSolver typeSolver) {
+        return new ReferenceTypeUsageImpl(typeDeclaration, typeSolver);
+    }
+
+    public ReferenceTypeUsageImpl(TypeDeclaration typeDeclaration, TypeSolver typeSolver) {
+        super(typeDeclaration, typeSolver);
+    }
+
+    public ReferenceTypeUsageImpl(TypeDeclaration typeDeclaration, List<TypeUsage> typeParameters, TypeSolver typeSolver) {
+        super(typeDeclaration, typeParameters, typeSolver);
+    }
+
+    @Override
+    public TypeParameter asTypeParameter() {
+        if (this.typeDeclaration instanceof JavaParserTypeVariableDeclaration) {
+            JavaParserTypeVariableDeclaration javaParserTypeVariableDeclaration = (JavaParserTypeVariableDeclaration) this.typeDeclaration;
+            return javaParserTypeVariableDeclaration.asTypeParameter();
+        }
+        throw new UnsupportedOperationException(this.typeDeclaration.getClass().getCanonicalName());
+    }
+
+    @Override
+    public boolean isAssignableBy(TypeUsage other) {
+        if (other instanceof NullTypeUsage) {
+            return !this.isPrimitive();
+        }
+        // consider boxing
+        if (other.isPrimitive()) {
+            if (this.getQualifiedName().equals(Object.class.getCanonicalName())) {
+                return true;
+            } else {
+                return isCorrespondingBoxingType(other.describe());
+            }
+        }
+        if (other instanceof LambdaArgumentTypeUsagePlaceholder) {
+            return this.getQualifiedName().equals(Predicate.class.getCanonicalName()) || this.getQualifiedName().equals(Function.class.getCanonicalName());
+        } else if (other instanceof ReferenceTypeUsageImpl) {
+            ReferenceTypeUsageImpl otherRef = (ReferenceTypeUsageImpl) other;
+            if (compareConsideringTypeParameters(otherRef)) {
+                return true;
+            }
+            for (ReferenceTypeUsage otherAncestor : otherRef.getAllAncestors()) {
+                if (compareConsideringTypeParameters(otherAncestor)) {
+                    return true;
+                }
+            }
+            return false;
+        } else if (other.isTypeVariable()) {
+            // TODO look bounds...
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+
+}
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/typesystem/TypeParameterUsage.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/typesystem/TypeParameterUsage.java
deleted file mode 100644
index d1408fe..0000000
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/typesystem/TypeParameterUsage.java
+++ /dev/null
@@ -1,85 +0,0 @@
-package me.tomassetti.symbolsolver.model.typesystem;
-
-import me.tomassetti.symbolsolver.resolution.TypeParameter;
-
-public class TypeParameterUsage implements TypeUsage {
-
-    private TypeParameter typeParameter;
-
-    public TypeParameterUsage(TypeParameter typeParameter) {
-        this.typeParameter = typeParameter;
-    }
-
-    @Override
-    public String toString() {
-        return "TypeUsageOfTypeParameter{" +
-                "typeParameter=" + typeParameter +
-                '}';
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-
-        TypeParameterUsage that = (TypeParameterUsage) o;
-
-        if (!typeParameter.getName().equals(that.typeParameter.getName())) return false;
-
-        return true;
-    }
-
-    @Override
-    public int hashCode() {
-        return typeParameter.hashCode();
-    }
-
-    @Override
-    public boolean isArray() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean isPrimitive() {
-        return false;
-    }
-
-    @Override
-    public TypeUsage replaceParam(String name, TypeUsage replaced) {
-        if (name.equals(typeParameter.getName())) {
-            return replaced;
-        } else {
-            return this;
-        }
-    }
-
-    @Override
-    public boolean isReferenceType() {
-        return false;
-    }
-
-    @Override
-    public String describe() {
-        return typeParameter.getName();
-    }
-
-    @Override
-    public TypeParameter asTypeParameter() {
-        return typeParameter;
-    }
-
-    @Override
-    public boolean isTypeVariable() {
-        return true;
-    }
-
-    @Override
-    public boolean isAssignableBy(TypeUsage other) {
-        if (other.isTypeVariable()) {
-            return describe().equals(other.describe());
-        } else {
-            return false;
-        }
-    }
-
-}
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/typesystem/TypeUsage.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/typesystem/TypeUsage.java
deleted file mode 100644
index 819911b..0000000
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/typesystem/TypeUsage.java
+++ /dev/null
@@ -1,111 +0,0 @@
-package me.tomassetti.symbolsolver.model.typesystem;
-
-import me.tomassetti.symbolsolver.resolution.TypeParameter;
-
-/**
- * A usage of a type. It could be a primitive type or a reference type (enum, class, interface).
- * In the later case it could take type parameters (other TypeUsages). It could also be a TypeVariable, like in:
- * <p/>
- * class A<B> { }
- * <p/>
- * where B is a TypeVariable. It could also be Wildcard Type, possibly with constraints.
- */
-public interface TypeUsage {
-
-    ///
-    /// Relation with other types
-    ///
-
-    /**
-     * Does this type represent an array?
-     */
-    default boolean isArray() {
-        return false;
-    }
-
-    /**
-     * Is this a primitive type?
-     */
-    default boolean isPrimitive() {
-        return false;
-    }
-
-    /**
-     * Is this the null type?
-     */
-    default boolean isNull() {
-        return false;
-    }
-
-    /**
-     * Is this a non primitive value?
-     */
-    default boolean isReference() {
-        return isReferenceType() || isArray() || isTypeVariable() || isNull();
-    }
-
-    /**
-     * Can this be seen as a ReferenceTypeUsage?
-     * In other words: is this a reference to a class, an interface or an enum?
-     */
-    default boolean isReferenceType() {
-        return false;
-    }
-
-    default boolean isVoid() {
-        return false;
-    }
-
-    default boolean isTypeVariable() {
-        return false;
-    }
-
-    default boolean isWildcard() {
-        return false;
-    }
-
-    ///
-    /// Downcasting
-    ///
-
-    default ArrayTypeUsage asArrayTypeUsage() {
-        throw new UnsupportedOperationException(this.getClass().getCanonicalName());
-    }
-
-    default ReferenceTypeUsage asReferenceTypeUsage() {
-        throw new UnsupportedOperationException(this.getClass().getCanonicalName());
-    }
-
-    default TypeParameter asTypeParameter() {
-        throw new UnsupportedOperationException(this.getClass().getCanonicalName());
-    }
-
-    default PrimitiveTypeUsage asPrimitive() {
-        throw new UnsupportedOperationException(this.getClass().getCanonicalName());
-    }
-
-    default WildcardUsage asWildcard() {
-        throw new UnsupportedOperationException(this.getClass().getCanonicalName());
-    }
-
-    ///
-    /// Naming
-    ///
-
-    String describe();
-
-    ///
-    /// TypeParameters
-    ///
-
-    default TypeUsage replaceParam(String name, TypeUsage replaced) {
-        return this;
-    }
-
-    ///
-    /// Relation with other types
-    ///
-
-    boolean isAssignableBy(TypeUsage other);
-
-}
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/typesystem/VoidTypeUsage.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/typesystem/VoidTypeUsage.java
deleted file mode 100644
index 36df640..0000000
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/typesystem/VoidTypeUsage.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package me.tomassetti.symbolsolver.model.typesystem;
-
-public class VoidTypeUsage implements TypeUsage {
-    public static final TypeUsage INSTANCE = new VoidTypeUsage();
-
-    private VoidTypeUsage() {
-    }
-
-    @Override
-    public String describe() {
-        return "void";
-    }
-
-    @Override
-    public boolean isAssignableBy(TypeUsage other) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean isVoid() {
-        return true;
-    }
-}
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/typesystem/WildcardUsage.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/typesystem/WildcardUsage.java
deleted file mode 100644
index 40c7051..0000000
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/model/typesystem/WildcardUsage.java
+++ /dev/null
@@ -1,120 +0,0 @@
-package me.tomassetti.symbolsolver.model.typesystem;
-
-/**
- * A wildcard can be:
- * - unbounded (?)
- * - have a lower bound (? super Number)
- * - have an upper bound (? extends Number)
- * It is not possible to have both a lower and an upper bound at the same time.
- */
-public class WildcardUsage implements TypeUsage {
-
-    public static WildcardUsage UNBOUNDED = new WildcardUsage(null, null);
-    private BoundType type;
-    private TypeUsage boundedType;
-
-    private WildcardUsage(BoundType type, TypeUsage boundedType) {
-        this.type = type;
-        this.boundedType = boundedType;
-    }
-
-    @Override
-    public String toString() {
-        return "WildcardUsage{" +
-                "type=" + type +
-                ", boundedType=" + boundedType +
-                '}';
-    }
-
-    public static WildcardUsage superBound(TypeUsage typeUsage) {
-        return new WildcardUsage(BoundType.SUPER, typeUsage);
-    }
-
-    public static WildcardUsage extendsBound(TypeUsage typeUsage) {
-        return new WildcardUsage(BoundType.EXTENDS, typeUsage);
-    }
-
-    public boolean isWildcard() {
-        return true;
-    }
-
-    public WildcardUsage asWildcard() {
-        return this;
-    }
-
-    @Override
-    public boolean isReference() {
-        return true;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (!(o instanceof WildcardUsage)) return false;
-
-        WildcardUsage that = (WildcardUsage) o;
-
-        if (boundedType != null ? !boundedType.equals(that.boundedType) : that.boundedType != null) return false;
-        if (type != that.type) return false;
-
-        return true;
-    }
-
-    @Override
-    public int hashCode() {
-        int result = type != null ? type.hashCode() : 0;
-        result = 31 * result + (boundedType != null ? boundedType.hashCode() : 0);
-        return result;
-    }
-
-    @Override
-    public String describe() {
-        if (type == null) {
-            return "?";
-        } else if (type == BoundType.SUPER) {
-            return "? super " + boundedType.describe();
-        } else if (type == BoundType.EXTENDS) {
-            return "? extends " + boundedType.describe();
-        } else {
-            throw new UnsupportedOperationException();
-        }
-    }
-
-    public boolean isSuper() {
-        return type == BoundType.SUPER;
-    }
-
-    public boolean isExtends() {
-        return type == BoundType.EXTENDS;
-    }
-
-    public TypeUsage getBoundedType() {
-        if (boundedType == null) {
-            throw new IllegalStateException();
-        }
-        return boundedType;
-    }
-
-    @Override
-    public boolean isAssignableBy(TypeUsage other) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public TypeUsage replaceParam(String name, TypeUsage replaced) {
-        if (boundedType == null) {
-            return this;
-        }
-        TypeUsage boundedTypeReplaced = boundedType.replaceParam(name, replaced);
-        if (boundedTypeReplaced != boundedType) {
-            return new WildcardUsage(type, boundedTypeReplaced);
-        } else {
-            return this;
-        }
-    }
-
-    public enum BoundType {
-        SUPER,
-        EXTENDS
-    }
-}
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/reflectionmodel/ClassOrInterfaceDeclarationContext.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/reflectionmodel/ClassOrInterfaceDeclarationContext.java
index 901a7a7..0dd866f 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/reflectionmodel/ClassOrInterfaceDeclarationContext.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/reflectionmodel/ClassOrInterfaceDeclarationContext.java
@@ -3,10 +3,10 @@
 import me.tomassetti.symbolsolver.model.declarations.MethodDeclaration;
 import me.tomassetti.symbolsolver.model.declarations.TypeDeclaration;
 import me.tomassetti.symbolsolver.model.declarations.ValueDeclaration;
+import me.tomassetti.symbolsolver.model.resolution.Context;
+import me.tomassetti.symbolsolver.model.resolution.SymbolReference;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
-import me.tomassetti.symbolsolver.resolution.Context;
-import me.tomassetti.symbolsolver.resolution.SymbolReference;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
 
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/reflectionmodel/ReflectionClassDeclaration.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/reflectionmodel/ReflectionClassDeclaration.java
index d48ce73..0b1fc2a 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/reflectionmodel/ReflectionClassDeclaration.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/reflectionmodel/ReflectionClassDeclaration.java
@@ -5,13 +5,14 @@
 import me.tomassetti.symbolsolver.logic.MethodResolutionLogic;
 import me.tomassetti.symbolsolver.model.declarations.*;
 import me.tomassetti.symbolsolver.model.invokations.MethodUsage;
+import me.tomassetti.symbolsolver.model.resolution.Context;
+import me.tomassetti.symbolsolver.model.resolution.SymbolReference;
+import me.tomassetti.symbolsolver.model.resolution.TypeParameter;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.model.typesystem.NullTypeUsage;
 import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsage;
+import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsageImpl;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
-import me.tomassetti.symbolsolver.resolution.Context;
-import me.tomassetti.symbolsolver.resolution.SymbolReference;
-import me.tomassetti.symbolsolver.resolution.TypeParameter;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.resolution.javaparser.LambdaArgumentTypeUsagePlaceholder;
 import me.tomassetti.symbolsolver.resolution.javaparser.UnsolvedSymbolException;
 
@@ -52,11 +53,11 @@
     public List<ReferenceTypeUsage> getAllAncestors() {
         List<ReferenceTypeUsage> ancestors = new LinkedList<>();
         if (getSuperClass() != null) {
-            ReferenceTypeUsage superClass = getSuperClass();
+            ReferenceTypeUsageImpl superClass = getSuperClass();
             ancestors.add(superClass);
             ancestors.addAll(getSuperClass().getAllAncestors());
         }
-        ancestors.addAll(getAllInterfaces().stream().map((i) -> new ReferenceTypeUsage(i, typeSolver)).collect(Collectors.<ReferenceTypeUsage>toList()));
+        ancestors.addAll(getAllInterfaces().stream().map((i) -> new ReferenceTypeUsageImpl(i, typeSolver)).collect(Collectors.<ReferenceTypeUsageImpl>toList()));
         for (int i = 0; i < ancestors.size(); i++) {
             ReferenceTypeUsage ancestor = ancestors.get(i);
             if (ancestor.hasName() && ancestor.getQualifiedName().equals(Object.class.getCanonicalName())) {
@@ -64,7 +65,7 @@
                 i--;
             }
         }
-        ReferenceTypeUsage object = new ReferenceTypeUsage(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver);
+        ReferenceTypeUsageImpl object = new ReferenceTypeUsageImpl(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver);
         ancestors.add(object);
         return ancestors;
     }
@@ -129,7 +130,7 @@
 
     public TypeUsage getUsage(Node node) {
 
-        return new ReferenceTypeUsage(this, typeSolver);
+        return new ReferenceTypeUsageImpl(this, typeSolver);
     }
 
     @Override
@@ -204,8 +205,8 @@
         if (typeUsage.describe().equals(getQualifiedName())) {
             return true;
         }
-        if (typeUsage instanceof ReferenceTypeUsage) {
-            ReferenceTypeUsage otherTypeDeclaration = (ReferenceTypeUsage) typeUsage;
+        if (typeUsage instanceof ReferenceTypeUsageImpl) {
+            ReferenceTypeUsageImpl otherTypeDeclaration = (ReferenceTypeUsageImpl) typeUsage;
             return otherTypeDeclaration.getTypeDeclaration().canBeAssignedTo(this);
         }
 
@@ -277,7 +278,7 @@
                 return true;
             }
         }
-        ReferenceTypeUsage superclass = getSuperClass();
+        ReferenceTypeUsageImpl superclass = getSuperClass();
         if (superclass == null) {
             return false;
         } else {
@@ -287,7 +288,7 @@
 
     @Override
     public boolean isAssignableBy(TypeDeclaration other) {
-        return isAssignableBy(new ReferenceTypeUsage(other, typeSolver));
+        return isAssignableBy(new ReferenceTypeUsageImpl(other, typeSolver));
     }
 
     @Override
@@ -321,7 +322,7 @@
     }
 
     @Override
-    public ReferenceTypeUsage getSuperClass() {
+    public ReferenceTypeUsageImpl getSuperClass() {
         if (clazz.getGenericSuperclass() == null) {
             return null;
         }
@@ -331,9 +332,9 @@
             List<TypeUsage> typeParameters = Arrays.stream(parameterizedType.getActualTypeArguments())
                     .map((t) -> ReflectionFactory.typeUsageFor(t, typeSolver))
                     .collect(Collectors.toList());
-            return new ReferenceTypeUsage(new ReflectionClassDeclaration(clazz.getSuperclass(), typeSolver), typeParameters, typeSolver);
+            return new ReferenceTypeUsageImpl(new ReflectionClassDeclaration(clazz.getSuperclass(), typeSolver), typeParameters, typeSolver);
         }
-        return new ReferenceTypeUsage(new ReflectionClassDeclaration(clazz.getSuperclass(), typeSolver), typeSolver);
+        return new ReferenceTypeUsageImpl(new ReflectionClassDeclaration(clazz.getSuperclass(), typeSolver), typeSolver);
     }
 
     @Override
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/reflectionmodel/ReflectionFactory.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/reflectionmodel/ReflectionFactory.java
index 962f778..cff1c79 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/reflectionmodel/ReflectionFactory.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/reflectionmodel/ReflectionFactory.java
@@ -1,13 +1,10 @@
 package me.tomassetti.symbolsolver.reflectionmodel;
 
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.model.typesystem.*;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
 
 import java.lang.reflect.*;
 
-/**
- * Created by federico on 02/08/15.
- */
 public class ReflectionFactory {
     public static TypeUsage typeUsageFor(Class<?> clazz, TypeSolver typeSolver) {
         if (clazz.isArray()) {
@@ -19,9 +16,9 @@
                 return PrimitiveTypeUsage.byName(clazz.getName());
             }
         } else if (clazz.isInterface()) {
-            return new ReferenceTypeUsage(new ReflectionInterfaceDeclaration(clazz, typeSolver), typeSolver);
+            return new ReferenceTypeUsageImpl(new ReflectionInterfaceDeclaration(clazz, typeSolver), typeSolver);
         } else {
-            return new ReferenceTypeUsage(new ReflectionClassDeclaration(clazz, typeSolver), typeSolver);
+            return new ReferenceTypeUsageImpl(new ReflectionClassDeclaration(clazz, typeSolver), typeSolver);
         }
     }
 
@@ -29,7 +26,7 @@
         if (type instanceof TypeVariable) {
             TypeVariable tv = (TypeVariable) type;
             // TODO the false value is arbitrary...
-            me.tomassetti.symbolsolver.resolution.TypeParameter typeParameter = new ReflectionTypeParameter(tv, true);
+            me.tomassetti.symbolsolver.model.resolution.TypeParameter typeParameter = new ReflectionTypeParameter(tv, true);
             return new TypeParameterUsage(typeParameter);
         } else if (type instanceof ParameterizedType) {
             ParameterizedType pt = (ParameterizedType) type;
@@ -51,9 +48,9 @@
             } else if (c.isArray()) {
                 return new ArrayTypeUsage(typeUsageFor(c.getComponentType(), typeSolver));
             } else if (c.isInterface()) {
-                return new ReferenceTypeUsage(new ReflectionInterfaceDeclaration(c, typeSolver), typeSolver);
+                return new ReferenceTypeUsageImpl(new ReflectionInterfaceDeclaration(c, typeSolver), typeSolver);
             } else {
-                return new ReferenceTypeUsage(new ReflectionClassDeclaration(c, typeSolver), typeSolver);
+                return new ReferenceTypeUsageImpl(new ReflectionClassDeclaration(c, typeSolver), typeSolver);
             }
         } else if (type instanceof GenericArrayType) {
             GenericArrayType genericArrayType = (GenericArrayType) type;
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/reflectionmodel/ReflectionFieldDeclaration.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/reflectionmodel/ReflectionFieldDeclaration.java
index d670fc6..b9221d6 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/reflectionmodel/ReflectionFieldDeclaration.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/reflectionmodel/ReflectionFieldDeclaration.java
@@ -1,8 +1,8 @@
 package me.tomassetti.symbolsolver.reflectionmodel;
 
 import me.tomassetti.symbolsolver.model.declarations.FieldDeclaration;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
 
 import java.lang.reflect.Field;
 
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/reflectionmodel/ReflectionInterfaceDeclaration.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/reflectionmodel/ReflectionInterfaceDeclaration.java
index df30b06..5b157c4 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/reflectionmodel/ReflectionInterfaceDeclaration.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/reflectionmodel/ReflectionInterfaceDeclaration.java
@@ -5,13 +5,14 @@
 import me.tomassetti.symbolsolver.logic.MethodResolutionLogic;
 import me.tomassetti.symbolsolver.model.declarations.*;
 import me.tomassetti.symbolsolver.model.invokations.MethodUsage;
+import me.tomassetti.symbolsolver.model.resolution.Context;
+import me.tomassetti.symbolsolver.model.resolution.SymbolReference;
+import me.tomassetti.symbolsolver.model.resolution.TypeParameter;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.model.typesystem.NullTypeUsage;
 import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsage;
+import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsageImpl;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
-import me.tomassetti.symbolsolver.resolution.Context;
-import me.tomassetti.symbolsolver.resolution.SymbolReference;
-import me.tomassetti.symbolsolver.resolution.TypeParameter;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.resolution.javaparser.LambdaArgumentTypeUsagePlaceholder;
 import me.tomassetti.symbolsolver.resolution.javaparser.UnsolvedSymbolException;
 
@@ -42,7 +43,7 @@
 
     @Override
     public boolean isAssignableBy(TypeDeclaration other) {
-        return isAssignableBy(new ReferenceTypeUsage(other, typeSolver));
+        return isAssignableBy(new ReferenceTypeUsageImpl(other, typeSolver));
     }
 
     @Override
@@ -74,7 +75,7 @@
     }
 
     public TypeUsage getUsage(Node node) {
-        return new ReferenceTypeUsage(this, typeSolver);
+        return new ReferenceTypeUsageImpl(this, typeSolver);
     }
 
     @Override
@@ -109,7 +110,7 @@
                 // Parameters not specified, so default to Object
                 typeParameterValues = new ArrayList<>();
                 for (int i = 0; i < getTypeParameters().size(); i++) {
-                    typeParameterValues.add(new ReferenceTypeUsage(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver));
+                    typeParameterValues.add(new ReferenceTypeUsageImpl(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver));
                 }
             }
         }
@@ -184,8 +185,8 @@
         if (typeUsage.describe().equals(getQualifiedName())) {
             return true;
         }
-        if (typeUsage instanceof ReferenceTypeUsage) {
-            ReferenceTypeUsage otherTypeDeclaration = (ReferenceTypeUsage) typeUsage;
+        if (typeUsage instanceof ReferenceTypeUsageImpl) {
+            ReferenceTypeUsageImpl otherTypeDeclaration = (ReferenceTypeUsageImpl) typeUsage;
             return otherTypeDeclaration.getTypeDeclaration().canBeAssignedTo(this);
         }
 
@@ -249,12 +250,12 @@
     public List<ReferenceTypeUsage> getAllAncestors() {
         List<ReferenceTypeUsage> ancestors = new LinkedList<>();
         if (clazz.getSuperclass() != null) {
-            ReferenceTypeUsage superclass = new ReferenceTypeUsage(new ReflectionInterfaceDeclaration(clazz.getSuperclass(), typeSolver), typeSolver);
+            ReferenceTypeUsageImpl superclass = new ReferenceTypeUsageImpl(new ReflectionInterfaceDeclaration(clazz.getSuperclass(), typeSolver), typeSolver);
             ancestors.add(superclass);
             ancestors.addAll(superclass.getAllAncestors());
         }
         for (Class<?> interfaze : clazz.getInterfaces()) {
-            ReferenceTypeUsage interfazeDecl = new ReferenceTypeUsage(new ReflectionInterfaceDeclaration(interfaze, typeSolver), typeSolver);
+            ReferenceTypeUsageImpl interfazeDecl = new ReferenceTypeUsageImpl(new ReflectionInterfaceDeclaration(interfaze, typeSolver), typeSolver);
             ancestors.add(interfazeDecl);
             ancestors.addAll(interfazeDecl.getAllAncestors());
         }
@@ -264,7 +265,7 @@
                 i--;
             }
         }
-        ReferenceTypeUsage object = new ReferenceTypeUsage(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver);
+        ReferenceTypeUsageImpl object = new ReferenceTypeUsageImpl(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver);
         ancestors.add(object);
         return ancestors;
     }
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/reflectionmodel/ReflectionMethodDeclaration.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/reflectionmodel/ReflectionMethodDeclaration.java
index 1833f3d..e82bdf6 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/reflectionmodel/ReflectionMethodDeclaration.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/reflectionmodel/ReflectionMethodDeclaration.java
@@ -5,19 +5,16 @@
 import me.tomassetti.symbolsolver.model.declarations.ParameterDeclaration;
 import me.tomassetti.symbolsolver.model.declarations.TypeDeclaration;
 import me.tomassetti.symbolsolver.model.invokations.MethodUsage;
+import me.tomassetti.symbolsolver.model.resolution.Context;
+import me.tomassetti.symbolsolver.model.resolution.TypeParameter;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
-import me.tomassetti.symbolsolver.resolution.Context;
-import me.tomassetti.symbolsolver.resolution.TypeParameter;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
 
 import java.lang.reflect.Method;
 import java.util.Arrays;
 import java.util.List;
 import java.util.stream.Collectors;
 
-/**
- * Created by federico on 02/08/15.
- */
 public class ReflectionMethodDeclaration implements MethodDeclaration {
 
     private Method method;
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/reflectionmodel/ReflectionParameterDeclaration.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/reflectionmodel/ReflectionParameterDeclaration.java
index 4ccdf82..fbc0cc0 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/reflectionmodel/ReflectionParameterDeclaration.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/reflectionmodel/ReflectionParameterDeclaration.java
@@ -1,8 +1,8 @@
 package me.tomassetti.symbolsolver.reflectionmodel;
 
 import me.tomassetti.symbolsolver.model.declarations.ParameterDeclaration;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
 
 import java.lang.reflect.Type;
 
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/reflectionmodel/ReflectionTypeParameter.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/reflectionmodel/ReflectionTypeParameter.java
index 0dfa2d3..c3a30e8 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/reflectionmodel/ReflectionTypeParameter.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/reflectionmodel/ReflectionTypeParameter.java
@@ -1,8 +1,7 @@
 package me.tomassetti.symbolsolver.reflectionmodel;
 
-
-import me.tomassetti.symbolsolver.resolution.TypeParameter;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
+import me.tomassetti.symbolsolver.model.resolution.TypeParameter;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 
 import java.lang.reflect.TypeVariable;
 import java.util.Arrays;
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/Context.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/Context.java
deleted file mode 100644
index afb8b8b..0000000
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/Context.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package me.tomassetti.symbolsolver.resolution;
-
-import me.tomassetti.symbolsolver.model.declarations.MethodDeclaration;
-import me.tomassetti.symbolsolver.model.declarations.TypeDeclaration;
-import me.tomassetti.symbolsolver.model.declarations.ValueDeclaration;
-import me.tomassetti.symbolsolver.model.invokations.MethodUsage;
-import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
-
-import java.util.List;
-import java.util.Optional;
-
-/**
- * Context is very similar to scope.
- * In the context we look for solving symbols.
- */
-public interface Context {
-
-    public Context getParent();
-
-    /* Type resolution */
-
-    default Optional<TypeUsage> solveGenericType(String name, TypeSolver typeSolver) {
-        return Optional.empty();
-    }
-
-    default SymbolReference<TypeDeclaration> solveType(String name, TypeSolver typeSolver) {
-        Context parent = getParent();
-        if (parent == null) {
-            return SymbolReference.unsolved(TypeDeclaration.class);
-        } else {
-            return getParent().solveType(name, typeSolver);
-        }
-    }
-
-    /* Symbol resolution */
-
-    public SymbolReference<? extends ValueDeclaration> solveSymbol(String name, TypeSolver typeSolver);
-
-    default Optional<Value> solveSymbolAsValue(String name, TypeSolver typeSolver) {
-        SymbolReference<? extends ValueDeclaration> ref = solveSymbol(name, typeSolver);
-        if (ref.isSolved()) {
-            Value value = Value.from(ref.getCorrespondingDeclaration(), typeSolver);
-            return Optional.of(value);
-        } else {
-            return Optional.empty();
-        }
-    }
-
-    /* Methods resolution */
-
-    /**
-     * We find the method declaration which is the best match for the given name and list of parameters.
-     */
-    public SymbolReference<MethodDeclaration> solveMethod(String name, List<TypeUsage> parameterTypes, TypeSolver typeSolver);
-
-    /**
-     * Similar to solveMethod but we return a MethodUsage. A MethodUsage corresponds to a MethodDeclaration plus the
-     * resolved type variables.
-     */
-    public default Optional<MethodUsage> solveMethodAsUsage(String name, List<TypeUsage> parameterTypes, TypeSolver typeSolver) {
-        SymbolReference<MethodDeclaration> methodSolved = solveMethod(name, parameterTypes, typeSolver);
-        if (methodSolved.isSolved()) {
-            MethodDeclaration methodDeclaration = methodSolved.getCorrespondingDeclaration();
-            return Optional.of(methodDeclaration.resolveTypeVariables(this, parameterTypes));
-        } else {
-            return Optional.empty();
-        }
-    }
-}
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/SymbolReference.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/SymbolReference.java
deleted file mode 100644
index a63b98c..0000000
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/SymbolReference.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package me.tomassetti.symbolsolver.resolution;
-
-import me.tomassetti.symbolsolver.model.declarations.Declaration;
-import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Optional;
-
-/**
- * Created by federico on 28/07/15.
- */
-public class SymbolReference<S extends Declaration> {
-
-    private Optional<? extends S> correspondingDeclaration;
-    private Map<String, TypeUsage> typeParametersByName = new HashMap<>();
-
-    private SymbolReference(Optional<? extends S> correspondingDeclaration) {
-        this.correspondingDeclaration = correspondingDeclaration;
-    }
-
-    public static <S extends Declaration, S2 extends S> SymbolReference<S> solved(S2 symbolDeclaration) {
-        return new SymbolReference(Optional.of(symbolDeclaration));
-    }
-
-    public static <S extends Declaration, S2 extends S> SymbolReference<S> unsolved(Class<S2> clazz) {
-        return new SymbolReference(Optional.<S>empty());
-    }
-
-    @Override
-    public String toString() {
-        return "SymbolReference{" +
-                "correspondingDeclaration=" + correspondingDeclaration +
-                '}';
-    }
-
-    public S getCorrespondingDeclaration() {
-        if (!isSolved()) {
-            throw new IllegalStateException();
-        }
-        return correspondingDeclaration.get();
-    }
-
-    public boolean isSolved() {
-        return correspondingDeclaration.isPresent();
-    }
-}
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/SymbolSolver.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/SymbolSolver.java
index 2003f8a..ab6ce53 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/SymbolSolver.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/SymbolSolver.java
@@ -8,7 +8,11 @@
 import me.tomassetti.symbolsolver.model.declarations.TypeDeclaration;
 import me.tomassetti.symbolsolver.model.declarations.ValueDeclaration;
 import me.tomassetti.symbolsolver.model.invokations.MethodUsage;
-import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsage;
+import me.tomassetti.symbolsolver.model.resolution.Context;
+import me.tomassetti.symbolsolver.model.resolution.SymbolReference;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
+import me.tomassetti.symbolsolver.model.resolution.Value;
+import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsageImpl;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
 import me.tomassetti.symbolsolver.resolution.javaparser.JavaParserFactory;
 import me.tomassetti.symbolsolver.resolution.javaparser.UnsolvedSymbolException;
@@ -16,9 +20,6 @@
 import java.util.List;
 import java.util.Optional;
 
-/**
- * Created by federico on 28/07/15.
- */
 public class SymbolSolver {
 
     private TypeSolver typeSolver;
@@ -105,7 +106,7 @@
             return genericType.get();
         }
         TypeDeclaration typeDeclaration = typeSolver.solveType(name);
-        ReferenceTypeUsage typeUsage = new ReferenceTypeUsage(typeDeclaration, typeSolver);
+        ReferenceTypeUsageImpl typeUsage = new ReferenceTypeUsageImpl(typeDeclaration, typeSolver);
         return typeUsage;
     }
 }
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/TypeParameter.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/TypeParameter.java
deleted file mode 100644
index ea7be98..0000000
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/TypeParameter.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package me.tomassetti.symbolsolver.resolution;
-
-import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
-
-import java.util.List;
-
-public interface TypeParameter {
-
-    public static TypeParameter onClass(final String name, String classQName, List<Bound> bounds) {
-        return new TypeParameter() {
-            @Override
-            public String getName() {
-                return name;
-            }
-
-            @Override
-            public boolean declaredOnClass() {
-                return true;
-            }
-
-            @Override
-            public boolean declaredOnMethod() {
-                return false;
-            }
-
-            @Override
-            public String getQNameOfDeclaringClass() {
-                return classQName;
-            }
-
-            @Override
-            public List<Bound> getBounds(TypeSolver typeSolver) {
-                return bounds;
-            }
-
-            @Override
-            public String toString() {
-                return "TypeParameter onClass " + name;
-            }
-        };
-    }
-
-    public String getName();
-
-    public boolean declaredOnClass();
-
-    public boolean declaredOnMethod();
-
-    public String getQNameOfDeclaringClass();
-
-    public List<Bound> getBounds(TypeSolver typeSolver);
-
-    public class Bound {
-        private boolean extendsBound;
-        private TypeUsage type;
-
-        private Bound(boolean extendsBound, TypeUsage type) {
-            this.extendsBound = extendsBound;
-            this.type = type;
-        }
-
-        public static Bound extendsBound(TypeUsage typeUsage) {
-            return new Bound(true, typeUsage);
-        }
-
-        public static Bound superBound(TypeUsage typeUsage) {
-            return new Bound(false, typeUsage);
-        }
-
-        public TypeUsage getType() {
-            return type;
-        }
-
-        public boolean isExtends() {
-            return extendsBound;
-        }
-
-        public boolean isSuper() {
-            return !isExtends();
-        }
-    }
-
-}
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/TypeSolver.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/TypeSolver.java
deleted file mode 100644
index 80a6734..0000000
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/TypeSolver.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package me.tomassetti.symbolsolver.resolution;
-
-import me.tomassetti.symbolsolver.model.declarations.TypeDeclaration;
-import me.tomassetti.symbolsolver.resolution.javaparser.UnsolvedSymbolException;
-
-public interface TypeSolver {
-
-    public default TypeSolver getRoot() {
-        if (getParent() == null) {
-            return this;
-        } else {
-            return getParent().getRoot();
-        }
-    }
-
-    public TypeSolver getParent();
-
-    void setParent(TypeSolver parent);
-
-    public SymbolReference<TypeDeclaration> tryToSolveType(String name);
-
-    public default TypeDeclaration solveType(String name) throws UnsolvedSymbolException {
-        SymbolReference<TypeDeclaration> ref = tryToSolveType(name);
-        if (ref.isSolved()) {
-            return ref.getCorrespondingDeclaration();
-        } else {
-            throw new UnsolvedSymbolException(name, this);
-        }
-    }
-
-}
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/Value.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/Value.java
deleted file mode 100644
index b0a6e66..0000000
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/Value.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package me.tomassetti.symbolsolver.resolution;
-
-import me.tomassetti.symbolsolver.model.declarations.ValueDeclaration;
-import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
-
-public class Value {
-
-    private TypeUsage typeUsage;
-    private String name;
-    private boolean field;
-
-    public Value(TypeUsage typeUsage, String name, boolean field) {
-        this.typeUsage = typeUsage;
-        this.name = name;
-        this.field = field;
-    }
-
-    public static Value from(ValueDeclaration decl, TypeSolver typeSolver) {
-        TypeUsage typeUsage = decl.getType();
-        return new Value(typeUsage, decl.getName(), decl.isField());
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public boolean isField() {
-        return field;
-    }
-
-    public TypeUsage getUsage() {
-        return typeUsage;
-    }
-
-}
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/JavaParserFacade.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/JavaParserFacade.java
index a891d6e..c951bab 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/JavaParserFacade.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/JavaParserFacade.java
@@ -8,6 +8,10 @@
 import me.tomassetti.symbolsolver.model.declarations.TypeDeclaration;
 import me.tomassetti.symbolsolver.model.declarations.ValueDeclaration;
 import me.tomassetti.symbolsolver.model.invokations.MethodUsage;
+import me.tomassetti.symbolsolver.model.resolution.Context;
+import me.tomassetti.symbolsolver.model.resolution.SymbolReference;
+import me.tomassetti.symbolsolver.model.resolution.TypeParameter;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.model.typesystem.*;
 import me.tomassetti.symbolsolver.resolution.*;
 import me.tomassetti.symbolsolver.resolution.javaparser.declarations.*;
@@ -138,7 +142,7 @@
         if (node instanceof NameExpr) {
             NameExpr nameExpr = (NameExpr) node;
             logger.finest("getType on name expr " + node);
-            Optional<Value> value = new SymbolSolver(typeSolver).solveSymbolAsValue(nameExpr.getName(), nameExpr);
+            Optional<me.tomassetti.symbolsolver.model.resolution.Value> value = new SymbolSolver(typeSolver).solveSymbolAsValue(nameExpr.getName(), nameExpr);
             if (!value.isPresent()) {
                 throw new UnsolvedSymbolException("FOO Solving " + node, nameExpr.getName());
             } else {
@@ -193,7 +197,7 @@
             FieldAccessExpr fieldAccessExpr = (FieldAccessExpr) node;
             // We should understand if this is a static access
             try {
-                Optional<Value> value = new SymbolSolver(typeSolver).solveSymbolAsValue(fieldAccessExpr.getField(), fieldAccessExpr);
+                Optional<me.tomassetti.symbolsolver.model.resolution.Value> value = new SymbolSolver(typeSolver).solveSymbolAsValue(fieldAccessExpr.getField(), fieldAccessExpr);
                 if (value.isPresent()) {
                     return value.get().getUsage();
                 } else {
@@ -230,7 +234,7 @@
         } else if (node instanceof CharLiteralExpr) {
             return PrimitiveTypeUsage.CHAR;
         } else if (node instanceof StringLiteralExpr) {
-            return new ReferenceTypeUsage(new JreTypeSolver().solveType("java.lang.String"), typeSolver);
+            return new ReferenceTypeUsageImpl(new JreTypeSolver().solveType("java.lang.String"), typeSolver);
         } else if (node instanceof UnaryExpr) {
             UnaryExpr unaryExpr = (UnaryExpr) node;
             switch (unaryExpr.getOperator()) {
@@ -283,7 +287,7 @@
             AssignExpr assignExpr = (AssignExpr) node;
             return getTypeConcrete(assignExpr.getTarget(), solveLambdas);
         } else if (node instanceof ThisExpr) {
-            return new ReferenceTypeUsage(getTypeDeclaration(findContainingTypeDecl(node)), typeSolver);
+            return new ReferenceTypeUsageImpl(getTypeDeclaration(findContainingTypeDecl(node)), typeSolver);
         } else if (node instanceof ConditionalExpr) {
             ConditionalExpr conditionalExpr = (ConditionalExpr) node;
             return getTypeConcrete(conditionalExpr.getThenExpr(), solveLambdas);
@@ -352,16 +356,16 @@
                     return new TypeParameterUsage(javaParserTypeVariableDeclaration.asTypeParameter());
                 }
             } else {
-                return new ReferenceTypeUsage(typeDeclaration, typeParameters, typeSolver);
+                return new ReferenceTypeUsageImpl(typeDeclaration, typeParameters, typeSolver);
             }
         } else if (type instanceof PrimitiveType) {
             return PrimitiveTypeUsage.byName(((PrimitiveType) type).getType().name());
         } else if (type instanceof WildcardType) {
             WildcardType wildcardType = (WildcardType) type;
             if (wildcardType.getExtends() != null && wildcardType.getSuper() == null) {
-                return WildcardUsage.extendsBound((ReferenceTypeUsage) convertToUsage(wildcardType.getExtends(), context));
+                return WildcardUsage.extendsBound((ReferenceTypeUsageImpl) convertToUsage(wildcardType.getExtends(), context));
             } else if (wildcardType.getExtends() == null && wildcardType.getSuper() != null) {
-                return WildcardUsage.extendsBound((ReferenceTypeUsage) convertToUsage(wildcardType.getSuper(), context));
+                return WildcardUsage.extendsBound((ReferenceTypeUsageImpl) convertToUsage(wildcardType.getSuper(), context));
             } else if (wildcardType.getExtends() == null && wildcardType.getSuper() == null) {
                 return WildcardUsage.UNBOUNDED;
             } else {
@@ -414,7 +418,7 @@
         // TODO consider static methods
         if (node instanceof ClassOrInterfaceDeclaration) {
             JavaParserClassDeclaration classDeclaration = new JavaParserClassDeclaration((ClassOrInterfaceDeclaration) node, typeSolver);
-            return new ReferenceTypeUsage(classDeclaration, typeSolver);
+            return new ReferenceTypeUsageImpl(classDeclaration, typeSolver);
         } else {
             return getTypeOfThisIn(node.getParentNode());
         }
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/JavaParserFactory.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/JavaParserFactory.java
index c1b5b00..f2cf6ac 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/JavaParserFactory.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/JavaParserFactory.java
@@ -8,18 +8,15 @@
 import com.github.javaparser.ast.expr.MethodCallExpr;
 import com.github.javaparser.ast.expr.VariableDeclarationExpr;
 import com.github.javaparser.ast.stmt.*;
-import me.tomassetti.symbolsolver.resolution.Context;
+import me.tomassetti.symbolsolver.model.resolution.Context;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.resolution.SymbolDeclarator;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.resolution.javaparser.contexts.*;
 import me.tomassetti.symbolsolver.resolution.javaparser.declarators.FieldSymbolDeclarator;
-import me.tomassetti.symbolsolver.resolution.javaparser.declarators.NoSimboyDeclarator;
+import me.tomassetti.symbolsolver.resolution.javaparser.declarators.NoSimbolDeclarator;
 import me.tomassetti.symbolsolver.resolution.javaparser.declarators.ParameterSymbolDeclarator;
 import me.tomassetti.symbolsolver.resolution.javaparser.declarators.VariableSymbolDeclarator;
 
-/**
- * Created by federico on 28/07/15.
- */
 public class JavaParserFactory {
 
     public static Context getContext(Node node, TypeSolver typeSolver) {
@@ -64,15 +61,15 @@
             if (expressionStmt.getExpression() instanceof VariableDeclarationExpr) {
                 return new VariableSymbolDeclarator((VariableDeclarationExpr) (expressionStmt.getExpression()), typeSolver);
             } else {
-                return new NoSimboyDeclarator(node, typeSolver);
+                return new NoSimbolDeclarator(node, typeSolver);
             }
         } else if (node instanceof IfStmt) {
-            return new NoSimboyDeclarator(node, typeSolver);
+            return new NoSimbolDeclarator(node, typeSolver);
         } else if (node instanceof ForeachStmt) {
             ForeachStmt foreachStmt = (ForeachStmt) node;
             return new VariableSymbolDeclarator((VariableDeclarationExpr) (foreachStmt.getVariable()), typeSolver);
         } else {
-            return new NoSimboyDeclarator(node, typeSolver);
+            return new NoSimbolDeclarator(node, typeSolver);
         }
     }
 
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/LambdaArgumentTypeUsagePlaceholder.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/LambdaArgumentTypeUsagePlaceholder.java
index 1da055c..740f53e 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/LambdaArgumentTypeUsagePlaceholder.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/LambdaArgumentTypeUsagePlaceholder.java
@@ -1,8 +1,8 @@
 package me.tomassetti.symbolsolver.resolution.javaparser;
 
 import me.tomassetti.symbolsolver.model.declarations.MethodDeclaration;
+import me.tomassetti.symbolsolver.model.resolution.SymbolReference;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
-import me.tomassetti.symbolsolver.resolution.SymbolReference;
 
 /**
  * Placeholder used to represent a lambda argument type while it is being
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/UnsolvedSymbolException.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/UnsolvedSymbolException.java
index 0070eed..7814030 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/UnsolvedSymbolException.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/UnsolvedSymbolException.java
@@ -1,7 +1,7 @@
 package me.tomassetti.symbolsolver.resolution.javaparser;
 
-import me.tomassetti.symbolsolver.resolution.Context;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
+import me.tomassetti.symbolsolver.model.resolution.Context;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 
 public class UnsolvedSymbolException extends RuntimeException {
 
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/UnsolvedTypeException.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/UnsolvedTypeException.java
index bcc2a1b..7374c36 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/UnsolvedTypeException.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/UnsolvedTypeException.java
@@ -1,6 +1,6 @@
 package me.tomassetti.symbolsolver.resolution.javaparser;
 
-import me.tomassetti.symbolsolver.resolution.Context;
+import me.tomassetti.symbolsolver.model.resolution.Context;
 
 /**
  * Created by federico on 30/07/15.
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/AbstractJavaParserContext.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/AbstractJavaParserContext.java
index 522de97..44c1d0b 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/AbstractJavaParserContext.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/AbstractJavaParserContext.java
@@ -4,6 +4,10 @@
 import com.github.javaparser.ast.expr.Expression;
 import com.github.javaparser.ast.expr.MethodCallExpr;
 import me.tomassetti.symbolsolver.model.declarations.ValueDeclaration;
+import me.tomassetti.symbolsolver.model.resolution.Context;
+import me.tomassetti.symbolsolver.model.resolution.SymbolReference;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
+import me.tomassetti.symbolsolver.model.resolution.Value;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
 import me.tomassetti.symbolsolver.resolution.*;
 import me.tomassetti.symbolsolver.resolution.javaparser.JavaParserFactory;
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/ClassOrInterfaceDeclarationContext.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/ClassOrInterfaceDeclarationContext.java
index 38b9157..2b2032d 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/ClassOrInterfaceDeclarationContext.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/ClassOrInterfaceDeclarationContext.java
@@ -10,9 +10,9 @@
 import me.tomassetti.symbolsolver.model.typesystem.TypeParameterUsage;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
 import me.tomassetti.symbolsolver.resolution.SymbolDeclarator;
-import me.tomassetti.symbolsolver.resolution.SymbolReference;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
-import me.tomassetti.symbolsolver.resolution.Value;
+import me.tomassetti.symbolsolver.model.resolution.SymbolReference;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
+import me.tomassetti.symbolsolver.model.resolution.Value;
 import me.tomassetti.symbolsolver.resolution.javaparser.JavaParserFactory;
 import me.tomassetti.symbolsolver.resolution.javaparser.UnsolvedSymbolException;
 import me.tomassetti.symbolsolver.resolution.javaparser.UnsolvedTypeException;
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/CompilationUnitContext.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/CompilationUnitContext.java
index ba8f2ad..25851a6 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/CompilationUnitContext.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/CompilationUnitContext.java
@@ -7,18 +7,15 @@
 import com.github.javaparser.ast.expr.QualifiedNameExpr;
 import me.tomassetti.symbolsolver.model.declarations.MethodDeclaration;
 import me.tomassetti.symbolsolver.model.declarations.ValueDeclaration;
+import me.tomassetti.symbolsolver.model.resolution.SymbolReference;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
-import me.tomassetti.symbolsolver.resolution.SymbolReference;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.resolution.javaparser.declarations.JavaParserClassDeclaration;
 import me.tomassetti.symbolsolver.resolution.javaparser.declarations.JavaParserInterfaceDeclaration;
 
 import java.util.List;
 
 
-/**
- * Created by federico on 30/07/15.
- */
 public class CompilationUnitContext extends AbstractJavaParserContext<CompilationUnit> {
 
     public CompilationUnitContext(CompilationUnit wrappedNode, TypeSolver typeSolver) {
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/ConstructorContext.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/ConstructorContext.java
index c047ba3..a6e1a67 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/ConstructorContext.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/ConstructorContext.java
@@ -6,18 +6,15 @@
 import me.tomassetti.symbolsolver.model.typesystem.TypeParameterUsage;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
 import me.tomassetti.symbolsolver.resolution.SymbolDeclarator;
-import me.tomassetti.symbolsolver.resolution.SymbolReference;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
-import me.tomassetti.symbolsolver.resolution.Value;
+import me.tomassetti.symbolsolver.model.resolution.SymbolReference;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
+import me.tomassetti.symbolsolver.model.resolution.Value;
 import me.tomassetti.symbolsolver.resolution.javaparser.JavaParserFactory;
 import me.tomassetti.symbolsolver.resolution.javaparser.declarations.JavaParserTypeParameter;
 
 import java.util.List;
 import java.util.Optional;
 
-/**
- * Created by federico on 28/07/15.
- */
 public class ConstructorContext extends AbstractJavaParserContext<ConstructorDeclaration> {
 
 
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/EnumDeclarationContext.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/EnumDeclarationContext.java
index ce7bbc5..6d9c834 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/EnumDeclarationContext.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/EnumDeclarationContext.java
@@ -3,10 +3,10 @@
 import com.github.javaparser.ast.body.*;
 import me.tomassetti.symbolsolver.logic.MethodResolutionLogic;
 import me.tomassetti.symbolsolver.model.declarations.ValueDeclaration;
+import me.tomassetti.symbolsolver.model.resolution.SymbolReference;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
 import me.tomassetti.symbolsolver.resolution.SymbolDeclarator;
-import me.tomassetti.symbolsolver.resolution.SymbolReference;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.resolution.javaparser.JavaParserFactory;
 import me.tomassetti.symbolsolver.resolution.javaparser.declarations.JavaParserClassDeclaration;
 import me.tomassetti.symbolsolver.resolution.javaparser.declarations.JavaParserEnumConstantDeclaration;
@@ -16,7 +16,6 @@
 import java.util.ArrayList;
 import java.util.List;
 
-
 /**
  * @author Federico Tomassetti
  */
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/FieldAccessContext.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/FieldAccessContext.java
index e0dc927..7f9f76c 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/FieldAccessContext.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/FieldAccessContext.java
@@ -5,10 +5,10 @@
 import me.tomassetti.symbolsolver.model.declarations.MethodDeclaration;
 import me.tomassetti.symbolsolver.model.declarations.TypeDeclaration;
 import me.tomassetti.symbolsolver.model.declarations.ValueDeclaration;
+import me.tomassetti.symbolsolver.model.resolution.SymbolReference;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
+import me.tomassetti.symbolsolver.model.resolution.Value;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
-import me.tomassetti.symbolsolver.resolution.SymbolReference;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
-import me.tomassetti.symbolsolver.resolution.Value;
 import me.tomassetti.symbolsolver.resolution.javaparser.JavaParserFacade;
 import me.tomassetti.symbolsolver.resolution.javaparser.JavaParserFactory;
 
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/ForStatementContext.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/ForStatementContext.java
index c2a3257..9c39752 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/ForStatementContext.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/ForStatementContext.java
@@ -7,16 +7,13 @@
 import com.github.javaparser.ast.stmt.ForStmt;
 import me.tomassetti.symbolsolver.model.declarations.MethodDeclaration;
 import me.tomassetti.symbolsolver.model.declarations.ValueDeclaration;
+import me.tomassetti.symbolsolver.model.resolution.SymbolReference;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
-import me.tomassetti.symbolsolver.resolution.SymbolReference;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.resolution.javaparser.declarations.JavaParserSymbolDeclaration;
 
 import java.util.List;
 
-/**
- * Created by federico on 23/08/15.
- */
 public class ForStatementContext extends AbstractJavaParserContext<ForStmt> {
 
     public ForStatementContext(ForStmt wrappedNode, TypeSolver typeSolver) {
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/ForechStatementContext.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/ForechStatementContext.java
index 389839b..bcb83df 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/ForechStatementContext.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/ForechStatementContext.java
@@ -5,16 +5,13 @@
 import com.github.javaparser.ast.stmt.ForeachStmt;
 import me.tomassetti.symbolsolver.model.declarations.MethodDeclaration;
 import me.tomassetti.symbolsolver.model.declarations.ValueDeclaration;
+import me.tomassetti.symbolsolver.model.resolution.SymbolReference;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
-import me.tomassetti.symbolsolver.resolution.SymbolReference;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.resolution.javaparser.declarations.JavaParserSymbolDeclaration;
 
 import java.util.List;
 
-/**
- * Created by federico on 23/08/15.
- */
 public class ForechStatementContext extends AbstractJavaParserContext<ForeachStmt> {
 
     public ForechStatementContext(ForeachStmt wrappedNode, TypeSolver typeSolver) {
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/LambdaExprContext.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/LambdaExprContext.java
index d8564f0..fe5a77a 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/LambdaExprContext.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/LambdaExprContext.java
@@ -10,9 +10,9 @@
 import me.tomassetti.symbolsolver.model.invokations.MethodUsage;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
 import me.tomassetti.symbolsolver.resolution.SymbolDeclarator;
-import me.tomassetti.symbolsolver.resolution.SymbolReference;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
-import me.tomassetti.symbolsolver.resolution.Value;
+import me.tomassetti.symbolsolver.model.resolution.SymbolReference;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
+import me.tomassetti.symbolsolver.model.resolution.Value;
 import me.tomassetti.symbolsolver.resolution.javaparser.JavaParserFacade;
 import me.tomassetti.symbolsolver.resolution.javaparser.JavaParserFactory;
 
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/MethodCallExprContext.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/MethodCallExprContext.java
index e514793..05f92f9 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/MethodCallExprContext.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/MethodCallExprContext.java
@@ -6,10 +6,10 @@
 import me.tomassetti.symbolsolver.model.declarations.TypeDeclaration;
 import me.tomassetti.symbolsolver.model.declarations.ValueDeclaration;
 import me.tomassetti.symbolsolver.model.invokations.MethodUsage;
-import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsage;
+import me.tomassetti.symbolsolver.model.resolution.*;
+import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsageImpl;
 import me.tomassetti.symbolsolver.model.typesystem.TypeParameterUsage;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
-import me.tomassetti.symbolsolver.resolution.*;
 import me.tomassetti.symbolsolver.resolution.javaparser.JavaParserFacade;
 import me.tomassetti.symbolsolver.resolution.javaparser.UnsolvedSymbolException;
 import me.tomassetti.symbolsolver.reflectionmodel.ReflectionClassDeclaration;
@@ -32,7 +32,7 @@
         return typeOfScope.asReferenceTypeUsage().getGenericParameterByName(name);
     }
 
-    private Optional<MethodUsage> solveMethodAsUsage(ReferenceTypeUsage refType, String name, List<TypeUsage> parameterTypes, TypeSolver typeSolver, Context invokationContext) {
+    private Optional<MethodUsage> solveMethodAsUsage(ReferenceTypeUsageImpl refType, String name, List<TypeUsage> parameterTypes, TypeSolver typeSolver, Context invokationContext) {
         Optional<MethodUsage> ref = refType.getTypeDeclaration().solveMethodAsUsage(name, parameterTypes, typeSolver, invokationContext, refType.parameters());
         if (ref.isPresent()) {
             MethodUsage methodUsage = ref.get();
@@ -66,8 +66,8 @@
     }
 
     private Optional<MethodUsage> solveMethodAsUsage(TypeUsage typeUsage, String name, List<TypeUsage> parameterTypes, TypeSolver typeSolver, Context invokationContext) {
-        if (typeUsage instanceof ReferenceTypeUsage) {
-            return solveMethodAsUsage((ReferenceTypeUsage) typeUsage, name, parameterTypes, typeSolver, invokationContext);
+        if (typeUsage instanceof ReferenceTypeUsageImpl) {
+            return solveMethodAsUsage((ReferenceTypeUsageImpl) typeUsage, name, parameterTypes, typeSolver, invokationContext);
         } else if (typeUsage instanceof TypeParameterUsage) {
             return solveMethodAsUsage((TypeParameterUsage) typeUsage, name, parameterTypes, typeSolver, invokationContext);
         } else {
@@ -132,7 +132,7 @@
                 if (typeOfScope.asWildcard().isExtends() || typeOfScope.asWildcard().isSuper()) {
                     return typeOfScope.asWildcard().getBoundedType().asReferenceTypeUsage().solveMethod(name, parameterTypes);
                 } else {
-                    return new ReferenceTypeUsage(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver).solveMethod(name, parameterTypes);
+                    return new ReferenceTypeUsageImpl(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver).solveMethod(name, parameterTypes);
                 }
             } else {
                 return typeOfScope.asReferenceTypeUsage().solveMethod(name, parameterTypes);
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/MethodContext.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/MethodContext.java
index 731505f..c4daed8 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/MethodContext.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/MethodContext.java
@@ -7,21 +7,17 @@
 import me.tomassetti.symbolsolver.model.typesystem.TypeParameterUsage;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
 import me.tomassetti.symbolsolver.resolution.SymbolDeclarator;
-import me.tomassetti.symbolsolver.resolution.SymbolReference;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
-import me.tomassetti.symbolsolver.resolution.Value;
+import me.tomassetti.symbolsolver.model.resolution.SymbolReference;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
+import me.tomassetti.symbolsolver.model.resolution.Value;
 import me.tomassetti.symbolsolver.resolution.javaparser.JavaParserFactory;
 import me.tomassetti.symbolsolver.resolution.javaparser.declarations.JavaParserTypeParameter;
 
 import java.util.List;
 import java.util.Optional;
 
-/**
- * Created by federico on 28/07/15.
- */
 public class MethodContext extends AbstractJavaParserContext<MethodDeclaration> {
 
-
     public MethodContext(MethodDeclaration wrappedNode, TypeSolver typeSolver) {
         super(wrappedNode, typeSolver);
     }
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/StatementContext.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/StatementContext.java
index 8c765a8..6637443 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/StatementContext.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/StatementContext.java
@@ -7,6 +7,10 @@
 import me.tomassetti.symbolsolver.model.declarations.MethodDeclaration;
 import me.tomassetti.symbolsolver.model.declarations.TypeDeclaration;
 import me.tomassetti.symbolsolver.model.declarations.ValueDeclaration;
+import me.tomassetti.symbolsolver.model.resolution.Context;
+import me.tomassetti.symbolsolver.model.resolution.SymbolReference;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
+import me.tomassetti.symbolsolver.model.resolution.Value;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
 import me.tomassetti.symbolsolver.resolution.*;
 import me.tomassetti.symbolsolver.resolution.javaparser.JavaParserFactory;
@@ -14,9 +18,6 @@
 import java.util.List;
 import java.util.Optional;
 
-/**
- * Created by federico on 28/07/15.
- */
 public class StatementContext<N extends Statement> extends AbstractJavaParserContext<N> {
 
     public StatementContext(N wrappedNode, TypeSolver typeSolver) {
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/SwitchEntryContext.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/SwitchEntryContext.java
index dc1868f..5ea89a6 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/SwitchEntryContext.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/contexts/SwitchEntryContext.java
@@ -4,29 +4,27 @@
 import com.github.javaparser.ast.stmt.SwitchStmt;
 import me.tomassetti.symbolsolver.model.declarations.MethodDeclaration;
 import me.tomassetti.symbolsolver.model.declarations.ValueDeclaration;
-import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsage;
+import me.tomassetti.symbolsolver.model.resolution.SymbolReference;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
+import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsageImpl;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
-import me.tomassetti.symbolsolver.resolution.SymbolReference;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.resolution.javaparser.JavaParserFacade;
 
 import java.util.List;
 
-
 public class SwitchEntryContext extends AbstractJavaParserContext<SwitchEntryStmt> {
 
     public SwitchEntryContext(SwitchEntryStmt wrappedNode, TypeSolver typeSolver) {
         super(wrappedNode, typeSolver);
     }
 
-
     @Override
     public SymbolReference<? extends ValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
         SwitchStmt switchStmt = (SwitchStmt) wrappedNode.getParentNode();
         TypeUsage type = JavaParserFacade.get(typeSolver).getType(switchStmt.getSelector());
         if (type.isReferenceType() && type.asReferenceTypeUsage().getTypeDeclaration().isEnum()) {
-            if (type instanceof ReferenceTypeUsage) {
-                ReferenceTypeUsage typeUsageOfTypeDeclaration = (ReferenceTypeUsage) type;
+            if (type instanceof ReferenceTypeUsageImpl) {
+                ReferenceTypeUsageImpl typeUsageOfTypeDeclaration = (ReferenceTypeUsageImpl) type;
                 if (typeUsageOfTypeDeclaration.getTypeDeclaration().hasField(name)) {
                     return SymbolReference.solved(typeUsageOfTypeDeclaration.getTypeDeclaration().getField(name));
                 }
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserClassDeclaration.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserClassDeclaration.java
index b3787dd..15da03e 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserClassDeclaration.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserClassDeclaration.java
@@ -11,7 +11,12 @@
 import com.github.javaparser.ast.type.Type;
 import me.tomassetti.symbolsolver.logic.AbstractClassDeclaration;
 import me.tomassetti.symbolsolver.model.declarations.*;
+import me.tomassetti.symbolsolver.model.resolution.Context;
+import me.tomassetti.symbolsolver.model.resolution.SymbolReference;
+import me.tomassetti.symbolsolver.model.resolution.TypeParameter;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsage;
+import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsageImpl;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
 import me.tomassetti.symbolsolver.resolution.*;
 import me.tomassetti.symbolsolver.resolution.javaparser.JavaParserFacade;
@@ -94,15 +99,15 @@
     }
 
     @Override
-    public ReferenceTypeUsage getSuperClass() {
+    public ReferenceTypeUsageImpl getSuperClass() {
         if (wrappedNode.getExtends() == null || wrappedNode.getExtends().isEmpty()) {
-            return new ReferenceTypeUsage(typeSolver.getRoot().solveType("java.lang.Object").asType().asClass(), typeSolver);
+            return new ReferenceTypeUsageImpl(typeSolver.getRoot().solveType("java.lang.Object").asType().asClass(), typeSolver);
         } else {
             SymbolReference<TypeDeclaration> ref = solveType(wrappedNode.getExtends().get(0).getName(), typeSolver);
             if (!ref.isSolved()) {
                 throw new UnsolvedSymbolException(wrappedNode.getExtends().get(0).getName());
             }
-            return new ReferenceTypeUsage(ref.getCorrespondingDeclaration().asClass(), typeSolver);
+            return new ReferenceTypeUsageImpl(ref.getCorrespondingDeclaration().asClass(), typeSolver);
         }
     }
 
@@ -139,7 +144,7 @@
     @Override
     public boolean isAssignableBy(TypeDeclaration other) {
         List<ReferenceTypeUsage> ancestorsOfOther = other.getAllAncestors();
-        ancestorsOfOther.add(new ReferenceTypeUsage(other, typeSolver));
+        ancestorsOfOther.add(new ReferenceTypeUsageImpl(other, typeSolver));
         for (ReferenceTypeUsage ancestorOfOther : ancestorsOfOther) {
             if (ancestorOfOther.getQualifiedName().equals(this.getQualifiedName())) {
                 return true;
@@ -325,14 +330,14 @@
     @Override
     public List<ReferenceTypeUsage> getAllAncestors() {
         List<ReferenceTypeUsage> ancestors = new ArrayList<>();
-        ReferenceTypeUsage superclass = getSuperClass();
+        ReferenceTypeUsageImpl superclass = getSuperClass();
         if (superclass != null) {
             ancestors.add(superclass);
             ancestors.addAll(superclass.getAllAncestors());
         }
         if (wrappedNode.getImplements() != null) {
             for (ClassOrInterfaceType implemented : wrappedNode.getImplements()) {
-                ReferenceTypeUsage ancestor = toTypeUsage(implemented, typeSolver);
+                ReferenceTypeUsageImpl ancestor = toTypeUsage(implemented, typeSolver);
                 ancestors.add(ancestor);
                 ancestors.addAll(ancestor.getAllAncestors());
             }
@@ -340,16 +345,16 @@
         return ancestors;
     }
 
-    private ReferenceTypeUsage toTypeUsage(ClassOrInterfaceType type, TypeSolver typeSolver) {
+    private ReferenceTypeUsageImpl toTypeUsage(ClassOrInterfaceType type, TypeSolver typeSolver) {
         SymbolReference<TypeDeclaration> ancestor = solveType(type.getName(), typeSolver.getRoot());
         if (!ancestor.isSolved()) {
             throw new UnsolvedSymbolException(type.getName());
         }
         if (type.getTypeArgs() != null) {
             List<TypeUsage> typeParams = type.getTypeArgs().stream().map((t) -> toTypeUsage(t, typeSolver)).collect(Collectors.toList());
-            return new ReferenceTypeUsage(ancestor.getCorrespondingDeclaration(), typeParams, typeSolver);
+            return new ReferenceTypeUsageImpl(ancestor.getCorrespondingDeclaration(), typeParams, typeSolver);
         } else {
-            return new ReferenceTypeUsage(ancestor.getCorrespondingDeclaration(), typeSolver);
+            return new ReferenceTypeUsageImpl(ancestor.getCorrespondingDeclaration(), typeSolver);
         }
     }
 
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserEnumConstantDeclaration.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserEnumConstantDeclaration.java
index 22e247d..e5445a8 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserEnumConstantDeclaration.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserEnumConstantDeclaration.java
@@ -2,9 +2,9 @@
 
 import com.github.javaparser.ast.body.EnumDeclaration;
 import me.tomassetti.symbolsolver.model.declarations.ValueDeclaration;
-import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsage;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
+import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsageImpl;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
 
 public class JavaParserEnumConstantDeclaration implements ValueDeclaration {
 
@@ -18,7 +18,7 @@
 
     @Override
     public TypeUsage getType() {
-        return new ReferenceTypeUsage(new JavaParserEnumDeclaration((EnumDeclaration) wrappedNode.getParentNode(), typeSolver), typeSolver);
+        return new ReferenceTypeUsageImpl(new JavaParserEnumDeclaration((EnumDeclaration) wrappedNode.getParentNode(), typeSolver), typeSolver);
     }
 
     @Override
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserEnumDeclaration.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserEnumDeclaration.java
index 58851fc..413c6fd 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserEnumDeclaration.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserEnumDeclaration.java
@@ -9,13 +9,14 @@
 import me.tomassetti.symbolsolver.logic.AbstractTypeDeclaration;
 import me.tomassetti.symbolsolver.model.declarations.*;
 import me.tomassetti.symbolsolver.model.invokations.MethodUsage;
+import me.tomassetti.symbolsolver.model.resolution.Context;
+import me.tomassetti.symbolsolver.model.resolution.SymbolReference;
+import me.tomassetti.symbolsolver.model.resolution.TypeParameter;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.model.typesystem.ArrayTypeUsage;
 import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsage;
+import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsageImpl;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
-import me.tomassetti.symbolsolver.resolution.Context;
-import me.tomassetti.symbolsolver.resolution.SymbolReference;
-import me.tomassetti.symbolsolver.resolution.TypeParameter;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.resolution.javaparser.JavaParserFactory;
 import me.tomassetti.symbolsolver.resolution.javaparser.UnsolvedSymbolException;
 
@@ -36,7 +37,7 @@
 
     @Override
     public boolean isAssignableBy(TypeDeclaration other) {
-        return isAssignableBy(new ReferenceTypeUsage(other, typeSolver));
+        return isAssignableBy(new ReferenceTypeUsageImpl(other, typeSolver));
     }
 
     @Override
@@ -275,7 +276,7 @@
 
         @Override
         public TypeUsage getReturnType() {
-            return new ArrayTypeUsage(new ReferenceTypeUsage(JavaParserEnumDeclaration.this, typeSolver));
+            return new ArrayTypeUsage(new ReferenceTypeUsageImpl(JavaParserEnumDeclaration.this, typeSolver));
         }
 
         @Override
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserFieldDeclaration.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserFieldDeclaration.java
index 880fe12..83c8d9f 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserFieldDeclaration.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserFieldDeclaration.java
@@ -3,9 +3,9 @@
 import com.github.javaparser.ast.body.EnumConstantDeclaration;
 import com.github.javaparser.ast.body.VariableDeclarator;
 import me.tomassetti.symbolsolver.model.declarations.FieldDeclaration;
-import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsage;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
+import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsageImpl;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.resolution.javaparser.JavaParserFacade;
 
 public class JavaParserFieldDeclaration implements FieldDeclaration {
@@ -32,7 +32,7 @@
     public TypeUsage getType() {
         if (enumConstantDeclaration != null) {
             com.github.javaparser.ast.body.EnumDeclaration enumDeclaration = (com.github.javaparser.ast.body.EnumDeclaration) enumConstantDeclaration.getParentNode();
-            return new ReferenceTypeUsage(new JavaParserEnumDeclaration(enumDeclaration, typeSolver), typeSolver);
+            return new ReferenceTypeUsageImpl(new JavaParserEnumDeclaration(enumDeclaration, typeSolver), typeSolver);
         } else {
             return JavaParserFacade.get(typeSolver).convert(fieldDeclaration.getType(), fieldDeclaration);
         }
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserInterfaceDeclaration.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserInterfaceDeclaration.java
index 322c2d0..d5375cf 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserInterfaceDeclaration.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserInterfaceDeclaration.java
@@ -13,7 +13,12 @@
 import me.tomassetti.symbolsolver.model.declarations.InterfaceDeclaration;
 import me.tomassetti.symbolsolver.model.declarations.TypeDeclaration;
 import me.tomassetti.symbolsolver.model.declarations.ValueDeclaration;
+import me.tomassetti.symbolsolver.model.resolution.Context;
+import me.tomassetti.symbolsolver.model.resolution.SymbolReference;
+import me.tomassetti.symbolsolver.model.resolution.TypeParameter;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsage;
+import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsageImpl;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
 import me.tomassetti.symbolsolver.resolution.*;
 import me.tomassetti.symbolsolver.resolution.javaparser.JavaParserFactory;
@@ -101,7 +106,7 @@
     @Override
     public boolean isAssignableBy(TypeDeclaration other) {
         List<ReferenceTypeUsage> ancestorsOfOther = other.getAllAncestors();
-        ancestorsOfOther.add(new ReferenceTypeUsage(other, typeSolver));
+        ancestorsOfOther.add(new ReferenceTypeUsageImpl(other, typeSolver));
         for (ReferenceTypeUsage ancestorOfOther : ancestorsOfOther) {
             if (ancestorOfOther.getQualifiedName().equals(this.getQualifiedName())) {
                 return true;
@@ -282,7 +287,7 @@
                 if (!superclass.isSolved()) {
                     throw new UnsolvedSymbolException(extended.getName());
                 }
-                ancestors.add(new ReferenceTypeUsage(superclass.getCorrespondingDeclaration(), typeSolver));
+                ancestors.add(new ReferenceTypeUsageImpl(superclass.getCorrespondingDeclaration(), typeSolver));
                 ancestors.addAll(superclass.getCorrespondingDeclaration().getAllAncestors());
             }
         }
@@ -292,7 +297,7 @@
                 if (!superclass.isSolved()) {
                     throw new UnsolvedSymbolException(implemented.getName());
                 }
-                ancestors.add(new ReferenceTypeUsage(superclass.getCorrespondingDeclaration(), typeSolver));
+                ancestors.add(new ReferenceTypeUsageImpl(superclass.getCorrespondingDeclaration(), typeSolver));
                 ancestors.addAll(superclass.getCorrespondingDeclaration().getAllAncestors());
             }
         }
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserMethodDeclaration.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserMethodDeclaration.java
index a2b1fac..7179b91 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserMethodDeclaration.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserMethodDeclaration.java
@@ -6,21 +6,19 @@
 import me.tomassetti.symbolsolver.model.declarations.ParameterDeclaration;
 import me.tomassetti.symbolsolver.model.declarations.TypeDeclaration;
 import me.tomassetti.symbolsolver.model.invokations.MethodUsage;
+import me.tomassetti.symbolsolver.model.resolution.Context;
+import me.tomassetti.symbolsolver.model.resolution.TypeParameter;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsage;
+import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsageImpl;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
 import me.tomassetti.symbolsolver.model.typesystem.WildcardUsage;
-import me.tomassetti.symbolsolver.resolution.Context;
-import me.tomassetti.symbolsolver.resolution.TypeParameter;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.resolution.javaparser.JavaParserFacade;
 import me.tomassetti.symbolsolver.resolution.javaparser.JavaParserFactory;
 
 import java.util.*;
 import java.util.stream.Collectors;
 
-/**
- * Created by federico on 17/08/15.
- */
 public class JavaParserMethodDeclaration implements MethodDeclaration {
 
     private com.github.javaparser.ast.body.MethodDeclaration wrappedNode;
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserParameterDeclaration.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserParameterDeclaration.java
index e3f6e68..bab998c 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserParameterDeclaration.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserParameterDeclaration.java
@@ -2,8 +2,8 @@
 
 import com.github.javaparser.ast.body.Parameter;
 import me.tomassetti.symbolsolver.model.declarations.ParameterDeclaration;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.resolution.javaparser.JavaParserFacade;
 
 public class JavaParserParameterDeclaration implements ParameterDeclaration {
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserSymbolDeclaration.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserSymbolDeclaration.java
index dc55b99..55927cf 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserSymbolDeclaration.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserSymbolDeclaration.java
@@ -9,9 +9,9 @@
 import com.github.javaparser.ast.expr.VariableDeclarationExpr;
 import com.github.javaparser.ast.type.PrimitiveType;
 import me.tomassetti.symbolsolver.model.declarations.ValueDeclaration;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.model.typesystem.PrimitiveTypeUsage;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.resolution.javaparser.JavaParserFacade;
 import me.tomassetti.symbolsolver.resolution.javaparser.JavaParserFactory;
 
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserTypeParameter.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserTypeParameter.java
index 04f2f2b..5b28119 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserTypeParameter.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserTypeParameter.java
@@ -7,12 +7,13 @@
 import me.tomassetti.symbolsolver.model.declarations.FieldDeclaration;
 import me.tomassetti.symbolsolver.model.declarations.TypeDeclaration;
 import me.tomassetti.symbolsolver.model.declarations.ValueDeclaration;
+import me.tomassetti.symbolsolver.model.resolution.Context;
+import me.tomassetti.symbolsolver.model.resolution.SymbolReference;
+import me.tomassetti.symbolsolver.model.resolution.TypeParameter;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsage;
+import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsageImpl;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
-import me.tomassetti.symbolsolver.resolution.Context;
-import me.tomassetti.symbolsolver.resolution.SymbolReference;
-import me.tomassetti.symbolsolver.resolution.TypeParameter;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.resolution.javaparser.JavaParserFacade;
 
 import java.util.Collections;
@@ -50,7 +51,7 @@
 
     @Override
     public boolean isAssignableBy(TypeDeclaration other) {
-        return isAssignableBy(new ReferenceTypeUsage(other, typeSolver));
+        return isAssignableBy(new ReferenceTypeUsageImpl(other, typeSolver));
     }
 
     @Override
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserTypeVariableDeclaration.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserTypeVariableDeclaration.java
index 167cf92..948cfd5 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserTypeVariableDeclaration.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarations/JavaParserTypeVariableDeclaration.java
@@ -7,12 +7,12 @@
 import me.tomassetti.symbolsolver.model.declarations.MethodDeclaration;
 import me.tomassetti.symbolsolver.model.declarations.TypeDeclaration;
 import me.tomassetti.symbolsolver.model.declarations.ValueDeclaration;
+import me.tomassetti.symbolsolver.model.resolution.Context;
+import me.tomassetti.symbolsolver.model.resolution.SymbolReference;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsage;
+import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsageImpl;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
-import me.tomassetti.symbolsolver.resolution.Context;
-import me.tomassetti.symbolsolver.resolution.SymbolReference;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
-
 import java.util.Collections;
 import java.util.List;
 
@@ -28,7 +28,7 @@
 
     @Override
     public boolean isAssignableBy(TypeDeclaration other) {
-        return isAssignableBy(new ReferenceTypeUsage(other, typeSolver));
+        return isAssignableBy(new ReferenceTypeUsageImpl(other, typeSolver));
     }
 
     @Override
@@ -137,11 +137,11 @@
     }
 
     @Override
-    public List<me.tomassetti.symbolsolver.resolution.TypeParameter> getTypeParameters() {
+    public List<me.tomassetti.symbolsolver.model.resolution.TypeParameter> getTypeParameters() {
         return Collections.emptyList();
     }
 
-    public me.tomassetti.symbolsolver.resolution.TypeParameter asTypeParameter() {
+    public me.tomassetti.symbolsolver.model.resolution.TypeParameter asTypeParameter() {
         return new JavaParserTypeParameter(this.wrappedNode, typeSolver);
     }
 }
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarators/AbstractSymbolDeclarator.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarators/AbstractSymbolDeclarator.java
index aa6b4a8..9e74f5e 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarators/AbstractSymbolDeclarator.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarators/AbstractSymbolDeclarator.java
@@ -1,8 +1,8 @@
 package me.tomassetti.symbolsolver.resolution.javaparser.declarators;
 
 import com.github.javaparser.ast.Node;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.resolution.SymbolDeclarator;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
 
 /**
  * @author Federico Tomassetti
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarators/FieldSymbolDeclarator.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarators/FieldSymbolDeclarator.java
index 73f7468..b167caa 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarators/FieldSymbolDeclarator.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarators/FieldSymbolDeclarator.java
@@ -4,16 +4,13 @@
 import com.github.javaparser.ast.body.VariableDeclarator;
 import me.tomassetti.symbolsolver.model.declarations.MethodDeclaration;
 import me.tomassetti.symbolsolver.model.declarations.ValueDeclaration;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.resolution.javaparser.declarations.JavaParserSymbolDeclaration;
 
 import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
 
-/**
- * Created by federico on 28/07/15.
- */
 public class FieldSymbolDeclarator extends AbstractSymbolDeclarator<FieldDeclaration> {
 
 
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarators/NoSimboyDeclarator.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarators/NoSimbolDeclarator.java
similarity index 73%
rename from java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarators/NoSimboyDeclarator.java
rename to java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarators/NoSimbolDeclarator.java
index d7edb82..8909537 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarators/NoSimboyDeclarator.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarators/NoSimbolDeclarator.java
@@ -3,17 +3,14 @@
 import com.github.javaparser.ast.Node;
 import me.tomassetti.symbolsolver.model.declarations.MethodDeclaration;
 import me.tomassetti.symbolsolver.model.declarations.ValueDeclaration;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 
 import java.util.Collections;
 import java.util.List;
 
-/**
- * Created by federico on 23/08/15.
- */
-public class NoSimboyDeclarator<N extends Node> extends AbstractSymbolDeclarator<N> {
+public class NoSimbolDeclarator<N extends Node> extends AbstractSymbolDeclarator<N> {
 
-    public NoSimboyDeclarator(N wrappedNode, TypeSolver typeSolver) {
+    public NoSimbolDeclarator(N wrappedNode, TypeSolver typeSolver) {
         super(wrappedNode, typeSolver);
     }
 
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarators/ParameterSymbolDeclarator.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarators/ParameterSymbolDeclarator.java
index 5578765..209f3da 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarators/ParameterSymbolDeclarator.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarators/ParameterSymbolDeclarator.java
@@ -3,16 +3,13 @@
 import com.github.javaparser.ast.body.Parameter;
 import me.tomassetti.symbolsolver.model.declarations.MethodDeclaration;
 import me.tomassetti.symbolsolver.model.declarations.ValueDeclaration;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.resolution.javaparser.declarations.JavaParserSymbolDeclaration;
 
 import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
 
-/**
- * Created by federico on 28/07/15.
- */
 public class ParameterSymbolDeclarator extends AbstractSymbolDeclarator<Parameter> {
 
 
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarators/VariableSymbolDeclarator.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarators/VariableSymbolDeclarator.java
index 6bfe5d9..9467d20 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarators/VariableSymbolDeclarator.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javaparser/declarators/VariableSymbolDeclarator.java
@@ -3,7 +3,7 @@
 import com.github.javaparser.ast.expr.VariableDeclarationExpr;
 import me.tomassetti.symbolsolver.model.declarations.MethodDeclaration;
 import me.tomassetti.symbolsolver.model.declarations.ValueDeclaration;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.resolution.javaparser.declarations.JavaParserSymbolDeclaration;
 
 import java.util.Collections;
@@ -11,9 +11,6 @@
 import java.util.List;
 import java.util.stream.Collectors;
 
-/**
- * Created by federico on 28/07/15.
- */
 public class VariableSymbolDeclarator extends AbstractSymbolDeclarator<VariableDeclarationExpr> {
 
 
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javassist/JavassistClassDeclaration.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javassist/JavassistClassDeclaration.java
index 11c45e2..0add350 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javassist/JavassistClassDeclaration.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javassist/JavassistClassDeclaration.java
@@ -11,7 +11,12 @@
 import me.tomassetti.symbolsolver.logic.MethodResolutionLogic;
 import me.tomassetti.symbolsolver.model.declarations.*;
 import me.tomassetti.symbolsolver.model.invokations.MethodUsage;
+import me.tomassetti.symbolsolver.model.resolution.Context;
+import me.tomassetti.symbolsolver.model.resolution.SymbolReference;
+import me.tomassetti.symbolsolver.model.resolution.TypeParameter;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsage;
+import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsageImpl;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
 import me.tomassetti.symbolsolver.resolution.*;
 import me.tomassetti.symbolsolver.resolution.javaparser.LambdaArgumentTypeUsagePlaceholder;
@@ -42,7 +47,7 @@
 
     @Override
     public boolean isAssignableBy(TypeDeclaration other) {
-        return isAssignableBy(new ReferenceTypeUsage(other, typeSolver));
+        return isAssignableBy(new ReferenceTypeUsageImpl(other, typeSolver));
     }
 
     @Override
@@ -192,7 +197,7 @@
             ancestors.add(getSuperClass());
             ancestors.addAll(getSuperClass().getAllAncestors());
         }
-        ancestors.addAll(getAllInterfaces().stream().map((i) -> new ReferenceTypeUsage(i, typeSolver)).collect(Collectors.<ReferenceTypeUsage>toList()));
+        ancestors.addAll(getAllInterfaces().stream().map((i) -> new ReferenceTypeUsageImpl(i, typeSolver)).collect(Collectors.<ReferenceTypeUsageImpl>toList()));
         return ancestors;
     }
 
@@ -238,7 +243,7 @@
     }
 
     public TypeUsage getUsage(Node node) {
-        return new ReferenceTypeUsage(this, typeSolver);
+        return new ReferenceTypeUsageImpl(this, typeSolver);
     }
 
     @Override
@@ -322,12 +327,12 @@
     }
 
     @Override
-    public ReferenceTypeUsage getSuperClass() {
+    public ReferenceTypeUsageImpl getSuperClass() {
         try {
             if (ctClass.getSuperclass() == null) {
                 throw new UnsupportedOperationException();
             }
-            return new ReferenceTypeUsage(new JavassistClassDeclaration(ctClass.getSuperclass(), typeSolver).asClass(), typeSolver);
+            return new ReferenceTypeUsageImpl(new JavassistClassDeclaration(ctClass.getSuperclass(), typeSolver).asClass(), typeSolver);
         } catch (NotFoundException e) {
             throw new RuntimeException(e);
         }
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javassist/JavassistFactory.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javassist/JavassistFactory.java
index cd6726c..b71f16e 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javassist/JavassistFactory.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javassist/JavassistFactory.java
@@ -4,10 +4,9 @@
 import javassist.NotFoundException;
 import me.tomassetti.symbolsolver.model.typesystem.ArrayTypeUsage;
 import me.tomassetti.symbolsolver.model.typesystem.PrimitiveTypeUsage;
-import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsage;
+import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsageImpl;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
-
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 
 public class JavassistFactory {
 
@@ -18,7 +17,7 @@
             } else if (ctClazz.isPrimitive()) {
                 return PrimitiveTypeUsage.byName(ctClazz.getName());
             } else {
-                return new ReferenceTypeUsage(new JavassistClassDeclaration(ctClazz, typeSolver), typeSolver);
+                return new ReferenceTypeUsageImpl(new JavassistClassDeclaration(ctClazz, typeSolver), typeSolver);
             }
         } catch (NotFoundException e) {
             throw new RuntimeException(e);
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javassist/JavassistFieldDeclaration.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javassist/JavassistFieldDeclaration.java
index 0ad2e92..7a1f46b 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javassist/JavassistFieldDeclaration.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javassist/JavassistFieldDeclaration.java
@@ -3,11 +3,8 @@
 import javassist.CtField;
 import javassist.NotFoundException;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 
-/**
- * Created by federico on 01/08/15.
- */
 public class JavassistFieldDeclaration implements me.tomassetti.symbolsolver.model.declarations.FieldDeclaration {
     private CtField ctField;
     private TypeSolver typeSolver;
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javassist/JavassistMethodDeclaration.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javassist/JavassistMethodDeclaration.java
index 89d003f..6438e24 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javassist/JavassistMethodDeclaration.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javassist/JavassistMethodDeclaration.java
@@ -10,18 +10,15 @@
 import me.tomassetti.symbolsolver.model.declarations.TypeDeclaration;
 import me.tomassetti.symbolsolver.model.invokations.MethodUsage;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
-import me.tomassetti.symbolsolver.resolution.Context;
-import me.tomassetti.symbolsolver.resolution.TypeParameter;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
+import me.tomassetti.symbolsolver.model.resolution.Context;
+import me.tomassetti.symbolsolver.model.resolution.TypeParameter;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import java.util.stream.Collectors;
 
-/**
- * Created by federico on 01/08/15.
- */
 public class JavassistMethodDeclaration implements MethodDeclaration {
     private CtMethod ctMethod;
     private TypeSolver typeSolver;
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javassist/JavassistParameterDeclaration.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javassist/JavassistParameterDeclaration.java
index ba7263d..f5b5414 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javassist/JavassistParameterDeclaration.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javassist/JavassistParameterDeclaration.java
@@ -3,12 +3,8 @@
 import javassist.CtClass;
 import me.tomassetti.symbolsolver.model.declarations.ParameterDeclaration;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 
-
-/**
- * Created by federico on 02/08/15.
- */
 public class JavassistParameterDeclaration implements ParameterDeclaration {
     private CtClass type;
     private TypeSolver typeSolver;
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javassist/JavassistTypeParameter.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javassist/JavassistTypeParameter.java
index f2215e0..55348a6 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javassist/JavassistTypeParameter.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javassist/JavassistTypeParameter.java
@@ -1,15 +1,12 @@
 package me.tomassetti.symbolsolver.resolution.javassist;
 
 import javassist.bytecode.SignatureAttribute;
-import me.tomassetti.symbolsolver.resolution.TypeParameter;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
+import me.tomassetti.symbolsolver.model.resolution.TypeParameter;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 
 import java.util.ArrayList;
 import java.util.List;
 
-/**
- * Created by federico on 05/08/15.
- */
 public class JavassistTypeParameter implements TypeParameter {
 
     private SignatureAttribute.TypeParameter wrapped;
@@ -50,7 +47,7 @@
     }
 
     @Override
-    public List<Bound> getBounds(TypeSolver typeSolver) {
+    public List<TypeParameter.Bound> getBounds(TypeSolver typeSolver) {
         List<Bound> bounds = new ArrayList<>();
         if (wrapped.getClassBound() != null) {
             throw new UnsupportedOperationException(wrapped.getClassBound().toString());
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javassist/contexts/JavassistClassContext.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javassist/contexts/JavassistClassContext.java
index fff116d..a008ff8 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javassist/contexts/JavassistClassContext.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javassist/contexts/JavassistClassContext.java
@@ -7,16 +7,13 @@
 import me.tomassetti.symbolsolver.model.declarations.TypeDeclaration;
 import me.tomassetti.symbolsolver.model.declarations.ValueDeclaration;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
-import me.tomassetti.symbolsolver.resolution.Context;
-import me.tomassetti.symbolsolver.resolution.SymbolReference;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
+import me.tomassetti.symbolsolver.model.resolution.Context;
+import me.tomassetti.symbolsolver.model.resolution.SymbolReference;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 
 import java.util.List;
 import java.util.Optional;
 
-/**
- * Created by fede on 8/14/15.
- */
 public class JavassistClassContext implements Context {
 
     private CtClass wrappedNode;
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javassist/contexts/JavassistMethodContext.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javassist/contexts/JavassistMethodContext.java
index eca07e5..b9e8142 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javassist/contexts/JavassistMethodContext.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/javassist/contexts/JavassistMethodContext.java
@@ -6,16 +6,13 @@
 import me.tomassetti.symbolsolver.model.declarations.TypeDeclaration;
 import me.tomassetti.symbolsolver.model.declarations.ValueDeclaration;
 import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
-import me.tomassetti.symbolsolver.resolution.Context;
-import me.tomassetti.symbolsolver.resolution.SymbolReference;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
+import me.tomassetti.symbolsolver.model.resolution.Context;
+import me.tomassetti.symbolsolver.model.resolution.SymbolReference;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 
 import java.util.List;
 import java.util.Optional;
 
-/**
- * Created by fede on 8/14/15.
- */
 public class JavassistMethodContext implements Context {
 
     private CtMethod wrappedNode;
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/typesolvers/CombinedTypeSolver.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/typesolvers/CombinedTypeSolver.java
index 91527b2..c45a4d3 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/typesolvers/CombinedTypeSolver.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/typesolvers/CombinedTypeSolver.java
@@ -1,8 +1,8 @@
 package me.tomassetti.symbolsolver.resolution.typesolvers;
 
 import me.tomassetti.symbolsolver.model.declarations.TypeDeclaration;
-import me.tomassetti.symbolsolver.resolution.SymbolReference;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
+import me.tomassetti.symbolsolver.model.resolution.SymbolReference;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.resolution.javaparser.UnsolvedSymbolException;
 
 import java.util.ArrayList;
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/typesolvers/DummyTypeSolver.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/typesolvers/DummyTypeSolver.java
index c00d567..8d32b9c 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/typesolvers/DummyTypeSolver.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/typesolvers/DummyTypeSolver.java
@@ -1,8 +1,8 @@
 package me.tomassetti.symbolsolver.resolution.typesolvers;
 
 import me.tomassetti.symbolsolver.model.declarations.TypeDeclaration;
-import me.tomassetti.symbolsolver.resolution.SymbolReference;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
+import me.tomassetti.symbolsolver.model.resolution.SymbolReference;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 
 import java.util.HashMap;
 import java.util.Map;
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/typesolvers/JarTypeSolver.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/typesolvers/JarTypeSolver.java
index 0aeee03..bc646df 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/typesolvers/JarTypeSolver.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/typesolvers/JarTypeSolver.java
@@ -3,8 +3,8 @@
 import javassist.ClassPool;
 import javassist.CtClass;
 import me.tomassetti.symbolsolver.model.declarations.TypeDeclaration;
-import me.tomassetti.symbolsolver.resolution.SymbolReference;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
+import me.tomassetti.symbolsolver.model.resolution.SymbolReference;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.resolution.javaparser.UnsolvedSymbolException;
 import me.tomassetti.symbolsolver.resolution.javassist.JavassistClassDeclaration;
 
@@ -16,9 +16,6 @@
 import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
 
-/**
- * Created by federico on 01/08/15.
- */
 public class JarTypeSolver implements TypeSolver {
 
     private TypeSolver parent;
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/typesolvers/JavaParserTypeSolver.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/typesolvers/JavaParserTypeSolver.java
index 420b60a..4519424 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/typesolvers/JavaParserTypeSolver.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/typesolvers/JavaParserTypeSolver.java
@@ -5,8 +5,8 @@
 import com.github.javaparser.ast.CompilationUnit;
 import me.tomassetti.symbolsolver.javaparser.Navigator;
 import me.tomassetti.symbolsolver.model.declarations.TypeDeclaration;
-import me.tomassetti.symbolsolver.resolution.SymbolReference;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
+import me.tomassetti.symbolsolver.model.resolution.SymbolReference;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.resolution.javaparser.JavaParserFacade;
 
 import java.io.File;
diff --git a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/typesolvers/JreTypeSolver.java b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/typesolvers/JreTypeSolver.java
index 149832f..caad468 100644
--- a/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/typesolvers/JreTypeSolver.java
+++ b/java-symbol-solver-core/src/main/java/me/tomassetti/symbolsolver/resolution/typesolvers/JreTypeSolver.java
@@ -1,8 +1,8 @@
 package me.tomassetti.symbolsolver.resolution.typesolvers;
 
 import me.tomassetti.symbolsolver.model.declarations.TypeDeclaration;
-import me.tomassetti.symbolsolver.resolution.SymbolReference;
-import me.tomassetti.symbolsolver.resolution.TypeSolver;
+import me.tomassetti.symbolsolver.model.resolution.SymbolReference;
+import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
 import me.tomassetti.symbolsolver.reflectionmodel.ReflectionClassDeclaration;
 import me.tomassetti.symbolsolver.reflectionmodel.ReflectionInterfaceDeclaration;