title: Direct copy of mongodb Document object
body: <p>Long story short, I am working inside of a giant nasty recursive function that is building out a mongo Document object. I have to extend the functionality of this function to support complex queries and need to know how to create a direct copy (not object reference) of a mongo Document object. Is there any way of doing this? The current implementation does the following:</p>
  
  <pre><code>private Document generateArrayAddsDoc(DataChanges dataChanges, Document filter)
      {
          Document arrayUpdatesDoc = new Document();
          generateArrayDocImpl(arrayUpdatesDoc, null, dataChanges, DataChanges.Type.MODEL_ADD, filter, 0);
          return arrayUpdatesDoc;
      }
  </code></pre>
  
  <p>Here is the nasty recursive function just for context:</p>
  
  <pre><code>private void generateArrayDocImpl(Document arrayUpdateDoc, String parentFieldName, DataChanges dataChanges, DataChanges.Type type, Document filter, int currentLevel)
      {
          switch (dataChanges.getType())
          {
              case MODEL_UPDATE:
              {
                  for (DataChange dataChange : dataChanges.getDataChanges())
                  {
                      if (dataChange.getNewValue() instanceof DataChanges)
                      {
                          DataChanges arrayChanges = (DataChanges) dataChange.getNewValue();
  
                          Document arrayDoc = new Document();
                          String dotFieldName = generateDotFieldName(parentFieldName, dataChange.getFieldName());
  
                          if (type == DataChanges.Type.MODEL_ADD || type == DataChanges.Type.MODEL_DELETE)
                          {
                              generateArrayDocImpl(arrayDoc, dotFieldName, arrayChanges, type, filter, currentLevel+1);
                          }
  
                          if (!arrayDoc.isEmpty())
                          {
                              if (currentLevel &gt; 0)
                              {
                                  arrayUpdateDoc.append(dotFieldName, arrayDoc);
                              }
                              else
                              {
                                  arrayUpdateDoc = arrayDoc; // need to direct copy instead of referencing here
                              }
                          }
                      }
                  }
  
                  break;
              }
              case ARRAY_UPDATE:
              {
                  List&lt;Document&gt; updateDocsList = new ArrayList&lt;&gt;();
                  for (DataChange dataChange : dataChanges.getDataChanges())
                  {
                      Document arrayElementDoc = null;
                      DataChanges arrayElementChanges = (DataChanges) dataChange.getNewValue();
  
                      if (arrayElementChanges.getType() == type)
                      {
                          arrayElementDoc = generateFieldUpdatesDoc(arrayElementChanges, filter);
                      }
                      else if (arrayElementChanges.getType() == DataChanges.Type.MODEL_UPDATE)
                      {
                          String dotFieldName = generateDollarSignIndexedFieldName(parentFieldName, dataChange.getFieldName());
                          generateArrayDocImpl(arrayUpdateDoc, dotFieldName, arrayElementChanges, type, filter, currentLevel+1);
                      }
  
                      if (null != arrayElementDoc &amp;&amp; !arrayElementDoc.isEmpty())
                      {
                          updateDocsList.add(arrayElementDoc);
                      }
                  }
  
                  if (!updateDocsList.isEmpty() &amp;&amp; type == DataChanges.Type.MODEL_ADD)
                  {
                      arrayUpdateDoc.append("$each", updateDocsList);
                  }
  
                  if (!updateDocsList.isEmpty() &amp;&amp; type == DataChanges.Type.MODEL_DELETE)
                  {
                      String fieldName = pullFieldNameFromList(updateDocsList);
                      List&lt;String&gt; valuesToDelete = getValuesToDelete(updateDocsList);
  
                      Document doc = new Document();
                      doc.append("$in", valuesToDelete);
  
                      arrayUpdateDoc.append(fieldName, doc);
                  }
  
                  break;
              }
          }
      }
  </code></pre>
  
  <p>Where this function is doing "arrayUpdateDoc = arrayDoc;", I need to copy document into a new object because arrayDoc is being destroyed after this function call is finished resulting in a bug. Any recommendations on doing a direct object copy (not by reference) of a mongo Document object would be greatly appreciated!</p>