@Override
 public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
   if (monitor.isCanceled()) {
     return Status.CANCEL_STATUS;
   }
   monitor.beginTask("Confuguring the project", 1);
   // JSDT "Includes Path", has changed.
   if (fJsProject != null) {
     IProject project = fJsProject.getProject();
     if (TernCorePlugin.hasTernNature(project)) {
       // It's a tern project
       try {
         IIDETernProject ternProject = TernCorePlugin.getTernProject(project);
         // Synchronize tern script paths with JSDT
         // "Include Path"
         synchTernScriptPaths(fJsProject, ternProject);
       } catch (Exception e) {
         Trace.trace(Trace.SEVERE, "Error while JSDT ClassPath changed.", e);
       }
     }
   }
   monitor.worked(1);
   monitor.done();
   return Status.OK_STATUS;
 }
 /** Observe the changes of the JSDT "Include Path" to synchronize tern script paths. */
 @Override
 public void elementChanged(ElementChangedEvent event) {
   IJavaScriptElementDelta delta = event.getDelta();
   if (delta.getKind() == IJavaScriptElementDelta.CHANGED) {
     // retrieve the JSDT Project if delta is about "Includes Path"
     // changes.
     IJavaScriptProject jsProject = getJavaScriptProjectIfClassPathChanged(delta);
     if (jsProject != null) {
       Job configJob = new ConfigureJob(jsProject);
       configJob.setRule(jsProject.getProject());
       configJob.schedule();
     }
   }
 }
  protected Object[] getPackageFragmentRoots(IJavaScriptProject project)
      throws JavaScriptModelException {
    if (!project.getProject().isOpen()) return NO_CHILDREN;

    IPackageFragmentRoot[] roots = project.getPackageFragmentRoots();
    List list = new ArrayList(roots.length);
    // filter out package fragments that correspond to projects and
    // replace them with the package fragments directly
    for (int i = 0; i < roots.length; i++) {
      IPackageFragmentRoot root = roots[i];
      if (!root.isExternal()) {
        Object[] children = root.getChildren();
        for (int k = 0; k < children.length; k++) list.add(children[k]);
      } else if (hasChildren(root)) {
        list.add(root);
      }
    }
    return concatenate(list.toArray(), project.getNonJavaScriptResources());
  }
 /* (non-Javadoc)
  * @see org.eclipse.core.expressions.IPropertyTester#test(java.lang.Object, java.lang.String, java.lang.Object[], java.lang.Object)
  */
 public boolean test(Object receiver, String method, Object[] args, Object expectedValue) {
   if (!(receiver instanceof IJavaScriptElement)) {
     return false;
   }
   IJavaScriptElement res = (IJavaScriptElement) receiver;
   if (method.equals(NAME)) {
     return Pattern.matches(toString(expectedValue), res.getElementName());
   } else if (method.equals(IS_IN_JAVA_PROJECT)) {
     IJavaScriptProject javaProject = res.getJavaScriptProject();
     return javaProject != null && javaProject.exists() && javaProject.getProject().isOpen();
   } else if (method.equals(IS_IN_JAVA_PROJECT_WITH_NATURE)) {
     IJavaScriptProject javaProject = res.getJavaScriptProject();
     if (javaProject != null && javaProject.exists() && javaProject.getProject().isOpen()) {
       if (expectedValue != null) {
         try {
           return javaProject.getProject().hasNature(toString(expectedValue));
         } catch (CoreException e) {
           return false;
         }
       }
     }
     return false;
   } else if (method.equals(IS_ON_CLASSPATH)) {
     IJavaScriptProject javaProject = res.getJavaScriptProject();
     if (javaProject != null && javaProject.exists()) {
       return javaProject.isOnIncludepath(res);
     }
     return false;
   } else if (method.equals(IN_SOURCE_FOLDER)) {
     IJavaScriptElement root = res.getAncestor(IJavaScriptElement.PACKAGE_FRAGMENT_ROOT);
     if (root != null) {
       try {
         return ((IPackageFragmentRoot) root).getKind() == IPackageFragmentRoot.K_SOURCE;
       } catch (JavaScriptModelException e) {
         // ignore
       }
     }
     return false;
   } else if (method.equals(IN_ARCHIVE)) {
     IJavaScriptElement root = res.getAncestor(IJavaScriptElement.PACKAGE_FRAGMENT_ROOT);
     if (root != null) {
       return ((IPackageFragmentRoot) root).isArchive();
     }
     return false;
   } else if (method.equals(IN_EXTERNAL_ARCHIVE)) {
     IJavaScriptElement root = res.getAncestor(IJavaScriptElement.PACKAGE_FRAGMENT_ROOT);
     if (root != null) {
       return ((IPackageFragmentRoot) root).isExternal();
     }
     return false;
   } else if (method.equals(PROJECT_OPTION)) {
     IJavaScriptProject project = res.getJavaScriptProject();
     if (project != null) {
       if (args.length == 2) {
         String current = project.getOption(toString(args[0]), true);
         return current != null && current.equals(args[1]);
       } else if (args.length == 1) {
         return project.getOption(toString(args[0]), false) != null;
       }
     }
     return false;
   } else if (method.equals(HAS_TYPE_ON_CLASSPATH)) {
     IJavaScriptProject javaProject = res.getJavaScriptProject();
     if (javaProject != null && javaProject.exists()) {
       try {
         return javaProject.findType(toString(expectedValue)) != null;
       } catch (JavaScriptModelException e) {
         return false;
       }
     }
   }
   return false;
 }