Index: src/test/java/org/apache/jackrabbit/core/PersistenceManagerTest.java
===================================================================
--- src/test/java/org/apache/jackrabbit/core/PersistenceManagerTest.java	(revision 1146668)
+++ src/test/java/org/apache/jackrabbit/core/PersistenceManagerTest.java	(working copy)
@@ -17,16 +17,18 @@
 package org.apache.jackrabbit.core;
 
 import java.io.File;
+import java.lang.reflect.Method;
 import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
 
 import javax.jcr.PropertyType;
 
-import junit.framework.TestCase;
-
 import org.apache.commons.io.FileUtils;
 import org.apache.jackrabbit.core.fs.mem.MemoryFileSystem;
 import org.apache.jackrabbit.core.id.NodeId;
 import org.apache.jackrabbit.core.id.PropertyId;
+import org.apache.jackrabbit.core.persistence.CachingPersistenceManager;
 import org.apache.jackrabbit.core.persistence.PMContext;
 import org.apache.jackrabbit.core.persistence.PersistenceManager;
 import org.apache.jackrabbit.core.persistence.mem.InMemPersistenceManager;
@@ -44,6 +46,8 @@
 import org.apache.jackrabbit.spi.commons.name.NameConstants;
 import org.apache.jackrabbit.spi.commons.name.NameFactoryImpl;
 
+import junit.framework.TestCase;
+
 public class PersistenceManagerTest extends TestCase {
 
     private static final NodeId NODE_ID = new NodeId();
@@ -126,6 +130,7 @@
             assertCreateNewProperty(manager);
             assertMissingItemStates(manager);
             assertCreateUpdateDelete(manager);
+            assertCreateUpdateDeleteMixins(manager);
         } finally {
             manager.close();
         }
@@ -251,6 +256,74 @@
         assertFalse(manager.existsReferencesTo(CHILD_ID));
     }
 
+    private void assertCreateUpdateDeleteMixins(PersistenceManager manager)
+            throws Exception {
+        NodeState node = new NodeState(
+                NODE_ID, TEST, RepositoryImpl.ROOT_NODE_ID,
+                ItemState.STATUS_NEW, true);
+        node.addChildNodeEntry(TEST, CHILD_ID);
+        node.addPropertyName(NameConstants.JCR_PRIMARYTYPE);
+        node.addPropertyName(NameConstants.JCR_MIXINTYPES);
+
+        PropertyId mixinPropertyId = new PropertyId(NODE_ID, NameConstants.JCR_MIXINTYPES);
+        PropertyState property =
+            new PropertyState(mixinPropertyId, ItemState.STATUS_NEW, true);
+        property.setType(PropertyType.NAME);
+        property.setMultiValued(true);
+        property.setValues(
+                new InternalValue[] { InternalValue.create(TEST) });
+        Set<Name> mixins = new HashSet<Name>();
+        mixins.add(TEST);
+        node.setMixinTypeNames(mixins);
+
+        ChangeLog create = new ChangeLog();
+        create.added(node);
+        create.added(property);
+        manager.store(create);
+        create.persisted();
+
+        assertTrue(manager.exists(NODE_ID));
+        assertTrue(manager.exists(mixinPropertyId));
+
+        assertEquals(node, manager.load(NODE_ID));
+
+        Method touchMethod = PropertyState.class.getDeclaredMethod("touch");
+        touchMethod.setAccessible(true);
+        touchMethod.invoke(property);
+
+        ChangeLog modified = new ChangeLog();
+        modified.modified(node);
+        modified.modified(property);
+        manager.store(modified);
+        modified.persisted();
+
+        // purge cache
+        if (manager instanceof CachingPersistenceManager) {
+            CachingPersistenceManager cpm = (CachingPersistenceManager) manager;
+            ChangeLog modify = new ChangeLog();
+            modify.modified(property);
+            modify.modified(node);
+            cpm.onExternalUpdate(modify);
+        }
+
+        PropertyState updated = manager.load(mixinPropertyId);
+        assertFalse(updated == property);
+        assertEquals(updated, property);
+        assertEquals(updated.isModCountDefined(), property.isModCountDefined());
+        if (updated.isModCountDefined()) {
+            assertEquals(updated.getModCount(), property.getModCount());
+        }
+
+        ChangeLog delete = new ChangeLog();
+        delete.deleted(node);
+        delete.deleted(property);
+        manager.store(delete);
+        delete.persisted();
+
+        assertFalse(manager.exists(NODE_ID));
+        assertFalse(manager.exists(mixinPropertyId));
+    }
+
     private void assertEquals(NodeState expected, NodeState actual) {
         assertEquals(expected.getId(), actual.getId());
         assertEquals(expected.getNodeId(), actual.getNodeId());
Index: src/test/java/org/apache/jackrabbit/core/state/NodeStateMergerTest.java
===================================================================
--- src/test/java/org/apache/jackrabbit/core/state/NodeStateMergerTest.java	(revision 1146668)
+++ src/test/java/org/apache/jackrabbit/core/state/NodeStateMergerTest.java	(working copy)
@@ -475,12 +475,7 @@
         testNodeB.addMixin("test:mixinProp_1");
         sessionB.save();
 
-        try {
-            superuser.save();
-            fail();
-        } catch (InvalidItemStateException e) {
-            // expected
-        }
+        superuser.save();
     }
 
     public void testMixinModifiedInSessionAB2() throws Exception {
Index: src/main/java/org/apache/jackrabbit/core/persistence/AbstractPersistenceManager.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/persistence/AbstractPersistenceManager.java	(revision 1146668)
+++ src/main/java/org/apache/jackrabbit/core/persistence/AbstractPersistenceManager.java	(working copy)
@@ -67,6 +67,7 @@
             }
         }
         for (ItemState state : changeLog.addedStates()) {
+            state.setModCount((short) 0);
             if (state.isNode()) {
                 store((NodeState) state);
             } else {
Index: src/main/java/org/apache/jackrabbit/core/persistence/bundle/AbstractBundlePersistenceManager.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/persistence/bundle/AbstractBundlePersistenceManager.java	(revision 1146668)
+++ src/main/java/org/apache/jackrabbit/core/persistence/bundle/AbstractBundlePersistenceManager.java	(working copy)
@@ -580,6 +580,7 @@
                 }
             } else {
                 PropertyId id = (PropertyId) state.getId();
+                // FIXME: skip mixintypes, uuid?
                 NodeId nodeId = id.getParentId();
                 if (!deleted.contains(nodeId)) {
                     NodePropBundle bundle = modified.get(nodeId);
Index: src/main/java/org/apache/jackrabbit/core/persistence/util/NodePropBundle.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/persistence/util/NodePropBundle.java	(revision 1146668)
+++ src/main/java/org/apache/jackrabbit/core/persistence/util/NodePropBundle.java	(working copy)
@@ -320,6 +320,8 @@
             properties.put(state.getName(), new PropertyEntry(state));
         if (old != null) {
             old.destroy(blobStore);
+        } else {
+            state.setModCount((short) 0);
         }
     }
 
Index: src/main/java/org/apache/jackrabbit/core/PropertyImpl.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/PropertyImpl.java	(revision 1146668)
+++ src/main/java/org/apache/jackrabbit/core/PropertyImpl.java	(working copy)
@@ -172,7 +172,7 @@
 
     protected void restoreTransient(PropertyState transientState)
             throws RepositoryException {
-        PropertyState thisState = null;
+        PropertyState thisState;
 
         if (!isTransient()) {
             thisState = (PropertyState) getOrCreateTransientItemState();
@@ -201,7 +201,9 @@
         thisState.setType(transientState.getType());
         thisState.setMultiValued(transientState.isMultiValued());
         thisState.setValues(transientState.getValues());
-        thisState.setModCount(transientState.getModCount());
+        if (transientState.isModCountDefined()) {
+            thisState.setModCount(transientState.getModCount());
+        }
     }
 
     protected void onRedefine(QPropertyDefinition def) throws RepositoryException {
Index: src/main/java/org/apache/jackrabbit/core/state/PropertyState.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/state/PropertyState.java	(revision 1146668)
+++ src/main/java/org/apache/jackrabbit/core/state/PropertyState.java	(working copy)
@@ -16,14 +16,14 @@
  */
 package org.apache.jackrabbit.core.state;
 
+import javax.jcr.PropertyType;
+
+import org.apache.jackrabbit.core.id.ItemId;
+import org.apache.jackrabbit.core.id.NodeId;
 import org.apache.jackrabbit.core.id.PropertyId;
-import org.apache.jackrabbit.core.id.NodeId;
-import org.apache.jackrabbit.core.id.ItemId;
 import org.apache.jackrabbit.core.value.InternalValue;
 import org.apache.jackrabbit.spi.Name;
 
-import javax.jcr.PropertyType;
-
 /**
  * <code>PropertyState</code> represents the state of a <code>Property</code>.
  */
@@ -50,6 +50,12 @@
     private boolean multiValued;
 
     /**
+     * When modcount is not persisted, it is not used for detecting stale-ness.
+     * This is for properties like the {@link org.apache.jackrabbit.spi.commons.name.NameConstants#JCR_MIXINTYPES}
+     */
+    boolean modCountDefined;
+
+    /**
      * Constructs a new property state that is initially connected to an
      * overlayed state.
      *
@@ -76,6 +82,7 @@
         type = PropertyType.UNDEFINED;
         values = InternalValue.EMPTY_ARRAY;
         multiValued = false;
+        modCountDefined = false;
     }
 
     //-------------------------------------------------------< public methods >
@@ -89,7 +96,8 @@
             type = propState.type;
             values = propState.values;
             multiValued = propState.multiValued;
-            if (syncModCount) {
+            if (syncModCount && propState.modCountDefined) {
+                modCountDefined = true;
                 setModCount(state.getModCount());
             }
         }
@@ -193,6 +201,24 @@
         return values;
     }
 
+    @Override
+    public boolean isStale() {
+        return modCountDefined && super.isStale();
+    }
+
+    @Override
+    public void setModCount(final short modCount) {
+        super.setModCount(modCount);
+        this.modCountDefined = true;
+    }
+
+    @Override
+    void touch() {
+        if (modCountDefined) {
+            super.touch();
+        }
+    }
+
     /**
      * Returns an estimate of the memory size of this property state. The
      * return value actually highly overestimates the amount of required
@@ -206,4 +232,7 @@
         return 350 + values.length * 100;
     }
 
+    public boolean isModCountDefined() {
+        return modCountDefined;
+    }
 }
