/**
  * Prepares the array that is ready to be inserted to mongodb for a given object document.
  *
  * @param ClassMetadata $class
  * @param UnitOfWork    $uow
  * @param object        $document
  *
  * @return \stdClass $insertData
  * @throws ODMOrientDbException
  */
 public function prepareData(ClassMetadata $class, UnitOfWork $uow, $document)
 {
     $insertData = new \stdClass();
     if ($class->isEmbeddedDocument()) {
         $insertData->{'@type'} = 'd';
         $insertData->{'@class'} = $class->getOrientClass();
         $cs = $uow->getDocumentActualData($document);
     } else {
         $cs = $uow->getDocumentChangeSet($document);
         array_Walk($cs, function (&$val) {
             $val = $val[1];
         });
     }
     $mappings =& $class->fieldMappings;
     foreach ($cs as $name => $new) {
         $mapping = isset($mappings[$name]) ? $mappings[$name] : null;
         if ($mapping === null) {
             // don't store arbitrary values for now
             continue;
         }
         // Don't store null values unless nullable === true
         if ($new === null && $mapping['nullable'] === false) {
             continue;
         }
         $value = null;
         if ($new !== null) {
             switch (true) {
                 // @Property
                 case !isset($mapping['association']):
                     $value = Type::getType($mapping['type'])->convertToDatabaseValue($new);
                     break;
                 case $mapping['association'] & ClassMetadata::LINK:
                     $value = $this->getDocReference($new);
                     break;
                 case $mapping['association'] & ClassMetadata::LINK_MANY:
                     // initialize the link collection
                     if ($mapping['association'] & ClassMetadata::LINK_MAP) {
                         $value = new \stdClass();
                     } else {
                         $value = [];
                     }
                     break;
                 case $mapping['association'] & ClassMetadata::EMBED:
                     /** @var ClassMetadata $rmd */
                     $rmd = $this->metadataFactory->getMetadataFor(get_class($new));
                     $value = $this->prepareData($rmd, $uow, $new);
                     break;
                 case $mapping['association'] & ClassMetadata::EMBED_MANY:
                     $value = [];
                     if ($mapping['association'] & ClassMetadata::EMBED_MAP) {
                         foreach ($new as $k => $item) {
                             /** @var ClassMetadata $rmd */
                             $rmd = $this->metadataFactory->getMetadataFor(get_class($item));
                             $value[$k] = $this->prepareData($rmd, $uow, $item);
                         }
                     } else {
                         foreach ($new as $k => $item) {
                             /** @var ClassMetadata $rmd */
                             $rmd = $this->metadataFactory->getMetadataFor(get_class($item));
                             $value[] = $this->prepareData($rmd, $uow, $item);
                         }
                     }
                     break;
             }
         }
         $insertData->{$mapping['name']} = $value;
     }
     return $insertData;
 }