public void addCastClass(GenericClass clazz, int depth) {
    if (clazz.getRawClass() == null) {
      logger.warn("ADDING NULL!");
      assert (false);
    }
    if (clazz.isAbstract()) {
      for (Class<?> concreteClass :
          ConcreteClassAnalyzer.getConcreteClasses(
              clazz.getRawClass(), TestCluster.getInheritanceTree())) {
        GenericClass c = new GenericClass(concreteClass);
        if (TestUsageChecker.canUse(c.getRawClass())) {
          classMap.put(c, depth);
        }
      }

      if (Properties.P_FUNCTIONAL_MOCKING > 0.0) {
        if (TestUsageChecker.canUse(clazz.getRawClass())) classMap.put(clazz, depth);
      }

    } else {
      if (TestUsageChecker.canUse(clazz.getRawClass())) classMap.put(clazz, depth);
    }
  }
  private boolean addAssignableClass(
      TypeVariable<?> typeVariable, Map<TypeVariable<?>, Type> typeMap) {
    Set<Class<?>> classes = TestCluster.getInstance().getAnalyzedClasses();
    Set<Class<?>> assignableClasses = new LinkedHashSet<Class<?>>();

    for (Class<?> clazz : classes) {
      if (!TestUsageChecker.canUse(clazz)) continue;

      GenericClass genericClass = new GenericClass(clazz).getWithWildcardTypes();

      if (!genericClass.satisfiesBoundaries(typeVariable, typeMap)) {
        logger.debug("Not assignable: " + clazz);
      } else {
        logger.debug("Assignable");
        assignableClasses.add(clazz);
      }
    }
    for (Type t : typeMap.values()) {
      if (t instanceof WildcardType) continue; // TODO: For now.

      Class<?> clazz = GenericTypeReflector.erase(t);
      if (!TestUsageChecker.canUse(GenericTypeReflector.erase(clazz))) continue;

      GenericClass genericClass = new GenericClass(clazz).getWithWildcardTypes();
      if (!genericClass.satisfiesBoundaries(typeVariable, typeMap)) {
        logger.debug("Not assignable: " + clazz);
      } else {
        logger.debug("Assignable");
        assignableClasses.add(clazz);
      }
    }
    /*
    for (Type t : typeVariable.getBounds()) {
    	if (typeMap.containsKey(t))
    		t = typeMap.get(t);

    	Class<?> clazz = GenericTypeReflector.erase(t);
    	logger.debug("Checking bound: " + t);

    	if (!TestClusterGenerator.canUse(clazz))
    		continue;

    	GenericClass genericClass = new GenericClass(t);
    	//if (genericClass.hasTypeVariables()) {
    	logger.debug("Has type variables: " + genericClass
    	        + ", checking wildcard version with type map " + typeMap);
    	GenericClass wildcardClass = genericClass.getWithWildcardTypes();
    	//if (!wildcardClass.satisfiesBoundaries(typeVariable, typeMap)) {
    	//	logger.debug("Not assignable: " + clazz);
    	//} else {
    	//	logger.debug("Assignable");
    	assignableClasses.add(clazz);
    	//}
    	//} else {
    	//	logger.debug("Adding directly: " + genericClass);
    	//	assignableClasses.add(genericClass.getRawClass());
    	//	classMap.put(genericClass, 10);
    	//}
    }
    */
    logger.debug(
        "Found assignable classes for type variable "
            + typeVariable
            + ": "
            + assignableClasses.size());
    if (!assignableClasses.isEmpty()) {
      Class<?> clazz = Randomness.choice(assignableClasses);
      GenericClass castClass = new GenericClass(clazz);
      logger.debug("Adding cast class " + castClass);
      classMap.put(castClass, 10);
      return true;
    } else {
      InheritanceTree inheritanceTree = DependencyAnalysis.getInheritanceTree();
      Set<Class<?>> boundCandidates = new LinkedHashSet<Class<?>>();
      for (Type bound : typeVariable.getBounds()) {
        Class<?> rawBound = GenericTypeReflector.erase(bound);
        boundCandidates.add(rawBound);
        logger.debug("Getting concrete classes for " + rawBound);
        boundCandidates.addAll(ConcreteClassAnalyzer.getConcreteClasses(rawBound, inheritanceTree));
      }
      for (Class<?> clazz : boundCandidates) {
        if (!TestUsageChecker.canUse(clazz)) continue;

        boolean isAssignable = true;
        for (Type bound : typeVariable.getBounds()) {
          if (GenericTypeReflector.erase(bound).equals(Enum.class)) {
            if (clazz.isEnum()) continue;
          }

          if (!GenericClass.isAssignable(bound, clazz)) {
            isAssignable = false;
            logger.debug("Not assignable: " + clazz + " to bound " + bound);
            break;
          }
          if (bound instanceof ParameterizedType) {
            if (Arrays.asList(((ParameterizedType) bound).getActualTypeArguments())
                .contains(typeVariable)) {
              isAssignable = false;
              break;
            }
          }
        }
        if (isAssignable) {
          assignableClasses.add(clazz);
        }
      }
      logger.debug(
          "After adding bounds, found "
              + assignableClasses.size()
              + " assignable classes for type variable "
              + typeVariable
              + ": "
              + assignableClasses);
      if (!assignableClasses.isEmpty()) {
        // TODO: Add all classes?
        //				for(Class<?> clazz : assignableClasses) {
        //					GenericClass castClass = new GenericClass(clazz);
        //					logger.debug("Adding cast class " + castClass);
        //					classMap.put(castClass, 10);
        //				}
        Class<?> clazz = Randomness.choice(assignableClasses);
        GenericClass castClass = new GenericClass(clazz);
        logger.debug("Adding cast class " + castClass);
        classMap.put(castClass, 10);
        return true;
      }
    }

    return false;
  }