private function computeSingleDocumentChangeSet($document)
    {
        $state = $this->getDocumentState($document);

        if ($state !== self::STATE_MANAGED && $state !== self::STATE_REMOVED) {
            throw new \InvalidArgumentException("Document has to be managed or scheduled for removal for single computation " . self::objToStr($document));
        }

        $class = $this->dm->getClassMetadata(get_class($document));

        if ($state === self::STATE_MANAGED && $class->isChangeTrackingDeferredImplicit()) {
            $this->persist($document);
        }

        // Compute changes for INSERTed and UPSERTed documents first. This must always happen even in this case.
        $this->computeScheduleInsertsChangeSets();
        $this->computeScheduleUpsertsChangeSets();

        // Ignore uninitialized proxy objects
        if ($document instanceof Proxy && ! $document->__isInitialized__) {
            return;
        }

        // Only MANAGED documents that are NOT SCHEDULED FOR INSERTION, UPSERT OR DELETION are processed here.
        $oid = spl_object_hash($document);

        if ( ! isset($this->documentInsertions[$oid])
            && ! isset($this->documentUpserts[$oid])
            && ! isset($this->documentDeletions[$oid])
            && isset($this->documentStates[$oid])
        ) {
            $this->computeChangeSet($class, $document);
        }
    }