diff --git a/lib/Doctrine/ORM/PersistentCollection.php b/lib/Doctrine/ORM/PersistentCollection.php
index a4b579b7e..48daa4dc6 100644
--- a/lib/Doctrine/ORM/PersistentCollection.php
+++ b/lib/Doctrine/ORM/PersistentCollection.php
@@ -19,7 +19,6 @@
 
 namespace Doctrine\ORM;
 
-use Closure;
 use Doctrine\Common\Collections\AbstractLazyCollection;
 use Doctrine\Common\Collections\Collection;
 use Doctrine\Common\Collections\ArrayCollection;
@@ -685,21 +684,41 @@ final class PersistentCollection extends AbstractLazyCollection implements Selec
     protected function doInitialize()
     {
         // Has NEW objects added through add(). Remember them.
-        $newObjects = array();
+        $newlyAddedDirtyObjects = array();
 
         if ($this->isDirty) {
-            $newObjects = $this->collection->toArray();
+            $newlyAddedDirtyObjects = $this->collection->toArray();
         }
 
         $this->collection->clear();
         $this->em->getUnitOfWork()->loadCollection($this);
         $this->takeSnapshot();
 
-        // Reattach NEW objects added through add(), if any.
-        if ($newObjects) {
-            foreach ($newObjects as $obj) {
-                $this->collection->add($obj);
-            }
+        if ($newlyAddedDirtyObjects) {
+            $this->restoreNewObjectsInDirtyCollection($newlyAddedDirtyObjects);
+        }
+    }
+
+    /**
+     * @param object[] $newObjects
+     *
+     * @return void
+     *
+     * Note: the only reason why this entire looping/complexity is performed via `spl_object_hash`
+     *       is because we want to prevent using `array_udiff()`, which is likely to cause very
+     *       high overhead (complexity of O(n^2)). `array_diff_key()` performs the operation in
+     *       core, which is faster than using a callback for comparisons
+     */
+    private function restoreNewObjectsInDirtyCollection(array $newObjects)
+    {
+        $loadedObjects               = $this->collection->toArray();
+        $newObjectsByOid             = \array_combine(\array_map('spl_object_hash', $newObjects), $newObjects);
+        $loadedObjectsByOid          = \array_combine(\array_map('spl_object_hash', $loadedObjects), $loadedObjects);
+        $newObjectsThatWereNotLoaded = \array_diff_key($newObjectsByOid, $loadedObjectsByOid);
+
+        if ($newObjectsThatWereNotLoaded) {
+            // Reattach NEW objects added through add(), if any.
+            \array_walk($newObjectsThatWereNotLoaded, [$this->collection, 'add']);
 
             $this->isDirty = true;
         }
diff --git a/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php b/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php
index 190fe2ef1..2ca179ef9 100644
--- a/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php
+++ b/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php
@@ -4,6 +4,7 @@ namespace Doctrine\Tests\ORM;
 
 use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\ORM\PersistentCollection;
+use Doctrine\ORM\UnitOfWork;
 use Doctrine\Tests\Mocks\ConnectionMock;
 use Doctrine\Tests\Mocks\DriverMock;
 use Doctrine\Tests\Mocks\EntityManagerMock;
@@ -23,7 +24,7 @@ class PersistentCollectionTest extends OrmTestCase
     protected $collection;
 
     /**
-     * @var \Doctrine\ORM\EntityManagerInterface
+     * @var EntityManagerMock
      */
     private $_emMock;
 
@@ -32,6 +33,8 @@ class PersistentCollectionTest extends OrmTestCase
         parent::setUp();
 
         $this->_emMock = EntityManagerMock::create(new ConnectionMock([], new DriverMock()));
+
+        $this->setUpPersistentCollection();
     }
 
     /**
@@ -58,7 +61,6 @@ class PersistentCollectionTest extends OrmTestCase
      */
     public function testCurrentInitializesCollection()
     {
-        $this->setUpPersistentCollection();
         $this->collection->current();
         $this->assertTrue($this->collection->isInitialized());
     }
@@ -68,7 +70,6 @@ class PersistentCollectionTest extends OrmTestCase
      */
     public function testKeyInitializesCollection()
     {
-        $this->setUpPersistentCollection();
         $this->collection->key();
         $this->assertTrue($this->collection->isInitialized());
     }
@@ -78,7 +79,6 @@ class PersistentCollectionTest extends OrmTestCase
      */
     public function testNextInitializesCollection()
     {
-        $this->setUpPersistentCollection();
         $this->collection->next();
         $this->assertTrue($this->collection->isInitialized());
     }
@@ -88,12 +88,12 @@ class PersistentCollectionTest extends OrmTestCase
      */
     public function testRemovingElementsAlsoRemovesKeys()
     {
-        $this->setUpPersistentCollection();
+        $dummy = new \stdClass();
 
-        $this->collection->add('dummy');
+        $this->collection->add($dummy);
         $this->assertEquals([0], array_keys($this->collection->toArray()));
 
-        $this->collection->removeElement('dummy');
+        $this->collection->removeElement($dummy);
         $this->assertEquals([], array_keys($this->collection->toArray()));
     }
 
@@ -102,9 +102,7 @@ class PersistentCollectionTest extends OrmTestCase
      */
     public function testClearWillAlsoClearKeys()
     {
-        $this->setUpPersistentCollection();
-
-        $this->collection->add('dummy');
+        $this->collection->add(new \stdClass());
         $this->collection->clear();
         $this->assertEquals([], array_keys($this->collection->toArray()));
     }
@@ -114,12 +112,133 @@ class PersistentCollectionTest extends OrmTestCase
      */
     public function testClearWillAlsoResetKeyPositions()
     {
-        $this->setUpPersistentCollection();
+        $dummy = new \stdClass();
 
-        $this->collection->add('dummy');
-        $this->collection->removeElement('dummy');
+        $this->collection->add($dummy);
+        $this->collection->removeElement($dummy);
         $this->collection->clear();
-        $this->collection->add('dummy');
+        $this->collection->add($dummy);
         $this->assertEquals([0], array_keys($this->collection->toArray()));
     }
+
+    /**
+     * @group 6613
+     * @group 6614
+     * @group 6616
+     */
+    public function testWillKeepNewItemsInDirtyCollectionAfterInitialization()
+    {
+        /* @var $unitOfWork UnitOfWork|\PHPUnit_Framework_MockObject_MockObject */
+        $unitOfWork = $this->createMock(UnitOfWork::class);
+
+        $this->_emMock->setUnitOfWork($unitOfWork);
+
+        $newElement       = new \stdClass();
+        $persistedElement = new \stdClass();
+
+        $this->collection->add($newElement);
+
+        self::assertFalse($this->collection->isInitialized());
+        self::assertTrue($this->collection->isDirty());
+
+        $unitOfWork
+            ->expects(self::once())
+            ->method('loadCollection')
+            ->with($this->collection)
+            ->willReturnCallback(function (PersistentCollection $persistentCollection) use ($persistedElement) {
+                $persistentCollection->unwrap()->add($persistedElement);
+            });
+
+        $this->collection->initialize();
+
+        self::assertSame([$persistedElement, $newElement], $this->collection->toArray());
+        self::assertTrue($this->collection->isInitialized());
+        self::assertTrue($this->collection->isDirty());
+    }
+
+    /**
+     * @group 6613
+     * @group 6614
+     * @group 6616
+     */
+    public function testWillDeDuplicateNewItemsThatWerePreviouslyPersistedInDirtyCollectionAfterInitialization()
+    {
+        /* @var $unitOfWork UnitOfWork|\PHPUnit_Framework_MockObject_MockObject */
+        $unitOfWork = $this->createMock(UnitOfWork::class);
+
+        $this->_emMock->setUnitOfWork($unitOfWork);
+
+        $newElement                    = new \stdClass();
+        $newElementThatIsAlsoPersisted = new \stdClass();
+        $persistedElement              = new \stdClass();
+
+        $this->collection->add($newElementThatIsAlsoPersisted);
+        $this->collection->add($newElement);
+
+        self::assertFalse($this->collection->isInitialized());
+        self::assertTrue($this->collection->isDirty());
+
+        $unitOfWork
+            ->expects(self::once())
+            ->method('loadCollection')
+            ->with($this->collection)
+            ->willReturnCallback(function (PersistentCollection $persistentCollection) use (
+                $persistedElement,
+                $newElementThatIsAlsoPersisted
+            ) {
+                $persistentCollection->unwrap()->add($newElementThatIsAlsoPersisted);
+                $persistentCollection->unwrap()->add($persistedElement);
+            });
+
+        $this->collection->initialize();
+
+        self::assertSame(
+            [$newElementThatIsAlsoPersisted, $persistedElement, $newElement],
+            $this->collection->toArray()
+        );
+        self::assertTrue($this->collection->isInitialized());
+        self::assertTrue($this->collection->isDirty());
+    }
+
+    /**
+     * @group 6613
+     * @group 6614
+     * @group 6616
+     */
+    public function testWillNotMarkCollectionAsDirtyAfterInitializationIfNoElementsWereAdded()
+    {
+        /* @var $unitOfWork UnitOfWork|\PHPUnit_Framework_MockObject_MockObject */
+        $unitOfWork = $this->createMock(UnitOfWork::class);
+
+        $this->_emMock->setUnitOfWork($unitOfWork);
+
+        $newElementThatIsAlsoPersisted = new \stdClass();
+        $persistedElement              = new \stdClass();
+
+        $this->collection->add($newElementThatIsAlsoPersisted);
+
+        self::assertFalse($this->collection->isInitialized());
+        self::assertTrue($this->collection->isDirty());
+
+        $unitOfWork
+            ->expects(self::once())
+            ->method('loadCollection')
+            ->with($this->collection)
+            ->willReturnCallback(function (PersistentCollection $persistentCollection) use (
+                $persistedElement,
+                $newElementThatIsAlsoPersisted
+            ) {
+                $persistentCollection->unwrap()->add($newElementThatIsAlsoPersisted);
+                $persistentCollection->unwrap()->add($persistedElement);
+            });
+
+        $this->collection->initialize();
+
+        self::assertSame(
+            [$newElementThatIsAlsoPersisted, $persistedElement],
+            $this->collection->toArray()
+        );
+        self::assertTrue($this->collection->isInitialized());
+        self::assertFalse($this->collection->isDirty());
+    }
 }