protected function doMoveBefore() {
    $request = $this->getRequest();
    $persistenceFacade = $this->getPersistenceFacade();
    $isOrderBottom = $this->isOrderBotton($request);

    // load the moved object and the reference object
    $insertOid = ObjectId::parse($request->getValue('insertOid'));
    $referenceOid = ObjectId::parse($request->getValue('referenceOid'));
    $insertObject = $persistenceFacade->load($insertOid);
    $referenceObject = $isOrderBottom ? new NullNode() : $persistenceFacade->load($referenceOid);

    // check object existence
    $objectMap = ['insertOid' => $insertObject,
        'referenceOid' => $referenceObject];
    if ($this->checkObjects($objectMap)) {
      // determine the sort key
      $mapper = $insertObject->getMapper();
      $type = $insertObject->getType();
      $sortkeyDef = $mapper->getSortkey();
      $sortkey = $sortkeyDef['sortFieldName'];
      $sortdir = strtoupper($sortkeyDef['sortDirection']);

      // get the sortkey values of the objects before and after the insert position
      if ($isOrderBottom) {
        $lastObject = $this->loadLastObject($type, $sortkey, $sortdir);
        $prevValue = $lastObject != null ? $this->getSortkeyValue($lastObject, $sortkey) : 1;
        $nextValue = ceil($sortdir == 'ASC' ? $prevValue+1 : $prevValue-1);
      }
      else {
        $nextValue = $this->getSortkeyValue($referenceObject, $sortkey);
        $prevObject = $this->loadPreviousObject($type, $sortkey, $nextValue, $sortdir);
        $prevValue = $prevObject != null ? $this->getSortkeyValue($prevObject, $sortkey) :
          ceil($sortdir == 'ASC' ? $nextValue-1 : $nextValue+1);
      }

      // set the sortkey value to the average
      $insertObject->setValue($sortkey, ($nextValue+$prevValue)/2);
    }
  }