public function moveDrop(Model $model, $id = null, $newParentId = null, $oldParentId = null, $dropData = null) {
		if (empty($id)) {
			return false;
		}

		$changeRoot = false;
		$dataSource = $model->getDataSource();
		$dataSource->begin();
		if ($newParentId != $oldParentId) {
			$changeRoot = true;
			if (!$this->_changeParent($model, $id, $newParentId)) {
				$dataSource->rollback();

				return false;
			}
		}

		$newDataList = [];
		if (!empty($dropData) && is_array($dropData)) {
			$newDataList = Hash::extract($dropData, '0.{n}.id');
		}
		$oldDataList = $this->_getSubTree($model, $newParentId);
		if ($newDataList == $oldDataList) {
			if (!$changeRoot) {
				return true;
			}

			$dataSource->rollback();

			return false;
		}

		$indexNew = array_search($id, $newDataList);
		$indexOld = array_search($id, $oldDataList);
		if (($indexNew === false) || ($indexOld === false)) {
			return false;
		}

		$delta = $indexNew - $indexOld;
		$method = 'moveDown';
		if ($delta < 0) {
			$delta *= -1;
			$method = 'moveUp';
		}

		$optionsEvent = compact('id', 'newParentId', 'method', 'delta');
		$event = new CakeEvent('Model.beforeUpdateTree', $model, [$optionsEvent]);
		$model->getEventManager()->dispatch($event);
		if ($event->isStopped()) {
			$dataSource->rollback();

			return false;
		}

		$result = $model->$method($id, $delta);
		if ($result) {
			$dataSource->commit();
			$event = new CakeEvent('Model.afterUpdateTree', $model);
			$model->getEventManager()->dispatch($event);
		} else {
			$dataSource->rollback();
		}

		return $result;
	}