/**
  * 
  *
  * @return MString
  */
 public function toString()
 {
     if ($this->element()) {
         $markup = new MMutableString();
         $indentString = MString::stringWithRepeatingString(S(" "), $this->indentLevel());
         $properties = new MMutableArray();
         foreach ($this->properties()->allKeys()->toArray() as $name) {
             $value = $this->properties()->objectForKey($name);
             $properties->addObject(Sf("%s=\"%s\"", $name, $value));
         }
         if ($properties->count() > 0) {
             $markup->appendFormat("%s<%s %s", $indentString, $this->element(), $properties->componentsJoinedByString(S(" ")));
         } else {
             $markup->appendFormat("%s<%s", $indentString, $this->element());
         }
         if ($this->text()) {
             $markup->appendFormat(">%s</%s>", $this->text()->stringByEncodingHTMLEntities(), $this->element());
         } else {
             if ($this->subviews()->count() > 0) {
                 $markup->appendLine(S(">"));
                 $markup->appendLine(parent::toString());
                 $markup->appendString(Sf("%s</%s>", $indentString, $this->element()));
             } else {
                 $markup->appendString(S("/>"));
             }
         }
         if ($this->shouldAppendEmptyLine()) {
             $markup->appendLine();
         }
         return $markup;
     } else {
         return parent::toString();
     }
 }
 /**
  * @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();
     }
 }