+SCM
+Grob_properties::mark_smob ()
+{
+ scm_gc_mark (alist_);
+ scm_gc_mark (based_on_);
+ scm_gc_mark (cooked_);
+ return cooked_from_;
+}
+
+LY_DEFINE (ly_make_grob_properties, "ly:make-grob-properties",
+ 1, 0, 0, (SCM alist),
+ "This packages the given property list @var{alist} in"
+ " a grob property container stored in a context property"
+ " with the name of a grob.")
+{
+ LY_ASSERT_TYPE (ly_is_list, alist, 1);
+ return Grob_properties (alist, SCM_EOL).smobbed_copy ();
+}
+
+
+Grob_property_info
+Grob_property_info::find ()
+{
+ if (props_)
+ return *this;
+ SCM res = SCM_UNDEFINED;
+ if (Context *c = context_->where_defined (symbol_, &res))
+ if (c != context_)
+ return Grob_property_info (c, symbol_, Grob_properties::unsmob (res));
+ props_ = Grob_properties::unsmob (res);
+ return *this;
+}
+
+bool
+Grob_property_info::check ()
+{
+ if (props_)
+ return true;
+ SCM res = SCM_UNDEFINED;
+ if (context_->here_defined (symbol_, &res))
+ props_ = Grob_properties::unsmob (res);
+ return props_;
+}
+
+bool
+Grob_property_info::create ()
+{
+ // Using scm_hashq_create_handle_x would seem like the one-lookup
+ // way to create a handle if it does not exist yet. However, we
+ // need to check that there is a corresponding grob in this
+ // particular output first, and we have to do this in the global
+ // context. By far the most frequent case will be that a
+ // Grob_properties for this context already exists, so we optimize
+ // for that and only check the global handle when the local
+ // context is pristine.
+ if (check ())
+ return true;
+ SCM current_context_val = SCM_EOL;
+ Context *g = context_->get_global_context ();
+ if (!g)
+ return false; // Context is probably dead