@SuppressWarnings("unchecked")
  public static <T> T coerceOutput(Object object, Class<T> targetClass)
      throws TemplateOutputCastException
  {
    Class<?> objectClass = object.getClass();
    if (objectClass == targetClass)
    {
      return (T) object;
    }
    if (targetClass.isEnum())
    {
      if (objectClass == String.class)
      {
        return (T) stringToEnum(targetClass, (String) object);
      }
      throw new TemplateOutputCastException("Output " + object + " has type " + object.getClass().getName() + ", and cannot be coerced to enum type " + targetClass.getName());
    }

    return coerceCustomOutput(object, targetClass);
  }
@Test
  public static void testCoerceOutputNonNumericNumberCases()
  {
    // Convert Specific Floating point string - NaN to Double
    Object object1 = DataTemplateUtil.coerceOutput(NAN, Double.class);
    assertEquals(object1, Double.NaN);

    // Convert Specific Floating point string - POSITIVE_INFINITY to Double
    Object object2 = DataTemplateUtil.coerceOutput(POSITIVE_INFINITY, Double.class);
    assertEquals(object2, Double.POSITIVE_INFINITY);

    // Convert Specific Floating point string - NEGATIVE_INFINITY to Double
    Object object3 = DataTemplateUtil.coerceOutput(NEGATIVE_INFINITY, Double.class);
    assertEquals(object3, Double.NEGATIVE_INFINITY);

    // Convert Specific Floating point string - NaN to Float
    Object object4 = DataTemplateUtil.coerceOutput(NAN, Float.class);
    assertEquals(object4, Float.NaN);

    // Convert Specific Floating point string - POSITIVE_INFINITY to Float
    Object object5 = DataTemplateUtil.coerceOutput(POSITIVE_INFINITY, Float.class);
    assertEquals(object5, Float.POSITIVE_INFINITY);

    // Convert Specific Floating point string - NEGATIVE_INFINITY to Float
    Object object6 = DataTemplateUtil.coerceOutput(NEGATIVE_INFINITY, Float.class);
    assertEquals(object6, Float.NEGATIVE_INFINITY);
  }