+struct Bracket_nesting_node
+{
+public:
+ virtual ~Bracket_nesting_node(){}
+ virtual bool add_staff (Grob *) { return false; }
+ virtual void add_support (Grob *) { }
+ virtual void set_bound (Direction, Grob *){}
+ virtual void set_nesting_support (Grob*) {}
+ virtual void create_grobs (Engraver*, SCM) {}
+};
+
+struct Bracket_nesting_group : public Bracket_nesting_node
+{
+ Spanner *delimiter_;
+ vector<Bracket_nesting_node*> children_;
+ SCM symbol_;
+
+ void from_list (SCM );
+ virtual void add_support (Grob *grob);
+ virtual bool add_staff (Grob *grob);
+ virtual void set_nesting_support (Grob*);
+ virtual void set_bound (Direction, Grob *grob);
+ virtual void create_grobs (Engraver*, SCM);
+ ~Bracket_nesting_group ();
+ Bracket_nesting_group ();
+};
+
+
+struct Bracket_nesting_staff : public Bracket_nesting_node
+{
+ Grob *staff_;
+
+ Bracket_nesting_staff (Grob *s) { staff_ = s; }
+ virtual bool add_staff (Grob *);
+};
+
+
+Bracket_nesting_group::Bracket_nesting_group ()
+{
+ symbol_ = SCM_EOL;
+ delimiter_ = 0;
+}
+
+bool
+Bracket_nesting_staff::add_staff (Grob *g)
+{
+ if (!staff_)
+ {
+ staff_ = g;
+ return true;
+ }
+ return false;
+}
+
+void
+Bracket_nesting_group::create_grobs (Engraver *engraver, SCM default_type)
+{
+ SCM type = scm_is_symbol (symbol_) ? symbol_ : default_type;
+ delimiter_ = engraver->make_spanner (ly_symbol2string (type).c_str (), SCM_EOL);
+
+ for (vsize i = 0 ; i < children_.size (); i++)
+ {
+ children_[i]->create_grobs (engraver, default_type);
+ }
+}
+
+void
+Bracket_nesting_group::add_support (Grob *g)
+{
+ Side_position_interface::add_support (g, delimiter_);
+ for (vsize i = 0 ; i < children_.size (); i++)
+ {
+ children_[i]->add_support (g);
+ }
+}
+
+Bracket_nesting_group::~Bracket_nesting_group ()
+{
+ for (vsize i = 0 ; i < children_.size (); i++)
+ delete children_[i];
+}
+
+void
+Bracket_nesting_group::set_bound (Direction d, Grob *g)
+{
+ delimiter_->set_bound (d, g);
+ for (vsize i = 0 ; i < children_.size (); i++)
+ {
+ children_[i]->set_bound (d, g);
+ }
+}
+
+void
+Bracket_nesting_group::set_nesting_support (Grob *parent)
+{
+ if (parent)
+ Side_position_interface::add_support (delimiter_, parent);
+
+ for (vsize i = 0 ; i < children_.size (); i++)
+ {
+ children_[i]->set_nesting_support (delimiter_);
+ }
+}
+
+
+void
+Bracket_nesting_group::from_list (SCM x)
+{
+ for (SCM s = x; scm_is_pair (s); s = scm_cdr (s))
+ {
+ SCM entry = scm_car (s);
+ if (scm_is_pair (entry))
+ {
+ Bracket_nesting_group *node = new Bracket_nesting_group;
+ node->from_list (entry);
+ children_.push_back (node);
+ }
+ else if (entry == ly_symbol2scm ("SystemStartBrace")
+ || entry == ly_symbol2scm ("SystemStartBracket")
+ || entry == ly_symbol2scm ("SystemStartBar")
+ || entry == ly_symbol2scm ("SystemStartSquare")
+ )
+ symbol_ = entry;
+ else
+ {
+ children_.push_back (new Bracket_nesting_staff (0));
+ }
+ }
+}
+
+bool
+Bracket_nesting_group::add_staff (Grob *grob)
+{
+ for (vsize i = 0; i < children_.size (); i++)
+ {
+ if (children_[i]->add_staff (grob))
+ {
+ Pointer_group_interface::add_grob (delimiter_, ly_symbol2scm ("elements"), grob);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+
+
+/****************/
+