/// <summary>
        /// Since we need to use ourselves.
        /// </summary>
        /// <param name="method"></param>
        /// <param name="instruction"></param>
        /// <param name="indentStart"></param>
        /// <returns></returns>
        public static string ParseInstruction(MethodDefinition method, Instruction instruction, int indentStart)
        {
            var    opcode = instruction.OpCode;
            string output = "";

            //output += AssemblyHelper.Indent("// {0}: {1} {2}", indentStart, instruction.Offset, instruction.OpCode, instruction.Operand) + Environment.NewLine;

            if (InstructionHelper.IsBranchConditional(opcode.Code))
            {
                output += Indent(GetIfStatement(method, instruction), indentStart) + Environment.NewLine;
                output += ParseInstruction(method, instruction.Operand as Instruction, indentStart + 1);
            }

            // Check if the instruction is for
            // storing a value onto a variable
            if (InstructionHelper.IsStore(opcode.Code))
            {
                output += Indent(GetStoreLocation(method, instruction) + " = " + GetValueOf(method, instruction.Previous) + ";", indentStart) + Environment.NewLine;
            }
            // Check if we want to return the method
            // And if there is any value we want to return.
            else if (opcode.Code == Code.Ret)
            {
                if (InstructionHelper.IsLoad(instruction.Previous.OpCode.Code))
                {
                    output += Indent("return " + GetValueOf(method, instruction.Previous) + ";", indentStart) + Environment.NewLine;
                }
                else
                {
                    output += Indent("return;", indentStart) + Environment.NewLine;
                }
            }

            return(output);
        }
        public static string GetIfStatement(MethodDefinition method, Instruction instruction)
        {
            var target      = "";
            var ifStatement = "if(";
            var prev        = instruction.Previous;

            if (InstructionHelper.IsLoad(prev.OpCode.Code))
            {
                target = GetValueOf(method, prev);
            }
            if (InstructionHelper.IsBranchOnFalse(instruction.OpCode.Code))
            {
                ifStatement += "!";
            }
            return(ifStatement + target + ")");
        }
        public static string GetConditionalStatement(MethodDefinition method, Instruction instruction)
        {
            var code = instruction.OpCode.Code;
            var val2 = instruction.Previous;
            var val1 = val2.Previous;

            if (InstructionHelper.IsEqualTo(code))
            {
                return(GetValueOf(method, val1) + " == " + GetValueOf(method, val2));
            }
            else if (InstructionHelper.IsLessThan(code))
            {
                return(GetValueOf(method, val1) + " < " + GetValueOf(method, val2));
            }
            else
            {
                return(GetValueOf(method, val1) + " > " + GetValueOf(method, val2));
                // IsGreaterThan
            }
        }
        /// <summary>
        /// This function will return the name of the variable, argument, etc
        /// that we want to store our value into.
        /// </summary>
        /// <param name="method"></param>
        /// <param name="instruction"></param>
        /// <returns></returns>
        public static string GetStoreLocation(MethodDefinition method, Instruction instruction)
        {
            var code = instruction.OpCode.Code;

            if (instruction.Operand != null && !InstructionHelper.IsStoreN(code))
            {
                return(instruction.Operand.ToString());
            }

            if (InstructionHelper.IsStoreLocalVariable(code))
            {
                if (InstructionHelper.IsStoreN(code))
                {
                    /* Not yet implemented. */
                }
                else
                {
                    var index = InstructionHelper.GetCodeIndex(code);
                    return(GetVariableName(method.Body.Variables[index]));
                }
            }

            if (InstructionHelper.IsStoreArgument(code))
            {
                if (InstructionHelper.IsStoreN(code))
                {
                    return(instruction.Operand.ToString());
                }
                else
                {
                    var index = InstructionHelper.GetCodeIndex(code);
                    return(method.Parameters[index].Name);
                }
            }

            return("");
        }
        /// <summary>
        /// This function will return a string, representing the values grabbed from the instruction
        /// </summary>
        /// <param name="instruction"></param>
        /// <returns></returns>
        public static string GetValueOf(MethodDefinition method, Instruction instruction)
        {
            var code = instruction.OpCode.Code;

            // If this is a conditional instruction. lets return the value of that.
            if (InstructionHelper.IsConditional(instruction.OpCode.Code))
            {
                return(GetConditionalStatement(method, instruction));
            }


            // Check if we are trying to load a value
            // Can be, Load a field, load a constant value, argument
            // variable and more.
            if (InstructionHelper.IsLoad(code))
            {
                // Check if we want to return a null value
                if (InstructionHelper.IsLoadNull(instruction.OpCode.Code))
                {
                    return("null");
                }

                // For now, we will settle with just handling integers.
                // We will have to add more if checks later to support
                // strings, variables, etc.
                if (InstructionHelper.IsLoadInteger(code))
                {
                    // In case the integer is bigger than 4
                    // We will need to get the value from the
                    // operand instead of the "index".
                    if (InstructionHelper.IsLoadN(code))
                    {
                        return(instruction.Operand.ToString());
                    }
                    else
                    {
                        // The GetCodeIndex will return the value used from
                        // the constant load. For instance ldc.i4.4 will return
                        // the value 4, ldc.i4.3 will return value 3. Etc.
                        return(InstructionHelper.GetCodeIndex(code).ToString());
                    }
                }

                // Check if we want to load a string
                // if so, then return the value from the operand.
                if (InstructionHelper.IsLoadString(code))
                {
                    return("\"" + instruction.Operand + "\"");
                }

                // If we want to load a local variable.
                // So be it!
                if (InstructionHelper.IsLoadLocalVariable(code))
                {
                    if (InstructionHelper.IsLoadN(code))
                    {
                        var targetVariable = instruction.Operand as VariableDefinition;
                        return(GetVariableName(targetVariable));
                    }
                    else
                    {
                        var index = InstructionHelper.GetCodeIndex(code);
                        return(GetVariableName(method.Body.Variables[index]));
                    }
                }

                // If we want to load the value of a argument
                // Then this is necessary.
                if (InstructionHelper.IsLoadArgs(code))
                {
                    if (InstructionHelper.IsLoadN(code))
                    {
                        return(instruction.Operand.ToString());
                    }
                    else
                    {
                        var index = InstructionHelper.GetCodeIndex(code);
                        if (method.IsConstructor)
                        {
                            index--;
                        }
                        return(method.Parameters[index].Name);
                    }
                }
            }

            // If our instructions are to call a method
            if (InstructionHelper.IsCallMethod(code))
            {
                // We will need to grab the information of that specific method
                // By casting the Operand into a MethodDefinition.
                var callingMethod = instruction.Operand as MethodDefinition;
                // Note: We are not managing any parameters yet.
                return(callingMethod.Name + "()");
            }
            // Return a empty value if we can't determine what we want to return.
            return("");
        }