diff --git oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentDiscoveryLiteService.java oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentDiscoveryLiteService.java
index 3d7e0f9..cbd0890 100644
--- oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentDiscoveryLiteService.java
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentDiscoveryLiteService.java
@@ -662,7 +662,7 @@ public class DocumentDiscoveryLiteService implements ClusterStateChangeListener,
         // Now from the above it also results that this only wakes up the
         // backgroundWorker if we have any pending 'backlogy instances'
         // otherwise this is a no-op
-        if (info == null) {
+        if (info.isExternal()) {
             // then ignore this as this is likely an external change
             // note: it could be a compacted change, in which case we should
             // probably still process it - but we have a 5sec fallback
diff --git oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java
index a72c238..66fbb5c 100644
--- oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java
@@ -85,6 +85,7 @@ import org.apache.jackrabbit.oak.spi.blob.AbstractBlobStore;
 import org.apache.jackrabbit.oak.spi.blob.BlobStore;
 import org.apache.jackrabbit.oak.spi.blob.GarbageCollectableBlobStore;
 import org.apache.jackrabbit.oak.spi.blob.MemoryBlobStore;
+import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
 import org.apache.jackrabbit.oak.stats.Clock;
 import org.apache.jackrabbit.oak.stats.StatisticsProvider;
 import org.slf4j.Logger;
@@ -287,7 +288,7 @@ public class DocumentMK {
             isBranch = baseRev != null && baseRev.isBranch();
             parseJsonDiff(commit, jsonDiff, rootPath);
             commit.apply();
-            rev = nodeStore.done(commit, isBranch, null);
+            rev = nodeStore.done(commit, isBranch, CommitInfo.EMPTY);
             success = true;
         } catch (DocumentStoreException e) {
             throw new DocumentStoreException(e);
@@ -314,7 +315,7 @@ public class DocumentMK {
             throw new DocumentStoreException("Not a branch: " + branchRevisionId);
         }
         try {
-            return nodeStore.merge(revision, null).toString();
+            return nodeStore.merge(revision, CommitInfo.EMPTY).toString();
         } catch (DocumentStoreException e) {
             throw new DocumentStoreException(e);
         } catch (CommitFailedException e) {
diff --git oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
index f61e210..add63ef 100644
--- oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
@@ -767,7 +767,7 @@ public final class DocumentNodeStore
         return c;
     }
 
-    RevisionVector done(final @Nonnull Commit c, boolean isBranch, final @Nullable CommitInfo info) {
+    RevisionVector done(final @Nonnull Commit c, boolean isBranch, final @Nonnull CommitInfo info) {
         if (commitQueue.contains(c.getRevision())) {
             try {
                 final RevisionVector[] newHead = new RevisionVector[1];
@@ -803,7 +803,11 @@ public final class DocumentNodeStore
             try {
                 commitQueue.canceled(c.getRevision());
             } finally {
-                backgroundOperationLock.readLock().unlock();
+                try {
+                    backgroundOperationLock.readLock().unlock();
+                }catch(IllegalMonitorStateException ignore){
+
+                }
             }
         } else {
             Branch b = branches.getBranch(c.getBaseRevision());
@@ -2001,7 +2005,7 @@ public final class DocumentNodeStore
                     stats.populateDiffCache = clock.getTime() - time;
                     time = clock.getTime();
 
-                    dispatcher.contentChanged(getRoot().fromExternalChange(), null);
+                    dispatcher.contentChanged(getRoot().fromExternalChange(), CommitInfo.EMPTY_EXTERNAL);
                 } finally {
                     backgroundOperationLock.writeLock().unlock();
                 }
diff --git oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/PrefetchDispatcher.java oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/PrefetchDispatcher.java
index ae2715e..b4d25c9 100644
--- oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/PrefetchDispatcher.java
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/PrefetchDispatcher.java
@@ -50,7 +50,7 @@ class PrefetchDispatcher extends ChangeDispatcher {
 
     @Override
     public synchronized void contentChanged(@Nonnull NodeState root,
-                                            @Nullable CommitInfo info) {
+                                            @Nonnull CommitInfo info) {
         if (root instanceof DocumentNodeState) {
             final DocumentNodeState state = (DocumentNodeState) root;
             if (state.isFromExternalChange()) {
diff --git oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/secondary/SecondaryStoreObserver.java oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/secondary/SecondaryStoreObserver.java
index ea21882..56aa6bf 100644
--- oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/secondary/SecondaryStoreObserver.java
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/secondary/SecondaryStoreObserver.java
@@ -23,7 +23,6 @@ import java.util.List;
 import java.util.concurrent.TimeUnit;
 
 import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
 
 import com.google.common.base.Stopwatch;
 import org.apache.jackrabbit.oak.api.CommitFailedException;
@@ -70,7 +69,7 @@ public class SecondaryStoreObserver implements Observer {
     }
 
     @Override
-    public void contentChanged(@Nonnull NodeState root, @Nullable CommitInfo info) {
+    public void contentChanged(@Nonnull NodeState root, @Nonnull CommitInfo info) {
         //Diff here would also be traversing non visible areas and there
         //diffManyChildren might pose problem for e.g. data under uuid index
         if (!firstEventProcessed){
@@ -93,7 +92,7 @@ public class SecondaryStoreObserver implements Observer {
             NodeState updatedSecondaryRoot = nodeStore.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
             secondaryObserver.contentChanged(DelegatingDocumentNodeState.wrap(updatedSecondaryRoot, differ));
 
-            TimerStats timer = info == null ? external : local;
+            TimerStats timer = info.isExternal() ? external : local;
             timer.update(w.elapsed(TimeUnit.NANOSECONDS), TimeUnit.NANOSECONDS);
 
             if (!firstEventProcessed){
diff --git oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdate.java oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdate.java
index d973794..9337404 100644
--- oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdate.java
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdate.java
@@ -390,7 +390,8 @@ public class AsyncIndexUpdate implements Runnable, Closeable {
         int hardTimeOut = 5 * softTimeOutSecs;
         if(!runPermit.tryAcquire()){
             //First let current run complete without bothering it
-            log.debug("[{}] [WAITING] Indexing in progress. Would wait for {} secs for it to finish", name, softTimeOutSecs);
+            log.debug("[{}] [WAITING] exexing in progress. Would wait for {} secs for it to finish", name,
+                    softTimeOutSecs);
             try {
                 if(!runPermit.tryAcquire(softTimeOutSecs, TimeUnit.SECONDS)){
                     //We have now waited enough. So signal the indexer that it should return right away
diff --git oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStore.java oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStore.java
index 070159c..232093c 100644
--- oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStore.java
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStore.java
@@ -84,7 +84,7 @@ public class MemoryNodeStore implements NodeStore, Observable {
 
     @Override
     public synchronized Closeable addObserver(Observer observer) {
-        observer.contentChanged(getRoot(), null);
+        observer.contentChanged(getRoot(), CommitInfo.EMPTY_EXTERNAL);
 
         Closeable closeable = new Closeable() {
             @Override
diff --git oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/multiplex/MultiplexingNodeStore.java oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/multiplex/MultiplexingNodeStore.java
index 728b4f9..9916125 100644
--- oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/multiplex/MultiplexingNodeStore.java
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/multiplex/MultiplexingNodeStore.java
@@ -277,7 +277,7 @@ public class MultiplexingNodeStore implements NodeStore, Observable {
 
     @Override
     public Closeable addObserver(final Observer observer) {
-        observer.contentChanged(getRoot(), null);
+        observer.contentChanged(getRoot(), CommitInfo.EMPTY_EXTERNAL);
         observers.add(observer);
         return new Closeable() {
             @Override
diff --git oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/FilterBuilder.java oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/FilterBuilder.java
index 9b983b2..01ec482 100644
--- oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/FilterBuilder.java
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/FilterBuilder.java
@@ -425,7 +425,7 @@ public final class FilterBuilder {
             }
 
             private boolean isExternal(CommitInfo info) {
-                return info == null;
+                return info.isExternal();
             }
             
             @Override
diff --git oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/BackgroundObserver.java oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/BackgroundObserver.java
index 6c456ce..490c623 100644
--- oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/BackgroundObserver.java
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/BackgroundObserver.java
@@ -33,7 +33,6 @@ import java.util.concurrent.Executor;
 import java.util.concurrent.TimeUnit;
 
 import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
 
 import com.google.common.base.Predicate;
 import org.apache.jackrabbit.oak.commons.concurrent.NotifyingFutureTask;
@@ -246,7 +245,7 @@ public class BackgroundObserver implements Observer, Closeable {
                 return size(filter(queue, new Predicate<ContentChange>() {
                     @Override
                     public boolean apply(ContentChange input) {
-                        return input.info != null;
+                        return !isExternal(input.info);
                     }
                 }));
             }
@@ -256,7 +255,7 @@ public class BackgroundObserver implements Observer, Closeable {
                 return size(filter(queue, new Predicate<ContentChange>() {
                     @Override
                     public boolean apply(ContentChange input) {
-                        return input.info == null;
+                        return isExternal(input.info);
                     }
                 }));
             }
@@ -269,11 +268,11 @@ public class BackgroundObserver implements Observer, Closeable {
      * @throws IllegalStateException  if {@link #close()} has already been called.
      */
     @Override
-    public synchronized void contentChanged(@Nonnull NodeState root, @Nullable CommitInfo info) {
+    public synchronized void contentChanged(@Nonnull NodeState root, @Nonnull CommitInfo info) {
         checkState(!stopped);
         checkNotNull(root);
 
-        if (alwaysCollapseExternalEvents && info == null && last != null && last.info == null) {
+        if (alwaysCollapseExternalEvents && isExternal(info) && last != null && isExternal(last.info)) {
             // This is an external change. If the previous change was
             // also external, we can drop it from the queue (since external
             // changes in any case can cover multiple commits) to help
@@ -311,6 +310,12 @@ public class BackgroundObserver implements Observer, Closeable {
 
     //------------------------------------------------------------< internal >---
 
+    private boolean isExternal(CommitInfo info) {
+        //TODO info would not be not null for external change now. So collapsing aspect needs to be
+        //checked
+        return info == null || info.isExternal();
+    }
+
     private static Logger getLogger(@Nonnull Observer observer) {
         return LoggerFactory.getLogger(checkNotNull(observer).getClass());
     }
diff --git oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/ChangeDispatcher.java oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/ChangeDispatcher.java
index bf75673..1050fe2 100644
--- oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/ChangeDispatcher.java
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/ChangeDispatcher.java
@@ -63,7 +63,7 @@ public class ChangeDispatcher implements Observable, Observer {
     @Override
     @Nonnull
     public synchronized Closeable addObserver(final Observer observer) {
-        observer.contentChanged(root, null);
+        observer.contentChanged(root, CommitInfo.EMPTY_EXTERNAL);
         observers.addObserver(observer);
         return new Closeable() {
             @Override
@@ -74,8 +74,9 @@ public class ChangeDispatcher implements Observable, Observer {
     }
 
     @Override
-    public synchronized void contentChanged(@Nonnull NodeState root, @Nullable CommitInfo info) {
+    public synchronized void contentChanged(@Nonnull NodeState root, @Nonnull CommitInfo info) {
         checkNotNull(root);
+        checkNotNull(info);
         observers.contentChanged(root, info);
         this.root = root;
     }
diff --git oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/CommitInfo.java oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/CommitInfo.java
index 640a8f3..34f2379 100644
--- oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/CommitInfo.java
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/CommitInfo.java
@@ -45,6 +45,9 @@ public final class CommitInfo {
     public static final CommitInfo EMPTY =
             new CommitInfo(OAK_UNKNOWN, OAK_UNKNOWN);
 
+    public static final CommitInfo EMPTY_EXTERNAL =
+            new CommitInfo(OAK_UNKNOWN, OAK_UNKNOWN, Collections.<String, Object>emptyMap(), true);
+
     private final String sessionId;
 
     private final String userId;
@@ -53,6 +56,8 @@ public final class CommitInfo {
 
     private final Map<String, Object> info;
 
+    private final boolean external;
+
     /**
      * Creates a commit info for the given session and user.
      *
@@ -72,9 +77,21 @@ public final class CommitInfo {
      * @param info info map
      */
     public CommitInfo(@Nonnull String sessionId, @Nullable String userId, Map<String, Object> info) {
+        this(sessionId, userId, info, false);
+    }
+
+    /**
+     * Creates a commit info for the given session and user and info map.
+     *  @param sessionId session identifier
+     * @param userId The user id.
+     * @param info info map
+     * @param external indicates if the commit info is from external change
+     */
+    public CommitInfo(@Nonnull String sessionId, @Nullable String userId, Map<String, Object> info, boolean external) {
         this.sessionId = checkNotNull(sessionId);
         this.userId = (userId == null) ? OAK_UNKNOWN : userId;
         this.info = checkNotNull(info);
+        this.external = external;
     }
 
     /**
@@ -101,6 +118,18 @@ public final class CommitInfo {
     }
 
     /**
+     * Return a flag indicating whether this is commit info is
+     * for an external change
+     *
+     * @return true if commit info is for an external change
+     */
+    public boolean isExternal() {
+        return external;
+    }
+
+    /**
+
+    /**
      * Returns the base path of this commit. All changes within this commit
      * are expected to be located within the returned path. By default this
      * is the root path, but a particular commit can declare a more specific
@@ -135,6 +164,7 @@ public final class CommitInfo {
             return sessionId.equals(that.sessionId)
                     && userId.equals(that.userId)
                     && this.date == that.date
+                    && this.external == that.external
                     && info.equals(that.info);
         } else {
             return false;
@@ -143,7 +173,7 @@ public final class CommitInfo {
 
     @Override
     public int hashCode() {
-        return Objects.hashCode(sessionId, userId, date, info);
+        return Objects.hashCode(sessionId, userId, date, info, external);
     }
 
     @Override
@@ -151,6 +181,7 @@ public final class CommitInfo {
         return toStringHelper(this).omitNullValues()
                 .add("sessionId", sessionId)
                 .add("userId", userId)
+                .add("external", external)
                 .add("date", date)
                 .add("info", info)
                 .toString();
diff --git oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/CompositeObserver.java oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/CompositeObserver.java
index 5724f51..b24a497 100644
--- oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/CompositeObserver.java
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/CompositeObserver.java
@@ -47,7 +47,7 @@ public class CompositeObserver implements Observer {
 
     @Override
     public synchronized void contentChanged(
-            @Nonnull NodeState root, @Nullable CommitInfo info) {
+            @Nonnull NodeState root, @Nonnull CommitInfo info) {
         checkNotNull(root);
         for (Observer observer : observers) {
             observer.contentChanged(root, info);
diff --git oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/Observer.java oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/Observer.java
index 1eae37b..19f03f1 100644
--- oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/Observer.java
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/Observer.java
@@ -17,7 +17,6 @@
 package org.apache.jackrabbit.oak.spi.commit;
 
 import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
 
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 
@@ -64,8 +63,8 @@ public interface Observer {
      * information on when and how this method gets called.
      *
      * @param root root state of the repository
-     * @param info local commit information, or {@code null}
+     * @param info commit information
      */
-    void contentChanged(@Nonnull NodeState root, @Nullable CommitInfo info);
+    void contentChanged(@Nonnull NodeState root, @Nonnull CommitInfo info);
 
 }
diff --git oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/CommitQueueTest.java oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/CommitQueueTest.java
index 8d9064a..1efeed0 100644
--- oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/CommitQueueTest.java
+++ oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/CommitQueueTest.java
@@ -107,7 +107,7 @@ public class CommitQueueTest {
                                 store.canceled(commit);
                             } else {
                                 boolean isBranch = random.nextInt(5) == 0;
-                                store.done(commit, isBranch, null);
+                                store.done(commit, isBranch, CommitInfo.EMPTY_EXTERNAL);
                             }
                         }
                     } catch (Exception e) {
diff --git oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/CommitRootUpdateTest.java oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/CommitRootUpdateTest.java
index e5d3a31..1e67f89 100644
--- oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/CommitRootUpdateTest.java
+++ oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/CommitRootUpdateTest.java
@@ -88,7 +88,7 @@ public class CommitRootUpdateTest {
             success = true;
         } finally {
             if (success) {
-                ns.done(c, false, null);
+                ns.done(c, false, CommitInfo.EMPTY_EXTERNAL);
             } else {
                 ns.canceled(c);
             }
diff --git oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/CommitTest.java oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/CommitTest.java
index 4250ba2..5e1cc47 100644
--- oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/CommitTest.java
+++ oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/CommitTest.java
@@ -66,7 +66,7 @@ public class CommitTest {
             op.setMapEntry("p", c.getRevision(), "v");
             try {
                 c.apply();
-                ns.done(c, false, null);
+                ns.done(c, false, CommitInfo.EMPTY_EXTERNAL);
             } catch (DocumentStoreException e) {
                 // expected
             }
@@ -99,7 +99,7 @@ public class CommitTest {
                     new RevisionVector(c.getRevision())));
             try {
                 c.apply();
-                ns.done(c, false, null);
+                ns.done(c, false, CommitInfo.EMPTY_EXTERNAL);
                 fail("commit must fail");
             } catch (DocumentStoreException e) {
                 // expected
diff --git oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/PrefetchDispatcherTest.java oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/PrefetchDispatcherTest.java
index 18b8078..cf4b255 100644
--- oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/PrefetchDispatcherTest.java
+++ oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/PrefetchDispatcherTest.java
@@ -75,7 +75,7 @@ public class PrefetchDispatcherTest {
         PrefetchDispatcher dispatcher = new PrefetchDispatcher(
                 before, MoreExecutors.sameThreadExecutor());
         numQueries.set(0);
-        dispatcher.contentChanged(after, null);
+        dispatcher.contentChanged(after, CommitInfo.EMPTY_EXTERNAL);
         // expect two queries for children: below /foo and /foo/bar
         assertEquals(2, numQueries.get());
     }
diff --git oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/secondary/SecondaryStoreCacheTest.java oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/secondary/SecondaryStoreCacheTest.java
index 9aa6009..a8f7611 100644
--- oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/secondary/SecondaryStoreCacheTest.java
+++ oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/secondary/SecondaryStoreCacheTest.java
@@ -193,7 +193,7 @@ public class SecondaryStoreCacheTest {
         AbstractDocumentNodeState r0 = merge(nb);
         AbstractDocumentNodeState a_c_0 = documentState(primary.getRoot(), "/a/c");
 
-        observer.contentChanged(r0, null);
+        observer.contentChanged(r0, CommitInfo.EMPTY);
 
         AbstractDocumentNodeState result = cache.getDocumentNodeState("/a/c", r0.getRootRevision(), a_c_0
                 .getLastRevision());
diff --git oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdateTest.java oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdateTest.java
index 6ebab0c..ba03a49 100644
--- oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdateTest.java
+++ oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdateTest.java
@@ -1651,7 +1651,7 @@ public class AsyncIndexUpdateTest {
 
         @Override
         public void contentChanged(@Nonnull NodeState root, @Nullable CommitInfo info) {
-            if (info != null){
+            if (info != CommitInfo.EMPTY_EXTERNAL){
                 infos.add(info);
             }
         }
diff --git oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/EventFactory.java oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/EventFactory.java
index eba2108..7fb75f0 100644
--- oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/EventFactory.java
+++ oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/EventFactory.java
@@ -64,7 +64,7 @@ public class EventFactory {
 
     EventFactory(NamePathMapper mapper, CommitInfo commitInfo) {
         this.mapper = mapper;
-        if (commitInfo != null) {
+        if (!commitInfo.isExternal()) {
             this.userID = commitInfo.getUserId();
             Object userData = commitInfo.getInfo().get(USER_DATA);
             this.userData = userData instanceof String ? (String) userData : null;
diff --git oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/LocalIndexObserver.java oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/LocalIndexObserver.java
index e5ccf0f..68ea04c 100644
--- oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/LocalIndexObserver.java
+++ oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/LocalIndexObserver.java
@@ -39,9 +39,9 @@ public class LocalIndexObserver implements Observer{
     }
 
     @Override
-    public void contentChanged(@Nonnull NodeState root, @Nullable CommitInfo info) {
+    public void contentChanged(@Nonnull NodeState root, @Nonnull CommitInfo info) {
         //TODO [hybrid] Do external diff?
-        if (info == null){
+        if (info.isExternal()){
            return;
         }
 
diff --git oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/LocalIndexObserverTest.java oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/LocalIndexObserverTest.java
index 1ef338f..2b6b5ec 100644
--- oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/LocalIndexObserverTest.java
+++ oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/LocalIndexObserverTest.java
@@ -53,8 +53,8 @@ public class LocalIndexObserverTest {
     }
 
     @Test
-    public void nullCommitInfo() throws Exception{
-        observer.contentChanged(EMPTY_NODE, null);
+    public void externalCommitInfo() throws Exception{
+        observer.contentChanged(EMPTY_NODE, CommitInfo.EMPTY_EXTERNAL);
     }
 
     @Test
diff --git oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStore.java oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStore.java
index 53eaac3..cb32f28 100644
--- oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStore.java
+++ oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStore.java
@@ -251,7 +251,7 @@ public class SegmentNodeStore implements NodeStore, Observable {
         if (!state.getRecordId().equals(head.get().getRecordId())) {
             head.set(state);
             if (dispatchChanges) {
-                contentChanged(state.getChildNode(ROOT), null);
+                contentChanged(state.getChildNode(ROOT), CommitInfo.EMPTY_EXTERNAL);
             }
         }
     }
diff --git oak-segment/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStore.java oak-segment/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStore.java
index c519bf1..b6cfd35 100644
--- oak-segment/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStore.java
+++ oak-segment/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStore.java
@@ -254,7 +254,7 @@ public class SegmentNodeStore implements NodeStore, Observable {
         if (!state.getRecordId().equals(head.get().getRecordId())) {
             head.set(state);
             if (dispatchChanges) {
-                changeDispatcher.contentChanged(state.getChildNode(ROOT), null);
+                changeDispatcher.contentChanged(state.getChildNode(ROOT), CommitInfo.EMPTY_EXTERNAL);
             }
         }
     }
