+ anchor_ = *this;
+}
+
+
+
+bool LCursor::posLeft()
+{
+ if (pos() == 0)
+ return false;
+ --pos();
+ return true;
+}
+
+
+bool LCursor::posRight()
+{
+ if (pos() == lastpos())
+ return false;
+ ++pos();
+ return true;
+}
+
+
+CursorSlice LCursor::anchor() const
+{
+ BOOST_ASSERT(anchor_.size() >= size());
+ CursorSlice normal = anchor_[size() - 1];
+ if (size() < anchor_.size() && back() <= normal) {
+ // anchor is behind cursor -> move anchor behind the inset
+ ++normal.pos();
+ }
+ return normal;
+}
+
+
+CursorSlice LCursor::selBegin() const
+{
+ if (!selection())
+ return back();
+ return anchor() < back() ? anchor() : back();
+}
+
+
+CursorSlice LCursor::selEnd() const
+{
+ if (!selection())
+ return back();
+ return anchor() > back() ? anchor() : back();
+}
+
+
+DocIterator LCursor::selectionBegin() const
+{
+ if (!selection())
+ return *this;
+ return anchor() < back() ? anchor_ : *this;
+}
+
+
+DocIterator LCursor::selectionEnd() const
+{
+ if (!selection())
+ return *this;
+ return anchor() > back() ? anchor_ : *this;
+}
+
+
+void LCursor::setSelection()
+{
+ selection() = true;
+ // a selection with no contents is not a selection
+#warning doesnt look ok
+ if (par() == anchor().par() && pos() == anchor().pos())
+ selection() = false;
+}
+
+
+void LCursor::setSelection(DocIterator const & where, size_t n)
+{
+ setCursor(where, true);
+ anchor_ = where;
+ pos() += n;
+}
+
+
+void LCursor::clearSelection()
+{
+ selection() = false;
+ mark() = false;
+ resetAnchor();
+ bv().unsetXSel();
+}
+
+
+int & LCursor::x_target()
+{
+ return x_target_;
+}
+
+
+int LCursor::x_target() const
+{
+ return x_target_;
+}
+
+
+void LCursor::clearTargetX()
+{
+ x_target_ = -1;
+}
+
+
+
+void LCursor::info(std::ostream & os) const
+{
+ for (int i = 1, n = depth(); i < n; ++i) {
+ operator[](i).inset().infoize(os);
+ os << " ";
+ }
+ if (pos() != 0)
+ prevInset()->infoize2(os);
+ // overwite old message
+ os << " ";
+}
+
+
+string LCursor::grabSelection()
+{
+ if (!selection())
+ return string();
+
+ CursorSlice i1 = selBegin();
+ CursorSlice i2 = selEnd();
+
+ if (i1.idx() == i2.idx()) {
+ if (i1.inset().asMathInset()) {
+ MathArray::const_iterator it = i1.cell().begin();
+ return asString(MathArray(it + i1.pos(), it + i2.pos()));
+ } else {
+ return "unknown selection 1";
+ }
+ }
+
+ row_type r1, r2;
+ col_type c1, c2;
+ region(i1, i2, r1, r2, c1, c2);
+
+ string data;
+ if (i1.inset().asMathInset()) {
+ for (row_type row = r1; row <= r2; ++row) {
+ if (row > r1)
+ data += "\\\\";
+ for (col_type col = c1; col <= c2; ++col) {
+ if (col > c1)
+ data += '&';
+ data += asString(i1.asMathInset()->cell(i1.asMathInset()->index(row, col)));
+ }
+ }
+ } else {
+ data = "unknown selection 2";
+ }
+ return data;
+}
+
+
+void LCursor::eraseSelection()
+{
+ //lyxerr << "LCursor::eraseSelection" << endl;
+ CursorSlice const & i1 = selBegin();
+ CursorSlice const & i2 = selEnd();
+#ifdef WITH_WARNINGS
+#warning FIXME
+#endif
+ if (i1.inset().asMathInset()) {
+ if (i1.idx() == i2.idx()) {
+ i1.cell().erase(i1.pos(), i2.pos());
+ } else {
+ MathInset * p = i1.asMathInset();
+ row_type r1, r2;
+ col_type c1, c2;
+ region(i1, i2, r1, r2, c1, c2);
+ for (row_type row = r1; row <= r2; ++row)
+ for (col_type col = c1; col <= c2; ++col)
+ p->cell(p->index(row, col)).clear();
+ }
+ back() = i1;
+ } else {
+ lyxerr << "can't erase this selection 1" << endl;
+ }
+ //lyxerr << "LCursor::eraseSelection end" << endl;
+}
+
+
+string LCursor::grabAndEraseSelection()
+{
+ if (!selection())
+ return string();
+ string res = grabSelection();
+ eraseSelection();
+ selection() = false;
+ return res;
+}
+
+
+void LCursor::selCopy()
+{
+ if (selection()) {
+ theCutBuffer.push(grabSelection());
+ selection() = false;
+ } else {
+ //theCutBuffer.erase();
+ }
+}
+
+
+void LCursor::selCut()
+{
+ theCutBuffer.push(grabAndEraseSelection());
+}
+
+
+void LCursor::selDel()
+{
+ //lyxerr << "LCursor::selDel" << endl;
+ if (selection()) {
+ eraseSelection();
+ selection() = false;
+ }
+}
+
+
+void LCursor::selPaste(size_t n)
+{
+ selClearOrDel();
+ if (n < theCutBuffer.size())
+ paste(theCutBuffer[n]);
+ //grabSelection();
+ selection() = false;
+}
+
+
+void LCursor::selHandle(bool sel)
+{
+ //lyxerr << "LCursor::selHandle" << endl;
+ if (sel == selection()) {
+#warning Alfredo: This is too strong (Andre)
+ //if (!sel)
+ // noUpdate();
+ return;
+ }
+
+ resetAnchor();
+ selection() = sel;
+}
+
+
+void LCursor::selClearOrDel()
+{
+ //lyxerr << "LCursor::selClearOrDel" << endl;
+ if (lyxrc.auto_region_delete)
+ selDel();
+ else
+ selection() = false;
+}
+
+
+std::ostream & operator<<(std::ostream & os, LCursor const & cur)
+{
+ for (size_t i = 0, n = cur.size(); i != n; ++i) {
+ os << " " << cur.operator[](i) << " | ";
+ if (i < cur.anchor_.size())
+ os << cur.anchor_[i];
+ else
+ os << "-------------------------------";
+ os << "\n";
+ }
+ for (size_t i = cur.size(), n = cur.anchor_.size(); i < n; ++i) {
+ os << "------------------------------- | " << cur.anchor_[i] << "\n";
+ }
+ os << " selection: " << cur.selection_
+ << " x_target: " << cur.x_target_ << endl;
+ return os;
+}
+
+
+
+
+///////////////////////////////////////////////////////////////////
+//
+// The part below is the non-integrated rest of the original math
+// cursor. This should be either generalized for texted or moved
+// back to mathed (in most cases to MathNestInset).
+//
+///////////////////////////////////////////////////////////////////
+
+#include "mathed/math_charinset.h"
+#include "mathed/math_factory.h"
+#include "mathed/math_gridinset.h"
+#include "mathed/math_macroarg.h"
+#include "mathed/math_mathmlstream.h"
+#include "mathed/math_scriptinset.h"
+#include "mathed/math_support.h"
+#include "mathed/math_unknowninset.h"
+
+//#define FILEDEBUG 1
+
+
+bool LCursor::isInside(InsetBase const * p)
+{
+ for (unsigned i = 0; i < depth(); ++i)
+ if (&operator[](i).inset() == p)