/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.osgi.util.converter;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.osgi.framework.Version;
import org.osgi.util.converter.MyDTO.Count;
import org.osgi.util.converter.MyEmbeddedDTO.Alpha;

import java.lang.reflect.Array;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Deque;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.NavigableMap;
import java.util.NavigableSet;
import java.util.Queue;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TimeZone;
import java.util.UUID;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentNavigableMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

public class ConverterTest {
    private Converter converter;

    @Before
    public void setUp() {
        converter = Converters.standardConverter();
    }

    @After
    public void tearDown() {
        converter = null;
    }

    @Test
    public void testVersion() {
        Version v =new Version(1,2,3,"qualifier");
        Converter c = Converters.standardConverter();
        String s = c.convert(v).to(String.class);
        Version v2 = c.convert(s).to(Version.class);
        assertEquals(v, v2);
    }

    @Test
    public void testSimpleConversions() {
        // Conversions to String
        assertEquals("abc", converter.convert("abc").to(String.class));
        assertEquals("true", converter.convert(Boolean.TRUE).to(String.class));
        assertEquals("c", converter.convert('c').to(String.class));
        assertEquals("123", converter.convert(123).to(String.class));
        assertEquals("" + Long.MAX_VALUE, converter.convert(Long.MAX_VALUE).to(String.class));
        assertEquals("12.3", converter.convert(12.3f).to(String.class));
        assertEquals("12.345", converter.convert(12.345d).to(String.class));
        assertNull(converter.convert(null).to(String.class));
        assertNull(converter.convert(Collections.emptyList()).to(String.class));

        String bistr = "999999999999999999999"; // more than Long.MAX_VALUE
        assertEquals(bistr, converter.convert(new BigInteger(bistr)).to(String.class));

        // Conversions to boolean
        assertTrue(converter.convert("true").to(boolean.class));
        assertTrue(converter.convert("TRUE").to(boolean.class));
        assertTrue(converter.convert('x').to(boolean.class));
        assertTrue(converter.convert(Long.MIN_VALUE).to(boolean.class));
        assertTrue(converter.convert(72).to(boolean.class));
        assertFalse(converter.convert("false").to(boolean.class));
        assertFalse(converter.convert("bleh").to(boolean.class));
        assertFalse(converter.convert((char) 0).to(boolean.class));
        assertFalse(converter.convert(null).to(boolean.class));
        assertFalse(converter.convert(Collections.emptyList()).to(boolean.class));

        // Conversions to integer
        assertEquals(Integer.valueOf(123), converter.convert("123").to(int.class));
        assertEquals(1, (int) converter.convert(true).to(int.class));
        assertEquals(0, (int) converter.convert(false).to(int.class));
        assertEquals(65, (int) converter.convert('A').to(int.class));

        // Conversions to long
        assertEquals(Long.valueOf(65), converter.convert('A').to(Long.class));

        // Conversions to Class
        assertEquals(BigDecimal.class, converter.convert("java.math.BigDecimal").to(Class.class));
        assertEquals(BigDecimal.class, converter.convert("java.math.BigDecimal").to(new TypeReference<Class<?>>() {}));
        assertNull(converter.convert(null).to(Class.class));
        assertNull(converter.convert(Collections.emptyList()).to(Class.class));

        assertEquals(Integer.valueOf(123), converter.convert("123").to(Integer.class));
        assertEquals(Long.valueOf(123), converter.convert("123").to(Long.class));
        assertEquals('1', (char) converter.convert("123").to(Character.class));
        assertEquals('Q', (char) converter.convert(null).defaultValue('Q').to(Character.class));
        assertEquals((char) 123, (char) converter.convert(123L).to(Character.class));
        assertEquals((char) 123, (char) converter.convert(123).to(Character.class));
        assertEquals(Byte.valueOf((byte) 123), converter.convert("123").to(Byte.class));
        assertEquals(Float.valueOf("12.3"), converter.convert("12.3").to(Float.class));
        assertEquals(Double.valueOf("12.3"), converter.convert("12.3").to(Double.class));
    }

    @Test
    public void testCharAggregateToString() {
        Converter c = Converters.newConverterBuilder().
                rule(new Rule<List<Character>, String>(ConverterTest::characterListToString) {}).
                rule(new Rule<String, List<Character>>(ConverterTest::stringToCharacterList) {}).
                build();

        char[] ca = new char[] {'h', 'e', 'l', 'l', 'o'};
        assertEquals("hello", c.convert(ca).to(String.class));

        Character[] ca2 = c.convert(ca).to(Character[].class);
        assertEquals("hello", c.convert(ca2).to(String.class));

        List<Character> cl = c.convert(ca).to(new TypeReference<List<Character>>() {});
        assertEquals("hello", c.convert(cl).to(String.class));

        // And back
        assertArrayEquals(ca, c.convert("hello").to(char[].class));
        assertArrayEquals(ca2, c.convert("hello").to(Character[].class));
        assertEquals(cl, c.convert("hello").to(new TypeReference<List<Character>>() {}));
    }

    private static String characterListToString(List<Character> cl) {
        StringBuilder sb = new StringBuilder(cl.size());
        for (char c : cl) {
            sb.append(c);
        }
        return sb.toString();
    }

    private static List<Character> stringToCharacterList(String s) {
        List<Character> lc = new ArrayList<>();

        for (int i=0; i<s.length(); i++) {
            lc.add(s.charAt(i));
        }
        return lc;
    }

    enum TestEnum { FOO, BAR, BLAH, FALSE, X};
    enum TestEnum2 { BLAH };
    @Test
    public void testEnums() {
        assertSame(TestEnum.BLAH, converter.convert("BLAH").to(TestEnum.class));
        assertSame(TestEnum.X, converter.convert('X').to(TestEnum.class));
        assertSame(TestEnum.FALSE, converter.convert(false).to(TestEnum.class));
        assertSame(TestEnum.BAR, converter.convert(1).to(TestEnum.class));
        assertSame(TestEnum.BLAH, converter.convert(TestEnum2.BLAH).to(TestEnum.class));
        assertNull(converter.convert(null).to(TestEnum.class));
        assertNull(converter.convert(Collections.emptySet()).to(TestEnum.class));
    }

    @Test
    public void testToReflectType() {
        Type t = TestEnum.class;
        TestEnum e = converter.convert("X").to(t);
        assertEquals(TestEnum.X, e);
    }

    @Test
    public void testIdentialTarget() {
        Object o = new Object();
        assertSame(o, converter.convert(o).to(Object.class));

        Thread t = new Thread(); // No converter available
        assertSame(t, converter.convert(t).to(Thread.class));
        assertSame(t, converter.convert(t).to(Runnable.class));
        assertSame(t, converter.convert(t).to(Object.class));

        Thread st = new Thread() {}; // Subclass of Thread
        assertSame(st, converter.convert(st).to(Thread.class));
    }

    @Test
    public void testFromUnknownDataTypeViaString() {
        class MyClass {
            @Override
            public String toString() {
                return "1234";
            }
        };
        MyClass o = new MyClass();

        assertEquals(1234, (int) converter.convert(o).to(int.class));
        assertEquals("1234", converter.convert(o).to(String.class));
    }

    @Test
    public void testToUnknownViaStringCtor() {
        class MyClass {
            @Override
            public String toString() {
                return "http://127.0.0.1:1234/blah";
            }
        };
        MyClass o = new MyClass();

        URL url = converter.convert(o).to(URL.class);
        assertEquals("http://127.0.0.1:1234/blah", url.toString());
        assertEquals("http", url.getProtocol());
        assertEquals("127.0.0.1", url.getHost());
        assertEquals(1234, url.getPort());
        assertEquals("/blah", url.getPath());

        assertNull(converter.convert(null).to(URL.class));
        assertNull(converter.convert(Collections.emptyList()).to(URL.class));
    }

    @Test
    public void testFromMultiToSingle() {
        assertEquals("abc", converter.convert(Collections.singleton("abc")).to(String.class));
        assertEquals("abc", converter.convert(Arrays.asList("abc", "def", "ghi")).to(String.class));
        assertEquals(42, (int) converter.convert(Arrays.asList("42", "17")).to(Integer.class));
        MyClass2 mc = converter.convert(new String[] {"xxx", "yyy", "zzz"}).to(MyClass2.class);
        assertEquals("xxx", mc.toString());
        MyClass2[] arr = new MyClass2[] {new MyClass2("3.1412"), new MyClass2("6.2824")};
        assertEquals(Float.valueOf(3.1412f), Float.valueOf(converter.convert(arr).to(float.class)));
    }

    @Test
    public void testFromListToSet() {
        List<Object> l = new ArrayList<>(Arrays.asList("A", 'B', 333));

        Set<?> s = converter.convert(l).to(Set.class);
        assertEquals(3, s.size());

        for (Object o : s) {
            Object expected = l.remove(0);
            assertEquals(expected, o);
        }
    }

    @Test
    public void testFromGenericSetToLinkedList() {
        Set<Integer> s = new LinkedHashSet<>();
        s.add(123);
        s.add(456);

        LinkedList<String> ll = converter.convert(s).to(new TypeReference<LinkedList<String>>() {});
        assertEquals(Arrays.asList("123", "456"), ll);
    }

    @Test
    public void testFromArrayToGenericOrderPreservingSet() {
        String[] sa = {"567", "-765", "0", "-900"};

        // Returned set should be order preserving
        Set<Long> s = converter.convert(sa).to(new TypeReference<Set<Long>>() {});

        List<String> sl = new ArrayList<>(Arrays.asList(sa));
        for (long l : s) {
            long expected = Long.parseLong(sl.remove(0));
            assertEquals(expected, l);
        }
    }

    @Test
    public void testFromSetToArray() {
        Set<Integer> s = new LinkedHashSet<>();
        s.add(Integer.MIN_VALUE);

        long[] la = converter.convert(s).to(long[].class);
        assertEquals(1, la.length);
        assertEquals(Integer.MIN_VALUE, la[0]);
    }

    @Test
    public void testStringArrayToIntegerArray() {
        String[] sa = {"999", "111", "-909"};
        Integer[] ia = converter.convert(sa).to(Integer[].class);
        assertEquals(3, ia.length);
        assertArrayEquals(new Integer[] {999, 111, -909}, ia);
    }

    @Test
    public void testCharArrayConversion() {
        char[] ca = converter.convert(new int[] {9,8,7}).to(char[].class);
        assertArrayEquals(new char[] {9,8,7}, ca);
        Character[] ca2 = converter.convert((long) 17).to(Character[].class);
        assertArrayEquals(new Character[] {(char)17}, ca2);
        char[] ca3 = converter.convert(new short[] {257}).to(char[].class);
        assertArrayEquals(new char[] {257}, ca3);
        char c = converter.convert(new char[] {'x', 'y'}).to(char.class);
        assertEquals('x', c);
        char[] ca4a = {'x', 'y'};
        char[] ca4b = converter.convert(ca4a).to(char[].class);
        assertArrayEquals(new char [] {'x', 'y'}, ca4b);
        assertNotSame("Should have created a new instance", ca4a, ca4b);
    }
    
    /**
     * 707.4.3.1 - null becomes an empty array
     */
    @Test
    public void testNullToArrayConversion() {
    	
    	checkArray(String[].class);
    	checkArray(boolean[].class);
    	checkArray(byte[].class);
    	checkArray(short[].class);
    	checkArray(char[].class);
    	checkArray(int[].class);
    	checkArray(float[].class);
    	checkArray(long[].class);
    	checkArray(double[].class);

    	checkArray(String[][].class);
    	checkArray(boolean[][].class);
    	checkArray(byte[][].class);
    	checkArray(short[][].class);
    	checkArray(char[][].class);
    	checkArray(int[][].class);
    	checkArray(float[][].class);
    	checkArray(long[][].class);
    	checkArray(double[][].class);

    	
    	checkArray(String[][][].class);
    	checkArray(boolean[][][].class);
    	checkArray(byte[][][].class);
    	checkArray(short[][][].class);
    	checkArray(char[][][].class);
    	checkArray(int[][][].class);
    	checkArray(float[][][].class);
    	checkArray(long[][][].class);
    	checkArray(double[][][].class);
    }

	private void checkArray(Class<?> arrayType) {
		assertTrue(arrayType.isArray());
		
		Object array = converter.convert(null).to(arrayType);
    	assertEquals(0, Array.getLength(array));
    	assertTrue(arrayType.isInstance(array));
	}

    @Test
    public void testLongCollectionConversion() {
        long[] l = converter.convert(Long.MAX_VALUE).to(long[].class);
        assertArrayEquals(new long[] {Long.MAX_VALUE}, l);
        Long[] l2 = converter.convert(Long.MAX_VALUE).to(Long[].class);
        assertArrayEquals(new Long[] {Long.MAX_VALUE}, l2);
        List<Long> ll = converter.convert(new long[] {Long.MIN_VALUE, Long.MAX_VALUE}).to(new TypeReference<List<Long>>() {});
        assertEquals(Arrays.asList(Long.MIN_VALUE, Long.MAX_VALUE), ll);
        List<Long> ll2 = converter.convert(Arrays.asList(123, 345)).to(new TypeReference<List<Long>>() {});
        assertEquals(Arrays.asList(123L, 345L), ll2);

    }

    @Test
    public void testExceptionDefaultValue() {
        assertEquals(42, (int) converter.convert("haha").defaultValue(42).to(int.class));
        assertEquals(999, (int) converter.convert("haha").defaultValue(999).to(int.class));
        try {
            converter.convert("haha").to(int.class);
            fail("Should have thrown an exception");
        } catch (ConversionException ex) {
            // good
        }
    }

    @Test
    public void testStandardStringArrayConversion() {
        String[] sa = {"A", "B"};
        assertEquals("A", converter.convert(sa).toString());
        assertEquals("A", converter.convert(sa).to(String.class));

        String[] sa2 = {"A"};
        assertArrayEquals(sa2, converter.convert("A").to(String[].class));
    }

    @Test
    public void testCustomStringArrayConversion() {
        ConverterBuilder cb = converter.newConverterBuilder();
        cb.rule(new Rule<String[],String>(v -> Stream.of(v).collect(Collectors.joining(","))){});
        cb.rule(new Rule<String,String[]>(v -> v.split(",")){});

        Converter adapted = cb.build();

        String[] sa = {"A", "B"};
        assertEquals("A,B", adapted.convert(sa).to(String.class));
        assertArrayEquals(sa, adapted.convert("A,B").to(String[].class));
    }

    @Test
    public void testCustomIntArrayConversion() {
        ConverterBuilder cb = converter.newConverterBuilder();
        cb.rule(String.class, (f,t) -> f instanceof int[] ? Arrays.stream((int []) f).mapToObj(Integer::toString).collect(Collectors.joining(",")) : null);
        cb.rule(int[].class, (f,t) -> f instanceof String ? Arrays.stream(((String) f).split(",")).mapToInt(Integer::parseInt).toArray() : null);
        Converter adapted = cb.build();

        int[] ia = {1, 2};
        assertEquals("1,2", adapted.convert(ia).to(String.class));
        assertArrayEquals(ia, adapted.convert("1,2").to(int[].class));
    }

    @Test
    public void testCustomConverterChaining() {
        ConverterBuilder cb = converter.newConverterBuilder();
        cb.rule(Date.class,
                (f,t) -> f instanceof String ? new Date(0) : ConverterFunction.CANNOT_HANDLE);
        Converter c1 = cb.build();
        assertEquals(new Date(0), c1.convert("something").to(Date.class));
        assertEquals(new Date(0), c1.convert("foo").to(Date.class));

        ConverterBuilder cb2 = c1.newConverterBuilder();
        cb2.rule(Date.class,
                (f,t) -> f.equals("foo") ? new Date(100000) : ConverterFunction.CANNOT_HANDLE);
        Converter c2 = cb2.build();
        assertEquals(new Date(0), c2.convert("something").to(Date.class));
        assertEquals(new Date(100000), c2.convert("foo").to(Date.class));
    }


    @Test
    public void testCustomErrorHandling() {
        ConverterFunction func = new ConverterFunction() {
            @Override
            public Object apply(Object obj, Type targetType) {
                if ("hello".equals(obj)) {
                    return -1;
                }
                if ("goodbye".equals(obj)) {
                    return null;
                }
                return ConverterFunction.CANNOT_HANDLE;
            }
        };

        ConverterBuilder cb = converter.newConverterBuilder();
        Converter adapted = cb.errorHandler(func).build();

        assertEquals(new Integer(12), adapted.convert("12").to(Integer.class));
        assertEquals(new Integer(-1), adapted.convert("hello").to(Integer.class));
        assertNull(adapted.convert("goodbye").to(Integer.class));

        try {
            adapted.convert("nothing").to(Integer.class);
            fail("Should have thrown a Conversion Exception when converting 'hello' to a number");
        } catch (ConversionException ce) {
            // good
        }

        // This is with the non-adapted converter
        try {
            converter.convert("hello").to(Integer.class);
            fail("Should have thrown a Conversion Exception when converting 'hello' to a number");
        } catch (ConversionException ce) {
            // good
        }
    }

    @Test
    public void testCustomErrorHandlingProxy() {
        ConverterFunction errHandler = new ConverterFunction() {
            @Override
            public Object apply(Object obj, Type targetType) throws Exception {
                return 123;
            }
        };
        ConverterBuilder cb = converter.newConverterBuilder();
        Converter c = cb.errorHandler(errHandler).build();

        Map<?,?> m = new HashMap<>();

        MyIntf i = c.convert(m).to(MyIntf.class);
        assertEquals(123, i.value());
    }

    @Test
    public void testMultipleCustomErrorHandling() {
        ConverterBuilder cb1 = converter.newConverterBuilder();
        ConverterFunction func1 = new ConverterFunction() {
            @Override
            public Object apply(Object obj, Type targetType) {
                return -1;
            }
        };
        cb1.errorHandler(func1);
        Converter c1 = cb1.build();

        ConverterBuilder cb2 = c1.newConverterBuilder();
        ConverterFunction func2 = new ConverterFunction() {
            @Override
            public Object apply(Object obj, Type targetType) {
                if ("hello".equals(obj)) {
                    return 0;
                }
                return ConverterFunction.CANNOT_HANDLE;
            }
        };
        cb2.errorHandler(func2);
        Converter adapted = cb2.build();

        assertEquals(Integer.valueOf(0), adapted.convert("hello").to(Integer.class));
        assertEquals(Integer.valueOf(-1), adapted.convert("bye").to(Integer.class));
    }

    static class MyConverterFunction implements ConverterFunction {
        @Override
        public Object apply(Object obj, Type targetType) throws Exception {
            if ("hello".equals(obj)) {
                return 0;
            }
            return ConverterFunction.CANNOT_HANDLE;
        }
    }

    @Test
    public void testUUIDConversion() {
        UUID uuid = UUID.randomUUID();
        String s = converter.convert(uuid).to(String.class);
        assertTrue("UUID should be something", s.length() > 0);
        UUID uuid2 = converter.convert(s).to(UUID.class);
        assertEquals(uuid, uuid2);
    }

    @Test
    public void testPatternConversion() {
        String p = "\\S*";
        Pattern pattern = converter.convert(p).to(Pattern.class);
        Matcher matcher = pattern.matcher("hi");
        assertTrue(matcher.matches());
        String p2 = converter.convert(pattern).to(String.class);
        assertEquals(p, p2);
    }

    @Test
    public void testLocalDateTime() {
        LocalDateTime ldt = LocalDateTime.now();
        String s = converter.convert(ldt).to(String.class);
        assertTrue(s.length() > 0);
        LocalDateTime ldt2 = converter.convert(s).to(LocalDateTime.class);
        assertEquals(ldt, ldt2);
    }

    @Test
    public void testLocalDate() {
        LocalDate ld = LocalDate.now();
        String s = converter.convert(ld).to(String.class);
        assertTrue(s.length() > 0);
        LocalDate ld2 = converter.convert(s).to(LocalDate.class);
        assertEquals(ld, ld2);
    }

    @Test
    public void testLocalTime() {
        LocalTime lt = LocalTime.now();
        String s = converter.convert(lt).to(String.class);
        assertTrue(s.length() > 0);
        LocalTime lt2 = converter.convert(s).to(LocalTime.class);
        assertEquals(lt, lt2);
    }

    @Test
    public void testOffsetDateTime() {
        OffsetDateTime ot = OffsetDateTime.now();
        String s = converter.convert(ot).to(String.class);
        assertTrue(s.length() > 0);
        OffsetDateTime ot2 = converter.convert(s).to(OffsetDateTime.class);
        assertEquals(ot, ot2);
    }

    @Test
    public void testOffsetTime() {
        OffsetTime ot = OffsetTime.now();
        String s = converter.convert(ot).to(String.class);
        assertTrue(s.length() > 0);
        OffsetTime ot2 = converter.convert(s).to(OffsetTime.class);
        assertEquals(ot, ot2);
    }

    @Test
    public void testZonedDateTime() {
        ZonedDateTime zdt = ZonedDateTime.now();
        String s = converter.convert(zdt).to(String.class);
        assertTrue(s.length() > 0);
        ZonedDateTime zdt2 = converter.convert(s).to(ZonedDateTime.class);
        assertEquals(zdt, zdt2);
    }

    @Test
    public void testCalendarDate() {
        Calendar cal = new GregorianCalendar(1971, 1, 13, 12, 37, 41);
        TimeZone tz =TimeZone.getTimeZone("CET");
        cal.setTimeZone(tz);
        Date d = cal.getTime();

        Converter c = converter;

        String s = c.convert(d).toString();
        assertEquals("1971-02-13T11:37:41Z", s);
        assertEquals(d, c.convert(s).to(Date.class));

        String s2 = c.convert(cal).toString();
        assertEquals("1971-02-13T11:37:41Z", s2);
        Calendar cal2 = c.convert(s2).to(Calendar.class);
        assertEquals(cal.getTime(), cal2.getTime());
    }

    @Test
    public void testCalendarLong() {
        Calendar cal = new GregorianCalendar(1971, 1, 13, 12, 37, 41);
        TimeZone tz =TimeZone.getTimeZone("UTC");
        cal.setTimeZone(tz);

        long l = converter.convert(cal).to(Long.class);
        assertEquals(l, cal.getTimeInMillis());

        Calendar cal2 = converter.convert(l).to(Calendar.class);
        assertEquals(cal.getTime(), cal2.getTime());
    }

    @Test
    public void testDefaultValue() {
        long l = converter.convert(null).defaultValue("12").to(Long.class);
        assertEquals(12L, l);
        assertNull(converter.convert("haha").defaultValue(null).to(Integer.class));
        assertNull(converter.convert("test").defaultValue(null).to(new TypeReference<List<Long>>() {}));
    }

    @Test
    public void testDTO2Map() {
        MyEmbeddedDTO embedded = new MyEmbeddedDTO();
        embedded.marco = "hohoho";
        embedded.polo = Long.MAX_VALUE;
        embedded.alpha = Alpha.A;

        MyDTO dto = new MyDTO();
        dto.ping = "lalala";
        dto.pong = Long.MIN_VALUE;
        dto.count = Count.ONE;
        dto.embedded = embedded;

        @SuppressWarnings("rawtypes")
        Map m = converter.convert(dto).to(Map.class);
        assertEquals(4, m.size());
        assertEquals("lalala", m.get("ping"));
        assertEquals(Long.MIN_VALUE, m.get("pong"));
        assertEquals(Count.ONE, m.get("count"));
        assertNotNull(m.get("embedded"));

        MyEmbeddedDTO e = (MyEmbeddedDTO) m.get("embedded");
        assertEquals("hohoho", e.marco);
        assertEquals(Long.MAX_VALUE, e.polo);
        assertEquals(Alpha.A, e.alpha);
    }

    @Test
    public void testDTO2Map2() {
        MyEmbeddedDTO embedded = new MyEmbeddedDTO();
        embedded.marco = "hohoho";
        embedded.polo = Long.MAX_VALUE;
        embedded.alpha = Alpha.A;

        MyDTO dto = new MyDTO();
        dto.ping = "lalala";
        dto.pong = Long.MIN_VALUE;
        dto.count = Count.ONE;
        dto.embedded = embedded;

        @SuppressWarnings("rawtypes")
        Map m = converter.convert(dto).sourceAsDTO().to(Map.class);
        assertEquals(4, m.size());
        assertEquals("lalala", m.get("ping"));
        assertEquals(Long.MIN_VALUE, m.get("pong"));
        assertEquals(Count.ONE, m.get("count"));
        assertNotNull(m.get("embedded"));

        MyEmbeddedDTO e = (MyEmbeddedDTO) m.get("embedded");
        assertEquals("hohoho", e.marco);
        assertEquals(Long.MAX_VALUE, e.polo);
        assertEquals(Alpha.A, e.alpha);

        /* TODO this is the way it was, but it does not seem right
        Map e = (Map)m.get("embedded");
        assertEquals("hohoho", e.get("marco"));
        assertEquals(Long.MAX_VALUE, e.get("polo"));
        assertEquals(Alpha.A, e.get("alpha"));
        */
    }

    @Test
    public void testDTO2Map3() {
        MyEmbeddedDTO embedded2 = new MyEmbeddedDTO();
        embedded2.marco = "hohoho";
        embedded2.polo = Long.MAX_VALUE;
        embedded2.alpha = Alpha.A;

        MyDTOWithMethods embedded = new MyDTOWithMethods();
        embedded.ping = "lalala";
        embedded.pong = Long.MIN_VALUE;
        embedded.count = Count.ONE;
        embedded.embedded = embedded2;

        MyDTO8 dto = new MyDTO8();
        dto.ping = "lalala";
        dto.pong = Long.MIN_VALUE;
        dto.count = MyDTO8.Count.ONE;
        dto.embedded = embedded;

        @SuppressWarnings("rawtypes")
        Map m = converter.convert(dto).sourceAsDTO().to(Map.class);
        assertEquals(4, m.size());
        assertEquals("lalala", m.get("ping"));
        assertEquals(Long.MIN_VALUE, m.get("pong"));
        assertEquals(MyDTO8.Count.ONE, m.get("count"));
        assertNotNull(m.get("embedded"));
        assertTrue(m.get( "embedded" ) instanceof MyDTOWithMethods);
        MyDTOWithMethods e = (MyDTOWithMethods)m.get("embedded");
        assertEquals("lalala", e.ping);
        assertEquals(Long.MIN_VALUE, e.pong);
        assertEquals(Count.ONE, e.count);
        assertNotNull(e.embedded);
        assertTrue(e.embedded instanceof MyEmbeddedDTO);
        MyEmbeddedDTO e2 = e.embedded;
        assertEquals("hohoho", e2.marco);
        assertEquals(Long.MAX_VALUE, e2.polo);
        assertEquals(Alpha.A, e2.alpha);
    }

    @Test
    public void testDTO2Map4() {
    	MyDefaultCtorDTOAlike dto = new MyDefaultCtorDTOAlike();
    	dto.myProp = "myValue";

    	@SuppressWarnings("rawtypes")
    	Map m = converter.convert(dto).to(Map.class);
    	assertEquals(1, m.size());
    	assertEquals("myValue", m.get("myProp"));
    }

    @Test
    public void testDTO2Map5() {
    	MyDTO3 dto = new MyDTO3();
    	dto.charSet = new HashSet<>(Arrays.asList('f', 'o', 'o'));

    	@SuppressWarnings("rawtypes")
    	Map m = converter.convert(dto).to(new TypeReference<Map<String, ?>>() {});
    	assertEquals(1, m.size());
    	assertEquals(dto.charSet, m.get("charSet"));

    	m = converter.convert(dto).to(new TypeReference<Map<String, ? extends List<String>>>() {});
    	assertEquals(1, m.size());

    	List<String> list = new ArrayList<>();
    	for (Character character : dto.charSet) {
			list.add(String.valueOf(character));
		}

    	assertEquals(list, m.get("charSet"));
    }

    @Test @SuppressWarnings({ "rawtypes", "unchecked" })
    public void testDTOFieldShadowing() {
        MySubDTO dto = new MySubDTO();
        dto.ping = "test";
        dto.count = Count.THREE;

        Map m = converter.convert(dto).to(new TypeReference<Map<String,String>>() {});

        Map<String, String> expected = new HashMap<>();
        expected.put("ping", "test");
        expected.put("count", "THREE");
        expected.put("pong", "0");
        expected.put("embedded", null);
        assertEquals(expected, new HashMap<String, String>(m));

        MySubDTO dto2 = converter.convert(m).to(MySubDTO.class);
        assertEquals("test", dto2.ping);
        assertEquals(Count.THREE, dto2.count);
        assertEquals(0L, dto2.pong);
        assertNull(dto2.embedded);
    }

    @Test
    public void testMap2DTO() {
        Map<String, Object> m = new HashMap<>();
        m.put("ping", "abc xyz");
        m.put("pong", 42L);
        m.put("count", Count.ONE);
        Map<String, Object> e = new HashMap<>();
        e.put("marco", "ichi ni san");
        e.put("polo", 64L);
        e.put("alpha", Alpha.A);
        m.put("embedded", e);

        MyDTO dto = converter.convert(m).to(MyDTO.class);
        assertEquals("abc xyz", dto.ping);
        assertEquals(42L, dto.pong);
        assertEquals(Count.ONE, dto.count);
        assertNotNull(dto.embedded);
        assertEquals(dto.embedded.marco, "ichi ni san");
        assertEquals(dto.embedded.polo, 64L);
        assertEquals(dto.embedded.alpha, Alpha.A);
    }

    @Test
    public void testMap2DTOView() {
        Map<String, Object> src = Collections.singletonMap("pong", 42);
        MyDTOWithMethods dto = converter.convert(src).targetAs(MyDTO.class).to(MyDTOWithMethods.class);
        assertEquals(42, dto.pong);
    }

    @Test @SuppressWarnings({ "rawtypes", "unchecked" })
    public void testDTOWithGenerics() {
        MyDTO2 dto = new MyDTO2();
        dto.longList = Arrays.asList(999L, 1000L);
        dto.dtoMap = new LinkedHashMap<>();

        MyDTO3 subDTO1 = new MyDTO3();
        subDTO1.charSet = new HashSet<>(Arrays.asList('f', 'o', 'o'));
        dto.dtoMap.put("zzz", subDTO1);

        MyDTO3 subDTO2 = new MyDTO3();
        subDTO2.charSet = new HashSet<>(Arrays.asList('b', 'a', 'r'));
        dto.dtoMap.put("aaa", subDTO2);

        Map m = converter.convert(dto).to(Map.class);
        assertEquals(2, m.size());

        assertEquals(Arrays.asList(999L, 1000L), m.get("longList"));
        Map nestedMap = (Map) m.get("dtoMap");

        // Check iteration order is preserved by iterating
        int i=0;
        for (Iterator<Map.Entry> it = nestedMap.entrySet().iterator(); it.hasNext(); i++) {
            Map.Entry entry = it.next();
            switch (i) {
            case 0:
                assertEquals("zzz", entry.getKey());
                MyDTO3 dto1 = (MyDTO3) entry.getValue();
                assertNotSame("Should have created a copy", subDTO1, dto1);
                assertEquals(new HashSet<Character>(Arrays.asList('f', 'o')), dto1.charSet);
                break;
            case 1:
                assertEquals("aaa", entry.getKey());
                MyDTO3 dto2 = (MyDTO3) entry.getValue();
                assertNotSame("Should have created a copy", subDTO2, dto2);
                assertEquals(new HashSet<Character>(Arrays.asList('b', 'a', 'r')), dto2.charSet);
                break;
            default:
                fail("Unexpected number of elements on map");
            }
        }

        // convert back
        MyDTO2 dto2 = converter.convert(m).to(MyDTO2.class);
        assertEquals(dto.longList, dto2.longList);

        // Cannot simply do dto.equals() as the DTOs don't implement that
        assertEquals(dto.dtoMap.size(), dto2.dtoMap.size());
        MyDTO3 dto2SubZZZ = dto2.dtoMap.get("zzz");
        assertEquals(dto2SubZZZ.charSet, new HashSet<Character>(Arrays.asList('f', 'o')));
        MyDTO3 dto2SubAAA = dto2.dtoMap.get("aaa");
        assertEquals(dto2SubAAA.charSet, new HashSet<Character>(Arrays.asList('b', 'a', 'r')));
    }

    @Test
    public void testMapToDTOWithGenerics() {
    	    Map<String, Object> dto = new HashMap<>();

        dto.put("longList", Arrays.asList((short)999, "1000"));

        Map<String, Object> dtoMap = new LinkedHashMap<>();
        dto.put("dtoMap", dtoMap);

        Map<String, Object> subDTO1 = new HashMap<>();
        subDTO1.put("charSet", new HashSet<>(Arrays.asList("foo", (int) 'o', 'o')));
        dtoMap.put("zzz", subDTO1);

        Map<String, Object> subDTO2 = new HashMap<>();
        subDTO2.put("charSet", new HashSet<>(Arrays.asList('b', 'a', 'r')));
        dtoMap.put("aaa", subDTO2);

        MyDTO2 converted = converter.convert(dto).to(MyDTO2.class);

        assertEquals(Arrays.asList(999L, 1000L), converted.longList);
        Map<String, MyDTO3> nestedMap = converted.dtoMap;

        // Check iteration order is preserved by iterating
        int i=0;
        for (Iterator<Map.Entry<String, MyDTO3>> it = nestedMap.entrySet().iterator(); it.hasNext(); i++) {
            Map.Entry<String, MyDTO3> entry = it.next();
            switch (i) {
            case 0:
                assertEquals("zzz", entry.getKey());
                MyDTO3 dto1 = entry.getValue();
                assertEquals(new HashSet<Character>(Arrays.asList('f', 'o')), dto1.charSet);
                break;
            case 1:
                assertEquals("aaa", entry.getKey());
                MyDTO3 dto2 = entry.getValue();
                assertEquals(new HashSet<Character>(Arrays.asList('b', 'a', 'r')), dto2.charSet);
                break;
            default:
                fail("Unexpected number of elements on map");
            }
        }
    }

    @Test
    public void testMapToDTOWithGenericVariables() {
    	    	Map<String, Object> dto = new HashMap<>();
    	    	dto.put("set", new HashSet<>(Arrays.asList("foo", (int) 'o', 'o')));
    	    	dto.put("raw", "1234");
    	    	dto.put("array", Arrays.asList("foo", (int) 'o', 'o'));

    	    	MyGenericDTOWithVariables<Character> converted =
    	    			converter.convert(dto).to(new TypeReference<MyGenericDTOWithVariables<Character>>() {});
    	    	assertEquals(Character.valueOf('1'), converted.raw);
    	    	assertArrayEquals(new Character[] {'f', 'o', 'o'}, converted.array);
    	    	assertEquals(new HashSet<Character>(Arrays.asList('f', 'o')), converted.set);
    }

    @Test
    public void testMapToDTOWithSurplusMapFiels() {
        Map<String, String> m = new HashMap<>();
        m.put("foo", "bar");
        MyDTO3 dtoDoesNotMap = converter.convert(m).to(MyDTO3.class);
        assertNull(dtoDoesNotMap.charSet);
    }

    @Test @SuppressWarnings("rawtypes")
    public void testCopyMap() {
        Map m = new HashMap();
        Map m2 = converter.convert(m).to(Map.class);
        assertEquals(m, m2);
        assertNotSame(m, m2);
    }

    @Test @SuppressWarnings({ "rawtypes", "unchecked" })
    public void testCopyMap2() {
        Map m = new HashMap();
        m.put("key", Arrays.asList("a", "b", "c"));
        Map m2 = converter.convert(m).to(Map.class);
        assertEquals(m, m2);
        assertNotSame(m, m2);
    }

    @Test
    public void testConversionPriority() {
        MyBean mb = new MyBean();
        mb.intfVal = 17;
        mb.beanVal = "Hello";

        assertEquals(Collections.singletonMap("value", "Hello"),
                converter.convert(mb).sourceAsBean().to(Map.class));
    }

    @Test
    public void testConvertAsInterface() {
        MyBean mb = new MyBean();
        mb.intfVal = 17;
        mb.beanVal = "Hello";

        assertEquals(17,
                converter.convert(mb).sourceAs(MyIntf.class).to(Map.class).get("value"));
    }

    @Test
    public void testConvertAsBean() {
        MyBean mb = new MyBean();
        mb.intfVal = 17;
        mb.beanVal = "Hello";

        assertEquals(Collections.singletonMap("value", "Hello"),
                converter.convert(mb).sourceAsBean().to(Map.class));
    }

    @Test
    public void testConvertAsDTO() {
        MyClass3 mc3 = new MyClass3(17);

        assertEquals(17,
                converter.convert(mc3).sourceAsDTO().to(Map.class).get("value"));
    }

    @Test
    public void testDTONameMangling() {
        Map<String,String> m = new HashMap<>();
        m.put("org.osgi.framework.uuid", "test123");
        m.put("myProperty143", "true");
        m.put("my$prop", "42");
        m.put("dot.prop", "456");
        m.put(".secret", " ");
        m.put("another_prop", "lalala");
        m.put("three_.prop", "hi ha ho");
        m.put("four._prop", "");
        m.put("five..prop", "test");
        m.put("six-prop", "987");
        m.put("seven$.prop", "3.141");

        MyDTO7 dto = converter.convert(m).to(MyDTO7.class);
        assertEquals("test123", dto.org_osgi_framework_uuid);
        assertTrue(dto.myProperty143);
        assertEquals(42, dto.my$$prop);
        assertEquals(Long.valueOf(456L), dto.dot_prop);
        assertEquals(' ', dto._secret);
        assertEquals("lalala", dto.another__prop);
        assertEquals("hi ha ho", dto.three___prop);
        assertEquals("", dto.four_$__prop);
        assertEquals("test", dto.five_$_prop);
        assertEquals((short) 987, dto.six$_$prop);
        dto.seven$$_$prop = 3.141;

        // And convert back
        Map<String, String> m2 = converter.convert(dto).to(new TypeReference<Map<String,String>>() {});
        assertEquals(new HashMap<String,String>(m), new HashMap<String,String>(m2));
    }

    @Test
    public void testCollectionInterfaceMapping() {
        Collection<?> coll = converter.convert("test").to(Collection.class);
        assertEquals("test", coll.iterator().next());

        List<?> list = converter.convert("test").to(List.class);
        assertEquals("test", list.iterator().next());

        Set<?> set = converter.convert("test").to(Set.class);
        assertEquals("test", set.iterator().next());

        NavigableSet<?> ns = converter.convert("test").to(NavigableSet.class);
        assertEquals("test", ns.iterator().next());

        SortedSet<?> ss = converter.convert("test").to(SortedSet.class);
        assertEquals("test", ss.iterator().next());

        Queue<?> q = converter.convert("test").to(Queue.class);
        assertEquals("test", q.iterator().next());

        Deque<?> dq = converter.convert("test").to(Deque.class);
        assertEquals("test", dq.iterator().next());

        Map<?,?> m = converter.convert(Collections.singletonMap("x", "y")).to(Map.class);
        assertEquals("y", m.get("x"));

        ConcurrentMap<?,?> cm = converter.convert(Collections.singletonMap("x", "y")).to(ConcurrentMap.class);
        assertEquals("y", cm.get("x"));

        ConcurrentNavigableMap<?,?> cnm = converter.convert(Collections.singletonMap("x", "y")).to(ConcurrentNavigableMap.class);
        assertEquals("y", cnm.get("x"));

        NavigableMap<?,?> nm = converter.convert(Collections.singletonMap("x", "y")).to(NavigableMap.class);
        assertEquals("y", nm.get("x"));

        SortedMap<?,?> sm = converter.convert(Collections.singletonMap("x", "y")).to(SortedMap.class);
        assertEquals("y", sm.get("x"));
    }

    @SuppressWarnings("unchecked")
    @Test
    public void testLiveMapFromInterface() {
        int[] val = new int[1];
        val[0] = 51;

        MyIntf intf = new MyIntf() {
            @Override
            public int value() {
                return val[0];
            }
        };

        @SuppressWarnings("rawtypes")
        Map m = converter.convert(intf).view().to(Map.class);
        assertEquals(51, m.get("value"));

        val[0] = 52;
        assertEquals("Changes to the backing map should be reflected",
                52, m.get("value"));

        m.put("value", 53);
        assertEquals(53, m.get("value"));

        val[0] = 54;
        assertEquals("Changes to the backing map should not be reflected any more",
                53, m.get("value"));
    }

    @SuppressWarnings("unchecked")
    @Test
    public void testLiveMapFromDTO() {
        MyDTO8 myDTO = new MyDTO8();

        myDTO.count = MyDTO8.Count.TWO;
        myDTO.pong = 42L;

        @SuppressWarnings("rawtypes")
        Map m = converter.convert(myDTO).view().to(Map.class);
        assertEquals(42L, m.get("pong"));

        myDTO.ping = "Ping!";
        assertEquals("Ping!", m.get("ping"));
        myDTO.pong = 52L;
        assertEquals(52L, m.get("pong"));
        myDTO.ping = "Pong!";
        assertEquals("Pong!", m.get("ping"));
        assertNull(m.get("nonexistant"));

        m.put("pong", 62L);
        myDTO.ping = "Poing!";
        myDTO.pong = 72L;
        assertEquals("Pong!", m.get("ping"));
        assertEquals(62L, m.get("pong"));
        assertNull(m.get("nonexistant"));
    }

    @Test
    public void testMapFromDTO() {
        MyDTO9 dto = new MyDTO9();
        dto.key1 = "value1";
        dto.key2 = "value2";

        Map<Character, Character> m = converter.convert(dto).to(new TypeReference<Map<Character, Character>>() {});
        assertEquals(1, m.size());
        assertEquals('v', (char) m.get('k'));

        assertTrue(m.containsKey('k'));
        assertFalse(m.containsKey("key1"));
        assertTrue(m.containsValue('v'));
        assertFalse(m.containsValue("value1"));
    }

    @Test
    public void testLiveMapFromDictionary() throws URISyntaxException {
        URI testURI = new URI("http://foo");
        Hashtable<String, Object> d = new Hashtable<>();
        d.put("test", testURI);

        Map<String, Object> m = converter.convert(d).view().to(new TypeReference<Map<String, Object>>(){});
        assertEquals(testURI, m.get("test"));

        URI testURI2 = new URI("http://bar");
        d.put("test2", testURI2);
        assertEquals(testURI2, m.get("test2"));
        assertEquals(testURI, m.get("test"));
    }

    @Test
    public void testLiveMapFromMap() {
        Map<String, String> s = new HashMap<>();

        s.put("true", "123");
        s.put("false", "456");

        Map<Boolean, Short> m = converter.convert(s).view().to(new TypeReference<Map<Boolean, Short>>(){});
        assertEquals(Short.valueOf("123"), m.get(Boolean.TRUE));
        assertEquals(Short.valueOf("456"), m.get(Boolean.FALSE));

        s.remove("true");
        assertNull(m.get(Boolean.TRUE));

        s.put("TRUE", "999");
        assertEquals(Short.valueOf("999"), m.get(Boolean.TRUE));
    }

    @Test
    public void testLiveMapFromBean() {
        MyBean mb = new MyBean();
        mb.beanVal = "" + Long.MAX_VALUE;

        Map<SomeEnum, Long> m = converter.convert(mb).sourceAsBean().view().to(new TypeReference<Map<SomeEnum, Long>>(){});
        assertEquals(1, m.size());
        assertEquals(Long.valueOf(Long.MAX_VALUE), m.get(SomeEnum.VALUE));

        mb.beanVal = "" + Long.MIN_VALUE;
        assertEquals(Long.valueOf(Long.MIN_VALUE), m.get(SomeEnum.VALUE));

        m.put(SomeEnum.GETVALUE, 123L);
        mb.beanVal = "12";
        assertEquals(Long.valueOf(Long.MIN_VALUE), m.get(SomeEnum.VALUE));
    }

    @Test
    public void testPrefixDTO() {
        Map<String, String> m = new HashMap<>();
        m.put("org.foo.bar.width", "327");
        m.put("org.foo.bar.warp", "eeej");
        m.put("length", "12");

        PrefixDTO dto = converter.convert(m).to(PrefixDTO.class);
        assertEquals(327L, dto.width);
        assertEquals("This one should not be set", 0, dto.length);

        Map<String, String> m2 = converter.convert(dto).to(new TypeReference<HashMap<String,String>>() {});
        Map<String, String> expected = new HashMap<>();
        expected.put("org.foo.bar.width", "327");
        expected.put("org.foo.bar.length", "0");
        assertEquals(expected, m2);
    }

    @Test
    public void testPrefixInterface() {
        Map<String, String> m = new HashMap<>();
        m.put("org.foo.bar.width", "327");
        m.put("org.foo.bar.warp", "eeej");
        m.put("length", "12");

        PrefixInterface i = converter.convert(m).to(PrefixInterface.class);
        assertEquals(327L, i.width());
        try {
            i.length();
            fail("Should have thrown an exception");
        } catch (ConversionException ce) {
            // good
        }

        PrefixInterface i2 = new PrefixInterface() {
            @Override
            public long width() {
                return Long.MAX_VALUE;
            }

            @Override
            public int length() {
                return Integer.MIN_VALUE;
            }
        };

        Map<String, String> m2 = converter.convert(i2).to(new TypeReference<Map<String,String>>() {});
        Map<String, String> expected = new HashMap<>();
        expected.put("org.foo.bar.width", "" + Long.MAX_VALUE);
        expected.put("org.foo.bar.length", "" + Integer.MIN_VALUE);
        assertEquals(expected, m2);
    }

    @Test
    public void testAnnotationInterface() {
        Map<String, String> m = new HashMap<>();
        m.put("org.foo.bar.width", "327");
        m.put("org.foo.bar.warp", "eeej");
        m.put("length", "12");

        PrefixAnnotation pa = converter.convert(m).to(PrefixAnnotation.class);
        assertEquals(327L, pa.width());
        assertEquals(51, pa.length());

        Map<String, String> m2 = converter.convert(pa).to(new TypeReference<Map<String,String>>() {});
        Map<String, String> expected = new HashMap<>();
        expected.put("org.foo.bar.width", "327");
        expected.put("org.foo.bar.length", "51");
        assertEquals(expected, m2);
    }

    @Test
    public void testPrefixEnumAnnotation() {
        PrefixEnumAnnotation pea = converter.convert(Collections.emptyMap()).to(PrefixEnumAnnotation.class);

        assertEquals(1000, pea.timeout());
        assertEquals(PrefixEnumAnnotation.Type.SINGLE, pea.type());

        @SuppressWarnings("rawtypes")
        Map m = converter.convert(pea).to(Map.class);
        assertEquals(1000L, m.get("com.acme.config.timeout"));
        assertEquals(PrefixEnumAnnotation.Type.SINGLE, m.get("com.acme.config.type"));
    }

    @Test
    public void testTargetAsString() {
        Map<String, String> m = new HashMap<>();
        CharSequence cs = converter.convert(m).targetAs(String.class).to(CharSequence.class);
        assertNull(cs);

        Map<String, String> m2 = new HashMap<>();
        m2.put("Hi", "there");
        CharSequence cs2 = converter.convert(m2).targetAs(String.class).to(CharSequence.class);
        assertEquals("Hi", cs2);
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Test
    public void testTargetAsDTO() {
        MyDTOWithMethods expected = new MyDTOWithMethods();
        expected.count = Count.ONE;
        expected.ping = "pong";
        expected.pong = 42;
        Map m = new HashMap<>();
        m.put("count", Count.ONE);
        m.put("ping", "pong");
        m.put("pong", 42);
        MyDTOWithMethods actual = converter.convert(m).targetAsDTO().to(MyDTOWithMethods.class);
        assertEquals(expected.count, actual.count);
        assertEquals(expected.ping, actual.ping);
        assertEquals(expected.pong, actual.pong);
    }

    @SuppressWarnings("rawtypes")
    @Test
    public void testLongArrayToLongCollection() {
        Long[] la = new Long[] {Long.MIN_VALUE, Long.MAX_VALUE};

        List lc = converter.convert(la).to(List.class);

        assertEquals(la.length, lc.size());

        int i=0;
        for (Iterator it = lc.iterator(); it.hasNext(); i++) {
            assertEquals(la[i], it.next());
        }
    }

    @Test
    public void testMapToInterfaceWithGenerics() {
    	    Map<String, Object> dto = new HashMap<>();
        dto.put("charSet", new HashSet<>(Arrays.asList("foo", (int) 'o', 'o')));

        MyGenericInterface converted = converter.convert(dto).to(MyGenericInterface.class);
        assertEquals(new HashSet<Character>(Arrays.asList('f', 'o')), converted.charSet());
    }

    @Test
    public void testMapToInterfaceWithGenericVariables() {
	    	Map<String, Object> dto = new HashMap<>();
	    	dto.put("set", new HashSet<>(Arrays.asList("foo", (int) 'o', 'o')));
	    	dto.put("raw", "1234");
	    	dto.put("array", Arrays.asList("foo", (int) 'o', 'o'));

	    	MyGenericInterfaceWithVariables<Character> converted =
	    			converter.convert(dto).to(new TypeReference<MyGenericInterfaceWithVariables<Character>>() {});
	    	assertEquals(Character.valueOf('1'), converted.raw());
	    	assertArrayEquals(new Character[] {'f', 'o', 'o'}, converted.array());
	    	assertEquals(new HashSet<Character>(Arrays.asList('f', 'o')), converted.set());
    }

    @Test
    public void testMapToInterfaceWithOptionalValue() throws Exception {
        ConverterBuilder cb = Converters.newConverterBuilder();
        cb.errorHandler(new ConverterFunction() {
            @Override
            public Object apply(Object pObj, Type pTargetType) throws Exception {
                if ("java.lang.Integer".equals(pTargetType.getTypeName()))
                {
                    return 0;
                }
                return ConverterFunction.CANNOT_HANDLE;
            }
        });
        Converter convWithErrorHandler = cb.build();

        Map<String, Object> map = new HashMap<String, Object>();
        map.put("code", "harley");
        MyIntf2 inter = convWithErrorHandler.convert(map).to(MyIntf2.class);
        assertEquals("harley", inter.code());
        assertEquals(Integer.valueOf(0), inter.value());
    }

    static interface MyIntf2 {
        String code();
        Integer value();
    }

    static class MyClass2 {
        private final String value;
        public MyClass2(String v) {
            value = v;
        }

        @Override
        public String toString() {
            return value;
        }
    }

    static interface MyIntf {
        int value();
    }

    static class MyBean implements MyIntf {
        int intfVal;
        String beanVal;

        @Override
        public int value() {
            return intfVal;
        }

        public String getValue() {
            return beanVal;
        }
    }

    static class MyClass3 {
        public int value;
        public String string = "String";

        public MyClass3( int value ) {
            this.value = value;
        }

        public int value() {
            return value;
        }
    }

    static @interface MyAnnotation {
        int value() default 17;
    }

    enum SomeEnum { VALUE, GETVALUE };
}
