protected internal override void VisitUnaryExpression(UnaryExpression expression)
			{
				Ssm.UOp op;

				switch (expression.Operator)
				{
					case UnaryOperator.Minus:
						op = Ssm.UOp.Minus;
						break;
					case UnaryOperator.Not:
						op = Ssm.UOp.Not;
						break;
					default:
						Assert.NotReached("Unsupported unary operator.");
						return;
				}

				_expr = Ssm.Expr.NewUExpr(op, GetTransformed(expression.Operand));
			}
			protected internal override void VisitVariableExpression(VariableExpression expression)
			{
				if (expression.Variable.IsParameter)
					_expr = Ssm.Expr.NewVarExpr(Ssm.Var.NewLocal(expression.Variable.Name, Transform(expression.Variable.Type)));
				else
					_expr = Ssm.Expr.NewVarExpr(Ssm.Var.NewArg(expression.Variable.Name, Transform(expression.Variable.Type)));
			}
			protected internal override void VisitMethodInvocationExpression(MethodInvocationExpression expression)
			{
				_expr = Ssm.CreateCall(expression.Method.Name, expression.Method.MethodInfo.DeclaringType.FullName,
					expression.Method.MethodInfo.GetParameters().Select(p => Transform(p.ParameterType)),
					expression.Method.MethodInfo.GetParameters().Select(p =>
					{
						if (p.IsOut)
							return Ssm.ParamDir.Out;

						if (p.ParameterType.IsByRef)
							return Ssm.ParamDir.InOut;

						return Ssm.ParamDir.In;
					}), Transform(expression.Method.MethodInfo.ReturnType), expression.Arguments.Select(GetTransformed));

				if (expression.Method.DeclaringObject == _this)
					return;

				var component = (ComponentMetadata)expression.Method.DeclaringObject;
				var field = Ssm.Var.NewField(component.Name, Ssm.Type.NewClassType(component.GetType().FullName));
				_expr = Ssm.Expr.NewMemberExpr(field, _expr);
			}
			protected internal override void VisitIntegerLiteralExpression(IntegerLiteralExpression expression)
			{
				_expr = Ssm.Expr.NewIntExpr(expression.Value);
			}
			protected internal override void VisitFieldExpression(FieldExpression expression)
			{
				_expr = Ssm.Expr.NewVarExpr(Ssm.Var.NewField(expression.Field.Name, Transform(expression.Field.Type)));
			}
			protected internal override void VisitEnumerationLiteralExpression(EnumerationLiteralExpression expression)
			{
				_expr = Ssm.Expr.NewIntExpr(expression.IntegerValue);
			}
			protected internal override void VisitDoubleLiteralExpression(DoubleLiteralExpression expression)
			{
				_expr = Ssm.Expr.NewDoubleExpr(expression.Value);
			}
			protected internal override void VisitBooleanLiteralExpression(BooleanLiteralExpression expression)
			{
				_expr = Ssm.Expr.NewBoolExpr(expression.Value);
			}
			protected internal override void VisitBinaryExpression(BinaryExpression expression)
			{
				Ssm.BOp op;
				switch (expression.Operator)
				{
					case BinaryOperator.Add:
						op = Ssm.BOp.Add;
						break;
					case BinaryOperator.Subtract:
						op = Ssm.BOp.Sub;
						break;
					case BinaryOperator.Multiply:
						op = Ssm.BOp.Mul;
						break;
					case BinaryOperator.Divide:
						op = Ssm.BOp.Div;
						break;
					case BinaryOperator.Modulo:
						op = Ssm.BOp.Mod;
						break;
					case BinaryOperator.And:
						op = Ssm.BOp.And;
						break;
					case BinaryOperator.Or:
						op = Ssm.BOp.Or;
						break;
					case BinaryOperator.Equals:
						op = Ssm.BOp.Eq;
						break;
					case BinaryOperator.NotEquals:
						op = Ssm.BOp.Ne;
						break;
					case BinaryOperator.Less:
						op = Ssm.BOp.Lt;
						break;
					case BinaryOperator.LessEqual:
						op = Ssm.BOp.Le;
						break;
					case BinaryOperator.Greater:
						op = Ssm.BOp.Gt;
						break;
					case BinaryOperator.GreaterEqual:
						op = Ssm.BOp.Ge;
						break;
					default:
						Assert.NotReached("Unsupported binary operator.");
						return;
				}

				_expr = Ssm.Expr.NewBExpr(GetTransformed(expression.LeftOperand), op, GetTransformed(expression.RightOperand));
			}