private void FixArguments(MethodReference method, ExpressionCollection arguments)
		{
			TypeDefinition declaringTypeDefinition = method.DeclaringType.Resolve();
			if (declaringTypeDefinition == null)
			{
				return;
			}
			List<MethodDefinition> sameNameMethods = GetSameNameMethods(declaringTypeDefinition, method, arguments);
			if (sameNameMethods.Count > 0)
			{
				for (int i = 0; i < arguments.Count; i++)
				{
					TypeReference paramType = method.Parameters[i].ResolveParameterType(method);
					if (!arguments[i].HasType)
					{
						continue;
					}
					if (arguments[i].ExpressionType.FullName == paramType.FullName)
					{
						continue;
					}
					if (ShouldAddCast(arguments[i], sameNameMethods, i, paramType))
					{
						arguments[i] = new CastExpression(arguments[i], paramType, null);
					}
				}
			}
		}
		public override void VisitCastExpression(CastExpression node)
		{
			TypesDependingOn.UnionWith(Utilities.GetTypeReferenceTypesDepedningOn(node.ExpressionType));
            if (node.UnresolvedReferenceForAmbiguousCastToObject != null)
            {
                this.AmbiguousCastsToObject.Add(node);
            }

            base.VisitCastExpression(node);
		}
        private void VisitInvocationArguments(ExpressionCollection arguments, MethodReference method)
        {
			Collection<ParameterDefinition> parameters = method.Parameters;
            for (int index = 0; index < arguments.Count; index++)
            {
				TypeReference paramType = parameters[index].ResolveParameterType(method);
                if (NeedsCast(arguments[index].ExpressionType, paramType))
                {
                    if (arguments[index].CodeNodeType == CodeNodeType.LiteralExpression)
                    {
						arguments[index] = EnumHelper.GetEnumExpression(paramType.Resolve(), (arguments[index] as LiteralExpression), typeSystem);
                    }
					else
					{
						arguments[index] = new CastExpression(arguments[index], paramType, null);
					}
                }
            }
        }
        public override ICodeNode VisitCastExpression(CastExpression node)
        {
            if (node.Expression.CodeNodeType == CodeNodeType.LiteralExpression)
            {
                TypeDefinition typeDef = node.ExpressionType.Resolve();
                if (typeDef != null && typeDef.IsEnum && !node.ExpressionType.IsArray)
                {
					return EnumHelper.GetEnumExpression(node.ExpressionType.Resolve(), node.Expression as LiteralExpression, typeSystem);
                }
                return node;
            }
            else
            {
                return base.VisitCastExpression(node);
            }
        }
        public override Expression CloneExpressionOnly()
        {
			CastExpression result = new CastExpression(Expression.CloneExpressionOnly(), TargetType, null) 
										{
                                            IsChecked = this.IsChecked,
                                            IsExplicitInterfaceCast = this.IsExplicitInterfaceCast,
                                            UnresolvedReferenceForAmbiguousCastToObject = this.UnresolvedReferenceForAmbiguousCastToObject
                                        };
            return result;
        }
		private void CastMethodArguments(MethodReference method, ExpressionCollection arguments)
		{
			for (int i = 0; i < arguments.Count; i++)
			{
				Expression argument = arguments[i];

				TypeReference parameterType = method.Parameters[i].ResolveParameterType(method);

				if (argument.HasType && parameterType != null && !(argument is LiteralExpression))
				{
					TypeReference argumentType = argument.ExpressionType;
					if ((IsUnsignedIntegerType(argumentType) && IsSignedIntegerType(parameterType)) || (IsSignedIntegerType(argumentType) && IsUnsignedIntegerType(parameterType)))
					{
						Expression toCast = argument;

						if (argument is CastExpression)
						{
							CastExpression argumentCast = argument as CastExpression;
							if (IsIntegerType(argumentCast.TargetType))
							{
								toCast = argumentCast.Expression;
							}
						}

						arguments[i] = new CastExpression(toCast, parameterType, null);
					}
				}
			}
		}
        private void WriteCastExpression(CastExpression node)
        {
            bool isComplexCastTarget = IsComplexTarget(node.Expression);

            if (isComplexCastTarget)
            {
                WriteToken("(");
            }

            Visit(node.Expression);

            if (isComplexCastTarget)
            {
                WriteToken(")");
            }
        }
        public override ICodeNode VisitCastExpression(CastExpression node)
        {
			if (node.Expression.CodeNodeType == CodeNodeType.LiteralExpression && node.TargetType.FullName == currentTypeSystem.Boolean.FullName)
            {
                FixBooleanLiteral(node.Expression as LiteralExpression);
                return node.Expression.CloneAndAttachInstructions(node.MappedInstructions);
            }

            if (node.Expression.CodeNodeType == CodeNodeType.LiteralExpression && node.TargetType.FullName == currentTypeSystem.Char.FullName)
            {
                FixCharLiteral(node.Expression as LiteralExpression);
                return node.Expression.CloneAndAttachInstructions(node.MappedInstructions);
            }

            return base.VisitCastExpression(node);
        }
        public override void VisitCastExpression(CastExpression node)
        {
            var castMethod = GetCastMethod(node.TargetType);
            if (castMethod == null)
            {
                WriteKeyword("DirectCast");
                WriteToken("(");
                WriteCastExpression(node);
                WriteToken(",");
                WriteSpace();
                WriteReferenceAndNamespaceIfInCollision(node.TargetType);
            }
            else
            {
                if (node.UnresolvedReferenceForAmbiguousCastToObject == null)
                {
                    WriteKeyword(castMethod);
                }
                else
                {
                    TypeReference lastResolvedType;
                    Common.Extensions.ResolveToOverloadedEqualityOperator(node.Expression.ExpressionType, out lastResolvedType);
                    WriteNotResolvedReference(castMethod, lastResolvedType, string.Format(CastToObjectResolvementError, lastResolvedType.Name));
                }

                WriteToken("(");
                WriteCastExpression(node);
            }
            WriteToken(")");
        }
        public override void VisitCastExpression(CastExpression node)
        {
            if (node.IsChecked)
            {
                WriteKeyword(KeyWordWriter.Checked);
                WriteToken("(");
            }
            WriteToken("(");
            if (node.IsDynamic)
            {
                WriteDynamicType(node.TargetType, node.DynamicPositioningFlags);
            }
            else
            {
                if (node.UnresolvedReferenceForAmbiguousCastToObject == null)
                {
                    WriteReferenceAndNamespaceIfInCollision(node.TargetType);
                }
                else
                {
                    TypeReference lastResolvedType;
                    Common.Extensions.ResolveToOverloadedEqualityOperator(node.Expression.ExpressionType, out lastResolvedType);
                    WriteNotResolvedReference("object", lastResolvedType, string.Format(CastToObjectResolvementError, lastResolvedType.Name));
                }
            }
            WriteToken(")");

            bool isComplexCastTarget = IsComplexTarget(node.Expression);

            if (isComplexCastTarget)
            {
                WriteToken("(");
            }

            Visit(node.Expression);

            if (isComplexCastTarget)
            {
                WriteToken(")");
            }
            if (node.IsChecked)
            {
                WriteToken(")");
            }
        }
		private void HandleCastArgument(TypeReference parameterType, CastExpression castArgument)
		{
			if (parameterType.FullName == currentTypeSystem.Char.FullName && castArgument.ExpressionType.FullName == currentTypeSystem.UInt16.FullName)
			{
				castArgument.TargetType = currentTypeSystem.Char;
			}
		}
 public virtual void VisitCastExpression(CastExpression node)
 {
     Visit(node.Expression);
 }
 private void MarkDynamicArguments(CallSiteInfo callSiteInfo, IList<Expression> arguments)
 {
     foreach (int index in callSiteInfo.DynamicArgumentIndices)
     {
         if (arguments[index].CodeNodeType != CodeNodeType.BinaryExpression &&
             (arguments[index].CodeNodeType != CodeNodeType.UnaryExpression || (arguments[index] as UnaryExpression).Operator != UnaryOperator.None) &&
             arguments[index].CodeNodeType != CodeNodeType.DynamicIndexerExpression &&
             arguments[index].CodeNodeType != CodeNodeType.DynamicMemberReferenceExpression &&
             !DynamicElementAnalyzer.Analyze(arguments[index]))
         {
             CastExpression theCastExpression = new CastExpression(arguments[index], objectTypeRef, null);
             theCastExpression.DynamicPositioningFlags = new bool[] { true };
             arguments[index] = theCastExpression;
         }
     }
 }
            public override ICodeNode VisitUnaryExpression(UnaryExpression node)
            {
                if (node.Operator == UnaryOperator.AddressDereference)
                {
					if (node.Operand is UnaryExpression)
					{
						UnaryExpression unaryOperand = node.Operand as UnaryExpression;
						if (unaryOperand.Operator == UnaryOperator.AddressOf || unaryOperand.Operator == UnaryOperator.AddressReference)
						{
							return Visit(unaryOperand.Operand);
						}
					}
					if (node.Operand is CastExpression && node.Operand.ExpressionType.IsByReference)
					{
						CastExpression theCast = node.Operand as CastExpression;
						TypeReference targetType = (theCast.ExpressionType as ByReferenceType).ElementType;
						CastExpression result = new CastExpression(theCast.Expression, targetType, theCast.MappedInstructions);
						return Visit(result);
					}
                }
                return base.VisitUnaryExpression(node);
            }
		private void CheckArguments(Mono.Collections.Generic.Collection<ParameterDefinition> parameters, ExpressionCollection arguments)
		{
			for (int i = 0; i < arguments.Count; i++)
			{
				Expression argument = arguments[i];
				if (argument.HasType)
				{
					TypeDefinition argumentType = argument.ExpressionType.Resolve();
					TypeReference parameterType = parameters[i].ParameterType;
					if (ShouldAddCast(argumentType, parameterType))
					{
						arguments[i] = new CastExpression(argument, parameterType, null);
					}
				}
			}
		}
		private Expression FixCaseLiteralValue(LiteralExpression literalCondition)
		{
			TypeReference conditionType = theSwitch.Condition.ExpressionType;
			int integerRepresentation = Convert.ToInt32(literalCondition.Value) + this.conditionOffset;
			literalCondition.Value = integerRepresentation;
			var theTypeSystem = context.MethodContext.Method.Module.TypeSystem;

			if (conditionType.Name == "System.Nullable`1" && conditionType.HasGenericParameters)
			{
				conditionType = conditionType.GenericParameters[0];
			}
			if (conditionType.FullName == theTypeSystem.Char.FullName)
			{
				//switch cases should have char labels;
				return new LiteralExpression(Convert.ToChar(integerRepresentation),theTypeSystem, null);
			}
			else if (conditionType.FullName == theTypeSystem.Boolean.FullName)
			{
				return new LiteralExpression(Convert.ToBoolean(integerRepresentation),theTypeSystem,null);
			}
			else
			{
				TypeDefinition resolvedConditionType = conditionType.Resolve();
				if (resolvedConditionType != null && resolvedConditionType.IsEnum)
				{
					Expression result = EnumHelper.GetEnumExpression(resolvedConditionType,literalCondition,theTypeSystem);
					if (result is LiteralExpression)
					{
						result = new CastExpression(result, resolvedConditionType, null);
					}
					return result;
				}
			}
			return literalCondition;
		}