private EvaluatedExpression FindClass(string signature)
        {
            Contract.Requires <ArgumentNullException>(signature != null, "signature");
            Contract.Requires <ArgumentException>(!string.IsNullOrEmpty(signature));
            Contract.Ensures(Contract.Result <EvaluatedExpression>() != null);

            switch (signature[0])
            {
            case 'Z':
                return(GetField(GetReflectedType(FindClass("Ljava/lang/Boolean;")), "TYPE"));

            case 'B':
                return(GetField(GetReflectedType(FindClass("Ljava/lang/Byte;")), "TYPE"));

            case 'C':
                return(GetField(GetReflectedType(FindClass("Ljava/lang/Character;")), "TYPE"));

            case 'D':
                return(GetField(GetReflectedType(FindClass("Ljava/lang/Double;")), "TYPE"));

            case 'F':
                return(GetField(GetReflectedType(FindClass("Ljava/lang/Float;")), "TYPE"));

            case 'I':
                return(GetField(GetReflectedType(FindClass("Ljava/lang/Integer;")), "TYPE"));

            case 'J':
                return(GetField(GetReflectedType(FindClass("Ljava/lang/Long;")), "TYPE"));

            case 'S':
                return(GetField(GetReflectedType(FindClass("Ljava/lang/Short;")), "TYPE"));

            case 'V':
                return(GetField(GetReflectedType(FindClass("Ljava/lang/Void;")), "TYPE"));

            case '[':
            case 'L':
                if (_classForNameMethod == null)
                {
                    _javaLangClassClass = (IClassType)_stackFrame.GetVirtualMachine().GetClassesByName("java.lang.Class").Single();
                    _classForNameMethod = _javaLangClassClass.GetConcreteMethod("forName", "(Ljava/lang/String;)Ljava/lang/Class;");
                }

                if (signature[0] != '[')
                {
                    signature = SignatureHelper.DecodeTypeName(signature);
                }

                using (var signatureValue = _stackFrame.GetVirtualMachine().GetMirrorOf(signature))
                {
                    var result = _javaLangClassClass.InvokeMethod(null, _classForNameMethod, InvokeOptions.None, signatureValue.Value);
                    return(new EvaluatedExpression(signature, signature, result.Value, true));
                }

            default:
                throw new ArgumentException();
            }
        }
        public EvaluatedExpression EvaluateCall(EvaluatedExpression obj, List <EvaluatedExpression> arguments)
        {
            Contract.Requires <ArgumentNullException>(obj != null, "obj");
            Contract.Requires <ArgumentNullException>(arguments != null, "arguments");
            Contract.Ensures(Contract.Result <EvaluatedExpression>() != null);

            IMethod method = obj.Method;

            if (method == null)
            {
                throw new ArgumentException();
            }

            IValue[] args = arguments.Select(i => i.Value).ToArray();
            IStrongValueHandle <IValue> result;

            if (method.GetIsStatic())
            {
                IClassType declaringType = (IClassType)method.GetDeclaringType();
                result = declaringType.InvokeMethod(default(IThreadReference), method, InvokeOptions.None, args);
            }
            else
            {
                IObjectReference instance = obj.Referencer;
                if (instance == null)
                {
                    throw new InvalidOperationException("Cannot call an instance method on a null object.");
                }

                result = instance.InvokeMethod(default(IThreadReference), method, InvokeOptions.None, args);
            }

            string fullName       = string.Format("{0}({1})", obj.FullName, string.Join(", ", arguments.Select(i => i.FullName)));
            bool   hasSideEffects = obj.HasSideEffects || arguments.Any(i => i.HasSideEffects);

            return(new EvaluatedExpression(fullName, fullName, method.GetReturnType(), result, hasSideEffects));
        }