SLING-8558 - ValueMapDecorator should allow getting ZonedDateTime values

- fix test case, conversions should not assume GregorianCalendar
diff --git a/src/test/java/org/apache/sling/api/wrappers/impl/Convert.java b/src/test/java/org/apache/sling/api/wrappers/impl/Convert.java
index f2a9b92..9507352 100644
--- a/src/test/java/org/apache/sling/api/wrappers/impl/Convert.java
+++ b/src/test/java/org/apache/sling/api/wrappers/impl/Convert.java
@@ -18,6 +18,8 @@
  */
 package org.apache.sling.api.wrappers.impl;
 
+import org.apache.commons.lang3.ClassUtils;
+
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
@@ -25,8 +27,7 @@
 import java.lang.reflect.Array;
 import java.util.Calendar;
 import java.util.Date;
-
-import org.apache.commons.lang3.ClassUtils;
+import java.util.GregorianCalendar;
 
 /**
  * Tests all permutations of object conversions between single values and array types, and null handling.
@@ -36,80 +37,60 @@
     private Convert() {
         // static methods only
     }
-    
-    @SuppressWarnings("unchecked")
-    public static class ConversionAssert<T,U> {
+
+    public static class ConversionInput<T> {
+
         private final T input1;
+
         private final T input2;
-        private Class<T> inputType;
-        private U expected1;
-        private U expected2;
-        private U nullValue;
-        private Class<U> expectedType;
-        
-        private ConversionAssert(T input1, T input2, boolean inputTypePrimitive) {
+
+        private final Class<? super T> inputType;
+
+        private ConversionInput(T input1, T input2, Class<? super T> inputType) {
             this.input1 = input1;
             this.input2 = input2;
-            this.inputType = (Class<T>)input1.getClass();
-            if (inputTypePrimitive) {
-                this.inputType = (Class<T>)ClassUtils.wrapperToPrimitive(this.inputType);
-            }
-        }
-        
-        private void expected(U expected1, U expected2, boolean expectedTypePrimitive) {
-            this.expected1 = expected1;
-            this.expected2 = expected2;
-            this.expectedType = (Class<U>)expected1.getClass();
-            if (expectedTypePrimitive) {
-                expectedType = (Class<U>)ClassUtils.wrapperToPrimitive(this.expectedType);
-            }
-        }
-        
-        /**
-         * @param expected1 Singleton or first array expected result value
-         * @param expected2 Second array expected result value
-         * @return this
-         */
-        public ConversionAssert<T,U> to(U expected1, U expected2) {
-            expected(expected1, expected2, false);
-            return this;
+            this.inputType = inputType;
         }
 
         /**
          * @param expected1 Singleton or first array expected result value
          * @param expected2 Second array expected result value
+         * @param expectedType The (super)class or interface used for the conversion.
          * @return this
          */
-        public ConversionAssert<T,U> toPrimitive(U expected1, U expected2) {
-            expected(expected1, expected2, true);
-            return this;
+        public <U> ConversionAssert<T, U> to(U expected1, U expected2, Class<? super U> expectedType) {
+            return new ConversionAssert<T, U>(input1, input2, inputType, expected1, expected2, expectedType);
         }
-        
-        /**
-         * @param expected1 Singleton or first array expected result value
-         * @param expected2 Second array expected result value
-         * @return this
-         */
-        public ConversionAssert<T,U> toNull(Class<U> expectedType) {
-            expected1 = null;
-            expected2 = null;
+    }
+    
+    @SuppressWarnings("unchecked")
+    public static class ConversionAssert<T,U> {
+
+        private final T input1;
+        private final T input2;
+        private final Class<? super T> inputType;
+
+        private final U expected1;
+        private final U expected2;
+        private final Class<? super U> expectedType;
+        private final U nullValue;
+
+        private ConversionAssert(T input1, T input2, Class<? super T> inputType, U expected1, U expected2, Class<? super U> expectedType) {
+            this.input1 = input1;
+            this.input2 = input2;
+            this.inputType = inputType;
+
+            this.expected1 = expected1;
+            this.expected2 = expected2;
             this.expectedType = expectedType;
-            return this;
+            this.nullValue = null;
         }
-        
-        /**
-         * @param nullValue Result value in case of null
-         */
-        public ConversionAssert<T,U> nullValue(U nullValue) {
-            this.nullValue = nullValue;
-            return this;
-        }
-        
+
         /**
          * Do assertion
          */
         public void test() {
-            Class<U[]> expectedArrayType = (Class<U[]>)Array.newInstance(this.expectedType, 0).getClass();
+            Class<? super U[]> expectedArrayType = (Class<? super U[]>)Array.newInstance(this.expectedType, 0).getClass();
             assertPermuations(input1, input2, inputType, expected1, expected2, nullValue, expectedType, expectedArrayType);
         }
     }
@@ -118,20 +99,12 @@
      * @param input1 Singleton or first array input value
      * @param input2 Second array input value
      */
-    public static <T,U> ConversionAssert<T,U> from(T input1, T input2) {
-        return new ConversionAssert<T,U>(input1, input2, false);
+    public static <T> ConversionInput<T> from(T input1, T input2, Class<? super T> inputType) {
+        return new ConversionInput<>(input1, input2, inputType);
     }
 
-    /**
-     * @param input1 Singleton or first array input value
-     * @param input2 Second array input value
-     */
-    public static <T,U> ConversionAssert<T,U> fromPrimitive(T input1, T input2) {
-        return new ConversionAssert<T,U>(input1, input2, true);
-    }
-
-    private static <T,U> void assertPermuations(T input1, T input2, Class<T> inputType,
-            U expected1, U expected2, U nullValue, Class<U> expectedType, Class<U[]> expectedArrayType) {
+    private static <T, U> void assertPermuations(T input1, T input2, Class<? super T> inputType,
+            U expected1, U expected2, U nullValue, Class<? super U> expectedType, Class<? super U[]> expectedArrayType) {
         
         // single value to single value
         assertConversion(expected1, input1, expectedType);
@@ -181,14 +154,14 @@
     }
     
     @SuppressWarnings("unchecked")
-    private static <T,U> void assertConversion(Object expected, Object input, Class<U> type) {
-        U result = ObjectConverter.convert(input, type);
-        String msg = "Convert '" + toString(input) + "' to " + type.getSimpleName();
+    private static <T,U> void assertConversion(Object expected, Object input, Class<U> expectedType) {
+        U result = ObjectConverter.convert(input, expectedType);
+        String msg = "Convert '" + toString(input) + "' to " + expectedType.getSimpleName();
         if (expected == null) {
             assertNull(msg, result);
         }
-        else if (expected.getClass().isArray()) {
-            assertArrayEquals(msg, (U[])toStringIfDate(expected), (U[])toStringIfDate(result));
+        else if (expectedType.isArray() && !expectedType.getComponentType().isPrimitive()) {
+            assertArrayEquals(msg, toStringIfDate((Object[]) expected), toStringIfDate((Object[]) result));
         }
         else {
             assertEquals(msg, toStringIfDate(expected), toStringIfDate(result));
@@ -212,31 +185,30 @@
             return sb.toString();
         }
         else {
-            return toStringIfDate(input).toString();
+            return toStringIfDate(input);
         }
     }
     
-    private static Object toStringIfDate(Object input) {
-        if (input == null) {
-            return null;
-        }
+    private static String toStringIfDate(Object input) {
         if (input instanceof Calendar) {
             return "(Calendar)" + ((Calendar)input).getTime().toInstant().toString();
         }
         if (input instanceof Date) {
             return "(Date)" + ((Date)input).toInstant().toString();
         }
-        if (input.getClass().isArray()) {
-            if (Calendar.class.isAssignableFrom(input.getClass().getComponentType())
-                    || input.getClass().getComponentType() == Date.class) {
-                Object[] resultArray = new String[Array.getLength(input)];
-                for (int i=0; i<Array.getLength(input); i++) {
-                    resultArray[i] = toStringIfDate(Array.get(input, i));
-                }
-                return resultArray;
+        return null;
+    }
+
+    private static String[] toStringIfDate(Object[] input) {
+        if (Calendar.class.isAssignableFrom(input.getClass().getComponentType())
+                || input.getClass().getComponentType() == Date.class) {
+            String[] resultArray = new String[Array.getLength(input)];
+            for (int i=0; i<Array.getLength(input); i++) {
+                resultArray[i] = toStringIfDate(Array.get(input, i));
             }
+            return resultArray;
         }
-        return input;
+        return null;
     }
         
 }
diff --git a/src/test/java/org/apache/sling/api/wrappers/impl/ObjectConverterTest.java b/src/test/java/org/apache/sling/api/wrappers/impl/ObjectConverterTest.java
index a7493fc..7eab819 100644
--- a/src/test/java/org/apache/sling/api/wrappers/impl/ObjectConverterTest.java
+++ b/src/test/java/org/apache/sling/api/wrappers/impl/ObjectConverterTest.java
@@ -60,24 +60,24 @@
 
     @Test
     public void testDateToString() {
-        Convert.from(STRING_1, STRING_2).to(STRING_1, STRING_2).test();
-        Convert.fromPrimitive(BOOLEAN_1, BOOLEAN_2).to(Boolean.toString(BOOLEAN_1), Boolean.toString(BOOLEAN_2)).test();
-        Convert.from(BOOLEAN_1, BOOLEAN_2).to(Boolean.toString(BOOLEAN_1), Boolean.toString(BOOLEAN_2)).test();
-        Convert.fromPrimitive(BYTE_1, BYTE_2).to(Byte.toString(BYTE_1), Byte.toString(BYTE_2)).test();
-        Convert.from(BYTE_1, BYTE_2).to(Byte.toString(BYTE_1), Byte.toString(BYTE_2)).test();
-        Convert.fromPrimitive(SHORT_1, SHORT_2).to(Short.toString(SHORT_1), Short.toString(SHORT_2)).test();
-        Convert.from(SHORT_1, SHORT_2).to(Short.toString(SHORT_1), Short.toString(SHORT_2)).test();
-        Convert.fromPrimitive(INT_1, INT_2).to(Integer.toString(INT_1), Integer.toString(INT_2)).test();
-        Convert.from(INT_1, INT_2).to(Integer.toString(INT_1), Integer.toString(INT_2)).test();
-        Convert.fromPrimitive(LONG_1, LONG_2).to(Long.toString(LONG_1), Long.toString(LONG_2)).test();
-        Convert.from(LONG_1, LONG_2).to(Long.toString(LONG_1), Long.toString(LONG_2)).test();
-        Convert.fromPrimitive(FLOAT_1, FLOAT_2).to(Float.toString(FLOAT_1), Float.toString(FLOAT_2)).test();
-        Convert.from(FLOAT_1, FLOAT_2).to(Float.toString(FLOAT_1), Float.toString(FLOAT_2)).test();
-        Convert.fromPrimitive(DOUBLE_1, DOUBLE_2).to(Double.toString(DOUBLE_1), Double.toString(DOUBLE_2)).test();
-        Convert.from(DOUBLE_1, DOUBLE_2).to(Double.toString(DOUBLE_1), Double.toString(DOUBLE_2)).test();
-        Convert.from(BIGDECIMAL_1, BIGDECIMAL_2).to(BIGDECIMAL_1.toString(), BIGDECIMAL_2.toString()).test();
-        Convert.from(CALENDAR_1, CALENDAR_2).to(calendarToString(CALENDAR_1), calendarToString(CALENDAR_2)).test();
-        Convert.from(DATE_1, DATE_2).to(calendarToString(toCalendar(DATE_1)), calendarToString(toCalendar(DATE_2))).test();
+        Convert.from(STRING_1, STRING_2, String.class).to(STRING_1, STRING_2, String.class).test();
+        Convert.from(BOOLEAN_1, BOOLEAN_2, boolean.class).to(Boolean.toString(BOOLEAN_1), Boolean.toString(BOOLEAN_2), String.class).test();
+        Convert.from(BOOLEAN_1, BOOLEAN_2, Boolean.class).to(Boolean.toString(BOOLEAN_1), Boolean.toString(BOOLEAN_2), String.class).test();
+        Convert.from(BYTE_1, BYTE_2, byte.class).to(Byte.toString(BYTE_1), Byte.toString(BYTE_2), String.class).test();
+        Convert.from(BYTE_1, BYTE_2, Byte.class).to(Byte.toString(BYTE_1), Byte.toString(BYTE_2), String.class).test();
+        Convert.from(SHORT_1, SHORT_2, short.class).to(Short.toString(SHORT_1), Short.toString(SHORT_2), String.class).test();
+        Convert.from(SHORT_1, SHORT_2, Short.class).to(Short.toString(SHORT_1), Short.toString(SHORT_2), String.class).test();
+        Convert.from(INT_1, INT_2, int.class).to(Integer.toString(INT_1), Integer.toString(INT_2), String.class).test();
+        Convert.from(INT_1, INT_2, Integer.class).to(Integer.toString(INT_1), Integer.toString(INT_2), String.class).test();
+        Convert.from(LONG_1, LONG_2, long.class).to(Long.toString(LONG_1), Long.toString(LONG_2), String.class).test();
+        Convert.from(LONG_1, LONG_2, Long.class).to(Long.toString(LONG_1), Long.toString(LONG_2), String.class).test();
+        Convert.from(FLOAT_1, FLOAT_2, float.class).to(Float.toString(FLOAT_1), Float.toString(FLOAT_2), String.class).test();
+        Convert.from(FLOAT_1, FLOAT_2, float.class).to(Float.toString(FLOAT_1), Float.toString(FLOAT_2), String.class).test();
+        Convert.from(DOUBLE_1, DOUBLE_2, double.class).to(Double.toString(DOUBLE_1), Double.toString(DOUBLE_2), String.class).test();
+        Convert.from(DOUBLE_1, DOUBLE_2, Double.class).to(Double.toString(DOUBLE_1), Double.toString(DOUBLE_2), String.class).test();
+        Convert.from(BIGDECIMAL_1, BIGDECIMAL_2, BigDecimal.class).to(BIGDECIMAL_1.toString(), BIGDECIMAL_2.toString(), String.class).test();
+        Convert.from(CALENDAR_1, CALENDAR_2, Calendar.class).to(calendarToString(CALENDAR_1), calendarToString(CALENDAR_2), String.class).test();
+        Convert.from(DATE_1, DATE_2, Date.class).to(calendarToString(toCalendar(DATE_1)), calendarToString(toCalendar(DATE_2)), String.class).test();
     }
     
     private String calendarToString(Calendar calendar) {
@@ -92,144 +92,144 @@
 
     @Test
     public void testToBoolean() {
-        Convert.fromPrimitive(BOOLEAN_1, BOOLEAN_2).to(BOOLEAN_1, BOOLEAN_2).test();
-        Convert.from(BOOLEAN_1, BOOLEAN_2).to(BOOLEAN_1, BOOLEAN_2).test();
-        Convert.from(Boolean.toString(BOOLEAN_1), Boolean.toString(BOOLEAN_2)).to(BOOLEAN_1, BOOLEAN_2).test();
-        Convert.<Integer,Boolean>from(INT_1, INT_2).to(true,true).test();
-        Convert.<Integer,Boolean>from(1, 0).to(true,false).test();
-        Convert.<Date,Boolean>from(DATE_1, DATE_2).to(false,false).test();
+        Convert.from(BOOLEAN_1, BOOLEAN_2, boolean.class).to(BOOLEAN_1, BOOLEAN_2, Boolean.class).test();
+        Convert.from(BOOLEAN_1, BOOLEAN_2, Boolean.class).to(BOOLEAN_1, BOOLEAN_2, Boolean.class).test();
+        Convert.from(Boolean.toString(BOOLEAN_1), Boolean.toString(BOOLEAN_2), String.class).to(BOOLEAN_1, BOOLEAN_2, Boolean.class).test();
+        Convert.from(INT_1, INT_2, int.class).to(true, true, boolean.class).test();
+        Convert.from(1, 0, int.class).to(true, false, boolean.class).test();
+        Convert.from(DATE_1, DATE_2, Date.class).to(false, false, boolean.class).test();
     }
     
     @Test
     public void testToByte() {
-        Convert.fromPrimitive(BYTE_1, BYTE_2).to(BYTE_1, BYTE_2).test();
-        Convert.from(BYTE_1, BYTE_2).to(BYTE_1, BYTE_2).test();
-        Convert.from(Byte.toString(BYTE_1), Byte.toString(BYTE_2)).to(BYTE_1, BYTE_2).test();
+        Convert.from(BYTE_1, BYTE_2, byte.class).to(BYTE_1, BYTE_2, Byte.class).test();
+        Convert.from(BYTE_1, BYTE_2, Byte.class).to(BYTE_1, BYTE_2, Byte.class).test();
+        Convert.from(Byte.toString(BYTE_1), Byte.toString(BYTE_2), String.class).to(BYTE_1, BYTE_2, byte.class).test();
         
         // test conversion from other number types
-        Convert.from(INT_1, INT_2).to((byte)INT_1, (byte)INT_2).test();
-        Convert.fromPrimitive(INT_1, INT_2).to((byte)INT_1, (byte)INT_2).test();
+        Convert.from(INT_1, INT_2, Integer.class).to((byte)INT_1, (byte)INT_2, byte.class).test();
+        Convert.from(INT_1, INT_2, int.class).to((byte)INT_1, (byte)INT_2, Byte.class).test();
 
         // test other types that should not be converted
-        Convert.<Date,Byte>from(DATE_1, DATE_2).toNull(Byte.class).test();
+        Convert.from(DATE_1, DATE_2, Date.class).to(null, null, Byte.class).test();
     }
     
     @Test
     public void testToShort() {
-        Convert.fromPrimitive(SHORT_1, SHORT_2).to(SHORT_1, SHORT_2).test();
-        Convert.from(SHORT_1, SHORT_2).to(SHORT_1, SHORT_2).test();
-        Convert.from(Short.toString(SHORT_1), Short.toString(SHORT_2)).to(SHORT_1, SHORT_2).test();
+        Convert.from(SHORT_1, SHORT_2, short.class).to(SHORT_1, SHORT_2, Short.class).test();
+        Convert.from(SHORT_1, SHORT_2, Short.class).to(SHORT_1, SHORT_2, short.class).test();
+        Convert.from(Short.toString(SHORT_1), Short.toString(SHORT_2), String.class).to(SHORT_1, SHORT_2, short.class).test();
         
         // test conversion from other number types
-        Convert.from(INT_1, INT_2).to((short)INT_1, (short)INT_2).test();
-        Convert.fromPrimitive(INT_1, INT_2).to((short)INT_1, (short)INT_2).test();
+        Convert.from(INT_1, INT_2, Integer.class).to((short)INT_1, (short)INT_2, short.class).test();
+        Convert.from(INT_1, INT_2, int.class).to((short)INT_1, (short)INT_2, Short.class).test();
 
         // test other types that should not be converted
-        Convert.<Date,Short>from(DATE_1, DATE_2).toNull(Short.class).test();
+        Convert.from(DATE_1, DATE_2, Date.class).to(null, null, Short.class).test();
     }
     
     @Test
     public void testToInteger() {
-        Convert.fromPrimitive(INT_1, INT_2).to(INT_1, INT_2).test();
-        Convert.from(INT_1, INT_2).to(INT_1, INT_2).test();
-        Convert.from(Integer.toString(INT_1), Integer.toString(INT_2)).to(INT_1, INT_2).test();
+        Convert.from(INT_1, INT_2, int.class).to(INT_1, INT_2, int.class).test();
+        Convert.from(INT_1, INT_2, Integer.class).to(INT_1, INT_2, int.class).test();
+        Convert.from(Integer.toString(INT_1), Integer.toString(INT_2), String.class).to(INT_1, INT_2, int.class).test();
         
         // test conversion from other number types
-        Convert.from(SHORT_1, SHORT_2).to((int)SHORT_1, (int)SHORT_2).test();
-        Convert.fromPrimitive(SHORT_1, SHORT_2).to((int)SHORT_1, (int)SHORT_2).test();
+        Convert.from(SHORT_1, SHORT_2, Short.class).to((int)SHORT_1, (int)SHORT_2, Integer.class).test();
+        Convert.from(SHORT_1, SHORT_2, short.class).to((int)SHORT_1, (int)SHORT_2, int.class).test();
 
         // test other types that should not be converted
-        Convert.<Date,Integer>from(DATE_1, DATE_2).toNull(Integer.class).test();
+        Convert.from(DATE_1, DATE_2, Date.class).to(null, null, Integer.class).test();
     }
     
     @Test
     public void testToLong() {
-        Convert.fromPrimitive(LONG_1, LONG_2).to(LONG_1, LONG_2).test();
-        Convert.from(LONG_1, LONG_2).to(LONG_1, LONG_2).test();
-        Convert.from(Long.toString(LONG_1), Long.toString(LONG_2)).to(LONG_1, LONG_2).test();
+        Convert.from(LONG_1, LONG_2, long.class).to(LONG_1, LONG_2, long.class).test();
+        Convert.from(LONG_1, LONG_2, Long.class).to(LONG_1, LONG_2, Long.class).test();
+        Convert.from(Long.toString(LONG_1), Long.toString(LONG_2), String.class).to(LONG_1, LONG_2, long.class).test();
         
         // test conversion from other number types
-        Convert.from(SHORT_1, SHORT_2).to((long)SHORT_1, (long)SHORT_2).test();
-        Convert.fromPrimitive(SHORT_1, SHORT_2).to((long)SHORT_1, (long)SHORT_2).test();
+        Convert.from(SHORT_1, SHORT_2, Short.class).to((long)SHORT_1, (long)SHORT_2, long.class).test();
+        Convert.from(SHORT_1, SHORT_2, short.class).to((long)SHORT_1, (long)SHORT_2, Long.class).test();
 
         // test conversion from DATE to LONG
-        Convert.<Date,Long>from(DATE_1, DATE_2).to(DATE_1.getTime(), DATE_2.getTime()).test();
+        Convert.from(DATE_1, DATE_2, Date.class).to(DATE_1.getTime(), DATE_2.getTime(), long.class).test();
     }
     
     @Test
     public void testToFloat() {
-        Convert.fromPrimitive(FLOAT_1, FLOAT_2).to(FLOAT_1, FLOAT_2).test();
-        Convert.from(FLOAT_1, FLOAT_2).to(FLOAT_1, FLOAT_2).test();
-        Convert.from(Float.toString(FLOAT_1), Float.toString(FLOAT_2)).to(FLOAT_1, FLOAT_2).test();
+        Convert.from(FLOAT_1, FLOAT_2, float.class).to(FLOAT_1, FLOAT_2, float.class).test();
+        Convert.from(FLOAT_1, FLOAT_2, Float.class).to(FLOAT_1, FLOAT_2, float.class).test();
+        Convert.from(Float.toString(FLOAT_1), Float.toString(FLOAT_2), String.class).to(FLOAT_1, FLOAT_2, float.class).test();
         
         // test conversion from other number types
-        Convert.from(SHORT_1, SHORT_2).to((float)SHORT_1, (float)SHORT_2).test();
-        Convert.fromPrimitive(SHORT_1, SHORT_2).to((float)SHORT_1, (float)SHORT_2).test();
+        Convert.from(SHORT_1, SHORT_2, Short.class).to((float)SHORT_1, (float)SHORT_2, Float.class).test();
+        Convert.from(SHORT_1, SHORT_2, short.class).to((float)SHORT_1, (float)SHORT_2, float.class).test();
 
         // test other types that should not be converted
-        Convert.<Date,Float>from(DATE_1, DATE_2).toNull(Float.class).test();
+        Convert.from(DATE_1, DATE_2, Date.class).to(null, null, Float.class).test();
     }
     
     @Test
     public void testToDouble() {
-        Convert.fromPrimitive(DOUBLE_1, DOUBLE_2).to(DOUBLE_1, DOUBLE_2).test();
-        Convert.from(DOUBLE_1, DOUBLE_2).to(DOUBLE_1, DOUBLE_2).test();
-        Convert.from(Double.toString(DOUBLE_1), Double.toString(DOUBLE_2)).to(DOUBLE_1, DOUBLE_2).test();
+        Convert.from(DOUBLE_1, DOUBLE_2, double.class).to(DOUBLE_1, DOUBLE_2, double.class).test();
+        Convert.from(DOUBLE_1, DOUBLE_2, Double.class).to(DOUBLE_1, DOUBLE_2, Double.class).test();
+        Convert.from(Double.toString(DOUBLE_1), Double.toString(DOUBLE_2), String.class).to(DOUBLE_1, DOUBLE_2, double.class).test();
         
         // test conversion from other number types
-        Convert.from(SHORT_1, SHORT_2).to((double)SHORT_1, (double)SHORT_2).test();
-        Convert.fromPrimitive(SHORT_1, SHORT_2).to((double)SHORT_1, (double)SHORT_2).test();
+        Convert.from(SHORT_1, SHORT_2, Short.class).to((double)SHORT_1, (double)SHORT_2, Double.class).test();
+        Convert.from(SHORT_1, SHORT_2, short.class).to((double)SHORT_1, (double)SHORT_2, double.class).test();
 
         // test other types that should not be converted
-        Convert.<Date,Double>from(DATE_1, DATE_2).toNull(Double.class).test();
+        Convert.from(DATE_1, DATE_2, Date.class).to(null, null, Double.class).test();
     }
     
     @Test
     public void testToBigDecimal() {
-        Convert.from(BIGDECIMAL_1, BIGDECIMAL_2).to(BIGDECIMAL_1, BIGDECIMAL_2).test();
-        Convert.from(BIGDECIMAL_1.toString(), BIGDECIMAL_2.toString()).to(BIGDECIMAL_1, BIGDECIMAL_2).test();
+        Convert.from(BIGDECIMAL_1, BIGDECIMAL_2, BigDecimal.class).to(BIGDECIMAL_1, BIGDECIMAL_2, BigDecimal.class).test();
+        Convert.from(BIGDECIMAL_1.toString(), BIGDECIMAL_2.toString(), String.class).to(BIGDECIMAL_1, BIGDECIMAL_2, BigDecimal.class).test();
         
         // test conversion from other number types
-        Convert.from(LONG_1, LONG_2).to(BigDecimal.valueOf(LONG_1), BigDecimal.valueOf(LONG_2)).test();
-        Convert.fromPrimitive(LONG_1, LONG_2).to(BigDecimal.valueOf(LONG_1), BigDecimal.valueOf(LONG_2)).test();
-        Convert.from(DOUBLE_1, DOUBLE_2).to(BigDecimal.valueOf(DOUBLE_1), BigDecimal.valueOf(DOUBLE_2)).test();
-        Convert.fromPrimitive(DOUBLE_1, DOUBLE_2).to(BigDecimal.valueOf(DOUBLE_1), BigDecimal.valueOf(DOUBLE_2)).test();
+        Convert.from(LONG_1, LONG_2, Long.class).to(BigDecimal.valueOf(LONG_1), BigDecimal.valueOf(LONG_2), BigDecimal.class).test();
+        Convert.from(LONG_1, LONG_2, Long.class).to(BigDecimal.valueOf(LONG_1), BigDecimal.valueOf(LONG_2), BigDecimal.class).test();
+        Convert.from(DOUBLE_1, DOUBLE_2, Double.class).to(BigDecimal.valueOf(DOUBLE_1), BigDecimal.valueOf(DOUBLE_2), BigDecimal.class).test();
+        Convert.from(DOUBLE_1, DOUBLE_2, double.class).to(BigDecimal.valueOf(DOUBLE_1), BigDecimal.valueOf(DOUBLE_2), BigDecimal.class).test();
 
         // test other types that should not be converted
-        Convert.<Date,BigDecimal>from(DATE_1, DATE_2).toNull(BigDecimal.class).test();
+        Convert.from(DATE_1, DATE_2, Date.class).to(null, null, BigDecimal.class).test();
     }
     
     @Test
     public void testToCalendar() {
-        Convert.from(CALENDAR_1, CALENDAR_2).to(CALENDAR_1, CALENDAR_2).test();
-        Convert.from(calendarToString(CALENDAR_1), calendarToString(CALENDAR_2)).to(CALENDAR_1, CALENDAR_2).test();
+        Convert.from(CALENDAR_1, CALENDAR_2, Calendar.class).to(CALENDAR_1, CALENDAR_2, Calendar.class).test();
+        Convert.from(calendarToString(CALENDAR_1), calendarToString(CALENDAR_2), String.class).to(CALENDAR_1, CALENDAR_2, Calendar.class).test();
         
         // test conversion from other date types
-        Convert.from(DATE_1, DATE_2).to(toCalendar(DATE_1), toCalendar(DATE_2)).test();
+        Convert.from(DATE_1, DATE_2, Date.class).to(toCalendar(DATE_1), toCalendar(DATE_2), Calendar.class).test();
 
         // test other types that should not be converted
-        Convert.<String,Calendar>from(STRING_1, STRING_2).toNull(Calendar.class).test();
-        Convert.<Boolean,Calendar>from(BOOLEAN_1, BOOLEAN_2).toNull(Calendar.class).test();
+        Convert.from(STRING_1, STRING_2, String.class).to(null, null, Calendar.class).test();
+        Convert.from(BOOLEAN_1, BOOLEAN_2, Boolean.class).to(null, null, Calendar.class).test();
     }
     
     @Test
     public void testToDate() {
-        Convert.from(DATE_1, DATE_2).to(DATE_1, DATE_2).test();
-        Convert.from(dateToString(DATE_1), dateToString(DATE_2)).to(DATE_1, DATE_2).test();
+        Convert.from(DATE_1, DATE_2, Date.class).to(DATE_1, DATE_2, Date.class).test();
+        Convert.from(dateToString(DATE_1), dateToString(DATE_2), String.class).to(DATE_1, DATE_2, Date.class).test();
         
         // test conversion from other date types
-        Convert.from(CALENDAR_1, CALENDAR_2).to(toDate(CALENDAR_1), toDate(CALENDAR_2)).test();
+        Convert.from(CALENDAR_1, CALENDAR_2, Calendar.class).to(toDate(CALENDAR_1), toDate(CALENDAR_2), Date.class).test();
 
         // test other types that should not be converted
-        Convert.<String,Date>from(STRING_1, STRING_2).toNull(Date.class).test();
-        Convert.<Boolean,Date>from(BOOLEAN_1, BOOLEAN_2).toNull(Date.class).test();
+        Convert.from(STRING_1, STRING_2, String.class).to(null, null, Date.class).test();
+        Convert.from(BOOLEAN_1, BOOLEAN_2, Boolean.class).to(null, null, Date.class).test();
     }
     
-    private Object toDate(Calendar calendar1) {
+    private Date toDate(Calendar calendar1) {
         return calendar1.getTime();
     }
 
-    private Object dateToString(Date date1) {
+    private String dateToString(Date date1) {
         return date1.toInstant().toString();
     }