@NotNull
  private static String findMainClass(VirtualFile gradleHome, VirtualFile script, Project project) {
    final String userDefined = System.getProperty("gradle.launcher.class");
    if (StringUtil.isNotEmpty(userDefined)) {
      return userDefined;
    }

    VirtualFile launcher = gradleHome.findFileByRelativePath("bin/gradle");
    if (launcher == null) {
      launcher = gradleHome.findFileByRelativePath("bin/gradle.bat");
    }
    if (launcher != null) {
      try {
        final String text = StringUtil.convertLineSeparators(VfsUtilCore.loadText(launcher));
        final Matcher matcher = MAIN_CLASS_NAME_PATTERN.matcher(text);
        if (matcher.find()) {
          String candidate = matcher.group(1);
          if (StringUtil.isNotEmpty(candidate)) {
            return candidate;
          }
        }
      } catch (IOException ignored) {
      }
    }

    final PsiFile grFile = PsiManager.getInstance(project).findFile(script);
    if (grFile != null
        && JavaPsiFacade.getInstance(project)
                .findClass("org.gradle.BootstrapMain", grFile.getResolveScope())
            != null) {
      return "org.gradle.BootstrapMain";
    }

    return "org.gradle.launcher.GradleMain";
  }
  @Nullable
  public VirtualFile findFileByDartUrl(final @NotNull String url) {
    if (url.startsWith(DART_PREFIX)) {
      return findFileInDartSdkLibFolder(myProject, myDartSdk, url);
    }

    if (url.startsWith(PACKAGE_PREFIX)) {
      final String packageRelPath = url.substring(PACKAGE_PREFIX.length());

      final int slashIndex = packageRelPath.indexOf('/');
      final String packageName =
          slashIndex > 0 ? packageRelPath.substring(0, slashIndex) : packageRelPath;
      final String pathRelToPackageDir =
          slashIndex > 0 ? packageRelPath.substring(slashIndex + 1) : "";

      final VirtualFile packageDir =
          StringUtil.isEmpty(packageName) ? null : myLivePackageNameToDirMap.get(packageName);
      if (packageDir != null) {
        return packageDir.findFileByRelativePath(pathRelToPackageDir);
      }

      for (final VirtualFile packageRoot : myPackageRoots) {
        final VirtualFile file = packageRoot.findFileByRelativePath(packageRelPath);
        if (file != null) {
          return file;
        }
      }

      final Set<String> packageDirs = myPubListPackageDirsMap.get(packageName);
      if (packageDirs != null) {
        for (String packageDirPath : packageDirs) {
          final VirtualFile file =
              LocalFileSystem.getInstance()
                  .findFileByPath(packageDirPath + "/" + pathRelToPackageDir);
          if (file != null) {
            return file;
          }
        }
      }
    }

    if (url.startsWith(FILE_PREFIX)) {
      final String path = StringUtil.trimLeading(url.substring(FILE_PREFIX.length()), '/');
      return LocalFileSystem.getInstance()
          .findFileByPath(SystemInfo.isWindows ? path : ("/" + path));
    }

    if (ApplicationManager.getApplication().isUnitTestMode() && url.startsWith(TEMP_PREFIX)) {
      return TempFileSystem.getInstance().findFileByPath(url.substring((TEMP_PREFIX).length()));
    }

    return null;
  }
  // relativePaths are guaranteed to fit into command line length limitations.
  @Override
  @NotNull
  public Collection<VirtualFile> untrackedFilesNoChunk(
      @NotNull Project project, @NotNull VirtualFile root, @Nullable List<String> relativePaths)
      throws VcsException {
    final Set<VirtualFile> untrackedFiles = new HashSet<VirtualFile>();
    GitSimpleHandler h = new GitSimpleHandler(project, root, GitCommand.LS_FILES);
    h.setNoSSH(true);
    h.setSilent(true);
    h.addParameters("--exclude-standard", "--others", "-z");
    h.endOptions();
    if (relativePaths != null) {
      h.addParameters(relativePaths);
    }

    final String output = h.run();
    if (StringUtil.isEmptyOrSpaces(output)) {
      return untrackedFiles;
    }

    for (String relPath : output.split("\u0000")) {
      VirtualFile f = root.findFileByRelativePath(relPath);
      if (f == null) {
        // files was created on disk, but VirtualFile hasn't yet been created,
        // when the GitChangeProvider has already been requested about changes.
        LOG.info(String.format("VirtualFile for path [%s] is null", relPath));
      } else {
        untrackedFiles.add(f);
      }
    }

    return untrackedFiles;
  }
  @NotNull
  public List<? extends LocalQuickFix> registerFixes(final FileReference reference) {
    final PsiElement element = reference.getElement();
    if (!(reference instanceof JSFlexFileReference)
        || !(element instanceof JSAttributeNameValuePair)) return Collections.emptyList();

    final PsiElement parent = element.getParent();
    if (!(parent instanceof JSAttribute)
        || !FlexAnnotationNames.EMBED.equals(((JSAttribute) parent).getName())) {
      return Collections.emptyList();
    }

    final String value = ((JSAttributeNameValuePair) element).getSimpleValue();
    if (value.startsWith("/")) return Collections.emptyList();

    final Module module = ModuleUtil.findModuleForPsiElement(element);
    if (module == null) return Collections.emptyList();

    final ModuleRootManager rootManager = ModuleRootManager.getInstance(module);
    final VirtualFile virtualFile = element.getContainingFile().getVirtualFile();
    final boolean testSourceRoot =
        virtualFile != null && rootManager.getFileIndex().isInTestSourceContent(virtualFile);

    for (VirtualFile sourceRoot : rootManager.getSourceRoots(testSourceRoot)) {
      if (sourceRoot.findFileByRelativePath(value) != null) {
        return Collections.singletonList(
            new AddLeadingSlashFix((JSAttributeNameValuePair) element));
      }
    }

    return Collections.emptyList();
  }
Пример #5
0
  @Nullable
  public static VirtualFile doResolveSuperPomFile(@NotNull File mavenHome) {
    File[] files = mavenHome.listFiles();
    if (files == null) return null;

    for (File library : files) {

      for (Pair<Pattern, String> path : SUPER_POM_PATHS) {
        if (path.first.matcher(library.getName()).matches()) {
          VirtualFile libraryVirtualFile = LocalFileSystem.getInstance().findFileByIoFile(library);
          if (libraryVirtualFile == null) continue;

          VirtualFile root = ArchiveVfsUtil.getJarRootForLocalFile(libraryVirtualFile);
          if (root == null) continue;

          VirtualFile pomFile = root.findFileByRelativePath(path.second);
          if (pomFile != null) {
            return pomFile;
          }
        }
      }
    }

    return null;
  }
  @Nullable
  public VirtualFile getPackageDirIfLivePackageOrFromPubListPackageDirs(
      @NotNull final String packageName, @Nullable final String pathRelToPackageDir) {
    final VirtualFile dir = myLivePackageNameToDirMap.get(packageName);
    if (dir != null) return dir;

    final Set<String> dirPaths = myPubListPackageDirsMap.get(packageName);
    if (dirPaths != null) {
      VirtualFile notNullPackageDir = null;

      for (String dirPath : dirPaths) {
        final VirtualFile packageDir =
            ApplicationManager.getApplication().isUnitTestMode()
                ? TempFileSystem.getInstance().findFileByPath(dirPath)
                : LocalFileSystem.getInstance().findFileByPath(dirPath);
        if (notNullPackageDir == null && packageDir != null) {
          notNullPackageDir = packageDir;
        }

        if (packageDir != null
            && (StringUtil.isEmpty(pathRelToPackageDir)
                || packageDir.findFileByRelativePath(pathRelToPackageDir) != null)) {
          return packageDir;
        }
      }

      return notNullPackageDir; // file by pathRelToPackageDir was not found, but not-null
                                // packageDir still may be useful
    }

    return null;
  }
  @Test
  public void updateShouldNotMergeWithNonCommittedChanges() throws Exception {
    changeFile_A_AndCommitInRemoteRepository();

    // generate some extra local history
    createAndCommitNewFileInLocalRepository();

    HgRevisionNumber parentBeforeUpdate =
        new HgWorkingCopyRevisionsCommand(myProject).parents(projectRepoVirtualFile).get(0);

    editFileInCommand(
        myProject,
        projectRepoVirtualFile.findFileByRelativePath("com/a.txt"),
        "modified file contents");

    assertUpdateThroughPluginFails();

    assertEquals(
        new HgHeadsCommand(myProject, projectRepoVirtualFile).execute().size(),
        2,
        "Remote head should have been pulled in");

    assertEquals(
        new HgWorkingCopyRevisionsCommand(myProject).parents(projectRepoVirtualFile).size(),
        1,
        "No merge should have been attempted");

    assertEquals(
        new HgWorkingCopyRevisionsCommand(myProject).parents(projectRepoVirtualFile).get(0),
        parentBeforeUpdate,
        "No merge should have been attempted");
  }
 private static void visitGitDirVfs(@NotNull VirtualFile gitDir) {
   gitDir.getChildren();
   for (String subdir : GitRepositoryFiles.getSubDirRelativePaths()) {
     VirtualFile dir = gitDir.findFileByRelativePath(subdir);
     // process recursively, because we need to visit all branches under refs/heads and
     // refs/remotes
     visitAllChildrenRecursively(dir);
   }
 }
Пример #9
0
 public static void visitVcsDirVfs(
     @NotNull VirtualFile vcsDir, @NotNull Collection<String> subDirs) {
   vcsDir.getChildren();
   for (String subdir : subDirs) {
     VirtualFile dir = vcsDir.findFileByRelativePath(subdir);
     // process recursively, because we need to visit all branches under refs/heads and
     // refs/remotes
     ensureAllChildrenInVfs(dir);
   }
 }
  private static PsiFile findInModuleRoots(Module module, String path) {
    for (VirtualFile root : ModuleRootManager.getInstance(module).getContentRoots()) {
      VirtualFile file = root.findFileByRelativePath(path);
      if (file != null) {
        return PsiManager.getInstance(module.getProject()).findFile(file);
      }
    }

    return null;
  }
  @Nullable
  private static VirtualFile getHelpFile(
      AntDomElement antElement, final VirtualFile documentationRoot) {
    final XmlTag xmlTag = antElement.getXmlTag();
    if (xmlTag == null) {
      return null;
    }
    @NonNls final String helpFileShortName = "/" + xmlTag.getName() + ".html";

    VirtualFile candidateHelpFile =
        documentationRoot.findFileByRelativePath(CORE_TASKS_FOLDER_NAME + helpFileShortName);
    if (candidateHelpFile != null) {
      return candidateHelpFile;
    }

    candidateHelpFile =
        documentationRoot.findFileByRelativePath(OPTIONAL_TASKS_FOLDER_NAME + helpFileShortName);
    if (candidateHelpFile != null) {
      return candidateHelpFile;
    }

    candidateHelpFile =
        documentationRoot.findFileByRelativePath(CORE_TYPES_FOLDER_NAME + helpFileShortName);
    if (candidateHelpFile != null) {
      return candidateHelpFile;
    }

    candidateHelpFile =
        documentationRoot.findFileByRelativePath(OPTIONAL_TYPES_FOLDER_NAME + helpFileShortName);
    if (candidateHelpFile != null) {
      return candidateHelpFile;
    }

    if (antElement instanceof AntDomTarget || antElement instanceof AntDomProject) {
      candidateHelpFile = documentationRoot.findFileByRelativePath("using.html");
      if (candidateHelpFile != null) {
        return candidateHelpFile;
      }
    }

    return null;
  }
Пример #12
0
 /**
  * Get git roots from content roots
  *
  * @param roots git content roots
  * @return a content root
  */
 public static Set<VirtualFile> gitRootsForPaths(final Collection<VirtualFile> roots) {
   HashSet<VirtualFile> rc = new HashSet<VirtualFile>();
   for (VirtualFile root : roots) {
     VirtualFile f = root;
     do {
       if (f.findFileByRelativePath(DOT_GIT) != null) {
         rc.add(f);
         break;
       }
       f = f.getParent();
     } while (f != null);
   }
   return rc;
 }
  @Nullable
  @Override
  public String getCompilerOutputUrl() {
    if (myOutputDirPointer == null) {
      VirtualFile baseDir = myProject.getBaseDir();
      assert baseDir != null;
      VirtualFile outDir = baseDir.findFileByRelativePath(DEFAULT_OUTPUT_URL);

      return outDir == null
          ? myProject.getPresentableUrl() + "/" + DEFAULT_OUTPUT_URL
          : outDir.getUrl();
    }
    return myOutputDirPointer.getUrl();
  }
 /**
  * Creates the necessary temporary directories in the filesystem with empty ".mock" directories
  * for given roots. And creates an instance of the project.
  *
  * @param mockRoots path to actual .mock roots, relative to the project dir.
  */
 public void initProject(@NotNull VcsRootConfiguration vcsRootConfiguration) throws IOException {
   createDirs(vcsRootConfiguration.getMockRoots());
   Collection<String> contentRoots = vcsRootConfiguration.getContentRoots();
   createProjectStructure(myProject, contentRoots);
   if (!contentRoots.isEmpty()) {
     for (String root : contentRoots) {
       myProjectRoot.refresh(false, true);
       VirtualFile f = myProjectRoot.findFileByRelativePath(root);
       if (f != null) {
         myRootModel.addContentEntry(f);
       }
     }
   }
 }
Пример #15
0
 /**
  * Return a git root for the file (the parent directory with ".git" subdirectory)
  *
  * @param file the file to check
  * @return git root for the file or null if the file is not not under Git
  * @deprecated because uses the java.io.File.
  * @use GitRepositoryManager#getRepositoryForFile().
  */
 @Nullable
 public static VirtualFile gitRootOrNull(final VirtualFile file) {
   if (file instanceof AbstractVcsVirtualFile) {
     return getGitRootOrNull(VcsUtil.getFilePath(file.getPath()));
   }
   VirtualFile root = file;
   while (root != null) {
     if (root.findFileByRelativePath(DOT_GIT) != null) {
       return root;
     }
     root = root.getParent();
   }
   return root;
 }
  @Nullable
  @Override
  public VirtualFile getCompilerOutput() {
    if (myOutputDirPointer == null) {
      VirtualFile baseDir = myProject.getBaseDir();
      if (baseDir == null) {
        return null;
      }
      VirtualFile outDir = baseDir.findFileByRelativePath(DEFAULT_OUTPUT_URL);

      return outDir == null ? null : outDir;
    }
    return myOutputDirPointer.getFile();
  }
 @Nullable
 public String getDefaultMessageFor(FilePath[] filesToCheckin) {
   LinkedHashSet<String> messages = ContainerUtil.newLinkedHashSet();
   for (VirtualFile root : GitUtil.gitRoots(Arrays.asList(filesToCheckin))) {
     VirtualFile mergeMsg = root.findFileByRelativePath(GitRepositoryFiles.GIT_MERGE_MSG);
     VirtualFile squashMsg = root.findFileByRelativePath(GitRepositoryFiles.GIT_SQUASH_MSG);
     try {
       if (mergeMsg == null && squashMsg == null) {
         continue;
       }
       String encoding = GitConfigUtil.getCommitEncoding(myProject, root);
       if (mergeMsg != null) {
         messages.add(loadMessage(mergeMsg, encoding));
       } else {
         messages.add(loadMessage(squashMsg, encoding));
       }
     } catch (IOException e) {
       if (log.isDebugEnabled()) {
         log.debug("Unable to load merge message", e);
       }
     }
   }
   return DvcsUtil.joinMessagesOrNull(messages);
 }
  @Override
  public PsiFile fromString(@Nullable @NonNls String s, ConvertContext context) {
    if (StringUtil.isEmptyOrSpaces(s)) return null;

    VirtualFile contextFile = context.getFile().getVirtualFile();
    if (contextFile == null) return null;

    VirtualFile f = contextFile.getParent().findFileByRelativePath(s);
    if (f == null) return null;

    if (f.isDirectory()) f = f.findFileByRelativePath(MavenConstants.POM_XML);
    if (f == null) return null;

    return context.getPsiManager().findFile(f);
  }
  @Nullable
  private static VirtualFile getPluginXmlFile(
      Project project, String groupId, String artifactId, String version) {
    File file =
        MavenArtifactUtil.getArtifactFile(
            MavenProjectsManager.getInstance(project).getLocalRepository(),
            groupId,
            artifactId,
            version,
            "jar");
    VirtualFile pluginFile = LocalFileSystem.getInstance().findFileByIoFile(file);
    if (pluginFile == null) return null;

    VirtualFile pluginJarRoot = JarFileSystem.getInstance().getJarRootForLocalFile(pluginFile);
    if (pluginJarRoot == null) return null;
    return pluginJarRoot.findFileByRelativePath(MavenArtifactUtil.MAVEN_PLUGIN_DESCRIPTOR);
  }
 private static void addSourceDirectoriesFromLibraries(
     @NotNull Project project,
     @NotNull VirtualFile directory,
     @NotNull Collection<VirtualFile> outSourceRoots) {
   ProjectFileIndex index = ProjectFileIndex.SERVICE.getInstance(project);
   VirtualFile classRoot = index.getClassRootForFile(directory);
   if (classRoot == null) return;
   String relativePath = VfsUtilCore.getRelativePath(directory, classRoot);
   if (relativePath == null) return;
   for (OrderEntry orderEntry : index.getOrderEntriesForFile(directory)) {
     for (VirtualFile sourceRoot : orderEntry.getFiles(OrderRootType.SOURCES)) {
       VirtualFile sourceFile = sourceRoot.findFileByRelativePath(relativePath);
       if (sourceFile != null) {
         outSourceRoots.add(sourceFile);
       }
     }
   }
 }
Пример #21
0
  @Override
  public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
    final String nameText = nlsName;
    VirtualFile[] nlsRoots = NlsUtils.getNlsRoots(module);
    assert nlsRoots.length > 0 : "Nls files without nls roots should not exists";

    final VirtualFile nlsRoot = nlsRoots[0]; // todo #WT-24
    assert nlsRoot != null;
    assert nlsRoot.isValid();

    VirtualFile child = nlsRoot.findFileByRelativePath(NlsUtils.nlsNameToPath(nameText, "/"));
    assert child == null : "QuickFix called on unresolved name, but file exists!";

    final String[] chunks = NlsUtils.nlsNameToPathChunks(nameText);
    if (ArrayUtils.isEmpty(chunks)) return;

    VirtualFile createdFile =
        ApplicationManager.getApplication()
            .runWriteAction(
                new Computable<VirtualFile>() {
                  @Override
                  public VirtualFile compute() {
                    try {
                      return createNlsByPath(nlsRoot, chunks);
                    } catch (IOException e) {
                      LOG.error("On create nls ''{0}''", e, nameText);
                    }
                    return null;
                  }
                });

    if (createdFile != null) {
      OpenFileDescriptor openFileDescriptor = new OpenFileDescriptor(project, createdFile, 0);
      FileEditorManager.getInstance(project).openTextEditor(openFileDescriptor, true);
    }
  }
 @Nullable
 private static ParentDirWithLastComponentPrefix findParentDirWithLastComponentPrefix(
     @NotNull VirtualFile basePath, @NotNull String pathBeforeCaret) {
   BipartiteString parentDirStrWithLastComponent =
       findParentDirStrWithLastComponentPrefix(pathBeforeCaret);
   String parentDirPath =
       FileUtil.toSystemIndependentName(parentDirStrWithLastComponent.getPrefix());
   {
     VirtualFile parentFile = basePath.findFileByRelativePath(parentDirPath);
     if (parentFile != null) {
       return new ParentDirWithLastComponentPrefix(
           parentFile, parentDirStrWithLastComponent.getSuffix());
     }
   }
   File absolutePath = new File(parentDirPath);
   if (absolutePath.isAbsolute()) {
     VirtualFile absolute = LocalFileSystem.getInstance().findFileByIoFile(absolutePath);
     if (absolute != null) {
       return new ParentDirWithLastComponentPrefix(
           absolute, parentDirStrWithLastComponent.getSuffix());
     }
   }
   return null;
 }
Пример #23
0
  private List<JavaFileObject> findInside(
      Location location, String packageName, Set<JavaFileObject.Kind> kinds, boolean lookForFile)
      throws IOException {
    Iterable<? extends File> path = getLocation(location);
    if (path == null) return Collections.emptyList();

    String subdirectory = packageName.replace('.', '/');
    List<JavaFileObject> results = null;

    for (File directory : path) {
      VirtualFile dir = LocalFileSystem.getInstance().findFileByIoFile(directory);
      if (dir == null) continue;
      if (!dir.isDirectory()) {
        dir = JarFileSystem.getInstance().getJarRootForLocalFile(dir);
        if (dir == null) continue;
      }
      VirtualFile virtualFile =
          StringUtil.isEmptyOrSpaces(subdirectory) ? dir : dir.findFileByRelativePath(subdirectory);
      if (virtualFile == null) continue;

      VirtualFile[] children;
      if (lookForFile) {
        if (!virtualFile.isDirectory()) {
          children = new VirtualFile[] {virtualFile};
        } else continue;
      } else {
        children = virtualFile.getChildren();
      }
      for (VirtualFile child : children) {
        JavaFileObject.Kind kind = getKind("." + child.getExtension());
        if (kinds == null || kinds.contains(kind)) {
          if (results == null) results = new SmartList<JavaFileObject>();
          if (kind == JavaFileObject.Kind.SOURCE && child.getFileSystem() instanceof JarFileSystem)
            continue; // for some reasdon javac looks for java files inside jar

          // use VFS to read content inside .jar
          String childPath = child.getPath();
          JavaFileObject fileObject =
              !childPath.contains("!/")
                  ? new JavaIoFile(new File(childPath), kind, myEncoding)
                  : new JavaVirtualFile(child, kind);
          results.add(fileObject);
        }
      }
    }

    List<JavaFileObject> ret = results == null ? Collections.<JavaFileObject>emptyList() : results;

    if (LOG.isDebugEnabled()) {
      // for testing consistency
      Collection c = (Collection) myStandardFileManager.list(location, packageName, kinds, false);
      Collection<JavaFileObject> sup = new HashSet(c);
      assert sup.size() == c.size();
      assert new HashSet(c).equals(sup);

      THashSet<JavaFileObject> s =
          new THashSet<JavaFileObject>(
              new TObjectHashingStrategy<JavaFileObject>() {
                public int computeHashCode(JavaFileObject object) {
                  return object.getName().hashCode();
                }

                public boolean equals(JavaFileObject o1, JavaFileObject o2) {
                  return o1.getKind() == o2.getKind() && o1.toUri().equals(o2.toUri());
                }
              });
      s.addAll(ret);

      s.removeAll(sup);
      if (ret.size() != sup.size()) {
        assert false : "our implementation differs from javac'";
      }
    }

    return ret;
  }
 @Nullable
 protected static PsiDirectory findDirectory(
     Project project, VirtualFile root, @NotNull String relativePath) {
   final VirtualFile file = root.findFileByRelativePath(relativePath);
   return file == null ? null : PsiManager.getInstance(project).findDirectory(file);
 }
  @Override
  public void setupSdkPaths(@NotNull Sdk sdk) {
    VirtualFile homeDirectory = sdk.getHomeDirectory();

    if (sdk.getSdkType() != this || homeDirectory == null) {
      return;
    }

    String path = homeDirectory.getPath();

    GoSdkData sdkData = GoSdkUtil.testGoogleGoSdk(path);

    if (sdkData == null) return;

    final VirtualFile sdkSourcesRoot = homeDirectory.findFileByRelativePath("src/pkg/");

    if (sdkSourcesRoot != null) {
      sdkSourcesRoot.refresh(false, false);
    }

    String goPathFirst = System.getenv("GOPATH");

    VirtualFile goPathDirectory;
    VirtualFile pathSourcesRoot = null;

    if (goPathFirst != null
        && !goPathFirst.equals("")
        && goPathFirst.contains(File.pathSeparator)) {

      // If there are multiple directories under GOPATH then we extract only the first one
      if (goPathFirst.contains(File.pathSeparator)) {
        goPathFirst = goPathFirst.split(File.pathSeparator)[0];
      }

      if ((new File(goPathFirst).exists())) {
        goPathDirectory = StandardFileSystems.local().findFileByPath(goPathFirst);

        if (goPathDirectory != null) {
          pathSourcesRoot = goPathDirectory.findFileByRelativePath("src/");
        }
      }
    }

    final SdkModificator sdkModificator = sdk.getSdkModificator();
    final VirtualFile finalPathSourcesRoot = pathSourcesRoot;

    ApplicationManager.getApplication()
        .runWriteAction(
            new Runnable() {
              public void run() {
                sdkModificator.addRoot(sdkSourcesRoot, OrderRootType.CLASSES);
                sdkModificator.addRoot(sdkSourcesRoot, OrderRootType.SOURCES);

                // If we could detect the GOPATH properly, automatically add the first directory to
                // the autocompletion path
                if (finalPathSourcesRoot != null) {
                  sdkModificator.addRoot(finalPathSourcesRoot, OrderRootType.CLASSES);
                  sdkModificator.addRoot(finalPathSourcesRoot, OrderRootType.SOURCES);
                }
              }
            });

    sdkModificator.setVersionString(sdkData.VERSION_MAJOR);
    sdkModificator.setSdkAdditionalData(sdkData);
    sdkModificator.commitChanges();
  }
  @Override
  @Nullable
  public List<PsiFile> findExternalAnnotationsFiles(@NotNull PsiModifierListOwner listOwner) {
    final PsiFile containingFile = listOwner.getContainingFile();
    if (!(containingFile instanceof PsiJavaFile)) {
      return null;
    }
    final PsiJavaFile javaFile = (PsiJavaFile) containingFile;
    final String packageName = javaFile.getPackageName();
    final VirtualFile virtualFile = containingFile.getVirtualFile();
    if (virtualFile == null) return null;

    final List<PsiFile> files = myExternalAnnotations.get(virtualFile);
    if (files == NULL_LIST) return null;
    if (files != null) {
      boolean allValid = true;
      for (PsiFile file : files) {
        allValid &= file.isValid();
      }
      if (allValid) {
        return files;
      }
    }

    if (virtualFile == null) {
      return null;
    }

    Set<PsiFile> possibleAnnotationsXmls = new THashSet<PsiFile>();
    for (VirtualFile root : getExternalAnnotationsRoots(virtualFile)) {
      final VirtualFile ext =
          root.findFileByRelativePath(packageName.replace('.', '/') + "/" + ANNOTATIONS_XML);
      if (ext == null) continue;
      final PsiFile psiFile = myPsiManager.findFile(ext);
      if (psiFile == null) continue;
      possibleAnnotationsXmls.add(psiFile);
    }
    List<PsiFile> result;
    if (possibleAnnotationsXmls.isEmpty()) {
      myExternalAnnotations.put(virtualFile, NULL_LIST);
      result = null;
    } else {
      result = new SmartList<PsiFile>(possibleAnnotationsXmls);
      // sorting by writability: writable go first
      Collections.sort(
          result,
          new Comparator<PsiFile>() {
            @Override
            public int compare(PsiFile f1, PsiFile f2) {
              boolean w1 = f1.isWritable();
              boolean w2 = f2.isWritable();
              if (w1 == w2) {
                return 0;
              }
              return w1 ? -1 : 1;
            }
          });

      myExternalAnnotations.put(virtualFile, result);
    }
    return result;
  }