/// <summary>
        /// Determines if the use of <paramref name="variable"/> in <paramref name="useExpression"/> requires a cast.
        /// </summary>
        /// <param name="useExpression">The expression being checked.</param>
        /// <param name="variable">The variable that might need to be casted.</param>
        private void AddCastIfNeeded(Expression useExpression, VariableReference variable)
        {
            switch (useExpression.CodeNodeType)
            {
            case CodeNodeType.MethodInvocationExpression:
                MethodInvocationExpression miEx = useExpression as MethodInvocationExpression;
                Expression argument             = miEx.Arguments.FirstOrDefault(x => x.CodeNodeType == CodeNodeType.VariableReferenceExpression &&
                                                                                (x as VariableReferenceExpression).Variable == variable);
                if (argument != null)
                {
                    ///The variable is passed as argument to the method.
                    int           argumentIndex = miEx.Arguments.IndexOf(argument);
                    TypeReference argumentType  = miEx.MethodExpression.Method.Parameters[argumentIndex].ResolveParameterType(miEx.MethodExpression.Method);
                    if (!IsSubtype(argumentType, variable.VariableType))
                    {
                        if (argumentType.IsPrimitive && variable.VariableType.IsPrimitive)
                        {
                            ///Integer values are not in inheritance relations. Some of them, however, can be expanded to bigger types
                            ///automatically, without the addition of a cast, i.e. Byte variable can be passed as int parameter without the
                            ///need to include a cast.
                            TypeReference containingType = ExpressionTypeInferer.GetContainingType(argumentType.Resolve(), variable.VariableType.Resolve());
                            if (containingType.FullName == argumentType.FullName)
                            {
                                ///Then the type of the argument contains the type of the variable, thus no cast is needed.
                                return;
                            }
                        }

                        ///Then a cast is needed.
                        miEx.Arguments[argumentIndex] = new CastExpression(argument, argumentType, null);
                        ///This should be enough to update the expression everywhere it is seen.
                    }
                }
                else
                {
                    /// Then the variable is the object from which the method is called
                    /// variable.SomeMethod(...);
                    Expression target = miEx.MethodExpression.Target;
                    if (target.CodeNodeType == CodeNodeType.VariableReferenceExpression && (target as VariableReferenceExpression).Variable == variable)
                    {
                        TypeReference targetType = miEx.MethodExpression.Method.DeclaringType;
                        if (!IsSubtype(targetType, variable.VariableType))
                        {
                            miEx.MethodExpression.Target = new CastExpression(target, targetType, null);
                        }
                    }
                    else
                    {
                        ///This should not be reachable, but anyway.
                        AddCastIfNeeded(target, variable);
                    }
                }
                break;

            case CodeNodeType.BinaryExpression:
                BinaryExpression binEx = useExpression as BinaryExpression;
                if (binEx.Operator == BinaryOperator.Assign)
                {
                    if (binEx.Right.CodeNodeType == CodeNodeType.VariableReferenceExpression &&
                        (binEx.Right as VariableReferenceExpression).Variable == variable)
                    {
                        TypeReference assignedAs = binEx.Left.ExpressionType;
                        ///binex.Right should be VariableReferenceExpression to 'variable'.
                        if (!IsSubtype(assignedAs, variable.VariableType))
                        {
                            binEx.Right = new CastExpression(binEx.Right, assignedAs, null);
                        }
                    }
                }
                break;
                //default:
                //throw new NotSupportedException("Not supported cast expression.");
            }
        }
 private void AddCastIfNeeded(Expression useExpression, VariableReference variable)
 {
     V_0          = new TypeInferer.u003cu003ec__DisplayClass8_0();
     V_0.variable = variable;
     V_4          = useExpression.get_CodeNodeType();
     if (V_4 == 19)
     {
         V_1 = useExpression as MethodInvocationExpression;
         V_2 = V_1.get_Arguments().FirstOrDefault <Expression>(new Func <Expression, bool>(V_0.u003cAddCastIfNeededu003eb__0));
         if (V_2 == null)
         {
             V_7 = V_1.get_MethodExpression().get_Target();
             if (V_7.get_CodeNodeType() != 26 || (object)(V_7 as VariableReferenceExpression).get_Variable() != (object)V_0.variable)
             {
                 this.AddCastIfNeeded(V_7, V_0.variable);
                 return;
             }
             V_8 = V_1.get_MethodExpression().get_Method().get_DeclaringType();
             if (!this.IsSubtype(V_8, V_0.variable.get_VariableType()))
             {
                 V_1.get_MethodExpression().set_Target(new ExplicitCastExpression(V_7, V_8, null));
                 return;
             }
         }
         else
         {
             V_5 = V_1.get_Arguments().IndexOf(V_2);
             V_6 = V_1.get_MethodExpression().get_Method().get_Parameters().get_Item(V_5).ResolveParameterType(V_1.get_MethodExpression().get_Method());
             if (!this.IsSubtype(V_6, V_0.variable.get_VariableType()))
             {
                 if (V_6.get_IsPrimitive() && V_0.variable.get_VariableType().get_IsPrimitive() && String.op_Equality(ExpressionTypeInferer.GetContainingType(V_6.Resolve(), V_0.variable.get_VariableType().Resolve()).get_FullName(), V_6.get_FullName()))
                 {
                     return;
                 }
                 V_1.get_Arguments().set_Item(V_5, new ExplicitCastExpression(V_2, V_6, null));
                 return;
             }
         }
     }
     else
     {
         if (V_4 != 24)
         {
             return;
         }
         V_3 = useExpression as BinaryExpression;
         if (V_3.get_Operator() == 26 && V_3.get_Right().get_CodeNodeType() == 26 && (object)(V_3.get_Right() as VariableReferenceExpression).get_Variable() == (object)V_0.variable)
         {
             V_9 = V_3.get_Left().get_ExpressionType();
             if (!this.IsSubtype(V_9, V_0.variable.get_VariableType()))
             {
                 V_3.set_Right(new ExplicitCastExpression(V_3.get_Right(), V_9, null));
             }
         }
     }
     return;
 }