+ for (vsize i = 0; i < grob_array->size (); i++)
+ {
+ Grob *g = grob_array->grob (i);
+
+ Slice sr = grob_system_range (g);
+ sr.intersect (system_range);
+
+ int idx = 0;
+ if (dynamic_cast<Spanner *> (g))
+ idx = --spanner_index;
+ else if (dynamic_cast<Item *> (g))
+ idx = item_index++;
+
+ vec[idx].set (g, sr);
+ }
+
+ qsort (vec, item_index,
+ sizeof (Substitution_entry), &Substitution_entry::item_compare);
+
+ vector<Slice> item_indices;
+ vector<Slice> spanner_indices;
+ for (int i = 0; i <= system_range.length (); i++)
+ {
+ item_indices.push_back (Slice (len, 0));
+ spanner_indices.push_back (Slice (len, 0));
+ }
+
+ vector<Slice> *arrs[]
+ = {
+ &item_indices, &spanner_indices
+ };
+
+ for (int i = 0; i < item_index;i++)
+ {
+ for (int j = vec[i].left_; j <= vec[i].right_; j++)
+ item_indices[j - system_range[LEFT]].add_point (i);
+ }
+
+ /*
+ sorting vec[spanner_index.. len]
+ is a waste of time -- the staff-spanners screw up the
+ ordering, since they go across the entire score.
+ */
+ for (vsize i = spanner_indices.size (); i--;)
+ spanner_indices[i] = Slice (spanner_index, len - 1);
+
+ assert (item_index <= spanner_index);
+
+ assert ((broken_intos_.size () == (vsize)system_range.length () + 1)
+ || (broken_intos_.empty () && system_range.length () == 0));
+ for (vsize i = 0; i < broken_intos_.size (); i++)
+ {
+ Grob *sc = broken_intos_[i];
+ System *l = sc->get_system ();
+ set_break_subsititution (l ? l->self_scm () : SCM_UNDEFINED);
+
+ SCM newval = sc->internal_get_object (sym);
+ if (!unsmob_grob_array (newval))
+ {
+ newval = Grob_array::make_array ();
+ sc->set_object (sym, newval);
+ }
+
+ Grob_array *new_array = unsmob_grob_array (newval);
+ for (int k = 0; k < 2;k++)
+ for (int j = (*arrs[k])[i][LEFT]; j <= (*arrs[k])[i][RIGHT]; j++)
+ {
+ Grob *substituted = substitute_grob (vec[j].grob_);
+ if (substituted)
+ new_array->add (substituted);
+ }
+
+#ifdef PARANOIA
+ printf ("%d (%d), sp %d (%d)\n",
+ item_indices [i].length (), item_index,
+ spanner_indices[i].length (), len -spanner_index);
+
+ {
+ SCM l1 = substitute_grob_list (grob_list);
+ assert (scm_ilength (l1) == scm_ilength (newval));
+ }
+#endif
+ }
+
+ return true;
+}