/** Configure this type hierarchy that is based on a region. */
  private void createTypeHierarchyBasedOnRegion(
      HashMap allOpenablesInRegion, IProgressMonitor monitor) {

    int size = allOpenablesInRegion.size();
    if (size == 0) {
      if (monitor != null) {
        monitor.done();
      }
      return;
    }

    this.infoToHandle = new HashMap(size);
    Iterator javaProjects = allOpenablesInRegion.entrySet().iterator();
    while (javaProjects.hasNext()) {
      Map.Entry entry = (Map.Entry) javaProjects.next();
      ScriptProject project = (ScriptProject) entry.getKey();
      ArrayList allOpenables = (ArrayList) entry.getValue();
      Openable[] openables = new Openable[allOpenables.size()];
      allOpenables.toArray(openables);

      try {
        // resolve
        if (monitor != null) {
          monitor.beginTask(
              "", size * 2 /* 1 for build binding, 1 for connect hierarchy*/); // $NON-NLS-1$
        }
        ISearchableEnvironment searchableEnvironment =
            project.newSearchableNameEnvironment(this.hierarchy.workingCopies);
        this.nameLookup = searchableEnvironment.getNameLookup();
        //			this.hierarchyResolver.resolve(openables, null, monitor);
      } catch (ModelException e) {
        // project doesn't exit: ignore
      } finally {
        if (monitor != null) {
          monitor.done();
        }
      }
    }
  }
  /**
   * Add a path to current script search scope or all project fragment roots if null. Use project
   * resolved classpath to retrieve and store access restriction on each classpath entry. Recurse if
   * dependent projects are found.
   *
   * @param scriptProject Project used to get resolved classpath entries
   * @param pathToAdd Path to add in case of single element or null if user want to add all project
   *     package fragment roots
   * @param includeMask Mask to apply on buildpath entries
   * @param visitedProjects Set to avoid infinite recursion
   * @param referringEntry Project raw entry in referring project buildpath
   * @throws ModelException May happen while getting script model info
   */
  void add(
      ScriptProject scriptProject,
      IPath pathToAdd,
      int includeMask,
      HashSet<IProject> visitedProjects,
      IBuildpathEntry referringEntry)
      throws ModelException {
    if (!natureFilter(scriptProject)) {
      return;
    }
    IProject project = scriptProject.getProject();
    if (!project.isAccessible() || !visitedProjects.add(project)) return;

    IPath projectPath = project.getFullPath();
    String projectPathString = projectPath.toString();
    this.addEnclosingProjectOrArchive(projectPath);

    // Iterate via project fragments without buildpath entries
    IProjectFragment[] fragments = scriptProject.getProjectFragments();
    for (int i = 0; i < fragments.length; i++) {
      if (fragments[i].getRawBuildpathEntry() == null) {
        add(fragments[i]);
      }
    }

    IBuildpathEntry[] entries = scriptProject.getResolvedBuildpath();
    IScriptModel model = scriptProject.getModel();
    ModelManager.PerProjectInfo perProjectInfo = scriptProject.getPerProjectInfo();
    for (int i = 0, length = entries.length; i < length; i++) {
      IBuildpathEntry entry = entries[i];
      AccessRuleSet access = null;
      BuildpathEntry cpEntry = (BuildpathEntry) entry;
      if (referringEntry != null) {
        // Add only exported entries.
        // Source folder are implicitly exported.
        if (!entry.isExported() && entry.getEntryKind() != IBuildpathEntry.BPE_SOURCE) continue;
        cpEntry = cpEntry.combineWith((BuildpathEntry) referringEntry);
        // cpEntry =
        // ((BuildpathEntry)referringEntry).combineWith(cpEntry);
      }
      access = cpEntry.getAccessRuleSet();
      switch (entry.getEntryKind()) {
        case IBuildpathEntry.BPE_LIBRARY:
          IBuildpathEntry rawEntry = null;
          Map<IPath, IBuildpathEntry> rootPathToRawEntries = perProjectInfo.rootPathToRawEntries;
          if (rootPathToRawEntries != null) {
            rawEntry = rootPathToRawEntries.get(entry.getPath());
          }
          if (rawEntry == null) {
            break;
          }
          switch (rawEntry.getEntryKind()) {
            case IBuildpathEntry.BPE_LIBRARY:
            case IBuildpathEntry.BPE_VARIABLE:
              if ((includeMask & APPLICATION_LIBRARIES) != 0) {
                IPath path = entry.getPath();
                if (pathToAdd == null || pathToAdd.equals(path)) {
                  String pathToString = path.toString();
                  add(
                      projectPath.toString(),
                      "",
                      pathToString,
                      false /* not a package */,
                      access); //$NON-NLS-1$
                  addEnclosingProjectOrArchive(path);
                }
              }
              break;
            case IBuildpathEntry.BPE_CONTAINER:
              IBuildpathContainer container =
                  DLTKCore.getBuildpathContainer(rawEntry.getPath(), scriptProject);
              if (container == null) break;
              if ((container.getKind() == IBuildpathContainer.K_APPLICATION
                      && (includeMask & APPLICATION_LIBRARIES) != 0)
                  || (includeMask & SYSTEM_LIBRARIES) != 0) {
                IPath path = entry.getPath();
                if (pathToAdd == null || pathToAdd.equals(path)) {
                  String pathToString = path.toString();
                  add(
                      projectPath.toString(),
                      "",
                      pathToString,
                      false /* not a package */,
                      access); //$NON-NLS-1$
                  addEnclosingProjectOrArchive(path);
                }
              }
              break;
          }
          break;
        case IBuildpathEntry.BPE_PROJECT:
          if ((includeMask & REFERENCED_PROJECTS) != 0) {
            IPath path = entry.getPath();
            if (pathToAdd == null || pathToAdd.equals(path)) {
              add(
                  (ScriptProject) model.getScriptProject(entry.getPath().lastSegment()),
                  null,
                  includeMask,
                  visitedProjects,
                  cpEntry);
            }
          }
          break;
        case IBuildpathEntry.BPE_SOURCE:
          if ((includeMask & SOURCES) != 0) {
            IPath path = entry.getPath();
            if (pathToAdd == null || pathToAdd.equals(path)) {
              add(
                  projectPath.toString(),
                  Util.relativePath(path, 1 /*
														 * remove project
														 * segment
														 */),
                  projectPathString,
                  false /*
                         * not a package
                         */,
                  access);
            }
          }
          break;
      }
    }
  }