--- ../../lilypond29/lily/context.cc	2006-05-05 18:03:29.000000000 +0200
+++ context.cc	2006-05-13 19:13:53.000000000 +0200
@@ -9,6 +9,7 @@
 #include "context.hh"
 
 #include "context-def.hh"
+#include "dispatcher.hh"
 #include "international.hh"
 #include "ly-smobs.icc"
 #include "main.hh"
@@ -24,7 +25,7 @@
 Context::is_removable () const
 {
   return context_list_ == SCM_EOL && ! iterator_count_
-    && !dynamic_cast<Score_context const *> (this);
+    && !dynamic_cast<Global_context const *> (daddy_context_);
 }
 
 void
@@ -96,12 +97,19 @@
   accepts_list_ = SCM_EOL;
   context_list_ = SCM_EOL;
   definition_ = SCM_EOL;
+  definition_mods_ = SCM_EOL;
   unique_ = -1;
+  event_source_ = 0;
+  events_below_ = 0;
 
   smobify_self ();
 
   Scheme_hash_table *tab = new Scheme_hash_table;
   properties_scm_ = tab->unprotect ();
+  event_source_ = new Dispatcher ();
+  event_source_->unprotect ();
+  events_below_ = new Dispatcher ();
+  events_below_->unprotect ();
 
   /*
     UGH UGH
@@ -117,9 +125,9 @@
   /*
     Don't create multiple score contexts.
   */
-  if (dynamic_cast<Global_context *> (this)
-      && dynamic_cast<Global_context *> (this)->get_score_context ())
-    return get_score_context ()->create_unique_context (name, id, operations);
+  Global_context *gthis = dynamic_cast<Global_context *> (this);
+  if (gthis && gthis->get_score_context ())
+    return gthis->get_score_context ()->create_unique_context (name, id, operations);
 
   /*
     TODO: use accepts_list_.
@@ -171,9 +179,9 @@
   /*
     Don't create multiple score contexts.
   */
-  if (dynamic_cast<Global_context *> (this)
-      && dynamic_cast<Global_context *> (this)->get_score_context ())
-    return get_score_context ()->find_create_context (n, id, operations);
+  Global_context *gthis = dynamic_cast<Global_context *> (this);
+  if (gthis && gthis->get_score_context ())
+    return gthis->get_score_context ()->find_create_context (n, id, operations);
 
   if (Context *existing = find_context_below (this, n, id))
     return existing;
@@ -239,6 +247,9 @@
 
   new_context->unique_ = get_global_context()->new_unique();
   new_context->id_string_ = id;
+  
+  new_context->events_below_->register_as_listener (new_context->event_source_);
+  
   add_context (new_context);
   apply_property_operations (new_context, ops);
 
@@ -280,10 +291,7 @@
 	}
 
       Context *tg = create_context (t, "", SCM_EOL);
-      if (!tg->is_bottom_context ())
-	return tg->get_default_interpreter ();
-      else
-	return tg;
+      return tg->get_default_interpreter ();
     }
   return this;
 }
@@ -377,6 +385,7 @@
   return trans;
 }
 
+
 /*
   ID == "" means accept any ID.
 */
@@ -402,6 +411,25 @@
   return found;
 }
 
+Context *
+find_context_below (Context *where,
+                    int unique)
+{
+  if (where->get_unique () == unique)
+    return where;
+
+  Context *found = 0;
+  for (SCM s = where->children_contexts ();
+       !found && scm_is_pair (s); s = scm_cdr (s))
+    {
+      Context *tr = unsmob_context (scm_car (s));
+
+      found = find_context_below (tr, unique);
+    }
+
+  return found;
+}
+
 SCM
 Context::properties_as_alist () const
 {
@@ -500,10 +528,13 @@
   scm_gc_mark (me->context_list_);
   scm_gc_mark (me->aliases_);
   scm_gc_mark (me->definition_);
+  scm_gc_mark (me->definition_mods_);
   scm_gc_mark (me->properties_scm_);
   scm_gc_mark (me->accepts_list_);
   if (me->implementation_)
     scm_gc_mark (me->implementation_->self_scm ());
+  if (me->event_source_) scm_gc_mark (me->event_source_->self_scm ());
+  if (me->events_below_) scm_gc_mark (me->events_below_->self_scm ());
 
   return me->properties_scm_;
 }
--- ../../lilypond29/lily/context-def.cc	2006-02-22 14:26:44.000000000 +0100
+++ context-def.cc	2006-05-13 00:41:11.000000000 +0200
@@ -298,6 +298,7 @@
     context = new Context (key);
 
   context->definition_ = self_scm ();
+  context->definition_mods_ = ops;
 
   SCM trans_names = get_translator_names (ops);
 
--- ../../lilypond29/lily/context-scheme.cc	2006-01-24 02:42:14.000000000 +0100
+++ context-scheme.cc	2006-05-13 10:59:40.000000000 +0200
@@ -9,6 +9,7 @@
 
 #include "context.hh"
 #include "context-def.hh"
+#include "dispatcher.hh"
 
 LY_DEFINE (ly_context_id, "ly:context-id",
 	   1, 0, 0, (SCM context),
@@ -159,3 +160,22 @@
   SCM_ASSERT_TYPE (ctx, context, SCM_ARG1, __FUNCTION__, "Context");
   return ctx->now_mom ().smobbed_copy ();
 }
+
+LY_DEFINE (ly_context_event_source, "ly:context-event-source",
+           1, 0, 0, (SCM context),
+           "Return event-source of context CONTEXT")
+{
+  Context *ctx = unsmob_context (context);
+  SCM_ASSERT_TYPE (ctx, context, SCM_ARG1, __FUNCTION__, "Context");
+  return ctx->event_source ()->self_scm ();
+}
+
+LY_DEFINE (ly_context_events_below, "ly:context-events-below",
+           1, 0, 0, (SCM context),
+           "Return a stream-distributor that distributes all events\n"
+           " from @var{context} and all its subcontexts.")
+{
+  Context *ctx = unsmob_context (context);
+  SCM_ASSERT_TYPE (ctx, context, SCM_ARG1, __FUNCTION__, "Context");
+  return ctx->events_below ()->self_scm ();
+}
--- ../../lilypond29/lily/music.cc	2006-03-31 02:23:26.000000000 +0200
+++ music.cc	2006-05-13 11:08:04.000000000 +0200
@@ -8,6 +8,8 @@
 
 #include "music.hh"
 
+#include "context.hh"
+#include "dispatcher.hh"
 #include "duration.hh"
 #include "input-smob.hh"
 #include "international.hh"
@@ -16,6 +18,7 @@
 #include "music-sequence.hh"
 #include "pitch.hh"
 #include "score.hh"
+#include "stream-event.hh"
 #include "warn.hh"
 
 /*
@@ -234,6 +237,13 @@
   return ip ? ip : &dummy_input_global;
 }
 
+void
+Music::send_to_context (Context *c)
+{
+  SEND_EVENT_TO_CONTEXT (c, "MusicEvent",
+                         EVENT_PROPERTY("music", self_scm ()));
+}
+
 Music *
 make_music_by_name (SCM sym)
 {
--- ../../lilypond29/lily/music-iterator.cc	2006-02-01 00:52:52.000000000 +0100
+++ music-iterator.cc	2006-05-13 11:07:10.000000000 +0200
@@ -157,6 +157,12 @@
   Music_iterator *it = b ? (Music_iterator *) this : 0;	// ugh
   if (!it)
     it = try_music_in_children (m);
+  else
+    /* TODO: try_music should only do the following:
+     - descend iterator to bottom context
+     - send music to a bottom context.
+     The function should also be renamed, and it should not return a value. */
+    m->send_to_context (get_outlet ());
   return it;
 }
 
--- ../../lilypond29/lily/include/context.hh	2006-05-05 18:03:29.000000000 +0200
+++ include/context.hh	2006-05-13 00:37:17.000000000 +0200
@@ -33,7 +33,10 @@
 protected:
   int unique_;
   Context *daddy_context_;
+  /* The used Context_def */
   SCM definition_;
+  /* Additions to the Context_def, given by \with */
+  SCM definition_mods_;
   Context_key_manager key_manager_;
   
   SCM properties_scm_;
@@ -42,6 +45,13 @@
   SCM aliases_;
   Translator_group *implementation_;
   string id_string_;
+  
+  /* Events reported in the context is sent to this dispatcher. */
+  Dispatcher *event_source_;
+
+  /* Events reported to this context or recursively in any of its
+     children, are sent to this dispatcher. */
+  Dispatcher *events_below_;
 
   friend class Context_def;
   void clear_key_disambiguations ();
@@ -57,6 +67,11 @@
   SCM default_child_context_name () const;
   int get_unique() { return unique_; }
 
+  Dispatcher *event_source () const { return event_source_; }
+  Dispatcher *events_below () const { return events_below_; }
+  SCM get_definition () const { return definition_; }
+  SCM get_definition_mods () const { return definition_mods_; }
+
   Translator_group *implementation () const { return implementation_; }
   Context *get_parent_context () const;
   Context (Object_key const *);
--- ../../lilypond29/lily/include/music.hh	2006-01-24 14:15:30.000000000 +0100
+++ include/music.hh	2006-05-13 11:03:39.000000000 +0200
@@ -41,6 +41,9 @@
 
   /// Scale the music in time by #factor#.
   void compress (Moment factor);
+  
+  // Broadcast the event in a context's event-source.
+  void send_to_context (Context *c);
 
   DECLARE_SCHEME_CALLBACK (duration_length_callback, (SCM));
   
--- ../../lilypond29/lily/include/stream-event.hh	2006-05-05 17:59:21.000000000 +0200
+++ include/stream-event.hh	2006-05-13 21:21:15.000000000 +0200
@@ -46,8 +46,8 @@
   {									\
     Stream_event *_e_ = new Stream_event (ctx, ly_symbol2scm (cl));	\
     __VA_ARGS__;							\
-    ctx->event_source ()->distribute (_e_);				\
-    scm_gc_unprotect_object (_e_->self_scm ());				\
+    ctx->event_source ()->broadcast (_e_);				\
+    _e_->unprotect ();							\
   }
   
 #define EVENT_PROPERTY(prop, val)	\
