+ Stream_event *ev = unsmob<Stream_event> (sev);
+
+ string id = ly_scm2string (ev->get_property ("id"));
+ SCM ops = ev->get_property ("ops");
+ SCM type_scm = ev->get_property ("type");
+ string type = ly_symbol2string (type_scm);
+
+ vector<Context_def *> path = path_to_acceptable_context (type_scm);
+
+ if (path.size () != 1)
+ {
+ programming_error (to_string ("Invalid CreateContext event: Cannot create %s context", type.c_str ()));
+ return;
+ }
+ Context_def *cdef = path[0];
+
+ Context *new_context = cdef->instantiate (ops);
+
+ new_context->id_string_ = id;
+
+ /* Register various listeners:
+ - Make the new context hear events that universally affect contexts
+ - connect events_below etc. properly */
+ /* We want to be the first ones to hear our own events. Therefore, wait
+ before registering events_below_ */
+ new_context->event_source ()->
+ add_listener (new_context->GET_LISTENER (Context, create_context_from_event),
+ ly_symbol2scm ("CreateContext"));
+ new_context->event_source ()->
+ add_listener (new_context->GET_LISTENER (Context, remove_context),
+ ly_symbol2scm ("RemoveContext"));
+ new_context->event_source ()->
+ add_listener (new_context->GET_LISTENER (Context, change_parent),
+ ly_symbol2scm ("ChangeParent"));
+ new_context->event_source ()->
+ add_listener (new_context->GET_LISTENER (Context, set_property_from_event),
+ ly_symbol2scm ("SetProperty"));
+ new_context->event_source ()->
+ add_listener (new_context->GET_LISTENER (Context, unset_property_from_event),
+ ly_symbol2scm ("UnsetProperty"));
+
+ new_context->events_below_->register_as_listener (new_context->event_source_);
+ add_context (new_context);
+
+ new_context->unprotect ();
+
+ Context_def *td = unsmob<Context_def> (new_context->definition_);
+
+ /* This cannot move before add_context (), because \override
+ operations require that we are in the hierarchy. */
+ td->apply_default_property_operations (new_context);
+ apply_property_operations (new_context, ops);
+
+ send_stream_event (this, "AnnounceNewContext", 0,
+ ly_symbol2scm ("context"), new_context->self_scm (),
+ ly_symbol2scm ("creator"), sev);
+}
+
+vector<Context_def *>
+Context::path_to_acceptable_context (SCM name) const
+{
+ // The 'accepts elements in definition_mods_ is a list of ('accepts string),
+ // but the Context_def expects to see elements of the form ('accepts symbol).
+ SCM accepts = SCM_EOL;
+ for (SCM s = definition_mods_; scm_is_pair (s); s = scm_cdr (s))
+ if (scm_is_eq (scm_caar (s), ly_symbol2scm ("accepts")))
+ {
+ SCM elt = scm_list_2 (scm_caar (s), scm_string_to_symbol (scm_cadar (s)));
+ accepts = scm_cons (elt, accepts);
+ }
+
+ return unsmob<Context_def> (definition_)->path_to_acceptable_context (name,
+ get_output_def (),
+ scm_reverse_x (accepts, SCM_EOL));
+
+}