public void testTwoPlatformsoverSameSDK() throws Exception {
    final File binDir = new File(getWorkDir(), "boot"); // NOI18N
    binDir.mkdir();
    final File jdocFile1 = new File(getWorkDir(), "jdoc1"); // NOI18N
    jdocFile1.mkdir();
    final File jdocFile2 = new File(getWorkDir(), "jdoc2"); // NOI18N
    jdocFile2.mkdir();
    JavaPlatformProviderImpl provider = Lookup.getDefault().lookup(JavaPlatformProviderImpl.class);
    final URL binRoot = Utilities.toURI(binDir).toURL();
    final ClassPath bootCp = ClassPathSupport.createClassPath(binRoot);
    final List<URL> javadoc1 = Collections.singletonList(Utilities.toURI(jdocFile1).toURL());
    final List<URL> javadoc2 = Collections.singletonList(Utilities.toURI(jdocFile2).toURL());
    final TestJavaPlatform platform1 = new TestJavaPlatform("platform1", bootCp); // NOI18N
    final TestJavaPlatform platform2 = new TestJavaPlatform("platform2", bootCp); // NOI18N
    platform2.setJavadoc(javadoc2);
    provider.addPlatform(platform1);
    provider.addPlatform(platform2);

    final JavadocForBinaryQuery.Result result1 = JavadocForBinaryQuery.findJavadoc(binRoot);
    assertEquals(javadoc2, Arrays.asList(result1.getRoots()));

    platform1.setJavadoc(javadoc1);
    assertEquals(javadoc1, Arrays.asList(result1.getRoots()));

    final JavadocForBinaryQuery.Result result2 = JavadocForBinaryQuery.findJavadoc(binRoot);
    assertEquals(javadoc1, Arrays.asList(result2.getRoots()));

    platform1.setJavadoc(Collections.<URL>emptyList());
    assertEquals(javadoc2, Arrays.asList(result1.getRoots()));
    assertEquals(javadoc2, Arrays.asList(result2.getRoots()));
  }
  private void runJavaProcessInProject(
      TmcProjectInfo projectInfo,
      ClassPath classPath,
      String taskName,
      List<String> args,
      InputOutput inOut,
      BgTaskListener<ProcessResult> listener) {
    FileObject projectDir = projectInfo.getProjectDir();

    JavaPlatform platform =
        JavaPlatform.getDefault(); // Should probably use project's configured platform instead

    FileObject javaExe = platform.findTool("java");
    if (javaExe == null) {
      throw new IllegalArgumentException();
    }

    // TMC server packages this with every exercise for our convenience.
    // True even for Maven exercises, at least until NB's Maven API is published.
    ClassPath testRunnerClassPath = getTestRunnerClassPath(projectInfo);

    if (testRunnerClassPath != null) {
      classPath = ClassPathSupport.createProxyClassPath(classPath, testRunnerClassPath);
    }

    String[] command = new String[3 + args.size()];
    command[0] = FileUtil.toFile(javaExe).getAbsolutePath();
    command[1] = "-cp";
    command[2] = classPath.toString(ClassPath.PathConversionMode.WARN);
    System.arraycopy(args.toArray(new String[args.size()]), 0, command, 3, args.size());

    log.info(StringUtils.join(command, ' '));
    ProcessRunner runner = new ProcessRunner(command, FileUtil.toFile(projectDir), inOut);
    BgTask.start(taskName, runner, listener);
  }
 @Override
 protected Map<String, ClassPath> createClassPathsForTest() {
   return Collections.singletonMap(
       PhpSourcePath.SOURCE_CP,
       ClassPathSupport.createClassPath(
           new FileObject[] {
             FileUtil.toFileObject(
                 new File(getDataDir(), "/testfiles/completion/lib/qualifiedStatic/"))
           }));
 }
 private ClassPath getTestRunnerClassPath(TmcProjectInfo projectInfo) {
   FileObject projectDir = projectInfo.getProjectDir();
   FileObject testrunnerDir = projectDir.getFileObject("lib/testrunner");
   if (testrunnerDir != null) {
     FileObject[] files = testrunnerDir.getChildren();
     ArrayList<URL> urls = new ArrayList<URL>();
     for (FileObject file : files) {
       URL url = FileUtil.urlForArchiveOrDir(FileUtil.toFile(file));
       if (url != null) {
         urls.add(url);
       }
     }
     return ClassPathSupport.createClassPath(urls.toArray(new URL[0]));
   } else {
     return null;
   }
 }
  public void computeTypeNames(TypeProvider.Context context, TypeProvider.Result res) {
    isCanceled = false;
    String text = context.getText();
    SearchType searchType = context.getSearchType();

    //        boolean hasBinaryOpen = Lookup.getDefault().lookup(BinaryElementOpen.class) != null;
    final ClassIndex.NameKind nameKind;
    switch (searchType) {
      case EXACT_NAME:
        nameKind = ClassIndex.NameKind.SIMPLE_NAME;
        break;
      case CASE_INSENSITIVE_EXACT_NAME:
        nameKind = ClassIndex.NameKind.CASE_INSENSITIVE_REGEXP;
        break;
      case PREFIX:
        nameKind = ClassIndex.NameKind.PREFIX;
        break;
      case CASE_INSENSITIVE_PREFIX:
        nameKind = ClassIndex.NameKind.CASE_INSENSITIVE_PREFIX;
        break;
      case REGEXP:
        nameKind = ClassIndex.NameKind.REGEXP;
        break;
      case CASE_INSENSITIVE_REGEXP:
        nameKind = ClassIndex.NameKind.CASE_INSENSITIVE_REGEXP;
        break;
      case CAMEL_CASE:
        nameKind = ClassIndex.NameKind.CAMEL_CASE;
        break;
      default:
        throw new RuntimeException("Unexpected search type: " + searchType); // NOI18N
    }

    long time = 0;

    long cp, gss, gsb, sfb, gtn, add, sort;
    cp = gss = gsb = sfb = gtn = add = sort = 0;

    Future<Project[]> openProjectsTask = OpenProjects.getDefault().openProjects();
    Project[] projs = new Project[0];
    try {
      projs = openProjectsTask.get();
    } catch (InterruptedException ex) {
      LOGGER.fine(ex.getMessage());
    } catch (ExecutionException ex) {
      LOGGER.fine(ex.getMessage());
    }

    if (cache == null) {
      Set<CacheItem> sources = new HashSet<CacheItem>();
      Set<FileObject> roots = new HashSet<FileObject>();
      for (Project project : projs) {
        if (!(project instanceof VisageProject)) continue;
        VisageProject jfxp = (VisageProject) project;
        ClassPath pcp = jfxp.getClassPathProvider().getProjectSourcesClassPath(ClassPath.SOURCE);

        for (FileObject root : pcp.getRoots()) {
          if (roots.add(root)) {
            ClassPath src =
                org.netbeans.spi.java.classpath.support.ClassPathSupport.createClassPath(root);
            ClasspathInfo ci = ClasspathInfo.create(EMPTY_CLASSPATH, EMPTY_CLASSPATH, src);
            if (isCanceled) return;

            sources.add(new CacheItem(root, ci, false));
          }
        }
      }

      if (isCanceled) return;
      cache = sources;
    }

    ArrayList<VisageTypeDescription> types = new ArrayList<VisageTypeDescription>();

    res.setMessage(null); // no startup scanning yet.

    final String textForQuery;
    switch (nameKind) {
      case REGEXP:
      case CASE_INSENSITIVE_REGEXP:
        //                text = removeNonJavaChars(text);
        String pattern =
            searchType == SearchType.CASE_INSENSITIVE_EXACT_NAME ? text : text + "*"; // NOI18N
        pattern = pattern.replace("*", ".*").replace('?', '.');
        textForQuery = pattern;
        break;
      default:
        textForQuery = text;
    }
    LOGGER.fine("Text For Query '" + textForQuery + "'.");

    for (final CacheItem ci : cache) {
      @SuppressWarnings("unchecked")
      final Set<ElementHandle<TypeElement>> names =
          ci.classpathInfo
              .getClassIndex()
              .getDeclaredTypes(
                  textForQuery,
                  nameKind,
                  EnumSet.of(
                      ci.isBinary
                          ? ClassIndex.SearchScope.DEPENDENCIES
                          : ClassIndex.SearchScope.SOURCE));
      for (ElementHandle<TypeElement> name : names) {
        VisageTypeDescription td = new VisageTypeDescription(ci, name);
        types.add(td);
        if (isCanceled) {
          return;
        }
      }
    }

    if (isCanceled) return;

    res.addResult(types);
  }
/** @author nenik */
public class VisageTypeProvider implements TypeProvider {
  private static final Logger LOGGER = Logger.getLogger(VisageTypeProvider.class.getName());
  private static final ClassPath EMPTY_CLASSPATH =
      org.netbeans.spi.java.classpath.support.ClassPathSupport.createClassPath(new FileObject[0]);
  private Set<CacheItem> cache;
  private volatile boolean isCanceled = false;

  public String name() {
    return "visage"; // system name: NOI18N
  }

  public String getDisplayName() {
    return "Visage Types"; // XXX internationalization
  }

  public void cancel() {
    isCanceled = true;
  }

  public void cleanup() {
    isCanceled = false;
    cache = null;
  }

  public void computeTypeNames(TypeProvider.Context context, TypeProvider.Result res) {
    isCanceled = false;
    String text = context.getText();
    SearchType searchType = context.getSearchType();

    //        boolean hasBinaryOpen = Lookup.getDefault().lookup(BinaryElementOpen.class) != null;
    final ClassIndex.NameKind nameKind;
    switch (searchType) {
      case EXACT_NAME:
        nameKind = ClassIndex.NameKind.SIMPLE_NAME;
        break;
      case CASE_INSENSITIVE_EXACT_NAME:
        nameKind = ClassIndex.NameKind.CASE_INSENSITIVE_REGEXP;
        break;
      case PREFIX:
        nameKind = ClassIndex.NameKind.PREFIX;
        break;
      case CASE_INSENSITIVE_PREFIX:
        nameKind = ClassIndex.NameKind.CASE_INSENSITIVE_PREFIX;
        break;
      case REGEXP:
        nameKind = ClassIndex.NameKind.REGEXP;
        break;
      case CASE_INSENSITIVE_REGEXP:
        nameKind = ClassIndex.NameKind.CASE_INSENSITIVE_REGEXP;
        break;
      case CAMEL_CASE:
        nameKind = ClassIndex.NameKind.CAMEL_CASE;
        break;
      default:
        throw new RuntimeException("Unexpected search type: " + searchType); // NOI18N
    }

    long time = 0;

    long cp, gss, gsb, sfb, gtn, add, sort;
    cp = gss = gsb = sfb = gtn = add = sort = 0;

    Future<Project[]> openProjectsTask = OpenProjects.getDefault().openProjects();
    Project[] projs = new Project[0];
    try {
      projs = openProjectsTask.get();
    } catch (InterruptedException ex) {
      LOGGER.fine(ex.getMessage());
    } catch (ExecutionException ex) {
      LOGGER.fine(ex.getMessage());
    }

    if (cache == null) {
      Set<CacheItem> sources = new HashSet<CacheItem>();
      Set<FileObject> roots = new HashSet<FileObject>();
      for (Project project : projs) {
        if (!(project instanceof VisageProject)) continue;
        VisageProject jfxp = (VisageProject) project;
        ClassPath pcp = jfxp.getClassPathProvider().getProjectSourcesClassPath(ClassPath.SOURCE);

        for (FileObject root : pcp.getRoots()) {
          if (roots.add(root)) {
            ClassPath src =
                org.netbeans.spi.java.classpath.support.ClassPathSupport.createClassPath(root);
            ClasspathInfo ci = ClasspathInfo.create(EMPTY_CLASSPATH, EMPTY_CLASSPATH, src);
            if (isCanceled) return;

            sources.add(new CacheItem(root, ci, false));
          }
        }
      }

      if (isCanceled) return;
      cache = sources;
    }

    ArrayList<VisageTypeDescription> types = new ArrayList<VisageTypeDescription>();

    res.setMessage(null); // no startup scanning yet.

    final String textForQuery;
    switch (nameKind) {
      case REGEXP:
      case CASE_INSENSITIVE_REGEXP:
        //                text = removeNonJavaChars(text);
        String pattern =
            searchType == SearchType.CASE_INSENSITIVE_EXACT_NAME ? text : text + "*"; // NOI18N
        pattern = pattern.replace("*", ".*").replace('?', '.');
        textForQuery = pattern;
        break;
      default:
        textForQuery = text;
    }
    LOGGER.fine("Text For Query '" + textForQuery + "'.");

    for (final CacheItem ci : cache) {
      @SuppressWarnings("unchecked")
      final Set<ElementHandle<TypeElement>> names =
          ci.classpathInfo
              .getClassIndex()
              .getDeclaredTypes(
                  textForQuery,
                  nameKind,
                  EnumSet.of(
                      ci.isBinary
                          ? ClassIndex.SearchScope.DEPENDENCIES
                          : ClassIndex.SearchScope.SOURCE));
      for (ElementHandle<TypeElement> name : names) {
        VisageTypeDescription td = new VisageTypeDescription(ci, name);
        types.add(td);
        if (isCanceled) {
          return;
        }
      }
    }

    if (isCanceled) return;

    res.addResult(types);
  }

  class VisageTypeDescription extends TypeDescriptor {
    private Icon icon;

    private final CacheItem cacheItem;

    private final ElementHandle<TypeElement> handle;
    private String simpleName;
    private String outerName;
    private String packageName;

    public VisageTypeDescription(CacheItem cacheItem, final ElementHandle<TypeElement> handle) {
      this.cacheItem = cacheItem;
      this.handle = handle;
      init();
    }

    private void init() {
      final String typeName = this.handle.getSignatures()[0]; // getBinaryName();
      int lastDot = typeName.lastIndexOf('.'); // NOI18N
      int lastDollar = typeName.lastIndexOf('$'); // NOI18N
      if (lastDot == -1) {
        if (lastDollar == -1) {
          simpleName = typeName;
        } else {
          simpleName = typeName.substring(lastDollar + 1);
          outerName = typeName.substring(0, lastDollar).replace('$', '.'); // NOI18N;
        }
      } else {
        packageName = typeName.substring(0, lastDot);

        if (lastDollar == -1) {
          simpleName = typeName.substring(lastDot + 1).replace('$', '.'); // NOI18N
        } else {
          simpleName = typeName.substring(lastDollar + 1);
          outerName = typeName.substring(lastDot + 1, lastDollar).replace('$', '.'); // NOI18N;
        }
      }
      icon = null; // Icons.getElementIcon (handle.getKind(), null);
    }

    @Override
    public String getSimpleName() {
      return simpleName;
    }

    @Override
    public String getOuterName() {
      return outerName;
    }

    @Override
    public String getTypeName() {
      StringBuilder sb = new StringBuilder(simpleName);
      if (outerName != null) {
        sb.append(" in ").append(outerName);
      }
      return sb.toString();
    }

    @Override
    public String getContextName() {
      StringBuilder sb = new StringBuilder();
      sb.append(" (").append(packageName == null ? "Default Package" : packageName).append(")");
      return sb.toString();
    }

    @Override
    public Icon getIcon() {
      return icon;
    }

    @Override
    public String getProjectName() {
      String projectName = cacheItem.getProjectName();
      return projectName == null ? "" : projectName; // NOI18N
    }

    @Override
    public Icon getProjectIcon() {
      return cacheItem.getProjectIcon();
    }

    @Override
    public FileObject getFileObject() {
      return cacheItem.getRoot();
    }

    @Override
    public int getOffset() {
      throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void open() {
      ClasspathInfo ci = ClasspathInfo.create(cacheItem.getRoot());
      FileObject file = VisageSourceUtils.getFile(handle, ci);
      try {
        ElementOpen.open(file, handle);
      } catch (Exception exception) {
        LOGGER.fine(exception.getMessage());
        System.err.println("Exc: " + exception);
      }
    }
  }

  static class CacheItem {
    public final boolean isBinary;
    public final FileObject fileObject;
    public final ClasspathInfo classpathInfo;
    public String projectName;
    public Icon projectIcon;
    private ClassPath.Entry defEntry;

    public CacheItem(FileObject fileObject, ClasspathInfo classpathInfo, boolean isBinary) {
      this.isBinary = isBinary;
      this.fileObject = fileObject;
      this.classpathInfo = classpathInfo;
    }

    @Override
    public int hashCode() {
      return this.fileObject == null ? 0 : this.fileObject.hashCode();
    }

    @Override
    public boolean equals(Object other) {
      if (other instanceof CacheItem) {
        CacheItem otherItem = (CacheItem) other;
        return this.fileObject == null
            ? otherItem.fileObject == null
            : this.fileObject.equals(otherItem.fileObject);
      }
      return false;
    }

    public FileObject getRoot() {
      return fileObject;
    }

    public boolean isBinary() {
      return isBinary;
    }

    public synchronized String getProjectName() {
      if (!isBinary && projectName == null) {
        initProjectInfo();
      }
      return projectName;
    }

    public synchronized Icon getProjectIcon() {
      if (!isBinary && projectIcon == null) {
        initProjectInfo();
      }
      return projectIcon;
    }

    private void initProjectInfo() {
      Project p = FileOwnerQuery.getOwner(fileObject);
      if (p != null) {
        ProjectInformation pi = ProjectUtils.getInformation(p);
        projectName = pi.getDisplayName();
        projectIcon = pi.getIcon();
      }
    }
  }
}
  public static List<ErrorDescription> runFindBugs(
      CompilationInfo info,
      Preferences customSettings,
      String singleBug,
      FileObject sourceRoot,
      Iterable<? extends String> classNames,
      FindBugsProgress progress,
      SigFilesValidator validator) {
    List<ErrorDescription> result = new ArrayList<ErrorDescription>();

    try {
      Class.forName(
          "org.netbeans.modules.findbugs.NbClassFactory",
          true,
          RunFindBugs.class.getClassLoader()); // NOI18N
      Project p = new Project();
      URL[] binaryRoots =
          CacheBinaryForSourceQuery.findCacheBinaryRoots(sourceRoot.toURL()).getRoots();

      if (classNames == null) {
        for (URL binary : binaryRoots) {
          try {
            p.addFile(new File(binary.toURI()).getAbsolutePath());
          } catch (URISyntaxException ex) {
            Exceptions.printStackTrace(ex);
          }
        }
      } else {
        ClassPath binary = ClassPathSupport.createClassPath(binaryRoots);
        List<FileObject> sigFiles = new ArrayList<FileObject>();

        for (String className : classNames) {
          FileObject classFO = binary.findResource(className.replace('.', '/') + ".sig"); // NOI18N

          if (classFO != null) {
            sigFiles.add(classFO);
          } else {
            LOG.log(
                Level.WARNING,
                "Cannot find sig file for: "
                    + className); // TODO: should probably become FINE eventually
          }
        }

        assert validator != null;

        if (!validator.validate(sigFiles)) return null;

        for (FileObject classFO : sigFiles) {
          p.addFile(new File(classFO.toURI()).getAbsolutePath());
        }

        addCompileRootAsSource(p, sourceRoot);
      }

      ClassPath compile = ClassPath.getClassPath(sourceRoot, ClassPath.COMPILE);

      for (FileObject compileRoot : compile.getRoots()) {
        addCompileRoot(p, compileRoot);
      }

      BugCollectionBugReporter r =
          new BugCollectionBugReporter(p) {
            @Override
            protected void emitLine(String line) {
              LOG.log(Level.FINE, line);
            }
          };

      r.setPriorityThreshold(Integer.MAX_VALUE);
      r.setRankThreshold(Integer.MAX_VALUE);

      FindBugs2 engine = new FindBugs2();

      engine.setProject(p);
      engine.setNoClassOk(true);
      engine.setBugReporter(r);

      if (progress != null) {
        engine.setProgressCallback(progress);
      }

      boolean inEditor = validator != null;
      Preferences settings =
          customSettings != null
              ? customSettings
              : NbPreferences.forModule(RunFindBugs.class).node("global-settings");
      UserPreferences preferences;

      if (singleBug != null) {
        singleBug = singleBug.substring(PREFIX_FINDBUGS.length());
        preferences = forSingleBug(singleBug);
      } else {
        preferences = readPreferences(settings, customSettings != null);
      }

      if (preferences == null) {
        // nothing enabled, stop
        return result;
      }

      engine.setUserPreferences(preferences);
      engine.setDetectorFactoryCollection(DetectorFactoryCollection.instance());

      LOG.log(Level.FINE, "Running FindBugs");

      engine.execute();

      Map<FileObject, List<BugInstance>> file2Bugs = new HashMap<FileObject, List<BugInstance>>();

      for (BugInstance b : r.getBugCollection().getCollection()) {
        if (singleBug != null && !singleBug.equals(b.getBugPattern().getType())) continue;
        if (singleBug == null
            && !settings.getBoolean(
                b.getBugPattern().getType(),
                customSettings == null && isEnabledByDefault(b.getBugPattern()))) {
          continue;
        }

        SourceLineAnnotation sourceLine = b.getPrimarySourceLineAnnotation();
        FileObject sourceFile = null;

        if (sourceLine != null) {
          sourceFile = sourceRoot.getFileObject(sourceLine.getSourcePath());

          if (sourceFile != null) {
            List<BugInstance> bugs = file2Bugs.get(sourceFile);

            if (bugs == null) {
              file2Bugs.put(sourceFile, bugs = new ArrayList<BugInstance>());
            }

            bugs.add(b);
          } else {
            LOG.log(
                Level.WARNING,
                "{0}, location: {1}:{2}",
                new Object[] {b, sourceLine.getSourcePath(), sourceLine.getStartLine()});
          }
        }
      }

      for (Entry<FileObject, List<BugInstance>> e : file2Bugs.entrySet()) {
        int[] lineOffsets = null;
        FileObject sourceFile = e.getKey();
        DataObject d = DataObject.find(sourceFile);
        EditorCookie ec = d.getLookup().lookup(EditorCookie.class);
        Document doc = ec.getDocument();
        JavaSource js = null;

        for (BugInstance b : e.getValue()) {
          SourceLineAnnotation sourceLine = b.getPrimarySourceLineAnnotation();

          if (sourceLine.getStartLine() >= 0) {
            LazyFixList fixes =
                prepareFixes(b, inEditor, sourceFile, sourceLine.getStartLine(), null);

            if (doc != null) {
              result.add(
                  ErrorDescriptionFactory.createErrorDescription(
                      PREFIX_FINDBUGS + b.getType(),
                      Severity.VERIFIER,
                      b.getMessageWithoutPrefix(),
                      b.getBugPattern().getDetailHTML(),
                      fixes,
                      doc,
                      sourceLine.getStartLine()));
            } else {
              if (lineOffsets == null) {
                lineOffsets = computeLineMap(sourceFile, FileEncodingQuery.getEncoding(sourceFile));
              }

              int edLine = 2 * (Math.min(sourceLine.getStartLine(), lineOffsets.length / 2) - 1);

              result.add(
                  ErrorDescriptionFactory.createErrorDescription(
                      PREFIX_FINDBUGS + b.getType(),
                      Severity.VERIFIER,
                      b.getMessageWithoutPrefix(),
                      b.getBugPattern().getDetailHTML(),
                      fixes,
                      sourceFile,
                      lineOffsets[edLine],
                      lineOffsets[edLine + 1]));
            }
          } else {
            if (js == null) {
              js = JavaSource.forFileObject(sourceFile);
            }
            addByElementAnnotation(b, info, sourceFile, js, result, inEditor);
          }
        }
      }
    } catch (ClassNotFoundException ex) {
      Exceptions.printStackTrace(ex);
    } catch (IOException ex) {
      Exceptions.printStackTrace(ex);
    } catch (InterruptedException ex) {
      LOG.log(Level.FINE, null, ex);
    }

    return result;
  }
 public ClassPathProviderImpl(FileObject[] sourceRoots) {
   this.sourcePath = ClassPathSupport.createClassPath(sourceRoots);
 }
 public ClassPath getBootstrapLibraries() {
   return ClassPathSupport.createClassPath(new URL[0]);
 }