+ return bf_.empty();
+}
+
+
+MathArray::size_type MathArray::size() const
+{
+ return bf_.size();
+}
+
+
+void MathArray::erase()
+{
+ erase(0, size());
+}
+
+
+void MathArray::erase(size_type pos)
+{
+ if (pos < size())
+ erase(pos, pos + 1);
+}
+
+
+void MathArray::erase(size_type pos1, size_type pos2)
+{
+ bf_.erase(begin() + pos1, begin() + pos2);
+}
+
+
+MathAtom & MathArray::back()
+{
+ return bf_.back();
+}
+
+
+void MathArray::dump2(ostream & os) const
+{
+ for (const_iterator it = begin(); it != end(); ++it)
+ os << it->nucleus() << ' ';
+}
+
+
+void MathArray::dump(ostream & os) const
+{
+ for (const_iterator it = begin(); it != end(); ++it)
+ os << "<" << it->nucleus() << ">";
+}
+
+
+std::ostream & operator<<(std::ostream & os, MathArray const & ar)
+{
+ ar.dump2(os);
+ return os;
+}
+
+
+// returns sequence of char with same code starting at it up to end
+// it might be less, though...
+string charSequence(MathArray::const_iterator it, MathArray::const_iterator end)
+{
+ string s;
+ MathCharInset const * p = it->nucleus()->asCharInset();
+ if (!p)
+ return s;
+
+ for (MathTextCodes c = p->code(); it != end; ++it) {
+ if (!it->nucleus())
+ break;
+ p = it->nucleus()->asCharInset();
+ if (!p || p->code() != c)
+ break;
+ s += p->getChar();
+ }
+ return s;
+}
+
+
+MathArray MathArray::glueChars() const
+{
+ MathArray ar;
+ const_iterator it = begin();
+ while (it != end()) {
+ if (it->nucleus() && it->nucleus()->asCharInset()) {
+ string s = charSequence(it, end());
+ MathTextCodes c = it->nucleus()->asCharInset()->code();
+ ar.push_back(MathAtom(new MathStringInset(s, c)));
+ it += s.size();
+ } else {
+ ar.push_back(*it);
+ ++it;
+ }