public ContentAssistContext(Library typeSystem, Library annotatedTypeSystem) {
			this.typeSystem = typeSystem;
			this.annotatedTypeSystem = annotatedTypeSystem;
			this.packageNames = Query.empty();
			this.packageInfos = new ArrayList<PackageInfo>();
			this.typeInfos = new ArrayList<TypeInfo>();
			this.methodInfos = new ArrayList<MethodInfo>();
			this.localInfos = new ArrayList<MemberInfo>();
		}
     	: super(typeSystem, name) {
     this.typeSystem = typeSystem;
     this.descriptor = "L" + name + ";";
     numericTypeKind = TypeKinds[name];
     if (numericTypeKind == null) {
         numericTypeKind = NumericTypeKind.None;
     }
     new ClassReader(bytes).accept(new OutlineVisitor(this), ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
     
     this.genericsScope = new Scope<String, TypeInfo>();
     this.genericsScope.enterScope();
 }
		public void testMapIndexer() {
			var userDir = System.getProperty("user.dir");
			var alPath = PathHelper.combine(userDir, "bin/stabal.jar");
			var rtPath = PathHelper.combine(userDir, "bin/stabrt.jar");
			var typeSystem = new Library(new String[] { alPath, rtPath });
			var mapType = typeSystem.getType("java/util/Map");
			var indexers = MemberInfo.getIndexers(typeSystem, mapType, 1);
			
			Assert.assertEquals(1, indexers.count());
			
			var indexer = indexers.single();
			
			Assert.assertNotNull(indexer.GetAccessor);
			Assert.assertNotNull(indexer.SetAccessor);
			Assert.assertFalse(indexer.GetAccessor == indexer.SetAccessor);
			
			Assert.assertFalse(indexer.isOverridingMembers(typeSystem));
		}
        public Library(String[] classPath, Library parent) {
			this.classPath = new ArrayList<String>();
			foreach(string path in classPath)
				this.classPath.add(path);
            this.fileClasses = new HashMap<String, File>(128);
            int capacity = (parent == null) ? 0x5000 : 128;
            this.jarClasses = new HashMap<String, ZipFile>(capacity);
            this.classNames = new ArrayList<String>(capacity);
            this.typeInfos = new HashMap<String, TypeInfo>();
			this.constructedGenericTypes = new HashMap<TypeInfo, ArrayList<TypeInfo>>();
			this.constructedGenericMethods = new HashMap<MethodInfo, ArrayList<MethodInfo>>();
            this.parent = parent;

			if (parent == null) {
	            initializeBootClasses();
			}
            
            foreach (var path in classPath) {
                explorePath(path);
            }
        }
		public void testResolveTypeName2() {
			var userDir = System.getProperty("user.dir");
			var alPath = PathHelper.combine(userDir, "bin/stabal.jar");
			var rtPath = PathHelper.combine(userDir, "bin/stabrt.jar");
			var typeSystem = new Library(new String[] { rtPath });
			var annotatedTypeSystem = new Library(new String[] { alPath }, typeSystem);
		
			var memberResolver = new MemberResolver(typeSystem, annotatedTypeSystem);
			memberResolver.initialize();

			memberResolver.usingDirective(
				new HashMap<String, MemberInfo>(),
				new ArrayList<String> { "java/awt", "java/util" },
				new HashMap<String, Iterable<String>>());
			
			var listType = memberResolver.resolveTypeName(typeSystem.getType("java/lang/Object").PackageName, "List");
			Assert.assertNull(listType);
			Assert.assertTrue(memberResolver.isAmbiguousTypeName("List"));
			
			memberResolver.dispose();
		}
 public static bool isDeprecated(Library typeSystem, TypeInfo type) {
     return containsDeprecated(getAnnotations(typeSystem, type));
 }
 public static bool isDeprecated(Library typeSystem, MethodInfo method) {
     return containsDeprecated(getAnnotations(typeSystem, method));
 }
 public static Iterable<AnnotationValue> getAnnotations(Library typeSystem, TypeInfo type) {
     var annotatedTypeName = "stab/annotated/" + type.FullName;
     if (typeSystem.typeExists(annotatedTypeName)) {
         var annotatedType = typeSystem.getType(annotatedTypeName);
         return type.Annotations.concat(annotatedType.Annotations);
     }
     return type.Annotations;
 }
 public static Iterable<AnnotationValue> getAnnotations(Library typeSystem, MethodInfo method) {
     var annotatedTypeName = "stab/annotated/" + method.DeclaringType.FullName;
     if (typeSystem.typeExists(annotatedTypeName)) {
         var annotatedType = typeSystem.getType(annotatedTypeName);
         if (method.DeclaringType.GenericArguments.any()) {
             annotatedType = typeSystem.getGenericType(annotatedType, method.DeclaringType.GenericArguments);
         }
         foreach (var m in annotatedType.Methods) {
             if (m.Name.equals(method.Name) && m.hasSameParameters(method)) {
                 return method.Annotations.concat(m.Annotations);
             }
         }
     }
     return method.Annotations;
 }
        public static Iterable<MemberInfo> getMembers(Library typeSystem, TypeInfo scope, TypeInfo type, String name,
                Iterable<TypeInfo> typeArguments, bool useCache) {
			try {
				var allMembers = getMembersRecursively(typeSystem, scope, type, name, typeArguments, useCache, new LookupContext());
				var members = allMembers.toList();
				return members.distinct().toList();
			} catch (IllegalArgumentException e) {
				throw new RuntimeException("Unexpected error in getMembers: \ntypeSystem " + typeSystem + 
				"\nscope " + scope + "\ntype " + type + "\nname " + name + "\ntypeArguments " + typeArguments + "\nuseCache " + useCache, e);
			}
        }
 public static Iterable<MemberInfo> getCachedMembers(Library typeSystem, TypeInfo type, String name) {
     var typeMembers = type.getUserData(typeof(TypeMembers));
     if (typeMembers == null) {
         typeMembers = new TypeMembers();
         type.addUserData(typeMembers);
     }
     var members = typeMembers.members[name];
     if (members == null) {
         members = getMembers(typeSystem, type, name);
         typeMembers.members[name] = members;
     }
     return members;
 }
 public static Iterable<MemberInfo> getIndexers(Library typeSystem, TypeInfo type, int indexes) {
     List<MethodInfo> getters = null;
     List<MethodInfo> setters = null;
     foreach (var method in type.Methods) {
         foreach (var annotation in BytecodeHelper.getAnnotations(typeSystem, method)) {
             if (BytecodeHelper.isIndexerGet(annotation)) {
                 var nparams = method.Parameters.count();
                 if (indexes == nparams || (method.IsVarargs && indexes >= nparams)) {
                     if (getters == null) {
                         getters = new ArrayList<MethodInfo>();
                     }
                     getters.add(method);
                 }
                 break;
             }
             if (BytecodeHelper.isIndexerSet(annotation)) {
                 var nparams = method.Parameters.count() - 1;
                 if (indexes == nparams || (method.IsVarargs && indexes >= nparams)) {
                     if (setters == null) {
                         setters = new ArrayList<MethodInfo>();
                     }
                     setters.add(method);
                 }
                 break;
             }
         }
     }
     if (setters == null && getters == null) {
         return Query.empty();
     }
     var result = new ArrayList<MemberInfo>();
     var getters2 = (getters == null) ? Collections.emptySet<MethodInfo>() : new HashSet<MethodInfo>(getters);
     var setters2 = (setters == null) ? Collections.emptySet<MethodInfo>() : new HashSet<MethodInfo>(setters);
     if (getters == null) {
         getters = Collections.emptyList();
     }
     if (setters == null) {
         setters = Collections.emptyList();
     }
     foreach (var get in getters) {
         foreach (var set in setters) {
             if (get.Parameters.count() == set.Parameters.count() - 1) {
                 var it1 = get.OriginalMethodDefinition.Parameters.iterator();
                 var it2 = set.OriginalMethodDefinition.Parameters.iterator();
                 var match = true;
                 while (it1.hasNext()) {
                     var t1 = it1.next().Type;
                     var t2 = it2.next().Type;
                     if (t1.IsGenericParameter) {
                         t1 = BytecodeHelper.getGenericParameterTypeErasure(typeSystem, t1);
                     }
                     if (t2.IsGenericParameter) {
                         t2 = BytecodeHelper.getGenericParameterTypeErasure(typeSystem, t2);
                     }
                     if (t1 != t2) {
                         match = false;
                         break;
                     }
                 }
                 if (match) {
                     var t1 = get.OriginalMethodDefinition.ReturnType;
                     if (t1.IsGenericParameter) {
                         t1 = BytecodeHelper.getGenericParameterTypeErasure(typeSystem, t1);
                     }
                     var t2 = it2.next().Type;
                     if (t2.IsGenericParameter) {
                         t2 = BytecodeHelper.getGenericParameterTypeErasure(typeSystem, t2);
                     }
                     if (t1 == t2) {
                         getters2.remove(get);
                         setters2.remove(set);
                         result.add(MemberInfo.getInfo(get, set));
                     }
                 }
             }
         }
     }
     foreach (var m in getters2) {
         result.add(MemberInfo.getInfo(m, null));
     }
     foreach (var m in setters2) {
         result.add(MemberInfo.getInfo((MethodInfo)null, m));
     }
     return result;
 }
 public MemberResolver(Library typeSystem, Library annotatedTypeSystem) {
     this.TypeFinder = new TypeFinder(typeSystem);
     this.annotatedTypeSystem = annotatedTypeSystem;
     this.packages = new ArrayList<String>();
 }
 private static Iterable<MemberInfo> filterMembers(Library typeSystem, TypeInfo scope, Iterable<MemberInfo> members) {
     HashSet<MemberInfo> exclude = null;
     foreach (var mi in members) {
         if (exclude != null && exclude.contains(mi)) {
             continue;
         }
         if (!scope.canAccessMember(mi.DeclaringType, mi.IsPublic, mi.IsProtected, mi.IsPrivate)) {
             continue;
         }
         if (mi.isOverridingMembers(typeSystem)) {
             foreach (var m in mi.getOverridenMembers(typeSystem)) {
                 if (exclude == null) {
                     exclude = new HashSet<MemberInfo>();
                 }
                 exclude.add(m);
             }
         }
         yield return mi;
     }
 }
 public static Iterable<MemberInfo> getCachedIndexers(Library typeSystem, TypeInfo type, int indexes) {
     var typeMembers = type.getUserData(typeof(TypeMembers));
     if (typeMembers == null) {
         typeMembers = new TypeMembers();
         type.addUserData(typeMembers);
     }
     var members = typeMembers.members[indexes];
     if (members == null) {
         members = getIndexers(typeSystem, type, indexes);
         typeMembers.members[indexes] = members;
     }
     return members;
 }
 private static Iterable<MemberInfo> getIndexersRecursively(Library typeSystem, TypeInfo scope, TypeInfo type,
         int indexes, bool useCache) {
     Iterable<MemberInfo> members;
     if (type.IsArray) {
         members = getIndexersRecursively(typeSystem, scope, typeSystem.ObjectType, indexes, useCache);
     } else if (type.IsGenericParameter) {
         if (type.GenericParameterBounds.any()) {
             members = Query.empty();
             foreach (var t in type.GenericParameterBounds) {
                 members = members.concat(getIndexersRecursively(typeSystem, scope, t, indexes, useCache));
             }
         } else {
             members = getIndexersRecursively(typeSystem, scope, typeSystem.ObjectType, indexes, useCache);
         }
     } else {
         members = (useCache) ? getCachedIndexers(typeSystem, type, indexes) : getIndexers(typeSystem, type, indexes);
         foreach (var t in type.getBaseTypes()) {
             members = members.concat((useCache) ? getCachedIndexers(typeSystem, t, indexes) : getIndexers(typeSystem, t, indexes));
         }
     }
     return filterMembers(typeSystem, scope, members);
 }
 public static Iterable<MemberInfo> getIndexers(Library typeSystem, TypeInfo scope, TypeInfo type,
         int indexes, bool useCache) {
     return getIndexersRecursively(typeSystem, scope, type, indexes, useCache).distinct().toList();
 }
        public static Iterable<MemberInfo> getMembers(Library typeSystem, TypeInfo type, String name) {
            var result = new ArrayList<MemberInfo>();
            
            foreach (var f in type.Fields) {
                if (f.Name.equals(name)) {
                    result.add(MemberInfo.getInfo(f));
                    break;
                }
            }

            MethodInfo getAccessor = null;
            MethodInfo setAccessor = null;
            foreach (var m in type.Methods) {
                if (getAccessor == null || setAccessor == null) {
                    foreach (var annotation in BytecodeHelper.getAnnotations(typeSystem, m)) {
                        if (BytecodeHelper.isPropertyGet(annotation) && name.equals(BytecodeHelper.getPropertyGetName(m, annotation))) {
                            getAccessor = m;
                            break;
                        }
                        if (BytecodeHelper.isPropertySet(annotation) && name.equals(BytecodeHelper.getPropertySetName(m, annotation))) {
                            setAccessor = m;
                            break;
                        }
                    }
                }
                if (m.Name.equals(name)) {
                    result.add(MemberInfo.getInfo(m));
                }
            }
            if (getAccessor != null || setAccessor != null) {
                result.add(MemberInfo.getInfo(getAccessor, setAccessor, name));
            }
            
            foreach (var t in type.NestedTypes) {
                if (name.equals(t.Name)) {
                    result.add(MemberInfo.getInfo(t));
                    break;
                }
            }
            
            return result;
        }
 public static bool isDeprecated(Library typeSystem, FieldInfo field) {
     return containsDeprecated(field.Annotations);
 }
        public byte[] createType(Library typeSystem) {
            checkCreated();
            this.created = true;
            var classWriter = new ClassWriterNoReflection(typeSystem, ClassWriter.COMPUTE_FRAMES);
            classWriter.visit(Opcodes.V1_6, modifiers, getFullName(), ReflectionHelper.getClassSignature(this),
                baseType.getFullName(), getTypeNames(interfaces));
            if (sourceFile != null || sourceDebugExtension != null) {
                classWriter.visitSource(sourceFile, sourceDebugExtension);
            }
            foreach (var a in annotations) {
                a.accept(classWriter.visitAnnotation(a.Type.Descriptor, a.IsRuntimeVisible));
            }

            if (declaringType != null) {
                classWriter.visitInnerClass(FullName, declaringType.FullName, FullName.substring(FullName.lastIndexOf('$') + 1), modifiers);
            }
            
            foreach (var t in nestedTypes) {
                classWriter.visitInnerClass(t.FullName, FullName, t.FullName.substring(t.FullName.lastIndexOf('$') + 1), t.NestedModifiers);
            }
            
            foreach (var f in fields) {
                ((FieldBuilder)f).accept(classWriter.visitField(f.modifiers, f.Name, f.Descriptor, f.Signature, f.Value));
            }
            
            foreach (var m in methods) {
                if (!m.IsExcludedFromCompilation) {
                    ((MethodBuilder)m).accept(classWriter.visitMethod(m.Modifiers, m.Name, m.Descriptor,
                            m.Signature, getTypeNames(m.Exceptions)));
                }
            }
            
            classWriter.visitEnd();
            return classWriter.toByteArray();
        }
 public static bool isDeprecated(Library typeSystem, ParameterInfo parameter) {
     return containsDeprecated(parameter.Annotations);
 }
 public ClassWriterNoReflection(Library typeSystem, int flags)
     : super(flags) {
 ClassFileType(Library typeSystem, String name, byte[] bytes)
     	: super(typeSystem, name) {
        private static Iterable<MemberInfo> getMembersRecursively(Library typeSystem, TypeInfo scope, TypeInfo type, String name,
                Iterable<TypeInfo> typeArguments, bool useCache, LookupContext context) {
            Iterable<MemberInfo> members;
			switch (type.TypeKind) {
			case Array:
			case LowerBoundedWildcard:
			case UnboundedWildcard:
				type = typeSystem.ObjectType;
				break;
			case UpperBoundedWildcard:
				type = type.WildcardBound;
				break;
			}
            if (type.IsGenericParameter) {
                if (type.GenericParameterBounds.any()) {
                    members = Query.empty();
                    foreach (var t in type.GenericParameterBounds) {
                        members = members.concat(getMembersRecursively(typeSystem, scope, t, name, typeArguments, useCache, context));
                    }
                } else {
                    members = getMembersRecursively(typeSystem, scope, typeSystem.ObjectType, name, typeArguments, useCache, context);
                }
            } else {
                members = getMembers(typeSystem, type, name, typeArguments, useCache, context);
                foreach (var t in type.getBaseTypes()) {
                    members = members.concat(getMembers(typeSystem, t, name, typeArguments, useCache, context));
                }
            }
            return filterMembers(typeSystem, scope, members);
        }
 public static MethodInfo getDisposeMethod(Library typeSystem, TypeInfo type) {
     foreach (var method in Collections.singletonList(type).concat(type.getBaseTypes()).selectMany(p => p.Methods)) {
         if (!method.Parameters.any()) {
             foreach (var annotation in BytecodeHelper.getAnnotations(typeSystem, method)) {
                 if (BytecodeHelper.isDispose(annotation)) {
                     return method;
                 }
             }
         }
     }
     return null;
 }
        private static Iterable<MemberInfo> getMembers(Library typeSystem, TypeInfo type, String name,
            Iterable<TypeInfo> typeArguments, bool useCache, LookupContext context) {
            var nTypeArgs = typeArguments.count();
            foreach (var mi in (useCache) ? getCachedMembers(typeSystem, type, name) : getMembers(typeSystem, type, name)) {
                switch (mi.MemberKind) {
                case Field:
                    if (nTypeArgs == 0 && context.lookupField) {
                        context.lookupField = false;
                        yield return mi;
                    }
                    break;
                    
                case Property:
                    if (nTypeArgs == 0  && context.lookupProperty) {
                        context.lookupProperty = false;
                        yield return mi;
                    }
                    break;
                    
                case Method:
                    if (nTypeArgs > 0) {
                        if (nTypeArgs == mi.Method.GenericArguments.count()) {
                            yield return MemberInfo.getInfo(typeSystem.getGenericMethod(mi.Method, typeArguments));
                        }
                    } else {
                        yield return mi;
                    }
                    break;

                case Type:
                    if (context.lookupClass) {
                        context.lookupClass = false;
                        if (nTypeArgs > 0) {
                            if (nTypeArgs == mi.Type.GenericArguments.count()) {
                                yield return mi;
                            }
                        } else {
                            if (mi.MemberKind == MemberKind.Type && mi.Type.GenericArguments.count() > 0) {
                                mi = MemberInfo.getInfo(mi.Type.RawType);
                            }
                            yield return mi;
                        }
                    }
                    break;
                }
            }
        }
 TypeBuilder(Library library, TypeInfo declaringType, String name)
     : super(library, name) {
        public static TypeInfo getGenericParameterTypeErasure(Library typeSystem, TypeInfo type) {
            if (type.GenericParameterBounds.any()) {
            	return type.GenericParameterBounds.first();
            } else {
	            return typeSystem.ObjectType;
            }
        }
     : super(flags) {
     this.typeSystem = typeSystem;
 }
 static void emitTypeof(CodeGenerator generator, Library typeSystem, TypeInfo type) {
     switch (type.TypeKind) {
     case Boolean:
         generator.emit(Opcode.Getstatic, typeSystem.getType("java/lang/Boolean").getField("TYPE"));
         break;
     case Byte:
         generator.emit(Opcode.Getstatic, typeSystem.getType("java/lang/Byte").getField("TYPE"));
         break;
     case Char:
         generator.emit(Opcode.Getstatic, typeSystem.getType("java/lang/Character").getField("TYPE"));
         break;
     case Double:
         generator.emit(Opcode.Getstatic, typeSystem.getType("java/lang/Double").getField("TYPE"));
         break;
     case Float:
         generator.emit(Opcode.Getstatic, typeSystem.getType("java/lang/Float").getField("TYPE"));
         break;
     case Int:
         generator.emit(Opcode.Getstatic, typeSystem.getType("java/lang/Integer").getField("TYPE"));
         break;
     case Long:
         generator.emit(Opcode.Getstatic, typeSystem.getType("java/lang/Long").getField("TYPE"));
         break;
     case Short:
         generator.emit(Opcode.Getstatic, typeSystem.getType("java/lang/Short").getField("TYPE"));
         break;
     case Void:
         generator.emit(Opcode.Getstatic, typeSystem.getType("java/lang/Void").getField("TYPE"));
         break;
     default:
         generator.emit(Opcode.Ldc, type);
         break;
     }
 }