Index: mathed/MathMacroTable.C
===================================================================
--- mathed/MathMacroTable.C	(Revision 17835)
+++ mathed/MathMacroTable.C	(Arbeitskopie)
@@ -36,12 +36,12 @@
 
 
 MacroData::MacroData()
-	: numargs_(0)
+	: numargs_(0), lockCount_(0)
 {}
 
 
 MacroData::MacroData(docstring const & def, int numargs, docstring const & disp, string const & requires)
-	: def_(def), numargs_(numargs), disp_(disp), requires_(requires)
+	: def_(def), numargs_(numargs), disp_(disp), requires_(requires), lockCount_(0)
 {}
 
 
Index: mathed/MathMacroTemplate.C
===================================================================
--- mathed/MathMacroTemplate.C	(Revision 17835)
+++ mathed/MathMacroTemplate.C	(Arbeitskopie)
@@ -111,6 +111,10 @@
 
 bool MathMacroTemplate::metrics(MetricsInfo & mi, Dimension & dim) const
 {
+	bool lockMacro = MacroTable::globalMacros().has(name_);
+	if (lockMacro)
+		MacroTable::globalMacros().get(name_).lock();
+
 	cell(0).metrics(mi);
 	cell(1).metrics(mi);
 	docstring dp = prefix();
@@ -118,6 +122,10 @@
 		+ theFontMetrics(mi.base.font).width(dp);
 	dim.asc = std::max(cell(0).ascent(),  cell(1).ascent())  + 7;
 	dim.des = std::max(cell(0).descent(), cell(1).descent()) + 7;
+	
+	if (lockMacro)
+		MacroTable::globalMacros().get(name_).unlock();
+	
 	if (dim_ == dim)
 		return false;
 	dim_ = dim;
@@ -127,6 +135,10 @@
 
 void MathMacroTemplate::draw(PainterInfo & p, int x, int y) const
 {
+	bool lockMacro = MacroTable::globalMacros().has(name_);
+	if (lockMacro)
+		MacroTable::globalMacros().get(name_).lock();
+	
 	setPosCache(p, x, y);
 
 	// label
@@ -167,6 +179,9 @@
 	cell(1).draw(pi, x + 8 + w0, y + 1);
 	pi.pain.rectangle(x + w0 + 6, y - dim_.ascent() + 3,
 		w1 + 4, dim_.height() - 6, LColor::mathline);
+	
+	if (lockMacro)
+		MacroTable::globalMacros().get(name_).unlock();
 }
 
 
Index: mathed/MathMacroTable.h
===================================================================
--- mathed/MathMacroTable.h	(Revision 17835)
+++ mathed/MathMacroTable.h	(Arbeitskopie)
@@ -40,6 +40,12 @@
 	std::string requires() const { return requires_; }
 	///
 	std::string & requires() { return requires_; }
+	/// lock while being drawn
+	int lock() const { return ++lockCount_; }
+	/// is it being drawn?
+	bool locked() const { return lockCount_!=0; }
+	///
+	void unlock() const { --lockCount_; assert(lockCount_>=0); } 	
 
 private:
 	///
@@ -50,6 +56,8 @@
 	docstring disp_;
 	///
 	std::string requires_;
+	///
+	mutable int lockCount_;
 };
 
 
Index: mathed/InsetMathMacro.C
===================================================================
--- mathed/InsetMathMacro.C	(Revision 17835)
+++ mathed/InsetMathMacro.C	(Arbeitskopie)
@@ -33,6 +33,54 @@
 using std::vector;
 
 
+/// This class is the value of a macro argument, technically 
+/// a wrapper of the cells of MathMacro.
+class MathMacroArgumentValue : public InsetMathDim {
+public:
+	///
+	MathMacroArgumentValue(MathArray const * value, docstring const & macroName) 
+		: value_(value), macroName_(macroName) {}
+	///
+	bool metrics(MetricsInfo & mi, Dimension & dim) const;
+	///
+	void draw(PainterInfo &, int x, int y) const;
+	
+private:
+	std::auto_ptr<InsetBase> doClone() const;
+	MathArray const * value_;
+	docstring macroName_;
+};
+
+
+auto_ptr<InsetBase> MathMacroArgumentValue::doClone() const 
+{
+	return auto_ptr<InsetBase>(new MathMacroArgumentValue(*this));
+}
+
+
+bool MathMacroArgumentValue::metrics(MetricsInfo & mi, Dimension & dim) const 
+{
+	// unlock outer macro in arguments, and lock it again later
+	MacroTable::globalMacros().get(macroName_).unlock();
+	value_->metrics(mi, dim);
+	MacroTable::globalMacros().get(macroName_).lock();
+	metricsMarkers2(dim);
+	if (dim_ == dim)
+		return false;
+	dim_ = dim;
+	return true;
+}
+
+
+void MathMacroArgumentValue::draw(PainterInfo & pi, int x, int y) const 
+{
+	// unlock outer macro in arguments, and lock it again later
+	MacroTable::globalMacros().get(macroName_).unlock();
+	value_->draw(pi, x, y);
+	MacroTable::globalMacros().get(macroName_).lock();
+}
+
+
 MathMacro::MathMacro(docstring const & name, int numargs)
 	: InsetMathNest(numargs), name_(name)
 {}
@@ -63,25 +111,39 @@
 {
 	if (!MacroTable::globalMacros().has(name())) {
 		mathed_string_dim(mi.base.font, "Unknown: " + name(), dim);
-	} else if (editing(mi.base.bv)) {
-		// FIXME UNICODE
-		asArray(MacroTable::globalMacros().get(name()).def(), tmpl_);
-		LyXFont font = mi.base.font;
-		augmentFont(font, from_ascii("lyxtex"));
-		tmpl_.metrics(mi, dim);
-		// FIXME UNICODE
-		dim.wid += mathed_string_width(font, name()) + 10;
-		// FIXME UNICODE
-		int ww = mathed_string_width(font, from_ascii("#1: "));
-		for (idx_type i = 0; i < nargs(); ++i) {
-			MathArray const & c = cell(i);
-			c.metrics(mi);
-			dim.wid  = max(dim.wid, c.width() + ww);
-			dim.des += c.height() + 10;
+	} else {
+		MacroData const & macro = MacroTable::globalMacros().get(name());
+		if (macro.locked()) {
+			mathed_string_dim(mi.base.font, "Self reference: " + name(), dim);
+			expanded_ = MathArray();
+		} else if (editing(mi.base.bv)) {
+			// FIXME UNICODE
+			asArray(macro.def(), tmpl_);
+			LyXFont font = mi.base.font;
+			augmentFont(font, from_ascii("lyxtex"));
+			tmpl_.metrics(mi, dim);
+			// FIXME UNICODE
+			dim.wid += mathed_string_width(font, name()) + 10;
+			// FIXME UNICODE
+			int ww = mathed_string_width(font, from_ascii("#1: "));
+			for (idx_type i = 0; i < nargs(); ++i) {
+				MathArray const & c = cell(i);
+				c.metrics(mi);
+				dim.wid  = max(dim.wid, c.width() + ww);
+				dim.des += c.height() + 10;
+			}
+		} else {
+			// create MathMacroArgumentValue object pointing to the cells of the macro
+			MacroData const & macro = MacroTable::globalMacros().get(name());
+			vector<MathArray> values(nargs());
+			for (size_t i = 0; i != nargs(); ++i) 
+				values[i].insert(0, MathAtom(new MathMacroArgumentValue(&cells_[i], name())));
+			macro.expand(values, expanded_);
+			
+			MacroTable::globalMacros().get(name()).lock();
+			expanded_.metrics(mi, dim);
+			MacroTable::globalMacros().get(name()).unlock();
 		}
-	} else {
-		MacroTable::globalMacros().get(name()).expand(cells_, expanded_);
-		expanded_.metrics(mi, dim);
 	}
 	metricsMarkers2(dim);
 	if (dim_ == dim)
@@ -96,28 +158,36 @@
 	if (!MacroTable::globalMacros().has(name())) {
 		// FIXME UNICODE
 		drawStrRed(pi, x, y, "Unknown: " + name());
-	} else if (editing(pi.base.bv)) {
-		LyXFont font = pi.base.font;
-		augmentFont(font, from_ascii("lyxtex"));
-		int h = y - dim_.ascent() + 2 + tmpl_.ascent();
-		pi.pain.text(x + 3, h, name(), font);
-		int const w = mathed_string_width(font, name());
-		tmpl_.draw(pi, x + w + 12, h);
-		h += tmpl_.descent();
-		Dimension ldim;
-		docstring t = from_ascii("#1: ");
-		mathed_string_dim(font, t, ldim);
-		for (idx_type i = 0; i < nargs(); ++i) {
-			MathArray const & c = cell(i);
-			h += max(c.ascent(), ldim.asc) + 5;
-			c.draw(pi, x + ldim.wid, h);
-			char_type str[] = { '#', '1', ':', '\0' };
-			str[1] += static_cast<char_type>(i);
-			pi.pain.text(x + 3, h, str, font);
-			h += max(c.descent(), ldim.des) + 5;
+	} else {
+		MacroData const & macro = MacroTable::globalMacros().get(name());
+		if (macro.locked()) {
+			// FIXME UNICODE
+			drawStrRed(pi, x, y, "Self reference: " + name());
+		} else if (editing(pi.base.bv)) {
+			LyXFont font = pi.base.font;
+			augmentFont(font, from_ascii("lyxtex"));
+			int h = y - dim_.ascent() + 2 + tmpl_.ascent();
+			pi.pain.text(x + 3, h, name(), font);
+			int const w = mathed_string_width(font, name());
+			tmpl_.draw(pi, x + w + 12, h);
+			h += tmpl_.descent();
+			Dimension ldim;
+			string t = "#1: ";
+			mathed_string_dim(font, name(), ldim);
+			for (idx_type i = 0; i < nargs(); ++i) {
+				MathArray const & c = cell(i);
+				h += max(c.ascent(), ldim.asc) + 5;
+				c.draw(pi, x + ldim.wid, h);
+				char_type str[] = { '#', '1', ':', '\0' };
+				str[1] += static_cast<char_type>(i);
+				pi.pain.text(x + 3, h, str, font);
+				h += max(c.descent(), ldim.des) + 5;
+			}
+		} else {
+			MacroTable::globalMacros().get(name()).lock();
+			expanded_.draw(pi, x, y);
+			MacroTable::globalMacros().get(name()).unlock();
 		}
-	} else {
-		expanded_.draw(pi, x, y);
 	}
 	drawMarkers2(pi, x, y);
 }
