protected static void GetInheritedTypes(IReferenceType type, HashSet <IReferenceType> inheritedTypes)
        {
            Contract.Requires <ArgumentNullException>(type != null, "type");
            Contract.Requires <ArgumentNullException>(inheritedTypes != null, "inheritedTypes");

            List <IReferenceType> immediateBases = new List <IReferenceType>();

            IClassType classtype = type as IClassType;

            if (classtype != null)
            {
                IClassType basetype = classtype.GetSuperclass();
                if (basetype != null)
                {
                    immediateBases.Add(basetype);
                }

                immediateBases.AddRange(classtype.GetInterfaces(false));
            }

            IInterfaceType interfacetype = type as IInterfaceType;

            if (interfacetype != null)
            {
                immediateBases.AddRange(interfacetype.GetSuperInterfaces());
            }

            foreach (var baseType in immediateBases)
            {
                if (inheritedTypes.Add(baseType))
                {
                    GetInheritedTypes(baseType, inheritedTypes);
                }
            }
        }
        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 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);
        }