/**
  * @internal
  *
  * @return void
  */
 protected function saveManagedObject(MManagedObject $object)
 {
     if ($object->hasChanges()) {
         // Inform the object that it is about to be saved
         $object->_willStartSaving();
         // Save object's updated data
         if ($object->_hasUpdatedData()) {
             $data = $this->unpackData($object->_updatedData(), $object->entity());
             if ($object->objectID() == MManagedObject::UNKNOWN_ID) {
                 $statements = A(array_fill(0, $data->count(), S("?")));
                 $query = Sf("INSERT INTO `%s` (`%s`) VALUES (%s);", $object->entity()->plural(), $data->allKeys()->componentsJoinedByString(S("`, `")), $statements->componentsJoinedByString(S(", ")));
                 $statement = $this->connection()->prepare($query->stringValue());
                 if (!$statement->execute($data->allObjects()->toArray())) {
                     throw new MPersistentStoreException(Sf("Could not save entity [%s]", $object->entity()->name()));
                 }
                 $object->_setObjectID((int) $this->connection()->lastInsertId());
             } else {
                 $statements = new MMutableArray();
                 foreach ($data->allKeys()->toArray() as $field) {
                     $statements->addObject(Sf("`%s` = ?", $field));
                 }
                 $query = Sf("UPDATE `%s` SET %s WHERE `objectID` = %s;", $object->entity()->plural(), $statements->componentsJoinedByString(S(", ")), $object->objectID());
                 $statement = $this->connection()->prepare($query->stringValue());
                 if (!$statement->execute($data->allObjects()->toArray())) {
                     throw new MPersistentStoreException(Sf("Could not save entity [%s]", $object->entity()->name()));
                 }
             }
         }
         // Save object's inserted relationships
         if ($object->_hasInsertedRelationships()) {
             foreach ($object->_insertedRelationships()->allKeys()->toArray() as $relationshipName) {
                 if (!$object->_isSavingInsertedObjectsForRelationshipName($relationshipName)) {
                     $relationshipObjects = $object->_insertedRelationships()->objectForKey($relationshipName);
                     $relationship = $object->entity()->attributeWithName($relationshipName);
                     foreach ($relationshipObjects->toArray() as $relationshipObject) {
                         $relationshipObject->_willSaveInsertedObjectsForRelationshipName($relationship->inverseRelationship()->name());
                         $this->saveManagedObject($relationshipObject);
                         $query = Sf("INSERT INTO `%s` (`%s`, `%s`) VALUES (%s);", $relationship->tableName(), $relationship->columnName(), $relationship->inverseColumnName(), S("?, ?"));
                         $statement = $this->connection()->prepare($query->stringValue());
                         if (!$statement->execute(array($object->objectID(), $relationshipObject->objectID()))) {
                             throw new MPersistentStoreException(Sf("Could not save relationship [%s] on entity [%s]", $relationshipName, $object->entity()->name()));
                         }
                         $relationshipObject->_didSaveInsertedObjectsForRelationshipName($relationship->inverseRelationship()->name());
                     }
                 }
             }
         }
         // Delete object's removed relationships
         if ($object->_hasRemovedRelationships()) {
             foreach ($object->_removedRelationships()->allKeys()->toArray() as $relationshipName) {
                 if (!$object->_isSavingRemovedObjectsForRelationshipName($relationshipName)) {
                     $relationshipObjects = $object->_removedRelationships()->objectForKey($relationshipName);
                     $relationship = $object->entity()->attributeWithName($relationshipName);
                     foreach ($relationshipObjects->toArray() as $relationshipObject) {
                         $relationshipObject->_willSaveRemovedObjectsForRelationshipName($relationship->inverseRelationship()->name());
                         $this->saveManagedObject($relationshipObject);
                         $query = Sf("DELETE FROM `%s` WHERE `%s` = ?;", $relationship->tableName(), $relationship->inverseColumnName());
                         $statement = $this->connection()->prepare($query->stringValue());
                         if (!$statement->execute(array($relationshipObject->objectID()))) {
                             throw new MPersistentStoreException(Sf("Could not remove relationship [%s] on entity [%s]", $relationshipName, $object->entity()->name()));
                         }
                         $relationshipObject->_didSaveRemovedObjectsForRelationshipName($relationship->inverseRelationship()->name());
                     }
                 }
             }
         }
         // Tell the object to persit it's changes
         $object->persistChanges();
         // Inform the object that it has finished being saved
         $object->_didFinishSaving();
     }
 }