/**
  * Partial re-order of milestone content relative to one element
  *
  * <br>
  * Example:
  * <pre>
  * "order": {
  *   "ids" : [123, 789, 1001],
  *   "direction": "before",
  *   "compared_to": 456
  * }
  * </pre>
  *
  * <br>
  * Resulting order will be: <pre>[…, 123, 789, 1001, 456, …]</pre>
  *
  * <br>
  * Add example:
  * <pre>
  * "add": [
  *   {
  *     "id": 34
  *     "remove_from": 56
  *   },
  *   ...
  * ]
  * </pre>
  *
  * <br>
  * Will remove element id 34 from milestone 56 content and add it to current milestone content
  *
  * @url PATCH {id}/content
  *
  * @param int                                                $id     Id of the milestone
  * @param \Tuleap\AgileDashboard\REST\v1\OrderRepresentation $order  Order of the children {@from body}
  * @param array                                              $add    Ids to add/move to milestone content  {@from body}
  *
  * @throw 400
  * @throw 403
  * @throw 404
  * @throw 409
  */
 protected function patchContent($id, OrderRepresentation $order = null, array $add = null)
 {
     $user = $this->getCurrentUser();
     $milestone = $this->getMilestoneById($user, $id);
     $this->checkIfUserCanChangePrioritiesInMilestone($milestone, $user);
     try {
         if ($add) {
             $this->resources_patcher->startTransaction();
             $to_add = $this->resources_patcher->removeArtifactFromSource($user, $add);
             if (count($to_add)) {
                 $linked_artifact_ids = $this->milestone_validator->getValidatedArtifactsIdsToAddOrRemoveFromContent($user, $milestone, array(), $to_add);
                 $this->artifactlink_updater->updateArtifactLinks($user, $milestone->getArtifact(), $to_add, array());
                 $this->linkToMilestoneParent($milestone, $user, $to_add);
             }
             $this->resources_patcher->commit();
         }
     } catch (ArtifactDoesNotExistException $exception) {
         throw new RestException(404, $exception->getMessage());
     } catch (ArtifactIsNotInBacklogTrackerException $exception) {
         throw new RestException(404, $exception->getMessage());
     } catch (ArtifactIsClosedOrAlreadyPlannedInAnotherMilestone $exception) {
         throw new RestException(400, $exception->getMessage());
     } catch (IdsFromBodyAreNotUniqueException $exception) {
         throw new RestException(400, $exception->getMessage());
     } catch (Tracker_NoChangeException $exception) {
         //Do nothing
     } catch (Tracker_NoArtifactLinkFieldException $exception) {
         throw new RestException(400, $exception->getMessage());
     } catch (\Exception $exception) {
         throw new RestException(400, $exception->getMessage());
         return;
     }
     try {
         if ($order) {
             $order->checkFormat($order);
             $this->milestone_validator->canOrderContent($user, $milestone, $order);
             $this->resources_patcher->updateArtifactPriorities($order, $id, $milestone->getProject()->getId());
         }
     } catch (IdsFromBodyAreNotUniqueException $exception) {
         throw new RestException(409, $exception->getMessage());
     } catch (OrderIdOutOfBoundException $exception) {
         throw new RestException(409, $exception->getMessage());
     } catch (Tracker_Artifact_Exception_CannotRankWithMyself $exception) {
         throw new RestException(400, $exception->getMessage());
     } catch (\Exception $exception) {
         throw new RestException(400, $exception->getMessage());
     }
     $this->sendAllowHeaderForContent();
 }
 public function itDoesntAddAnElementAlreadyInContent()
 {
     $this->assertEqual($this->milestone_resource_validator->getValidatedArtifactsIdsToAddOrRemoveFromContent($this->user, $this->milestone, null, array(113)), array(112, 113, 114, 115));
 }