private static boolean hasReadOnlyResourcesAndSubResources(IJavaScriptElement javaElement)
      throws CoreException {
    switch (javaElement.getElementType()) {
      case IJavaScriptElement.CLASS_FILE:
        // if this assert fails, it means that a precondition is missing
        Assert.isTrue(((IClassFile) javaElement).getResource() instanceof IFile);
        // fall thru
      case IJavaScriptElement.JAVASCRIPT_UNIT:
        IResource resource = ReorgUtils.getResource(javaElement);
        return (resource != null && Resources.isReadOnly(resource));
      case IJavaScriptElement.PACKAGE_FRAGMENT:
        IResource packResource = ReorgUtils.getResource(javaElement);
        if (packResource == null) return false;
        IPackageFragment pack = (IPackageFragment) javaElement;
        if (Resources.isReadOnly(packResource)) return true;
        Object[] nonJava = pack.getNonJavaScriptResources();
        for (int i = 0; i < nonJava.length; i++) {
          Object object = nonJava[i];
          if (object instanceof IResource
              && hasReadOnlyResourcesAndSubResources((IResource) object)) return true;
        }
        return hasReadOnlyResourcesAndSubResources(pack.getChildren());
      case IJavaScriptElement.PACKAGE_FRAGMENT_ROOT:
        IPackageFragmentRoot root = (IPackageFragmentRoot) javaElement;
        if (root.isArchive()) return false;
        IResource pfrResource = ReorgUtils.getResource(javaElement);
        if (pfrResource == null) return false;
        if (Resources.isReadOnly(pfrResource)) return true;
        Object[] nonJava1 = root.getNonJavaScriptResources();
        for (int i = 0; i < nonJava1.length; i++) {
          Object object = nonJava1[i];
          if (object instanceof IResource
              && hasReadOnlyResourcesAndSubResources((IResource) object)) return true;
        }
        return hasReadOnlyResourcesAndSubResources(root.getChildren());

      case IJavaScriptElement.FIELD:
      case IJavaScriptElement.IMPORT_CONTAINER:
      case IJavaScriptElement.IMPORT_DECLARATION:
      case IJavaScriptElement.INITIALIZER:
      case IJavaScriptElement.METHOD:
      case IJavaScriptElement.TYPE:
        return false;
      default:
        Assert.isTrue(false); // not handled here
        return false;
    }
  }
 // List<IJavaElement>
 private static List getElementsSmallerThanCu(IJavaElement[] javaElements) {
   List result = new ArrayList();
   for (int i = 0; i < javaElements.length; i++) {
     IJavaElement element = javaElements[i];
     if (ReorgUtils.isInsideCompilationUnit(element)) result.add(element);
   }
   return result;
 }
  private static boolean hasReadOnlyResourcesAndSubResources(IModelElement modelElement)
      throws CoreException {
    switch (modelElement.getElementType()) {
      case IModelElement.SOURCE_MODULE:
        IResource resource = ReorgUtils.getResource(modelElement);
        return (resource != null && Resources.isReadOnly(resource));
      case IModelElement.SCRIPT_FOLDER:
        IResource packResource = ReorgUtils.getResource(modelElement);
        if (packResource == null) return false;
        IScriptFolder pack = (IScriptFolder) modelElement;
        if (Resources.isReadOnly(packResource)) return true;
        Object[] nonScript = pack.getForeignResources();
        for (int i = 0; i < nonScript.length; i++) {
          Object object = nonScript[i];
          if (object instanceof IResource
              && hasReadOnlyResourcesAndSubResources((IResource) object)) return true;
        }
        return hasReadOnlyResourcesAndSubResources(pack.getChildren());
      case IModelElement.PROJECT_FRAGMENT:
        IProjectFragment root = (IProjectFragment) modelElement;
        if (root.isArchive()) return false;
        IResource pfrResource = ReorgUtils.getResource(modelElement);
        if (pfrResource == null) return false;
        if (Resources.isReadOnly(pfrResource)) return true;
        Object[] nonScript1 = root.getForeignResources();
        for (int i = 0; i < nonScript1.length; i++) {
          Object object = nonScript1[i];
          if (object instanceof IResource
              && hasReadOnlyResourcesAndSubResources((IResource) object)) return true;
        }
        return hasReadOnlyResourcesAndSubResources(root.getChildren());

      case IModelElement.FIELD:
        //			case IModelElement.IMPORT_CONTAINER:
        //			case IModelElement.IMPORT_DECLARATION:
        //			case IModelElement.INITIALIZER:
      case IModelElement.METHOD:
        //			case IModelElement.PACKAGE_DECLARATION:
      case IModelElement.TYPE:
        return false;
      default:
        Assert.isTrue(false); // not handled here
        return false;
    }
  }
 private static Change createSourceManipulationDeleteChange(ISourceManipulation element) {
   // XXX workaround for bug 31384, in case of linked ISourceManipulation delete the resource
   if (element instanceof ICompilationUnit || element instanceof IPackageFragment) {
     IResource resource;
     if (element instanceof ICompilationUnit)
       resource = ReorgUtils.getResource((ICompilationUnit) element);
     else resource = ((IPackageFragment) element).getResource();
     if (resource != null && resource.isLinked()) return createDeleteChange(resource);
   }
   return new DeleteSourceManipulationChange(element, true);
 }
  /**
   * @param manager the text change manager
   * @param resources the resources to delete
   * @param javaElements the Java elements to delete
   * @param changeName the name of the change
   * @param packageDeletes a list of {@link IResource}s that will be deleted by the delete operation
   *     of the {@link IPackageFragment}s in <code>javaElements</code>, or <code>null</code> iff
   *     <code>javaElements</code> does not contain package fragments
   * @return the created change
   * @throws CoreException
   */
  static Change createDeleteChange(
      TextChangeManager manager,
      IResource[] resources,
      IJavaElement[] javaElements,
      String changeName,
      List /*<IResource>*/ packageDeletes)
      throws CoreException {
    /*
     * Problem: deleting a package and subpackages can result in
     * multiple package fragments in fJavaElements but only
     * one folder in packageDeletes. The way to handle this is to make the undo
     * change of individual package delete changes an empty change, and
     * add take care of the undo in UndoablePackageDeleteChange.
     */
    DynamicValidationStateChange result;
    if (packageDeletes.size() > 0) {
      result = new UndoablePackageDeleteChange(changeName, packageDeletes);
    } else {
      result = new DynamicValidationStateChange(changeName);
    }

    for (int i = 0; i < javaElements.length; i++) {
      IJavaElement element = javaElements[i];
      if (!ReorgUtils.isInsideCompilationUnit(element)) result.add(createDeleteChange(element));
    }

    for (int i = 0; i < resources.length; i++) {
      result.add(createDeleteChange(resources[i]));
    }

    Map grouped = ReorgUtils.groupByCompilationUnit(getElementsSmallerThanCu(javaElements));
    if (grouped.size() != 0) {
      Assert.isNotNull(manager);
      for (Iterator iter = grouped.keySet().iterator(); iter.hasNext(); ) {
        ICompilationUnit cu = (ICompilationUnit) iter.next();
        result.add(createDeleteChange(cu, (List) grouped.get(cu), manager));
      }
    }

    return result;
  }
  private static Change createDeleteChange(IJavaElement javaElement) throws JavaModelException {
    Assert.isTrue(!ReorgUtils.isInsideCompilationUnit(javaElement));

    switch (javaElement.getElementType()) {
      case IJavaElement.PACKAGE_FRAGMENT_ROOT:
        return createPackageFragmentRootDeleteChange((IPackageFragmentRoot) javaElement);

      case IJavaElement.PACKAGE_FRAGMENT:
        return createSourceManipulationDeleteChange((IPackageFragment) javaElement);

      case IJavaElement.COMPILATION_UNIT:
        return createSourceManipulationDeleteChange((ICompilationUnit) javaElement);

      case IJavaElement.CLASS_FILE:
        // if this assert fails, it means that a precondition is missing
        Assert.isTrue(((IClassFile) javaElement).getResource() instanceof IFile);
        return createDeleteChange(((IClassFile) javaElement).getResource());

      case IJavaElement.JAVA_MODEL: // cannot be done
        Assert.isTrue(false);
        return null;

      case IJavaElement.JAVA_PROJECT: // handled differently
        Assert.isTrue(false);
        return null;

      case IJavaElement.TYPE:
      case IJavaElement.FIELD:
      case IJavaElement.METHOD:
      case IJavaElement.INITIALIZER:
      case IJavaElement.PACKAGE_DECLARATION:
      case IJavaElement.IMPORT_CONTAINER:
      case IJavaElement.IMPORT_DECLARATION:
        Assert.isTrue(false); // not done here
        return new NullChange();
      default:
        Assert.isTrue(false); // there's no more kinds
        return new NullChange();
    }
  }