public ASTExplorer(Composite parent,int style) {
		super(parent,style);
		this.problems = new IProblem[0];
		this.blue = getDisplay().getSystemColor(SWT.COLOR_BLUE);
		this.red = getDisplay().getSystemColor(SWT.COLOR_RED);
			
		GridLayout gridLayout = new GridLayout();
		super.setLayout(gridLayout);
		
		Composite composite = new Composite(this,SWT.NONE);
		gridLayout = new GridLayout();
		gridLayout.numColumns = 3;
		composite.setLayout(gridLayout);
		composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		
		Button button = new Button(composite,SWT.PUSH);
		button.setText("File...");
		button.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
		
		button.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				Shell shell = ((Button)event.widget).getShell();  
				FileDialog dialog = new FileDialog(shell,SWT.PRIMARY_MODAL | SWT.OPEN);
				dialog.setText("Java Source File");
				dialog.setFilterExtensions(new String[] {"*.java"});
				String file = dialog.open(); 
				if (file == null) return; 
				addressControl.setText(file);
				go();
			}
		});
		
		this.addressControl = new Text(composite,SWT.BORDER); 
		this.addressControl.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
									
		button = new Button(composite,SWT.PUSH);
		button.setText("Go");
		button.getShell().setDefaultButton(button); 
		button.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
		button.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				go();
			}
		});
		
		SashForm sashFormVertical = new SashForm(this,SWT.VERTICAL);
		sashFormVertical.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL | 
				GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL));
		
		SashForm sashFormHorizontal = new SashForm(sashFormVertical,SWT.HORIZONTAL);
		sashFormHorizontal.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL | 
				GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL));
			
		this.treeControl = new Tree(sashFormHorizontal,SWT.BORDER | SWT.SINGLE);
		this.treeControl.setLayoutData(new GridData(GridData.GRAB_VERTICAL | GridData.VERTICAL_ALIGN_FILL));
		this.treeControl.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				// first reset any previous selections 
				StyleRange styleRange = new StyleRange();
				styleRange.start = 0;
				styleRange.length = textControl.getCharCount();
				textControl.setStyleRange(styleRange);
				
				// select text
				int startSelection = -1;
				Tree tree = (Tree) e.widget;
				Display display = tree.getDisplay(); 
				TreeItem[] items = tree.getSelection();
				for (int i=0; i < items.length; ++i) {
					ASTNode node = (ASTNode) items[i].getData(ASTExplorerVisitor.NODE);
					if (node != null) {
						styleRange = createRange(node.getStartPosition(),node.getLength(),blue);
						textControl.setStyleRange(styleRange);
						if (startSelection < 0 || styleRange.start < startSelection)
							startSelection = styleRange.start;
					}
				}
				if (startSelection >= 0)
					textControl.setSelection(startSelection);
				
				// select errors
				for (int i=0; i < problems.length; ++i) {
					IProblem problem = problems[i];
					String msg = problem.getMessage();
					styleRange = createRange(problem.getSourceStart(),
								problem.getSourceEnd() - problem.getSourceStart() + 1,red);
					textControl.setStyleRange(styleRange);
				}
			}
		});
			
		this.textControl = new StyledText(sashFormHorizontal, SWT.BORDER | SWT.READ_ONLY | SWT.H_SCROLL | SWT.V_SCROLL);
		this.textControl.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL
				| GridData.GRAB_VERTICAL | GridData.HORIZONTAL_ALIGN_FILL
				| GridData.VERTICAL_ALIGN_FILL));
		
		this.errorsTextControl = new StyledText(sashFormVertical, SWT.BORDER | SWT.READ_ONLY | SWT.H_SCROLL | SWT.V_SCROLL);
		this.errorsTextControl.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL));
		
		sashFormVertical.setWeights(new int[]{80, 20});
	}