static boolean objectIsAcyclic(Object object)
  {
    if (object == null)
    {
      return true;
    }

    Class<?> klass = object.getClass();
    if (isPrimitiveClass(klass))
    {
      return true;
    }
    else if (isComplexClass(klass))
    {
      DataComplex complex = (DataComplex) object;
      try
      {
        Data.traverse(complex, new TraverseCallback() {});
        return true;
      }
      catch (IOException e)
      {
        return false;
      }
    }
    else
    {
      throw new IllegalStateException("Object of unknown type: " + object);
    }
  }
@Test
  public void testDataMapNoCyclesOnPut()
  {
    // test with DataMap

    DataMap a = new DataMap();
    DataMap b = new DataMap();
    DataMap c = new DataMap();

    a.put("b", b);
    a.put("c", c);

    assertTrue(Data.objectIsAcyclic(a));

    DataMap d = new DataMap();
    b.put("d", d);
    c.put("d", d);

    assertTrue(Data.objectIsAcyclic(a));

    DataMap e = new DataMap();
    d.put("e", e);

    assertTrue(Data.objectIsAcyclic(a));

    // cyclic due to edge from e to d.
    putAndExpectIllegalArgumentException(e, "e", e);
    assertTrue(Data.objectIsAcyclic(a));

    // cyclic due to edge from e to d.
    putAndExpectIllegalArgumentException(e, "d", d);
    assertTrue(Data.objectIsAcyclic(a));

    // cyclic due to edge from e to c
    putAndExpectIllegalArgumentException(e, "c", c);
    assertTrue(Data.objectIsAcyclic(a));

    // cyclic due to edge from e to b
    putAndExpectIllegalArgumentException(e, "b", b);
    assertTrue(Data.objectIsAcyclic(a));

    // cyclic due to edge from e to a
    putAndExpectIllegalArgumentException(e, "a", a);
    assertTrue(Data.objectIsAcyclic(a));
  }