@TestCoversMethods("fromMap")
  public void testFromMap_Mapable() throws Exception {
    // from map
    POJO2 p1 = new POJO2(1, "one", Arrays.asList(new Object[] {1.0}));
    Map<String, Object> m1 = mapper.toMap(p1, (Object[]) null);

    POJO2 expected;

    expected = new POJO2(p1.getId(), p1.getName(), p1.getValue());
    assertEquals(expected, mapper.fromMap(new POJO2(), m1, (Object[]) null));
    expected = new POJO2(p1.getId(), null, null);
    assertEquals(expected, mapper.fromMap(new POJO2(), m1, new Object[] {"id"}));
    expected = new POJO2(0, p1.getName(), null);
    assertEquals(expected, mapper.fromMap(new POJO2(), m1, new Object[] {"name"}));
    expected = new POJO2(0, null, p1.getValue());
    assertEquals(expected, mapper.fromMap(new POJO2(), m1, new Object[] {"value"}));
    expected = new POJO2(p1.getId(), p1.getName(), p1.getValue());
    assertEquals(expected, mapper.fromMap(new POJO2(), m1, new Object[] {"id", "name", "value"}));

    // from map for "trees"
    POJO2 p2 = new POJO2(2, "two");
    POJO2Parent pp1 = new POJO2Parent();
    pp1.setChildren(Arrays.asList(new POJO2[] {p1}));
    POJO2Parent pp2 = new POJO2Parent();
    pp2.setChildren(Arrays.asList(new POJO2[] {p2}));
    pp1.setSibling(pp2);

    Map<String, Object> mp1 = mapper.toMap(pp1, (Object[]) null);

    assertEquals(pp1, mapper.fromMap(new POJO2Parent(), mp1, (Object[]) null));
  }
  @TestCoversMethods({"toMap", "prepare"})
  public void testToMap_POJO3() throws Exception {
    // to map
    POJO3 p1 = new POJO3(1, "one", Arrays.asList(new Double[] {1.0}));

    checkMap(
        mapper.toMap(p1, (Object[]) null),
        "id",
        p1.getId(),
        "name",
        p1.getName(),
        "value",
        p1.getValue());

    // to map for "trees"
    POJO3 p2 = new POJO3(2, "two");
    POJO3Parent pp1 = new POJO3Parent();
    pp1.setChildren(Arrays.asList(new POJO3[] {p1}));
    POJO3Parent pp2 = new POJO3Parent();
    pp2.setChildren(Arrays.asList(new POJO3[] {p2}));
    pp1.setSibling(pp2);

    Map<String, Object> mp1 = mapper.toMap(pp1, (Object[]) null);
    Map<String, Object> mp2 = mapper.toMap(pp2, (Object[]) null);
    Map<String, Object> m1 = mapper.toMap(p1, (Object[]) null);
    Map<String, Object> m2 = mapper.toMap(p2, (Object[]) null);

    List<Object> c1 = Arrays.asList(new Object[] {m1});
    List<Object> c2 = Arrays.asList(new Object[] {m2});

    checkMap(m1, "id", p1.getId(), "name", p1.getName(), "value", p1.getValue());
    checkMap(m2, "id", p2.getId(), "name", p2.getName(), "value", p2.getValue());
    checkMap(mp2, "sibling", null, "children", c2);
    checkMap(mp1, "sibling", mp2, "children", c1);
  }
  @SuppressWarnings("unchecked")
  public void testMergeToCollection() throws Exception {
    POJO1 p1 = new POJO1(null, 1, "one");
    POJO1 p2 = new POJO1(null, 2, "two");
    POJO1 p3 = new POJO1(null, 3, "three");

    Map<String, Object> m1 = mapper.toMap(p1);
    Map<String, Object> m2 = mapper.toMap(p2);
    Map<String, Object> m3 = mapper.toMap(p3);

    Object[] array = new Object[] {m1, m2, m3};
    List<Object> list = Arrays.asList(array);

    POJO1[] expectedArray = new POJO1[] {p1, p2, p3};
    List<POJO1> expected = Arrays.asList(expectedArray);
    List<POJO1> result;

    result =
        (List<POJO1>)
            mapper.mergeToCollection(
                array, POJO1.class, (Class<? extends Collection<?>>) (Class<?>) List.class);
    assertEquals(expected, result);

    result = (List<POJO1>) mapper.mergeToCollection(list, POJO1.class);
    assertEquals(expected, result);
  }
  @TestCoversMethods({"toMap", "prepare"})
  public void testToMap_Map() throws Exception {
    Map<Object, Object> m = new HashMap<Object, Object>();
    m.put("x", 1);
    m.put("y", "one");

    checkMap(mapper.toMap(m, "any"), "x", m.get("x"), "y", m.get("y"));
    checkMap(mapper.toMap(m, "random"), "x", m.get("x"), "y", m.get("y"));
    checkMap(mapper.toMap(m, "role"), "x", m.get("x"), "y", m.get("y"));
  }
  @TestCoversMethods("fromMap")
  public void testFromMap_Map() throws Exception {
    Map<Object, Object> m = new HashMap<Object, Object>();
    m.put("x", 1);
    m.put("y", "one");

    assertEquals(
        m, mapper.fromMap(new HashMap<Object, Object>(), mapper.toMap(m, "any"), (Object[]) null));
    assertEquals(
        m,
        mapper.fromMap(new HashMap<Object, Object>(), mapper.toMap(m, "random"), (Object[]) null));
    assertEquals(
        m, mapper.fromMap(new HashMap<Object, Object>(), mapper.toMap(m, "role"), (Object[]) null));
  }
  @TestCoversMethods("fromMap")
  public void testFromMap_POJO() throws Exception {
    SecurityManager securityManager = new SecurityManager();
    securityManager.addAccessController(new FieldAccessController(new BaseAccessRule()));
    mapper.setSecurityManager(securityManager);

    Object owner = new Object();
    Object other = new Object();

    POJO1 p = new POJO1(owner, 1, "one");
    Map<String, Object> m = mapper.toMap(p, owner);
    assertTrue(m.containsKey("x"));
    assertTrue(m.containsKey("y"));

    POJO1 expected;

    // with owner
    expected = new POJO1(null, p.getX(), p.getY());
    assertEquals(expected, mapper.fromMap(new POJO1(owner), m, owner));

    // with other
    expected = new POJO1(null, 0, p.getY());
    assertEquals(expected, mapper.fromMap(new POJO1(owner), m, other));

    // noone
    assertEquals(expected, mapper.fromMap(new POJO1(owner), m, (Object[]) null));
    assertEquals(expected, mapper.fromMap(new POJO1(owner), m, new Object[] {}));

    mapper.setSecurityManager(null);
  }
  public void testMergeToArray() throws Exception {
    POJO1 p1 = new POJO1(null, 1, "one");
    POJO1 p2 = new POJO1(null, 2, "two");
    POJO1 p3 = new POJO1(null, 3, "three");

    Map<String, Object> m1 = mapper.toMap(p1);
    Map<String, Object> m2 = mapper.toMap(p2);
    Map<String, Object> m3 = mapper.toMap(p3);

    Object[] array = new Object[] {m1, m2, m3};
    List<Object> list = Arrays.asList(array);

    POJO1[] expected = new POJO1[] {p1, p2, p3};
    POJO1[] result;

    result = mapper.mergeToArray(array, POJO1.class);
    assertEquals(expected, result);
    assertEquals(POJO1.class, result.getClass().getComponentType());

    result = mapper.mergeToArray(list, POJO1.class);
    assertEquals(expected, result);
    assertEquals(POJO1.class, result.getClass().getComponentType());
  }
  @TestCoversMethods({"toMap", "prepare"})
  public void testToMap_POJO() throws Exception {
    SecurityManager securityManager = new SecurityManager();
    securityManager.addAccessController(new FieldAccessController(new BaseAccessRule()));
    mapper.setSecurityManager(securityManager);

    Object owner = new Object();
    Object other = new Object();

    POJO1 p = new POJO1(owner, 1, "one");

    // with owner
    checkMap(mapper.toMap(p, owner), "x", p.getX(), "y", p.getY());

    // with other
    checkMap(mapper.toMap(p, other), "y", p.getY());

    // noone
    checkMap(mapper.toMap(p, (Object[]) null), "y", p.getY());
    checkMap(mapper.toMap(p, new Object[] {}), "y", p.getY());

    mapper.setSecurityManager(null);
  }
  @TestCoversMethods("fromMap")
  public void testFromMap_POJO3() throws Exception {
    // from map
    POJO3 p1 = new POJO3(1, "one", Arrays.asList(new Double[] {1.0}));
    Map<String, Object> m1 = mapper.toMap(p1, (Object[]) null);

    POJO3 expected;

    expected = new POJO3(p1.getId(), p1.getName(), p1.getValue());
    System.out.println("----");
    assertEquals(expected, mapper.fromMap(new POJO3(), m1, (Object[]) null));

    // from map for "trees"
    POJO3 p2 = new POJO3(2, "two");
    POJO3Parent pp1 = new POJO3Parent();
    pp1.setChildren(Arrays.asList(new POJO3[] {p1}));
    POJO3Parent pp2 = new POJO3Parent();
    pp2.setChildren(Arrays.asList(new POJO3[] {p2}));
    pp1.setSibling(pp2);

    Map<String, Object> mp1 = mapper.toMap(pp1, (Object[]) null);

    assertEquals(pp1, mapper.fromMap(new POJO3Parent(), mp1, (Object[]) null));
  }