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 testDataListNoCyclesOnAdd()
  {
    // test with DataList

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

    a.add(b);
    a.add(c);

    assertTrue(Data.objectIsAcyclic(a));

    DataList d = new DataList();
    b.add(d);
    c.add(d);

    assertTrue(Data.objectIsAcyclic(a));

    DataList e = new DataList();
    d.add(e);

    assertTrue(Data.objectIsAcyclic(a));

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

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

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

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

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