static <T> T copy(T object, DataComplexTable alreadyCopied) throws CloneNotSupportedException
  {
    if (object == null)
    {
      return null;
    }
    else if (isComplex(object))
    {
      DataComplex src = (DataComplex) object;

      @SuppressWarnings("unchecked")
      T found = (T) alreadyCopied.get(src);

      if (found != null)
      {
        return found;
      }
      else
      {
        DataComplex clone = src.clone();
        alreadyCopied.put(src, clone);

        if (clone instanceof DataMap)
        {
          ((DataMap)clone).copyReferencedObjects(alreadyCopied);
        }
        else if (clone instanceof DataList)
        {
          ((DataList)clone).copyReferencedObjects(alreadyCopied);
        }

        @SuppressWarnings("unchecked")
        T converted = (T) clone;
        return converted;
      }
    }
    else if (isPrimitive(object))
    {
      return object;
    }
    else
    {
      throw new CloneNotSupportedException("Illegal value encountered: " + object);
    }
  }
@Test
  public void testCopyHashCollisions() throws Exception
  {
    DataMap a = new DataMap();
    a.put("b", new DataMap());
    a.put("c", new DataMap());

    // Use the next hashcode to cause collision.
    a.getDataMap("c")._dataComplexHashCode = DataComplexHashCode.nextHashCode() + 1;
    DataMap copy = a.copy();
    assertNotNull(copy.get("b"));
    assertNotNull(copy.get("c"));
    assertNotSame(copy.get("b"), copy);
    assertNotSame(copy.get("c"), copy);
  }