code: private Object specializeInstance(ClassDescriptor specializedClass, Object t) {
      try (Logger l = new Logger("specializeInstance(" + specializedClass.getSpecializedClass().getSimpleName() + " , " + t + ")")) {
        if (!specializedClass.isSpecialized()) {
          l.log("value unchanged");
          return t;
        }
        l.log("Creating new instance");
        Object newInstance = specializedClass.getSpecializedClass().newInstance();
        l.log("setting field values:");
        Class<?> c = t.getClass();
        l.log("from class " + c.getSimpleName() + " to class " + specializedClass.getSpecializedClass().getSimpleName());
        while (c != null && specializedClass != null) {
          for (Field field : c.getDeclaredFields()) {
            field.setAccessible(true);
            Object value = field.get(t);
            FieldDescriptor fieldDescriptor = specializedClass.getFields().get(field.getName());
            if (fieldDescriptor != null && fieldDescriptor.getSpecializedClass().isSpecialized()) {
              value = specializeInstance(fieldDescriptor.getSpecializedClass(), value);
              l.log("- specialized " + newInstance.getClass().getSimpleName() + "." + field.getName() + " = " + value);
            } else {
              l.log("- copied " + newInstance.getClass().getSimpleName() + "." + field.getName() + " = " + value);
            }
            Field newField = newInstance.getClass().getField(field.getName());
            newField.set(newInstance, value);
          }
          c = c.getSuperclass();
          specializedClass = specializedClass.getParent();
        }
        return newInstance;
      } catch (InstantiationException | IllegalAccessException | NoSuchFieldException | SecurityException e) {
        throw new SpecializationException("Could not create instance of the specialized class " + specializedClass.specializedClass.getSimpleName(), e);
      }
    }
docs: creates a specialized copy of the given instance
  @param specializedClass target specialized class to create an instance of
  @param t the object to copy and specialize
  @return the specialized instance. Should be functionally equivalent to t