private void createExternalSourceArchivesProject(IProject project, IProgressMonitor monitor)
     throws CoreException {
   IProjectDescription desc = project.getWorkspace().newProjectDescription(project.getName());
   IPath stateLocation = CeylonPlugin.getInstance().getStateLocation();
   desc.setLocation(stateLocation.append(EXTERNAL_PROJECT_NAME));
   project.create(desc, IResource.HIDDEN, monitor);
 }
 public static String getDefaultRepositoryPath() {
   String repositoryPath = CeylonPlugin.getInstance().getDialogSettings().get("repositoryPath");
   if (repositoryPath == null || repositoryPath.startsWith("http://")) {
     repositoryPath = System.getProperty("user.home") + "/.ceylon/repo";
   }
   return repositoryPath;
 }
 @Override
 protected void fillViewMenu(IMenuManager viewMenu) {
   super.fillViewMenu(viewMenu);
   viewMenu.add(new Separator("Sorters"));
   if (lexicalSortingAction != null) {
     viewMenu.add(lexicalSortingAction);
   }
   if (hideNonSharedAction != null) {
     viewMenu.add(hideNonSharedAction);
   }
   viewMenu.add(new Separator());
   Action configureAction =
       new Action(
           "Configure Labels...", CeylonPlugin.imageRegistry().getDescriptor(CONFIG_LABELS)) {
         @Override
         public void run() {
           createPreferenceDialogOn(
                   getShell(),
                   CeylonOutlinesPreferencePage.ID,
                   new String[] {
                     CeylonOutlinesPreferencePage.ID,
                     CeylonPlugin.COLORS_AND_FONTS_PAGE_ID,
                     CeylonFiltersPreferencePage.ID
                   },
                   null)
               .open();
           getTreeViewer().getTree().setFont(CeylonPlugin.getOutlineFont());
           getTreeViewer().refresh();
         }
       };
   viewMenu.add(configureAction);
 }
 public NewProjectWizard(
     NewJavaProjectWizardPageOne pageOne, NewJavaProjectWizardPageTwo pageTwo) {
   setDefaultPageImageDescriptor(
       CeylonPlugin.getInstance().getImageRegistry().getDescriptor(CEYLON_NEW_FILE));
   setDialogSettings(JavaPlugin.getDefault().getDialogSettings());
   setWindowTitle("New Ceylon Project");
   fFirstPage = pageOne;
   fSecondPage = pageTwo;
 }
 @Override
 protected IDialogSettings getDialogSettings() {
   IDialogSettings settings = CeylonPlugin.getInstance().getDialogSettings();
   IDialogSettings section = settings.getSection(SETTINGS_ID);
   if (section == null) {
     section = settings.addNewSection(SETTINGS_ID);
   }
   return section;
 }
 @Override
 public Object[] getChildren(Object element) {
   if (element instanceof CeylonOutlineNode) {
     if (mode) {
       boolean includeParameters = !CeylonPlugin.getPreferences().getBoolean(PARAMS_IN_OUTLINES);
       CeylonOutlineNode node = (CeylonOutlineNode) element;
       CompilationUnit rootNode = getEditor().getParseController().getLastCompilationUnit();
       Node treeNode = Nodes.findNode(rootNode, node.getStartOffset(), node.getEndOffset());
       TypeDeclaration td;
       if (treeNode instanceof ClassOrInterface) {
         ClassOrInterface ci = (ClassOrInterface) treeNode;
         td = ci.getDeclarationModel();
       } else if (treeNode instanceof ObjectDefinition) {
         ObjectDefinition od = (ObjectDefinition) treeNode;
         td = od.getDeclarationModel().getTypeDeclaration();
       } else {
         return super.getChildren(element);
       }
       List<Declaration> list = new ArrayList<Declaration>();
       String filter = getFilterText().getText();
       for (int i = 0; i < filter.length(); i++) {
         char ch = filter.charAt(i);
         if (ch == '*' || i > 0 && Character.isUpperCase(ch)) {
           filter = filter.substring(0, i);
           break;
         }
       }
       Collection<DeclarationWithProximity> members =
           td.getMatchingMemberDeclarations(rootNode.getUnit(), td, filter, 0, null).values();
       for (DeclarationWithProximity dwp : members) {
         for (Declaration dec : overloads(dwp.getDeclaration())) {
           if (!(dec instanceof TypeParameter)) {
             if (includeParameters || !dec.isParameter()) {
               list.add(dec);
             }
           }
         }
       }
       if (!lexicalSortingAction.isChecked()) {
         Collections.sort(
             list,
             new Comparator<Declaration>() {
               public int compare(Declaration x, Declaration y) {
                 String xn = x.getContainer().getQualifiedNameString();
                 String yn = y.getContainer().getQualifiedNameString();
                 return xn.compareTo(yn);
               }
             });
       }
       return list.toArray();
     } else {
       return super.getChildren(element);
     }
   } else {
     return null;
   }
 }
 /*
  * Attempt to open the given project (assuming it exists).
  * If failing to open, make all attempts to recreate the missing pieces.
  */
 private void openExternalSourceArchivesProject(IProject project, IProgressMonitor monitor)
     throws CoreException {
   try {
     project.open(monitor);
   } catch (CoreException e1) {
     if (e1.getStatus().getCode() == IResourceStatus.FAILED_READ_METADATA) {
       // workspace was moved
       project.delete(false /*don't delete content*/, true /*force*/, monitor);
       createExternalSourceArchivesProject(project, monitor);
     } else {
       // .project or folder on disk have been deleted, recreate them
       IPath stateLocation = CeylonPlugin.getInstance().getStateLocation();
       IPath projectPath = stateLocation.append(EXTERNAL_PROJECT_NAME);
       projectPath.toFile().mkdirs();
       try {
         FileOutputStream output =
             new FileOutputStream(projectPath.append(".project").toOSString()); // $NON-NLS-1$
         try {
           output.write(
               ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
                       + //$NON-NLS-1$
                       "<projectDescription>\n"
                       + //$NON-NLS-1$
                       "   <name>"
                       + EXTERNAL_PROJECT_NAME
                       + "</name>\n"
                       + //$NON-NLS-1$ //$NON-NLS-2$
                       "   <comment></comment>\n"
                       + //$NON-NLS-1$
                       "   <projects>\n"
                       + //$NON-NLS-1$
                       "   </projects>\n"
                       + //$NON-NLS-1$
                       "   <buildSpec>\n"
                       + //$NON-NLS-1$
                       "   </buildSpec>\n"
                       + //$NON-NLS-1$
                       "   <natures>\n"
                       + //$NON-NLS-1$
                       "   </natures>\n"
                       + //$NON-NLS-1$
                       "</projectDescription>")
                   .getBytes()); //$NON-NLS-1$
         } finally {
           output.close();
         }
       } catch (IOException e) {
         // fallback to re-creating the project
         project.delete(false /*don't delete content*/, true /*force*/, monitor);
         createExternalSourceArchivesProject(project, monitor);
       }
     }
     project.open(monitor);
   }
 }
  @Override
  public String[] getClasspath(ILaunchConfiguration configuration) throws CoreException {
    IJavaProject javaProject = getJavaProject(configuration);

    String[] javaClasspath = getJavaClasspath(configuration);
    String[] ceylonProjectClasspath = getCeylonProjectClasspath(javaProject);

    List<String> classpathList = new ArrayList<String>();
    classpathList.addAll(asList(javaClasspath));
    classpathList.addAll(asList(ceylonProjectClasspath));
    // at runtime, we need the compiler/common/typechecker/cmr jars to be present for the runtime
    // module system
    classpathList.addAll(CeylonPlugin.getRuntimeRequiredJars());

    return classpathList.toArray(new String[classpathList.size()]);
  }
  @Override
  protected TreeViewer createTreeViewer(Composite parent) {

    Tree tree = new Tree(parent, SWT.SINGLE);
    GridData gd = new GridData(GridData.FILL_BOTH);
    gd.heightHint = tree.getItemHeight() * 12;
    tree.setLayoutData(gd);

    final TreeViewer treeViewer = new OutlineTreeViewer(tree);
    lexicalSortingAction = new LexicalSortingAction(treeViewer);
    hideNonSharedAction = new HideNonSharedAction(treeViewer);

    outlineContentProvider = new ContentProvider();
    labelProvider =
        new CeylonOutlineLabelProvider() {
          Font getFont() {
            return getTreeViewer().getControl().getFont();
          }

          String getPrefix() {
            return getFilterText().getText();
          }
        };

    treeViewer.setLabelProvider(labelProvider);
    treeViewer.addFilter(new OutlineNamePatternFilter(getFilterText()));
    //    fSortByDefiningTypeAction= new SortByDefiningTypeAction(treeViewer);
    //    fShowOnlyMainTypeAction= new ShowOnlyMainTypeAction(treeViewer);
    treeViewer.setContentProvider(outlineContentProvider);
    outlineSorter = new OutlineSorter();
    treeViewer.setSorter(outlineSorter);
    treeViewer.setAutoExpandLevel(getDefaultLevel());
    tree.addKeyListener(new ChangeViewListener());
    tree.setFont(CeylonPlugin.getOutlineFont());
    return treeViewer;
  }
/**
 * A {@link DecoratedImageDescriptor} consists of a base image and several adornments. The
 * adornments are computed according to the flags either passed during creation or set via the
 * method {@link #setAdornments(int)}.
 *
 * <p>N.B. The JDT version of this code specially handles certain combinations of flags using a
 * "merged" decoration (e.g. synchronized + overrides) by checking for those first. We could
 * duplicate that functionality for each of the quadrants, if someone wanted us to. The
 * DecorationDescriptor and much of the logic is already prepared for that, but we'd just need to
 * change the behavior of the various drawXXX() methods.
 *
 * <p>For now, we assume the decorations in each quadrant are mutually exclusive.
 *
 * <p>This class may be instantiated; it is not intended to be subclassed.
 *
 * @since 0.1
 */
public class DecoratedImageDescriptor extends CompositeImageDescriptor {
  private ImageDescriptor fBaseImage;
  private int fFlags;
  private Point fSize;
  private final ImageRegistry imageRegistry = CeylonPlugin.imageRegistry();

  /**
   * Creates a new SourceEntityImageDescriptor.
   *
   * @param baseImage an image descriptor used as the base image
   * @param flags flags indicating which adornments are to be rendered. See {@link
   *     #setAdornments(int)} for valid values.
   * @param size the size of the resulting image
   */
  public DecoratedImageDescriptor(ImageDescriptor baseImage, int flags, Point size) {
    fBaseImage = baseImage;
    Assert.isNotNull(fBaseImage);
    fFlags = flags;
    Assert.isTrue(fFlags >= 0);
    fSize = size;
    Assert.isNotNull(fSize);
  }

  /**
   * Sets the descriptors adornments. Valid values are: {@link #ABSTRACT}, {@link #FINAL}, {@link
   * #SYNCHRONIZED}, {@link #STATIC}, {@link #RUNNABLE}, {@link #CEYLON_WARNING}, {@link
   * #CEYLON_ERROR}, {@link #OVERRIDES}, {@link #IMPLEMENTS}, {@link #CONSTRUCTOR}, {@link
   * #DEPRECATED}, {@link #VOLATILE}, {@link #TRANSIENT} or any combination of those.
   *
   * @param adornments the image descriptors adornments
   */
  public void setAdornments(int adornments) {
    Assert.isTrue(adornments >= 0);
    fFlags = adornments;
  }

  /**
   * Returns the current adornments.
   *
   * @return the current adornments
   */
  public int getAdornments() {
    return fFlags;
  }

  /**
   * Sets the size of the image created by calling {@link #createImage()}.
   *
   * @param size the size of the image returned from calling {@link #createImage()}
   */
  public void setImageSize(Point size) {
    Assert.isNotNull(size);
    Assert.isTrue(size.x >= 0 && size.y >= 0);
    fSize = size;
  }

  /**
   * Returns the size of the image created by calling {@link #createImage()}.
   *
   * @return the size of the image created by calling {@link #createImage()}
   */
  public Point getImageSize() {
    return new Point(fSize.x, fSize.y);
  }

  @Override
  protected Point getSize() {
    return fSize;
  }

  @Override
  public boolean equals(Object object) {
    if (object == null || !DecoratedImageDescriptor.class.equals(object.getClass())) return false;

    DecoratedImageDescriptor other = (DecoratedImageDescriptor) object;
    return fBaseImage.equals(other.fBaseImage)
        && fFlags == other.fFlags
        && fSize.equals(other.fSize);
  }

  @Override
  public int hashCode() {
    return fBaseImage.hashCode() | fFlags | fSize.hashCode();
  }

  @Override
  protected void drawCompositeImage(int width, int height) {
    ImageData bg = getImageData(fBaseImage);

    drawUnderlay();

    drawImage(bg, (width - bg.width) / 2, 0);

    drawTopLeft(); // conventionally not used
    drawTopRight();
    drawBottomRight();
    drawBottomLeft();
  }

  private ImageData getImageData(ImageDescriptor descriptor) {
    ImageData data = descriptor.getImageData(); // see bug 51965: getImageData can return null
    if (data == null) {
      data = DEFAULT_IMAGE_DATA;
      System.err.println("Image data not available: " + descriptor.toString()); // $NON-NLS-1$
    }
    return data;
  }

  private void addUnderlayImage(ImageDescriptor desc, Point pos) {
    ImageData data = getImageData(desc);
    int x = (pos.x - data.width) / 2;
    if (x >= 0) {
      drawImage(data, x, pos.y);
    }
  }

  private void addTopLeftImage(ImageDescriptor desc, Point pos) {
    ImageData data = getImageData(desc);
    drawImage(data, pos.x, pos.y);
  }

  private void addTopRightImage(ImageDescriptor desc, Point pos) {
    ImageData data = getImageData(desc);
    int x = pos.x - data.width;
    if (x >= 0) {
      drawImage(data, x, pos.y);
      pos.x = x;
    }
  }

  private void addBottomRightImage(ImageDescriptor desc, Point pos) {
    ImageData data = getImageData(desc);
    int x = pos.x - data.width;
    int y = pos.y - data.height;
    if (x >= 0 && y >= 0) {
      drawImage(data, x, y);
      pos.x = x;
    }
  }

  private void addBottomLeftImage(ImageDescriptor desc, Point pos) {
    ImageData data = getImageData(desc);
    int x = pos.x;
    int y = pos.y - data.height;
    if (x + data.width < getSize().x && y >= 0) {
      drawImage(data, x, y);
      pos.x = x + data.width;
    }
  }

  private void drawUnderlay() {
    Point pos = new Point(getSize().x, 0);
    for (DecorationDescriptor d : CeylonLabelProvider.DECORATIONS) {
      if (d.getQuadrant() == UNDERLAY && d.hasDecoration(fFlags)) {
        addUnderlayImage(imageRegistry.getDescriptor(d.getImageKey()), pos);
      }
    }
  }

  private void drawTopRight() {
    Point pos = new Point(getSize().x, 0);
    for (DecorationDescriptor d : CeylonLabelProvider.DECORATIONS) {
      if (d.getQuadrant() == TOP_RIGHT && d.hasDecoration(fFlags)) {
        addTopRightImage(imageRegistry.getDescriptor(d.getImageKey()), pos);
      }
    }
  }

  private void drawTopLeft() {
    Point pos = new Point(0, 0);
    for (DecorationDescriptor d : CeylonLabelProvider.DECORATIONS) {
      if (d.getQuadrant() == TOP_LEFT && d.hasDecoration(fFlags)) {
        addTopLeftImage(imageRegistry.getDescriptor(d.getImageKey()), pos);
      }
    }
  }

  private void drawBottomRight() {
    Point size = getSize();
    Point pos = new Point(size.x, size.y);

    // Were we to support "merged" decorators, we'd need to do something like the following instead:
    //
    //      int flags= fFlags;
    //      for(DecorationDescriptor d: fController.getBottomRightDecorations()) {
    //          if ((flags & d.mask) != 0) {
    //              addBottomRightImage(d.getImageDescriptor(), pos);
    //          }
    //          flags &= ~d.mask;
    //      }

    for (DecorationDescriptor d : CeylonLabelProvider.DECORATIONS) {
      if (d.getQuadrant() == BOTTOM_RIGHT && d.hasDecoration(fFlags)) {
        addBottomRightImage(imageRegistry.getDescriptor(d.getImageKey()), pos);
      }
    }
  }

  private void drawBottomLeft() {
    Point pos = new Point(0, getSize().y);
    for (DecorationDescriptor d : CeylonLabelProvider.DECORATIONS) {
      if (d.getQuadrant() == BOTTOM_LEFT && d.hasDecoration(fFlags)) {
        addBottomLeftImage(imageRegistry.getDescriptor(d.getImageKey()), pos);
      }
    }
  }
}
/**
 * Styled Label Provider which can be used to provide labels for Ceylon elements.
 *
 * <p>Extends StyledCellLabelProvider to provide custom styling by doing its own painting - here the
 * {@link #update(ViewerCell)} method is the entry point Implements
 * DelegatingStyledCellLabelProvider.IStyledLabelProvider too, but this probably is not required.
 *
 * @author max
 */
public class CeylonLabelProvider extends StyledCellLabelProvider
    implements DelegatingStyledCellLabelProvider.IStyledLabelProvider,
        ILabelProvider,
        ICeylonResources {

  private static CeylonLabelDecorator DECORATOR = new CeylonLabelDecorator();

  private Set<ILabelProviderListener> fListeners = new HashSet<ILabelProviderListener>();

  public static ImageRegistry imageRegistry = CeylonPlugin.getInstance().getImageRegistry();

  public static Image FILE_IMAGE = imageRegistry.get(CEYLON_FILE);
  private static Image FILE_WITH_WARNING_IMAGE = imageRegistry.get(CEYLON_FILE_WARNING);
  private static Image FILE_WITH_ERROR_IMAGE = imageRegistry.get(CEYLON_FILE_ERROR);

  public static Image CLASS = imageRegistry.get(CEYLON_CLASS);
  public static Image INTERFACE = imageRegistry.get(CEYLON_INTERFACE);
  public static Image LOCAL_CLASS = imageRegistry.get(CEYLON_LOCAL_CLASS);
  private static Image LOCAL_INTERFACE = imageRegistry.get(CEYLON_LOCAL_INTERFACE);
  public static Image METHOD = imageRegistry.get(CEYLON_METHOD);
  public static Image ATTRIBUTE = imageRegistry.get(CEYLON_ATTRIBUTE);
  public static Image LOCAL_METHOD = imageRegistry.get(CEYLON_LOCAL_METHOD);
  public static Image LOCAL_ATTRIBUTE = imageRegistry.get(CEYLON_LOCAL_ATTRIBUTE);
  public static Image PARAMETER = imageRegistry.get(CEYLON_PARAMETER);
  public static Image PACKAGE = imageRegistry.get(CEYLON_PACKAGE);
  public static Image ARCHIVE = imageRegistry.get(CEYLON_ARCHIVE);
  public static Image IMPORT = imageRegistry.get(CEYLON_IMPORT);
  private static Image IMPORT_LIST = imageRegistry.get(CEYLON_IMPORT_LIST);
  public static Image PROJECT = imageRegistry.get(CEYLON_PROJECT);
  public static Image CORRECTION = imageRegistry.get(CEYLON_CORRECTION);
  public static Image CHANGE = imageRegistry.get(CEYLON_CHANGE);
  public static Image COMPOSITE_CHANGE = imageRegistry.get(CEYLON_COMPOSITE_CHANGE);
  public static Image RENAME = imageRegistry.get(CEYLON_RENAME);
  public static Image MOVE = imageRegistry.get(CEYLON_MOVE);
  public static Image ADD = imageRegistry.get(CEYLON_ADD);

  private static ColorRegistry colorRegistry =
      PlatformUI.getWorkbench().getThemeManager().getCurrentTheme().getColorRegistry();

  public static final Styler ID_STYLER =
      new Styler() {
        @Override
        public void applyStyles(TextStyle textStyle) {
          textStyle.foreground = color(colorRegistry, IDENTIFIERS);
        }
      };

  public static final Styler TYPE_ID_STYLER =
      new Styler() {
        @Override
        public void applyStyles(TextStyle textStyle) {
          textStyle.foreground = color(colorRegistry, TYPES);
        }
      };

  public static final Styler TYPE_STYLER =
      new Styler() {
        @Override
        public void applyStyles(TextStyle textStyle) {
          textStyle.foreground = color(colorRegistry, TYPES);
        }
      };

  public static final Styler KW_STYLER =
      new Styler() {
        @Override
        public void applyStyles(TextStyle textStyle) {
          textStyle.foreground = color(colorRegistry, KEYWORDS);
        }
      };

  public static final Styler ANN_STYLER =
      new Styler() {
        @Override
        public void applyStyles(TextStyle textStyle) {
          textStyle.foreground = color(colorRegistry, ANNOTATIONS);
        }
      };

  private final boolean includePackage;

  public CeylonLabelProvider() {
    this(true);
  }

  public CeylonLabelProvider(boolean includePackage) {
    this.includePackage = includePackage;
  }

  @Override
  public Image getImage(Object element) {
    return DECORATOR.decorateImage(getPlainImage(element), element);
  }

  private static Image getPlainImage(Object element) {
    if (element instanceof IFile) {
      return getImageForFile((IFile) element);
    }
    if (element instanceof IProject) {
      return PROJECT;
    }
    if (element instanceof IPath) {
      return getImageForPath((IPath) element);
    }
    if (element instanceof CeylonElement) {
      return getImageFor(((CeylonElement) element).getNode());
    }
    if (element instanceof Package) {
      return PACKAGE;
    }
    if (element instanceof Module) {
      return ARCHIVE;
    }
    if (element instanceof Unit) {
      return FILE_IMAGE;
    }
    if (element instanceof CeylonOutlineNode) {
      return getImageFor((CeylonOutlineNode) element);
    }
    if (element instanceof Node) {
      return getImageFor((Node) element);
    }
    return FILE_IMAGE;
  }

  private static Image getImageForPath(IPath element) {
    return FILE_IMAGE;
  }

  private static Image getImageForFile(IFile file) {
    int sev = getMaxProblemMarkerSeverity(file, IResource.DEPTH_ONE);
    switch (sev) {
      case IMarker.SEVERITY_ERROR:
        return FILE_WITH_ERROR_IMAGE;
      case IMarker.SEVERITY_WARNING:
        return FILE_WITH_WARNING_IMAGE;
      default:
        return FILE_IMAGE;
    }
  }

  private static Image getImageFor(CeylonOutlineNode n) {
    return getImageFor((Node) n.getTreeNode());
  }

  private static Image getImageFor(Node n) {
    if (n instanceof PackageNode) {
      return PACKAGE;
    } else if (n instanceof Tree.CompilationUnit) {
      return FILE_IMAGE;
    } else if (n instanceof Tree.ImportList) {
      return IMPORT_LIST;
    } else if (n instanceof Tree.Import) {
      return IMPORT;
    } else if (n instanceof Tree.Declaration) {
      Tree.Declaration d = (Tree.Declaration) n;
      boolean shared = Util.hasAnnotation(d.getAnnotationList(), "shared");
      return getImage(n, shared);
    } else {
      return null;
    }
  }

  private static Image getImage(Node n, boolean shared) {
    if (n instanceof Tree.AnyClass) {
      if (shared) {
        return CLASS;
      } else {
        return LOCAL_CLASS;
      }
    } else if (n instanceof Tree.AnyInterface) {
      if (shared) {
        return INTERFACE;
      } else {
        return LOCAL_INTERFACE;
      }
    } else if (n instanceof Tree.AnyMethod) {
      if (shared) {
        return METHOD;
      } else {
        return LOCAL_METHOD;
      }
    } else if (n instanceof Tree.Parameter) {
      return PARAMETER;
    } else {
      if (shared) {
        return ATTRIBUTE;
      } else {
        return LOCAL_ATTRIBUTE;
      }
    }
  }

  public static Image getImage(Declaration d) {
    if (d == null) return null;
    return DECORATOR.decorateImage(getPlainImage(d), d);
  }

  private static Image getPlainImage(Declaration d) {
    boolean shared = d.isShared();
    if (d instanceof Class) {
      if (shared) {
        return CLASS;
      } else {
        return LOCAL_CLASS;
      }
    } else if (d instanceof Interface) {
      if (shared) {
        return INTERFACE;
      } else {
        return LOCAL_INTERFACE;
      }
    } else if (d instanceof Method) {
      if (shared) {
        return METHOD;
      } else {
        return LOCAL_METHOD;
      }
    } else if (d instanceof Parameter) {
      return PARAMETER;
    } else {
      if (shared) {
        return ATTRIBUTE;
      } else {
        return LOCAL_ATTRIBUTE;
      }
    }
  }

  @Override
  public StyledString getStyledText(Object element) {
    if (element instanceof CeylonOutlineNode) {
      return getStyledLabelFor((Node) ((CeylonOutlineNode) element).getTreeNode());
    } else if (element instanceof IFile) {
      return new StyledString(getLabelForFile((IFile) element));
    } else if (element instanceof IProject) {
      return new StyledString(((IProject) element).getName());
    } else if (element instanceof CeylonElement) {
      CeylonElement ce = (CeylonElement) element;
      String pkg;
      if (includePackage()) {
        pkg = " - " + getPackageLabel(ce.getNode());
      } else {
        pkg = "";
      }
      IFile file = ce.getFile();
      String path = file == null ? ce.getVirtualFile().getPath() : file.getFullPath().toString();
      return getStyledLabelFor(ce.getNode())
          .append(pkg, QUALIFIER_STYLER)
          .append(" - " + path, COUNTER_STYLER)
          .append(":" + ce.getLocation(), COUNTER_STYLER);
    } else if (element instanceof Package) {
      return new StyledString(getLabel((Package) element), QUALIFIER_STYLER);
    } else if (element instanceof Module) {
      return new StyledString(getLabel((Module) element));
    } else if (element instanceof Unit) {
      return new StyledString(((Unit) element).getFilename());
    } else {
      return getStyledLabelFor((Node) element);
    }
  }

  public String getText(Object element) {
    return getStyledText(element).toString();
  }

  protected boolean includePackage() {
    return includePackage;
  }

  private String getLabelForFile(IFile file) {
    return file.getName();
  }

  static StyledString getStyledLabelFor(Node n) {
    // TODO: it would be much better to render types
    //      from the tree nodes instead of from the
    //      model nodes

    if (n instanceof Tree.TypeParameterDeclaration) {
      Tree.TypeParameterDeclaration ac = (Tree.TypeParameterDeclaration) n;
      return new StyledString(name(ac.getIdentifier()));
    }
    if (n instanceof Tree.AnyClass) {
      Tree.AnyClass ac = (Tree.AnyClass) n;
      StyledString label = new StyledString("class ", KW_STYLER);
      label.append(name(ac.getIdentifier()), TYPE_ID_STYLER);
      parameters(ac.getTypeParameterList(), label);
      parameters(ac.getParameterList(), label);
      return label;
    } else if (n instanceof Tree.AnyInterface) {
      Tree.AnyInterface ai = (Tree.AnyInterface) n;
      StyledString label = new StyledString("interface ", KW_STYLER);
      label.append(name(ai.getIdentifier()), TYPE_ID_STYLER);
      parameters(ai.getTypeParameterList(), label);
      return label;
    } else if (n instanceof Tree.ObjectDefinition) {
      Tree.ObjectDefinition ai = (Tree.ObjectDefinition) n;
      return new StyledString("object ", KW_STYLER).append(name(ai.getIdentifier()), ID_STYLER);
    } else if (n instanceof Tree.AttributeSetterDefinition) {
      Tree.AttributeSetterDefinition ai = (Tree.AttributeSetterDefinition) n;
      return new StyledString("assign ", KW_STYLER).append(name(ai.getIdentifier()), ID_STYLER);
    } else if (n instanceof Tree.TypedDeclaration) {
      Tree.TypedDeclaration td = (Tree.TypedDeclaration) n;
      String type;
      Styler styler;
      if (td.getType() instanceof Tree.VoidModifier) {
        type = "void";
        styler = KW_STYLER;
      } else {
        type = type(td.getType());
        styler = TYPE_STYLER;
      }
      StyledString label = new StyledString(type, styler);
      label.append(" ").append(name(td.getIdentifier()), ID_STYLER);
      if (n instanceof Tree.AnyMethod) {
        Tree.AnyMethod am = (Tree.AnyMethod) n;
        parameters(am.getTypeParameterList(), label);
        for (Tree.ParameterList pl : am.getParameterLists()) {
          parameters(pl, label);
        }
      }
      return label;
    } else if (n instanceof Tree.CompilationUnit) {
      Tree.CompilationUnit ai = (Tree.CompilationUnit) n;
      return new StyledString(ai.getUnit().getFilename());
    } else if (n instanceof Tree.ImportList) {
      return new StyledString("imports");
    } else if (n instanceof Tree.Import) {
      Tree.Import ai = (Tree.Import) n;
      if (ai.getImportPath() != null && !ai.getImportPath().getIdentifiers().isEmpty()) {
        return new StyledString(toPath(ai), QUALIFIER_STYLER);
      }
    } else if (n instanceof PackageNode) {
      PackageNode pn = (PackageNode) n;
      if (pn.getPackageName().isEmpty()) {
        return new StyledString("default package");
      } else {
        return new StyledString(pn.getPackageName(), QUALIFIER_STYLER);
      }
    }

    return new StyledString("<something>");
  }

  private static String toPath(Tree.Import ai) {
    String path = "";
    for (Tree.Identifier id : ai.getImportPath().getIdentifiers()) {
      path += "." + id.getText();
    }
    path = path.substring(1);
    return path;
  }

  public static String getLabelFor(Node n) {
    return getStyledLabelFor(n).toString();
  }

  private static String type(Tree.Type type) {
    if (type == null) {
      return "<Unknown>";
    } else {
      ProducedType tm = type.getTypeModel();
      if (tm == null) {
        return "<Unknown>";
      } else {
        boolean sequenced = type instanceof Tree.SequencedType;
        if (sequenced) {
          tm = type.getUnit().getIteratedType(tm);
          if (tm == null) {
            return "<Unknown>";
          }
        }
        String tn = tm.getProducedTypeName();
        if (sequenced) {
          tn += "...";
        }
        return tn;
      }
    }
  }

  private static String name(Tree.Identifier id) {
    if (id == null) {
      return "<unknown>";
    } else {
      return id.getText();
    }
  }

  private static void parameters(Tree.ParameterList pl, StyledString label) {
    if (pl == null || pl.getParameters().isEmpty()) {
      label.append("()");
    } else {
      label.append("(");
      int len = pl.getParameters().size(), i = 0;
      for (Tree.Parameter p : pl.getParameters()) {
        if (p != null) {
          label
              .append(type(p.getType()), TYPE_STYLER)
              .append(" ")
              .append(name(p.getIdentifier()), ID_STYLER);
          if (p instanceof Tree.FunctionalParameterDeclaration) {
            Tree.FunctionalParameterDeclaration fp = (Tree.FunctionalParameterDeclaration) p;
            for (Tree.ParameterList ipl : fp.getParameterLists()) {
              parameters(ipl, label);
            }
          }
        }
        if (++i < len) label.append(", ");
      }
      label.append(")");
    }
  }

  private static void parameters(Tree.TypeParameterList tpl, StyledString label) {
    if (tpl != null && !tpl.getTypeParameterDeclarations().isEmpty()) {
      label.append("<");
      int len = tpl.getTypeParameterDeclarations().size(), i = 0;
      for (Tree.TypeParameterDeclaration p : tpl.getTypeParameterDeclarations()) {
        label.append(name(p.getIdentifier()), TYPE_STYLER);
        if (++i < len) label.append(", ");
      }
      label.append(">");
    }
  }

  public void addListener(ILabelProviderListener listener) {
    fListeners.add(listener);
  }

  public void dispose() {}

  public boolean isLabelProperty(Object element, String property) {
    return false;
  }

  public void removeListener(ILabelProviderListener listener) {
    fListeners.remove(listener);
  }

  public static String getLabel(Package packageModel) {
    String name = packageModel.getQualifiedNameString();
    if (name.isEmpty()) name = "default package";
    return name;
  }

  public static String getLabel(Module moduleModel) {
    String name = moduleModel.getNameAsString();
    if (name.isEmpty()) name = "default module";
    return name;
  }

  public static String getPackageLabel(Node decl) {
    return decl.getUnit() == null ? "unknown package" : getLabel(decl.getUnit().getPackage());
  }

  public static String getModuleLabel(Node decl) {
    return decl.getUnit() == null
        ? "unknown module"
        : getLabel(decl.getUnit().getPackage().getModule());
  }

  public static String getModuleLabel(Declaration decl) {
    return decl.getUnit() == null
        ? "unknown module"
        : getLabel(decl.getUnit().getPackage().getModule());
  }

  public static String getPackageLabel(Declaration decl) {
    return getLabel(decl.getUnit().getPackage());
  }

  @Override
  public void update(ViewerCell cell) {
    Object element = cell.getElement();
    StyledString styledText = getStyledText(element);
    cell.setText(styledText.toString());
    cell.setStyleRanges(styledText.getStyleRanges());
    cell.setImage(getImage(element));
    super.update(cell);
  }

  /**
   * Returns the maximum problem marker severity for the given resource, and, if depth is
   * IResource.DEPTH_INFINITE, its children. The return value will be one of IMarker.SEVERITY_ERROR,
   * IMarker.SEVERITY_WARNING, IMarker.SEVERITY_INFO or 0, indicating that no problem markers exist
   * on the given resource.
   *
   * @param depth TODO
   */
  public static int getMaxProblemMarkerSeverity(IResource res, int depth) {
    if (res == null || !res.isAccessible()) return 0;

    boolean hasWarnings = false; // if resource has errors, will return error image immediately
    IMarker[] markers = null;

    try {
      markers = res.findMarkers(IMarker.PROBLEM, true, depth);
    } catch (CoreException e) {
      e.printStackTrace();
    }
    if (markers == null) return 0; // don't know - say no errors/warnings/infos

    for (int i = 0; i < markers.length; i++) {
      IMarker m = markers[i];
      int priority = m.getAttribute(IMarker.SEVERITY, -1);

      if (priority == IMarker.SEVERITY_WARNING) {
        hasWarnings = true;
      } else if (priority == IMarker.SEVERITY_ERROR) {
        return IMarker.SEVERITY_ERROR;
      }
    }
    return hasWarnings ? IMarker.SEVERITY_WARNING : 0;
  }
}
  void addControls(final Composite parent) {
    Label desc = new Label(parent, SWT.LEFT | SWT.WRAP);
    desc.setText("The Ceylon builder compiles Ceylon source contained in the project.");

    enableBuilderButton = new Button(parent, SWT.PUSH);
    enableBuilderButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));
    enableBuilderButton.setText("Enable Ceylon Builder");
    enableBuilderButton.setEnabled(!builderEnabled && getSelectedProject().isOpen());
    enableBuilderButton.setImage(
        CeylonPlugin.getInstance().getImageRegistry().get(CeylonResources.ELE32));
    // enableBuilder.setSize(40, 40);

    Label sep = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL);
    GridData sgd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
    sep.setLayoutData(sgd);

    Composite composite = new Composite(parent, SWT.NONE);
    GridData gdb = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
    gdb.grabExcessHorizontalSpace = true;
    composite.setLayoutData(gdb);
    GridLayout layoutb = new GridLayout();
    layoutb.numColumns = 1;
    layoutb.marginBottom = 1;
    composite.setLayout(layoutb);

    addCharacterEncodingLabel(composite);

    offlineButton = new Button(composite, SWT.CHECK);
    offlineButton.setText("Work offline (disable connection to remote module repositories)");
    offlineButton.setEnabled(builderEnabled);
    offlineButton.setSelection(offlineOption != null && offlineOption);
    offlineButton.addListener(
        SWT.Selection,
        new Listener() {
          public void handleEvent(Event e) {
            if (offlineOption == null) {
              offlineOption = true;
            } else {
              offlineOption = !offlineOption;
            }
          }
        });

    final Group platformGroup = new Group(parent, SWT.NONE);
    platformGroup.setText("Target virtual machine");
    GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
    gd.grabExcessHorizontalSpace = true;
    platformGroup.setLayoutData(gd);
    GridLayout layout = new GridLayout();

    layout.numColumns = 1;
    layout.marginBottom = 1;
    platformGroup.setLayout(layout);

    compileToJava = new Button(platformGroup, SWT.CHECK);
    compileToJava.setText("Compile project for JVM");
    compileToJava.setSelection(backendJava);
    compileToJava.setEnabled(builderEnabled);

    compileToJs = new Button(platformGroup, SWT.CHECK);
    compileToJs.setText("Compile project to JavaScript");
    compileToJs.setSelection(backendJs);
    compileToJs.setEnabled(builderEnabled);

    Group troubleGroup = new Group(parent, SWT.NONE);
    troubleGroup.setText("Troubleshooting");
    troubleGroup.setLayout(new GridLayout(1, false));
    GridData gd3 = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
    gd3.grabExcessHorizontalSpace = true;
    troubleGroup.setLayoutData(gd3);

    astAwareIncrementalBuidsButton = new Button(troubleGroup, SWT.CHECK);
    astAwareIncrementalBuidsButton.setText("Disable structure-aware incremental compilation");
    astAwareIncrementalBuidsButton.setSelection(!astAwareIncrementalBuids);
    astAwareIncrementalBuidsButton.setEnabled(builderEnabled);

    final Button logButton = new Button(troubleGroup, SWT.CHECK);
    logButton.setText("Log compiler activity to Eclipse console");
    boolean loggingEnabled = verbose != null && !verbose.isEmpty();
    logButton.setSelection(loggingEnabled);
    logButton.setEnabled(builderEnabled);

    final Composite verbosityOptions = new Composite(troubleGroup, SWT.NONE);
    verbosityOptions.setLayout(new GridLayout(2, false));
    final GridData gd4 = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
    gd4.grabExcessHorizontalSpace = true;
    verbosityOptions.setLayoutData(gd4);
    gd4.exclude = !loggingEnabled;
    verbosityOptions.setVisible(loggingEnabled);
    verbosityOptions.setEnabled(loggingEnabled);

    final Label verbosityLabel = new Label(verbosityOptions, SWT.NONE);
    verbosityLabel.setText("Verbosity level");

    verboseText = new Combo(verbosityOptions, SWT.DROP_DOWN);
    verboseText.add("code");
    verboseText.add("ast");
    verboseText.add("loader");
    verboseText.add("cmr");
    verboseText.add("all");
    GridData vgd = new GridData();
    vgd.grabExcessHorizontalSpace = true;
    vgd.minimumWidth = 75;
    verboseText.setLayoutData(vgd);
    verboseText.setTextLimit(20);
    if (loggingEnabled) {
      verboseText.setText(verbose);
    }
    verboseText.addModifyListener(
        new ModifyListener() {
          @Override
          public void modifyText(ModifyEvent e) {
            String str = verboseText.getText();
            if (str == null || str.isEmpty()) {
              verbose = null;
            } else {
              verbose = str.trim();
            }
          }
        });

    logButton.addSelectionListener(
        new SelectionAdapter() {
          @Override
          public void widgetSelected(SelectionEvent e) {
            boolean selected = logButton.getSelection();
            verbose = selected ? verboseText.getText() : null;
            verboseText.setEnabled(selected);
            ((GridData) verbosityOptions.getLayoutData()).exclude = !selected;
            verbosityOptions.setVisible(selected);
            verbosityOptions.setEnabled(selected);
            verboseText.setVisible(selected);
            parent.layout();
          }
        });

    enableBuilderButton.addSelectionListener(
        new SelectionAdapter() {
          @Override
          public void widgetSelected(SelectionEvent e) {
            new CeylonNature().addToProject(getSelectedProject());
            enableBuilderButton.setEnabled(false);
            astAwareIncrementalBuidsButton.setEnabled(true);
            compileToJs.setEnabled(true);
            compileToJava.setEnabled(true);
            offlineButton.setEnabled(true);
            logButton.setEnabled(true);
            builderEnabled = true;
          }
        });

    astAwareIncrementalBuidsButton.addSelectionListener(
        new SelectionAdapter() {
          @Override
          public void widgetSelected(SelectionEvent e) {
            astAwareIncrementalBuids = !astAwareIncrementalBuids;
          }
        });

    compileToJava.addSelectionListener(
        new SelectionAdapter() {
          @Override
          public void widgetSelected(SelectionEvent e) {
            backendJava = !backendJava;
          }
        });

    compileToJs.addSelectionListener(
        new SelectionAdapter() {
          @Override
          public void widgetSelected(SelectionEvent e) {
            backendJs = !backendJs;
          }
        });

    Link buildPathsPageLink = new Link(parent, 0);
    buildPathsPageLink.setText("See '<a>Build Paths</a>' to configure project build paths.");
    buildPathsPageLink.addSelectionListener(
        new SelectionAdapter() {
          @Override
          public void widgetSelected(SelectionEvent e) {
            IWorkbenchPreferenceContainer container =
                (IWorkbenchPreferenceContainer) getContainer();
            container.openPage(CeylonBuildPathsPropertiesPage.ID, null);
          }
        });

    Link openRepoPageLink = new Link(parent, 0);
    openRepoPageLink.setText(
        "See '<a>Module Repositories</a>' to configure project module repositores.");
    openRepoPageLink.addSelectionListener(
        new SelectionAdapter() {
          @Override
          public void widgetSelected(SelectionEvent e) {
            IWorkbenchPreferenceContainer container =
                (IWorkbenchPreferenceContainer) getContainer();
            container.openPage(CeylonRepoPropertiesPage.ID, null);
          }
        });

    Link warningsPageLink = new Link(parent, 0);
    warningsPageLink.setText("See '<a>Warnings</a>' to enable or disable warnings.");
    warningsPageLink.addSelectionListener(
        new SelectionAdapter() {
          @Override
          public void widgetSelected(SelectionEvent e) {
            IWorkbenchPreferenceContainer container =
                (IWorkbenchPreferenceContainer) getContainer();
            container.openPage(CeylonWarningsPropertiesPage.ID, null);
          }
        });
  }
 public ExportModuleWizard() {
   setDialogSettings(CeylonPlugin.getInstance().getDialogSettings());
 }
 public static void persistDefaultRepositoryPath(String repositoryPath) {
   if (repositoryPath != null && !repositoryPath.isEmpty()) {
     CeylonPlugin.getInstance().getDialogSettings().put("repositoryPath", repositoryPath);
   }
 }