public int SetThreadName(string pszName)
        {
#if HIDE_THREADS
            return(VSConstants.S_OK);
#endif

            if (_setThreadNameMethod == null)
            {
                IClassType type = (IClassType)_thread.GetReferenceType();
                _setThreadNameMethod = type.GetConcreteMethod("setName", "(Ljava/lang/String;)V");
            }

            if (_setThreadNameMethod == null)
            {
                return(VSConstants.E_FAIL);
            }

            using (var stringValue = _program.VirtualMachine.GetMirrorOf(pszName))
            {
                using (_thread.InvokeMethod(null, _setThreadNameMethod, InvokeOptions.None, stringValue.Value))
                {
                    return(VSConstants.S_OK);
                }
            }
        }
        public int GetThreadPriorityId(out int priorityId)
        {
#if HIDE_THREADS
            priorityId = 0;
            return(VSConstants.S_OK);
#endif

            if (_getPriorityMethod == null)
            {
                IClassType type = (IClassType)_thread.GetReferenceType();
                _getPriorityMethod = type.GetConcreteMethod("getPriority", "()I");
            }

            priorityId = 0;
            if (_getPriorityMethod == null)
            {
                return(VSConstants.E_FAIL);
            }

            try
            {
                using (var result = _thread.InvokeMethod(null, _getPriorityMethod, InvokeOptions.SingleThreaded))
                {
                    priorityId = ((IIntegerValue)result.Value).GetValue();
                    return(VSConstants.S_OK);
                }
            }
            catch (DebuggerException)
            {
                priorityId = 0;
                return(VSConstants.E_FAIL);
            }
        }
        public int GetThreadId(out uint pdwThreadId)
        {
#if HIDE_THREADS
            pdwThreadId = 0;
            return(VSConstants.S_OK);
#endif

            if (_getIdMethod == null)
            {
                IClassType type = (IClassType)_thread.GetReferenceType();
                _getIdMethod = type.GetConcreteMethod("getId", "()J");
            }

            pdwThreadId = 0;
            if (_getIdMethod == null)
            {
                return(VSConstants.E_FAIL);
            }

            try
            {
                using (var result = _thread.InvokeMethod(null, _getIdMethod, InvokeOptions.SingleThreaded))
                {
                    pdwThreadId = (uint)((ILongValue)result.Value).GetValue();
                    return(VSConstants.S_OK);
                }
            }
            catch (DebuggerException)
            {
                pdwThreadId = 0;
                return(VSConstants.E_FAIL);
            }
        }
        private static bool TryGetCollectionValues(IObjectReference objectReference, out ReadOnlyCollection <IValue> values, out IType elementType)
        {
            IArrayReference arrayReference = objectReference as IArrayReference;

            if (arrayReference == null)
            {
                int size;
                if (TryGetCollectionSize(objectReference, out size))
                {
                    IClassType classType = objectReference.GetReferenceType() as IClassType;
                    if (classType != null)
                    {
                        IObjectReference collectionObject = null;

                        ReadOnlyCollection <IInterfaceType> interfaces = classType.GetInterfaces(true);
                        if (interfaces.Any(i => i.GetName() == "java.util.Collection"))
                        {
                            collectionObject = objectReference;
                        }
                        else if (interfaces.Any(i => i.GetName() == "java.util.Map"))
                        {
                            IMethod entrySetMethod             = classType.GetConcreteMethod("entrySet", "()Ljava/util/Set;");
                            IStrongValueHandle <IValue> result = objectReference.InvokeMethod(null, entrySetMethod, InvokeOptions.None);
                            if (result != null)
                            {
                                collectionObject = result.Value as IObjectReference;
                            }
                        }

                        if (collectionObject != null)
                        {
                            IClassType collectionObjectType = collectionObject.GetReferenceType() as IClassType;
                            if (collectionObjectType != null)
                            {
                                IMethod toArrayMethod = collectionObjectType.GetConcreteMethod("toArray", "()[Ljava/lang/Object;");
                                IStrongValueHandle <IValue> result = collectionObject.InvokeMethod(null, toArrayMethod, InvokeOptions.None);
                                if (result != null)
                                {
                                    arrayReference = result.Value as IArrayReference;
                                }
                            }
                        }
                    }
                }
            }

            if (arrayReference != null)
            {
                values = arrayReference.GetValues();
                IArrayType arrayType = (IArrayType)arrayReference.GetReferenceType();
                elementType = arrayType.GetComponentType();
                return(true);
            }

            values      = null;
            elementType = null;
            return(false);
        }
        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();
            }
        }
        private static bool TryGetCollectionSize(IObjectReference objectReference, out int size)
        {
            size = 0;

            IArrayReference arrayReference = objectReference as IArrayReference;

            if (arrayReference != null)
            {
                size = arrayReference.GetLength();
                return(true);
            }

            IClassType classType = objectReference.GetReferenceType() as IClassType;

            if (classType == null)
            {
                return(false);
            }

            ReadOnlyCollection <IInterfaceType> interfaces = classType.GetInterfaces(true);

            if (interfaces.Any(i => _collectionInterfaces.Contains(i.GetName())))
            {
                IMethod sizeMethod = classType.GetConcreteMethod("size", "()I");
                using (IStrongValueHandle <IValue> result = objectReference.InvokeMethod(null, sizeMethod, InvokeOptions.None))
                {
                    if (result == null)
                    {
                        return(false);
                    }

                    IIntegerValue integerValue = result.Value as IIntegerValue;
                    if (integerValue != null)
                    {
                        size = integerValue.GetValue();
                        return(true);
                    }
                }
            }

            return(false);
        }
        /// <summary>
        /// Gets the DEBUG_PROPERTY_INFO structure that describes a property.
        /// </summary>
        /// <param name="dwFields">[in] A combination of values from the DEBUGPROP_INFO_FLAGS enumeration that specifies which fields are to be filled out in the pPropertyInfo structure.</param>
        /// <param name="dwRadix">[in] Radix to be used in formatting any numerical information.</param>
        /// <param name="dwTimeout">[in] Specifies the maximum time, in milliseconds, to wait before returning from this method. Use INFINITE to wait indefinitely.</param>
        /// <param name="rgpArgs">[in, out] Reserved for future use; set to a null value.</param>
        /// <param name="dwArgCount">[in] Reserved for future use; set to zero.</param>
        /// <param name="pPropertyInfo">[out] A DEBUG_PROPERTY_INFO structure that is filled in with the description of the property.</param>
        /// <returns>If successful, returns S_OK; otherwise returns error code.</returns>
        public int GetPropertyInfo(enum_DEBUGPROP_INFO_FLAGS dwFields, uint dwRadix, uint dwTimeout, IDebugReference2[] rgpArgs, uint dwArgCount, DEBUG_PROPERTY_INFO[] pPropertyInfo)
        {
            if (pPropertyInfo == null)
            {
                throw new ArgumentNullException("pPropertyInfo");
            }
            if (pPropertyInfo.Length == 0)
            {
                throw new ArgumentException();
            }

            bool getFullName   = (dwFields & enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_FULLNAME) != 0;
            bool getName       = (dwFields & enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_NAME) != 0;
            bool getType       = (dwFields & enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_TYPE) != 0;
            bool getValue      = (dwFields & enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_VALUE) != 0;
            bool getAttributes = (dwFields & enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_ATTRIB) != 0;
            bool getProperty   = (dwFields & enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_PROP) != 0;

            bool useAutoExpandValue = (dwFields & enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_VALUE_AUTOEXPAND) != 0;
            bool noFormatting       = (dwFields & enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_VALUE_RAW) != 0;
            bool noToString         = (dwFields & enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_VALUE_NO_TOSTRING) != 0;

            if (getFullName)
            {
                pPropertyInfo[0].bstrFullName = _evaluatedExpression.FullName;
                pPropertyInfo[0].dwFields    |= enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_FULLNAME;
            }

            if (getName)
            {
                pPropertyInfo[0].bstrName  = _evaluatedExpression.Name;
                pPropertyInfo[0].dwFields |= enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_NAME;
            }

            if (getType)
            {
                pPropertyInfo[0].bstrType = _evaluatedExpression.ValueType.GetName();
                if (_evaluatedExpression.Value != null && !_evaluatedExpression.Value.GetValueType().Equals(_evaluatedExpression.ValueType))
                {
                    pPropertyInfo[0].bstrType += " {" + _evaluatedExpression.Value.GetValueType().GetName() + "}";
                }

                pPropertyInfo[0].dwFields |= enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_TYPE;
            }

            if (getValue)
            {
                if (_evaluatedExpression.Value == null)
                {
                    pPropertyInfo[0].bstrValue = "null";
                }
                if (_evaluatedExpression.Value is IVoidValue)
                {
                    pPropertyInfo[0].bstrValue = "The expression has been evaluated and has no value.";
                }
                else if (_evaluatedExpression.Value is IPrimitiveValue)
                {
                    IBooleanValue booleanValue = _evaluatedExpression.Value as IBooleanValue;
                    if (booleanValue != null)
                    {
                        pPropertyInfo[0].bstrValue = booleanValue.GetValue().ToString().ToLowerInvariant();
                        pPropertyInfo[0].dwAttrib |= enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_VALUE_BOOLEAN;
                        if (booleanValue.GetValue())
                        {
                            pPropertyInfo[0].dwAttrib |= enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_VALUE_BOOLEAN_TRUE;
                        }
                    }

                    IByteValue byteValue = _evaluatedExpression.Value as IByteValue;
                    if (byteValue != null)
                    {
                        pPropertyInfo[0].bstrValue = byteValue.GetValue().ToString();
                    }

                    ICharValue charValue = _evaluatedExpression.Value as ICharValue;
                    if (charValue != null)
                    {
                        pPropertyInfo[0].bstrValue = EscapeSpecialCharacters(charValue.GetValue().ToString(), 10, '\'');
                    }

                    IShortValue shortValue = _evaluatedExpression.Value as IShortValue;
                    if (shortValue != null)
                    {
                        pPropertyInfo[0].bstrValue = shortValue.GetValue().ToString();
                    }

                    IIntegerValue integerValue = _evaluatedExpression.Value as IIntegerValue;
                    if (integerValue != null)
                    {
                        pPropertyInfo[0].bstrValue = integerValue.GetValue().ToString();
                    }

                    ILongValue longValue = _evaluatedExpression.Value as ILongValue;
                    if (longValue != null)
                    {
                        pPropertyInfo[0].bstrValue = longValue.GetValue().ToString();
                    }

                    IFloatValue floatValue = _evaluatedExpression.Value as IFloatValue;
                    if (floatValue != null)
                    {
                        pPropertyInfo[0].bstrValue = floatValue.GetValue().ToString();
                    }

                    IDoubleValue doubleValue = _evaluatedExpression.Value as IDoubleValue;
                    if (doubleValue != null)
                    {
                        pPropertyInfo[0].bstrValue = doubleValue.GetValue().ToString();
                    }
                }
                else if (_evaluatedExpression.Value is IArrayReference)
                {
                    IArrayReference arrayReference = _evaluatedExpression.Value as IArrayReference;
                    int             length         = arrayReference.GetLength();
                    IArrayType      arrayType      = (IArrayType)arrayReference.GetReferenceType();
                    pPropertyInfo[0].bstrValue = string.Format("{{{0}[{1}]}}", arrayType.GetComponentTypeName(), length);
                    if (length > 0)
                    {
                        pPropertyInfo[0].dwAttrib |= enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_OBJ_IS_EXPANDABLE;
                    }
                }
                else if (_evaluatedExpression.Value is IObjectReference)
                {
                    IStringReference stringReference = _evaluatedExpression.Value as IStringReference;
                    if (stringReference != null)
                    {
                        pPropertyInfo[0].bstrValue = EscapeSpecialCharacters(stringReference.GetValue(), 120, '"');
                    }
                    else
                    {
                        IObjectReference objectReference = _evaluatedExpression.Value as IObjectReference;
                        if (objectReference != null)
                        {
                            int collectionSize;
                            if (TryGetCollectionSize(objectReference, out collectionSize))
                            {
                                pPropertyInfo[0].bstrValue = string.Format("{{size() = {0}}}", collectionSize);
                                pPropertyInfo[0].dwAttrib |= enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_OBJ_IS_EXPANDABLE;
                            }
                            else
                            {
                                string     displayValue = null;
                                IClassType classType    = objectReference.GetReferenceType() as IClassType;
                                if (noToString || classType == null)
                                {
                                    displayValue = objectReference.GetReferenceType().GetName();
                                }
                                else
                                {
                                    IMethod method = classType.GetConcreteMethod("toString", "()Ljava/lang/String;");
                                    using (IStrongValueHandle <IValue> result = objectReference.InvokeMethod(null, method, InvokeOptions.None))
                                    {
                                        if (result != null)
                                        {
                                            stringReference = result.Value as IStringReference;
                                            if (stringReference != null)
                                            {
                                                displayValue = stringReference.GetValue();
                                            }
                                        }
                                    }

                                    if (displayValue == null)
                                    {
                                        IClassType objectClass = classType;
                                        while (true)
                                        {
                                            IClassType parentClass = objectClass.GetSuperclass();
                                            if (parentClass != null)
                                            {
                                                objectClass = parentClass;
                                            }
                                            else
                                            {
                                                break;
                                            }
                                        }

                                        IMethod objectToStringMethod = objectClass.GetConcreteMethod("toString", "()Ljava/lang/String;");

                                        // fall back to a non-virtual call
                                        using (IStrongValueHandle <IValue> result = objectReference.InvokeMethod(null, objectToStringMethod, InvokeOptions.NonVirtual | InvokeOptions.SingleThreaded))
                                        {
                                            if (result != null)
                                            {
                                                stringReference = result.Value as IStringReference;
                                                if (stringReference != null)
                                                {
                                                    displayValue = stringReference.GetValue();
                                                }
                                            }
                                        }
                                    }
                                }

                                pPropertyInfo[0].bstrValue = "{" + displayValue + "}";
                                pPropertyInfo[0].dwAttrib |= enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_OBJ_IS_EXPANDABLE;
                            }
                        }
                        else
                        {
                            pPropertyInfo[0].bstrValue = "Unrecognized value";
                            pPropertyInfo[0].dwAttrib |= enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_VALUE_ERROR;
                        }
                    }
                }

                pPropertyInfo[0].dwFields |= enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_VALUE;
            }

            if (getAttributes)
            {
                if (_evaluatedExpression.Field != null)
                {
                    if (_evaluatedExpression.Field.GetIsPrivate())
                    {
                        pPropertyInfo[0].dwAttrib |= enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_ACCESS_PRIVATE;
                    }
                    if (_evaluatedExpression.Field.GetIsProtected())
                    {
                        pPropertyInfo[0].dwAttrib |= enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_ACCESS_PROTECTED;
                    }
                    if (_evaluatedExpression.Field.GetIsPublic())
                    {
                        pPropertyInfo[0].dwAttrib |= enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_ACCESS_PUBLIC;
                    }
                }

                pPropertyInfo[0].dwAttrib |= enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_VALUE_READONLY;
                pPropertyInfo[0].dwFields |= enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_ATTRIB;
#if false
                bool expandable;
                bool hasId;
                bool canHaveId;
                bool readOnly;
                bool error;
                bool sideEffect;
                bool overloadedContainer;
                bool boolean;
                bool booleanTrue;
                bool invalid;
                bool notAThing;
                bool autoExpanded;
                bool timeout;
                bool rawString;
                bool customViewer;

                bool accessNone;
                bool accessPrivate;
                bool accessProtected;
                bool accessPublic;

                bool storageNone;
                bool storageGlobal;
                bool storageStatic;
                bool storageRegister;

                bool noModifiers;
                bool @virtual;
                bool constant;
                bool synchronized;
                bool @volatile;

                bool dataField;
                bool method;
                bool property;
                bool @class;
                bool baseClass;
                bool @interface;
                bool innerClass;
                bool mostDerived;

                bool multiCustomViewers;
#endif
            }

            if (getProperty)
            {
                pPropertyInfo[0].pProperty = this;
                pPropertyInfo[0].dwFields |= enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_PROP;
            }

            return(VSConstants.S_OK);
        }
        public EvaluatedExpression EvaluateMethod(EvaluatedExpression expression, CommonTree methodName, IList <EvaluatedExpression> arguments)
        {
            Contract.Requires <ArgumentNullException>(expression != null, "expression");
            Contract.Requires <ArgumentNullException>(methodName != null, "methodName");
            Contract.Requires <ArgumentNullException>(arguments != null, "arguments");
            Contract.Ensures(Contract.Result <EvaluatedExpression>() != null);
            Contract.Ensures(Contract.Result <EvaluatedExpression>().Method != null);

            IReferenceType referenceType = expression.ValueType as IReferenceType;

            if (referenceType == null)
            {
                throw new InvalidOperationException();
            }

            List <IMethod> methods = referenceType.GetMethodsByName(methodName.Text).ToList();

            if (referenceType is IClassType)
            {
                methods.RemoveAll(i => !(i.GetDeclaringType() is IClassType));
            }

            if (methods.Count > 0)
            {
                methods.RemoveAll(i => i.GetArgumentTypeNames().Count != arguments.Count);
            }

            if (methods.Count == 0)
            {
                throw new InvalidOperationException("Evaluation failed.");
            }

            if (methods.Count > 1)
            {
                methods.RemoveAll(
                    m =>
                {
                    ReadOnlyCollection <IType> argumentTypes = m.GetArgumentTypes();
                    for (int i = 0; i < arguments.Count; i++)
                    {
                        if (!IsAssignableFrom(argumentTypes[0], arguments[i].ValueType))
                        {
                            return(true);
                        }
                    }

                    return(false);
                });
            }

            if (methods.Count > 1)
            {
                if (arguments.Any(i => i.ValueType is IPrimitiveType) || methods.Any(i => i.GetArgumentTypes().Any(j => j is IPrimitiveType)))
                {
                    throw new NotImplementedException("Auto boxing/unboxing is not yet implemented.");
                }

                throw new InvalidOperationException("Ambiguous match?");
            }

            IMethod method = methods[0];

            IObjectReference referencer = null;

            if (!method.GetIsStatic())
            {
                referencer = expression.Value as IObjectReference;
                if (referencer == null)
                {
                    throw new InvalidOperationException();
                }

                if (method.GetDeclaringType() is IInterfaceType)
                {
                    IClassType concreteType = referencer.GetReferenceType() as IClassType;
                    if (concreteType == null)
                    {
                        throw new InvalidOperationException();
                    }

                    method = concreteType.GetConcreteMethod(method.GetName(), method.GetSignature());
                    if (method == null)
                    {
                        throw new InvalidOperationException();
                    }
                }
            }

            string fullName = string.Format("({0}).{1}", expression.FullName, methodName);

            bool hasSideEffects = (expression != null && expression.HasSideEffects);

            return(new EvaluatedExpression(fullName, fullName, referencer, method, hasSideEffects));
        }