diff -Naur --exclude=i18n --exclude=var --exclude='#' ../knowledgeTree-3.1b_orig/lib/cache/cache.inc.php ./lib/cache/cache.inc.php
--- ../knowledgeTree-3.1b_orig/lib/cache/cache.inc.php	2006-09-19 14:22:15.000000000 +0200
+++ ./lib/cache/cache.inc.php	2007-03-26 11:19:11.000000000 +0200
@@ -39,9 +39,13 @@
         if (!file_exists($aOptions['cacheDir'])) {
             mkdir($aOptions['cacheDir']);
         }
+
+        // See thirdparty/pear/Cache/Lite.php to customize cache
         $aOptions['lifeTime'] = 60;
         $aOptions['memoryCaching'] = true;
         $aOptions['automaticSerialization'] = true;
+        // Disable fileCaching (when cache > 5Mo)
+        $aOptions['onlyMemoryCaching'] = true;
 
         $this->cacheDir = $aOptions['cacheDir'];
 
--- officialpublicop/lib/i18n/i18nregistry.inc.php	2006-08-29 09:42:37.000000000 +0200
+++ mpublicop/lib/i18n/i18nregistry.inc.php	2007-04-11 11:53:42.000000000 +0200
@@ -50,7 +52,7 @@
         if (is_string($sLang)) {
             $aLang = array($sLang);
         } else {
-            $aLang = $sLang;
+            $aLang =& $sLang;
         }
         $oi18n =& KTUtil::arrayGet($this->_ai18ns, $sDomain);
 
--- officialpublicop/lib/util/ktutil.inc	2006-08-29 09:42:37.000000000 +0200
+++ mpublicop/lib/util/ktutil.inc	2007-04-10 16:41:01.000000000 +0200
@@ -93,12 +93,12 @@
         return $sString;
     }
 
-    function arrayGet($aArray, $sKey, $mDefault = null, $bDefaultIfEmpty = true) {
+    function &arrayGet(&$aArray, $sKey, $mDefault = null, $bDefaultIfEmpty = true) {
         if (empty($aArray)) {
             return $mDefault;
         }
         if (array_key_exists($sKey, $aArray)) {
-            $mVal = $aArray[$sKey];
+            $mVal =& $aArray[$sKey];
             if (empty($mVal) && $bDefaultIfEmpty) {
                 return $mDefault;
             }
--- officialpublicop/lib/session/Session.inc	2006-12-11 18:06:04.000000000 +0100
+++ mpublicop/lib/session/Session.inc	2007-04-10 17:23:27.000000000 +0200
@@ -163,8 +163,8 @@
             );
             require_once(KT_LIB_DIR . '/users/userhistory.inc.php');
             $res = KTUserHistory::createFromArray($aParams);
-
-            DBUtil::whereDelete($sTable, array('id' => $iId));
+			$cond = array('id' => $iId);
+            DBUtil::whereDelete($sTable, $cond);
         }
     }
 
--- officialpublicop/lib/plugins/pluginentity.inc.php	2006-08-29 09:42:37.000000000 +0200
+++ mpublicop/lib/plugins/pluginentity.inc.php	2007-04-10 17:45:30.000000000 +0200
@@ -49,7 +49,10 @@
     );
 
     function _table() {
-        return KTUtil::getTableName('plugins');
+		static $tableName = null;
+		if (is_null($tableName))
+		  $tableName =& KTUtil::getTableName('plugins');
+		return $tableName;
     }
 
     function _cachedGroups() {
--- officialpublicop/lib/ktentity.inc	2007-04-11 13:34:49.000000000 +0200
+++ mpublicop/lib/ktentity.inc	2007-04-11 15:29:16.000000000 +0200
@@ -115,7 +115,7 @@
         return false;
     }
 
-    function newCopy() {
+    function &newCopy() {
         $sClass = get_class($this);
         $oObject =& new $sClass;
         foreach (array_keys($this->_aFieldToSelect) as $k) {
@@ -135,7 +135,7 @@
      *
      */
     function update() {
-        $group = sprintf("%s/%s", get_class($this), 'id');
+        $group = sprintf("%s/id", get_class($this));
         $oCache =& KTCache::getSingleton();
         $oCache->remove($group, $this->iId);
         $this->clearCachedGroups();
@@ -201,7 +201,7 @@
         $sClassName = get_class($this);
         // cache at lowest possible level.
         $oCache =& KTCache::getSingleton();
-        $group = sprintf("%s/%s", $sClassName , 'id');
+        $group = sprintf("%s/id", $sClassName);
         list($bCached, $mCached) = $oCache->get($group, $iId);
         if ($bCached && EVIL_CACHE_GRIND) {
             $default->log->debug(sprintf("Found and testing object cache for class %s, id %d", $sClassName, $iId));
@@ -379,7 +379,7 @@
 
 class KTEntityUtil {
     function &getList2($sClassName, $aWhereClause = null, $aOptions = null) {
-        $sTable = call_user_func(array($sClassName, "_table"));
+		$sTable = call_user_func(array($sClassName, "_table"));
         return KTEntityUtil::getList($sTable, $sClassName, $aWhereClause, $aOptions);
     }
 
@@ -637,9 +637,9 @@
         }
         $iId = (int)$iId;
         /* */
-        $sProxyClass = KTEntityUtil::_getProxyClass($sClassName);
+        $sProxyClass =& KTEntityUtil::_getProxyClass($sClassName);
         $oObject =& new $sProxyClass($iId);
-        $res = $oObject->getId();
+        $res =& $oObject->_fetch();
         if (PEAR::isError($res)) {
             return $res;
         }
@@ -706,30 +706,40 @@
         }
         eval($code);
     }
+
     function _proxyBuild($sClassName, $sProxyClassName) {
         // var_dump("Building proxy for $sClassName");
         $methods = get_class_methods($sClassName);
         $allcode = array();
+		$allcode[] = sprintf('var $cacheGlobal = null;%s', "\n");
         foreach ($methods as $sMethod) {
+		  if ($sMethod == 'getid') {
+            $code = sprintf('function getId() { return $this->iId; }');
+		  } else if ($sMethod == '_table' || $sMethod == 'update' ) {
+            $code = sprintf('function %s() { return parent::%s(); }', $sMethod, $sMethod);
+		  } else if ($sMethod == 'get') {
+			$code = sprintf('function get($oId) { return $this->get(%s, $oid); }', $sClassName);
+		  } else { 
             $code = sprintf('function %s() { $aArgs = func_get_args(); return $this->_callOnObject("%s", $aArgs); }%s', $sMethod, $sMethod, "\n");
-            $allcode[] = $code;
+		  }
+		  $allcode[] = $code;
         }
 
         $allcode[] = sprintf('function &_fetch() {
-        $oObject =& KTUtil::arrayGet($GLOBALS["_OBJECTCACHE"][%s], $this->iId);
+        $oObject =& KTUtil::arrayGet($this->cacheGlobal, $this->iId);
         if ($oObject) { return $oObject; }
         $oObject =& new %s;
         $res = $oObject->load($this->iId);
         if (PEAR::isError($res)) {
             return $res;
         }
-        $GLOBALS["_OBJECTCACHE"][%s][$this->iId] =& $oObject;
+        $this->cacheGlobal[$this->iId] =& $oObject;
         return $oObject;
     }
         ', $sClassName, $sClassName, $sClassName);
 
         $allcode[] = sprintf('function &_save(&$oObject) {
-        $GLOBALS["_OBJECTCACHE"][%s][$this->iId] =& $oObject;
+        $this->cacheGlobal[$this->iId] =& $oObject;
     }
         ', $sClassName);
 
@@ -740,7 +750,7 @@
         }
         /* */
         $res = call_user_func_array(array(&$oObject, $sName), $aArgs);
-        $this->_save($oObject);
+        $this->cacheGlobal[$this->iId] =& $oObject;
         return $res;
         /* */
 
@@ -759,7 +769,7 @@
     }
         ';
 
-        $allcode[] = sprintf('function %s ($iId) { $this->iId = $iId; }' . "\n", $sProxyClassName);
+        $allcode[] = sprintf('function %s ($iId) { $this->iId = $iId; $this->cacheGlobal =& $GLOBALS["_OBJECTCACHE"][%s]; }' . "\n", $sProxyClassName, $sClassName);
 
         $gen = sprintf("class %s extends %s {\n", $sProxyClassName, $sClassName);
         $gen .= "    " . join("\n    ", $allcode) . "\n";
--- officialpublicop/lib/documentmanagement/documentcore.inc.php	2006-08-29 09:42:37.000000000 +0200
+++ publicop/lib/documentmanagement/documentcore.inc.php	2007-04-10 14:03:39.000000000 +0200
@@ -161,14 +166,18 @@
 
     // {{{ ktentity requirements
     function _fieldValues () {
-        $sNewFullPath = Folder::generateFolderPath($this->iFolderId);
-        if (!PEAR::isError($sNewFullPath)) {
-            $this->sFullPath = $sNewFullPath;
-        }
-        $sNewParentFolderIds = Folder::generateFolderIds($this->iFolderId);
-        if (!PEAR::isError($sNewParentFolderIds)) {
-            $this->sParentFolderIds = $sNewParentFolderIds;
+		static $lastFolder = null;
+		if (is_null($lastFolder) || $lastFolder->getID() !== $this->iFolderId) {
+		  $lastFolder =& Folder::get($this->iFolderId);
+		  if (PEAR::isError($lastFolder)) {
+			$lastFolder = null;
+		  }
+		}
+        if (!is_null($lastFolder)) {
+            $this->sFullPath = $lastFolder->getFullPath();
+			$this->sParentFolderIds = $lastFolder->getParentFolderIDs();
         }
+
         return parent::_fieldValues();
     }
 
--- officialpublicop/lib/documentmanagement/documentutil.inc.php	2006-12-07 18:12:08.000000000 +0100
+++ publicop/lib/documentmanagement/documentutil.inc.php	2007-04-06 09:10:34.000000000 +0200
@@ -173,7 +173,7 @@
         return true;
     }
 
-    function &_add($oFolder, $sFilename, $oUser, $aOptions) {
+    function &_add(&$oFolder, &$sFilename, &$oUser, &$aOptions) {
         global $default;
         
         $oContents = KTUtil::arrayGet($aOptions, 'contents');
@@ -406,7 +407,7 @@
     // }}}
 
     // {{{ add
-    function &add($oFolder, $sFilename, $oUser, $aOptions) {
+    function &add(&$oFolder, &$sFilename, &$oUser, &$aOptions) {
         $GLOBALS['_IN_ADD'] = true;
         $ret = KTDocumentUtil::_in_add($oFolder, $sFilename, $oUser, $aOptions);
         unset($GLOBALS['_IN_ADD']);
@@ -416,7 +417,7 @@
 
 
     // {{{ _in_add
-    function &_in_add($oFolder, $sFilename, $oUser, $aOptions) {
+    function &_in_add(&$oFolder, &$sFilename, &$oUser, &$aOptions) {
     	//unique filename in all document tree
         if (KTDocumentUtil::fileExists($oFolder, $sFilename)) {
 	    $oDoc = Document::getByFilename($sFilename);
@@ -449,12 +450,14 @@
         }
 
         $oUploadChannel =& KTUploadChannel::getSingleton();
-        $oUploadChannel->sendMessage(new KTUploadNewFile($sFilename));
-        $oDocument =& KTDocumentUtil::_add($oFolder, $sFilename, $oUser, $aOptions);
-        // $oUploadChannel->sendMessage(new KTUploadGenericMessage(_kt("Document created")));
-        if (PEAR::isError($oDocument)) {
-            return $oDocument;
-        }
+		$oUploadChannel->sendMessage(new KTUploadNewFile($sFilename));
+		DBUtil::startTransaction();
+		$oDocument =& KTDocumentUtil::_add($oFolder, $sFilename, $oUser, $aOptions);
+		DBUtil::commit();
+		// $oUploadChannel->sendMessage(new KTUploadGenericMessage(_kt("Document created")));
+		if (PEAR::isError($oDocument)) {
+			return $oDocument;
+		}
 
         // $oUploadChannel->sendMessage(new KTUploadGenericMessage(_kt("Scanning file")));
         $oKTTriggerRegistry = KTTriggerRegistry::getSingleton();
--- officialpublicop/plugins/ktcore/folder/addDocument.php	2006-12-07 18:12:08.000000000 +0100
+++ publicop/plugins/ktcore/folder/addDocument.php	2007-04-06 09:12:43.000000000 +0200
@@ -150,7 +150,7 @@
         $aFields = array();
         foreach ($_REQUEST as $k => $v) {
             if (preg_match('/^metadata_(\d+)$/', $k, $matches)) {
-            	$oField = &DocumentField::get($matches[1]);
+            	$oField = DocumentField::get($matches[1]);
             	if (substr($oField->getName(),0,4)=='Date') {
             		if (!empty ($v) && !(ereg ("^([0-9]{1,2})/([0-9]{1,2})/([0-9]{4})$", $v, $regs) && checkdate($regs[2],$regs[1],$regs[3]))) {
             		$v="";
@@ -158,7 +158,7 @@
             		$this->oValidator->validateString($v,$aErrorOptions);
             		}
             	}
-                $aFields[] = array(DocumentField::get($matches[1]), $v);
+                $aFields[] = array($oField, $v);
             }
         }
 
@@ -173,8 +173,9 @@
         );
 
         $mpo->start();
-        $this->startTransaction();
+
         $oDocument =& KTDocumentUtil::add($this->oFolder, basename($aFile['name']), $this->oUser, $aOptions);
+        
         if (PEAR::isError($oDocument)) {
             $message = $oDocument->getMessage();
             $this->errorRedirectToMain($message, 'fFolderId=' . $this->oFolder->getId());
@@ -183,7 +184,7 @@
         $this->addInfoMessage(_kt("Document added"));
 
         $mpo->redirectToDocument($oDocument->getId());
-        $this->commitTransaction();
+
         exit(0);
     }
 
--- officialpublicop/plugins/ktcore/folder/Permissions.php	2006-11-24 11:42:43.000000000 +0100
+++ publicop/plugins/ktcore/folder/Permissions.php	2007-04-05 16:13:09.000000000 +0200
@@ -161,34 +161,31 @@
         $aMapPermissionRole = array();
         $aMapPermissionUser = array();
 
-        $aUsers = User::getList();
-
+        $aUsers =& User::getList();
         foreach ($aPermissions as $oPermission) {
             $oPLA = KTPermissionLookupAssignment::getByPermissionAndLookup($oPermission, $oPL);
             if (PEAR::isError($oPLA)) {
                 continue;
             }
-            $oDescriptor = KTPermissionDescriptor::get($oPLA->getPermissionDescriptorID());
+            $oDescriptor =& KTPermissionDescriptor::get($oPLA->getPermissionDescriptorID());
             $iPermissionID = $oPermission->getID();
             $aMapPermissionGroup[$iPermissionID] = array();
-            foreach ($aUsers as $oUser) {
-                if (KTPermissionUtil::userHasPermissionOnItem($oUser, $oPermission, $this->oFolder)) {
-                    $aMapPermissionUser[$iPermissionID][$oUser->getId()] = true;
-                    $aActiveUsers[$oUser->getId()] = true;
-                }
+			$hasPermission = false;
+			$everyone = $oDescriptor->hasRoles(array(-3));
+			$authenticated = $oDescriptor->hasRoles(array(-4));
+			// TODO : paginate this page, when there is too many users
+			foreach ($aUsers as $oUser) {
+				if ($everyone || ($authenticated && $oUser->isAnonymous()) || 
+					$oUser->hasPermission($oDescriptor)) {
+					$aMapPermissionUser[$iPermissionID][$oUser->getId()] = true;
+				}
             }
         }
 
         // now we constitute the actual sets.
-        $users = array();
         $groups = array();
         $roles = array(); // should _always_ be empty, barring a bug in permissions::updatePermissionLookup
-
-        // this should be quite limited - direct role -> user assignment is typically rare.
-        foreach ($aActiveUsers as $id => $marker) {
-            $oUser = User::get($id);
-            $users[$oUser->getName()] = $oUser;
-        }
+		$users =& $aUsers; 
         asort($users); // ascending, per convention.
 
         $bEdit = false;
@@ -212,17 +209,6 @@
         return $oTemplate->render($aTemplateData);
     }
 
-
-
-
-
-
-
-
-
-
-
-
     function _copyPermissions() {
         $oTransaction = KTFolderTransaction::createFromArray(array(
             'folderid' => $this->oFolder->getId(),
--- officialpublicop/lib/users/User.inc	2006-09-25 13:44:30.000000000 +0200
+++ publicop/lib/users/User.inc	2007-04-05 15:13:46.000000000 +0200
@@ -340,4 +340,27 @@
         }
         return parent::create();
     }
+
+	function hasPermission(&$oPermissionDescriptor) {
+		$pdgTable = KTUtil::getTableName('permission_descriptor_groups');
+        global $default;
+		$uglTable = $default->users_groups_table;
+
+		$sQuery = "SELECT COUNT(*) AS num FROM $pdgTable INNER JOIN " .
+		  "$uglTable ON $uglTable.group_id=$pdgTable.group_id" . 
+		  "WHERE $pdgTable.descriptor_id = ? AND " . 
+		  "$uglTable.user_id=?";
+		$aParams = array($oPermissionDescriptor->getID());
+		$aParams[] = $this->$iId;
+        $res = DBUtil::getOneResultKey(array($sQuery, $aParams), 'num');
+        if (PEAR::isError($res)) {
+            return $res;
+        }
+        if ((int)$res === 0) {
+            return false;
+        }
+        return true;
+
+	}
+
 }
--- mpublicop/lib/permissions/permissionutil.inc.php.old	2007-05-03 11:48:58.000000000 +0200
+++ mpublicop/lib/permissions/permissionutil.inc.php	2007-05-04 11:55:23.000000000 +0200
@@ -182,15 +182,40 @@
         $sWhere = 'permission_object_id = ?';
         $aParams = array($oPO->getID());
         $aFolders =& Folder::getList(array($sWhere, $aParams));
+
+		// init once time those var for speeding up updates
+		$oChannel =& KTPermissionChannel::getSingleton();
+		$aPAs = KTPermissionAssignment::getByObjectMulti($oPO);
+		$aMapPermAllowed = array();
+		foreach ($aPAs as $oPA) {
+		  $oPD = KTPermissionDescriptor::get($oPA->getPermissionDescriptorID());
+		  $aGroupIDs = $oPD->getGroups();
+		  $aUserIDs = array();
+		  $aRoleIDs = $oPD->getRoles();
+		  $aAllowed = array(
+							"group" => $aGroupIDs,
+							"user" => $aUserIDs,
+							"role" => $aRoleIDs,
+							);
+		  $aMapPermAllowed[$oPA->getPermissionID()] = $aAllowed;
+		}
+		$aMapPermDesc = array();
+		foreach ($aMapPermAllowed as $iPermissionId => $aAllowed) {
+		  $oLookupPD = KTPermissionUtil::getOrCreateDescriptor($aAllowed);
+		  $aMapPermDesc[$iPermissionId] = $oLookupPD->getID();
+		}
+		
+		$oPL = KTPermissionLookupAssignment::findOrCreateLookupByPermissionDescriptorMap($aMapPermDesc);
+		$aOptions = array($oChannel, $aMapPermAllowed, $oPL);
         if (!PEAR::isError($aFolders)) { 
             foreach ($aFolders as $oFolder) {
-                KTPermissionUtil::updatePermissionLookup($oFolder);
+                KTPermissionUtil::updatePermissionLookup($oFolder, $aOptions);
             }
         }
         $aDocuments =& Document::getList(array($sWhere, $aParams));
         if (!PEAR::isError($aDocuments)) {
             foreach ($aDocuments as $oDocument) {
-                KTPermissionUtil::updatePermissionLookup($oDocument);
+                KTPermissionUtil::updatePermissionLookup($oDocument, $aOptions);
             }
         }
     }
@@ -233,18 +258,30 @@
     /**
      * Update's the permission lookup on one folder or document,
      * non-recursively.
+     * Options must be in this order :
+     * 0 : oChannel
+     * 1 : aMapPermAllowed
+     * 2 : oPL
      */
-    function updatePermissionLookup(&$oFolderOrDocument) {
-        if (!is_a($oFolderOrDocument, 'Folder')) {
-            if (!is_a($oFolderOrDocument, 'Document')) {
-                if (!is_a($oFolderOrDocument, 'KTDocumentCore')) {
-                    return ; // we occasionally get handed a PEAR::raiseError.  Just ignore it.
-                }
-            }
-        }
+    function updatePermissionLookup(&$oFolderOrDocument, $aOptions = null) {
+		$is_a_folder = is_a($oFolderOrDocument, 'Folder');
+		$is_a_document = is_a($oFolderOrDocument, 'Document') || is_a($oFolderOrDocument, 'KTDocumentCore');
+		$oChannel = null;
+		$aMapPermAllowed = null;
+		$oPL = null;
+		if (!is_null($aOptions)) {
+		  $oChannel =& $aOptions[0];
+		  $aMapPermAllowed =& $aOptions[1];
+		  $oPL =& $aOptions[2];
+		}
+        if (!$is_a_folder && !$is_a_document) {
+		  return ; // we occasionally get handed a PEAR::raiseError.  Just ignore it.
+		}
         
-        $oChannel =& KTPermissionChannel::getSingleton();
-        if (is_a($oFolderOrDocument, 'Folder')) {
+		if (is_null($oChannel)) {
+			$oChannel =& KTPermissionChannel::getSingleton();
+		}
+        if ($is_a_folder) {
             $msg = sprintf("Updating folder %s", join("/", $oFolderOrDocument->getPathArray()));
         } else {
             if (is_a($oFolderOrDocument, 'Document')) {
@@ -259,23 +296,25 @@
         if (empty($iPermissionObjectId)) {
             return;
         }
-        $oPO = KTPermissionObject::get($iPermissionObjectId);
-        $aPAs = KTPermissionAssignment::getByObjectMulti($oPO);
-        $aMapPermAllowed = array();
-        foreach ($aPAs as $oPA) {
-            $oPD = KTPermissionDescriptor::get($oPA->getPermissionDescriptorID());
-            $aGroupIDs = $oPD->getGroups();
-            $aUserIDs = array();
-            $aRoleIDs = $oPD->getRoles();
-            $aAllowed = array(
-                "group" => $aGroupIDs,
-                "user" => $aUserIDs,
-                "role" => $aRoleIDs,
-            );
-            $aMapPermAllowed[$oPA->getPermissionID()] = $aAllowed;
-        }
+		if (is_null($aMapPermAllowed)) {
+			$oPO = KTPermissionObject::get($iPermissionObjectId);
+			$aPAs = KTPermissionAssignment::getByObjectMulti($oPO);
+			$aMapPermAllowed = array();
+			foreach ($aPAs as $oPA) {
+				$oPD = KTPermissionDescriptor::get($oPA->getPermissionDescriptorID());
+				$aGroupIDs = $oPD->getGroups();
+				$aUserIDs = array();
+				$aRoleIDs = $oPD->getRoles();
+				$aAllowed = array(
+								  "group" => $aGroupIDs,
+								  "user" => $aUserIDs,
+								  "role" => $aRoleIDs,
+								  );
+				$aMapPermAllowed[$oPA->getPermissionID()] = $aAllowed;
+			}
+		}
 
-        if (!is_a($oFolderOrDocument, 'Folder')) {
+        if (!$is_a_folder) {
             $aDynamicConditions = KTPermissionDynamicCondition::getByPermissionObject($oPO);
             if (!PEAR::isError($aDynamicConditions)) {
                 foreach ($aDynamicConditions as $oDynamicCondition) {
@@ -293,7 +332,7 @@
             }
         }
 
-        if (!is_a($oFolderOrDocument, 'Folder')) {
+        if (!$is_a_folder) {
             $oState = KTWorkflowUtil::getWorkflowStateForDocument($oFolderOrDocument);
             if (!(PEAR::isError($oState) || is_null($oState) || ($oState == false))) {
                 $aWorkflowStatePermissionAssignments = KTWorkflowStatePermissionAssignment::getByState($oState);
@@ -317,12 +356,13 @@
 
         // if we have roles:  nearest folder.
         $iRoleSourceFolder = null;
-        if (is_a($oFolderOrDocument, 'KTDocumentCore') || is_a($oFolderOrDocument, 'Document')) { $iRoleSourceFolder = $oFolderOrDocument->getFolderID(); }
+        if ($is_a_document) { $iRoleSourceFolder = $oFolderOrDocument->getFolderID(); }
         else { $iRoleSourceFolder = $oFolderOrDocument->getId(); }
             
+
         // very minor perf win:  map role_id (in context) to PD.
         $_roleCache = array(); 
-            
+
         foreach ($aMapPermAllowed as $iPermissionId => $aAllowed) {
             $aAfterRoles = array();
             if (array_key_exists('role', $aAllowed)) {
@@ -336,7 +376,7 @@
                     }
                     if (!array_key_exists($iRoleId, $_roleCache)) {
                         $oRoleAllocation = null;
-                        if (is_a($oFolderOrDocument, 'KTDocumentCore') || is_a($oFolderOrDocument, 'Document')) {
+                        if ($is_a_document) {
                             $oRoleAllocation =& DocumentRoleAllocation::getAllocationsForDocumentAndRole($oFolderOrDocument->getId(), $iRoleId);
                             if (PEAR::isError($oRoleAllocation)) { $oRoleAllocation = null; }
                         }
@@ -372,14 +412,15 @@
         print '</pre>';
         */
         
-
-        $aMapPermDesc = array();
-        foreach ($aMapPermAllowed as $iPermissionId => $aAllowed) {
+		if (is_null($oPL)) {
+		  $aMapPermDesc = array();
+		  foreach ($aMapPermAllowed as $iPermissionId => $aAllowed) {
             $oLookupPD = KTPermissionUtil::getOrCreateDescriptor($aAllowed);
             $aMapPermDesc[$iPermissionId] = $oLookupPD->getID();
-        }
+		  }
 
-        $oPL = KTPermissionLookupAssignment::findOrCreateLookupByPermissionDescriptorMap($aMapPermDesc);
+		  $oPL = KTPermissionLookupAssignment::findOrCreateLookupByPermissionDescriptorMap($aMapPermDesc);
+		}
         $oFolderOrDocument->setPermissionLookupID($oPL->getID());
         $oFolderOrDocument->update();
     }
