text:
var Class = require("./Class");
eval(Class.$import("./classdef"));
eval(Class.$import("./type"));
eval(Class.$import("./expression"));
eval(Class.$import("./statement"));
eval(Class.$import("./emitter"));
eval(Class.$import("./jssourcemap"));
eval(Class.$import("./util"));

"use strict";

var _Util = exports._Util = Class.extend({

	$toClosureType: function (type) {
		if (type.equals(Type.booleanType)) {
			return "!boolean";
		} else if (type.equals(Type.integerType) || type.equals(Type.numberType)) {
			return "!number";
		} else if (type.equals(Type.stringType)) {
			return "!string";
		} else if (type instanceof MayBeUndefinedType) {
			return "undefined|" + this.toClosureType(type.getBaseType());
		} else if (type instanceof ObjectType) {
			var classDef = type.getClassDef();
			if (classDef instanceof InstantiatedClassDefinition && classDef.getTemplateClassName() == "Array") {
				return "Array.<undefined|" + this.toClosureType(classDef.getTypeArguments()[0]) + ">";
			} else if (classDef instanceof InstantiatedClassDefinition && classDef.getTemplateClassName() == "Map") {
				return "Object.<string, undefined|" + this.toClosureType(classDef.getTypeArguments()[0]) + ">";
			} else {
				return classDef.getOutputClassName();
			}
		} else if (type instanceof VariantType) {
			return "*";
		}
		return null;
	},

	$getInstanceofNameFromClassDef: function (classDef) {
		if (classDef instanceof InstantiatedClassDefinition) {
			var name = classDef.getTemplateClassName();
			if (name == "Map")
				name = "Object";
		} else {
			name = classDef.getOutputClassName();
		}
		return name;
	},

	$buildAnnotation: function (template, type) {
		var closureType = this.toClosureType(type);
		if (closureType == null)
			return "";
		return Util.format(template, [closureType]);
	},

	$emitLabelOfStatement: function (emitter, statement) {
		var label = statement.getLabel();
		if (label != null) {
			emitter._reduceIndent();
			emitter._emit(label.getValue() + ":\n", label);
			emitter._advanceIndent();
		}
	}

});

// statement emitter

var _StatementEmitter = exports._StatementEmitter = Class.extend({

	constructor: function (emitter) {
		this._emitter = emitter;
	}

});

var _ConstructorInvocationStatementEmitter = exports._ConstructorInvocationStatementEmitter = _StatementEmitter.extend({

	constructor: function (emitter, statement) {
		_StatementEmitter.prototype.constructor.call(this, emitter);
		this._statement = statement;
	},

	emit: function () {
		var ctorType = this._statement.getConstructorType();
		var argTypes = ctorType != null ? ctorType.getArgumentTypes() : [];
		var ctorName = this._emitter._mangleConstructorName(this._statement.getConstructingClassDef(), argTypes);
		var token = this._statement.getQualifiedName().getToken();
		if (ctorName == "Error" && this._statement.getArguments().length == 1) {
			/*
				At least v8 does not support "Error.call(this, message)"; it not only does not setup the stacktrace but also does
				not set the message property.  So we set the message property.
				We continue to call "Error" hoping that it would have some positive effect on other platforms (like setting the
				stacktrace, etc.).

				FIXME check that doing  "Error.call(this);" does not have any negative effect on other platforms
			*/
			this._emitter._emit("Error.call(this);\n", token);
			this._emitter._emit("this.message = ", token);
			this._emitter._getExpressionEmitterFor(this._statement.getArguments()[0]).emit(_BinaryExpressionEmitter._operatorPrecedence["="]);
		} else {
			this._emitter._emitCallArguments(token, ctorName + ".call(this", this._statement.getArguments(), argTypes);
			this._emitter._emit(";\n", token);
		}
	}

});

var _ExpressionStatementEmitter = exports._ExpressionStatementEmitter = _StatementEmitter.extend({

	constructor: function (emitter, statement) {
		_StatementEmitter.prototype.constructor.call(this, emitter);
		this._statement = statement;
	},

	emit: function () {
		this._emitter._getExpressionEmitterFor(this._statement.getExpr()).emit(0);
		this._emitter._emit(";\n", null);
	}

});

var _ReturnStatementEmitter = exports._ReturnStatementEmitter = _StatementEmitter.extend({

	constructor: function (emitter, statement) {
		_StatementEmitter.prototype.constructor.call(this, emitter);
		this._statement = statement;
	},

	emit: function () {
		var expr = this._statement.getExpr();
		if (expr != null) {
			this._emitter._emit("return ", null);
			this._emitter._getExpressionEmitterFor(this._statement.getExpr()).emit(0);
			this._emitter._emit(";\n", null);
		} else {
			this._emitter._emit("return;\n", this._statement.getToken());
		}
	}

});

var _DeleteStatementEmitter = exports._DeleteStatementEmitter = _StatementEmitter.extend({

	constructor: function (emitter, statement) {
		_StatementEmitter.prototype.constructor.call(this, emitter);
		this._statement = statement;
	},

	emit: function () {
		this._emitter._emit("delete ", this._statement.getToken());
		this._emitter._getExpressionEmitterFor(this._statement.getExpr()).emit(0);
		this._emitter._emit(";\n", null);
	}

});

var _BreakStatementEmitter = exports._BreakStatementEmitter = _StatementEmitter.extend({

	constructor: function (emitter, statement) {
		_StatementEmitter.prototype.constructor.call(this, emitter);
		this._statement = statement;
	},

	emit: function () {
		if (this._statement.getLabel() != null)
			this._emitter._emit("break " + this._statement.getLabel().getValue() + ";\n", this._statement.getToken());
		else
			this._emitter._emit("break;\n", this._statement.getToken());
	}

});

var _ContinueStatementEmitter = exports._ContinueStatementEmitter = _StatementEmitter.extend({

	constructor: function (emitter, statement) {
		_StatementEmitter.prototype.constructor.call(this, emitter);
		this._statement = statement;
	},

	emit: function () {
		if (this._statement.getLabel() != null)
			this._emitter._emit("continue " + this._statement.getLabel().getValue() + ";\n", this._statement.getToken());
		else
			this._emitter._emit("continue;\n", this._statement.getToken());
	}

});

var _DoWhileStatementEmitter = exports._DoWhileStatementEmitter = _StatementEmitter.extend({

	constructor: function (emitter, statement) {
		_StatementEmitter.prototype.constructor.call(this, emitter);
		this._statement = statement;
	},

	emit: function () {
		_Util.emitLabelOfStatement(this._emitter, this._statement);
		this._emitter._emit("do {\n", null);
		this._emitter._emitStatements(this._statement.getStatements());
		this._emitter._emit("} while (", null);
		this._emitter._getExpressionEmitterFor(this._statement.getExpr()).emit(0);
		this._emitter._emit(");\n", null);
	}

});

var _ForInStatementEmitter = exports._ForInStatementEmitter = _StatementEmitter.extend({

	constructor: function (emitter, statement) {
		_StatementEmitter.prototype.constructor.call(this, emitter);
		this._statement = statement;
	},

	emit: function () {
		_Util.emitLabelOfStatement(this._emitter, this._statement);
		this._emitter._emit("for (", null);
		this._emitter._getExpressionEmitterFor(this._statement.getLHSExpr()).emit(0);
		this._emitter._emit(" in ", null);
		this._emitter._getExpressionEmitterFor(this._statement.getListExpr()).emit(0);
		this._emitter._emit(") {\n", null);
		this._emitter._emitStatements(this._statement.getStatements());
		this._emitter._emit("}\n", null);
	}

});

var _ForStatementEmitter = exports._ForStatementEmitter = _StatementEmitter.extend({

	constructor: function (emitter, statement) {
		_StatementEmitter.prototype.constructor.call(this, emitter);
		this._statement = statement;
	},

	emit: function () {
		_Util.emitLabelOfStatement(this._emitter, this._statement);
		this._emitter._emit("for (", null);
		var initExpr = this._statement.getInitExpr();
		if (initExpr != null)
			this._emitter._getExpressionEmitterFor(initExpr).emit(0);
		this._emitter._emit("; ", null);
		var condExpr = this._statement.getCondExpr();
		if (condExpr != null)
			this._emitter._getExpressionEmitterFor(condExpr).emit(0);
		this._emitter._emit("; ", null);
		var postExpr = this._statement.getPostExpr();
		if (postExpr != null)
			this._emitter._getExpressionEmitterFor(postExpr).emit(0);
		this._emitter._emit(") {\n", null);
		this._emitter._emitStatements(this._statement.getStatements());
		this._emitter._emit("}\n", null);
	}

});

var _IfStatementEmitter = exports._IfStatementEmitter = _StatementEmitter.extend({

	constructor: function (emitter, statement) {
		_StatementEmitter.prototype.constructor.call(this, emitter);
		this._statement = statement;
	},

	emit: function () {
		this._emitter._emit("if (", null);
		this._emitter._getExpressionEmitterFor(this._statement.getExpr()).emit(0);
		this._emitter._emit(") {\n", null);
		this._emitter._emitStatements(this._statement.getOnTrueStatements());
		var ifFalseStatements = this._statement.getOnFalseStatements();
		if (ifFalseStatements.length != 0) {
			this._emitter._emit("} else {\n", null);
			this._emitter._emitStatements(ifFalseStatements);
		}
		this._emitter._emit("}\n", null);
	}

});

var _SwitchStatementEmitter = exports._SwitchStatementEmitter = _StatementEmitter.extend({

	constructor: function (emitter, statement) {
		_StatementEmitter.prototype.constructor.call(this, emitter);
		this._statement = statement;
	},

	emit: function () {
		_Util.emitLabelOfStatement(this._emitter, this._statement);
		this._emitter._emit("switch (", null);
		var expr = this._statement.getExpr();
		if (this._emitter._enableRunTimeTypeCheck && expr.getType() instanceof MayBeUndefinedType) {
			this._emitter._emitExpressionWithUndefinedAssertion(expr);
		} else {
			this._emitter._getExpressionEmitterFor(expr).emit(0);
		}
		this._emitter._emit(") {\n", null);
		this._emitter._emitStatements(this._statement.getStatements());
		this._emitter._emit("}\n", null);
	}

});

var _CaseStatementEmitter = exports._CaseStatementEmitter = _StatementEmitter.extend({

	constructor: function (emitter, statement) {
		_StatementEmitter.prototype.constructor.call(this, emitter);
		this._statement = statement;
	},

	emit: function () {
		this._emitter._reduceIndent();
		this._emitter._emit("case ", null);
		var expr = this._statement.getExpr();
		if (this._emitter._enableRunTimeTypeCheck && expr.getType() instanceof MayBeUndefinedType) {
			this._emitter._emitExpressionWithUndefinedAssertion(expr);
		} else {
			this._emitter._getExpressionEmitterFor(expr).emit(0);
		}
		this._emitter._emit(":\n", null);
		this._emitter._advanceIndent();
	}

});

var _DefaultStatementEmitter = exports._DefaultStatementEmitter = _StatementEmitter.extend({

	constructor: function (emitter, statement) {
		_StatementEmitter.prototype.constructor.call(this, emitter);
		this._statement = statement;
	},

	emit: function () {
		this._emitter._reduceIndent();
		this._emitter._emit("default:\n", null);
		this._emitter._advanceIndent();
	}

});

var _WhileStatementEmitter = exports._WhileStatementEmitter = _StatementEmitter.extend({

	constructor: function (emitter, statement) {
		_StatementEmitter.prototype.constructor.call(this, emitter);
		this._statement = statement;
	},

	emit: function () {
		_Util.emitLabelOfStatement(this._emitter, this._statement);
		this._emitter._emit("while (", null);
		this._emitter._getExpressionEmitterFor(this._statement.getExpr()).emit(0);
		this._emitter._emit(") {\n", null);
		this._emitter._emitStatements(this._statement.getStatements());
		this._emitter._emit("}\n", null);
	}

});

var _TryStatementEmitter = exports._TryStatementEmitter = _StatementEmitter.extend({

	constructor: function (emitter, statement) {
		_StatementEmitter.prototype.constructor.call(this, emitter);
		this._statement = statement;
		var outerCatchStatements = 0;
		for (var i = 0; i < this._emitter._emittingStatementStack.length; ++i) {
			if (this._emitter._emittingStatementStack[i] instanceof _TryStatementEmitter)
				++outerCatchStatements;
		}
		this._emittingLocalName = "$__jsx_catch_" + outerCatchStatements;
	},

	emit: function () {
		this._emitter._emit("try {\n", this._statement.getToken());
		this._emitter._emitStatements(this._statement.getTryStatements());
		this._emitter._emit("}", null);
		var catchStatements = this._statement.getCatchStatements();
		if (catchStatements.length != 0) {
			this._emitter._emit(" catch (" + this._emittingLocalName + ") {\n", null);
			this._emitter._emitStatements(catchStatements);
			if (! catchStatements[catchStatements.length - 1].getLocal().getType().equals(Type.variantType)) {
				this._emitter._advanceIndent();
				this._emitter._emit("{\n", null);
				this._emitter._advanceIndent();
				this._emitter._emit("throw " + this._emittingLocalName + ";\n", null);
				this._emitter._reduceIndent();
				this._emitter._emit("}\n", null);
				this._emitter._reduceIndent();
			}
			this._emitter._emit("}", null);
		}
		var finallyStatements = this._statement.getFinallyStatements();
		if (finallyStatements.length != 0) {
			this._emitter._emit(" finally {\n", null);
			this._emitter._emitStatements(finallyStatements);
			this._emitter._emit("}", null);
		}
		this._emitter._emit("\n", null);
	},

	getEmittingLocalName: function () {
		return this._emittingLocalName;
	}

});

var _CatchStatementEmitter = exports._CatchStatementEmitter = _StatementEmitter.extend({

	constructor: function (emitter, statement) {
		_StatementEmitter.prototype.constructor.call(this, emitter);
		this._statement = statement;
	},

	emit: function () {
		var localType = this._statement.getLocal().getType();
		if (localType instanceof ObjectType) {
			var tryStatement = this._emitter._emittingStatementStack[this._emitter._emittingStatementStack.length - 2];
			var localName = tryStatement.getEmittingLocalName();
			this._emitter._emit("if (" + localName + " instanceof " + localType.getClassDef().getOutputClassName() + ") {\n", this._statement.getToken());
			this._emitter._emitStatements(this._statement.getStatements());
			this._emitter._emit("} else ", null);
		} else {
			this._emitter._emit("{\n", null);
			this._emitter._emitStatements(this._statement.getStatements());
			this._emitter._emit("}\n", null);
		}
	},

	$getLocalNameFor: function (emitter, name) {
		for (var i = emitter._emittingStatementStack.length - 1; i >= 0; --i) {
			if (! (emitter._emittingStatementStack[i] instanceof _CatchStatementEmitter))
				continue;
			var catchStatement = emitter._emittingStatementStack[i];
			if (catchStatement._statement.getLocal().getName().getValue() == name) {
				var tryEmitter = emitter._emittingStatementStack[i - 1];
				if (! (tryEmitter instanceof _TryStatementEmitter))
					throw new Error("logic flaw");
				return tryEmitter.getEmittingLocalName();
			}
		}
		throw new Error("logic flaw");
	}

});

var _ThrowStatementEmitter = exports._ThrowStatementEmitter = _StatementEmitter.extend({

	constructor: function (emitter, statement) {
		_StatementEmitter.prototype.constructor.call(this, emitter);
		this._statement = statement;
	},

	emit: function () {
		this._emitter._emit("throw ", this._statement.getToken());
		this._emitter._getExpressionEmitterFor(this._statement.getExpr()).emit(0);
		this._emitter._emit(";\n", null);
	}

});

var _AssertStatementEmitter = exports._AssertStatementEmitter = _StatementEmitter.extend({

	constructor: function (emitter, statement) {
		_StatementEmitter.prototype.constructor.call(this, emitter);
		this._statement = statement;
	},

	emit: function () {
		var condExpr = this._statement._expr;
		this._emitter._emitAssertion(function () {
			this._emitter._getExpressionEmitterFor(condExpr).emit(0);
		}.bind(this), this._statement.getToken(), "assertion failure");
	}

});

var _LogStatementEmitter = exports._LogStatementEmitter = _StatementEmitter.extend({

	constructor: function (emitter, statement) {
		_StatementEmitter.prototype.constructor.call(this, emitter);
		this._statement = statement;
	},

	emit: function () {
		this._emitter._emit("console.log(", null);
		var exprs = this._statement.getExprs();
		for (var i = 0; i < exprs.length; ++i) {
			if (i != 0)
				this._emitter._emit(", ", null);
			this._emitter._getExpressionEmitterFor(exprs[i]).emit(0);
		}
		this._emitter._emit(");\n", null);
	}

});

var _DebuggerStatementEmitter = exports._DebuggerStatementEmitter = _StatementEmitter.extend({

	constructor: function (emitter, statement) {
		_StatementEmitter.prototype.constructor.call(this, emitter);
		this._statement = statement;
	},

	emit: function () {
		this._emitter._emit("debugger;\n", this._statement.getToken());
	}

});

// expression emitter

var _ExpressionEmitter = exports._ExpressionEmitter = Class.extend({

	constructor: function (emitter) {
		this._emitter = emitter;
	},

	emitWithPrecedence: function (outerOpPrecedence, precedence, callback) {
		if (precedence > outerOpPrecedence) {
			this._emitter._emit("(", null);
			callback();
			this._emitter._emit(")", null);
		} else {
			callback();
		}
	}

});

var _IdentifierExpressionEmitter = exports._IdentifierExpressionEmitter = _ExpressionEmitter.extend({

	constructor: function (emitter, expr) {
		_ExpressionEmitter.prototype.constructor.call(this, emitter);
		this._expr = expr;
	},

	emit: function (outerOpPrecedence) {
		var type = this._expr.getType();
		if (type instanceof ClassDefType) {
			this._emitter._emit(type.getClassDef().getOutputClassName(), null);
		} else {
			var local = this._expr.getLocal();
			var localName = local.getName().getValue();
			if (local instanceof CaughtVariable) {
				localName = _CatchStatementEmitter.getLocalNameFor(this._emitter, localName);
			}
			this._emitter._emit(localName, this._expr.getToken());
		}
	}

});

var _UndefinedExpressionEmitter = exports._UndefinedExpressionEmitter = _ExpressionEmitter.extend({

	constructor: function (emitter, expr) {
		_ExpressionEmitter.prototype.constructor.call(this, emitter);
		this._expr = expr;
	},

	emit: function (outerOpPrecedence) {
		var token = this._expr.getToken();
		this._emitter._emit("undefined", token);
	}

});

var _NullExpressionEmitter = exports._NullExpressionEmitter = _ExpressionEmitter.extend({

	constructor: function (emitter, expr) {
		_ExpressionEmitter.prototype.constructor.call(this, emitter);
		this._expr = expr;
	},

	emit: function (outerOpPrecedence) {
		var token = this._expr.getToken();
		this._emitter._emit("null", token);
	}

});

var _BooleanLiteralExpressionEmitter = exports._BooleanLiteralExpressionEmitter = _ExpressionEmitter.extend({

	constructor: function (emitter, expr) {
		_ExpressionEmitter.prototype.constructor.call(this, emitter);
		this._expr = expr;
	},

	emit: function (outerOpPrecedence) {
		var token = this._expr.getToken();
		this._emitter._emit(token.getValue(), token);
	}

});

var _IntegerLiteralExpressionEmitter = exports._IntegerLiteralExpressionEmitter = _ExpressionEmitter.extend({

	constructor: function (emitter, expr) {
		_ExpressionEmitter.prototype.constructor.call(this, emitter);
		this._expr = expr;
	},

	emit: function (outerOpPrecedence) {
		var token = this._expr.getToken();
		this._emitter._emit("" + token.getValue(), token);
	}

});

var _NumberLiteralExpressionEmitter = exports._NumberLiteralExpressionEmitter = _ExpressionEmitter.extend({

	constructor: function (emitter, expr) {
		_ExpressionEmitter.prototype.constructor.call(this, emitter);
		this._expr = expr;
	},

	emit: function (outerOpPrecedence) {
		var token = this._expr.getToken();
		var str = token.getValue();
		if (outerOpPrecedence == _PropertyExpressionEmitter._operatorPrecedence && str.indexOf(".") == -1) {
			this._emitter._emit("(" + token.getValue() + ")", token);
		} else {
			this._emitter._emit("" + token.getValue(), token);
		}
	}

});

var _StringLiteralExpressionEmitter = exports._StringLiteralExpressionEmitter = _ExpressionEmitter.extend({

	constructor: function (emitter, expr) {
		_ExpressionEmitter.prototype.constructor.call(this, emitter);
		this._expr = expr;
	},

	emit: function (outerOpPrecedence) {
		var token = this._expr.getToken();
		// FIXME escape
		this._emitter._emit(token.getValue(), token);
	}

});

var _RegExpLiteralExpressionEmitter = exports._RegExpLiteralExpressionEmitter = _ExpressionEmitter.extend({

	constructor: function (emitter, expr) {
		_ExpressionEmitter.prototype.constructor.call(this, emitter);
		this._expr = expr;
	},

	emit: function (outerOpPrecedence) {
		var token = this._expr.getToken();
		this._emitter._emit(token.getValue(), token);
	}

});

var _ArrayLiteralExpressionEmitter = exports._ArrayLiteralExpressionEmitter = _ExpressionEmitter.extend({

	constructor: function (emitter, expr) {
		_ExpressionEmitter.prototype.constructor.call(this, emitter);
		this._expr = expr;
	},

	emit: function (outerOpPrecedence) {
		this._emitter._emit("[ ", null);
		var exprs = this._expr.getExprs();
		for (var i = 0; i < exprs.length; ++i) {
			if (i != 0)
				this._emitter._emit(", ", null);
			this._emitter._getExpressionEmitterFor(exprs[i]).emit(0);
		}
		this._emitter._emit(" ]", null);
	}

});

var _MapLiteralExpressionEmitter = exports._MapLiteralExpressionEmitter = _ExpressionEmitter.extend({

	constructor: function (emitter, expr) {
		_ExpressionEmitter.prototype.constructor.call(this, emitter);
		this._expr = expr;
	},

	emit: function (outerOpPrecedence) {
		this._emitter._emit("{ ", null);
		var elements = this._expr.getElements();
		for (var i = 0; i < elements.length; ++i) {
			var element = elements[i];
			if (i != 0)
				this._emitter._emit(", ", null);
			this._emitter._emit(element.getKey().getValue(), element.getKey());
			this._emitter._emit(": ", null);
			this._emitter._getExpressionEmitterFor(element.getExpr()).emit(0);
		}
		this._emitter._emit(" }", null);
	}

});

var _ThisExpressionEmitter = exports._ThisExpressionEmitter = _ExpressionEmitter.extend({

	constructor: function (emitter, expr) {
		_ExpressionEmitter.prototype.constructor.call(this, emitter);
		this._expr = expr;
	},

	emit: function (outerOpPrecedence) {
		var emittingFunction = this._emitter._emittingFunction;
		if ((emittingFunction.flags() & ClassDefinition.IS_STATIC) != 0)
			this._emitter._emit("$this", this._expr.getToken());
		else
			this._emitter._emit("this", this._expr.getToken());
	}

});

var _AsExpressionEmitter = exports._AsExpressionEmitter = _ExpressionEmitter.extend({

	constructor: function (emitter, expr) {
		_ExpressionEmitter.prototype.constructor.call(this, emitter);
		this._expr = expr;
	},

	emit: function (outerOpPrecedence) {
		var srcType = this._expr.getExpr().getType();
		var destType = this._expr.getType();
		if (srcType.resolveIfMayBeUndefined() instanceof ObjectType || srcType.equals(Type.variantType)) {
			if (srcType.resolveIfMayBeUndefined().isConvertibleTo(destType)) {
				if (srcType instanceof MayBeUndefinedType) {
					var prec = _BinaryExpressionEmitter._operatorPrecedence["||"];
					this._emitWithParens(outerOpPrecedence, prec, prec, null, "|| null");
				} else {
					this._emitter._getExpressionEmitterFor(this._expr.getExpr()).emit(outerOpPrecedence);
				}
				return true;
			}
			if (destType instanceof ObjectType) {
				// unsafe cast
				if ((destType.getClassDef().flags() & (ClassDefinition.IS_INTERFACE | ClassDefinition.IS_MIXIN)) == 0) {
					this.emitWithPrecedence(outerOpPrecedence, _CallExpressionEmitter._operatorPrecedence, (function () {
						this._emitter._emit("(function (o) { return o instanceof " + _Util.getInstanceofNameFromClassDef(destType.getClassDef()) + " ? o : null; })(", this._expr.getToken());
						this._emitter._getExpressionEmitterFor(this._expr.getExpr()).emit(0);
						this._emitter._emit(")", this._expr.getToken());
					}).bind(this));
				} else {
					this.emitWithPrecedence(outerOpPrecedence, _CallExpressionEmitter._operatorPrecedence, (function () {
						this._emitter._emit("(function (o) { return o && o.$__jsx_implements_" + destType.getClassDef().getOutputClassName() + " ? o : null; })(", this._expr.getToken());
						this._emitter._getExpressionEmitterFor(this._expr.getExpr()).emit(0);
						this._emitter._emit(")", this._expr.getToken());
					}).bind(this));
				}
				return true;
			}
			if (destType instanceof FunctionType) {
				// cast to function
				this._emitter._emit("(function (o) { return typeof(o) === \"function\" ? o : null; })(", this._expr.getToken());
				this._emitter._getExpressionEmitterFor(this._expr.getExpr()).emit(0);
				this._emitter._emit(")", this._expr.getToken());
				return true;
			}
		}
		if (srcType.equals(Type.nullType)) {
			// from null
			if (destType.equals(Type.booleanType)) {
				this._emitter._emit("false", this._expr.getToken());
				return true;
			}
			if (destType.equals(Type.integerType) || destType.equals(Type.numberType)) {
				this._emitter._emit("0", this._expr.getToken());
				return true;
			}
			if (destType.equals(Type.stringType)) {
				this._emitter._emit("\"null\"", this._expr.getToken());
				return true;
			}
			if (destType instanceof ObjectType || destType instanceof FunctionType) {
				this._emitter._emit("null", this._expr.getToken());
				return true;
			}
		}
		if (srcType.equals(Type.booleanType)) {
			// from boolean
			if (destType.equals(Type.integerType) || destType.equals(Type.numberType)) {
				var prec = _UnaryExpressionEmitter._operatorPrecedence["+"];
				this._emitWithParens(outerOpPrecedence, prec, prec, "+", null);
				return true;
			}
			if (destType.equals(Type.stringType)) {
				var prec = _BinaryExpressionEmitter._operatorPrecedence["+"];
				this._emitWithParens(outerOpPrecedence, prec, prec, null, " + \"\"");
				return true;
			}
		}
		if (srcType instanceof MayBeUndefinedType && srcType.getBaseType().equals(Type.booleanType)) {
			// from MayBeUndefined.<boolean>
			if (destType.equals(Type.booleanType)) {
				var prec = _BinaryExpressionEmitter._operatorPrecedence["||"];
				this._emitWithParens(outerOpPrecedence, prec, prec, null, " || false");
				return true;
			}
			if (destType.equals(Type.integerType) || destType.equals(Type.numberType)) {
				this._emitWithParens(
					outerOpPrecedence,
					_BinaryExpressionEmitter._operatorPrecedence["-"],
					_UnaryExpressionEmitter._operatorPrecedence["!"],
					"1 - ! ",
					null);
				return true;
			}
			if (destType.equals(Type.stringType)) {
				var prec = _BinaryExpressionEmitter._operatorPrecedence["+"];
				this._emitWithParens(outerOpPrecedence, prec, prec, null, " + \"\"");
				return true;
			}
		}
		if (srcType.equals(Type.integerType)) {
			// from integer
			if (destType.equals(Type.booleanType)) {
				var prec = _UnaryExpressionEmitter._operatorPrecedence["!"];
				this._emitWithParens(outerOpPrecedence, prec, prec, "!! ", null);
				return true;
			}
			if (destType.equals(Type.numberType)) {
				this._emitter._getExpressionEmitterFor(this._expr.getExpr()).emit(outerOpPrecedence);
				return true;
			}
			if (destType.equals(Type.stringType)) {
				var prec = _BinaryExpressionEmitter._operatorPrecedence["+"];
				this._emitWithParens(outerOpPrecedence, prec, prec, null, " + \"\"");
				return true;
			}
		}
		if (srcType instanceof MayBeUndefinedType && srcType.getBaseType().equals(Type.integerType)) {
			// from MayBeUndefined.<int>
			if (destType.equals(Type.booleanType)) {
				var prec = _UnaryExpressionEmitter._operatorPrecedence["!"];
				this._emitWithParens(outerOpPrecedence, prec, prec, "!! ", null);
				return true;
			}
			if (destType.equals(Type.integerType) || destType.equals(Type.numberType)) {
				var prec = _BinaryExpressionEmitter._operatorPrecedence["|"];
				this._emitWithParens(outerOpPrecedence, prec, prec, null, " | 0");
				return true;
			}
			if (destType.equals(Type.stringType)) {
				var prec = _BinaryExpressionEmitter._operatorPrecedence["+"];
				this._emitWithParens(outerOpPrecedence, prec, prec, null, " + \"\"");
				return true;
			}
		}
		if (srcType.equals(Type.numberType)) {
			// from number
			if (destType.equals(Type.booleanType)) {
				var prec = _UnaryExpressionEmitter._operatorPrecedence["!"];
				this._emitWithParens(outerOpPrecedence, prec, prec, "!! ", null);
				return true;
			}
			if (destType.equals(Type.integerType)) {
				var prec = _BinaryExpressionEmitter._operatorPrecedence["|"];
				this._emitWithParens(outerOpPrecedence, prec, prec, null, " | 0");
				return true;
			}
			if (destType.equals(Type.stringType)) {
				var prec = _BinaryExpressionEmitter._operatorPrecedence["+"];
				this._emitWithParens(outerOpPrecedence, prec, prec, null, " + \"\"");
				return true;
			}
		}
		if (srcType instanceof MayBeUndefinedType && srcType.getBaseType().equals(Type.numberType)) {
			// from MayBeUndefined.<number>
			if (destType.equals(Type.booleanType)) {
				var prec = _UnaryExpressionEmitter._operatorPrecedence["!"];
				this._emitWithParens(outerOpPrecedence, prec, prec, "!! ", null);
				return true;
			}
			if (destType.equals(Type.integerType)) {
				var prec = _BinaryExpressionEmitter._operatorPrecedence["|"];
				this._emitWithParens(outerOpPrecedence, prec, prec, null, " | 0");
				return true;
			}
			if (destType.equals(Type.numberType)) {
				var prec = _UnaryExpressionEmitter._operatorPrecedence["+"];
				this._emitWithParens(outerOpPrecedence, prec, prec, "+", null);
				return true;
			}
			if (destType.equals(Type.stringType)) {
				var prec = _BinaryExpressionEmitter._operatorPrecedence["+"];
				this._emitWithParens(outerOpPrecedence, prec, prec, null, " + \"\"");
				return true;
			}
		}
		if (srcType.equals(Type.stringType)) {
			// from String
			if (destType.equals(Type.booleanType)) {
				var prec = _UnaryExpressionEmitter._operatorPrecedence["!"];
				this._emitWithParens(outerOpPrecedence, prec, prec, "!! ", null);
				return true;
			}
			if (destType.equals(Type.integerType)) {
				var prec = _BinaryExpressionEmitter._operatorPrecedence["|"];
				this._emitWithParens(outerOpPrecedence, prec, prec, null, " | 0");
				return true;
			}
			if (destType.equals(Type.numberType)) {
				var prec = _UnaryExpressionEmitter._operatorPrecedence["+"];
				this._emitWithParens(outerOpPrecedence, prec, prec, "+", null);
				return true;
			}
		}
		if (srcType instanceof MayBeUndefinedType && srcType.getBaseType().equals(Type.stringType)) {
			// from MayBeUndefined.<String>
			if (destType.equals(Type.booleanType)) {
				var prec = _UnaryExpressionEmitter._operatorPrecedence["!"];
				this._emitWithParens(outerOpPrecedence, prec, prec, "!! ", null);
				return true;
			}
			if (destType.equals(Type.integerType)) {
				var prec = _BinaryExpressionEmitter._operatorPrecedence["|"];
				this._emitWithParens(outerOpPrecedence, prec, prec, null, " | 0");
				return true;
			}
			if (destType.equals(Type.numberType)) {
				var prec = _UnaryExpressionEmitter._operatorPrecedence["+"];
				this._emitWithParens(outerOpPrecedence, prec, prec, "+", null);
				return true;
			}
			if (destType.equals(Type.stringType)) {
				var prec = _BinaryExpressionEmitter._operatorPrecedence["+"];
				this._emitWithParens(outerOpPrecedence, prec, prec, null, " + \"\"");
				return true;
			}
		}
		if (srcType.equals(Type.variantType)) {
			// from variant
			if (destType.equals(Type.booleanType)) {
				var prec = _UnaryExpressionEmitter._operatorPrecedence["!"];
				this._emitWithParens(outerOpPrecedence, prec, prec, "!! ", null);
				return true;
			}
			if (destType.equals(Type.integerType)) {
				var prec = _BinaryExpressionEmitter._operatorPrecedence["|"];
				this._emitWithParens(outerOpPrecedence, prec, prec, null, " | 0");
				return true;
			}
			if (destType.equals(Type.numberType)) {
				var prec = _UnaryExpressionEmitter._operatorPrecedence["+"];
				this._emitWithParens(outerOpPrecedence, prec, prec, "+", null);
				return true;
			}
			if (destType.equals(Type.stringType)) {
				var prec = _BinaryExpressionEmitter._operatorPrecedence["+"];
				this._emitWithParens(outerOpPrecedence, prec, prec, null, " + \"\"");
				return true;
			}
		}
		if (srcType.isConvertibleTo(destType)) {
			// can perform implicit conversion
			this._emitter._getExpressionEmitterFor(this._expr.getExpr()).emit(outerOpPrecedence);
			return true;
		}
		throw new Error("explicit conversion logic unknown from " + srcType.toString() + " to " + destType.toString());
	},

	_emitWithParens: function (outerOpPrecedence, opPrecedence, innerOpPrecedence, prefix, postfix) {
		// in contrast to _ExpressionEmitter#emitWithPrecedence the comparison op. is >=, since the conversion should have higher precedence than the outer op. (see t/run/110)
		if (opPrecedence >= outerOpPrecedence)
			this._emitter._emit("(", null);
		if (prefix != null)
			this._emitter._emit(prefix, this._expr.getToken());
		this._emitter._getExpressionEmitterFor(this._expr.getExpr()).emit(innerOpPrecedence);
		if (postfix != null)
			this._emitter._emit(postfix, this._expr.getToken());
		if (opPrecedence >= outerOpPrecedence)
			this._emitter._emit(")", null);
	}

});

var _AsNoConvertExpressionEmitter = exports._AsNoConvertExpressionEmitter = _ExpressionEmitter.extend({

	constructor: function (emitter, expr) {
		_ExpressionEmitter.prototype.constructor.call(this, emitter);
		this._expr = expr;
	},

	emit: function (outerOpPrecedence) {
		if (this._emitter._enableRunTimeTypeCheck) {
			var emitWithAssertion = function (emitCheckExpr, message) {
				var token = this._expr.getToken();
				this._emitter._emit("(function (v) {\n", token);
				this._emitter._advanceIndent();
				this._emitter._emitAssertion(emitCheckExpr, token, message);
				this._emitter._emit("return v;\n", token);
				this._emitter._reduceIndent();
				this._emitter._emit("}(", token);
				this._emitter._getExpressionEmitterFor(this._expr.getExpr()).emit(0);
				this._emitter._emit("))", token);
			}.bind(this);
			var srcType = this._expr.getExpr().getType();
			var destType = this._expr.getType();
			if (srcType.equals(destType) || srcType.equals(destType.resolveIfMayBeUndefined)) {
				// skip
			} else if (destType instanceof VariantType) {
				// skip
			} else if (srcType instanceof ObjectType && srcType.isConvertibleTo(destType)) {
				// skip
			} else if (destType.equals(Type.booleanType)) {
				emitWithAssertion(function () {
					this._emitter._emit("typeof v === \"boolean\"", this._expr.getToken());
				}.bind(this), "detected invalid cast, value is not a boolean");
				return;
			} else if (destType.equals(Type.integerType) || destType.equals(Type.numberType)) {
				emitWithAssertion(function () {
					this._emitter._emit("typeof v === \"number\"", this._expr.getToken());
				}.bind(this), "detected invalid cast, value is not a number");
				return;
			} else if (destType.equals(Type.stringType)) {
				emitWithAssertion(function () {
					this._emitter._emit("typeof v === \"string\"", this._expr.getToken());
				}.bind(this), "detected invalid cast, value is not a string");
				return;
			} else if (destType instanceof FunctionType) {
				emitWithAssertion(function () {
					this._emitter._emit("v === null || typeof v === \"function\"", this._expr.getToken());
				}.bind(this), "detected invalid cast, value is not a function or null");
				return;
			} else if (destType instanceof ObjectType) {
				var destClassDef = destType.getClassDef();
				if ((destClassDef.flags() & ClassDefinition.IS_FAKE) != 0) {
					// skip
				} else if (destClassDef instanceof InstantiatedClassDefinition && destClassDef.getTemplateClassName() == "Array") {
					emitWithAssertion(function () {
						this._emitter._emit("v === null || v instanceof Array", this._expr.getToken());
					}.bind(this), "detected invalid cast, value is not an Array or null");
					return;
				} else if (destClassDef instanceof InstantiatedClassDefinition && destClassDef.getTemplateClassName() == "Map") {
					emitWithAssertion(function () {
						this._emitter._emit("v === null || typeof v === \"object\"", this._expr.getToken());
					}.bind(this), "detected invalid cast, value is not a Map or null");
					return;
				} else {
					emitWithAssertion(function () {
						this._emitter._emit("v === null || v instanceof " + destClassDef.getOutputClassName(), this._expr.getToken());
					}.bind(this), "detected invalid cast, value is not an instance of the designated type or null");
					return;
				}
			}
		}
		this._emitter._getExpressionEmitterFor(this._expr.getExpr()).emit(outerOpPrecedence);
		return;
	}

});

var _OperatorExpressionEmitter = exports._OperatorExpressionEmitter = _ExpressionEmitter.extend({

	constructor: function (emitter) {
		_ExpressionEmitter.prototype.constructor.call(this, emitter);
	},

	emit: function (outerOpPrecedence) {
		this.emitWithPrecedence(outerOpPrecedence, this._getPrecedence(), this._emit.bind(this));
	},

	_emit: null, // void emit()

	_getPrecedence: null // int _getPrecedence()

});

var _UnaryExpressionEmitter = exports._UnaryExpressionEmitter = _OperatorExpressionEmitter.extend({

	constructor: function (emitter, expr) {
		_OperatorExpressionEmitter.prototype.constructor.call(this, emitter);
		this._expr = expr;
	},

	_emit: function () {
		var opToken = this._expr.getToken();
		this._emitter._emit(opToken.getValue() + " ", opToken);
		this._emitter._getExpressionEmitterFor(this._expr.getExpr()).emit(this._getPrecedence());
	},

	_getPrecedence: function () {
		return _UnaryExpressionEmitter._operatorPrecedence[this._expr.getToken().getValue()];
	},

	$_operatorPrecedence: {},

	$_setOperatorPrecedence: function (op, precedence) {
		_UnaryExpressionEmitter._operatorPrecedence[op] = precedence;
	}

});

var _PostfixExpressionEmitter = exports._PostfixExpressionEmitter = _UnaryExpressionEmitter.extend({

	constructor: function (emitter, expr) {
		_UnaryExpressionEmitter.prototype.constructor.call(this, emitter, expr);
	},

	_emit: function () {
		var opToken = this._expr.getToken();
		this._emitter._getExpressionEmitterFor(this._expr.getExpr()).emit(this._getPrecedence());
		this._emitter._emit(opToken.getValue(), opToken);
	},

	_getPrecedence: function () {
		return _PostfixExpressionEmitter._operatorPrecedence[this._expr.getToken().getValue()];
	},

	$_operatorPrecedence: {},

	$_setOperatorPrecedence: function (op, precedence) {
		_PostfixExpressionEmitter._operatorPrecedence[op] = precedence;
	}

});

var _InstanceofExpressionEmitter = exports._InstanceofExpressionEmitter = _ExpressionEmitter.extend({

	constructor: function (emitter, expr) {
		_ExpressionEmitter.prototype.constructor.call(this, emitter);
		this._expr = expr;
	},

	emit: function (outerOpPrecedence) {
		var expectedType = this._expr.getExpectedType();
		if ((expectedType.getClassDef().flags() & (ClassDefinition.IS_INTERFACE | ClassDefinition.IS_MIXIN)) == 0) {
			this.emitWithPrecedence(outerOpPrecedence, _InstanceofExpressionEmitter._operatorPrecedence, (function () {
				this._emitter._getExpressionEmitterFor(this._expr.getExpr()).emit(_InstanceofExpressionEmitter._operatorPrecedence);
				this._emitter._emit(" instanceof " + _Util.getInstanceofNameFromClassDef(expectedType.getClassDef()), null);
			}).bind(this));
		} else {
			this.emitWithPrecedence(outerOpPrecedence, _CallExpressionEmitter._operatorPrecedence, (function () {
				this._emitter._emit("(function (o) { return !! (o && o.$__jsx_implements_" + expectedType.getClassDef().getOutputClassName() + "); })(", this._expr.getToken());
				this._emitter._getExpressionEmitterFor(this._expr.getExpr()).emit(0);
				this._emitter._emit(")", this._expr.getToken());
			}).bind(this));
		}
	},

	$_operatorPrecedence: 0,

	$_setOperatorPrecedence: function (op, precedence) {
		_InstanceofExpressionEmitter._operatorPrecedence = precedence;
	}

});

var _PropertyExpressionEmitter = exports._PropertyExpressionEmitter = _UnaryExpressionEmitter.extend({

	constructor: function (emitter, expr) {
		_UnaryExpressionEmitter.prototype.constructor.call(this, emitter, expr);
	},

	_emit: function () {
		var expr = this._expr;
		var exprType = expr.getType();
		var identifierToken = this._expr.getIdentifierToken();
		// special handling for import ... as
		if (exprType instanceof ClassDefType) {
			this._emitter._emit(exprType.getClassDef().getOutputClassName(), identifierToken);
			return;
		}
		// replace methods to global function (e.g. Number.isNaN to isNaN)
		if (expr.getExpr()._classDefType instanceof ClassDefType
			&& expr.getExpr()._classDefType.getClassDef() === Type.numberType.getClassDef()) {
			switch (identifierToken.getValue()) {
			case "parseInt":
			case "parseFloat":
			case "isNaN":
			case "isFinite":
				this._emitter._emit('$__jsx_' + identifierToken.getValue(), identifierToken);
				return;
			}
		}
		this._emitter._getExpressionEmitterFor(expr.getExpr()).emit(this._getPrecedence());
		// mangle the name if necessary
		if (exprType instanceof FunctionType && ! exprType.isAssignable()
			&& (expr.getHolderType().getClassDef().flags() & ClassDefinition.IS_NATIVE) == 0) {
			if (expr.getExpr()._classDefType instanceof ClassDefType) {
				// do not use "." notation for static functions, but use class$name
				this._emitter._emit("$", identifierToken);
			} else {
				this._emitter._emit(".", identifierToken);
			}
			this._emitter._emit(this._emitter._mangleFunctionName(identifierToken.getValue(), exprType.getArgumentTypes()), identifierToken);
		} else {
			this._emitter._emit(".", identifierToken);
			this._emitter._emit(identifierToken.getValue(), identifierToken);
		}
	},

	_getPrecedence: function () {
		return _PropertyExpressionEmitter._operatorPrecedence;
	},

	$_operatorPrecedence: 0,

	$_setOperatorPrecedence: function (op, precedence) {
		_PropertyExpressionEmitter._operatorPrecedence = precedence;
	}

});

var _FunctionExpressionEmitter = exports._FunctionExpressionEmitter = _UnaryExpressionEmitter.extend({

	constructor: function (emitter, expr) {
		_UnaryExpressionEmitter.prototype.constructor.call(this, emitter, expr);
	},

	_emit: function () {
		var funcDef = this._expr.getFuncDef();
		this._emitter._emit("(function (", funcDef.getToken());
		var args = funcDef.getArguments();
		for (var i = 0; i < args.length; ++i) {
			if (i != 0)
				this._emitter._emit(", ", funcDef.getToken());
			this._emitter._emit(args[i].getName().getValue(), funcDef.getToken());
		}
		this._emitter._emit(") {\n", funcDef.getToken());
		this._emitter._advanceIndent();
		this._emitter._emitFunctionBody(funcDef);
		this._emitter._reduceIndent();
		this._emitter._emit("})", funcDef.getToken())
	},

	_getPrecedence: function () {
		return _FunctionExpressionEmitter._operatorPrecedence;
	},

	$_operatorPrecedence: 0,

	$_setOperatorPrecedence: function (op, precedence) {
		_FunctionExpressionEmitter._operatorPrecedence = precedence;
	}

});

var _BinaryExpressionEmitter = exports._BinaryExpressionEmitter = _OperatorExpressionEmitter.extend({

	constructor: function (emitter, expr) {
		_OperatorExpressionEmitter.prototype.constructor.call(this, emitter);
		this._expr = expr;
		this._precedence = _BinaryExpressionEmitter._operatorPrecedence[this._expr.getToken().getValue()];
	},

	_emit: function () {
		var opToken = this._expr.getToken();
		var firstExpr = this._expr.getFirstExpr();
		var firstExprType = firstExpr.getType();
		var secondExpr = this._expr.getSecondExpr();
		var secondExprType = secondExpr.getType();
		var op = opToken.getValue();
		switch (op) {
		case "+":
			// special handling: (undefined as MayBeUndefined<String>) + (undefined as MayBeUndefined<String>) should produce "undefinedundefined", not NaN
			if (firstExprType.equals(secondExprType) && firstExprType.equals(Type.stringType.toMayBeUndefinedType()))
				this._emitter._emit("\"\" + ", null);
			break;
		case "==":
		case "!=":
			// equality operators of JSX are strict equality ops in JS (expect if either operand is an object and the other is the primitive counterpart)
			if ((firstExprType instanceof ObjectType) + (secondExprType instanceof ObjectType) != 1)
				op += "=";
			break;
		}
		this._emitter._getExpressionEmitterFor(firstExpr).emit(this._precedence);
		this._emitter._emit(" " + op + " ", opToken);
		if (this._expr instanceof AssignmentExpression) {
			this._emitter._emitRHSOfAssignment(secondExpr, firstExprType);
		} else {
			// RHS should have higher precedence (consider: 1 - (1 + 1))
			this._emitter._getExpressionEmitterFor(secondExpr).emit(this._precedence - 1);
		}
	},

	_getPrecedence: function () {
		return this._precedence;
	},

	$_operatorPrecedence: {},

	$_setOperatorPrecedence: function (op, precedence) {
		_BinaryExpressionEmitter._operatorPrecedence[op] = precedence;
	}

});

var _ArrayExpressionEmitter = exports._ArrayExpressionEmitter = _OperatorExpressionEmitter.extend({

	constructor: function (emitter, expr) {
		_OperatorExpressionEmitter.prototype.constructor.call(this, emitter);
		this._expr = expr;
	},

	_emit: function () {
		this._emitter._getExpressionEmitterFor(this._expr.getFirstExpr()).emit(_ArrayExpressionEmitter._operatorPrecedence);
		this._emitter._emit("[", this._expr.getToken());
		this._emitter._getExpressionEmitterFor(this._expr.getSecondExpr()).emit(0);
		this._emitter._emit("]", null);
	},

	_getPrecedence: function () {
		return _ArrayExpressionEmitter._operatorPrecedence;
	},

	$_operatorPrecedence: 0,

	$_setOperatorPrecedence: function (op, precedence) {
		_ArrayExpressionEmitter._operatorPrecedence = precedence;
	}

});

var _ConditionalExpressionEmitter = exports._ConditionalExpressionEmitter = _OperatorExpressionEmitter.extend({

	constructor: function (emitter, expr) {
		_OperatorExpressionEmitter.prototype.constructor.call(this, emitter);
		this._expr = expr;
	},

	_emit: function () {
		var precedence = this._getPrecedence();
		var ifTrueExpr = this._expr.getIfTrueExpr();
		if (ifTrueExpr != null) {
			this._emitter._getExpressionEmitterFor(this._expr.getCondExpr()).emit(precedence);
			this._emitter._emit(" ? ", null);
			this._emitter._getExpressionEmitterFor(ifTrueExpr).emit(precedence);
			this._emitter._emit(" : ", null);
			this._emitter._getExpressionEmitterFor(this._expr.getIfFalseExpr()).emit(precedence);
		} else {
			this._emitter._getExpressionEmitterFor(this._expr.getCondExpr()).emit(precedence);
			this._emitter._emit(" || ", null);
			this._emitter._getExpressionEmitterFor(this._expr.getIfFalseExpr()).emit(precedence);
		}
	},

	_getPrecedence: function () {
		return this._expr.getIfTrueExpr() != null ? _ConditionalExpressionEmitter._operatorPrecedence : _BinaryExpressionEmitter._operatorPrecedence["||"];
	},

	$_operatorPrecedence: 0,

	$_setOperatorPrecedence: function (op, precedence) {
		_ConditionalExpressionEmitter._operatorPrecedence = precedence;
	}

});

var _CallExpressionEmitter = exports._CallExpressionEmitter = _OperatorExpressionEmitter.extend({

	constructor: function (emitter, expr) {
		_OperatorExpressionEmitter.prototype.constructor.call(this, emitter);
		this._expr = expr;
	},

	_emit: function () {
		if (this._emitSpecial())
			return;
		// normal case
		var calleeExpr = this._expr.getExpr();
		if (this._emitter._enableRunTimeTypeCheck && calleeExpr.getType() instanceof MayBeUndefinedType)
			this._emitter._emitExpressionWithUndefinedAssertion(calleeExpr);
		else
			this._emitter._getExpressionEmitterFor(calleeExpr).emit(_CallExpressionEmitter._operatorPrecedence);
		this._emitter._emitCallArguments(this._expr.getToken(), "(", this._expr.getArguments(), this._expr.getExpr().getType().resolveIfMayBeUndefined().getArgumentTypes());
	},

	_getPrecedence: function () {
		return _CallExpressionEmitter._operatorPrecedence;
	},

	$_operatorPrecedence: 0,

	$_setOperatorPrecedence: function (op, precedence) {
		_CallExpressionEmitter._operatorPrecedence = precedence;
	},

	_emitSpecial: function () {
		// return false if is not js.apply
		var calleeExpr = this._expr.getExpr();
		if (! (calleeExpr instanceof PropertyExpression))
			return false;
		if (this._emitIfJsInvoke(calleeExpr))
			return true;
		else if (this._emitCallsToMap(calleeExpr))
			return true;
		else if (this._emitIfMathAbs(calleeExpr))
			return true;
		return false;
	},

	_emitIfJsInvoke: function (calleeExpr) {
		if (! (calleeExpr.getType() instanceof StaticFunctionType))
			return false;
		if (calleeExpr.getIdentifierToken().getValue() != "invoke")
			return false;
		var classDef = calleeExpr.getExpr().getType().getClassDef();
		if (! (classDef.className() == "js" && classDef.getToken().getFilename() == this._emitter._platform.getRoot() + "/lib/js/js.jsx"))
			return false;
		// emit
		var args = this._expr.getArguments();
		if (args[2] instanceof ArrayLiteralExpression) {
			this._emitter._getExpressionEmitterFor(args[0]).emit(_PropertyExpressionEmitter._operatorPrecedence);
			// FIXME emit as property expression if possible
			this._emitter._emit("[", calleeExpr.getToken());
			this._emitter._getExpressionEmitterFor(args[1]).emit(0);
			this._emitter._emit("]", calleeExpr.getToken());
			this._emitter._emitCallArguments(this._expr.getToken(), "(", args[2].getExprs(), null);
		} else {
			this._emitter._emit("(function (o, p, a) { return o[p].apply(o, a); }(", calleeExpr.getToken());
			this._emitter._getExpressionEmitterFor(args[0]).emit(0);
			this._emitter._emit(", ", this._expr.getToken());
			this._emitter._getExpressionEmitterFor(args[1]).emit(0);
			this._emitter._emit(", ", this._expr.getToken());
			this._emitter._getExpressionEmitterFor(args[2]).emit(0);
			this._emitter._emit("))", this._expr.getToken());
		}
		return true;
	},

	_emitCallsToMap: function (calleeExpr) {
		// NOTE once we support member function references, we need to add special handling in _PropertyExpressionEmitter as well
		if (calleeExpr.getType() instanceof StaticFunctionType)
			return false;
		var classDef = calleeExpr.getExpr().getType().getClassDef();
		if (! (classDef instanceof InstantiatedClassDefinition))
			return false;
		if (classDef.getTemplateClassName() != "Map")
			return false;
		switch (calleeExpr.getIdentifierToken().getValue()) {
		case "toString":
			this._emitter._emitCallArguments(
				calleeExpr.getToken(), "$__jsx_ObjectToString.call(", [ calleeExpr.getExpr() ], [ new ObjectType(classDef) ]);
			return true;
		case "hasOwnProperty":
			this._emitter._emitCallArguments(
				calleeExpr.getToken(), "$__jsx_ObjectHasOwnProperty.call(",
				[ calleeExpr.getExpr(), this._expr.getArguments()[0] ],
				[ new ObjectType(classDef), Type.stringType ]);
			return true;
		default:
			return false;
		}
	},

	_emitIfMathAbs: function (calleeExpr) {
		if (! _CallExpressionEmitter._calleeIsMathAbs(calleeExpr))
			return false;
		var argExpr = this._expr.getArguments()[0];
		if (argExpr instanceof LeafExpression) {
			this._emitter._emit("(", this._expr.getToken());
			this._emitter._getExpressionEmitterFor(argExpr).emit(0);
			this._emitter._emit(" >= 0 ? ", this._expr.getToken());
			this._emitter._getExpressionEmitterFor(argExpr).emit(0);
			this._emitter._emit(" : - ", this._expr.getToken());
			this._emitter._getExpressionEmitterFor(argExpr).emit(0);
			this._emitter._emit(")", this._expr.getToken());
		} else {
			this._emitter._emit("(($math_abs_t = ", this._expr.getToken());
			this._emitter._getExpressionEmitterFor(argExpr).emit(_BinaryExpressionEmitter._operatorPrecedence["="]);
			this._emitter._emit(") >= 0 ? $math_abs_t : -$math_abs_t)", this._expr.getToken());
		}
		return true;
	},

	$_calleeIsMathAbs: function (calleeExpr) {
		if (! (calleeExpr.getType() instanceof StaticFunctionType))
			return false;
		if (calleeExpr.getIdentifierToken().getValue() != "abs")
			return false;
		if (calleeExpr.getExpr().getType().getClassDef().className() != "Math")
			return false;
		return true;
	},

	$mathAbsUsesTemporary: function (funcDef) {
		return ! funcDef.forEachStatement(function onStatement(statement) {
			if (! statement.forEachExpression(function onExpr(expr) {
				var calleeExpr;
				if (expr instanceof CallExpression
					&& (calleeExpr = expr.getExpr()) instanceof PropertyExpression
					&& _CallExpressionEmitter._calleeIsMathAbs(calleeExpr)
					&& ! (expr.getArguments()[0] instanceof LeafExpression))
					return false;
				return expr.forEachExpression(onExpr);
			})) {
				return false;
			}
			return statement.forEachStatement(onStatement);
		});
	}

});

var _SuperExpressionEmitter = exports._SuperExpressionEmitter = _OperatorExpressionEmitter.extend({

	constructor: function (emitter, expr) {
		_OperatorExpressionEmitter.prototype.constructor.call(this, emitter);
		this._expr = expr;
	},

	_emit: function () {
		var funcType = this._expr.getFunctionType();
		var className = funcType.getObjectType().getClassDef().getOutputClassName();
		var argTypes = funcType.getArgumentTypes();
		var mangledFuncName = this._emitter._mangleFunctionName(this._expr.getName().getValue(), argTypes);
		this._emitter._emitCallArguments(this._expr.getToken(), className + ".prototype." + mangledFuncName + ".call(this", this._expr.getArguments(), argTypes);
	},

	_getPrecedence: function () {
		return _CallExpressionEmitter._operatorPrecedence;
	},

	$_operatorPrecedence: 0,

	$_setOperatorPrecedence: function (op, precedence) {
		_SuperExpressionEmitter._operatorPrecedence = precedence;
	}

});

var _NewExpressionEmitter = exports._NewExpressionEmitter = _OperatorExpressionEmitter.extend({

	constructor: function (emitter, expr) {
		_OperatorExpressionEmitter.prototype.constructor.call(this, emitter);
		this._expr = expr;
	},

	emit: function (outerOpPrecedence) {
		var classDef = this._expr.getType().getClassDef();
		var ctor = this._expr.getConstructor();
		var argTypes = ctor.getArgumentTypes();
		this._emitter._emitCallArguments(
			this._expr.getToken(),
			"new " + this._emitter._mangleConstructorName(classDef, argTypes) + "(",
			this._expr.getArguments(),
			argTypes);
	},

	_getPrecedence: function () {
		return _NewExpressionEmitter._operatorPrecedence;
	},

	$_operatorPrecedence: 0,

	$_setOperatorPrecedence: function (op, precedence) {
		_NewExpressionEmitter._operatorPrecedence = precedence;
	}

});

var _CommaExpressionEmitter = exports._CommaExpressionEmitter = _ExpressionEmitter.extend({

	constructor: function (emitter, expr) {
		_ExpressionEmitter.prototype.constructor.call(this, emitter);
		this._expr = expr;
	},

	emit: function (outerOpPrecedence) {
		// comma operations should be surrounded by brackets unless within a comma expression, since "," might get considered as an argument separator (of function calls, etc.)
		var useBrackets = outerOpPrecedence != _CommaExpressionEmitter._operatorPrecedence;
		if (useBrackets)
			this._emitter._emit("(", null);
		this._emitter._getExpressionEmitterFor(this._expr.getFirstExpr()).emit(_CommaExpressionEmitter._operatorPrecedence);
		this._emitter._emit(", ", null);
		this._emitter._getExpressionEmitterFor(this._expr.getSecondExpr()).emit(_CommaExpressionEmitter._operatorPrecedence);
		if (useBrackets)
			this._emitter._emit(")", null);
	},

	$_operatorPrecedence: 0,

	$_setOperatorPrecedence: function (op, precedence) {
		_CommaExpressionEmitter._operatorPrecedence = precedence;
	}

});

// the global emitter

var JavaScriptEmitter = exports.JavaScriptEmitter = Class.extend({

	constructor: function (platform) {
		this._platform = platform;
		this._output = this._platform.load(this._platform.getRoot() + "/src/js/bootstrap.js");
		this._outputFile = null;
		this._indent = 0;
		this._emittingClass = null;
		this._emittingFunction = null;
		this._emittingStatementStack = [];
		this._enableRunTimeTypeCheck = true;
	},

	getSearchPaths: function () {
		return [ this._platform.getRoot() + "/lib/js" ];
	},

	setOutputFile: function (name) {
		this._outputFile = name;

		if(this._enableSourceMap) {
			// FIXME: set correct sourceRoot
			var sourceRoot = null;
			this._sourceMapGen = new SourceMapGenerator(name, sourceRoot);
		}
	},

	saveSourceMappingFile: function (platform) {
		var gen = this._sourceMapGen;
		if(gen != null) {
			platform.save(this._sourceMapGen.getSourceMappingFile(),
								this._sourceMapGen.generate());
		}
	},

	setSourceMapGenerator: function (gen) {
		this._sourceMapGen = gen;
	},

	setEnableRunTimeTypeCheck: function (enable) {
		this._enableRunTimeTypeCheck = enable;
	},
	setEnableSourceMap : function (enable) {
		this._enableSourceMap = enable;
	},

	emit: function (classDefs) {
		for (var i = 0; i < classDefs.length; ++i) {
			if ((classDefs[i].flags() & ClassDefinition.IS_NATIVE) == 0)
				this._emitClassDefinition(classDefs[i]);
		}
		for (var i = 0; i < classDefs.length; ++i)
			this._emitStaticInitializationCode(classDefs[i]);
		this._emitClassMap(classDefs);
	},

	_emitClassDefinition: function (classDef) {
		this._emittingClass = classDef;
		try {

			// emit class object
			this._emitClassObject(classDef);

			// emit constructors
			var ctors = this._findFunctions(classDef, "constructor", false);
			for (var i = 0; i < ctors.length; ++i)
				this._emitConstructor(ctors[i]);

			// emit functions
			var members = classDef.members();
			for (var i = 0; i < members.length; ++i) {
				var member = members[i];
				if (member instanceof MemberFunctionDefinition) {
					if (! (member.name() == "constructor" && (member.flags() & ClassDefinition.IS_STATIC) == 0) && member.getStatements() != null) {
						this._emitFunction(member);
					}
				}
			}

		} finally {
			this._emittingClass = null;
		}

	},

	_emitStaticInitializationCode: function (classDef) {
		if ((classDef.flags() & ClassDefinition.IS_NATIVE) != 0)
			return;
		// special handling for js.jsx
		if (classDef.getToken().getFilename() == this._platform.getRoot() + "/lib/js/js.jsx") {
			this._emit("js.global = (function () { return this; })();\n\n", null);
			return;
		}
		// normal handling
		var members = classDef.members();
		// FIXME can we (should we?) automatically resolve dependencies? isn't it impossible?
		for (var i = 0; i < members.length; ++i) {
			var member = members[i];
			if ((member instanceof MemberVariableDefinition)
				&& (member.flags() & (ClassDefinition.IS_STATIC | ClassDefinition.IS_NATIVE)) == ClassDefinition.IS_STATIC)
				this._emitStaticMemberVariable(classDef.getOutputClassName(), member);
		}
	},

	_emitClassMap: function (classDefs) {
		classDefs = classDefs.concat([]); // shallow clone
		// remove the classDefs wo. source token or native
		for (var i = 0; i < classDefs.length;) {
			if (classDefs[i].getToken() == null || (classDefs[i].flags() & ClassDefinition.IS_NATIVE) != 0)
				classDefs.splice(i, 1);
			else
				++i;
		}
		// start emitting
		this._emit("var $__jsx_classMap = {\n", null);
		this._advanceIndent();
		while (classDefs.length != 0) {
			// fetch the first classDef, and others that came from the same file
			var list = [];
			var pushClass = (function (classDef) {
				var push = function (suffix) {
					list.push([ classDef.className() + suffix, classDef.getOutputClassName() + suffix ]);
				};
				var ctors = this._findFunctions(classDef, "constructor", false);
				push("");
				if (ctors.length == 0) {
					push(this._mangleFunctionArguments([]));
				} else {
					for (var i = 0; i < ctors.length; ++i)
						push(this._mangleFunctionArguments(ctors[i].getArgumentTypes()));
				}
			}).bind(this);
			var filename = classDefs[0].getToken().getFilename();
			pushClass(classDefs.shift());
			for (var i = 0; i < classDefs.length;) {
				if (classDefs[i].getToken().getFilename() == filename) {
					pushClass(classDefs[i]);
					classDefs.splice(i, 1);
				} else {
					++i;
				}
			}
			// emit the map
			this._emit("\"" + this._encodeFilename(filename) + "\": ", null); // FIXME escape
			this._emit("{\n", null);
			this._advanceIndent();
			for (var i = 0; i < list.length; ++i) {
				this._emit(list[i][0] + ": " + list[i][1], null);
				if (i != list.length - 1)
					this._emit(",", null);
				this._emit("\n", null);
			}
			this._reduceIndent();
			this._emit("}", null);
			if (classDefs.length != 0)
				this._emit(",", null);
			this._emit("\n", null);
		}
		this._reduceIndent();
		this._emit("};\n\n", null);
	},

	_encodeFilename: function (filename) {
		if (filename.indexOf(this._platform.getRoot() + "/") == 0)
			filename = "system:" + filename.substring(this._platform.getRoot().length + 1);
		return filename;
	},

	getOutput: function (sourceFile, entryPoint) {
		var output = this._output + "\n" +
			"}());\n";
		if (entryPoint != null) {
			output = this._platform.addLauncher(this, this._encodeFilename(sourceFile), output, entryPoint);
		}
		if (this._sourceMapGen) {
			output += this._sourceMapGen.magicToken();
		}
		return output;
	},

	_emitClassObject: function (classDef) {
		this._emit(
			"/**\n" +
			" * class " + classDef.getOutputClassName() +
			" extends " + classDef.extendClassDef().getOutputClassName() + "\n" +
			" * @constructor\n" +
			" */\n" +
			"function ", null);
		this._emit(classDef.getOutputClassName() + "() {\n" +
			"}\n" +
			"\n",
			classDef.getToken());
		this._emit(classDef.getOutputClassName() + ".prototype = new " + classDef.extendClassDef().getOutputClassName() + ";\n", null);
		if (classDef.implementClassDefs().length != 0) {
			var interfaceDefs = classDef.implementClassDefs();
			for (var i = 0; i < interfaceDefs.length; ++i)
				this._emit("$__jsx_merge_interface(" + classDef.getOutputClassName() + ", " + interfaceDefs[i].getOutputClassName() + ");\n", null);
			this._emit("\n", null);
		}
		if ((classDef.flags() & (ClassDefinition.IS_INTERFACE | ClassDefinition.IS_MIXIN)) != 0)
			this._emit(classDef.getOutputClassName() + ".prototype.$__jsx_implements_" + classDef.getOutputClassName() + " = true;\n\n", null);
	},

	_emitConstructor: function (funcDef) {
		var funcName = this._mangleConstructorName(funcDef.getClassDef(), funcDef.getArgumentTypes());

		// emit prologue
		this._emit("/**\n", null);
		this._emit(" * @constructor\n", null);
		this._emitFunctionArgumentAnnotations(funcDef);
		this._emit(" */\n", null);
		this._emit("function ", null);
		this._emit(funcName + "(", funcDef.getClassDef().getToken());
		this._emitFunctionArguments(funcDef);
		this._emit(") {\n", null);
		this._advanceIndent();
		// emit body
		this._emitFunctionBody(funcDef);
		// emit epilogue
		this._reduceIndent();
		this._emit("};\n\n", null);
		this._emit(funcName + ".prototype = new " + funcDef.getClassDef().getOutputClassName() + ";\n\n", null);
	},

	_emitFunction: function (funcDef) {
		var className = funcDef.getClassDef().getOutputClassName();
		var funcName = this._mangleFunctionName(funcDef.name(), funcDef.getArgumentTypes());
		// emit
		this._emit("/**\n", null);
		this._emitFunctionArgumentAnnotations(funcDef);
		this._emit(_Util.buildAnnotation(" * @return {%1}\n", funcDef.getReturnType()), null);
		this._emit(" */\n", null);
		this._emit(className + ".", null);
		if ((funcDef.flags() & ClassDefinition.IS_STATIC) == 0)
			this._emit("prototype.", null);
		this._emit(funcName + " = ", funcDef.getNameToken());
		this._emit("function (", funcDef.getToken());
		this._emitFunctionArguments(funcDef);
		this._emit(") {\n", null);
		this._advanceIndent();
		this._emitFunctionBody(funcDef);
		this._reduceIndent();
		this._emit("};\n\n", null);
		if ((funcDef.flags() & ClassDefinition.IS_STATIC) != 0)
			this._emit(className + "$" + funcName + " = " + className + "." + funcName + ";\n\n", null);
	},

	_emitFunctionArgumentAnnotations: function (funcDef) {
		var args = funcDef.getArguments();
		for (var i = 0; i < args.length; ++i)
			this._emit(_Util.buildAnnotation(" * @param {%1} " + args[i].getName().getValue() + "\n", args[i].getType()), null);
	},

	_emitFunctionArguments: function (funcDef) {
		var args = funcDef.getArguments();
		for (var i = 0; i < args.length; ++i) {
			if (i != 0)
				this._emit(", ");
			var name = args[i].getName();
			this._emit(name.getValue(), name);
		}
	},

	_emitFunctionBody: function (funcDef) {
		var prevEmittingFunction = this._emittingFunction;
		try {
			this._emittingFunction = funcDef;

			// emit reference to this for closures
			// if funDef is NOT in another closure
			if (funcDef.getClosures().length != 0 && (funcDef.flags() & ClassDefinition.IS_STATIC) == 0)
				this._emit("var $this = this;\n", null);
			// emit helper variable for Math.abs
			if (_CallExpressionEmitter.mathAbsUsesTemporary(funcDef)) {
				this._emit("var $math_abs_t;\n", null);
			}
			// emit local variable declarations
			var locals = funcDef.getLocals();
			for (var i = 0; i < locals.length; ++i) {
				// FIXME unused variables should never be emitted by the compiler
				var type = locals[i].getType();
				if (type == null)
					continue;
				this._emit(_Util.buildAnnotation("/** @type {%1} */\n", type), null);
				var name = locals[i].getName();
				this._emit("var " + name.getValue() + ";\n", name);
			}
			// emit code
			var statements = funcDef.getStatements();
			for (var i = 0; i < statements.length; ++i)
				this._emitStatement(statements[i]);

		} finally {
			this._emittingFunction = prevEmittingFunction;
		}
	},

	_emitStaticMemberVariable: function (holder, variable) {
		var initialValue = variable.getInitialValue();
		if (initialValue != null
			&& ! (initialValue instanceof UndefinedExpression
				|| initialValue instanceof NullExpression
				|| initialValue instanceof BooleanLiteralExpression
				|| initialValue instanceof IntegerLiteralExpression
				|| initialValue instanceof NumberLiteralExpression
				|| initialValue instanceof StringLiteralExpression
				|| initialValue instanceof RegExpLiteralExpression)) {
			// use deferred initialization
			this._emit("$__jsx_lazy_init(" + holder + ", \"" + variable.name() + "\", function () {\n", variable.getNameToken());
			this._advanceIndent();
			this._emit("return ", variable.getNameToken());
			this._emitRHSOfAssignment(initialValue, variable.getType());
			this._emit(";\n", variable.getNameToken());
			this._reduceIndent();
			this._emit("});\n", variable.getNameToken());
		} else {
			this._emit(holder + "." + variable.name() + " = ", variable.getNameToken());
			this._emitRHSOfAssignment(initialValue, variable.getType());
			this._emit(";\n", initialValue.getToken());
		}
	},

	_emitDefaultValueOf: function (type) {
		if (type.equals(Type.booleanType))
			this._emit("false", null);
		else if (type.equals(Type.integerType) || type.equals(Type.numberType))
			this._emit("0", null);
		else if (type.equals(Type.stringType))
			this._emit("\"\"", null);
		else if (type instanceof MayBeUndefinedType)
			this._emit("undefined", null);
		else
			this._emit("null", null);
	},

	_emitStatements: function (statements) {
		this._advanceIndent();
		for (var i = 0; i < statements.length; ++i)
			this._emitStatement(statements[i]);
		this._reduceIndent();
	},

	_emitStatement: function (statement) {
		var emitter = this._getStatementEmitterFor(statement);
		this._emittingStatementStack.push(emitter);
		try {
			emitter.emit();
		} finally {
			this._emittingStatementStack.pop();
		}
	},

	_emit: function (str, token) {
		if (str == "")
			return;
		if (this._output.match(/\n$/))
			this._output += this._getIndent();
		// optional source map
		if(this._sourceMapGen != null && token != null) {
			var outputLines = this._output.split(/^/m);
			var genPos = {
				line: outputLines.length,
				column: outputLines[outputLines.length-1].length - 1,
			};
			// XXX: 'line' of original pos seems zero-origin (gfx suspects it's a bug of mozilla/source-map)
			var origPos = {
				line: token.getLineNumber() - 1,
				column: token.getColumnNumber()
			};
			var tokenValue = token.isIdentifier()
				? token.getValue()
				: null;
			this._sourceMapGen.add(genPos, origPos,
								   token.getFilename(), tokenValue);
		}
		this._output += str.replace(/\n(.)/g, (function (a, m) { return "\n" + this._getIndent() + m; }).bind(this));
	},

	_advanceIndent: function () {
		++this._indent;
	},

	_reduceIndent: function () {
		if (--this._indent < 0)
			throw new Error("indent mistach");
	},

	_getIndent: function () {
		var s = "";
		for (var i = 0; i < this._indent; ++i)
			s += "\t";
		return s;
	},

	_getStatementEmitterFor: function (statement) {
		if (statement instanceof ConstructorInvocationStatement)
			return new _ConstructorInvocationStatementEmitter(this, statement);
		else if (statement instanceof ExpressionStatement)
			return new _ExpressionStatementEmitter(this, statement);
		else if (statement instanceof ReturnStatement)
			return new _ReturnStatementEmitter(this, statement);
		else if (statement instanceof DeleteStatement)
			return new _DeleteStatementEmitter(this, statement);
		else if (statement instanceof BreakStatement)
			return new _BreakStatementEmitter(this, statement);
		else if (statement instanceof ContinueStatement)
			return new _ContinueStatementEmitter(this, statement);
		else if (statement instanceof DoWhileStatement)
			return new _DoWhileStatementEmitter(this, statement);
		else if (statement instanceof ForInStatement)
			return new _ForInStatementEmitter(this, statement);
		else if (statement instanceof ForStatement)
			return new _ForStatementEmitter(this, statement);
		else if (statement instanceof IfStatement)
			return new _IfStatementEmitter(this, statement);
		else if (statement instanceof SwitchStatement)
			return new _SwitchStatementEmitter(this, statement);
		else if (statement instanceof CaseStatement)
			return new _CaseStatementEmitter(this, statement);
		else if (statement instanceof DefaultStatement)
			return new _DefaultStatementEmitter(this, statement);
		else if (statement instanceof WhileStatement)
			return new _WhileStatementEmitter(this, statement);
		else if (statement instanceof TryStatement)
			return new _TryStatementEmitter(this, statement);
		else if (statement instanceof CatchStatement)
			return new _CatchStatementEmitter(this, statement);
		else if (statement instanceof ThrowStatement)
			return new _ThrowStatementEmitter(this, statement);
		else if (statement instanceof AssertStatement)
			return new _AssertStatementEmitter(this, statement);
		else if (statement instanceof LogStatement)
			return new _LogStatementEmitter(this, statement);
		else if (statement instanceof DebuggerStatement)
			return new _DebuggerStatementEmitter(this, statement);
		throw new Error("got unexpected type of statement: " + JSON.stringify(statement.serialize()));
	},

	_getExpressionEmitterFor: function (expr) {
		if (expr instanceof IdentifierExpression)
			return new _IdentifierExpressionEmitter(this, expr);
		else if (expr instanceof UndefinedExpression)
			return new _UndefinedExpressionEmitter(this, expr);
		else if (expr instanceof NullExpression)
			return new _NullExpressionEmitter(this, expr);
		else if (expr instanceof BooleanLiteralExpression)
			return new _BooleanLiteralExpressionEmitter(this, expr);
		else if (expr instanceof IntegerLiteralExpression)
			return new _IntegerLiteralExpressionEmitter(this, expr);
		else if (expr instanceof NumberLiteralExpression)
			return new _NumberLiteralExpressionEmitter(this, expr);
		else if (expr instanceof StringLiteralExpression)
			return new _StringLiteralExpressionEmitter(this, expr);
		else if (expr instanceof RegExpLiteralExpression)
			return new _RegExpLiteralExpressionEmitter(this, expr);
		else if (expr instanceof ArrayLiteralExpression)
			return new _ArrayLiteralExpressionEmitter(this, expr);
		else if (expr instanceof MapLiteralExpression)
			return new _MapLiteralExpressionEmitter(this, expr);
		else if (expr instanceof ThisExpression)
			return new _ThisExpressionEmitter(this, expr);
		else if (expr instanceof BitwiseNotExpression)
			return new _UnaryExpressionEmitter(this, expr);
		else if (expr instanceof InstanceofExpression)
			return new _InstanceofExpressionEmitter(this, expr);
		else if (expr instanceof AsExpression)
			return new _AsExpressionEmitter(this, expr);
		else if (expr instanceof AsNoConvertExpression)
			return new _AsNoConvertExpressionEmitter(this, expr);
		else if (expr instanceof LogicalNotExpression)
			return new _UnaryExpressionEmitter(this, expr);
		else if (expr instanceof TypeofExpression)
			return new _UnaryExpressionEmitter(this, expr);
		else if (expr instanceof PostIncrementExpression)
			return new _PostfixExpressionEmitter(this, expr);
		else if (expr instanceof PreIncrementExpression)
			return new _UnaryExpressionEmitter(this, expr);
		else if (expr instanceof PropertyExpression)
			return new _PropertyExpressionEmitter(this, expr);
		else if (expr instanceof SignExpression)
			return new _UnaryExpressionEmitter(this, expr);
		else if (expr instanceof AdditiveExpression)
			return new _BinaryExpressionEmitter(this, expr);
		else if (expr instanceof ArrayExpression)
			return new _ArrayExpressionEmitter(this, expr);
		else if (expr instanceof AssignmentExpression)
			return new _BinaryExpressionEmitter(this, expr);
		else if (expr instanceof BinaryNumberExpression)
			return new _BinaryExpressionEmitter(this, expr);
		else if (expr instanceof EqualityExpression)
			return new _BinaryExpressionEmitter(this, expr);
		else if (expr instanceof InExpression)
			return new _BinaryExpressionEmitter(this, expr);
		else if (expr instanceof LogicalExpression)
			return new _BinaryExpressionEmitter(this, expr);
		else if (expr instanceof ShiftExpression)
			return new _BinaryExpressionEmitter(this, expr);
		else if (expr instanceof ConditionalExpression)
			return new _ConditionalExpressionEmitter(this, expr);
		else if (expr instanceof CallExpression)
			return new _CallExpressionEmitter(this, expr);
		else if (expr instanceof SuperExpression)
			return new _SuperExpressionEmitter(this, expr);
		else if (expr instanceof NewExpression)
			return new _NewExpressionEmitter(this, expr);
		else if (expr instanceof FunctionExpression)
			return new _FunctionExpressionEmitter(this, expr);
		else if (expr instanceof CommaExpression)
			return new _CommaExpressionEmitter(this, expr);
		throw new Error("got unexpected type of expression: " + (expr != null ? JSON.stringify(expr.serialize()) : expr));
	},

	_mangleConstructorName: function (classDef, argTypes) {
		if ((classDef.flags() & ClassDefinition.IS_NATIVE) != 0) {
			if (classDef instanceof InstantiatedClassDefinition) {
				if (classDef.getTemplateClassName() == "Map") {
					return "Object";
				} else {
					return classDef.getTemplateClassName();
				}
			} else {
				return classDef.className();
			}
		}
		return classDef.getOutputClassName() + this._mangleFunctionArguments(argTypes);
	},

	_mangleFunctionName: function (name, argTypes) {
		// NOTE: how mangling of "toString" is omitted is very hacky, but it seems like the easiest way, taking the fact into consideration that it is the only function in Object
		if (name != "toString")
			name += this._mangleFunctionArguments(argTypes);
		return name;
	},

	_mangleTypeName: function (type) {
		if (type.equals(Type.voidType))
			return "V";
		else if (type.equals(Type.booleanType))
			return "B";
		else if (type.equals(Type.integerType))
			return "I";
		else if (type.equals(Type.numberType))
			return "N";
		else if (type.equals(Type.stringType))
			return "S";
		else if (type instanceof ObjectType) {
			var classDef = type.getClassDef();
			if (classDef instanceof InstantiatedClassDefinition) {
				var typeArgs = classDef.getTypeArguments();
				switch (classDef.getTemplateClassName()) {
				case "Array":
					return "A" + this._mangleTypeName(typeArgs[0]);
				case "Map":
					return "H" + this._mangleTypeName(typeArgs[0]);
				default:
					throw new Error("unexpected template type: " + classDef.getTemplateClassName());
				}
			}
			return "L" + type.getClassDef().getOutputClassName() + "$";
		} else if (type instanceof StaticFunctionType)
			return "F" + this._mangleFunctionArguments(type.getArgumentTypes()) + this._mangleTypeName(type.getReturnType()) + "$";
		else if (type instanceof MemberFunctionType)
			return "M" + this._mangleTypeName(type.getObjectType()) + this._mangleFunctionArguments(type.getArgumentTypes()) + this._mangleTypeName(type.getReturnType()) + "$";
		else if (type instanceof MayBeUndefinedType)
			return "U" + this._mangleTypeName(type.getBaseType());
		else if (type.equals(Type.variantType))
			return "X";
		else
			throw new Error("FIXME " + type.toString());
	},

	_mangleFunctionArguments: function (argTypes) {
		var s = "$";
		for (var i = 0; i < argTypes.length; ++i)
			s += this._mangleTypeName(argTypes[i]);
		return s;
	},

	_mangleTypeString: function (s) {
		return s.length + s;
	},

	_findFunctions: function (classDef, name, isStatic) {
		var functions = [];
		var members = classDef.members();
		for (var i = 0; i < members.length; ++i) {
			var member = members[i];
			if ((member instanceof MemberFunctionDefinition) && member.name() == name
				&& (member.flags() & ClassDefinition.IS_STATIC) == (isStatic ? ClassDefinition.IS_STATIC : 0))
				functions.push(member);
		}
		return functions;
	},

	_emitCallArguments: function (token, prefix, args, argTypes) {
		this._emit(prefix, token);
		for (var i = 0; i < args.length; ++i) {
			if (i != 0 || prefix[prefix.length - 1] != '(')
				this._emit(", ", null);
			if (argTypes != null
				&& this._enableRunTimeTypeCheck
				&& args[i].getType() instanceof MayBeUndefinedType
				&& ! (argTypes[i] instanceof MayBeUndefinedType || argTypes[i] instanceof VariantType)) {
				this._emitExpressionWithUndefinedAssertion(args[i]);
			} else {
				this._getExpressionEmitterFor(args[i]).emit(0);
			}
		}
		this._emit(")", token);
	},

	_emitAssertion: function (emitTestExpr, token, message) {
		this._emit("if (! (", token);
		emitTestExpr();
		this._emit(")) {\n", null);
		this._advanceIndent();
		this._emit("debugger;\n", null);
		// FIXME make the expression source and throw a fit exception class
		var err = Util.format('throw new Error("[%1:%2] %3");\n',
							  [token.getFilename(), token.getLineNumber(), message]);
		this._emit(err, null);
		this._reduceIndent();
		this._emit("}\n", null);
	},

	_emitExpressionWithUndefinedAssertion: function (expr) {
		var token = expr.getToken();
		this._emit("(function (v) {\n", token);
		this._advanceIndent();
		this._emitAssertion(function () {
			this._emit("typeof v !== \"undefined\"", token);
		}.bind(this), token, "detected misuse of 'undefined' as type '" + expr.getType().resolveIfMayBeUndefined().toString() + "'");
		this._emit("return v;\n", token);
		this._reduceIndent();
		this._emit("}(", token);
		this._getExpressionEmitterFor(expr).emit(0);
		this._emit("))", token);
	},

	_emitRHSOfAssignment: function (expr, lhsType) {
		var exprType = expr.getType();
		// FIXME what happens if the op is /= or %= ?
		if (lhsType.resolveIfMayBeUndefined().equals(Type.integerType) && exprType.equals(Type.numberType)) {
			if (expr instanceof NumberLiteralExpression
				|| expr instanceof IntegerLiteralExpression) {
				this._emit((expr.getToken().getValue() | 0).toString(), expr.getToken());
			} else {
				this._emit("(", expr.getToken());
				this._getExpressionEmitterFor(expr).emit(_BinaryExpressionEmitter._operatorPrecedence["|"]);
				this._emit(" | 0)", expr.getToken());
			}
			return;
		}
		if (lhsType.equals(Type.integerType)
			&& (exprType instanceof MayBeUndefinedType && exprType.getBaseType().equals(Type.numberType))) {
			this._emit("(", expr.getToken());
			if (this._enableRunTimeTypeCheck) {
				this._emitExpressionWithUndefinedAssertion(expr);
			} else {
				this._getExpressionEmitterFor(expr).emit(_BinaryExpressionEmitter._operatorPrecedence["|"]);
			}
			this._emit(" | 0)", expr.getToken());
			return;
		}
		if ((lhsType instanceof MayBeUndefinedType && lhsType.getBaseType().equals(Type.integerType))
			&& (exprType instanceof MayBeUndefinedType && exprType.getBaseType().equals(Type.numberType))) {
			// NOTE this is very slow, but such an operation would practically not be found
			this._emit("(function (v) { return v !== undefined ? v | 0 : v; })(", expr.getToken());
			this._getExpressionEmitterFor(expr).emit(0);
			this._emit(")", expr.getToken());
			return;
		}
		// normal mode
		if (this._enableRunTimeTypeCheck
			&& ! (lhsType instanceof MayBeUndefinedType || lhsType.equals(Type.variantType))
			&& exprType instanceof MayBeUndefinedType) {
			this._emitExpressionWithUndefinedAssertion(expr);
		} else {
			this._getExpressionEmitterFor(expr).emit(_BinaryExpressionEmitter._operatorPrecedence["="]);
		}
	},

	$constructor: function () {
		var precedence = [
			[
				[ "new",        _NewExpressionEmitter._setOperatorPrecedence ],
				[ "[",          _ArrayExpressionEmitter._setOperatorPrecedence ],
				[ ".",          _PropertyExpressionEmitter._setOperatorPrecedence ],
				[ "(",          _CallExpressionEmitter._setOperatorPrecedence ],
				[ "super",      _SuperExpressionEmitter._setOperatorPrecedence ],
				[ "function",   _FunctionExpressionEmitter._setOperatorPrecedence ],
			], [
				[ "++",         _PostfixExpressionEmitter._setOperatorPrecedence ],
				[ "--",         _PostfixExpressionEmitter._setOperatorPrecedence ]
			], [
				// delete is not used by JSX
				[ "void",       _UnaryExpressionEmitter._setOperatorPrecedence ],
				[ "typeof",     _UnaryExpressionEmitter._setOperatorPrecedence ],
				[ "++",         _UnaryExpressionEmitter._setOperatorPrecedence ],
				[ "--",         _UnaryExpressionEmitter._setOperatorPrecedence ],
				[ "+",          _UnaryExpressionEmitter._setOperatorPrecedence ],
				[ "-",          _UnaryExpressionEmitter._setOperatorPrecedence ],
				[ "~",          _UnaryExpressionEmitter._setOperatorPrecedence ],
				[ "!",          _UnaryExpressionEmitter._setOperatorPrecedence ]
			], [
				[ "*",          _BinaryExpressionEmitter._setOperatorPrecedence ],
				[ "/",          _BinaryExpressionEmitter._setOperatorPrecedence ],
				[ "%",          _BinaryExpressionEmitter._setOperatorPrecedence ]
			], [
				[ "+",          _BinaryExpressionEmitter._setOperatorPrecedence ],
				[ "-",          _BinaryExpressionEmitter._setOperatorPrecedence ]
			], [
				[ "<<",         _BinaryExpressionEmitter._setOperatorPrecedence ],
				[ ">>",         _BinaryExpressionEmitter._setOperatorPrecedence ],
				[ ">>>",        _BinaryExpressionEmitter._setOperatorPrecedence ],
			], [
				[ "<",          _BinaryExpressionEmitter._setOperatorPrecedence ],
				[ ">",          _BinaryExpressionEmitter._setOperatorPrecedence ],
				[ "<=",         _BinaryExpressionEmitter._setOperatorPrecedence ],
				[ ">=",         _BinaryExpressionEmitter._setOperatorPrecedence ],
				[ "instanceof", _InstanceofExpressionEmitter._setOperatorPrecedence ],
				[ "in",         _BinaryExpressionEmitter._setOperatorPrecedence ]
			], [
				[ "==",         _BinaryExpressionEmitter._setOperatorPrecedence ],
				[ "!=",         _BinaryExpressionEmitter._setOperatorPrecedence ]
			], [
				[ "&",          _BinaryExpressionEmitter._setOperatorPrecedence ]
			], [
				[ "^",          _BinaryExpressionEmitter._setOperatorPrecedence ]
			], [
				[ "|",          _BinaryExpressionEmitter._setOperatorPrecedence ]
			], [
				[ "&&",         _BinaryExpressionEmitter._setOperatorPrecedence ]
			], [
				[ "||",         _BinaryExpressionEmitter._setOperatorPrecedence ]
			], [
				[ "=",          _BinaryExpressionEmitter._setOperatorPrecedence ],
				[ "*=",         _BinaryExpressionEmitter._setOperatorPrecedence ],
				[ "/=",         _BinaryExpressionEmitter._setOperatorPrecedence ],
				[ "%=",         _BinaryExpressionEmitter._setOperatorPrecedence ],
				[ "+=",         _BinaryExpressionEmitter._setOperatorPrecedence ],
				[ "-=",         _BinaryExpressionEmitter._setOperatorPrecedence ],
				[ "<<=",        _BinaryExpressionEmitter._setOperatorPrecedence ],
				[ ">>=",        _BinaryExpressionEmitter._setOperatorPrecedence ],
				[ ">>>=",       _BinaryExpressionEmitter._setOperatorPrecedence ],
				[ "&=",         _BinaryExpressionEmitter._setOperatorPrecedence ],
				[ "^=",         _BinaryExpressionEmitter._setOperatorPrecedence ],
				[ "|=",         _BinaryExpressionEmitter._setOperatorPrecedence ]
			], [
				[ "?",          _ConditionalExpressionEmitter._setOperatorPrecedence ]
			], [
				[ ",",          _CommaExpressionEmitter._setOperatorPrecedence ]
			]
		];
		for (var i = 0; i < precedence.length; ++i) {
			var opTypeList = precedence[i];
			for (var j = 0; j < opTypeList.length; ++j)
				opTypeList[j][1](opTypeList[j][0], -(precedence.length - i));
		}
	}

});
// vim: set noexpandtab:

redpajama_set_name: RedPajamaGithub


text:
Q: Why aren't selected items showing up in my owner drawn listview control? I am making an owner drawn listview, in which I am drawing shapes inside of a listview.
I have done this using Listview_DrawItem event.
My problem is that when I run the application, I can't select the shapes drawn in the listview.
private void AddItem(ListView lvw, string Shape_name, Color Shape_color)
    {
        // Make the item.
        ListViewItem item = new ListViewItem(Shape_name);

        // Save the Shape object  in the Tag property.
        Shapes myShape = new Shapes(Shape_name,Shape_color);

        item.Tag = myShape;
        item.SubItems[0].Name ="ShapeName";

        // Add subitems so they can draw.
        item.SubItems.Add("ShapeColor");

        // Add the item to the ListView.
        lvw.Items.Add(item);
    }

    // Draw the item. In this case, the Shape_name's logo.
    private void lvwServers_DrawItem(object sender, DrawListViewItemEventArgs e)
    {

        // Get the ListView item and the Shapes object.
        ListViewItem item = e.Item;

        Shapes myShape = item.Tag as Shapes;

        // Clear.
        e.DrawBackground();

        // Smoothing mode for blur free drawing
        e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

        Rectangle rect = new Rectangle(e.Bounds.Left + 10, e.Bounds.Top + 10, 41, 41);

        using (SolidBrush br = new SolidBrush(myShape.ShapeColor))
        {

            e.Graphics.FillRectangle(br, rect);
        }

        e.Graphics.DrawRectangle(Pens.Black, rect);

        e.Graphics.ResetTransform();
        e.DrawFocusRectangle();

Also, I can't change values of e.bound property.

A: You can base the drawing code in your DrawItem event handler on the value of e.State which is available in the DrawListViewItemEventArgs parameter.
bool isSelected = e.State == ListViewItemStates.Selected;

That way you can decide which elements of the drawn item you wish to change when an item is selected.

redpajama_set_name: RedPajamaStackExchange


As a nonprofit healthcare organization in central New Jersey, JFK Medical Center seeks to provide high-quality and compassionate care to diverse communities. However, the flagship acute-care hospital, with 498 beds, 3,500 employees, and a medical staff of 950, was spending vast amounts of time and money supporting an aging IT infrastructure, further slowed by the burden of burgeoning patient data.
To better support its mission and to provide clinicians across the system with quick and seamless access to data from its electronic health record (EHR) system and other computing resources, JFK replaced an aging IT infrastructure with NetApp technology, including NetApp all-flash systems. As a result of modernizing its infrastructure, JFK simplified management, lowered its costs, and positioned itself for a future where its next-generation data center can give clinicians access to secure patient records at any time, in any location, and on any device.
With our new infrastructure in place, we are able to focus on innovative new ways of delivering exceptional healthcare services.
Now JFK Medical Center can quickly move, manage, and protect all records wherever they are: the primary hospital, the satellite emergency room, rehabilitation and neuroscience centers of excellence, numerous physician practices, several long-term care facilities, and remote radiology offices.


The Space Coast has a split personality. On one hand everything seems too new. They're building new things everywhere. New developments with new houses, new roads, new businesses, and new attractions.
Beach it up at one of the top beaches on the Space Coast.
Florida's Space Coast is the surf capital of the East Coast.


Join us on April 29 for our second annual golf tournament hosted by our Men's Ministry at Druid Hills Golf Club. This will be an awesome time of golf, food, fellowship, and fun! We will play a scramble format. Cost includes golf, cart, lunch, post-tournament hor d'oeuvres, and prizes. Proceeds will benefit Northside's Disaster Response Ministry. Interested in sponsoring this event? Click here.


Built in 1904 for two families instrumental in establishing Flagstaff's early lumber industry and much of the town's infrastructure, the 13,000-square-foot duplex is an impressive reminder of gracious living in a small territorial logging town. An Arizona treasure, the historic building is a remarkable example of American Arts and Crafts-style architecture, featuring a rustic exterior composed of log-slab siding, volcanic stone arches, and hand-split wooden shingles. The Riordan Mansion interior is accessible by guided tour only, and reservations are recommended.
For more information about the Mansion, and events taking place there, visit the Arizona State Park's website for Riordan Mansion.
May – October Open Daily 9:30 a.m. to 5:00 p.m.
Tours on the hour: 10:00 a.m., 11:00 a.m., 12:00 p.m., 1:00 p.m., 2:00 p.m., 3:00 p.m. and 4:00 p.m.
November – April Open Thursdays through Mondays 10:30 a.m. – 5:00 p.m. Closed Tuesdays and Wednesdays.
Tours on the hour: 11:00 a.m., 12:00 p.m., 1:00 p.m., 2:00 p.m., 3:00 p.m. and 4:00 p.m.
Tour groups of up to 60 people can be accommodated, with advance reservations. Please call for more information.
Did you miss one of our Second Sunday Special Tours? Get together a group of 10-15 friends and call for more information. Special 90-minute tours can be arranged with advance reservations. Cost is $12.00 per person.
Riordan Mansion State Historic Park is committed to providing a comfortable environment for all visitors to enjoy the facilities. The exterior and first floor of the Mansion are wheelchair accessible. The second floor is accessible only by stairs, however, a video-tour of the second floor is available.
The main entrance is located at 409 W Riordan Rd just ¼ mile from S Milton Road (Highway 89A) and ½ mile from Historic Route 66 (Business I-40) in Flagstaff, Arizona. A pedestrian/bike entrance is located on Riordan Ranch Street.
A Mountain Line bus stop is located just a short walk from our pedestrian entrance.
The parking lot is accessible from the Riordan Road entrance. Two wheelchair accessible parking spaces are available with 35 additional spaces, including three RV/Bus spaces. Guests are welcome to drop off in the bus lane before parking.
Service Animals meeting American with Disabilities Act standards are allowed inside buildings and on tours. Leashed dogs are welcome on the grounds. Please clean up after your pets.
The interior of the Riordan Mansion is visited through a one hour guided tour. For guests with limited mobility and issues with standing for long periods of time, there are several benches throughout the house for resting. In addition, visitors may request any of the following assistance items at the front desk. These are available on a first come serve basis.
May be used as a cane, or opened to use as a seat. Maximum weight 250 lbs. Several are available.
The walker has a wide seat to allow one to sit whenever needed. Two walkers are available for use; one for upstairs & one for downstairs.
Wheelchairs (maximum width 26") can be used for the entire first floor as well as self-guided exterior tour. Two are available.
A video tour of the second floor is available at the end of the first floor tour for visitors with limited mobility.
Hearing impaired visitors may use our Electro Voice personal listening system. Headphones amplify the voice of the tour guide. Six sets of headphones are available.
FlagShakes at Riordan Mansion: God of Vengeance and Indecent Riordan Mansion State Historic Park 409 W Riordan Rd.
Experience a play at Riordan Mansion!
FlagShakes will be performing two different plays in the billiards room. Please visit their website for more information about the performances and to purchase tickets. Seating is extremely limited for these productions.
Riordan Second Sunday Special Tour: The Women of the Riordan Mansion Riordan Mansion State Historic Park 409 W Riordan Rd.
Step back to 1904 with a guided tour of the Riordan Mansion featuring the Riordan ladies and their stories. The tours are recommended for ages twelve and older. Cost is $15; $13 for AHS members. Space is limited, so reservations are required.
Brown Bag Lecture: Sports & Recreation in Milton 1890-1940 Riordan Mansion State Historic Park 409 W Riordan Rd.
What did people in Flagstaff do for fun? From bicycling to hunting, this talk will explore sports and recreation in Flagstaff and Milton at the turn of the century.
Evening Lecture: Route 66 Women: The Untold Story of the Mother Road Riordan Mansion State Historic Park 409 W Riordan Rd.
Filmmaker Katrina Parks will show segments from her documentary film series "Route 66 Women" that look in depth at Arizona's Route 66 legacy through the eyes and experiences of women who overcame segregation and gender discrimination to build fulfilling lives for themselves on America's most beloved road. Themes of growing up, traveling, challenging gender stereotypes, confronting prejudice and pushing boundaries in a man's world run-through the new oral histories.
Katrina will be joined by a panel of humanities experts including the Cline Library's archivist Sean Evans and historian and author John Westerlund who will provide historical context for the segments screened and participate in the discussion following the film. Each of these humanities experts brings their expertise in Arizona history and Route 66 to the program.
This event is made possible with support from Arizona Humanities, the state affiliate of the National Endowment for the Humanities, Riordan Mansion State Historic Park and Arizona Historical Society. Please visit www.azhumanities.org. Free and open to the public.
Enjoy a guest lecturer at 7:00 p.m. Saturday evenings.
A special event or theme tour each month.
Every second Monday at 12:15 p.m.
The Arizona Rough Riders living history group brings the Spanish-American War Era (1898) to life. Dressed in authentic period dress Rough Riders and their ladies portray the times, the war and its effects, and the social mores of turn-of-the-century America.
Riordan Mansion hosts several evening lectures during the annual festival. Visit http://www.scifest.org for the event schedule.
Riordan Mansion State Park, with its beautiful historic house, provides the perfect backdrop for tales of the fantastic and the factual. These tours are recommended for ages 12 and older. Tickets $12 per person.
Visit with Santa, make a craft, and enjoy cookies and cider. The Riordan Mansion Christmas party is a family tradition.
Exhibit panels and photographs depict the lumber industry, Flagstaff's beginnings, the Riordan families, and construction of the Riordan Mansion. A touch table features period items for visitors to explore.
Guests experience the Timothy and Caroline Riordan home, with original Stickley furniture and personal belongings on display, as if the family had just stepped out. Designed by architect Charles Whittlesey and completed in 1904, the home features all the amenities available at the time, including indoor plumbing, central heat, and electric lights.
The first floor of the Michael and Elizabeth Riordan home is filled with exhibits pertaining to the Riordan family, the Arts and Crafts style, and the lumber industry. Admission is included with the East House Guided Tour.
Available for Flagstaff schools, third grade and up. One of our volunteers or staff will visit your classroom to share photos and stories of Flagstaff's early history.
Recommended for third grade and up, this guided tour compares life for the Riordans in 1904 with life today.
The Riordan Mansion built in 1904 makes a beautiful location for an outdoor event. Weddings, memorials, reunions, and other quiet gatherings of up to 150 people can be accommodated in several locations on the grounds. The veranda with the historic arch, the forest by the hitching posts, or in the Visitor Center are all available for facility use.
Visit our Facility Rentals Guide for more details.
This Park has a gift shop in the Visitor Center with beautiful coffee table books on the Arts and Crafts Movement, Flagstaff history and childrens' history books. Souvenir items such as T-shirts, lapel pins, and magnets are also available.
The Pioneer Museum and Riordan Mansion State Historic Park are supported in part by a grant from the City of Flagstaff and the Flagstaff Arts Council.


text:
Edinburgh Edition (Change)
Confessional by Tennessee Williams
You are browsing our archive of past reviews. Shows often evolve and develop as time goes on, so the views expressed here may not be an accurate reflection of current productions.
If I walked in to a pub on a Friday night and spied a group of drunk and argumentative mates making a rowdy scene like this one, I'd be scared, perhaps even walk out. At Monk's Bar, however, I was gripped, glued to my seat. Confessional aims for an immersive experience, and thoroughly succeeds – with cast sitting among the audience, and Monk taking orders for drinks.
Theatre company Tramp have the script on their side. Tennessee Williams is the master of penning miscellaneous characters who might be described (in less polite circles) as the detritus of life, yet reveal sad souls from behind brash exteriors. And fans of the writer need not worry; the characters live in all their complexity in this production of a lesser-known play. There are a few tweaks: rather than California, the company chooses the Essex coast for its setting, and characters' accents are fittingly English too, a choice which works well.
The confessional theme is faithfully represented, and all twelve characters play their individual roles convincingly under the spotlight. If I've one reservation, it's that the sexual themes represented by Violet the nymphomaniac and the two gay guys visiting to the bar are less shocking these days than they would have been when written; in my view Violet's shameless and evidently uncontrollable urges are overplayed for our times, and attract more of our attention than necessary.
But that is forgiven, because Lizzie Stanton absolutely smashes it as beautician Leona. It's difficult to take your eyes off her, and Stanton adeptly achieves the complex character of a woman whose life has given her knocks enough to make her staunchly independent. We encounter her at a point when she's ready to move on up the coast from Treasure Island trailer park, without the lowlife she's given a rent-free home for six months. As she rants at him, she superbly pulls off a balance between aggression – letting him know exactly how it's going to be – and an observable vulnerability and loneliness.
At the end, we learn that the company lost and found a new sponsor only a few days before the Fringe. It would have been a tragedy had this powerful production not made it to Edinburgh… and I'm betting that it's only the start of great things to come for Lizzie Stanton.
This review of a show at the Edinburgh Fringe 2015 was published on Wednesday 26 August.
6-16, 18-31 Aug, 7:05pm-8:20pm
C venues – C cubed
Info & Tickets
About this reviewer
Catherine Meek
Copyright © 2006 – 2019 Fringe Guru Ltd and other contributors. Fringe Guru is a company registered in Edinburgh, number SC360286.

redpajama_set_name: RedPajamaCommonCrawl