public CodeMethodInvokeExpression(CodeExpression targetObject,
						   string methodName,
						   params CodeExpression[] parameters)
		{
			this.method = new CodeMethodReferenceExpression(targetObject, methodName);
			this.Parameters.AddRange(parameters);
		}
		protected override void GenerateMethodReferenceExpression(CodeMethodReferenceExpression expression)
		{
			if (expression.TargetObject != null)
			{
				base.GenerateExpression(expression.TargetObject);
				base.Output.Write('.');
			}
			base.Output.Write(this.GetSafeName(expression.MethodName));
			if (expression.TypeArguments.Count > 0)
			{
				base.Output.Write(this.GetTypeArguments(expression.TypeArguments));
			}
		}
		public CodeMethodInvokeExpression(CodeMethodReferenceExpression method, params CodeExpression[] parameters)
		{
			this.method = method;
			this.Parameters.AddRange(parameters);
		}
		public CodeExpression GetExpression(InstructionForm frm, int argIdx, WriteOperation wrOp)
		{
			int curIdx = 0;
			Token tok = toks[curIdx];
			if (tok.Type != TokenType.Identifier)
				throw new Exception("Expected an identifier!");

			if (tok.Value == "ToString")
			{
				curIdx++;

				tok = toks[curIdx];
				if (tok.Type != TokenType.LParen)
					throw new Exception("Expected an opening parenthesis!");
				curIdx++;

				tok = toks[curIdx];
				if (tok.Type != TokenType.Identifier)
					throw new Exception("Expected an identifier for the expression to convert to a string!");
				CodeExpression ldExpr = GetExpressionFromIdentifier(tok.Value, frm, argIdx, wrOp);
				curIdx++;

				tok = toks[curIdx];
				if (tok.Type != TokenType.RParen)
					throw new Exception("Expected the closing parenthesis!");
				curIdx++;

				return new CodeMethodInvokeExpression(
					ldExpr,
					"ToString"
				);
			}
			else if (tok.Value == "DirectCast")
			{
				curIdx++;

				tok = toks[curIdx];
				if (tok.Type != TokenType.LParen)
					throw new Exception("Expected an opening parenthesis!");
				curIdx++;

				tok = toks[curIdx];
				if (tok.Type != TokenType.Identifier)
					throw new Exception("Expected an identifier representing the argument to cast!");
				CustomInstructionArgParameter param;
				if (!ParentArg.Parameters.TryGetValue(tok.Value, out param))
					throw new Exception("Unknown parameter '" + tok.Value + "'!");
				CodeExpression argLoadExpression = param.GetLoadExpression(frm, argIdx);
				curIdx++;

				tok = toks[curIdx];
				if (tok.Type != TokenType.Comma)
					throw new Exception("Expected a comma before the destination type!");
				curIdx++;

				tok = toks[curIdx];
				if (tok.Type != TokenType.Identifier)
					throw new Exception("Expected an identifier representing the type to cast to!");
				CodeTypeReference destType;
				switch(tok.Value.ToLower())
				{
					case "byte":
						destType = StaticTypeReferences.Byte;
						break;
					case "sbyte":
						destType = StaticTypeReferences.SByte;
						break;
					case "ushort":
						destType = StaticTypeReferences.UShort;
						break;
					case "short":
						destType = StaticTypeReferences.Short;
						break;
					case "uint":
						destType = StaticTypeReferences.UInt;
						break;
					case "int":
						destType = StaticTypeReferences.Int;
						break;
					case "ulong":
						destType = StaticTypeReferences.ULong;
						break;
					case "long":
						destType = StaticTypeReferences.Long;
						break;
					default:
						destType = new CodeTypeReference(tok.Value);
						break;
				}
				curIdx++;

				tok = toks[curIdx];
				if (tok.Type != TokenType.RParen)
					throw new Exception("Expected closing parenthesis!");
				curIdx++;

				return new CodeCastExpression(
					destType,
					argLoadExpression
				);
			}
			else
			{
				CodeExpression sourceExpression;
				bool NamedArgNeedsCast = false;
				if (tok.Value == "Stream")
				{
					sourceExpression = StaticTypeReferences.Emit_StreamArg;
				}
				else
				{
					if (tok.Value == "BitPatterns")
						NamedArgNeedsCast = true;
					sourceExpression = new CodeTypeReferenceExpression(tok.Value);
				}
				curIdx++;
			
				tok = toks[curIdx];
				if (tok.Type != TokenType.Dot)
					throw new Exception("Expected a dot!");
				curIdx++;
			
				tok = toks[curIdx];
				if (tok.Type != TokenType.Identifier)
					throw new Exception("Expected an identifier!");
				CodeMethodReferenceExpression methodRef = new CodeMethodReferenceExpression(
					sourceExpression,
					NamedArgNeedsCast ? BitPatternRegistry.GetPattern(tok.Value).Name : tok.Value
				);
				curIdx++;

				tok = toks[curIdx];
				if (tok.Type != TokenType.LParen)
					throw new Exception("Expected an opening parenthesis!");
				curIdx++;

				List<CodeExpression> parms = new List<CodeExpression>(8);
				tok = toks[curIdx];
				bool expectsAnotherArg = true;
				while (tok.Type != TokenType.RParen)
				{
					if (!expectsAnotherArg)
						throw new Exception("Didn't expect another arg!");
					switch (tok.Type)
					{
						case TokenType.Identifier:
							parms.Add(GetExpressionFromIdentifier(tok.Value, frm, argIdx, wrOp, NamedArgNeedsCast));
							break;
						case TokenType.Number:
							if (tok.NumberValue.Format == NumberFormat.Decimal)
							{
								parms.Add(new CodePrimitiveExpression((int)tok.NumberValue.Value));
							}
							else
							{
								parms.Add(new CodePrimitiveExpression(tok.NumberValue.Value));
							}
							break;
						default:
							throw new Exception("Unknown token type!");
					}
					curIdx++;

					tok = toks[curIdx];
					if (tok.Type != TokenType.Comma)
					{
						expectsAnotherArg = false;
					}
					else
					{
						curIdx++;
						tok = toks[curIdx];
					}
				}
				if (expectsAnotherArg)
					throw new Exception("Expected another arg!");

				return new CodeMethodInvokeExpression(
					methodRef,
					parms.ToArray()
				);
			}
		}