graphdb/src/main/java/com/orientechnologies/orient/graph/gremlin/OGremlinHelper.java
@SuppressWarnings({ "rawtypes", "unchecked" })
  public static Object cloneObject(final Object objectToClone, final Object previousClone) {

    // ***************************************************************************************************************************************
    // 1. Class by class cloning (only clones known types)
    // ***************************************************************************************************************************************
    // Clone any Map (shallow clone should be enough at this level)
    if (objectToClone instanceof Map) {
      Map recycledMap = (Map) previousClone;
      if (recycledMap == null)
        recycledMap = new HashMap();
      else
        recycledMap.clear();
      recycledMap.putAll((Map<?, ?>) objectToClone);
      return recycledMap;

      // Clone any collection (shallow clone should be enough at this level)
    } else if (objectToClone instanceof Collection) {
      Collection recycledCollection = (Collection) previousClone;
      if (recycledCollection == null)
        recycledCollection = new ArrayList();
      else
        recycledCollection.clear();
      recycledCollection.addAll((Collection<?>) objectToClone);
      return recycledCollection;

      // Clone String
    } else if (objectToClone instanceof String) {
      return objectToClone;
    } else if (objectToClone instanceof Number) {
      return objectToClone;
      // Clone Date
    } else if (objectToClone instanceof Date) {
      return (Date) ((Date) objectToClone).clone();

    } else {
      // ***************************************************************************************************************************************
      // 2. Polymorphic clone (by reflection, looks for a clone() method in hierarchy and invoke it)
      // ***************************************************************************************************************************************
      try {
        Object newClone;
        for (Class<?> obj = objectToClone.getClass(); !obj.equals(Object.class); obj = obj.getSuperclass()) {
          Method m[] = obj.getDeclaredMethods();
          for (int i = 0; i < m.length; i++) {
            if (m[i].getName().equals("clone")) {
              m[i].setAccessible(true);
              newClone = m[i].invoke(objectToClone);
              System.out.println(objectToClone.getClass()
                  + " cloned by Reflection. Performance can be improved by adding the class to the list of known types");
              return newClone;
            }
          }
        }
        throw new Exception("Method clone not found");

        // ***************************************************************************************************************************************
        // 3. Polymorphic clone (Deep cloning by Serialization)
        // ***************************************************************************************************************************************
      } catch (Exception e1) {
        try {
          final ByteArrayOutputStream bytes = new ByteArrayOutputStream() {
            public synchronized byte[] toByteArray() {
              return buf;
            }
          };
          final ObjectOutputStream out = new ObjectOutputStream(bytes);
          out.writeObject(objectToClone);
          out.close();
          final ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes.toByteArray()));
          System.out.println(objectToClone.getClass()
              + " cloned by Serialization. Performance can be improved by adding the class to the list of known types");
          return in.readObject();

          // ***************************************************************************************************************************************
          // 4. Impossible to clone
          // ***************************************************************************************************************************************
        } catch (Exception e2) {
          OLogManager.instance()
              .error(null, "[GremlinHelper] error on cloning object %s, previous %s", e2, objectToClone, previousClone);
          return null;
        }
      }
    }
  }
@SuppressWarnings({ "rawtypes", "unchecked" })
  public static Object cloneObject(final Object objectToClone, final Object previousClone) {

    // ***************************************************************************************************************************************
    // 1. Class by class cloning (only clones known types)
    // ***************************************************************************************************************************************
    // Clone any Map (shallow clone should be enough at this level)
    if (objectToClone instanceof Map) {
      Map recycledMap = (Map) previousClone;
      if (recycledMap == null)
        recycledMap = new HashMap();
      else
        recycledMap.clear();
      recycledMap.putAll((Map<?, ?>) objectToClone);
      return recycledMap;

      // Clone any collection (shallow clone should be enough at this level)
    } else if (objectToClone instanceof Collection) {
      Collection recycledCollection = (Collection) previousClone;
      if (recycledCollection == null)
        recycledCollection = new ArrayList();
      else
        recycledCollection.clear();
      recycledCollection.addAll((Collection<?>) objectToClone);
      return recycledCollection;

      // Clone String
    } else if (objectToClone instanceof String) {
      return objectToClone;
    } else if (objectToClone instanceof Number) {
      return objectToClone;
      // Clone Date
    } else if (objectToClone instanceof Date) {
      return (Date) ((Date) objectToClone).clone();

    } else {
      // ***************************************************************************************************************************************
      // 2. Polymorphic clone (by reflection, looks for a clone() method in hierarchy and invoke it)
      // ***************************************************************************************************************************************
      try {
        Object newClone;
        for (Class<?> obj = objectToClone.getClass(); !obj.equals(Object.class); obj = obj.getSuperclass()) {
          Method m[] = obj.getDeclaredMethods();
          for (int i = 0; i < m.length; i++) {
            if (m[i].getName().equals("clone")) {
              m[i].setAccessible(true);
              newClone = m[i].invoke(objectToClone);
              System.out.println(objectToClone.getClass()
                  + " cloned by Reflection. Performance can be improved by adding the class to the list of known types");
              return newClone;
            }
          }
        }
        throw new Exception("Method clone not found");

        // ***************************************************************************************************************************************
        // 3. Polymorphic clone (Deep cloning by Serialization)
        // ***************************************************************************************************************************************
      } catch (Exception e1) {
        try {
          final ByteArrayOutputStream bytes = new ByteArrayOutputStream() {
            public synchronized byte[] toByteArray() {
              return buf;
            }
          };
          final ObjectOutputStream out = new ObjectOutputStream(bytes);
          out.writeObject(objectToClone);
          out.close();
          final ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes.toByteArray()));
          System.out.println(objectToClone.getClass()
              + " cloned by Serialization. Performance can be improved by adding the class to the list of known types");
          return in.readObject();

          // ***************************************************************************************************************************************
          // 4. Impossible to clone
          // ***************************************************************************************************************************************
        } catch (Exception e2) {
          OLogManager.instance()
              .error(null, "[GremlinHelper] error on cloning object %s, previous %s", e2, objectToClone, previousClone);
          return null;
        }
      }
    }
  }
/*
Tries to clone any Java object by using 3 techniques: - instanceof (most verbose but faster performance) - reflection (medium
performance) - serialization (applies for any object type but has a performance overhead)