Index: src/main/java/org/apache/jackrabbit/oak/plugins/index/diffindex/UUIDDiffIndexProviderWrapper.java
===================================================================
--- src/main/java/org/apache/jackrabbit/oak/plugins/index/diffindex/UUIDDiffIndexProviderWrapper.java	(revision 0)
+++ src/main/java/org/apache/jackrabbit/oak/plugins/index/diffindex/UUIDDiffIndexProviderWrapper.java	(revision 0)
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.plugins.index.diffindex;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.jackrabbit.oak.spi.query.QueryIndex;
+import org.apache.jackrabbit.oak.spi.query.QueryIndexProvider;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+
+import com.google.common.collect.ImmutableList;
+
+public class UUIDDiffIndexProviderWrapper implements QueryIndexProvider {
+
+    private final NodeState before;
+    private final NodeState after;
+
+    private final QueryIndexProvider baseProvider;
+
+    public UUIDDiffIndexProviderWrapper(QueryIndexProvider baseProvider,
+            NodeState before, NodeState after) {
+        this.baseProvider = baseProvider;
+        this.before = before;
+        this.after = after;
+    }
+
+    @Override
+    public List<? extends QueryIndex> getQueryIndexes(NodeState nodeState) {
+        List<QueryIndex> indexes = new ArrayList<QueryIndex>(
+                Collections.singletonList(new UUIDDiffIndex(before, after)));
+        indexes.addAll(this.baseProvider.getQueryIndexes(nodeState));
+        return ImmutableList.of();
+    }
+
+}
Index: src/main/java/org/apache/jackrabbit/oak/plugins/index/diffindex/DiffIndex.java
===================================================================
--- src/main/java/org/apache/jackrabbit/oak/plugins/index/diffindex/DiffIndex.java	(revision 0)
+++ src/main/java/org/apache/jackrabbit/oak/plugins/index/diffindex/DiffIndex.java	(revision 0)
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.plugins.index.diffindex;
+
+import org.apache.jackrabbit.oak.spi.query.Cursor;
+import org.apache.jackrabbit.oak.spi.query.Cursors;
+import org.apache.jackrabbit.oak.spi.query.Filter;
+import org.apache.jackrabbit.oak.spi.query.QueryIndex;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+
+/**
+ * QueryIndex that relies n a diff-ing mechanism to get query results
+ * 
+ */
+public abstract class DiffIndex implements QueryIndex {
+
+    private final DiffCollector collector;
+
+    public DiffIndex(DiffCollector collector) {
+        this.collector = collector;
+    }
+
+    @Override
+    public double getCost(Filter filter, NodeState rootState) {
+        return collector.getCost(filter);
+    }
+
+    @Override
+    public Cursor query(Filter filter, NodeState rootState) {
+        return Cursors.newPathCursor(collector.getResults(filter));
+    }
+
+    @Override
+    public String getPlan(Filter filter, NodeState rootState) {
+        // //TODO ?
+        return null;
+    }
+}
Index: src/main/java/org/apache/jackrabbit/oak/plugins/index/diffindex/UUIDDiffCollector.java
===================================================================
--- src/main/java/org/apache/jackrabbit/oak/plugins/index/diffindex/UUIDDiffCollector.java	(revision 0)
+++ src/main/java/org/apache/jackrabbit/oak/plugins/index/diffindex/UUIDDiffCollector.java	(revision 0)
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.plugins.index.diffindex;
+
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.spi.query.Filter;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+
+/**
+ * DiffCollector that looks for UUID properties
+ * 
+ */
+public class UUIDDiffCollector extends BaseDiffCollector {
+
+    private String uuid = null;
+
+    public UUIDDiffCollector(NodeState before, NodeState after) {
+        super(before, after);
+    }
+
+    @Override
+    public void collect(final Filter filter) {
+        uuid = null;
+        Filter.PropertyRestriction restriction = filter
+                .getPropertyRestriction("jcr:uuid");
+        if (restriction == null || restriction.isLike
+                || !restriction.firstIncluding || !restriction.lastIncluding
+                || !restriction.first.equals(restriction.last)) {
+            init = true;
+            return;
+        }
+        uuid = restriction.first.toString();
+        super.collect(filter);
+    }
+
+    @Override
+    protected boolean match(NodeState state, Filter filter) {
+        if (uuid == null) {
+            return false;
+        }
+        PropertyState propertyState = state.getProperty("jcr:uuid");
+        return propertyState != null
+                && uuid.equals(propertyState.getValue(Type.STRING));
+    }
+
+    @Override
+    protected boolean isUnique() {
+        return true;
+    }
+
+}
Index: src/main/java/org/apache/jackrabbit/oak/plugins/index/diffindex/BaseDiffCollector.java
===================================================================
--- src/main/java/org/apache/jackrabbit/oak/plugins/index/diffindex/BaseDiffCollector.java	(revision 0)
+++ src/main/java/org/apache/jackrabbit/oak/plugins/index/diffindex/BaseDiffCollector.java	(revision 0)
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.plugins.index.diffindex;
+
+import static org.apache.jackrabbit.oak.commons.PathUtils.concat;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.jackrabbit.oak.spi.query.Filter;
+import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
+import org.apache.jackrabbit.oak.spi.state.EmptyNodeStateDiff;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.spi.state.NodeStateUtils;
+
+public abstract class BaseDiffCollector implements DiffCollector {
+
+    private final NodeState before;
+    private final NodeState after;
+
+    private final Set<String> results;
+    protected boolean init = false;
+
+    /**
+     * @param before
+     *            initial state
+     * @param after
+     *            after state
+     * @param filter
+     *            filter that verifies of a NodeState qualifies or not
+     */
+    public BaseDiffCollector(NodeState before, NodeState after) {
+        this.before = before;
+        this.after = after;
+        results = new HashSet<String>();
+    }
+
+    public Set<String> getResults(Filter filter) {
+        if (!init) {
+            collect(filter);
+        }
+        return results;
+    }
+
+    public double getCost(Filter filter) {
+        if (!init) {
+            collect(filter);
+        }
+        if (results.isEmpty()) {
+            return Double.POSITIVE_INFINITY;
+        }
+
+        // TODO probably the number of read nodes during the diff
+        return 0;
+    }
+
+    public void collect(final Filter filter) {
+        after.compareAgainstBaseState(before, new EmptyNodeStateDiff() {
+
+            @Override
+            public void childNodeAdded(String name, NodeState after) {
+                if (NodeStateUtils.isHidden(name) || init) {
+                    return;
+                }
+                testNodeState(after, name);
+            }
+
+            @Override
+            public void childNodeChanged(String name, NodeState before,
+                    NodeState after) {
+                if (init) {
+                    return;
+                }
+                for (ChildNodeEntry entry : after.getChildNodeEntries()) {
+                    if (init) {
+                        break;
+                    }
+                    if (!before.hasChildNode(entry.getName())) {
+                        testNodeState(entry.getNodeState(),
+                                concat(name, entry.getName()));
+                    }
+                }
+            }
+
+            private void testNodeState(NodeState nodeState, String currentPath) {
+                if (init) {
+                    return;
+                }
+                boolean match = match(nodeState, filter);
+                if (match) {
+                    results.add(currentPath);
+                    if (isUnique()) {
+                        init = true;
+                        return;
+                    }
+                }
+                for (ChildNodeEntry entry : nodeState.getChildNodeEntries()) {
+                    if (!NodeStateUtils.isHidden(entry.getName())) {
+                        testNodeState(entry.getNodeState(),
+                                concat(currentPath, entry.getName()));
+                    }
+                }
+            }
+        });
+    }
+
+    protected abstract boolean match(NodeState state, Filter filter);
+
+    protected boolean isUnique() {
+        return false;
+    }
+
+}
Index: src/main/java/org/apache/jackrabbit/oak/plugins/index/diffindex/DiffCollector.java
===================================================================
--- src/main/java/org/apache/jackrabbit/oak/plugins/index/diffindex/DiffCollector.java	(revision 0)
+++ src/main/java/org/apache/jackrabbit/oak/plugins/index/diffindex/DiffCollector.java	(revision 0)
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.plugins.index.diffindex;
+
+import java.util.Set;
+
+import org.apache.jackrabbit.oak.spi.query.Filter;
+
+/**
+ * In charge of collecting the paths of nodes that match a given filter from the
+ * diff of the 2 states.
+ * 
+ */
+public interface DiffCollector {
+
+    Set<String> getResults(Filter filter);
+
+    double getCost(Filter filter);
+
+}
Index: src/main/java/org/apache/jackrabbit/oak/plugins/index/diffindex/UUIDDiffIndex.java
===================================================================
--- src/main/java/org/apache/jackrabbit/oak/plugins/index/diffindex/UUIDDiffIndex.java	(revision 0)
+++ src/main/java/org/apache/jackrabbit/oak/plugins/index/diffindex/UUIDDiffIndex.java	(revision 0)
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.plugins.index.diffindex;
+
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+
+public class UUIDDiffIndex extends DiffIndex {
+
+    public UUIDDiffIndex(NodeState before, NodeState after) {
+        super(new UUIDDiffCollector(before, after));
+    }
+
+    @Override
+    public String getIndexName() {
+        return "UUIDDiffIndex";
+    }
+}
Index: src/main/java/org/apache/jackrabbit/oak/core/RootImpl.java
===================================================================
--- src/main/java/org/apache/jackrabbit/oak/core/RootImpl.java	(revision 1437414)
+++ src/main/java/org/apache/jackrabbit/oak/core/RootImpl.java	(working copy)
@@ -30,11 +30,12 @@
 import org.apache.jackrabbit.oak.api.Blob;
 import org.apache.jackrabbit.oak.api.BlobFactory;
 import org.apache.jackrabbit.oak.api.CommitFailedException;
-import org.apache.jackrabbit.oak.api.Root;
 import org.apache.jackrabbit.oak.api.QueryEngine;
+import org.apache.jackrabbit.oak.api.Root;
 import org.apache.jackrabbit.oak.api.TreeLocation;
 import org.apache.jackrabbit.oak.namepath.NamePathMapper;
 import org.apache.jackrabbit.oak.plugins.commit.DefaultConflictHandler;
+import org.apache.jackrabbit.oak.plugins.index.diffindex.UUIDDiffIndexProviderWrapper;
 import org.apache.jackrabbit.oak.query.QueryEngineImpl;
 import org.apache.jackrabbit.oak.spi.commit.ConflictHandler;
 import org.apache.jackrabbit.oak.spi.observation.ChangeExtractor;
@@ -128,7 +129,7 @@
      */
     public Root getLatest() {
         checkLive();
-        RootImpl root = new RootImpl(store, null, subject, accConfiguration, indexProvider) {
+        RootImpl root = new RootImpl(store, null, subject, accConfiguration, getIndexProvider()) {
             @Override
             protected void checkLive() {
                 RootImpl.this.checkLive();
@@ -291,13 +292,13 @@
     @Override
     public QueryEngine getQueryEngine() {
         checkLive();
-        return new QueryEngineImpl(indexProvider) {
+        return new QueryEngineImpl(getIndexProvider()) {
 
             @Override
             protected NodeState getRootState() {
                 return rootTree.getNodeState();
             }
-            
+
             @Override
             protected Root getRootTree() {
                 return RootImpl.this;
@@ -320,6 +321,14 @@
         };
     }
 
+    private QueryIndexProvider getIndexProvider() {
+        if (hasPendingChanges()) {
+            return new UUIDDiffIndexProviderWrapper(indexProvider,
+                    getBaseState(), rootTree.getNodeState());
+        }
+        return indexProvider;
+    }
+
     //-----------------------------------------------------------< internal >---
 
     /**
