Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionImpl.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionImpl.java	(revision 529913)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionImpl.java	(working copy)
@@ -118,6 +118,14 @@
     public static final String SET_PROPERTY_ACTION = "set_property";
 
     /**
+     * Thread-local variable set to the observation session that is currently
+     * firing observation events. This variable is used to avoid concurrency
+     * issues by checking that an event listener won't use the session it
+     * was registered with.
+     */
+    public static ThreadLocal currentObservationSession = new ThreadLocal();
+
+    /**
      * flag indicating whether this session is alive
      */
     protected boolean alive;
@@ -352,6 +360,13 @@
         if (!alive) {
             throw new RepositoryException("this session has been closed");
         }
+
+        if (this == currentObservationSession.get()) {
+            throw new RepositoryException(
+                    "An event listener is trying to access the session"
+                    + " it was registered with. Access denied to avoid"
+                    + " concurrency issues.");
+        }
     }
 
     /**
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/observation/EventConsumer.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/observation/EventConsumer.java	(revision 529876)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/observation/EventConsumer.java	(working copy)
@@ -228,7 +228,12 @@
         // check if filtered iterator has at least one event
         EventIterator it = new FilteredEventIterator(events, filter, denied);
         if (it.hasNext()) {
-            listener.onEvent(it);
+            try {
+                SessionImpl.currentObservationSession.set(session);
+                listener.onEvent(it);
+            } finally {
+                SessionImpl.currentObservationSession.set(null);
+            }
         } else {
             // otherwise skip this listener
         }
