You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@jackrabbit.apache.org by Serge Huber <sh...@jahia.com> on 2005/06/27 17:27:12 UTC

Re: svn commit: r201999 - in /incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core: ./ query/lucene/ state/ state/obj/ state/xml/ version/ virtual/ xml/

Arg this commit breaks the ORM PMs again :)

I'll see if I can fix it quickly...

cheers,
  Serge...

stefan@apache.org wrote:

>Author: stefan
>Date: Mon Jun 27 08:08:35 2005
>New Revision: 201999
>
>URL: http://svn.apache.org/viewcvs?rev=201999&view=rev
>Log:
>JCR-129: applied patch supplied by serge as-is
>(http://issues.apache.org/jira/browse/JCR-129)misc. NodeState optimizations:
>- removed PropertyEntry class; the relevant
>  NodeState methods (e.g. getPropertyEntries())
>  now return QName's instead of PropertyEntry
>  to avoid unneccessary object creation
>- reimplemented internal ChildNodeEntries class
>  for improved speed and efficiency
>
>Modified:
>    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/BatchedItemOperations.java
>    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/HierarchyManagerImpl.java
>    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemImpl.java
>    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemManager.java
>    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemValidator.java
>    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NodeImpl.java
>    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/query/lucene/NodeIndexer.java
>    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/NodeState.java
>    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java
>    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java
>    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/obj/ObjectPersistenceManager.java
>    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/xml/XMLPersistenceManager.java
>    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/NodeStateEx.java
>    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionManagerImpl.java
>    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/AbstractVISProvider.java
>    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/VirtualNodeState.java
>    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/WorkspaceImporter.java
>
>Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/BatchedItemOperations.java
>URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/BatchedItemOperations.java?rev=201999&r1=201998&r2=201999&view=diff
>==============================================================================
>--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/BatchedItemOperations.java (original)
>+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/BatchedItemOperations.java Mon Jun 27 08:08:35 2005
>@@ -583,7 +583,7 @@
>                             parentState);
> 
>             // check for name collisions
>-            if (parentState.hasPropertyEntry(nodeName)) {
>+            if (parentState.hasPropertyName(nodeName)) {
>                 // there's already a property with that name
>                 throw new ItemExistsException("cannot add child node '"
>                         + nodeName.getLocalName() + "' to "
>@@ -1003,7 +1003,7 @@
>             RepositoryException, IllegalStateException {
> 
>         // check for name collisions with existing properties
>-        if (parent.hasPropertyEntry(nodeName)) {
>+        if (parent.hasPropertyName(nodeName)) {
>             String msg = "there's already a property with name " + nodeName;
>             log.debug(msg);
>             throw new RepositoryException(msg);
>@@ -1148,9 +1148,8 @@
>         }
> 
>         // check for name collisions with existing properties
>-        if (parent.hasPropertyEntry(propName)) {
>-            PropertyId id = new PropertyId(parent.getUUID(),
>-                    parent.getPropertyEntry(propName).getName());
>+        if (parent.hasPropertyName(propName)) {
>+            PropertyId id = new PropertyId(parent.getUUID(), propName);
>             throw new ItemExistsException(safeGetJCRPath(id));
>         }
> 
>@@ -1177,7 +1176,7 @@
>         }
> 
>         // now add new property entry to parent
>-        parent.addPropertyEntry(propName);
>+        parent.addPropertyName(propName);
>         // store parent
>         stateMgr.store(parent);
> 
>@@ -1301,7 +1300,7 @@
>          * this would have a negative impact on performance though...
>          */
>         NodeState nodeState = getNodeState(nodePath);
>-        while (!nodeState.hasPropertyEntry(JCR_ISCHECKEDOUT)) {
>+        while (!nodeState.hasPropertyName(JCR_ISCHECKEDOUT)) {
>             if (nodePath.denotesRoot()) {
>                 return;
>             }
>@@ -1528,16 +1527,16 @@
> 
>         // remove properties
>         // use temp array to avoid ConcurrentModificationException
>-        tmp = new ArrayList(targetState.getPropertyEntries());
>+        tmp = new ArrayList(targetState.getPropertyNames());
>         for (int i = 0; i < tmp.size(); i++) {
>-            NodeState.PropertyEntry entry = (NodeState.PropertyEntry) tmp.get(i);
>+            QName propName = (QName) tmp.get(i);
>             PropertyId propId =
>-                    new PropertyId(targetState.getUUID(), entry.getName());
>+                    new PropertyId(targetState.getUUID(), propName);
>             try {
>                 PropertyState propState =
>                         (PropertyState) stateMgr.getItemState(propId);
>                 // remove property entry
>-                targetState.removePropertyEntry(propId.getName());
>+                targetState.removePropertyName(propId.getName());
>                 // destroy property state
>                 stateMgr.destroy(propState);
>             } catch (ItemStateException ise) {
>@@ -1684,10 +1683,10 @@
>                 newState.addChildNodeEntry(entry.getName(), newChildState.getUUID());
>             }
>             // copy properties
>-            iter = srcState.getPropertyEntries().iterator();
>+            iter = srcState.getPropertyNames().iterator();
>             while (iter.hasNext()) {
>-                NodeState.PropertyEntry entry = (NodeState.PropertyEntry) iter.next();
>-                PropertyId propId = new PropertyId(srcState.getUUID(), entry.getName());
>+                QName propName = (QName) iter.next();
>+                PropertyId propId = new PropertyId(srcState.getUUID(), propName);
>                 if (!srcAccessMgr.isGranted(propId, AccessManager.READ)) {
>                     continue;
>                 }
>@@ -1709,14 +1708,14 @@
>                 }
> 
>                 PropertyState newChildState =
>-                        copyPropertyState(srcChildState, uuid, entry.getName());
>+                        copyPropertyState(srcChildState, uuid, propName);
>                 if (newChildState.getType() == PropertyType.REFERENCE) {
>                     refTracker.processedReference(newChildState);
>                 }
>                 // store new property
>                 stateMgr.store(newChildState);
>                 // add new property entry to new node
>-                newState.addPropertyEntry(entry.getName());
>+                newState.addPropertyName(propName);
>             }
>             return newState;
>         } catch (ItemStateException ise) {
>
>Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/HierarchyManagerImpl.java
>URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/HierarchyManagerImpl.java?rev=201999&r1=201998&r2=201999&view=diff
>==============================================================================
>--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/HierarchyManagerImpl.java (original)
>+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/HierarchyManagerImpl.java Mon Jun 27 08:08:35 2005
>@@ -169,7 +169,7 @@
>                     parentState.getChildNodeEntry(name, index);
>             childId = new NodeId(nodeEntry.getUUID());
> 
>-        } else if (parentState.hasPropertyEntry(name)) {
>+        } else if (parentState.hasPropertyName(name)) {
>             // property
>             if (index > 1) {
>                 // properties can't have same name siblings
>
>Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemImpl.java
>URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemImpl.java?rev=201999&r1=201998&r2=201999&view=diff
>==============================================================================
>--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemImpl.java (original)
>+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemImpl.java Mon Jun 27 08:08:35 2005
>@@ -518,7 +518,7 @@
>                          */
>                         continue;
>                     }
>-                    if (!nodeState.hasPropertyEntry(pd.getName())) {
>+                    if (!nodeState.hasPropertyName(pd.getName())) {
>                         String msg = node.safeGetJCRPath()
>                                 + ": mandatory property " + pd.getName()
>                                 + " does not exist";
>
>Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemManager.java
>URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemManager.java?rev=201999&r1=201998&r2=201999&view=diff
>==============================================================================
>--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemManager.java (original)
>+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemManager.java Mon Jun 27 08:08:35 2005
>@@ -462,12 +462,12 @@
>             throw new RepositoryException(msg);
>         }
>         NodeState nodeState = (NodeState) state;
>-        Iterator iter = nodeState.getPropertyEntries().iterator();
>+        Iterator iter = nodeState.getPropertyNames().iterator();
> 
>         while (iter.hasNext()) {
>-            NodeState.PropertyEntry entry = (NodeState.PropertyEntry) iter.next();
>+            QName propName = (QName) iter.next();
> 
>-            PropertyId id = new PropertyId(parentId.getUUID(), entry.getName());
>+            PropertyId id = new PropertyId(parentId.getUUID(), propName);
>             // check read access
>             if (session.getAccessManager().isGranted(id, AccessManager.READ)) {
>                 return true;
>@@ -497,11 +497,11 @@
>         }
>         NodeState nodeState = (NodeState) state;
>         ArrayList childIds = new ArrayList();
>-        Iterator iter = nodeState.getPropertyEntries().iterator();
>+        Iterator iter = nodeState.getPropertyNames().iterator();
> 
>         while (iter.hasNext()) {
>-            NodeState.PropertyEntry entry = (NodeState.PropertyEntry) iter.next();
>-            PropertyId id = new PropertyId(parentId.getUUID(), entry.getName());
>+            QName propName = (QName) iter.next();
>+            PropertyId id = new PropertyId(parentId.getUUID(), propName);
>             // check read access
>             if (session.getAccessManager().isGranted(id, AccessManager.READ)) {
>                 childIds.add(id);
>
>Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemValidator.java
>URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemValidator.java?rev=201999&r1=201998&r2=201999&view=diff
>==============================================================================
>--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemValidator.java (original)
>+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemValidator.java Mon Jun 27 08:08:35 2005
>@@ -115,7 +115,7 @@
>         PropDef[] pda = entPrimaryAndMixins.getMandatoryPropDefs();
>         for (int i = 0; i < pda.length; i++) {
>             PropDef pd = pda[i];
>-            if (!nodeState.hasPropertyEntry(pd.getName())) {
>+            if (!nodeState.hasPropertyName(pd.getName())) {
>                 String msg = safeGetJCRPath(nodeState.getId())
>                         + ": mandatory property " + pd.getName()
>                         + " does not exist";
>
>Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NodeImpl.java
>URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NodeImpl.java?rev=201999&r1=201998&r2=201999&view=diff
>==============================================================================
>--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NodeImpl.java (original)
>+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NodeImpl.java Mon Jun 27 08:08:35 2005
>@@ -165,7 +165,7 @@
>                     }
>                     // check if property entry exists
>                     NodeState thisState = (NodeState) state;
>-                    if (thisState.hasPropertyEntry(pe.getName())) {
>+                    if (thisState.hasPropertyName(pe.getName())) {
>                         return new PropertyId(thisState.getUUID(), pe.getName());
>                     } else {
>                         // there's no property with that name
>@@ -422,7 +422,7 @@
>         status.clear();
> 
>         NodeState thisState = (NodeState) state;
>-        if (thisState.hasPropertyEntry(name)) {
>+        if (thisState.hasPropertyName(name)) {
>             /**
>              * the following call will throw ItemNotFoundException if the
>              * current session doesn't have read access
>@@ -481,7 +481,7 @@
>         // modify the state of 'this', i.e. the parent node
>         NodeState thisState = (NodeState) getOrCreateTransientItemState();
>         // add new property entry
>-        thisState.addPropertyEntry(name);
>+        thisState.addPropertyName(name);
> 
>         return prop;
>     }
>@@ -570,7 +570,7 @@
>         NodeState thisState = (NodeState) getOrCreateTransientItemState();
> 
>         // remove the property entry
>-        if (!thisState.removePropertyEntry(propName)) {
>+        if (!thisState.removePropertyName(propName)) {
>             String msg = "failed to remove property " + propName + " of "
>                     + safeGetJCRPath();
>             log.debug(msg);
>@@ -626,32 +626,32 @@
>         // modify the state of 'this', i.e. the target node
>         NodeState thisState = (NodeState) getOrCreateTransientItemState();
> 
>-        // remove child nodes
>-        // use temp array to avoid ConcurrentModificationException
>-        ArrayList tmp = new ArrayList(thisState.getChildNodeEntries());
>-        // remove from tail to avoid problems with same-name siblings
>-        for (int i = tmp.size() - 1; i >= 0; i--) {
>-            NodeState.ChildNodeEntry entry =
>-                    (NodeState.ChildNodeEntry) tmp.get(i);
>-            // recursively remove child node
>-            NodeId childId = new NodeId(entry.getUUID());
>-            NodeImpl childNode = (NodeImpl) itemMgr.getItem(childId);
>-            childNode.onRemove();
>-
>-            // remove the child node entry
>-            thisState.removeChildNodeEntry(entry.getName(), entry.getIndex());
>+        if (thisState.hasChildNodeEntries()) {
>+            // remove child nodes
>+            // use temp array to avoid ConcurrentModificationException
>+            ArrayList tmp = new ArrayList(thisState.getChildNodeEntries());
>+            // remove from tail to avoid problems with same-name siblings
>+            for (int i = tmp.size() - 1; i >= 0; i--) {
>+                NodeState.ChildNodeEntry entry =
>+                        (NodeState.ChildNodeEntry) tmp.get(i);
>+                // recursively remove child node
>+                NodeId childId = new NodeId(entry.getUUID());
>+                NodeImpl childNode = (NodeImpl) itemMgr.getItem(childId);
>+                childNode.onRemove();
>+                // remove the child node entry
>+                thisState.removeChildNodeEntry(entry.getName(), entry.getIndex());
>+            }
>         }
> 
>         // remove properties
>         // use temp array to avoid ConcurrentModificationException
>-        tmp = new ArrayList(thisState.getPropertyEntries());
>+        ArrayList tmp = new ArrayList(thisState.getPropertyNames());
>         for (int i = 0; i < tmp.size(); i++) {
>-            NodeState.PropertyEntry entry =
>-                    (NodeState.PropertyEntry) tmp.get(i);
>+            QName propName = (QName) tmp.get(i);
>             // remove the property entry
>-            thisState.removePropertyEntry(entry.getName());
>+            thisState.removePropertyName(propName);
>             // remove property
>-            PropertyId propId = new PropertyId(thisState.getUUID(), entry.getName());
>+            PropertyId propId = new PropertyId(thisState.getUUID(), propName);
>             itemMgr.getItem(propId).setRemoved();
>         }
> 
>@@ -759,7 +759,7 @@
> 
>         // check for name collisions
>         NodeState thisState = (NodeState) state;
>-        if (thisState.hasPropertyEntry(nodeName)) {
>+        if (thisState.hasPropertyName(nodeName)) {
>             // there's already a property with that name
>             throw new ItemExistsException(itemMgr.safeGetJCRPath(nodePath));
>         }
>@@ -792,7 +792,7 @@
>         NodeState thisState = (NodeState) state;
>         // get or create jcr:mixinTypes property
>         PropertyImpl prop;
>-        if (thisState.hasPropertyEntry(JCR_MIXINTYPES)) {
>+        if (thisState.hasPropertyName(JCR_MIXINTYPES)) {
>             prop = (PropertyImpl) itemMgr.getItem(new PropertyId(thisState.getUUID(), JCR_MIXINTYPES));
>         } else {
>             // find definition for the jcr:mixinTypes property and create property
>@@ -901,7 +901,7 @@
>         // child node entries
>         persistentState.setChildNodeEntries(transientState.getChildNodeEntries());
>         // property entries
>-        persistentState.setPropertyEntries(transientState.getPropertyEntries());
>+        persistentState.setPropertyNames(transientState.getPropertyNames());
> 
>         // make state persistent
>         stateMgr.store(persistentState);
>@@ -1137,18 +1137,18 @@
>         // defined by the specified mixin type
> 
>         // use temp array to avoid ConcurrentModificationException
>-        ArrayList tmp = new ArrayList(thisState.getPropertyEntries());
>+        ArrayList tmp = new ArrayList(thisState.getPropertyNames());
>         Iterator iter = tmp.iterator();
>         while (iter.hasNext()) {
>-            NodeState.PropertyEntry entry = (NodeState.PropertyEntry) iter.next();
>-            PropertyImpl prop = (PropertyImpl) itemMgr.getItem(new PropertyId(thisState.getUUID(), entry.getName()));
>+            QName propName = (QName) iter.next();
>+            PropertyImpl prop = (PropertyImpl) itemMgr.getItem(new PropertyId(thisState.getUUID(), propName));
>             // check if property has been defined by mixin type (or one of its supertypes)
>             NodeTypeImpl declaringNT = (NodeTypeImpl) prop.getDefinition().getDeclaringNodeType();
>             if (!entRemaining.includesNodeType(declaringNT.getQName())) {
>                 // the remaining effective node type doesn't include the
>                 // node type that declared this property, it is thus safe
>                 // to remove it
>-                removeChildProperty(entry.getName());
>+                removeChildProperty(propName);
>             }
>         }
>         // use temp array to avoid ConcurrentModificationException
>@@ -1465,7 +1465,7 @@
>         sanityCheck();
> 
>         NodeState thisState = (NodeState) state;
>-        if (!thisState.hasPropertyEntry(name)) {
>+        if (!thisState.hasPropertyName(name)) {
>             return false;
>         }
>         PropertyId propId = new PropertyId(thisState.getUUID(), name);
>
>Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/query/lucene/NodeIndexer.java
>URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/query/lucene/NodeIndexer.java?rev=201999&r1=201998&r2=201999&view=diff
>==============================================================================
>--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/query/lucene/NodeIndexer.java (original)
>+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/query/lucene/NodeIndexer.java Mon Jun 27 08:08:35 2005
>@@ -151,10 +151,10 @@
>             // unknown uri<->prefix mappings
>         }
> 
>-        List props = node.getPropertyEntries();
>+        List props = node.getPropertyNames();
>         for (Iterator it = props.iterator(); it.hasNext();) {
>-            NodeState.PropertyEntry prop = (NodeState.PropertyEntry) it.next();
>-            PropertyId id = new PropertyId(node.getUUID(), prop.getName());
>+            QName propName = (QName) it.next();
>+            PropertyId id = new PropertyId(node.getUUID(), propName);
>             try {
>                 PropertyState propState = (PropertyState) stateProvider.getItemState(id);
>                 InternalValue[] values = propState.getValues();
>@@ -257,14 +257,14 @@
>                 // don't know how to index
>                 return;
>             }
>-            if (node.hasPropertyEntry(JCR_MIMETYPE)) {
>+            if (node.hasPropertyName(JCR_MIMETYPE)) {
>                 PropertyState dataProp = (PropertyState) stateProvider.getItemState(new PropertyId(node.getUUID(), JCR_DATA));
>                 PropertyState mimeTypeProp =
>                     (PropertyState) stateProvider.getItemState(new PropertyId(node.getUUID(), JCR_MIMETYPE));
> 
>                 // jcr:encoding is not mandatory
>                 String encoding = null;
>-                if (node.hasPropertyEntry(JCR_ENCODING)) {
>+                if (node.hasPropertyName(JCR_ENCODING)) {
>                     PropertyState encodingProp =
>                         (PropertyState) stateProvider.getItemState(new PropertyId(node.getUUID(), JCR_ENCODING));
>                     encodingProp.getValues()[0].internalValue().toString();
>
>Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/NodeState.java
>URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/NodeState.java?rev=201999&r1=201998&r2=201999&view=diff
>==============================================================================
>--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/NodeState.java (original)
>+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/NodeState.java Mon Jun 27 08:08:35 2005
>@@ -20,7 +20,9 @@
> import org.apache.jackrabbit.core.QName;
> import org.apache.jackrabbit.core.nodetype.NodeDefId;
> import org.apache.commons.collections.map.ReferenceMap;
>+import org.apache.commons.collections.map.LinkedMap;
> import org.apache.commons.collections.MapIterator;
>+import org.apache.commons.collections.set.ListOrderedSet;
> 
> import java.io.IOException;
> import java.io.ObjectInputStream;
>@@ -34,23 +36,34 @@
> import java.util.List;
> import java.util.Set;
> import java.util.Map;
>+import java.util.Collection;
>+import java.util.ListIterator;
> 
> /**
>  * <code>NodeState</code> represents the state of a <code>Node</code>.
>  */
> public class NodeState extends ItemState {
> 
>-    static final long serialVersionUID = -3210487938753054604L;
>+    /** Serialization UID of this class. */
>+    static final long serialVersionUID = 2387880829766640392L;
> 
>+    /** the uuid of this node */
>     protected String uuid;
>+
>+    /** the name of this node's primary type */
>     protected QName nodeTypeName;
>+
>+    /** the names of this node's mixin types */
>     protected Set mixinTypeNames = new HashSet();
>+
>+    /** id of this node's definition */
>     protected NodeDefId defId;
> 
>-    // insertion-ordered collection of ChildNodeEntry objects
>+    /** insertion-ordered collection of ChildNodeEntry objects */
>     protected ChildNodeEntries childNodeEntries = new ChildNodeEntries();
>-    // insertion-ordered collection of PropertyEntry objects
>-    protected List propertyEntries = new ArrayList();
>+
>+    /** insertion-ordered set of property names (QName objects) */
>+    protected ListOrderedSet propertyNames = new ListOrderedSet();
> 
>     /**
>      * Listeners (weak references)
>@@ -102,8 +115,8 @@
>         mixinTypeNames.addAll(nodeState.getMixinTypeNames());
>         defId = nodeState.getDefinitionId();
>         uuid = nodeState.getUUID();
>-        propertyEntries.clear();
>-        propertyEntries.addAll(nodeState.getPropertyEntries());
>+        propertyNames.clear();
>+        propertyNames.addAll(nodeState.getPropertyNames());
>         childNodeEntries.removeAll();
>         childNodeEntries.addAll(nodeState.getChildNodeEntries());
>     }
>@@ -175,6 +188,16 @@
>     }
> 
>     /**
>+     * Determines if there are any child node entries.
>+     *
>+     * @return <code>true</code> if there are child node entries,
>+     *         <code>false</code> otherwise.
>+     */
>+    public boolean hasChildNodeEntries() {
>+        return !childNodeEntries.isEmpty();
>+    }
>+
>+    /**
>      * Determines if there is a <code>ChildNodeEntry</code> with the
>      * specified <code>name</code>.
>      *
>@@ -195,6 +218,18 @@
> 
>     /**
>      * Determines if there is a <code>ChildNodeEntry</code> with the
>+     * specified <code>uuid</code>.
>+     *
>+     * @param uuid UUID of the child node
>+     * @return <code>true</code> if there is a <code>ChildNodeEntry</code> with
>+     *         the specified <code>name</code>.
>+     */
>+    public synchronized boolean hasChildNodeEntry(String uuid) {
>+        return childNodeEntries.get(uuid) != null;
>+    }
>+
>+    /**
>+     * Determines if there is a <code>ChildNodeEntry</code> with the
>      * specified <code>name</code> and <code>index</code>.
>      *
>      * @param name  <code>QName</code> object specifying a node name
>@@ -220,35 +255,15 @@
>     }
> 
>     /**
>-     * Determines if there is a <code>PropertyEntry</code> with the
>-     * specified <code>QName</code>.
>-     *
>-     * @param propName <code>QName</code> object specifying a property name
>-     * @return <code>true</code> if there is a <code>PropertyEntry</code> with
>-     *         the specified <code>QName</code>.
>-     */
>-    public synchronized boolean hasPropertyEntry(QName propName) {
>-        PropertyEntry entry = new PropertyEntry(propName);
>-        return propertyEntries.contains(entry);
>-    }
>-
>-    /**
>-     * Returns the <code>PropertyEntry</code> with the specified name or
>-     * <code>null</code> if there's no such entry.
>+     * Determines if there is a property entry with the specified
>+     * <code>QName</code>.
>      *
>      * @param propName <code>QName</code> object specifying a property name
>-     * @return the <code>PropertyEntry</code> with the specified name or
>-     *         <code>null</code> if there's no such entry.
>+     * @return <code>true</code> if there is a property entry with the specified
>+     *         <code>QName</code>.
>      */
>-    public synchronized PropertyEntry getPropertyEntry(QName propName) {
>-        Iterator iter = propertyEntries.iterator();
>-        while (iter.hasNext()) {
>-            PropertyEntry entry = (PropertyEntry) iter.next();
>-            if (propName.equals(entry.getName())) {
>-                return entry;
>-            }
>-        }
>-        return null;
>+    public synchronized boolean hasPropertyName(QName propName) {
>+        return propertyNames.contains(propName);
>     }
> 
>     /**
>@@ -281,7 +296,7 @@
>      * Returns the <code>ChildNodeEntry</code> with the specified uuid or
>      * <code>null</code> if there's no such entry.
>      *
>-     * @param uuid UUID of a child node state.
>+     * @param uuid UUID of the child node
>      * @return the <code>ChildNodeEntry</code> with the specified uuid or
>      *         <code>null</code> if there's no such entry.
>      * @see #addChildNodeEntry
>@@ -300,7 +315,7 @@
>      * @see #removeChildNodeEntry
>      */
>     public synchronized List getChildNodeEntries() {
>-        return childNodeEntries.entries();
>+        return childNodeEntries;
>     }
> 
>     /**
>@@ -352,9 +367,9 @@
>     }
> 
>     /**
>-     * Removes a <code>ChildNodeEntry<code>.
>+     * Removes a <code>ChildNodeEntry</code>.
>      *
>-     * @param nodeName <code>ChildNodeEntry<code> object specifying a node name
>+     * @param nodeName <code>ChildNodeEntry</code> object specifying a node name
>      * @param index    1-based index if there are same-name child node entries
>      * @return <code>true</code> if the specified child node entry was found
>      *         in the list of child node entries and could be removed.
>@@ -386,11 +401,7 @@
>      * Removes all <code>ChildNodeEntry</code>s.
>      */
>     public synchronized void removeAllChildNodeEntries() {
>-        Iterator iter = childNodeEntries.entries().iterator();
>-        while (iter.hasNext()) {
>-            ChildNodeEntry entry = (ChildNodeEntry) iter.next();
>-            removeChildNodeEntry(entry.getUUID());
>-        }
>+        childNodeEntries.removeAll();
>     }
> 
>     /**
>@@ -404,59 +415,51 @@
>     }
> 
>     /**
>-     * Returns a list of <code>PropertyEntry</code> objects denoting the
>-     * properties of this node.
>+     * Returns the names of this node's properties as a list of
>+     * <code>QNames</code> objects.
>      *
>-     * @return list of <code>PropertyEntry</code> objects
>-     * @see #addPropertyEntry
>-     * @see #removePropertyEntry
>+     * @return list of <code>QNames</code> objects
>+     * @see #addPropertyName
>+     * @see #removePropertyName
>      */
>-    public synchronized List getPropertyEntries() {
>-        return Collections.unmodifiableList(propertyEntries);
>+    public synchronized List getPropertyNames() {
>+        return propertyNames.asList();
>     }
> 
>     /**
>-     * Adds a <code>PropertyEntry</code>.
>+     * Adds a property name entry.
>      *
>      * @param propName <code>QName</code> object specifying the property name
>      */
>-    public synchronized void addPropertyEntry(QName propName) {
>-        PropertyEntry entry = new PropertyEntry(propName);
>-        propertyEntries.add(entry);
>+    public synchronized void addPropertyName(QName propName) {
>+        propertyNames.add(propName);
>     }
> 
>     /**
>-     * Removes a <code>PropertyEntry</code>.
>+     * Removes a property name entry.
>      *
>      * @param propName <code>QName</code> object specifying the property name
>-     * @return <code>true</code> if the specified property entry was found
>-     *         in the list of property entries and could be removed.
>+     * @return <code>true</code> if the specified property name was found
>+     *         in the list of property name entries and could be removed.
>      */
>-    public synchronized boolean removePropertyEntry(QName propName) {
>-        PropertyEntry entry = new PropertyEntry(propName);
>-        int pos = propertyEntries.indexOf(entry);
>-        if (pos == -1) {
>-            return false;
>-        } else {
>-            propertyEntries.remove(pos);
>-            return true;
>-        }
>+    public synchronized boolean removePropertyName(QName propName) {
>+        return propertyNames.remove(propName);
>     }
> 
>     /**
>-     * Removes all <code>PropertyEntry</code>s.
>+     * Removes all property name entries.
>      */
>-    public synchronized void removeAllPropertyEntries() {
>-        propertyEntries.clear();
>+    public synchronized void removeAllPropertyNames() {
>+        propertyNames.clear();
>     }
> 
>     /**
>-     * Sets the list of <code>PropertyEntry</code> objects denoting the
>+     * Sets the list of <code>QName</code> objects denoting the
>      * properties of this node.
>      */
>-    public synchronized void setPropertyEntries(List propEntries) {
>-        propertyEntries.clear();
>-        propertyEntries.addAll(propEntries);
>+    public synchronized void setPropertyNames(List propNames) {
>+        propertyNames.clear();
>+        propertyNames.addAll(propNames);
>     }
> 
>     /**
>@@ -471,31 +474,33 @@
> 
>     //---------------------------------------------------------< diff methods >
>     /**
>-     * Returns a list of property entries, that do not exist in the overlayed
>-     * node state but have been added to <i>this</i> node state.
>+     * Returns a list of <code>QName</code>s denoting those properties that
>+     * do not exist in the overlayed node state but have been added to
>+     * <i>this</i> node state.
>      *
>-     * @return list of added property entries
>+     * @return list of <code>QName</code>s denoting the properties that have
>+     *         been added.
>      */
>-    public synchronized List getAddedPropertyEntries() {
>+    public synchronized List getAddedPropertyNames() {
>         if (!hasOverlayedState()) {
>-            return Collections.unmodifiableList(propertyEntries);
>+            return propertyNames.asList();
>         }
> 
>         NodeState other = (NodeState) getOverlayedState();
>-        ArrayList list = new ArrayList(propertyEntries);
>-        list.removeAll(other.propertyEntries);
>+        ArrayList list = new ArrayList(propertyNames);
>+        list.removeAll(other.propertyNames);
>         return list;
>     }
> 
>     /**
>-     * Returns a list of child node entries, that do not exist in the overlayed
>+     * Returns a list of child node entries that do not exist in the overlayed
>      * node state but have been added to <i>this</i> node state.
>      *
>      * @return list of added child node entries
>      */
>     public synchronized List getAddedChildNodeEntries() {
>         if (!hasOverlayedState()) {
>-            return Collections.unmodifiableList(childNodeEntries.entries());
>+            return childNodeEntries;
>         }
> 
>         NodeState other = (NodeState) getOverlayedState();
>@@ -503,19 +508,21 @@
>     }
> 
>     /**
>-     * Returns a list of property entries, that exist in the overlayed node state
>-     * but have been removed from <i>this</i> node state.
>+     * Returns a list of <code>QName</code>s denoting those properties that
>+     * exist in the overlayed node state but have been removed from
>+     * <i>this</i> node state.
>      *
>-     * @return list of removed property entries
>+     * @return list of <code>QName</code>s denoting the properties that have
>+     *         been removed.
>      */
>-    public synchronized List getRemovedPropertyEntries() {
>+    public synchronized List getRemovedPropertyNames() {
>         if (!hasOverlayedState()) {
>             return Collections.EMPTY_LIST;
>         }
> 
>         NodeState other = (NodeState) getOverlayedState();
>-        ArrayList list = new ArrayList(other.propertyEntries);
>-        list.removeAll(propertyEntries);
>+        ArrayList list = new ArrayList(other.propertyNames);
>+        list.removeAll(propertyNames);
>         return list;
>     }
> 
>@@ -536,11 +543,11 @@
> 
>     /**
>      * Returns a list of child node entries that exist both in <i>this</i> node
>-     * state and in the overlayed node state, but have been reordered.
>+     * state and in the overlayed node state but have been reordered.
>      * <p/>
>      * The list may include only the minimal set of nodes that have been
>      * reordered. That is, even though a certain number of nodes have changed
>-     * their context position, the list may include less that this number of
>+     * their absolute position the list may include less that this number of
>      * nodes.
>      * <p/>
>      * Example:<br/>
>@@ -556,7 +563,7 @@
>      *  + node3
>      *  + node1
>      * </pre>
>-     * All nodes have changed their context position. The returned list however
>+     * All nodes have changed their absolute position. The returned list however
>      * may only return that <code>node1</code> has been reordered (from the
>      * first position to the end).
>      *
>@@ -568,19 +575,19 @@
>         }
> 
>         List others = new ArrayList();
>-        others.addAll(((NodeState) getOverlayedState()).childNodeEntries.entries);
>+        others.addAll(((NodeState) getOverlayedState()).getChildNodeEntries());
> 
>         List ours = new ArrayList();
>-        ours.addAll(childNodeEntries.entries);
>+        ours.addAll(childNodeEntries);
> 
>         // do a lazy init
>         List reordered = null;
>-        // remove added nodes from ours entries
>+        // remove added nodes from 'our' entries
>         ours.removeAll(getAddedChildNodeEntries());
>-        // remove all removed nodes from others entries
>+        // remove all removed nodes from 'other' entries
>         others.removeAll(getRemovedChildNodeEntries());
>-        // both entry list now contain the set of nodes that have not
>-        // been removed or added. but they may have changed their position
>+        // both entry lists now contain the set of nodes that have not
>+        // been removed or added, but they may have changed their position.
>         for (int i = 0; i < ours.size();) {
>             ChildNodeEntry entry = (ChildNodeEntry) ours.get(i);
>             ChildNodeEntry other = (ChildNodeEntry) others.get(i);
>@@ -588,13 +595,13 @@
>                 if (reordered == null) {
>                     reordered = new ArrayList();
>                 }
>-                // Note, that this check will not necessarily find the
>+                // Note that this check will not necessarily find the
>                 // minimal reorder operations required to convert the overlayed
>                 // child node entries into the current.
> 
>-                // is there a next entry
>+                // is there a next entry?
>                 if (i + 1 < ours.size()) {
>-                    // if entry is the next in the other list, then probably
>+                    // if entry is the next in the other list then probably
>                     // the other entry at position <code>i</code> was reordered
>                     if (entry.getUUID().equals(((ChildNodeEntry) others.get(i + 1)).getUUID())) {
>                         // scan for the uuid of the other entry in our list
>@@ -622,7 +629,7 @@
>                     }
>                 }
>                 // if a reorder has been detected index <code>i</code> is not
>-                // incremented, because entries will be shifted when the
>+                // incremented because entries will be shifted when the
>                 // reordered entry is removed.
>             } else {
>                 // no reorder, move to next child entry
>@@ -671,7 +678,7 @@
> 
>     //-------------------------------------------------< misc. helper methods >
>     /**
>-     * Notify the listeners that some child node was added
>+     * Notify the listeners that a child node entry has been added
>      */
>     protected void notifyNodeAdded(ChildNodeEntry added) {
>         synchronized (listeners) {
>@@ -687,7 +694,7 @@
>     }
> 
>     /**
>-     * Notify the listeners that the children nodes were replaced
>+     * Notify the listeners that the child node entries have been replaced
>      */
>     protected void notifyNodesReplaced() {
>         synchronized (listeners) {
>@@ -702,7 +709,7 @@
>     }
> 
>     /**
>-     * Notify the listeners that some child node was removed
>+     * Notify the listeners that a child node entry has been removed
>      */
>     protected void notifyNodeRemoved(ChildNodeEntry removed) {
>         synchronized (listeners) {
>@@ -734,31 +741,37 @@
>      * <code>ChildNodeEntries</code> represents an insertion-ordered
>      * collection of <code>ChildNodeEntry</code>s that also maintains
>      * the index values of same-name siblings on insertion and removal.
>+     * <p/>
>+     * <code>ChildNodeEntries</code> also provides an unmodifiable
>+     * <code>List</code> view.
>      */
>-    private static class ChildNodeEntries implements Serializable {
>+    private static class ChildNodeEntries implements List, Serializable {
> 
>-        // insertion-ordered collection of entries
>-        List entries;
>-        // mapping from names to list of same-name sibling entries
>-        Map names;
>+        // insertion-ordered map of entries (key=uuid, value=entry)
>+        LinkedMap entries;
>+        // map used for lookup by name (key=uuid, value=1st same-name sibling entry)
>+        Map nameMap;
> 
>         ChildNodeEntries() {
>-            entries = new ArrayList();
>-            names = new HashMap();
>+            entries = new LinkedMap();
>+            nameMap = new HashMap();
>         }
> 
>         ChildNodeEntry add(QName nodeName, String uuid) {
>-            List siblings = (List) names.get(nodeName);
>-            if (siblings == null) {
>-                siblings = new ArrayList();
>-                names.put(nodeName, siblings);
>+            ChildNodeEntry sibling = (ChildNodeEntry) nameMap.get(nodeName);
>+            while (sibling != null && sibling.getNextSibling() != null) {
>+                sibling = sibling.getNextSibling();
>             }
> 
>-            int index = siblings.size() + 1;
>+            int index = (sibling == null) ? 1 : sibling.getIndex() + 1;
> 
>             ChildNodeEntry entry = new ChildNodeEntry(nodeName, uuid, index);
>-            siblings.add(entry);
>-            entries.add(entry);
>+            if (sibling == null) {
>+                nameMap.put(nodeName, entry);
>+            } else {
>+                sibling.setNextSibling(entry);
>+            }
>+            entries.put(uuid, entry);
> 
>             return entry;
>         }
>@@ -773,8 +786,16 @@
>         }
> 
>         public void removeAll() {
>-            names.clear();
>             entries.clear();
>+            nameMap.clear();
>+        }
>+
>+        ChildNodeEntry remove(String uuid) {
>+            ChildNodeEntry entry = (ChildNodeEntry) entries.get(uuid);
>+            if (entry != null) {
>+                return remove(entry.getName(), entry.getIndex());
>+           }
>+            return entry;
>         }
> 
>         public ChildNodeEntry remove(ChildNodeEntry entry) {
>@@ -785,74 +806,75 @@
>             if (index < 1) {
>                 throw new IllegalArgumentException("index is 1-based");
>             }
>-            List siblings = (List) names.get(nodeName);
>-            if (siblings == null) {
>-                return null;
>+
>+            ChildNodeEntry sibling = (ChildNodeEntry) nameMap.get(nodeName);
>+            ChildNodeEntry prevSibling = null;
>+            while (sibling != null) {
>+                if (sibling.getIndex() == index) {
>+                    break;
>+                }
>+                prevSibling = sibling;
>+                sibling = sibling.getNextSibling();
>             }
>-            if (index > siblings.size()) {
>+            if (sibling == null) {
>                 return null;
>             }
>-            // remove from siblings list
>-            ChildNodeEntry removedEntry = (ChildNodeEntry) siblings.remove(index - 1);
>+
>             // remove from entries list
>-            entries.remove(removedEntry);
>+            entries.remove(sibling.getUUID());
> 
>-            if (siblings.size() == 0) {
>-                // short cut
>-                names.remove(nodeName);
>-                return removedEntry;
>+            // update linked list of siblings & name map entry
>+            if (prevSibling != null) {
>+                prevSibling.setNextSibling(sibling.getNextSibling());
>+            } else {
>+                // the head is removed from the linked siblings list,
>+                // update name map
>+                if (sibling.getNextSibling() == null) {
>+                    nameMap.remove(nodeName);
>+                } else {
>+                    nameMap.put(nodeName, sibling.getNextSibling());
>+                }
>             }
>-
>             // update indices of subsequent same-name siblings
>-            for (int i = index - 1; i < siblings.size(); i++) {
>-                ChildNodeEntry oldEntry = (ChildNodeEntry) siblings.get(i);
>-                ChildNodeEntry newEntry = new ChildNodeEntry(nodeName, oldEntry.getUUID(), oldEntry.getIndex() - 1);
>-                // overwrite old entry with updated entry in siblings list
>-                siblings.set(i, newEntry);
>-                // overwrite old entry with updated entry in entries list
>-                entries.set(entries.indexOf(oldEntry), newEntry);
>+            ChildNodeEntry nextSibling = sibling.getNextSibling();
>+            while (nextSibling != null) {
>+                nextSibling.decIndex();
>+                nextSibling = nextSibling.getNextSibling();
>             }
> 
>-            return removedEntry;
>+            return sibling;
>         }
> 
>         List get(QName nodeName) {
>-            List siblings = (List) names.get(nodeName);
>-            if (siblings == null) {
>+            ChildNodeEntry sibling = (ChildNodeEntry) nameMap.get(nodeName);
>+            if (sibling == null) {
>                 return Collections.EMPTY_LIST;
>-            } else {
>-                return Collections.unmodifiableList(siblings);
>             }
>-        }
>-
>-        ChildNodeEntry remove(String uuid) {
>-            Iterator iter = entries.iterator();
>-            while (iter.hasNext()) {
>-                ChildNodeEntry entry = (ChildNodeEntry) iter.next();
>-                if (entry.getUUID().equals(uuid)) {
>-                    return remove(entry);
>-                }
>+            List siblings = new ArrayList();
>+            while (sibling != null) {
>+                siblings.add(sibling);
>+                sibling = sibling.getNextSibling();
>             }
>-            return null;
>+            return siblings;
>         }
> 
>         ChildNodeEntry get(String uuid) {
>-            Iterator iter = entries.iterator();
>-            while (iter.hasNext()) {
>-                ChildNodeEntry entry = (ChildNodeEntry) iter.next();
>-                if (entry.getUUID().equals(uuid)) {
>-                    return entry;
>-                }
>-            }
>-            return null;
>+            return (ChildNodeEntry) entries.get(uuid);
>         }
> 
>-        Iterator iterator() {
>-            return entries.iterator();
>-        }
>+        ChildNodeEntry get(QName nodeName, int index) {
>+            if (index < 1) {
>+                throw new IllegalArgumentException("index is 1-based");
>+            }
> 
>-        List entries() {
>-            return Collections.unmodifiableList(entries);
>+            ChildNodeEntry sibling = (ChildNodeEntry) nameMap.get(nodeName);
>+            while (sibling != null) {
>+                if (sibling.getIndex() == index) {
>+                    return sibling;
>+                }
>+                sibling = sibling.getNextSibling();
>+            }
>+            return null;
>         }
> 
>         /**
>@@ -860,87 +882,208 @@
>          * <code>this</code> but not in <code>other</code>
>          * <p/>
>          * Note that two entries are considered identical in this context if
>-         * they have the same name and uuid, i.e. the index is disregarded,
>+         * they have the same name and uuid, i.e. the index is disregarded
>          * whereas <code>ChildNodeEntry.equals(Object)</code> also compares
>          * the index.
>          *
>          * @param other entries to be removed
>-         * @return a new list of entries who do only exist in <code>this</code>
>-         *         but not in <code>other</code>
>+         * @return a new list of those entries that do only exist in
>+         *         <code>this</code> but not in <code>other</code>
>          */
>         List removeAll(ChildNodeEntries other) {
>             if (entries.isEmpty()) {
>                 return Collections.EMPTY_LIST;
>             }
>-            if (other.entries.isEmpty()) {
>-                return Collections.unmodifiableList(entries);
>+            if (other.isEmpty()) {
>+                return this;
>             }
> 
>-            List result = new ArrayList(entries);
>-
>-            Iterator otherIter = other.entries.iterator();
>-            while (otherIter.hasNext()) {
>-                ChildNodeEntry otherEntry = (ChildNodeEntry) otherIter.next();
>-                Iterator ourIter = entries.iterator();
>-                while (ourIter.hasNext()) {
>-                    ChildNodeEntry ourEntry = (ChildNodeEntry) ourIter.next();
>-                    if (ourEntry.getName().equals(otherEntry.getName())
>-                            && ourEntry.getUUID().equals(otherEntry.getUUID())) {
>-                        result.remove(ourEntry);
>-                    }
>+            List result = new ArrayList();
>+            Iterator iter = iterator();
>+            while (iter.hasNext()) {
>+                ChildNodeEntry entry = (ChildNodeEntry) iter.next();
>+                ChildNodeEntry otherEntry = (ChildNodeEntry) other.get(entry.uuid);
>+                if (otherEntry == null
>+                        || !entry.getName().equals(otherEntry.getName())) {
>+                    result.add(entry);
>                 }
>             }
>+
>             return result;
>         }
>-    }
> 
>-    /**
>-     * base class for <code>PropertyEntry</code> and <code>ChildNodeEntry</code>
>-     */
>-    private abstract static class ChildEntry implements Serializable {
>-        protected QName name;
>+        //-------------------------------------------< unmodifiable List view >
>+        public boolean contains(Object o) {
>+            if (o instanceof ChildNodeEntry) {
>+                return entries.containsKey(((ChildNodeEntry) o).uuid);
>+            } else {
>+                return false;
>+            }
>+        }
> 
>-        protected ChildEntry(QName name) {
>-            this.name = name;
>+        public boolean containsAll(Collection c) {
>+            Iterator iter = c.iterator();
>+            while (iter.hasNext()) {
>+                if (!contains(iter.next())) {
>+                    return false;
>+                }
>+            }
>+            return true;
>         }
> 
>-        public QName getName() {
>-            return name;
>+        public Object get(int index) {
>+            return entries.getValue(index);
>         }
>-    }
> 
>-    /**
>-     * <code>PropertyEntry</code> specifies the name of a property entry.
>-     */
>-    public static class PropertyEntry extends ChildEntry {
>+        public int indexOf(Object o) {
>+            if (o instanceof ChildNodeEntry) {
>+                return entries.indexOf(((ChildNodeEntry) o).uuid);
>+            } else {
>+                return -1;
>+            }
>+        }
> 
>-        private int hash = 0;
>+        public boolean isEmpty() {
>+            return entries.isEmpty();
>+        }
> 
>-        protected PropertyEntry(QName propName) {
>-            super(propName);
>+        public int lastIndexOf(Object o) {
>+            // entries are unique
>+            return indexOf(o);
>         }
> 
>-        public boolean equals(Object obj) {
>-            if (this == obj) {
>-                return true;
>+        public Iterator iterator() {
>+            return new OrderedMapIterator(entries.asList().listIterator(), entries);
>+        }
>+
>+        public ListIterator listIterator() {
>+            return new OrderedMapIterator(entries.asList().listIterator(), entries);
>+        }
>+
>+        public ListIterator listIterator(int index) {
>+            return new OrderedMapIterator(entries.asList().listIterator(index), entries);
>+        }
>+
>+        public int size() {
>+            return entries.size();
>+        }
>+
>+        public List subList(int fromIndex, int toIndex) {
>+            // @todo FIXME does not fulfil the contract of List.subList(int,int)
>+            return Collections.unmodifiableList(new ArrayList(this).subList(fromIndex, toIndex));
>+        }
>+
>+        public Object[] toArray() {
>+            ChildNodeEntry[] array = new ChildNodeEntry[size()];
>+            return toArray(array);
>+        }
>+
>+        public Object[] toArray(Object a[]) {
>+            if (!a.getClass().getComponentType().isAssignableFrom(ChildNodeEntry.class)) {
>+                throw new ArrayStoreException();
>             }
>-            if (obj instanceof PropertyEntry) {
>-                PropertyEntry other = (PropertyEntry) obj;
>-                return name.equals(other.name);
>+            if (a.length < size()) {
>+                a = new ChildNodeEntry[size()];
>             }
>-            return false;
>+            MapIterator iter = entries.mapIterator();
>+            int i = 0;
>+            while (iter.hasNext()) {
>+                iter.next();
>+                a[i] = entries.getValue(i);
>+                i++;
>+            }
>+            while (i < a.length) {
>+                a[i++] = null;
>+            }
>+            return a;
>         }
> 
>-        public String toString() {
>-            return name.toString();
>+        public void add(int index, Object element) {
>+            throw new UnsupportedOperationException();
>         }
> 
>-        public int hashCode() {
>-            // PropertyEntry is immutable, we can store the computed hash code value
>-            if (hash == 0) {
>-                hash = name.hashCode();
>+        public boolean add(Object o) {
>+            throw new UnsupportedOperationException();
>+        }
>+
>+        public boolean addAll(Collection c) {
>+            throw new UnsupportedOperationException();
>+        }
>+
>+        public boolean addAll(int index, Collection c) {
>+            throw new UnsupportedOperationException();
>+        }
>+
>+        public void clear() {
>+            throw new UnsupportedOperationException();
>+        }
>+
>+        public Object remove(int index) {
>+            throw new UnsupportedOperationException();
>+        }
>+
>+        public boolean remove(Object o) {
>+            throw new UnsupportedOperationException();
>+        }
>+
>+        public boolean removeAll(Collection c) {
>+            throw new UnsupportedOperationException();
>+        }
>+
>+        public boolean retainAll(Collection c) {
>+            throw new UnsupportedOperationException();
>+        }
>+
>+        public Object set(int index, Object element) {
>+            throw new UnsupportedOperationException();
>+        }
>+
>+        //----------------------------------------------------< inner classes >
>+        class OrderedMapIterator implements ListIterator {
>+
>+            final ListIterator keyIter;
>+            final Map entries;
>+
>+            OrderedMapIterator(ListIterator keyIter, Map entries) {
>+                this.keyIter = keyIter;
>+                this.entries = entries;
>+            }
>+
>+            public boolean hasNext() {
>+                return keyIter.hasNext();
>+            }
>+
>+            public Object next() {
>+                return entries.get(keyIter.next());
>+            }
>+
>+            public boolean hasPrevious() {
>+                return keyIter.hasPrevious();
>+            }
>+
>+            public int nextIndex() {
>+                return keyIter.nextIndex();
>+            }
>+
>+            public Object previous() {
>+                return entries.get(keyIter.previous());
>+            }
>+
>+            public int previousIndex() {
>+                return keyIter.previousIndex();
>+            }
>+
>+            public void add(Object o) {
>+                throw new UnsupportedOperationException();
>+            }
>+
>+            public void remove() {
>+                throw new UnsupportedOperationException();
>+            }
>+
>+            public void set(Object o) {
>+                throw new UnsupportedOperationException();
>             }
>-            return hash;
>         }
>     }
> 
>@@ -948,15 +1091,18 @@
>      * <code>ChildNodeEntry</code> specifies the name, index (in the case of
>      * same-name siblings) and the UUID of a child node entry.
>      */
>-    public static class ChildNodeEntry extends ChildEntry {
>-
>-        private int hash = 0;
>+    public static class ChildNodeEntry {
> 
>+        private QName name;
>         private int index; // 1-based index for same-name siblings
>         private String uuid;
>+        private ChildNodeEntry nextSibling;
> 
>-        protected ChildNodeEntry(QName nodeName, String uuid, int index) {
>-            super(nodeName);
>+        private ChildNodeEntry(QName name, String uuid, int index) {
>+            if (name == null) {
>+                throw new IllegalArgumentException("name can not be null");
>+            }
>+            this.name = name;
> 
>             if (uuid == null) {
>                 throw new IllegalArgumentException("uuid can not be null");
>@@ -967,16 +1113,46 @@
>                 throw new IllegalArgumentException("index is 1-based");
>             }
>             this.index = index;
>+
>+            nextSibling = null;
>         }
> 
>         public String getUUID() {
>             return uuid;
>         }
> 
>+        public QName getName() {
>+            return name;
>+        }
>+
>         public int getIndex() {
>             return index;
>         }
> 
>+        public ChildNodeEntry getNextSibling() {
>+            return nextSibling;
>+        }
>+
>+        void setNextSibling(ChildNodeEntry nextSibling) {
>+            if (nextSibling != null && !nextSibling.getName().equals(name)) {
>+                throw new IllegalArgumentException("not a same-name sibling entry");
>+            }
>+
>+            this.nextSibling = nextSibling;
>+        }
>+
>+        int incIndex() {
>+            return ++index;
>+        }
>+
>+        int decIndex() {
>+            if (index == 1) {
>+                throw new IndexOutOfBoundsException();
>+            }
>+            return --index;
>+        }
>+
>+        //---------------------------------------< java.lang.Object overrides >
>         public boolean equals(Object obj) {
>             if (this == obj) {
>                 return true;
>@@ -993,17 +1169,15 @@
>             return name.toString() + "[" + index + "] -> " + uuid;
>         }
> 
>+        /**
>+         * Returns zero to satisfy the Object equals/hashCode contract.
>+         * This class is mutable and not meant to be used as a hash key.
>+         *
>+         * @return always zero
>+         * @see Object#hashCode()
>+         */
>         public int hashCode() {
>-            // ChildNodeEntry is immutable, we can store the computed hash code value
>-            int h = hash;
>-            if (h == 0) {
>-                h = 17;
>-                h = 37 * h + name.hashCode();
>-                h = 37 * h + uuid.hashCode();
>-                h = 37 * h + index;
>-                hash = h;
>-            }
>-            return h;
>+            return 0;
>         }
>     }
> }
>
>Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java
>URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java?rev=201999&r1=201998&r2=201999&view=diff
>==============================================================================
>--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java (original)
>+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java Mon Jun 27 08:08:35 2005
>@@ -412,6 +412,7 @@
>         if (!transientStateMgr.hasAnyItemStatesInAttic()) {
>             return Collections.EMPTY_LIST.iterator();
>         }
>+
>         // collection of descendant transient states in attic:
>         // the path serves as key and sort criteria
> 
>@@ -425,10 +426,8 @@
>         TreeMap descendants = new TreeMap(new PathComparator());
>         try {
>             Path parentPath = zombieHierMgr.getPath(parentId);
>-            /**
>-             * walk through list of transient states in attic and check if
>-             * they are descendants of the specified parent
>-             */
>+             // walk through list of transient states in attic and check if
>+             // they are descendants of the specified parent
>             Iterator iter = transientStateMgr.getEntriesInAttic();
>             while (iter.hasNext()) {
>                 ItemState state = (ItemState) iter.next();
>@@ -445,7 +444,17 @@
>         } catch (RepositoryException re) {
>             log.warn("inconsistent hierarchy state", re);
>         }
>-
>+/*
>+        TreeMap descendants = new TreeMap();
>+        Iterator iter = transientStateMgr.getEntriesInAttic();
>+        while (iter.hasNext()) {
>+            ItemState state = (ItemState) iter.next();
>+            int depth = getAncestorCount(state, parentId.getUUID());
>+            if (depth >= 0) {
>+                descendants.put(new ItemStateKey(state, depth), state);
>+            }
>+        }
>+*/
>         return descendants.values().iterator();
>     }
> 
>
>Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java
>URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java?rev=201999&r1=201998&r2=201999&view=diff
>==============================================================================
>--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java (original)
>+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java Mon Jun 27 08:08:35 2005
>@@ -148,7 +148,7 @@
>         rootState.setDefinitionId(nodeDefId);
> 
>         // create jcr:primaryType property
>-        rootState.addPropertyEntry(propDef.getName());
>+        rootState.addPropertyName(propDef.getName());
> 
>         PropertyState prop = createInstance(propDef.getName(), rootNodeUUID);
>         prop.setValues(new InternalValue[]{InternalValue.create(Constants.REP_ROOT)});
>
>Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/obj/ObjectPersistenceManager.java
>URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/obj/ObjectPersistenceManager.java?rev=201999&r1=201998&r2=201999&view=diff
>==============================================================================
>--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/obj/ObjectPersistenceManager.java (original)
>+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/obj/ObjectPersistenceManager.java Mon Jun 27 08:08:35 2005
>@@ -175,11 +175,11 @@
>             out.writeUTF(iter.next().toString());   // name
>         }
>         // properties (names)
>-        c = state.getPropertyEntries();
>+        c = state.getPropertyNames();
>         out.writeInt(c.size()); // count
>         for (Iterator iter = c.iterator(); iter.hasNext();) {
>-            NodeState.PropertyEntry entry = (NodeState.PropertyEntry) iter.next();
>-            out.writeUTF(entry.getName().toString());   // name
>+            QName propName = (QName) iter.next();
>+            out.writeUTF(propName.toString());   // name
>         }
>         // child nodes (list of name/uuid pairs)
>         c = state.getChildNodeEntries();
>@@ -235,7 +235,7 @@
>         // properties (names)
>         count = in.readInt();   // count
>         for (int i = 0; i < count; i++) {
>-            state.addPropertyEntry(QName.valueOf(in.readUTF())); // name
>+            state.addPropertyName(QName.valueOf(in.readUTF())); // name
>         }
>         // child nodes (list of name/uuid pairs)
>         count = in.readInt();   // count
>
>Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/xml/XMLPersistenceManager.java
>URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/xml/XMLPersistenceManager.java?rev=201999&r1=201998&r2=201999&view=diff
>==============================================================================
>--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/xml/XMLPersistenceManager.java (original)
>+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/xml/XMLPersistenceManager.java Mon Jun 27 08:08:35 2005
>@@ -226,7 +226,7 @@
>             while (walker.iterateElements(PROPERTY_ELEMENT)) {
>                 String propName = walker.getAttribute(NAME_ATTRIBUTE);
>                 // @todo deserialize type and values
>-                state.addPropertyEntry(QName.valueOf(propName));
>+                state.addPropertyName(QName.valueOf(propName));
>             }
>             walker.leaveElement();
>         }
>@@ -508,11 +508,11 @@
> 
>                 // properties
>                 writer.write("\t<" + PROPERTIES_ELEMENT + ">\n");
>-                iter = state.getPropertyEntries().iterator();
>+                iter = state.getPropertyNames().iterator();
>                 while (iter.hasNext()) {
>-                    NodeState.PropertyEntry entry = (NodeState.PropertyEntry) iter.next();
>+                    QName propName = (QName) iter.next();
>                     writer.write("\t\t<" + PROPERTY_ELEMENT + " "
>-                            + NAME_ATTRIBUTE + "=\"" + Text.encodeIllegalXMLCharacters(entry.getName().toString()) + "\">\n");
>+                            + NAME_ATTRIBUTE + "=\"" + Text.encodeIllegalXMLCharacters(propName.toString()) + "\">\n");
>                     // @todo serialize type, definition id and values
>                     writer.write("\t\t</" + PROPERTY_ELEMENT + ">\n");
>                 }
>
>Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/NodeStateEx.java
>URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/NodeStateEx.java?rev=201999&r1=201998&r2=201999&view=diff
>==============================================================================
>--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/NodeStateEx.java (original)
>+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/NodeStateEx.java Mon Jun 27 08:08:35 2005
>@@ -131,11 +131,11 @@
>      * @return
>      */
>     public PropertyState[] getProperties() throws ItemStateException {
>-        List list = nodeState.getPropertyEntries();
>+        List list = nodeState.getPropertyNames();
>         PropertyState[] props = new PropertyState[list.size()];
>         for (int i = 0; i < list.size(); i++) {
>-            NodeState.PropertyEntry entry = (NodeState.PropertyEntry) list.get(i);
>-            PropertyId propId = new PropertyId(nodeState.getUUID(), entry.getName());
>+            QName propName = (QName) list.get(i);
>+            PropertyId propId = new PropertyId(nodeState.getUUID(), propName);
>             props[i] = (PropertyState) stateMgr.getItemState(propId);
>         }
>         return props;
>@@ -262,7 +262,7 @@
>             propState.setDefinitionId(pd.getId());
> 
>             // need to store nodestate
>-            nodeState.addPropertyEntry(name);
>+            nodeState.addPropertyName(name);
>             if (nodeState.getStatus() == ItemState.STATUS_EXISTING) {
>                 nodeState.setStatus(ItemState.STATUS_EXISTING_MODIFIED);
>             }
>@@ -341,7 +341,7 @@
>     }
> 
>     /**
>-     * removes the property with the given name and 1-based index
>+     * removes the property with the given name
>      *
>      * @param name
>      * @return
>@@ -349,14 +349,13 @@
>      */
>     public boolean removeProperty(QName name) throws RepositoryException {
>         try {
>-            NodeState.PropertyEntry entry = nodeState.getPropertyEntry(name);
>-            if (entry == null) {
>+            if (!nodeState.hasPropertyName(name)) {
>                 return false;
>             } else {
>                 PropertyId propId = new PropertyId(nodeState.getUUID(), name);
>                 ItemState state = stateMgr.getItemState(propId);
>                 stateMgr.destroy(state);
>-                nodeState.removePropertyEntry(name);
>+                nodeState.removePropertyName(name);
>                 nodeState.setStatus(ItemState.STATUS_EXISTING_MODIFIED);
>                 return true;
>             }
>@@ -484,10 +483,10 @@
> 
>         if (state.getStatus() != ItemState.STATUS_EXISTING) {
>             // first store all transient properties
>-            List props = state.getPropertyEntries();
>+            List props = state.getPropertyNames();
>             for (int i = 0; i < props.size(); i++) {
>-                NodeState.PropertyEntry entry = (NodeState.PropertyEntry) props.get(i);
>-                PropertyState pstate = (PropertyState) stateMgr.getItemState(new PropertyId(state.getUUID(), entry.getName()));
>+                QName propName = (QName) props.get(i);
>+                PropertyState pstate = (PropertyState) stateMgr.getItemState(new PropertyId(state.getUUID(), propName));
>                 if (pstate.getStatus() != ItemState.STATUS_EXISTING) {
>                     stateMgr.store(pstate);
>                 }
>@@ -528,10 +527,10 @@
>     private void reload(NodeState state) throws ItemStateException {
>         if (state.getStatus() != ItemState.STATUS_EXISTING) {
>             // first discard all all transient properties
>-            List props = state.getPropertyEntries();
>+            List props = state.getPropertyNames();
>             for (int i = 0; i < props.size(); i++) {
>-                NodeState.PropertyEntry entry = (NodeState.PropertyEntry) props.get(i);
>-                PropertyState pstate = (PropertyState) stateMgr.getItemState(new PropertyId(state.getUUID(), entry.getName()));
>+                QName propName = (QName) props.get(i);
>+                PropertyState pstate = (PropertyState) stateMgr.getItemState(new PropertyId(state.getUUID(), propName));
>                 if (pstate.getStatus() != ItemState.STATUS_EXISTING) {
>                     pstate.discard();
>                 }
>
>Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionManagerImpl.java
>URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionManagerImpl.java?rev=201999&r1=201998&r2=201999&view=diff
>==============================================================================
>--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionManagerImpl.java (original)
>+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionManagerImpl.java Mon Jun 27 08:08:35 2005
>@@ -140,7 +140,7 @@
>                 pt.setMultiValued(false);
>                 pt.setType(PropertyType.NAME);
>                 pt.setValues(new InternalValue[]{InternalValue.create(REP_VERSIONSTORAGE)});
>-                root.addPropertyEntry(pt.getName());
>+                root.addPropertyName(pt.getName());
>                 ChangeLog cl = new ChangeLog();
>                 cl.added(root);
>                 cl.added(pt);
>@@ -708,10 +708,10 @@
>         if (state != null) {
>             if (recursive && state instanceof NodeState) {
>                 NodeState nState = (NodeState) state;
>-                Iterator iter = nState.getPropertyEntries().iterator();
>+                Iterator iter = nState.getPropertyNames().iterator();
>                 while (iter.hasNext()) {
>-                    NodeState.PropertyEntry pe = (NodeState.PropertyEntry) iter.next();
>-                    invalidateItem(new PropertyId(nState.getUUID(), pe.getName()), false);
>+                    QName propName = (QName) iter.next();
>+                    invalidateItem(new PropertyId(nState.getUUID(), propName), false);
>                 }
>                 iter = nState.getChildNodeEntries().iterator();
>                 while (iter.hasNext()) {
>
>Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/AbstractVISProvider.java
>URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/AbstractVISProvider.java?rev=201999&r1=201998&r2=201999&view=diff
>==============================================================================
>--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/AbstractVISProvider.java (original)
>+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/AbstractVISProvider.java Mon Jun 27 08:08:35 2005
>@@ -211,7 +211,7 @@
> 
>             // handle some default prop states
>             if (parent instanceof VirtualNodeState) {
>-                return parent.hasPropertyEntry(id.getName());
>+                return parent.hasPropertyName(id.getName());
>             }
>         } catch (ItemStateException e) {
>             // ignore
>
>Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/VirtualNodeState.java
>URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/VirtualNodeState.java?rev=201999&r1=201998&r2=201999&view=diff
>==============================================================================
>--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/VirtualNodeState.java (original)
>+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/VirtualNodeState.java Mon Jun 27 08:08:35 2005
>@@ -177,7 +177,7 @@
>         if (prop == null) {
>             prop = stateMgr.createPropertyState(this, name, type, multiValued);
>             properties.put(name, prop);
>-            addPropertyEntry(name);
>+            addPropertyName(name);
>         }
>         return prop;
>     }
>@@ -198,49 +198,6 @@
>             }
>             setMixinTypeNames(set);
>             setPropertyValues(JCR_MIXINTYPES, PropertyType.NAME, values);
>-        }
>-    }
>-
>-    /**
>-     * Creates a new VirtualChildNodeEntry
>-     *
>-     * @param nodeName
>-     * @param uuid
>-     * @param index
>-     * @return
>-     */
>-    protected VirtualChildNodeEntry createChildNodeEntry(QName nodeName, String uuid, int index) {
>-        return new VirtualChildNodeEntry(nodeName, uuid, index);
>-    }
>-
>-    /**
>-     * Creates a new VirtualPropertyEntry
>-     *
>-     * @param name
>-     * @return
>-     */
>-    protected VirtualPropertyEntry createPropertyEntry(QName name) {
>-        return new VirtualPropertyEntry(name);
>-    }
>-
>-    /**
>-     * Overload NodeState.ChildNodeEntry in order to create own ones.
>-     */
>-    public class VirtualChildNodeEntry extends NodeState.ChildNodeEntry {
>-
>-        protected VirtualChildNodeEntry(QName nodeName, String uuid, int index) {
>-            super(nodeName, uuid, index);
>-        }
>-
>-    }
>-
>-    /**
>-     * Overload NodeState.PropertyEntry in order to create own ones.
>-     */
>-    public class VirtualPropertyEntry extends NodeState.PropertyEntry {
>-
>-        protected VirtualPropertyEntry(QName propName) {
>-            super(propName);
>         }
>     }
> 
>
>Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/WorkspaceImporter.java
>URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/WorkspaceImporter.java?rev=201999&r1=201998&r2=201999&view=diff
>==============================================================================
>--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/WorkspaceImporter.java (original)
>+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/WorkspaceImporter.java Mon Jun 27 08:08:35 2005
>@@ -274,7 +274,7 @@
>             VersionHistory hist = session.getVersionManager().createVersionHistory(session, node);
> 
>             // jcr:versionHistory
>-            if (!node.hasPropertyEntry(JCR_VERSIONHISTORY)) {
>+            if (!node.hasPropertyName(JCR_VERSIONHISTORY)) {
>                 def = itemOps.findApplicablePropertyDefinition(JCR_VERSIONHISTORY,
>                         PropertyType.REFERENCE, false, node);
>                 prop = itemOps.createPropertyState(node, JCR_VERSIONHISTORY,
>@@ -283,7 +283,7 @@
>             }
> 
>             // jcr:baseVersion
>-            if (!node.hasPropertyEntry(JCR_BASEVERSION)) {
>+            if (!node.hasPropertyName(JCR_BASEVERSION)) {
>                 def = itemOps.findApplicablePropertyDefinition(JCR_BASEVERSION,
>                         PropertyType.REFERENCE, false, node);
>                 prop = itemOps.createPropertyState(node, JCR_BASEVERSION,
>@@ -292,7 +292,7 @@
>             }
> 
>             // jcr:predecessors
>-            if (!node.hasPropertyEntry(JCR_PREDECESSORS)) {
>+            if (!node.hasPropertyName(JCR_PREDECESSORS)) {
>                 def = itemOps.findApplicablePropertyDefinition(JCR_PREDECESSORS,
>                         PropertyType.REFERENCE, true, node);
>                 prop = itemOps.createPropertyState(node, JCR_PREDECESSORS,
>@@ -301,7 +301,7 @@
>             }
> 
>             // jcr:isCheckedOut
>-            if (!node.hasPropertyEntry(JCR_ISCHECKEDOUT)) {
>+            if (!node.hasPropertyName(JCR_ISCHECKEDOUT)) {
>                 def = itemOps.findApplicablePropertyDefinition(JCR_ISCHECKEDOUT,
>                         PropertyType.BOOLEAN, false, node);
>                 prop = itemOps.createPropertyState(node, JCR_ISCHECKEDOUT,
>@@ -408,7 +408,7 @@
>                         return;
>                     }
> 
>-                    if (parent.hasPropertyEntry(nodeName)) {
>+                    if (parent.hasPropertyName(nodeName)) {
>                         /**
>                          * a property with the same name already exists; if this property
>                          * has been imported as well (e.g. through document view import
>@@ -424,14 +424,14 @@
>                             // rename conflicting property
>                             // @todo use better reversible escaping scheme to create unique name
>                             QName newName = new QName(nodeName.getNamespaceURI(), nodeName.getLocalName() + "_");
>-                            if (parent.hasPropertyEntry(newName)) {
>+                            if (parent.hasPropertyName(newName)) {
>                                 newName = new QName(newName.getNamespaceURI(), newName.getLocalName() + "_");
>                             }
>                             PropertyState newProp =
>                                     itemOps.createPropertyState(parent, newName,
>                                             conflicting.getType(), conflicting.getValues().length);
>                             newProp.setValues(conflicting.getValues());
>-                            parent.removePropertyEntry(nodeName);
>+                            parent.removePropertyName(nodeName);
>                             itemOps.store(parent);
>                             itemOps.destroy(conflicting);
>                         }
>@@ -494,7 +494,7 @@
>                 PropertyState prop = null;
>                 PropDef def = null;
> 
>-                if (node.hasPropertyEntry(propName)) {
>+                if (node.hasPropertyName(propName)) {
>                     // a property with that name already exists...
>                     PropertyId idExisting = new PropertyId(node.getUUID(), propName);
>                     PropertyState existing =
>
>
>
>  
>


Re: svn commit: r201999 - in /incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core: ./ query/lucene/ state/ state/obj/ state/xml/ version/ virtual/ xml/

Posted by Stefan Guggisberg <st...@gmail.com>.
i'll take care of it.

cheers
stefan

On 6/27/05, Serge Huber <sh...@jahia.com> wrote:
> 
> Ok I managed to fix it. Attached is the patch.
> 
> Stefan (or another committer), if this could be applied ASAP this would
> be great.
> 
> cheers,
>   Serge...
>

Re: svn commit: r201999 - in /incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core: ./ query/lucene/ state/ state/obj/ state/xml/ version/ virtual/ xml/

Posted by Stefan Guggisberg <st...@gmail.com>.
ok, done (r202167).

On 6/27/05, Serge Huber <sh...@jahia.com> wrote:
> 
> Ok I managed to fix it. Attached is the patch.
> 
> Stefan (or another committer), if this could be applied ASAP this would
> be great.
> 
> cheers,
>   Serge...
>

Re: svn commit: r201999 - in /incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core: ./ query/lucene/ state/ state/obj/ state/xml/ version/ virtual/ xml/

Posted by Serge Huber <sh...@jahia.com>.
Ok I managed to fix it. Attached is the patch.

Stefan (or another committer), if this could be applied ASAP this would 
be great.

cheers,
  Serge...

Serge Huber wrote:

> Arg this commit breaks the ORM PMs again :)
>
> I'll see if I can fix it quickly...
>
> cheers,
>  Serge...
>
> stefan@apache.org wrote:
>
>> Author: stefan
>> Date: Mon Jun 27 08:08:35 2005
>> New Revision: 201999
>>
>> URL: http://svn.apache.org/viewcvs?rev=201999&view=rev
>> Log:
>> JCR-129: applied patch supplied by serge as-is
>> (http://issues.apache.org/jira/browse/JCR-129)misc. NodeState 
>> optimizations:
>> - removed PropertyEntry class; the relevant
>>  NodeState methods (e.g. getPropertyEntries())
>>  now return QName's instead of PropertyEntry
>>  to avoid unneccessary object creation
>> - reimplemented internal ChildNodeEntries class
>>  for improved speed and efficiency
>>
>> Modified:
>>    
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/BatchedItemOperations.java 
>>
>>    
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/HierarchyManagerImpl.java 
>>
>>    
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemImpl.java 
>>
>>    
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemManager.java 
>>
>>    
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemValidator.java 
>>
>>    
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NodeImpl.java 
>>
>>    
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/query/lucene/NodeIndexer.java 
>>
>>    
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/NodeState.java 
>>
>>    
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java 
>>
>>    
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java 
>>
>>    
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/obj/ObjectPersistenceManager.java 
>>
>>    
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/xml/XMLPersistenceManager.java 
>>
>>    
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/NodeStateEx.java 
>>
>>    
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionManagerImpl.java 
>>
>>    
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/AbstractVISProvider.java 
>>
>>    
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/VirtualNodeState.java 
>>
>>    
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/WorkspaceImporter.java 
>>
>>
>> Modified: 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/BatchedItemOperations.java 
>>
>> URL: 
>> http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/BatchedItemOperations.java?rev=201999&r1=201998&r2=201999&view=diff 
>>
>> ============================================================================== 
>>
>> --- 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/BatchedItemOperations.java 
>> (original)
>> +++ 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/BatchedItemOperations.java 
>> Mon Jun 27 08:08:35 2005
>> @@ -583,7 +583,7 @@
>>                             parentState);
>>
>>             // check for name collisions
>> -            if (parentState.hasPropertyEntry(nodeName)) {
>> +            if (parentState.hasPropertyName(nodeName)) {
>>                 // there's already a property with that name
>>                 throw new ItemExistsException("cannot add child node '"
>>                         + nodeName.getLocalName() + "' to "
>> @@ -1003,7 +1003,7 @@
>>             RepositoryException, IllegalStateException {
>>
>>         // check for name collisions with existing properties
>> -        if (parent.hasPropertyEntry(nodeName)) {
>> +        if (parent.hasPropertyName(nodeName)) {
>>             String msg = "there's already a property with name " + 
>> nodeName;
>>             log.debug(msg);
>>             throw new RepositoryException(msg);
>> @@ -1148,9 +1148,8 @@
>>         }
>>
>>         // check for name collisions with existing properties
>> -        if (parent.hasPropertyEntry(propName)) {
>> -            PropertyId id = new PropertyId(parent.getUUID(),
>> -                    parent.getPropertyEntry(propName).getName());
>> +        if (parent.hasPropertyName(propName)) {
>> +            PropertyId id = new PropertyId(parent.getUUID(), propName);
>>             throw new ItemExistsException(safeGetJCRPath(id));
>>         }
>>
>> @@ -1177,7 +1176,7 @@
>>         }
>>
>>         // now add new property entry to parent
>> -        parent.addPropertyEntry(propName);
>> +        parent.addPropertyName(propName);
>>         // store parent
>>         stateMgr.store(parent);
>>
>> @@ -1301,7 +1300,7 @@
>>          * this would have a negative impact on performance though...
>>          */
>>         NodeState nodeState = getNodeState(nodePath);
>> -        while (!nodeState.hasPropertyEntry(JCR_ISCHECKEDOUT)) {
>> +        while (!nodeState.hasPropertyName(JCR_ISCHECKEDOUT)) {
>>             if (nodePath.denotesRoot()) {
>>                 return;
>>             }
>> @@ -1528,16 +1527,16 @@
>>
>>         // remove properties
>>         // use temp array to avoid ConcurrentModificationException
>> -        tmp = new ArrayList(targetState.getPropertyEntries());
>> +        tmp = new ArrayList(targetState.getPropertyNames());
>>         for (int i = 0; i < tmp.size(); i++) {
>> -            NodeState.PropertyEntry entry = 
>> (NodeState.PropertyEntry) tmp.get(i);
>> +            QName propName = (QName) tmp.get(i);
>>             PropertyId propId =
>> -                    new PropertyId(targetState.getUUID(), 
>> entry.getName());
>> +                    new PropertyId(targetState.getUUID(), propName);
>>             try {
>>                 PropertyState propState =
>>                         (PropertyState) stateMgr.getItemState(propId);
>>                 // remove property entry
>> -                targetState.removePropertyEntry(propId.getName());
>> +                targetState.removePropertyName(propId.getName());
>>                 // destroy property state
>>                 stateMgr.destroy(propState);
>>             } catch (ItemStateException ise) {
>> @@ -1684,10 +1683,10 @@
>>                 newState.addChildNodeEntry(entry.getName(), 
>> newChildState.getUUID());
>>             }
>>             // copy properties
>> -            iter = srcState.getPropertyEntries().iterator();
>> +            iter = srcState.getPropertyNames().iterator();
>>             while (iter.hasNext()) {
>> -                NodeState.PropertyEntry entry = 
>> (NodeState.PropertyEntry) iter.next();
>> -                PropertyId propId = new 
>> PropertyId(srcState.getUUID(), entry.getName());
>> +                QName propName = (QName) iter.next();
>> +                PropertyId propId = new 
>> PropertyId(srcState.getUUID(), propName);
>>                 if (!srcAccessMgr.isGranted(propId, 
>> AccessManager.READ)) {
>>                     continue;
>>                 }
>> @@ -1709,14 +1708,14 @@
>>                 }
>>
>>                 PropertyState newChildState =
>> -                        copyPropertyState(srcChildState, uuid, 
>> entry.getName());
>> +                        copyPropertyState(srcChildState, uuid, 
>> propName);
>>                 if (newChildState.getType() == PropertyType.REFERENCE) {
>>                     refTracker.processedReference(newChildState);
>>                 }
>>                 // store new property
>>                 stateMgr.store(newChildState);
>>                 // add new property entry to new node
>> -                newState.addPropertyEntry(entry.getName());
>> +                newState.addPropertyName(propName);
>>             }
>>             return newState;
>>         } catch (ItemStateException ise) {
>>
>> Modified: 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/HierarchyManagerImpl.java 
>>
>> URL: 
>> http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/HierarchyManagerImpl.java?rev=201999&r1=201998&r2=201999&view=diff 
>>
>> ============================================================================== 
>>
>> --- 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/HierarchyManagerImpl.java 
>> (original)
>> +++ 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/HierarchyManagerImpl.java 
>> Mon Jun 27 08:08:35 2005
>> @@ -169,7 +169,7 @@
>>                     parentState.getChildNodeEntry(name, index);
>>             childId = new NodeId(nodeEntry.getUUID());
>>
>> -        } else if (parentState.hasPropertyEntry(name)) {
>> +        } else if (parentState.hasPropertyName(name)) {
>>             // property
>>             if (index > 1) {
>>                 // properties can't have same name siblings
>>
>> Modified: 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemImpl.java 
>>
>> URL: 
>> http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemImpl.java?rev=201999&r1=201998&r2=201999&view=diff 
>>
>> ============================================================================== 
>>
>> --- 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemImpl.java 
>> (original)
>> +++ 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemImpl.java 
>> Mon Jun 27 08:08:35 2005
>> @@ -518,7 +518,7 @@
>>                          */
>>                         continue;
>>                     }
>> -                    if (!nodeState.hasPropertyEntry(pd.getName())) {
>> +                    if (!nodeState.hasPropertyName(pd.getName())) {
>>                         String msg = node.safeGetJCRPath()
>>                                 + ": mandatory property " + pd.getName()
>>                                 + " does not exist";
>>
>> Modified: 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemManager.java 
>>
>> URL: 
>> http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemManager.java?rev=201999&r1=201998&r2=201999&view=diff 
>>
>> ============================================================================== 
>>
>> --- 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemManager.java 
>> (original)
>> +++ 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemManager.java 
>> Mon Jun 27 08:08:35 2005
>> @@ -462,12 +462,12 @@
>>             throw new RepositoryException(msg);
>>         }
>>         NodeState nodeState = (NodeState) state;
>> -        Iterator iter = nodeState.getPropertyEntries().iterator();
>> +        Iterator iter = nodeState.getPropertyNames().iterator();
>>
>>         while (iter.hasNext()) {
>> -            NodeState.PropertyEntry entry = 
>> (NodeState.PropertyEntry) iter.next();
>> +            QName propName = (QName) iter.next();
>>
>> -            PropertyId id = new PropertyId(parentId.getUUID(), 
>> entry.getName());
>> +            PropertyId id = new PropertyId(parentId.getUUID(), 
>> propName);
>>             // check read access
>>             if (session.getAccessManager().isGranted(id, 
>> AccessManager.READ)) {
>>                 return true;
>> @@ -497,11 +497,11 @@
>>         }
>>         NodeState nodeState = (NodeState) state;
>>         ArrayList childIds = new ArrayList();
>> -        Iterator iter = nodeState.getPropertyEntries().iterator();
>> +        Iterator iter = nodeState.getPropertyNames().iterator();
>>
>>         while (iter.hasNext()) {
>> -            NodeState.PropertyEntry entry = 
>> (NodeState.PropertyEntry) iter.next();
>> -            PropertyId id = new PropertyId(parentId.getUUID(), 
>> entry.getName());
>> +            QName propName = (QName) iter.next();
>> +            PropertyId id = new PropertyId(parentId.getUUID(), 
>> propName);
>>             // check read access
>>             if (session.getAccessManager().isGranted(id, 
>> AccessManager.READ)) {
>>                 childIds.add(id);
>>
>> Modified: 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemValidator.java 
>>
>> URL: 
>> http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemValidator.java?rev=201999&r1=201998&r2=201999&view=diff 
>>
>> ============================================================================== 
>>
>> --- 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemValidator.java 
>> (original)
>> +++ 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemValidator.java 
>> Mon Jun 27 08:08:35 2005
>> @@ -115,7 +115,7 @@
>>         PropDef[] pda = entPrimaryAndMixins.getMandatoryPropDefs();
>>         for (int i = 0; i < pda.length; i++) {
>>             PropDef pd = pda[i];
>> -            if (!nodeState.hasPropertyEntry(pd.getName())) {
>> +            if (!nodeState.hasPropertyName(pd.getName())) {
>>                 String msg = safeGetJCRPath(nodeState.getId())
>>                         + ": mandatory property " + pd.getName()
>>                         + " does not exist";
>>
>> Modified: 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NodeImpl.java 
>>
>> URL: 
>> http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NodeImpl.java?rev=201999&r1=201998&r2=201999&view=diff 
>>
>> ============================================================================== 
>>
>> --- 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NodeImpl.java 
>> (original)
>> +++ 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NodeImpl.java 
>> Mon Jun 27 08:08:35 2005
>> @@ -165,7 +165,7 @@
>>                     }
>>                     // check if property entry exists
>>                     NodeState thisState = (NodeState) state;
>> -                    if (thisState.hasPropertyEntry(pe.getName())) {
>> +                    if (thisState.hasPropertyName(pe.getName())) {
>>                         return new PropertyId(thisState.getUUID(), 
>> pe.getName());
>>                     } else {
>>                         // there's no property with that name
>> @@ -422,7 +422,7 @@
>>         status.clear();
>>
>>         NodeState thisState = (NodeState) state;
>> -        if (thisState.hasPropertyEntry(name)) {
>> +        if (thisState.hasPropertyName(name)) {
>>             /**
>>              * the following call will throw ItemNotFoundException if 
>> the
>>              * current session doesn't have read access
>> @@ -481,7 +481,7 @@
>>         // modify the state of 'this', i.e. the parent node
>>         NodeState thisState = (NodeState) 
>> getOrCreateTransientItemState();
>>         // add new property entry
>> -        thisState.addPropertyEntry(name);
>> +        thisState.addPropertyName(name);
>>
>>         return prop;
>>     }
>> @@ -570,7 +570,7 @@
>>         NodeState thisState = (NodeState) 
>> getOrCreateTransientItemState();
>>
>>         // remove the property entry
>> -        if (!thisState.removePropertyEntry(propName)) {
>> +        if (!thisState.removePropertyName(propName)) {
>>             String msg = "failed to remove property " + propName + " 
>> of "
>>                     + safeGetJCRPath();
>>             log.debug(msg);
>> @@ -626,32 +626,32 @@
>>         // modify the state of 'this', i.e. the target node
>>         NodeState thisState = (NodeState) 
>> getOrCreateTransientItemState();
>>
>> -        // remove child nodes
>> -        // use temp array to avoid ConcurrentModificationException
>> -        ArrayList tmp = new ArrayList(thisState.getChildNodeEntries());
>> -        // remove from tail to avoid problems with same-name siblings
>> -        for (int i = tmp.size() - 1; i >= 0; i--) {
>> -            NodeState.ChildNodeEntry entry =
>> -                    (NodeState.ChildNodeEntry) tmp.get(i);
>> -            // recursively remove child node
>> -            NodeId childId = new NodeId(entry.getUUID());
>> -            NodeImpl childNode = (NodeImpl) itemMgr.getItem(childId);
>> -            childNode.onRemove();
>> -
>> -            // remove the child node entry
>> -            thisState.removeChildNodeEntry(entry.getName(), 
>> entry.getIndex());
>> +        if (thisState.hasChildNodeEntries()) {
>> +            // remove child nodes
>> +            // use temp array to avoid ConcurrentModificationException
>> +            ArrayList tmp = new 
>> ArrayList(thisState.getChildNodeEntries());
>> +            // remove from tail to avoid problems with same-name 
>> siblings
>> +            for (int i = tmp.size() - 1; i >= 0; i--) {
>> +                NodeState.ChildNodeEntry entry =
>> +                        (NodeState.ChildNodeEntry) tmp.get(i);
>> +                // recursively remove child node
>> +                NodeId childId = new NodeId(entry.getUUID());
>> +                NodeImpl childNode = (NodeImpl) 
>> itemMgr.getItem(childId);
>> +                childNode.onRemove();
>> +                // remove the child node entry
>> +                thisState.removeChildNodeEntry(entry.getName(), 
>> entry.getIndex());
>> +            }
>>         }
>>
>>         // remove properties
>>         // use temp array to avoid ConcurrentModificationException
>> -        tmp = new ArrayList(thisState.getPropertyEntries());
>> +        ArrayList tmp = new ArrayList(thisState.getPropertyNames());
>>         for (int i = 0; i < tmp.size(); i++) {
>> -            NodeState.PropertyEntry entry =
>> -                    (NodeState.PropertyEntry) tmp.get(i);
>> +            QName propName = (QName) tmp.get(i);
>>             // remove the property entry
>> -            thisState.removePropertyEntry(entry.getName());
>> +            thisState.removePropertyName(propName);
>>             // remove property
>> -            PropertyId propId = new PropertyId(thisState.getUUID(), 
>> entry.getName());
>> +            PropertyId propId = new PropertyId(thisState.getUUID(), 
>> propName);
>>             itemMgr.getItem(propId).setRemoved();
>>         }
>>
>> @@ -759,7 +759,7 @@
>>
>>         // check for name collisions
>>         NodeState thisState = (NodeState) state;
>> -        if (thisState.hasPropertyEntry(nodeName)) {
>> +        if (thisState.hasPropertyName(nodeName)) {
>>             // there's already a property with that name
>>             throw new 
>> ItemExistsException(itemMgr.safeGetJCRPath(nodePath));
>>         }
>> @@ -792,7 +792,7 @@
>>         NodeState thisState = (NodeState) state;
>>         // get or create jcr:mixinTypes property
>>         PropertyImpl prop;
>> -        if (thisState.hasPropertyEntry(JCR_MIXINTYPES)) {
>> +        if (thisState.hasPropertyName(JCR_MIXINTYPES)) {
>>             prop = (PropertyImpl) itemMgr.getItem(new 
>> PropertyId(thisState.getUUID(), JCR_MIXINTYPES));
>>         } else {
>>             // find definition for the jcr:mixinTypes property and 
>> create property
>> @@ -901,7 +901,7 @@
>>         // child node entries
>>         
>> persistentState.setChildNodeEntries(transientState.getChildNodeEntries()); 
>>
>>         // property entries
>> -        
>> persistentState.setPropertyEntries(transientState.getPropertyEntries());
>> +        
>> persistentState.setPropertyNames(transientState.getPropertyNames());
>>
>>         // make state persistent
>>         stateMgr.store(persistentState);
>> @@ -1137,18 +1137,18 @@
>>         // defined by the specified mixin type
>>
>>         // use temp array to avoid ConcurrentModificationException
>> -        ArrayList tmp = new ArrayList(thisState.getPropertyEntries());
>> +        ArrayList tmp = new ArrayList(thisState.getPropertyNames());
>>         Iterator iter = tmp.iterator();
>>         while (iter.hasNext()) {
>> -            NodeState.PropertyEntry entry = 
>> (NodeState.PropertyEntry) iter.next();
>> -            PropertyImpl prop = (PropertyImpl) itemMgr.getItem(new 
>> PropertyId(thisState.getUUID(), entry.getName()));
>> +            QName propName = (QName) iter.next();
>> +            PropertyImpl prop = (PropertyImpl) itemMgr.getItem(new 
>> PropertyId(thisState.getUUID(), propName));
>>             // check if property has been defined by mixin type (or 
>> one of its supertypes)
>>             NodeTypeImpl declaringNT = (NodeTypeImpl) 
>> prop.getDefinition().getDeclaringNodeType();
>>             if 
>> (!entRemaining.includesNodeType(declaringNT.getQName())) {
>>                 // the remaining effective node type doesn't include the
>>                 // node type that declared this property, it is thus 
>> safe
>>                 // to remove it
>> -                removeChildProperty(entry.getName());
>> +                removeChildProperty(propName);
>>             }
>>         }
>>         // use temp array to avoid ConcurrentModificationException
>> @@ -1465,7 +1465,7 @@
>>         sanityCheck();
>>
>>         NodeState thisState = (NodeState) state;
>> -        if (!thisState.hasPropertyEntry(name)) {
>> +        if (!thisState.hasPropertyName(name)) {
>>             return false;
>>         }
>>         PropertyId propId = new PropertyId(thisState.getUUID(), name);
>>
>> Modified: 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/query/lucene/NodeIndexer.java 
>>
>> URL: 
>> http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/query/lucene/NodeIndexer.java?rev=201999&r1=201998&r2=201999&view=diff 
>>
>> ============================================================================== 
>>
>> --- 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/query/lucene/NodeIndexer.java 
>> (original)
>> +++ 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/query/lucene/NodeIndexer.java 
>> Mon Jun 27 08:08:35 2005
>> @@ -151,10 +151,10 @@
>>             // unknown uri<->prefix mappings
>>         }
>>
>> -        List props = node.getPropertyEntries();
>> +        List props = node.getPropertyNames();
>>         for (Iterator it = props.iterator(); it.hasNext();) {
>> -            NodeState.PropertyEntry prop = (NodeState.PropertyEntry) 
>> it.next();
>> -            PropertyId id = new PropertyId(node.getUUID(), 
>> prop.getName());
>> +            QName propName = (QName) it.next();
>> +            PropertyId id = new PropertyId(node.getUUID(), propName);
>>             try {
>>                 PropertyState propState = (PropertyState) 
>> stateProvider.getItemState(id);
>>                 InternalValue[] values = propState.getValues();
>> @@ -257,14 +257,14 @@
>>                 // don't know how to index
>>                 return;
>>             }
>> -            if (node.hasPropertyEntry(JCR_MIMETYPE)) {
>> +            if (node.hasPropertyName(JCR_MIMETYPE)) {
>>                 PropertyState dataProp = (PropertyState) 
>> stateProvider.getItemState(new PropertyId(node.getUUID(), JCR_DATA));
>>                 PropertyState mimeTypeProp =
>>                     (PropertyState) stateProvider.getItemState(new 
>> PropertyId(node.getUUID(), JCR_MIMETYPE));
>>
>>                 // jcr:encoding is not mandatory
>>                 String encoding = null;
>> -                if (node.hasPropertyEntry(JCR_ENCODING)) {
>> +                if (node.hasPropertyName(JCR_ENCODING)) {
>>                     PropertyState encodingProp =
>>                         (PropertyState) 
>> stateProvider.getItemState(new PropertyId(node.getUUID(), 
>> JCR_ENCODING));
>>                     
>> encodingProp.getValues()[0].internalValue().toString();
>>
>> Modified: 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/NodeState.java 
>>
>> URL: 
>> http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/NodeState.java?rev=201999&r1=201998&r2=201999&view=diff 
>>
>> ============================================================================== 
>>
>> --- 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/NodeState.java 
>> (original)
>> +++ 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/NodeState.java 
>> Mon Jun 27 08:08:35 2005
>> @@ -20,7 +20,9 @@
>> import org.apache.jackrabbit.core.QName;
>> import org.apache.jackrabbit.core.nodetype.NodeDefId;
>> import org.apache.commons.collections.map.ReferenceMap;
>> +import org.apache.commons.collections.map.LinkedMap;
>> import org.apache.commons.collections.MapIterator;
>> +import org.apache.commons.collections.set.ListOrderedSet;
>>
>> import java.io.IOException;
>> import java.io.ObjectInputStream;
>> @@ -34,23 +36,34 @@
>> import java.util.List;
>> import java.util.Set;
>> import java.util.Map;
>> +import java.util.Collection;
>> +import java.util.ListIterator;
>>
>> /**
>>  * <code>NodeState</code> represents the state of a <code>Node</code>.
>>  */
>> public class NodeState extends ItemState {
>>
>> -    static final long serialVersionUID = -3210487938753054604L;
>> +    /** Serialization UID of this class. */
>> +    static final long serialVersionUID = 2387880829766640392L;
>>
>> +    /** the uuid of this node */
>>     protected String uuid;
>> +
>> +    /** the name of this node's primary type */
>>     protected QName nodeTypeName;
>> +
>> +    /** the names of this node's mixin types */
>>     protected Set mixinTypeNames = new HashSet();
>> +
>> +    /** id of this node's definition */
>>     protected NodeDefId defId;
>>
>> -    // insertion-ordered collection of ChildNodeEntry objects
>> +    /** insertion-ordered collection of ChildNodeEntry objects */
>>     protected ChildNodeEntries childNodeEntries = new 
>> ChildNodeEntries();
>> -    // insertion-ordered collection of PropertyEntry objects
>> -    protected List propertyEntries = new ArrayList();
>> +
>> +    /** insertion-ordered set of property names (QName objects) */
>> +    protected ListOrderedSet propertyNames = new ListOrderedSet();
>>
>>     /**
>>      * Listeners (weak references)
>> @@ -102,8 +115,8 @@
>>         mixinTypeNames.addAll(nodeState.getMixinTypeNames());
>>         defId = nodeState.getDefinitionId();
>>         uuid = nodeState.getUUID();
>> -        propertyEntries.clear();
>> -        propertyEntries.addAll(nodeState.getPropertyEntries());
>> +        propertyNames.clear();
>> +        propertyNames.addAll(nodeState.getPropertyNames());
>>         childNodeEntries.removeAll();
>>         childNodeEntries.addAll(nodeState.getChildNodeEntries());
>>     }
>> @@ -175,6 +188,16 @@
>>     }
>>
>>     /**
>> +     * Determines if there are any child node entries.
>> +     *
>> +     * @return <code>true</code> if there are child node entries,
>> +     *         <code>false</code> otherwise.
>> +     */
>> +    public boolean hasChildNodeEntries() {
>> +        return !childNodeEntries.isEmpty();
>> +    }
>> +
>> +    /**
>>      * Determines if there is a <code>ChildNodeEntry</code> with the
>>      * specified <code>name</code>.
>>      *
>> @@ -195,6 +218,18 @@
>>
>>     /**
>>      * Determines if there is a <code>ChildNodeEntry</code> with the
>> +     * specified <code>uuid</code>.
>> +     *
>> +     * @param uuid UUID of the child node
>> +     * @return <code>true</code> if there is a 
>> <code>ChildNodeEntry</code> with
>> +     *         the specified <code>name</code>.
>> +     */
>> +    public synchronized boolean hasChildNodeEntry(String uuid) {
>> +        return childNodeEntries.get(uuid) != null;
>> +    }
>> +
>> +    /**
>> +     * Determines if there is a <code>ChildNodeEntry</code> with the
>>      * specified <code>name</code> and <code>index</code>.
>>      *
>>      * @param name  <code>QName</code> object specifying a node name
>> @@ -220,35 +255,15 @@
>>     }
>>
>>     /**
>> -     * Determines if there is a <code>PropertyEntry</code> with the
>> -     * specified <code>QName</code>.
>> -     *
>> -     * @param propName <code>QName</code> object specifying a 
>> property name
>> -     * @return <code>true</code> if there is a 
>> <code>PropertyEntry</code> with
>> -     *         the specified <code>QName</code>.
>> -     */
>> -    public synchronized boolean hasPropertyEntry(QName propName) {
>> -        PropertyEntry entry = new PropertyEntry(propName);
>> -        return propertyEntries.contains(entry);
>> -    }
>> -
>> -    /**
>> -     * Returns the <code>PropertyEntry</code> with the specified 
>> name or
>> -     * <code>null</code> if there's no such entry.
>> +     * Determines if there is a property entry with the specified
>> +     * <code>QName</code>.
>>      *
>>      * @param propName <code>QName</code> object specifying a 
>> property name
>> -     * @return the <code>PropertyEntry</code> with the specified 
>> name or
>> -     *         <code>null</code> if there's no such entry.
>> +     * @return <code>true</code> if there is a property entry with 
>> the specified
>> +     *         <code>QName</code>.
>>      */
>> -    public synchronized PropertyEntry getPropertyEntry(QName 
>> propName) {
>> -        Iterator iter = propertyEntries.iterator();
>> -        while (iter.hasNext()) {
>> -            PropertyEntry entry = (PropertyEntry) iter.next();
>> -            if (propName.equals(entry.getName())) {
>> -                return entry;
>> -            }
>> -        }
>> -        return null;
>> +    public synchronized boolean hasPropertyName(QName propName) {
>> +        return propertyNames.contains(propName);
>>     }
>>
>>     /**
>> @@ -281,7 +296,7 @@
>>      * Returns the <code>ChildNodeEntry</code> with the specified 
>> uuid or
>>      * <code>null</code> if there's no such entry.
>>      *
>> -     * @param uuid UUID of a child node state.
>> +     * @param uuid UUID of the child node
>>      * @return the <code>ChildNodeEntry</code> with the specified 
>> uuid or
>>      *         <code>null</code> if there's no such entry.
>>      * @see #addChildNodeEntry
>> @@ -300,7 +315,7 @@
>>      * @see #removeChildNodeEntry
>>      */
>>     public synchronized List getChildNodeEntries() {
>> -        return childNodeEntries.entries();
>> +        return childNodeEntries;
>>     }
>>
>>     /**
>> @@ -352,9 +367,9 @@
>>     }
>>
>>     /**
>> -     * Removes a <code>ChildNodeEntry<code>.
>> +     * Removes a <code>ChildNodeEntry</code>.
>>      *
>> -     * @param nodeName <code>ChildNodeEntry<code> object specifying 
>> a node name
>> +     * @param nodeName <code>ChildNodeEntry</code> object specifying 
>> a node name
>>      * @param index    1-based index if there are same-name child 
>> node entries
>>      * @return <code>true</code> if the specified child node entry 
>> was found
>>      *         in the list of child node entries and could be removed.
>> @@ -386,11 +401,7 @@
>>      * Removes all <code>ChildNodeEntry</code>s.
>>      */
>>     public synchronized void removeAllChildNodeEntries() {
>> -        Iterator iter = childNodeEntries.entries().iterator();
>> -        while (iter.hasNext()) {
>> -            ChildNodeEntry entry = (ChildNodeEntry) iter.next();
>> -            removeChildNodeEntry(entry.getUUID());
>> -        }
>> +        childNodeEntries.removeAll();
>>     }
>>
>>     /**
>> @@ -404,59 +415,51 @@
>>     }
>>
>>     /**
>> -     * Returns a list of <code>PropertyEntry</code> objects denoting 
>> the
>> -     * properties of this node.
>> +     * Returns the names of this node's properties as a list of
>> +     * <code>QNames</code> objects.
>>      *
>> -     * @return list of <code>PropertyEntry</code> objects
>> -     * @see #addPropertyEntry
>> -     * @see #removePropertyEntry
>> +     * @return list of <code>QNames</code> objects
>> +     * @see #addPropertyName
>> +     * @see #removePropertyName
>>      */
>> -    public synchronized List getPropertyEntries() {
>> -        return Collections.unmodifiableList(propertyEntries);
>> +    public synchronized List getPropertyNames() {
>> +        return propertyNames.asList();
>>     }
>>
>>     /**
>> -     * Adds a <code>PropertyEntry</code>.
>> +     * Adds a property name entry.
>>      *
>>      * @param propName <code>QName</code> object specifying the 
>> property name
>>      */
>> -    public synchronized void addPropertyEntry(QName propName) {
>> -        PropertyEntry entry = new PropertyEntry(propName);
>> -        propertyEntries.add(entry);
>> +    public synchronized void addPropertyName(QName propName) {
>> +        propertyNames.add(propName);
>>     }
>>
>>     /**
>> -     * Removes a <code>PropertyEntry</code>.
>> +     * Removes a property name entry.
>>      *
>>      * @param propName <code>QName</code> object specifying the 
>> property name
>> -     * @return <code>true</code> if the specified property entry was 
>> found
>> -     *         in the list of property entries and could be removed.
>> +     * @return <code>true</code> if the specified property name was 
>> found
>> +     *         in the list of property name entries and could be 
>> removed.
>>      */
>> -    public synchronized boolean removePropertyEntry(QName propName) {
>> -        PropertyEntry entry = new PropertyEntry(propName);
>> -        int pos = propertyEntries.indexOf(entry);
>> -        if (pos == -1) {
>> -            return false;
>> -        } else {
>> -            propertyEntries.remove(pos);
>> -            return true;
>> -        }
>> +    public synchronized boolean removePropertyName(QName propName) {
>> +        return propertyNames.remove(propName);
>>     }
>>
>>     /**
>> -     * Removes all <code>PropertyEntry</code>s.
>> +     * Removes all property name entries.
>>      */
>> -    public synchronized void removeAllPropertyEntries() {
>> -        propertyEntries.clear();
>> +    public synchronized void removeAllPropertyNames() {
>> +        propertyNames.clear();
>>     }
>>
>>     /**
>> -     * Sets the list of <code>PropertyEntry</code> objects denoting the
>> +     * Sets the list of <code>QName</code> objects denoting the
>>      * properties of this node.
>>      */
>> -    public synchronized void setPropertyEntries(List propEntries) {
>> -        propertyEntries.clear();
>> -        propertyEntries.addAll(propEntries);
>> +    public synchronized void setPropertyNames(List propNames) {
>> +        propertyNames.clear();
>> +        propertyNames.addAll(propNames);
>>     }
>>
>>     /**
>> @@ -471,31 +474,33 @@
>>
>>     //---------------------------------------------------------< diff 
>> methods >
>>     /**
>> -     * Returns a list of property entries, that do not exist in the 
>> overlayed
>> -     * node state but have been added to <i>this</i> node state.
>> +     * Returns a list of <code>QName</code>s denoting those 
>> properties that
>> +     * do not exist in the overlayed node state but have been added to
>> +     * <i>this</i> node state.
>>      *
>> -     * @return list of added property entries
>> +     * @return list of <code>QName</code>s denoting the properties 
>> that have
>> +     *         been added.
>>      */
>> -    public synchronized List getAddedPropertyEntries() {
>> +    public synchronized List getAddedPropertyNames() {
>>         if (!hasOverlayedState()) {
>> -            return Collections.unmodifiableList(propertyEntries);
>> +            return propertyNames.asList();
>>         }
>>
>>         NodeState other = (NodeState) getOverlayedState();
>> -        ArrayList list = new ArrayList(propertyEntries);
>> -        list.removeAll(other.propertyEntries);
>> +        ArrayList list = new ArrayList(propertyNames);
>> +        list.removeAll(other.propertyNames);
>>         return list;
>>     }
>>
>>     /**
>> -     * Returns a list of child node entries, that do not exist in 
>> the overlayed
>> +     * Returns a list of child node entries that do not exist in the 
>> overlayed
>>      * node state but have been added to <i>this</i> node state.
>>      *
>>      * @return list of added child node entries
>>      */
>>     public synchronized List getAddedChildNodeEntries() {
>>         if (!hasOverlayedState()) {
>> -            return 
>> Collections.unmodifiableList(childNodeEntries.entries());
>> +            return childNodeEntries;
>>         }
>>
>>         NodeState other = (NodeState) getOverlayedState();
>> @@ -503,19 +508,21 @@
>>     }
>>
>>     /**
>> -     * Returns a list of property entries, that exist in the 
>> overlayed node state
>> -     * but have been removed from <i>this</i> node state.
>> +     * Returns a list of <code>QName</code>s denoting those 
>> properties that
>> +     * exist in the overlayed node state but have been removed from
>> +     * <i>this</i> node state.
>>      *
>> -     * @return list of removed property entries
>> +     * @return list of <code>QName</code>s denoting the properties 
>> that have
>> +     *         been removed.
>>      */
>> -    public synchronized List getRemovedPropertyEntries() {
>> +    public synchronized List getRemovedPropertyNames() {
>>         if (!hasOverlayedState()) {
>>             return Collections.EMPTY_LIST;
>>         }
>>
>>         NodeState other = (NodeState) getOverlayedState();
>> -        ArrayList list = new ArrayList(other.propertyEntries);
>> -        list.removeAll(propertyEntries);
>> +        ArrayList list = new ArrayList(other.propertyNames);
>> +        list.removeAll(propertyNames);
>>         return list;
>>     }
>>
>> @@ -536,11 +543,11 @@
>>
>>     /**
>>      * Returns a list of child node entries that exist both in 
>> <i>this</i> node
>> -     * state and in the overlayed node state, but have been reordered.
>> +     * state and in the overlayed node state but have been reordered.
>>      * <p/>
>>      * The list may include only the minimal set of nodes that have been
>>      * reordered. That is, even though a certain number of nodes have 
>> changed
>> -     * their context position, the list may include less that this 
>> number of
>> +     * their absolute position the list may include less that this 
>> number of
>>      * nodes.
>>      * <p/>
>>      * Example:<br/>
>> @@ -556,7 +563,7 @@
>>      *  + node3
>>      *  + node1
>>      * </pre>
>> -     * All nodes have changed their context position. The returned 
>> list however
>> +     * All nodes have changed their absolute position. The returned 
>> list however
>>      * may only return that <code>node1</code> has been reordered 
>> (from the
>>      * first position to the end).
>>      *
>> @@ -568,19 +575,19 @@
>>         }
>>
>>         List others = new ArrayList();
>> -        others.addAll(((NodeState) 
>> getOverlayedState()).childNodeEntries.entries);
>> +        others.addAll(((NodeState) 
>> getOverlayedState()).getChildNodeEntries());
>>
>>         List ours = new ArrayList();
>> -        ours.addAll(childNodeEntries.entries);
>> +        ours.addAll(childNodeEntries);
>>
>>         // do a lazy init
>>         List reordered = null;
>> -        // remove added nodes from ours entries
>> +        // remove added nodes from 'our' entries
>>         ours.removeAll(getAddedChildNodeEntries());
>> -        // remove all removed nodes from others entries
>> +        // remove all removed nodes from 'other' entries
>>         others.removeAll(getRemovedChildNodeEntries());
>> -        // both entry list now contain the set of nodes that have not
>> -        // been removed or added. but they may have changed their 
>> position
>> +        // both entry lists now contain the set of nodes that have not
>> +        // been removed or added, but they may have changed their 
>> position.
>>         for (int i = 0; i < ours.size();) {
>>             ChildNodeEntry entry = (ChildNodeEntry) ours.get(i);
>>             ChildNodeEntry other = (ChildNodeEntry) others.get(i);
>> @@ -588,13 +595,13 @@
>>                 if (reordered == null) {
>>                     reordered = new ArrayList();
>>                 }
>> -                // Note, that this check will not necessarily find the
>> +                // Note that this check will not necessarily find the
>>                 // minimal reorder operations required to convert the 
>> overlayed
>>                 // child node entries into the current.
>>
>> -                // is there a next entry
>> +                // is there a next entry?
>>                 if (i + 1 < ours.size()) {
>> -                    // if entry is the next in the other list, then 
>> probably
>> +                    // if entry is the next in the other list then 
>> probably
>>                     // the other entry at position <code>i</code> was 
>> reordered
>>                     if (entry.getUUID().equals(((ChildNodeEntry) 
>> others.get(i + 1)).getUUID())) {
>>                         // scan for the uuid of the other entry in 
>> our list
>> @@ -622,7 +629,7 @@
>>                     }
>>                 }
>>                 // if a reorder has been detected index 
>> <code>i</code> is not
>> -                // incremented, because entries will be shifted when 
>> the
>> +                // incremented because entries will be shifted when the
>>                 // reordered entry is removed.
>>             } else {
>>                 // no reorder, move to next child entry
>> @@ -671,7 +678,7 @@
>>
>>     //-------------------------------------------------< misc. helper 
>> methods >
>>     /**
>> -     * Notify the listeners that some child node was added
>> +     * Notify the listeners that a child node entry has been added
>>      */
>>     protected void notifyNodeAdded(ChildNodeEntry added) {
>>         synchronized (listeners) {
>> @@ -687,7 +694,7 @@
>>     }
>>
>>     /**
>> -     * Notify the listeners that the children nodes were replaced
>> +     * Notify the listeners that the child node entries have been 
>> replaced
>>      */
>>     protected void notifyNodesReplaced() {
>>         synchronized (listeners) {
>> @@ -702,7 +709,7 @@
>>     }
>>
>>     /**
>> -     * Notify the listeners that some child node was removed
>> +     * Notify the listeners that a child node entry has been removed
>>      */
>>     protected void notifyNodeRemoved(ChildNodeEntry removed) {
>>         synchronized (listeners) {
>> @@ -734,31 +741,37 @@
>>      * <code>ChildNodeEntries</code> represents an insertion-ordered
>>      * collection of <code>ChildNodeEntry</code>s that also maintains
>>      * the index values of same-name siblings on insertion and removal.
>> +     * <p/>
>> +     * <code>ChildNodeEntries</code> also provides an unmodifiable
>> +     * <code>List</code> view.
>>      */
>> -    private static class ChildNodeEntries implements Serializable {
>> +    private static class ChildNodeEntries implements List, 
>> Serializable {
>>
>> -        // insertion-ordered collection of entries
>> -        List entries;
>> -        // mapping from names to list of same-name sibling entries
>> -        Map names;
>> +        // insertion-ordered map of entries (key=uuid, value=entry)
>> +        LinkedMap entries;
>> +        // map used for lookup by name (key=uuid, value=1st 
>> same-name sibling entry)
>> +        Map nameMap;
>>
>>         ChildNodeEntries() {
>> -            entries = new ArrayList();
>> -            names = new HashMap();
>> +            entries = new LinkedMap();
>> +            nameMap = new HashMap();
>>         }
>>
>>         ChildNodeEntry add(QName nodeName, String uuid) {
>> -            List siblings = (List) names.get(nodeName);
>> -            if (siblings == null) {
>> -                siblings = new ArrayList();
>> -                names.put(nodeName, siblings);
>> +            ChildNodeEntry sibling = (ChildNodeEntry) 
>> nameMap.get(nodeName);
>> +            while (sibling != null && sibling.getNextSibling() != 
>> null) {
>> +                sibling = sibling.getNextSibling();
>>             }
>>
>> -            int index = siblings.size() + 1;
>> +            int index = (sibling == null) ? 1 : sibling.getIndex() + 1;
>>
>>             ChildNodeEntry entry = new ChildNodeEntry(nodeName, uuid, 
>> index);
>> -            siblings.add(entry);
>> -            entries.add(entry);
>> +            if (sibling == null) {
>> +                nameMap.put(nodeName, entry);
>> +            } else {
>> +                sibling.setNextSibling(entry);
>> +            }
>> +            entries.put(uuid, entry);
>>
>>             return entry;
>>         }
>> @@ -773,8 +786,16 @@
>>         }
>>
>>         public void removeAll() {
>> -            names.clear();
>>             entries.clear();
>> +            nameMap.clear();
>> +        }
>> +
>> +        ChildNodeEntry remove(String uuid) {
>> +            ChildNodeEntry entry = (ChildNodeEntry) entries.get(uuid);
>> +            if (entry != null) {
>> +                return remove(entry.getName(), entry.getIndex());
>> +           }
>> +            return entry;
>>         }
>>
>>         public ChildNodeEntry remove(ChildNodeEntry entry) {
>> @@ -785,74 +806,75 @@
>>             if (index < 1) {
>>                 throw new IllegalArgumentException("index is 1-based");
>>             }
>> -            List siblings = (List) names.get(nodeName);
>> -            if (siblings == null) {
>> -                return null;
>> +
>> +            ChildNodeEntry sibling = (ChildNodeEntry) 
>> nameMap.get(nodeName);
>> +            ChildNodeEntry prevSibling = null;
>> +            while (sibling != null) {
>> +                if (sibling.getIndex() == index) {
>> +                    break;
>> +                }
>> +                prevSibling = sibling;
>> +                sibling = sibling.getNextSibling();
>>             }
>> -            if (index > siblings.size()) {
>> +            if (sibling == null) {
>>                 return null;
>>             }
>> -            // remove from siblings list
>> -            ChildNodeEntry removedEntry = (ChildNodeEntry) 
>> siblings.remove(index - 1);
>> +
>>             // remove from entries list
>> -            entries.remove(removedEntry);
>> +            entries.remove(sibling.getUUID());
>>
>> -            if (siblings.size() == 0) {
>> -                // short cut
>> -                names.remove(nodeName);
>> -                return removedEntry;
>> +            // update linked list of siblings & name map entry
>> +            if (prevSibling != null) {
>> +                prevSibling.setNextSibling(sibling.getNextSibling());
>> +            } else {
>> +                // the head is removed from the linked siblings list,
>> +                // update name map
>> +                if (sibling.getNextSibling() == null) {
>> +                    nameMap.remove(nodeName);
>> +                } else {
>> +                    nameMap.put(nodeName, sibling.getNextSibling());
>> +                }
>>             }
>> -
>>             // update indices of subsequent same-name siblings
>> -            for (int i = index - 1; i < siblings.size(); i++) {
>> -                ChildNodeEntry oldEntry = (ChildNodeEntry) 
>> siblings.get(i);
>> -                ChildNodeEntry newEntry = new 
>> ChildNodeEntry(nodeName, oldEntry.getUUID(), oldEntry.getIndex() - 1);
>> -                // overwrite old entry with updated entry in 
>> siblings list
>> -                siblings.set(i, newEntry);
>> -                // overwrite old entry with updated entry in entries 
>> list
>> -                entries.set(entries.indexOf(oldEntry), newEntry);
>> +            ChildNodeEntry nextSibling = sibling.getNextSibling();
>> +            while (nextSibling != null) {
>> +                nextSibling.decIndex();
>> +                nextSibling = nextSibling.getNextSibling();
>>             }
>>
>> -            return removedEntry;
>> +            return sibling;
>>         }
>>
>>         List get(QName nodeName) {
>> -            List siblings = (List) names.get(nodeName);
>> -            if (siblings == null) {
>> +            ChildNodeEntry sibling = (ChildNodeEntry) 
>> nameMap.get(nodeName);
>> +            if (sibling == null) {
>>                 return Collections.EMPTY_LIST;
>> -            } else {
>> -                return Collections.unmodifiableList(siblings);
>>             }
>> -        }
>> -
>> -        ChildNodeEntry remove(String uuid) {
>> -            Iterator iter = entries.iterator();
>> -            while (iter.hasNext()) {
>> -                ChildNodeEntry entry = (ChildNodeEntry) iter.next();
>> -                if (entry.getUUID().equals(uuid)) {
>> -                    return remove(entry);
>> -                }
>> +            List siblings = new ArrayList();
>> +            while (sibling != null) {
>> +                siblings.add(sibling);
>> +                sibling = sibling.getNextSibling();
>>             }
>> -            return null;
>> +            return siblings;
>>         }
>>
>>         ChildNodeEntry get(String uuid) {
>> -            Iterator iter = entries.iterator();
>> -            while (iter.hasNext()) {
>> -                ChildNodeEntry entry = (ChildNodeEntry) iter.next();
>> -                if (entry.getUUID().equals(uuid)) {
>> -                    return entry;
>> -                }
>> -            }
>> -            return null;
>> +            return (ChildNodeEntry) entries.get(uuid);
>>         }
>>
>> -        Iterator iterator() {
>> -            return entries.iterator();
>> -        }
>> +        ChildNodeEntry get(QName nodeName, int index) {
>> +            if (index < 1) {
>> +                throw new IllegalArgumentException("index is 1-based");
>> +            }
>>
>> -        List entries() {
>> -            return Collections.unmodifiableList(entries);
>> +            ChildNodeEntry sibling = (ChildNodeEntry) 
>> nameMap.get(nodeName);
>> +            while (sibling != null) {
>> +                if (sibling.getIndex() == index) {
>> +                    return sibling;
>> +                }
>> +                sibling = sibling.getNextSibling();
>> +            }
>> +            return null;
>>         }
>>
>>         /**
>> @@ -860,87 +882,208 @@
>>          * <code>this</code> but not in <code>other</code>
>>          * <p/>
>>          * Note that two entries are considered identical in this 
>> context if
>> -         * they have the same name and uuid, i.e. the index is 
>> disregarded,
>> +         * they have the same name and uuid, i.e. the index is 
>> disregarded
>>          * whereas <code>ChildNodeEntry.equals(Object)</code> also 
>> compares
>>          * the index.
>>          *
>>          * @param other entries to be removed
>> -         * @return a new list of entries who do only exist in 
>> <code>this</code>
>> -         *         but not in <code>other</code>
>> +         * @return a new list of those entries that do only exist in
>> +         *         <code>this</code> but not in <code>other</code>
>>          */
>>         List removeAll(ChildNodeEntries other) {
>>             if (entries.isEmpty()) {
>>                 return Collections.EMPTY_LIST;
>>             }
>> -            if (other.entries.isEmpty()) {
>> -                return Collections.unmodifiableList(entries);
>> +            if (other.isEmpty()) {
>> +                return this;
>>             }
>>
>> -            List result = new ArrayList(entries);
>> -
>> -            Iterator otherIter = other.entries.iterator();
>> -            while (otherIter.hasNext()) {
>> -                ChildNodeEntry otherEntry = (ChildNodeEntry) 
>> otherIter.next();
>> -                Iterator ourIter = entries.iterator();
>> -                while (ourIter.hasNext()) {
>> -                    ChildNodeEntry ourEntry = (ChildNodeEntry) 
>> ourIter.next();
>> -                    if (ourEntry.getName().equals(otherEntry.getName())
>> -                            && 
>> ourEntry.getUUID().equals(otherEntry.getUUID())) {
>> -                        result.remove(ourEntry);
>> -                    }
>> +            List result = new ArrayList();
>> +            Iterator iter = iterator();
>> +            while (iter.hasNext()) {
>> +                ChildNodeEntry entry = (ChildNodeEntry) iter.next();
>> +                ChildNodeEntry otherEntry = (ChildNodeEntry) 
>> other.get(entry.uuid);
>> +                if (otherEntry == null
>> +                        || 
>> !entry.getName().equals(otherEntry.getName())) {
>> +                    result.add(entry);
>>                 }
>>             }
>> +
>>             return result;
>>         }
>> -    }
>>
>> -    /**
>> -     * base class for <code>PropertyEntry</code> and 
>> <code>ChildNodeEntry</code>
>> -     */
>> -    private abstract static class ChildEntry implements Serializable {
>> -        protected QName name;
>> +        //-------------------------------------------< unmodifiable 
>> List view >
>> +        public boolean contains(Object o) {
>> +            if (o instanceof ChildNodeEntry) {
>> +                return entries.containsKey(((ChildNodeEntry) o).uuid);
>> +            } else {
>> +                return false;
>> +            }
>> +        }
>>
>> -        protected ChildEntry(QName name) {
>> -            this.name = name;
>> +        public boolean containsAll(Collection c) {
>> +            Iterator iter = c.iterator();
>> +            while (iter.hasNext()) {
>> +                if (!contains(iter.next())) {
>> +                    return false;
>> +                }
>> +            }
>> +            return true;
>>         }
>>
>> -        public QName getName() {
>> -            return name;
>> +        public Object get(int index) {
>> +            return entries.getValue(index);
>>         }
>> -    }
>>
>> -    /**
>> -     * <code>PropertyEntry</code> specifies the name of a property 
>> entry.
>> -     */
>> -    public static class PropertyEntry extends ChildEntry {
>> +        public int indexOf(Object o) {
>> +            if (o instanceof ChildNodeEntry) {
>> +                return entries.indexOf(((ChildNodeEntry) o).uuid);
>> +            } else {
>> +                return -1;
>> +            }
>> +        }
>>
>> -        private int hash = 0;
>> +        public boolean isEmpty() {
>> +            return entries.isEmpty();
>> +        }
>>
>> -        protected PropertyEntry(QName propName) {
>> -            super(propName);
>> +        public int lastIndexOf(Object o) {
>> +            // entries are unique
>> +            return indexOf(o);
>>         }
>>
>> -        public boolean equals(Object obj) {
>> -            if (this == obj) {
>> -                return true;
>> +        public Iterator iterator() {
>> +            return new 
>> OrderedMapIterator(entries.asList().listIterator(), entries);
>> +        }
>> +
>> +        public ListIterator listIterator() {
>> +            return new 
>> OrderedMapIterator(entries.asList().listIterator(), entries);
>> +        }
>> +
>> +        public ListIterator listIterator(int index) {
>> +            return new 
>> OrderedMapIterator(entries.asList().listIterator(index), entries);
>> +        }
>> +
>> +        public int size() {
>> +            return entries.size();
>> +        }
>> +
>> +        public List subList(int fromIndex, int toIndex) {
>> +            // @todo FIXME does not fulfil the contract of 
>> List.subList(int,int)
>> +            return Collections.unmodifiableList(new 
>> ArrayList(this).subList(fromIndex, toIndex));
>> +        }
>> +
>> +        public Object[] toArray() {
>> +            ChildNodeEntry[] array = new ChildNodeEntry[size()];
>> +            return toArray(array);
>> +        }
>> +
>> +        public Object[] toArray(Object a[]) {
>> +            if 
>> (!a.getClass().getComponentType().isAssignableFrom(ChildNodeEntry.class)) 
>> {
>> +                throw new ArrayStoreException();
>>             }
>> -            if (obj instanceof PropertyEntry) {
>> -                PropertyEntry other = (PropertyEntry) obj;
>> -                return name.equals(other.name);
>> +            if (a.length < size()) {
>> +                a = new ChildNodeEntry[size()];
>>             }
>> -            return false;
>> +            MapIterator iter = entries.mapIterator();
>> +            int i = 0;
>> +            while (iter.hasNext()) {
>> +                iter.next();
>> +                a[i] = entries.getValue(i);
>> +                i++;
>> +            }
>> +            while (i < a.length) {
>> +                a[i++] = null;
>> +            }
>> +            return a;
>>         }
>>
>> -        public String toString() {
>> -            return name.toString();
>> +        public void add(int index, Object element) {
>> +            throw new UnsupportedOperationException();
>>         }
>>
>> -        public int hashCode() {
>> -            // PropertyEntry is immutable, we can store the computed 
>> hash code value
>> -            if (hash == 0) {
>> -                hash = name.hashCode();
>> +        public boolean add(Object o) {
>> +            throw new UnsupportedOperationException();
>> +        }
>> +
>> +        public boolean addAll(Collection c) {
>> +            throw new UnsupportedOperationException();
>> +        }
>> +
>> +        public boolean addAll(int index, Collection c) {
>> +            throw new UnsupportedOperationException();
>> +        }
>> +
>> +        public void clear() {
>> +            throw new UnsupportedOperationException();
>> +        }
>> +
>> +        public Object remove(int index) {
>> +            throw new UnsupportedOperationException();
>> +        }
>> +
>> +        public boolean remove(Object o) {
>> +            throw new UnsupportedOperationException();
>> +        }
>> +
>> +        public boolean removeAll(Collection c) {
>> +            throw new UnsupportedOperationException();
>> +        }
>> +
>> +        public boolean retainAll(Collection c) {
>> +            throw new UnsupportedOperationException();
>> +        }
>> +
>> +        public Object set(int index, Object element) {
>> +            throw new UnsupportedOperationException();
>> +        }
>> +
>> +        //----------------------------------------------------< 
>> inner classes >
>> +        class OrderedMapIterator implements ListIterator {
>> +
>> +            final ListIterator keyIter;
>> +            final Map entries;
>> +
>> +            OrderedMapIterator(ListIterator keyIter, Map entries) {
>> +                this.keyIter = keyIter;
>> +                this.entries = entries;
>> +            }
>> +
>> +            public boolean hasNext() {
>> +                return keyIter.hasNext();
>> +            }
>> +
>> +            public Object next() {
>> +                return entries.get(keyIter.next());
>> +            }
>> +
>> +            public boolean hasPrevious() {
>> +                return keyIter.hasPrevious();
>> +            }
>> +
>> +            public int nextIndex() {
>> +                return keyIter.nextIndex();
>> +            }
>> +
>> +            public Object previous() {
>> +                return entries.get(keyIter.previous());
>> +            }
>> +
>> +            public int previousIndex() {
>> +                return keyIter.previousIndex();
>> +            }
>> +
>> +            public void add(Object o) {
>> +                throw new UnsupportedOperationException();
>> +            }
>> +
>> +            public void remove() {
>> +                throw new UnsupportedOperationException();
>> +            }
>> +
>> +            public void set(Object o) {
>> +                throw new UnsupportedOperationException();
>>             }
>> -            return hash;
>>         }
>>     }
>>
>> @@ -948,15 +1091,18 @@
>>      * <code>ChildNodeEntry</code> specifies the name, index (in the 
>> case of
>>      * same-name siblings) and the UUID of a child node entry.
>>      */
>> -    public static class ChildNodeEntry extends ChildEntry {
>> -
>> -        private int hash = 0;
>> +    public static class ChildNodeEntry {
>>
>> +        private QName name;
>>         private int index; // 1-based index for same-name siblings
>>         private String uuid;
>> +        private ChildNodeEntry nextSibling;
>>
>> -        protected ChildNodeEntry(QName nodeName, String uuid, int 
>> index) {
>> -            super(nodeName);
>> +        private ChildNodeEntry(QName name, String uuid, int index) {
>> +            if (name == null) {
>> +                throw new IllegalArgumentException("name can not be 
>> null");
>> +            }
>> +            this.name = name;
>>
>>             if (uuid == null) {
>>                 throw new IllegalArgumentException("uuid can not be 
>> null");
>> @@ -967,16 +1113,46 @@
>>                 throw new IllegalArgumentException("index is 1-based");
>>             }
>>             this.index = index;
>> +
>> +            nextSibling = null;
>>         }
>>
>>         public String getUUID() {
>>             return uuid;
>>         }
>>
>> +        public QName getName() {
>> +            return name;
>> +        }
>> +
>>         public int getIndex() {
>>             return index;
>>         }
>>
>> +        public ChildNodeEntry getNextSibling() {
>> +            return nextSibling;
>> +        }
>> +
>> +        void setNextSibling(ChildNodeEntry nextSibling) {
>> +            if (nextSibling != null && 
>> !nextSibling.getName().equals(name)) {
>> +                throw new IllegalArgumentException("not a same-name 
>> sibling entry");
>> +            }
>> +
>> +            this.nextSibling = nextSibling;
>> +        }
>> +
>> +        int incIndex() {
>> +            return ++index;
>> +        }
>> +
>> +        int decIndex() {
>> +            if (index == 1) {
>> +                throw new IndexOutOfBoundsException();
>> +            }
>> +            return --index;
>> +        }
>> +
>> +        //---------------------------------------< java.lang.Object 
>> overrides >
>>         public boolean equals(Object obj) {
>>             if (this == obj) {
>>                 return true;
>> @@ -993,17 +1169,15 @@
>>             return name.toString() + "[" + index + "] -> " + uuid;
>>         }
>>
>> +        /**
>> +         * Returns zero to satisfy the Object equals/hashCode contract.
>> +         * This class is mutable and not meant to be used as a hash 
>> key.
>> +         *
>> +         * @return always zero
>> +         * @see Object#hashCode()
>> +         */
>>         public int hashCode() {
>> -            // ChildNodeEntry is immutable, we can store the 
>> computed hash code value
>> -            int h = hash;
>> -            if (h == 0) {
>> -                h = 17;
>> -                h = 37 * h + name.hashCode();
>> -                h = 37 * h + uuid.hashCode();
>> -                h = 37 * h + index;
>> -                hash = h;
>> -            }
>> -            return h;
>> +            return 0;
>>         }
>>     }
>> }
>>
>> Modified: 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java 
>>
>> URL: 
>> http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java?rev=201999&r1=201998&r2=201999&view=diff 
>>
>> ============================================================================== 
>>
>> --- 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java 
>> (original)
>> +++ 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java 
>> Mon Jun 27 08:08:35 2005
>> @@ -412,6 +412,7 @@
>>         if (!transientStateMgr.hasAnyItemStatesInAttic()) {
>>             return Collections.EMPTY_LIST.iterator();
>>         }
>> +
>>         // collection of descendant transient states in attic:
>>         // the path serves as key and sort criteria
>>
>> @@ -425,10 +426,8 @@
>>         TreeMap descendants = new TreeMap(new PathComparator());
>>         try {
>>             Path parentPath = zombieHierMgr.getPath(parentId);
>> -            /**
>> -             * walk through list of transient states in attic and 
>> check if
>> -             * they are descendants of the specified parent
>> -             */
>> +             // walk through list of transient states in attic and 
>> check if
>> +             // they are descendants of the specified parent
>>             Iterator iter = transientStateMgr.getEntriesInAttic();
>>             while (iter.hasNext()) {
>>                 ItemState state = (ItemState) iter.next();
>> @@ -445,7 +444,17 @@
>>         } catch (RepositoryException re) {
>>             log.warn("inconsistent hierarchy state", re);
>>         }
>> -
>> +/*
>> +        TreeMap descendants = new TreeMap();
>> +        Iterator iter = transientStateMgr.getEntriesInAttic();
>> +        while (iter.hasNext()) {
>> +            ItemState state = (ItemState) iter.next();
>> +            int depth = getAncestorCount(state, parentId.getUUID());
>> +            if (depth >= 0) {
>> +                descendants.put(new ItemStateKey(state, depth), state);
>> +            }
>> +        }
>> +*/
>>         return descendants.values().iterator();
>>     }
>>
>>
>> Modified: 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java 
>>
>> URL: 
>> http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java?rev=201999&r1=201998&r2=201999&view=diff 
>>
>> ============================================================================== 
>>
>> --- 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java 
>> (original)
>> +++ 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java 
>> Mon Jun 27 08:08:35 2005
>> @@ -148,7 +148,7 @@
>>         rootState.setDefinitionId(nodeDefId);
>>
>>         // create jcr:primaryType property
>> -        rootState.addPropertyEntry(propDef.getName());
>> +        rootState.addPropertyName(propDef.getName());
>>
>>         PropertyState prop = createInstance(propDef.getName(), 
>> rootNodeUUID);
>>         prop.setValues(new 
>> InternalValue[]{InternalValue.create(Constants.REP_ROOT)});
>>
>> Modified: 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/obj/ObjectPersistenceManager.java 
>>
>> URL: 
>> http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/obj/ObjectPersistenceManager.java?rev=201999&r1=201998&r2=201999&view=diff 
>>
>> ============================================================================== 
>>
>> --- 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/obj/ObjectPersistenceManager.java 
>> (original)
>> +++ 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/obj/ObjectPersistenceManager.java 
>> Mon Jun 27 08:08:35 2005
>> @@ -175,11 +175,11 @@
>>             out.writeUTF(iter.next().toString());   // name
>>         }
>>         // properties (names)
>> -        c = state.getPropertyEntries();
>> +        c = state.getPropertyNames();
>>         out.writeInt(c.size()); // count
>>         for (Iterator iter = c.iterator(); iter.hasNext();) {
>> -            NodeState.PropertyEntry entry = 
>> (NodeState.PropertyEntry) iter.next();
>> -            out.writeUTF(entry.getName().toString());   // name
>> +            QName propName = (QName) iter.next();
>> +            out.writeUTF(propName.toString());   // name
>>         }
>>         // child nodes (list of name/uuid pairs)
>>         c = state.getChildNodeEntries();
>> @@ -235,7 +235,7 @@
>>         // properties (names)
>>         count = in.readInt();   // count
>>         for (int i = 0; i < count; i++) {
>> -            state.addPropertyEntry(QName.valueOf(in.readUTF())); // 
>> name
>> +            state.addPropertyName(QName.valueOf(in.readUTF())); // name
>>         }
>>         // child nodes (list of name/uuid pairs)
>>         count = in.readInt();   // count
>>
>> Modified: 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/xml/XMLPersistenceManager.java 
>>
>> URL: 
>> http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/xml/XMLPersistenceManager.java?rev=201999&r1=201998&r2=201999&view=diff 
>>
>> ============================================================================== 
>>
>> --- 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/xml/XMLPersistenceManager.java 
>> (original)
>> +++ 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/xml/XMLPersistenceManager.java 
>> Mon Jun 27 08:08:35 2005
>> @@ -226,7 +226,7 @@
>>             while (walker.iterateElements(PROPERTY_ELEMENT)) {
>>                 String propName = walker.getAttribute(NAME_ATTRIBUTE);
>>                 // @todo deserialize type and values
>> -                state.addPropertyEntry(QName.valueOf(propName));
>> +                state.addPropertyName(QName.valueOf(propName));
>>             }
>>             walker.leaveElement();
>>         }
>> @@ -508,11 +508,11 @@
>>
>>                 // properties
>>                 writer.write("\t<" + PROPERTIES_ELEMENT + ">\n");
>> -                iter = state.getPropertyEntries().iterator();
>> +                iter = state.getPropertyNames().iterator();
>>                 while (iter.hasNext()) {
>> -                    NodeState.PropertyEntry entry = 
>> (NodeState.PropertyEntry) iter.next();
>> +                    QName propName = (QName) iter.next();
>>                     writer.write("\t\t<" + PROPERTY_ELEMENT + " "
>> -                            + NAME_ATTRIBUTE + "=\"" + 
>> Text.encodeIllegalXMLCharacters(entry.getName().toString()) + "\">\n");
>> +                            + NAME_ATTRIBUTE + "=\"" + 
>> Text.encodeIllegalXMLCharacters(propName.toString()) + "\">\n");
>>                     // @todo serialize type, definition id and values
>>                     writer.write("\t\t</" + PROPERTY_ELEMENT + ">\n");
>>                 }
>>
>> Modified: 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/NodeStateEx.java 
>>
>> URL: 
>> http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/NodeStateEx.java?rev=201999&r1=201998&r2=201999&view=diff 
>>
>> ============================================================================== 
>>
>> --- 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/NodeStateEx.java 
>> (original)
>> +++ 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/NodeStateEx.java 
>> Mon Jun 27 08:08:35 2005
>> @@ -131,11 +131,11 @@
>>      * @return
>>      */
>>     public PropertyState[] getProperties() throws ItemStateException {
>> -        List list = nodeState.getPropertyEntries();
>> +        List list = nodeState.getPropertyNames();
>>         PropertyState[] props = new PropertyState[list.size()];
>>         for (int i = 0; i < list.size(); i++) {
>> -            NodeState.PropertyEntry entry = 
>> (NodeState.PropertyEntry) list.get(i);
>> -            PropertyId propId = new PropertyId(nodeState.getUUID(), 
>> entry.getName());
>> +            QName propName = (QName) list.get(i);
>> +            PropertyId propId = new PropertyId(nodeState.getUUID(), 
>> propName);
>>             props[i] = (PropertyState) stateMgr.getItemState(propId);
>>         }
>>         return props;
>> @@ -262,7 +262,7 @@
>>             propState.setDefinitionId(pd.getId());
>>
>>             // need to store nodestate
>> -            nodeState.addPropertyEntry(name);
>> +            nodeState.addPropertyName(name);
>>             if (nodeState.getStatus() == ItemState.STATUS_EXISTING) {
>>                 nodeState.setStatus(ItemState.STATUS_EXISTING_MODIFIED);
>>             }
>> @@ -341,7 +341,7 @@
>>     }
>>
>>     /**
>> -     * removes the property with the given name and 1-based index
>> +     * removes the property with the given name
>>      *
>>      * @param name
>>      * @return
>> @@ -349,14 +349,13 @@
>>      */
>>     public boolean removeProperty(QName name) throws 
>> RepositoryException {
>>         try {
>> -            NodeState.PropertyEntry entry = 
>> nodeState.getPropertyEntry(name);
>> -            if (entry == null) {
>> +            if (!nodeState.hasPropertyName(name)) {
>>                 return false;
>>             } else {
>>                 PropertyId propId = new 
>> PropertyId(nodeState.getUUID(), name);
>>                 ItemState state = stateMgr.getItemState(propId);
>>                 stateMgr.destroy(state);
>> -                nodeState.removePropertyEntry(name);
>> +                nodeState.removePropertyName(name);
>>                 nodeState.setStatus(ItemState.STATUS_EXISTING_MODIFIED);
>>                 return true;
>>             }
>> @@ -484,10 +483,10 @@
>>
>>         if (state.getStatus() != ItemState.STATUS_EXISTING) {
>>             // first store all transient properties
>> -            List props = state.getPropertyEntries();
>> +            List props = state.getPropertyNames();
>>             for (int i = 0; i < props.size(); i++) {
>> -                NodeState.PropertyEntry entry = 
>> (NodeState.PropertyEntry) props.get(i);
>> -                PropertyState pstate = (PropertyState) 
>> stateMgr.getItemState(new PropertyId(state.getUUID(), entry.getName()));
>> +                QName propName = (QName) props.get(i);
>> +                PropertyState pstate = (PropertyState) 
>> stateMgr.getItemState(new PropertyId(state.getUUID(), propName));
>>                 if (pstate.getStatus() != ItemState.STATUS_EXISTING) {
>>                     stateMgr.store(pstate);
>>                 }
>> @@ -528,10 +527,10 @@
>>     private void reload(NodeState state) throws ItemStateException {
>>         if (state.getStatus() != ItemState.STATUS_EXISTING) {
>>             // first discard all all transient properties
>> -            List props = state.getPropertyEntries();
>> +            List props = state.getPropertyNames();
>>             for (int i = 0; i < props.size(); i++) {
>> -                NodeState.PropertyEntry entry = 
>> (NodeState.PropertyEntry) props.get(i);
>> -                PropertyState pstate = (PropertyState) 
>> stateMgr.getItemState(new PropertyId(state.getUUID(), entry.getName()));
>> +                QName propName = (QName) props.get(i);
>> +                PropertyState pstate = (PropertyState) 
>> stateMgr.getItemState(new PropertyId(state.getUUID(), propName));
>>                 if (pstate.getStatus() != ItemState.STATUS_EXISTING) {
>>                     pstate.discard();
>>                 }
>>
>> Modified: 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionManagerImpl.java 
>>
>> URL: 
>> http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionManagerImpl.java?rev=201999&r1=201998&r2=201999&view=diff 
>>
>> ============================================================================== 
>>
>> --- 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionManagerImpl.java 
>> (original)
>> +++ 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionManagerImpl.java 
>> Mon Jun 27 08:08:35 2005
>> @@ -140,7 +140,7 @@
>>                 pt.setMultiValued(false);
>>                 pt.setType(PropertyType.NAME);
>>                 pt.setValues(new 
>> InternalValue[]{InternalValue.create(REP_VERSIONSTORAGE)});
>> -                root.addPropertyEntry(pt.getName());
>> +                root.addPropertyName(pt.getName());
>>                 ChangeLog cl = new ChangeLog();
>>                 cl.added(root);
>>                 cl.added(pt);
>> @@ -708,10 +708,10 @@
>>         if (state != null) {
>>             if (recursive && state instanceof NodeState) {
>>                 NodeState nState = (NodeState) state;
>> -                Iterator iter = nState.getPropertyEntries().iterator();
>> +                Iterator iter = nState.getPropertyNames().iterator();
>>                 while (iter.hasNext()) {
>> -                    NodeState.PropertyEntry pe = 
>> (NodeState.PropertyEntry) iter.next();
>> -                    invalidateItem(new PropertyId(nState.getUUID(), 
>> pe.getName()), false);
>> +                    QName propName = (QName) iter.next();
>> +                    invalidateItem(new PropertyId(nState.getUUID(), 
>> propName), false);
>>                 }
>>                 iter = nState.getChildNodeEntries().iterator();
>>                 while (iter.hasNext()) {
>>
>> Modified: 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/AbstractVISProvider.java 
>>
>> URL: 
>> http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/AbstractVISProvider.java?rev=201999&r1=201998&r2=201999&view=diff 
>>
>> ============================================================================== 
>>
>> --- 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/AbstractVISProvider.java 
>> (original)
>> +++ 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/AbstractVISProvider.java 
>> Mon Jun 27 08:08:35 2005
>> @@ -211,7 +211,7 @@
>>
>>             // handle some default prop states
>>             if (parent instanceof VirtualNodeState) {
>> -                return parent.hasPropertyEntry(id.getName());
>> +                return parent.hasPropertyName(id.getName());
>>             }
>>         } catch (ItemStateException e) {
>>             // ignore
>>
>> Modified: 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/VirtualNodeState.java 
>>
>> URL: 
>> http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/VirtualNodeState.java?rev=201999&r1=201998&r2=201999&view=diff 
>>
>> ============================================================================== 
>>
>> --- 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/VirtualNodeState.java 
>> (original)
>> +++ 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/VirtualNodeState.java 
>> Mon Jun 27 08:08:35 2005
>> @@ -177,7 +177,7 @@
>>         if (prop == null) {
>>             prop = stateMgr.createPropertyState(this, name, type, 
>> multiValued);
>>             properties.put(name, prop);
>> -            addPropertyEntry(name);
>> +            addPropertyName(name);
>>         }
>>         return prop;
>>     }
>> @@ -198,49 +198,6 @@
>>             }
>>             setMixinTypeNames(set);
>>             setPropertyValues(JCR_MIXINTYPES, PropertyType.NAME, 
>> values);
>> -        }
>> -    }
>> -
>> -    /**
>> -     * Creates a new VirtualChildNodeEntry
>> -     *
>> -     * @param nodeName
>> -     * @param uuid
>> -     * @param index
>> -     * @return
>> -     */
>> -    protected VirtualChildNodeEntry createChildNodeEntry(QName 
>> nodeName, String uuid, int index) {
>> -        return new VirtualChildNodeEntry(nodeName, uuid, index);
>> -    }
>> -
>> -    /**
>> -     * Creates a new VirtualPropertyEntry
>> -     *
>> -     * @param name
>> -     * @return
>> -     */
>> -    protected VirtualPropertyEntry createPropertyEntry(QName name) {
>> -        return new VirtualPropertyEntry(name);
>> -    }
>> -
>> -    /**
>> -     * Overload NodeState.ChildNodeEntry in order to create own ones.
>> -     */
>> -    public class VirtualChildNodeEntry extends 
>> NodeState.ChildNodeEntry {
>> -
>> -        protected VirtualChildNodeEntry(QName nodeName, String uuid, 
>> int index) {
>> -            super(nodeName, uuid, index);
>> -        }
>> -
>> -    }
>> -
>> -    /**
>> -     * Overload NodeState.PropertyEntry in order to create own ones.
>> -     */
>> -    public class VirtualPropertyEntry extends NodeState.PropertyEntry {
>> -
>> -        protected VirtualPropertyEntry(QName propName) {
>> -            super(propName);
>>         }
>>     }
>>
>>
>> Modified: 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/WorkspaceImporter.java 
>>
>> URL: 
>> http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/WorkspaceImporter.java?rev=201999&r1=201998&r2=201999&view=diff 
>>
>> ============================================================================== 
>>
>> --- 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/WorkspaceImporter.java 
>> (original)
>> +++ 
>> incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/WorkspaceImporter.java 
>> Mon Jun 27 08:08:35 2005
>> @@ -274,7 +274,7 @@
>>             VersionHistory hist = 
>> session.getVersionManager().createVersionHistory(session, node);
>>
>>             // jcr:versionHistory
>> -            if (!node.hasPropertyEntry(JCR_VERSIONHISTORY)) {
>> +            if (!node.hasPropertyName(JCR_VERSIONHISTORY)) {
>>                 def = 
>> itemOps.findApplicablePropertyDefinition(JCR_VERSIONHISTORY,
>>                         PropertyType.REFERENCE, false, node);
>>                 prop = itemOps.createPropertyState(node, 
>> JCR_VERSIONHISTORY,
>> @@ -283,7 +283,7 @@
>>             }
>>
>>             // jcr:baseVersion
>> -            if (!node.hasPropertyEntry(JCR_BASEVERSION)) {
>> +            if (!node.hasPropertyName(JCR_BASEVERSION)) {
>>                 def = 
>> itemOps.findApplicablePropertyDefinition(JCR_BASEVERSION,
>>                         PropertyType.REFERENCE, false, node);
>>                 prop = itemOps.createPropertyState(node, 
>> JCR_BASEVERSION,
>> @@ -292,7 +292,7 @@
>>             }
>>
>>             // jcr:predecessors
>> -            if (!node.hasPropertyEntry(JCR_PREDECESSORS)) {
>> +            if (!node.hasPropertyName(JCR_PREDECESSORS)) {
>>                 def = 
>> itemOps.findApplicablePropertyDefinition(JCR_PREDECESSORS,
>>                         PropertyType.REFERENCE, true, node);
>>                 prop = itemOps.createPropertyState(node, 
>> JCR_PREDECESSORS,
>> @@ -301,7 +301,7 @@
>>             }
>>
>>             // jcr:isCheckedOut
>> -            if (!node.hasPropertyEntry(JCR_ISCHECKEDOUT)) {
>> +            if (!node.hasPropertyName(JCR_ISCHECKEDOUT)) {
>>                 def = 
>> itemOps.findApplicablePropertyDefinition(JCR_ISCHECKEDOUT,
>>                         PropertyType.BOOLEAN, false, node);
>>                 prop = itemOps.createPropertyState(node, 
>> JCR_ISCHECKEDOUT,
>> @@ -408,7 +408,7 @@
>>                         return;
>>                     }
>>
>> -                    if (parent.hasPropertyEntry(nodeName)) {
>> +                    if (parent.hasPropertyName(nodeName)) {
>>                         /**
>>                          * a property with the same name already 
>> exists; if this property
>>                          * has been imported as well (e.g. through 
>> document view import
>> @@ -424,14 +424,14 @@
>>                             // rename conflicting property
>>                             // @todo use better reversible escaping 
>> scheme to create unique name
>>                             QName newName = new 
>> QName(nodeName.getNamespaceURI(), nodeName.getLocalName() + "_");
>> -                            if (parent.hasPropertyEntry(newName)) {
>> +                            if (parent.hasPropertyName(newName)) {
>>                                 newName = new 
>> QName(newName.getNamespaceURI(), newName.getLocalName() + "_");
>>                             }
>>                             PropertyState newProp =
>>                                     
>> itemOps.createPropertyState(parent, newName,
>>                                             conflicting.getType(), 
>> conflicting.getValues().length);
>>                             newProp.setValues(conflicting.getValues());
>> -                            parent.removePropertyEntry(nodeName);
>> +                            parent.removePropertyName(nodeName);
>>                             itemOps.store(parent);
>>                             itemOps.destroy(conflicting);
>>                         }
>> @@ -494,7 +494,7 @@
>>                 PropertyState prop = null;
>>                 PropDef def = null;
>>
>> -                if (node.hasPropertyEntry(propName)) {
>> +                if (node.hasPropertyName(propName)) {
>>                     // a property with that name already exists...
>>                     PropertyId idExisting = new 
>> PropertyId(node.getUUID(), propName);
>>                     PropertyState existing =
>>
>>
>>
>>  
>>
>
>