/** Method to update m to n relationship. 
	* Called by PntObjectSaveAction if no corrsponding update method
	* or from update method
	* ( $updatemethodName = $mToNproperty~>getName(). 'NtoMmodIds'; )
	* update methods have the same arguments as the last two arguments of this method.
	* only works for two step relations to & through pntDbObjectswith
	* id properties corrsponding to the steps and mapped to the database
	* 
	* You should avoid overlap between $idsToAdd and $idsToRemove because 
	* duplicate relations with ids in $idsToRemove will all be removed without respect to
	* the number of (duplicate) ids in $idsToRemove.
	* @precondition $derivationPath must be set.
	* @param String $path from $this to the m to n related objects 
	*	(two steps, like the result of "$1ToNpropertyName.$nTo1propertyName")
	* @param Array $idsToAdd ids of the objects that should be added to the relation
	* @param Array $idsToRemove ids of the objets that should be removed from the relation
	* @throws PntReflectionError
	*/
	function mutateRelationFor_ids($obj, $idsToAdd, $idsToRemove) {
		//to be refactored
		try {
			$nav = $this->getDerivationNav();
			
			$relationObjCls = $nav->getStepResultType();
			$relationObjClsDes = PntClassDescriptor::getInstance($relationObjCls);
			$firstProp = $nav->getFirstProp();
			$ownIdProp = $firstProp->getIdPropertyDescriptor();
			$lastProp = $nav->getLastProp();
			$otherIdProp = $lastProp->getIdPropertyDescriptor();
			$ownId = $obj->get('id');
	
			//deleteFromRelation_ids
			if (count($idsToRemove) > 0) {
				$qh = $relationObjClsDes->getSelectQueryHandler();
				$qh->where_equals($ownIdProp->getColumnName(), $ownId);
				$qh->query .= " AND ";
				$qh->in($otherIdProp->getColumnName(), $idsToRemove);
				$toDelete = $relationObjClsDes->getPeanutsRunQueryHandler($qh);
				forEach(array_keys($toDelete) as $key) 
					$toDelete[$key]->delete();
			}
			
			//addToRelation_ids
			forEach($idsToAdd as $otherId) {
				$newObj = new $relationObjCls();
				$result = $ownIdProp->setValue_for($ownId, $newObj);
				if (Gen::is_a($result, 'PntError') )
					trigger_error($result->getLabel(), E_USER_ERROR);
				$result = $otherIdProp->setValue_for($otherId, $newObj);
				if (Gen::is_a($result, 'PntError') )
					trigger_error($result->getLabel(), E_USER_ERROR);
				$newObj->save();
			}
		} catch (PntError $err) {
			throw new PntReflectionError("$this could not update relation for $obj", 0, $err);
		}
	}