public void apply()
     throws IllegalAccessException, InvocationTargetException, InstantiationException {
   if (type.isEnum()) {
     for (T instance : type.getEnumConstants()) {
       assertThat(
           instance.toString(),
           is(
               type.getCanonicalName().substring(type.getPackage().getName().length() + 1)
                   + "."
                   + ((Enum<?>) instance).name()));
     }
     return;
   }
   for (Constructor<?> constructor : type.getDeclaredConstructors()) {
     if (constructor.isSynthetic() && skipSynthetic) {
       continue;
     }
     constructor.setAccessible(true);
     Class<?>[] parameterTypes = constructor.getParameterTypes();
     Object[] actualArguments = new Object[parameterTypes.length];
     Object[] otherArguments = new Object[parameterTypes.length];
     int index = 0;
     for (Class<?> parameterType : parameterTypes) {
       putInstance(parameterType, actualArguments, otherArguments, index++);
     }
     int testIndex = 0;
     @SuppressWarnings("unchecked")
     T instance = (T) constructor.newInstance(actualArguments);
     assertThat(instance, is(instance));
     assertThat(instance, not(is((Object) null)));
     assertThat(instance, not(is(new Object())));
     Object similarInstance = constructor.newInstance(actualArguments);
     assertThat(instance.hashCode(), is(similarInstance.hashCode()));
     assertThat(instance, is(similarInstance));
     if (skipToString) {
       assertThat(instance.toString(), notNullValue());
     } else if (optionalToStringRegex == null) {
       checkString(instance);
     } else {
       assertThat(instance.toString(), new RegexMatcher(optionalToStringRegex));
     }
     for (Object otherArgument : otherArguments) {
       Object[] compareArguments = new Object[actualArguments.length];
       int argumentIndex = 0;
       for (Object actualArgument : actualArguments) {
         if (argumentIndex == testIndex) {
           compareArguments[argumentIndex] = otherArgument;
         } else {
           compareArguments[argumentIndex] = actualArgument;
         }
         argumentIndex++;
       }
       Object unlikeInstance = constructor.newInstance(compareArguments);
       assertThat(instance.hashCode(), not(is(unlikeInstance)));
       assertThat(instance, not(is(unlikeInstance)));
       testIndex++;
     }
   }
 }
 private void checkString(T instance) {
   assertThat(
       instance.toString(),
       CoreMatchers.startsWith(
           type.getCanonicalName().substring(type.getPackage().getName().length() + 1) + "{"));
   assertThat(instance.toString(), endsWith("}"));
   Class<?> currentType = type;
   do {
     for (Field field : type.getDeclaredFields()) {
       if (!field.isSynthetic()
           && !Modifier.isStatic(field.getModifiers())
           && !ignoredFields.contains(field.getName())) {
         assertThat(instance.toString(), containsString(field.getName()));
       }
     }
   } while ((currentType = currentType.getSuperclass()) != Object.class);
 }
 /**
  * Computes the display string for any value.
  *
  * @param t the value to print
  * @return the formatted string
  */
 public static <T> String print(T t) {
   if (t == null) {
     return "";
   }
   if (conversion.canConvert(t.getClass(), String.class)) {
     return conversion.convert(t, String.class);
   } else {
     return t.toString();
   }
 }
 /**
  * Computes the display string for any value, for a specific type.
  *
  * @param desc the field descriptor - custom formatters are extracted from this descriptor.
  * @param t the value to print
  * @return the formatted string
  */
 public static <T> String print(TypeDescriptor desc, T t) {
   if (t == null) {
     return "";
   }
   if (desc != null && conversion.canConvert(desc, TypeDescriptor.valueOf(String.class))) {
     return (String) conversion.convert(t, desc, TypeDescriptor.valueOf(String.class));
   } else if (conversion.canConvert(t.getClass(), String.class)) {
     return conversion.convert(t, String.class);
   } else {
     return t.toString();
   }
 }