/**
  * Constructs an EntityChange from the given old and new Entity.
  *
  * @since 0.5
  *
  * @param string      $action The action name
  * @param EntityDocument|null $oldEntity
  * @param EntityDocument|null $newEntity
  * @param array $fields additional fields to set
  *
  * @return EntityChange
  * @throws MWException
  */
 public function newFromUpdate($action, EntityDocument $oldEntity = null, EntityDocument $newEntity = null, array $fields = array())
 {
     if ($oldEntity === null && $newEntity === null) {
         throw new MWException('Either $oldEntity or $newEntity must be given');
     }
     if ($oldEntity === null) {
         $oldEntity = $this->entityFactory->newEmpty($newEntity->getType());
         $id = $newEntity->getId();
     } elseif ($newEntity === null) {
         $newEntity = $this->entityFactory->newEmpty($oldEntity->getType());
         $id = $oldEntity->getId();
     } elseif ($oldEntity->getType() !== $newEntity->getType()) {
         throw new MWException('Entity type mismatch');
     } else {
         $id = $newEntity->getId();
     }
     // HACK: don't include statements diff, since those are unused and not helpful
     // performance-wise to the dispatcher and change handling.
     // For a better solution, see T113468.
     if ($oldEntity instanceof StatementListHolder) {
         $oldEntity->setStatements(new StatementList());
         $newEntity->setStatements(new StatementList());
     }
     $diff = $this->entityDiffer->diffEntities($oldEntity, $newEntity);
     /** @var EntityChange $instance */
     $instance = self::newForEntity($action, $id, $fields);
     $instance->setDiff($diff);
     return $instance;
 }
 /**
  * @param EntityDocument $entity
  *
  * @return EntityDocument
  */
 private function clearEntity(EntityDocument $entity)
 {
     $newEntity = $this->entityFactory->newEmpty($entity->getType());
     $newEntity->setId($entity->getId());
     // FIXME how to avoid special case handling here?
     if ($entity instanceof Property) {
         /** @var Property $newEntity */
         $newEntity->setDataTypeId($entity->getDataTypeId());
     }
     return $newEntity;
 }
 private function makeDiff($objectId, $revA, $revB)
 {
     $entityClasses = array(Item::ENTITY_TYPE => 'Wikibase\\DataModel\\Entity\\Item');
     $lookup = $this->getEntityRevisionLookup();
     $entityFactory = new EntityFactory($entityClasses);
     $itemId = new ItemId($objectId);
     if ($revA === 0) {
         $oldEntity = $entityFactory->newEmpty(Item::ENTITY_TYPE);
     } else {
         $oldEntity = $lookup->getEntityRevision($itemId, $revA)->getEntity();
     }
     if ($revB === 0) {
         $newEntity = $entityFactory->newEmpty(Item::ENTITY_TYPE);
     } else {
         $newEntity = $lookup->getEntityRevision($itemId, $revB)->getEntity();
     }
     $differ = new ItemDiffer();
     return $differ->diffEntities($oldEntity, $newEntity);
 }