From 5c2d0a056729f40011b67a58b334fea85510bb73 Mon Sep 17 00:00:00 2001
From: jsurfer  
+	 * This method is called when the delegating action has been triggered.
+	 * Implement this method to do the actual work.
+	 *  
+	 * Implementers can use this opportunity to change the availability of the
+	 * action or to modify other presentation properties.
+	 *  
+	 * This method is primarily used to determine if an editor input should 
+	 * appear in the "File Most Recently Used" menu.  An editor input will appear 
+	 * in the list until the return value of  
+	 * For instance, if the fully qualified input name is
+	 *  
+	 * A typical use for this method is registering the content provider as a listener
+	 * to changes on the new input (using model-specific means), and deregistering the viewer 
+	 * from the old input. In response to these change notifications, the content provider
+	 * propagates the changes to the viewer.
+	 *  
+	 * This method is called when the delegating action has been triggered.
+	 * Implement this method to do the actual work.
+	 *  
+	 * Implementers can use this opportunity to change the availability of the
+	 * action or to modify other presentation properties.
+	 *  
+	 *
+	 * @exception SWTException  
+	 *
+	 * @exception SWTException  
+	 *
+	 * @exception SWTException  
+	 * Clients should not call this method (the workbench calls this method at
+	 * appropriate times).
+	 *  
+	 * For implementors this is a multi-step process:
+	 * null if 
+	 *         the image could not be found
+	 */
+	private ImageDescriptor getImageDescriptor(String key) {
+		try {
+			URL url = getBundle().getEntry("/icons/" + key); //$NON-NLS-1$
+			return ImageDescriptor.createFromURL(url);
+		} catch (IllegalStateException e) {
+			return null;
+		}
+	}
+	
+	/**
+	 * Returns this plug-in's template store.
+	 * 
+	 * @return the template store of this plug-in instance
+	 */
+	public TemplateStore getTemplateStore() {
+		if (fStore == null) {
+			fStore= new ContributionTemplateStore(getContextTypeRegistry(), getDefault().getPreferenceStore(), CUSTOM_TEMPLATES_KEY);
+			try {
+				fStore.load();
+			} catch (IOException e) {
+				WebUI.getDefault().getLog().log(new Status(IStatus.ERROR, "net.sourceforge.phpeclipse.ui", IStatus.OK, "", e)); //$NON-NLS-1$ //$NON-NLS-2$
+			}
+		}
+		return fStore;
+	}
+
+	/**
+	 * Returns this plug-in's context type registry.
+	 * 
+	 * @return the context type registry for this plug-in instance
+	 */
+	public ContextTypeRegistry getContextTypeRegistry() {
+		if (fRegistry == null) {
+			// create an configure the contexts available in the editor
+			fRegistry= new ContributionContextTypeRegistry();
+			fRegistry.addContextType(XMLContextType.XML_CONTEXT_TYPE);
+			fRegistry.addContextType(HTMLContextType.HTML_CONTEXT_TYPE);
+			fRegistry.addContextType(JSContextType.JS_CONTEXT_TYPE);
+		}
+		return fRegistry;
+	}
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/editor/EditorMessages.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/editor/EditorMessages.java
new file mode 100644
index 0000000..28ae4ee
--- /dev/null
+++ b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/editor/EditorMessages.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://solareclipse.sourceforge.net/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ * 
+ * $Id: EditorMessages.java,v 1.1 2004-09-02 18:26:30 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.ui.editor;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * @author Igor Malinin
+ */
+public class EditorMessages {
+	private static ResourceBundle bundle = ResourceBundle
+		.getBundle("net.sourceforge.phpeclipse.ui.editor.EditorMessages"); //$NON-NLS-1$
+
+	private EditorMessages() {}
+
+	public static String getString( String key ) {
+		try {
+			return bundle.getString( key );
+		} catch ( MissingResourceException e ) {
+			return "!" + key + "!"; //$NON-NLS-1$ //$NON-NLS-2$
+		}
+	}
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/editor/EditorMessages.properties b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/editor/EditorMessages.properties
new file mode 100644
index 0000000..543c355
--- /dev/null
+++ b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/editor/EditorMessages.properties
@@ -0,0 +1,15 @@
+#
+# Copyright (c) 2004 Christopher Lenz and others.
+# All rights reserved. This program and the accompanying materials 
+# are made available under the terms of the Common Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/cpl-v10.html
+# 
+# Contributors:
+#     Christopher Lenz - initial english resources
+# 
+# $Id: EditorMessages.properties,v 1.1 2004-09-02 18:26:30 jsurfer Exp $
+#
+
+I18NDocumentProvider.task.saving=Saving
+I18NDocumentProvider.error.encoding=Declared encoding is not supported!
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/editor/I18NDocumentProvider.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/editor/I18NDocumentProvider.java
new file mode 100644
index 0000000..7aaf2ed
--- /dev/null
+++ b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/editor/I18NDocumentProvider.java
@@ -0,0 +1,286 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://solareclipse.sourceforge.net/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ * 
+ * $Id: I18NDocumentProvider.java,v 1.1 2004-09-02 18:26:30 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.ui.editor;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IStorageEditorInput;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.ContainerGenerator;
+import org.eclipse.ui.editors.text.FileDocumentProvider;
+import org.eclipse.ui.texteditor.ResourceMarkerAnnotationModel;
+
+/**
+ * @author Igor Malinin
+ */
+public class I18NDocumentProvider extends FileDocumentProvider {
+
+	private static final char BOM = 0xFEFF;
+
+	/*
+	 * @see org.eclipse.ui.editors.text.StorageDocumentProvider#setDocumentContent(IDocument,
+	 *      InputStream, String)
+	 */
+	protected void setDocumentContent(IDocument document,
+			InputStream contentStream, String encoding) throws CoreException {
+		Reader in = null;
+
+		try {
+			if (encoding == null) {
+				encoding = getDefaultEncoding();
+			}
+
+			in = new InputStreamReader(contentStream, encoding);
+
+			StringBuffer buffer = new StringBuffer();
+
+			char[] readBuffer = new char[2048];
+			int n = in.read(readBuffer);
+			while (n > 0) {
+				buffer.append(readBuffer, 0, n);
+				n = in.read(readBuffer);
+			}
+
+			if (buffer.length() > 0 && buffer.charAt(0) == BOM) {
+				buffer.deleteCharAt(0);
+			}
+
+			document.set(buffer.toString());
+		} catch (IOException x) {
+			String msg = x.getMessage();
+			if (msg == null) {
+				msg = ""; //$NON-NLS-1$
+			}
+
+			IStatus s = new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID,
+					IStatus.OK, msg, x);
+
+			throw new CoreException(s);
+		} finally {
+			if (in != null) try {
+				in.close();
+			} catch (IOException x) {
+			}
+		}
+	}
+
+	/*
+	 * @see org.eclipse.ui.texteditor.AbstractDocumentProvider#doSaveDocument(IProgressMonitor,
+	 *      Object, IDocument, boolean)
+	 */
+	protected void doSaveDocument(IProgressMonitor monitor, Object element,
+			IDocument document, boolean overwrite) throws CoreException {
+		if (!(element instanceof IFileEditorInput)) {
+			super.doSaveDocument(monitor, element, document, overwrite);
+			return;
+		}
+
+		IFileEditorInput input = (IFileEditorInput) element;
+
+		try {
+			String content = document.get();
+
+			String encoding = getDeclaredEncoding(new ByteArrayInputStream(
+					content.getBytes("ISO-8859-1")));
+
+			if (encoding == null) {
+				encoding = super.getEncoding(element);
+				if (encoding == null /* || !encoding.startsWith("UTF-16") */) {
+					encoding = getDefaultEncoding();
+				}
+			} else {
+				setEncoding(element, encoding);
+			}
+
+			if (encoding.startsWith("UTF-16")) {
+				content = BOM + content;
+			}
+
+			InputStream stream;
+			try {
+				stream = new ByteArrayInputStream(content.getBytes(encoding));
+			} catch (UnsupportedEncodingException e) {
+				IStatus s = new Status(
+						IStatus.ERROR,
+						PlatformUI.PLUGIN_ID,
+						IStatus.OK,
+						EditorMessages
+								.getString("I18NDocumentProvider.error.encoding"),
+						e);
+
+				throw new CoreException(s);
+			}
+
+			IFile file = input.getFile();
+			if (file.exists()) {
+				FileInfo info = (FileInfo) getElementInfo(element);
+
+				if (info != null && !overwrite) {
+					checkSynchronizationState(info.fModificationStamp, file);
+				}
+
+				// inform about the upcoming content change
+				fireElementStateChanging(element);
+
+				try {
+					file.setContents(stream, overwrite, true, monitor);
+				} catch (CoreException x) {
+					// inform about failure
+					fireElementStateChangeFailed(element);
+					throw x;
+				} catch (RuntimeException x) {
+					// inform about failure
+					fireElementStateChangeFailed(element);
+					throw x;
+				}
+
+				// If here, the editor state will be flipped to "not dirty".
+				// Thus, the state changing flag will be reset.
+
+				if (info != null) {
+					ResourceMarkerAnnotationModel model = (ResourceMarkerAnnotationModel) info.fModel;
+
+					model.updateMarkers(info.fDocument);
+
+					info.fModificationStamp = computeModificationStamp(file);
+				}
+			} else {
+				try {
+					monitor.beginTask(EditorMessages
+							.getString("I18NDocumentProvider.task.saving"), //$NON-NLS-1$
+							2000);
+
+					ContainerGenerator generator = new ContainerGenerator(file
+							.getParent().getFullPath());
+
+					generator.generateContainer(new SubProgressMonitor(monitor,
+							1000));
+
+					file.create(stream, false, new SubProgressMonitor(monitor,
+							1000));
+				} finally {
+					monitor.done();
+				}
+			}
+		} catch (IOException x) {
+			IStatus s = new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID,
+					IStatus.OK, x.getMessage(), x);
+
+			throw new CoreException(s);
+		}
+	}
+
+	/*
+	 * @see org.eclipse.ui.editors.text.IStorageDocumentProvider#getEncoding(Object)
+	 */
+	public String getEncoding(Object element) {
+		String encoding = super.getEncoding(element);
+		if (encoding != null) {
+			return encoding;
+		}
+
+		if (element instanceof IStorageEditorInput) {
+			IStorageEditorInput sei = (IStorageEditorInput) element;
+
+			try {
+				InputStream in = sei.getStorage().getContents();
+				try {
+					encoding = getDeclaredEncoding(in);
+				} finally {
+					in.close();
+				}
+			} catch (CoreException e) {
+			} catch (IOException e) {
+			}
+
+			if (encoding == null) {
+				encoding = getDefaultEncoding();
+			}
+
+			setEncoding(element, encoding);
+		}
+
+		return encoding;
+	}
+
+	/*
+	 * @see org.eclipse.ui.editors.text.IStorageDocumentProvider#setEncoding(Object,
+	 *      String)
+	 */
+	public void setEncoding(Object element, String encoding) {
+		if (encoding == null) {
+			encoding = getDefaultEncoding();
+		}
+
+		super.setEncoding(element, encoding);
+	}
+
+	/**
+	 * Tries to determine encoding from contents of the stream. Returns null
+	 * if encoding is unknown.
+	 */
+	public String getDeclaredEncoding(InputStream in) throws IOException {
+		return getBOMEncoding(in);
+	}
+
+	/**
+	 * Tries to determine encoding from the byte order mark. Returns null
+	 * if encoding is unknown.
+	 */
+	private String getBOMEncoding(InputStream in) throws IOException {
+		int first = in.read();
+		if (first < 0) {
+			return null;
+		}
+
+		int second = in.read();
+		if (second < 0) {
+			return null;
+		}
+
+		// look for the UTF-16 Byte Order Mark (BOM)
+		if (first == 0xFE && second == 0xFF) {
+			return "UTF-16BE";
+		}
+
+		if (first == 0xFF && second == 0xFE) {
+			return "UTF-16LE";
+		}
+
+		int third = in.read();
+		if (third < 0) {
+			return null;
+		}
+
+		// look for the UTF-8 BOM
+		if (first == 0xEF && second == 0xBB && third == 0xBF) {
+			return "UTF-8";
+		}
+
+		return null;
+	}
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/editor/StructuredTextEditor.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/editor/StructuredTextEditor.java
new file mode 100644
index 0000000..c09a5be
--- /dev/null
+++ b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/editor/StructuredTextEditor.java
@@ -0,0 +1,297 @@
+/*
+ * Copyright (c) 2004 Christopher Lenz and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Christopher Lenz - initial API and implementation
+ * 
+ * $Id: StructuredTextEditor.java,v 1.1 2004-09-02 18:26:30 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.ui.editor;
+
+import net.sourceforge.phpeclipse.core.model.ISourceModel;
+import net.sourceforge.phpeclipse.core.model.ISourceReference;
+import net.sourceforge.phpeclipse.ui.text.IReconcilingParticipant;
+import net.sourceforge.phpeclipse.ui.views.outline.ModelBasedOutlinePage;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.editors.text.TextEditor;
+import org.eclipse.ui.texteditor.IUpdate;
+import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
+
+/**
+ * Abstract base class for editors that keep a source model synchronized with
+ * the textual contants being edited.
+ */
+public abstract class StructuredTextEditor extends TextEditor
+	implements IReconcilingParticipant {
+
+	// Inner Classes -----------------------------------------------------------
+
+    /**
+     * Listens to changes to the selection in the outline page, and changes the
+     * selection and highlight range in the editor accordingly.
+     */
+    private class OutlineSelectionChangedListener
+        implements ISelectionChangedListener {
+
+        /*
+         * @see ISelectionChangedListener#selectionChanged(SelectionChangedEvent)
+         */
+        public void selectionChanged(SelectionChangedEvent event) {
+            IStructuredSelection selection =
+                (IStructuredSelection) event.getSelection();
+            if (selection.isEmpty()) {
+                resetHighlightRange();
+            } else {
+                ISourceReference element = (ISourceReference)
+					selection.getFirstElement();
+                highlightElement(element, true);
+            }
+        }
+
+    }
+
+	// Instance Variables ------------------------------------------------------
+
+	/**
+	 * The associated outline page.
+	 */
+	private IContentOutlinePage outlinePage;
+
+	/**
+	 * Listens to changes in the outline page's selection to update the editor
+	 * selection and highlight range.
+	 */
+	private ISelectionChangedListener outlinePageSelectionListener;
+
+	// TextEditor Implementation -----------------------------------------------
+
+	/*
+	 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
+	 */
+	public Object getAdapter(Class adapter) {
+		if (adapter.equals(IContentOutlinePage.class)) {
+			if (outlinePage == null) {
+				outlinePage = createOutlinePage();
+                outlinePageSelectionListener =
+                    new OutlineSelectionChangedListener();
+                outlinePage.addSelectionChangedListener(
+                outlinePageSelectionListener);
+			}
+			return outlinePage;
+		}
+		return super.getAdapter(adapter);
+	}
+
+	/*
+	 * @see org.eclipse.ui.texteditor.AbstractTextEditor#handleCursorPositionChanged()
+	 */
+	protected void handleCursorPositionChanged() {
+		super.handleCursorPositionChanged();
+		highlightElement(computeHighlightRangeSourceReference(), false);
+		synchronizeOutlinePageSelection();
+	}
+
+	// IReconcilingParticipant Implementation ----------------------------------
+
+	/* 
+	 * @see IReconcilingParticipant#reconciled()
+	 */
+	public void reconciled() {
+		Shell shell = getSite().getShell();
+		if ((shell != null) && !shell.isDisposed()) {
+			shell.getDisplay().asyncExec(new Runnable() {
+				public void run() {
+					if (outlinePage instanceof IUpdate) {
+						((IUpdate) outlinePage).update();
+					}
+					synchronizeOutlinePageSelection();
+				}
+			});
+		}
+	}
+
+	// Public Methods ----------------------------------------------------------
+
+	/**
+	 * Computes and returns the source reference that includes the caret and
+	 * serves as provider for the outline page selection and the editor range
+	 * indication.
+	 * 
+	 * @return the computed source reference
+	 */
+	public ISourceReference computeHighlightRangeSourceReference() {
+		ISourceViewer sourceViewer = getSourceViewer();
+		if (sourceViewer == null) {
+			return null;
+		}
+		StyledText styledText = sourceViewer.getTextWidget();
+		if ((styledText == null) || styledText.isDisposed()) {
+			return null;
+		}
+		int offset = sourceViewer.getVisibleRegion().getOffset();
+		int caret = offset + styledText.getCaretOffset();
+
+		return getElementAt(caret);
+	}
+
+	/**
+	 * Returns the source model element at the specified offset.
+	 * 
+	 * @param offset the offset into the document
+	 * @return the element at the given offset, or null if no model is
+	 *         available or there is no element at the offset
+	 */
+	public ISourceReference getElementAt(int offset) {
+		ISourceReference retVal = null;
+		ISourceModel model = getSourceModel();
+		if (model != null) {
+			ISourceReference elements[] = model.getElements();
+			retVal = getElementAt(model, elements, offset);
+		}
+		return retVal;
+	}
+
+	/**
+	 * Returns the structure source model corresponding to the document
+	 * currently being edited.
+	 * 
+	 * Concrete implementations must implement this method to return the model
+	 * appropriate to the content being edited.
+	 * 
+	 * @return the source model
+	 */
+	public abstract ISourceModel getSourceModel();
+
+	/**
+	 * Informs the editor that its outliner has been closed.
+	 * 
+	 * TODO There must be a more elegant way to get notified when the outline 
+	 *      page was closed. Otherwise move this method into an interface
+	 */
+	public void outlinePageClosed() {
+		if (outlinePage != null) {
+			outlinePage.removeSelectionChangedListener(
+					outlinePageSelectionListener);
+			outlinePage = null;
+			resetHighlightRange();
+		}
+	}
+
+	/**
+	 * Synchronizes the outliner selection with the given element position in 
+	 * the editor.
+	 * 
+	 * @param element the java element to select
+	 */
+	public void synchronizeOutlinePage(ISourceReference element) {
+		if (outlinePage != null) {
+			outlinePage.removeSelectionChangedListener(
+				outlinePageSelectionListener);
+			if (outlinePage instanceof ModelBasedOutlinePage) {
+				((ModelBasedOutlinePage) outlinePage).select(element);
+			}
+			outlinePage.addSelectionChangedListener(
+				outlinePageSelectionListener);
+		}
+	}
+
+	/**
+	 * Synchronizes the outliner selection with the currently highlighted source
+	 * reference.
+	 */
+	public void synchronizeOutlinePage() {
+		ISourceReference element = computeHighlightRangeSourceReference();
+		synchronizeOutlinePage(element);
+	}
+
+	// Protected Methods -------------------------------------------------------
+
+	protected abstract IContentOutlinePage createOutlinePage();
+
+	/**
+	 * Highlights the given element.
+	 * 
+	 * @param element the element that should be highlighted
+	 * @param moveCursor whether the cursor should be moved to the element
+	 */
+	protected final void highlightElement(ISourceReference element,
+			boolean moveCursor) {
+		if (element != null) {
+			IRegion highlightRegion = element.getSourceRegion();
+			setHighlightRange(highlightRegion.getOffset(),
+				highlightRegion.getLength(), moveCursor);
+		} else {
+			resetHighlightRange();
+		}
+	}
+
+	/**
+	 * Returns whether the outline page is currently linked with the editor,
+	 * meaning that its selection should automatically be updated to reflect the
+	 * current cursor position.
+	 * 
+	 * @return true if the outline page is linked with the editor,
+	 *         false otherwise
+	 */
+	protected abstract boolean isOutlineLinkedWithEditor();
+
+	// Private Methods ---------------------------------------------------------
+
+	/**
+	 * Recursively searches the specified list of elements managed by the given
+	 * model for the element that covers the specified offfset with minimal 
+	 * padding.
+	 * 
+	 * @param model the source model
+	 * @param elements the current list of elements
+	 * @param offset the offset into the document
+	 * @return the model element at the specified offset, or null if
+	 *         no element could be found
+	 */
+	private static ISourceReference getElementAt(
+			ISourceModel model, ISourceReference elements[], int offset) {
+		ISourceReference retVal = null;
+		for (int i = 0; i < elements.length; i++) {
+			ISourceReference element = elements[i];
+			IRegion region = element.getSourceRegion();
+			if ((offset > region.getOffset())
+			 && (offset < (region.getOffset() + region.getLength()))) {
+				ISourceReference[] children = model.getChildren(element);
+				if (children.length > 0) {
+					retVal = getElementAt(model, children, offset);
+					if (retVal != null) {
+						break;
+					}
+				}
+				if (retVal == null) {
+					retVal = element;
+				}
+			}
+		}
+		return retVal;
+	}
+
+	private void synchronizeOutlinePageSelection() {
+		IPreferenceStore store = getPreferenceStore();
+		if (store != null) {
+			boolean linkWithEditor = isOutlineLinkedWithEditor();
+			if (linkWithEditor) {
+				synchronizeOutlinePage(computeHighlightRangeSourceReference());
+			}
+		}
+	}
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/internal/WebUIMessages.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/internal/WebUIMessages.java
new file mode 100644
index 0000000..885d41b
--- /dev/null
+++ b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/internal/WebUIMessages.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2003-2004 Christopher Lenz and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Christopher Lenz - initial API and implementation
+ * 
+ * $Id: WebUIMessages.java,v 1.1 2004-09-02 18:26:29 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.ui.internal;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * Utility class that provides easy access to externalized strings.
+ */
+public final class WebUIMessages {
+
+	// Constants ---------------------------------------------------------------
+
+	/**
+	 * Qualified name of the resource bundle containing the localized messages.
+	 */
+	private static final String RESOURCE_BUNDLE =
+		"net.sourceforge.phpeclipse.ui.internal.WebUIMessages"; //$NON-NLS-1$
+
+	// Class Variables ---------------------------------------------------------
+
+	/**
+	 * The resource bundle.
+	 */
+	private static ResourceBundle resourceBundle =
+		ResourceBundle.getBundle(RESOURCE_BUNDLE);
+
+	// Constructors ------------------------------------------------------------
+
+	/**
+	 * Hidden constructor.
+	 */
+	private WebUIMessages() {
+		// Hidden
+	}
+
+	// Public Methods ----------------------------------------------------------
+
+	/**
+	 * Returns the resource bundle.
+	 * 
+	 * @return the resource bundle
+	 */
+	public static ResourceBundle getResourceBundle() {
+		return resourceBundle;
+	}
+
+	/**
+	 * Returns the message identified by the specified key.
+	 * 
+	 * @param key the message key
+	 * @return the localized message, or the key enclosed by exclamation marks
+	 *         if no message was found for the key
+	 */
+	public static String getString(String key) {
+		try {
+			return resourceBundle.getString(key);
+		} catch (MissingResourceException e) {
+			return "!" + key + "!"; //$NON-NLS-2$ //$NON-NLS-1$
+		}
+	}
+
+	/**
+	 * Returns the message identified by the specified key, replacing a single
+	 * parameter with the provided value.
+	 * 
+	 * @param key the message key
+	 * @param arg the parameter value
+	 * @return the formatted string, or the key enclosed by exclamation marks
+	 *         if no message was found for the key
+	 */
+	public static String getString(String key, String arg) {
+		return getString(key, new String[] { arg });
+	}
+
+	/**
+	 * Returns the message identified by the specified key, replacing all
+	 * parameters with the provided values.
+	 * 
+	 * @param key the message key
+	 * @param args the parameter values
+	 * @return the formatted string, or the key enclosed by exclamation marks
+	 *         if no message was found for the key
+	 */
+	public static String getString(String key, String[] args) {
+		return MessageFormat.format(getString(key), args);	
+	}
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/internal/WebUIMessages.properties b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/internal/WebUIMessages.properties
new file mode 100644
index 0000000..259e7c6
--- /dev/null
+++ b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/internal/WebUIMessages.properties
@@ -0,0 +1,23 @@
+#
+# Copyright (c) 2004 Christopher Lenz and others.
+# All rights reserved. This program and the accompanying materials 
+# are made available under the terms of the Common Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/cpl-v10.html
+# 
+# Contributors:
+#     Christopher Lenz - initial english resources
+# 
+# $Id: WebUIMessages.properties,v 1.1 2004-09-02 18:26:29 jsurfer Exp $
+#
+
+# Outline Page -----------------------------------------------------------------
+
+OutlinePage.linkWithEditor.image = link_editor.gif
+OutlinePage.linkWithEditor.label = Link with editor
+OutlinePage.linkWithEditor.tooltip = Link with editor
+OutlinePage.linkWithEditor.description = Link with editor
+
+# Preview View -----------------------------------------------------------------
+
+BrowserPreview.notAvailable = A preview is not available.
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/preferences/EmptyPreferencePage.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/preferences/EmptyPreferencePage.java
new file mode 100644
index 0000000..9cc1c24
--- /dev/null
+++ b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/preferences/EmptyPreferencePage.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://solareclipse.sourceforge.net/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ * 
+ * $Id: EmptyPreferencePage.java,v 1.1 2004-09-02 18:26:30 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.ui.preferences;
+
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+
+/**
+ * Empty preference page (could be used as a preferences category).
+ * 
+ * @author Igor Malinin
+ */
+public class EmptyPreferencePage extends PreferencePage implements
+		IWorkbenchPreferencePage {
+
+	/*
+	 * @see org.eclipse.jface.preference.PreferencePage#createContents(Composite)
+	 */
+	protected Control createContents(Composite parent) {
+		return new Composite(parent, SWT.NULL);
+	}
+
+	/*
+	 * @see org.eclipse.ui.IWorkbenchPreferencePage#init(IWorkbench)
+	 */
+	public void init(IWorkbench workbench) {
+	}
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/preferences/ITextStylePreferences.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/preferences/ITextStylePreferences.java
new file mode 100644
index 0000000..6235a01
--- /dev/null
+++ b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/preferences/ITextStylePreferences.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://solareclipse.sourceforge.net/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ * 
+ * $Id: ITextStylePreferences.java,v 1.1 2004-09-02 18:26:30 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.ui.preferences;
+
+
+/**
+ * 
+ * 
+ * @author Igor Malinin
+ */
+public interface ITextStylePreferences {
+	public static final String SUFFIX_FOREGROUND = "_foreground"; //$NON-NLS-1$
+	public static final String SUFFIX_BACKGROUND = "_background"; //$NON-NLS-1$
+	public static final String SUFFIX_STYLE      = "_style";      //$NON-NLS-1$
+
+	public static final String STYLE_NORMAL = "normal"; //$NON-NLS-1$
+	public static final String STYLE_BOLD   = "bold";   //$NON-NLS-1$
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/preferences/OverlayPreferenceStore.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/preferences/OverlayPreferenceStore.java
new file mode 100644
index 0000000..61951fa
--- /dev/null
+++ b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/preferences/OverlayPreferenceStore.java
@@ -0,0 +1,445 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://solareclipse.sourceforge.net/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ * 
+ * $Id: OverlayPreferenceStore.java,v 1.1 2004-09-02 18:26:30 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.ui.preferences;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceStore;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+
+
+/**
+ * An overlaying preference store.
+ */
+public class OverlayPreferenceStore implements IPreferenceStore {
+	private class PropertyListener implements IPropertyChangeListener {
+		public void propertyChange(PropertyChangeEvent event) {
+			PreferenceDescriptor key = findOverlayKey(event.getProperty());
+			if (key != null) {
+				propagateProperty(parent, key, store);
+			}
+		}
+	}
+
+	IPreferenceStore parent;
+	IPreferenceStore store;
+
+	private PreferenceDescriptor[] keys;
+
+	private PropertyListener fPropertyListener;
+
+	public OverlayPreferenceStore(
+		IPreferenceStore parent, PreferenceDescriptor[] overlayKeys
+	) {
+		this.parent = parent;
+		this.keys = overlayKeys;
+
+		store = new PreferenceStore();
+	}
+
+	PreferenceDescriptor findOverlayKey(String key) {
+		for (int i = 0; i < keys.length; i++) {
+			if (keys[i].key.equals(key)) {
+				return keys[i];
+			}
+		}
+
+		return null;
+	}
+
+	private boolean covers(String key) {
+		return (findOverlayKey(key) != null);
+	}
+
+	void propagateProperty(
+		IPreferenceStore orgin, PreferenceDescriptor key,
+		IPreferenceStore target
+	) {
+		if (orgin.isDefault(key.key)) {
+			if (!target.isDefault(key.key)) {
+				target.setToDefault(key.key);
+			}
+
+			return;
+		}
+
+		PreferenceDescriptor.Type d = key.type;
+		if (PreferenceDescriptor.BOOLEAN == d) {
+			boolean originValue = orgin.getBoolean(key.key);
+			boolean targetValue = target.getBoolean(key.key);
+			if (targetValue != originValue) {
+				target.setValue(key.key, originValue);
+			}
+		} else if (PreferenceDescriptor.DOUBLE == d) {
+			double originValue = orgin.getDouble(key.key);
+			double targetValue = target.getDouble(key.key);
+			if (targetValue != originValue) {
+				target.setValue(key.key, originValue);
+			}
+		} else if (PreferenceDescriptor.FLOAT == d) {
+			float originValue = orgin.getFloat(key.key);
+			float targetValue = target.getFloat(key.key);
+			if (targetValue != originValue) {
+				target.setValue(key.key, originValue);
+			}
+		} else if (PreferenceDescriptor.INT == d) {
+			int originValue = orgin.getInt(key.key);
+			int targetValue = target.getInt(key.key);
+			if (targetValue != originValue) {
+				target.setValue(key.key, originValue);
+			}
+		} else if (PreferenceDescriptor.LONG == d) {
+			long originValue = orgin.getLong(key.key);
+			long targetValue = target.getLong(key.key);
+			if (targetValue != originValue) {
+				target.setValue(key.key, originValue);
+			}
+		} else if (PreferenceDescriptor.STRING == d) {
+			String originValue = orgin.getString(key.key);
+			String targetValue = target.getString(key.key);
+			if (targetValue != null && originValue != null
+					&& !targetValue.equals(originValue)) {
+				target.setValue(key.key, originValue);
+			}
+		}
+	}
+
+	public void propagate() {
+		for (int i = 0; i < keys.length; i++) {
+			propagateProperty(store, keys[i], parent);
+		}
+	}
+
+	private void loadProperty(
+		IPreferenceStore orgin, PreferenceDescriptor key,
+		IPreferenceStore target, boolean forceInitialization
+	) {
+		PreferenceDescriptor.Type d = key.type;
+		if (PreferenceDescriptor.BOOLEAN == d) {
+			if (forceInitialization) {
+				target.setValue(key.key, true);
+			}
+			target.setValue(key.key, orgin.getBoolean(key.key));
+			target.setDefault(key.key, orgin.getDefaultBoolean(key.key));
+		} else if (PreferenceDescriptor.DOUBLE == d) {
+			if (forceInitialization) {
+				target.setValue(key.key, 1.0D);
+			}
+			target.setValue(key.key, orgin.getDouble(key.key));
+			target.setDefault(key.key, orgin.getDefaultDouble(key.key));
+		} else if (PreferenceDescriptor.FLOAT == d) {
+			if (forceInitialization) {
+				target.setValue(key.key, 1.0F);
+			}
+			target.setValue(key.key, orgin.getFloat(key.key));
+			target.setDefault(key.key, orgin.getDefaultFloat(key.key));
+		} else if (PreferenceDescriptor.INT == d) {
+			if (forceInitialization) {
+				target.setValue(key.key, 1);
+			}
+			target.setValue(key.key, orgin.getInt(key.key));
+			target.setDefault(key.key, orgin.getDefaultInt(key.key));
+		} else if (PreferenceDescriptor.LONG == d) {
+			if (forceInitialization) {
+				target.setValue(key.key, 1L);
+			}
+			target.setValue(key.key, orgin.getLong(key.key));
+			target.setDefault(key.key, orgin.getDefaultLong(key.key));
+		} else if (PreferenceDescriptor.STRING == d) {
+			if (forceInitialization) {
+				target.setValue(key.key, "1"); //$NON-NLS-1$
+			}
+			target.setValue(key.key, orgin.getString(key.key));
+			target.setDefault(key.key, orgin.getDefaultString(key.key));
+		}
+	}
+
+	public void load() {
+		for (int i = 0; i < keys.length; i++) {
+			loadProperty(parent, keys[i], store, true);
+		}
+	}
+
+	public void loadDefaults() {
+		for (int i = 0; i < keys.length; i++) {
+			setToDefault(keys[i].key);
+		}
+	}
+
+	public void start() {
+		if (fPropertyListener == null) {
+			fPropertyListener = new PropertyListener();
+			parent.addPropertyChangeListener(fPropertyListener);
+		}
+	}
+
+	public void stop() {
+		if (fPropertyListener != null) {
+			parent.removePropertyChangeListener(fPropertyListener);
+			fPropertyListener = null;
+		}
+	}
+
+	/*
+	 * @see IPreferenceStore#addPropertyChangeListener(IPropertyChangeListener)
+	 */
+	public void addPropertyChangeListener(IPropertyChangeListener listener) {
+		store.addPropertyChangeListener(listener);
+	}
+
+	/*
+	 * @see IPreferenceStore#removePropertyChangeListener(IPropertyChangeListener)
+	 */
+	public void removePropertyChangeListener(IPropertyChangeListener listener) {
+		store.removePropertyChangeListener(listener);
+	}
+
+	/*
+	 * @see IPreferenceStore#firePropertyChangeEvent(String, Object, Object)
+	 */
+	public void firePropertyChangeEvent(
+		String name, Object oldValue, Object newValue
+	) {
+		store.firePropertyChangeEvent(name, oldValue, newValue);
+	}
+
+	/*
+	 * @see IPreferenceStore#contains(String)
+	 */
+	public boolean contains(String name) {
+		return store.contains(name);
+	}
+
+	/*
+	 * @see IPreferenceStore#getBoolean(String)
+	 */
+	public boolean getBoolean(String name) {
+		return store.getBoolean(name);
+	}
+
+	/*
+	 * @see IPreferenceStore#getDefaultBoolean(String)
+	 */
+	public boolean getDefaultBoolean(String name) {
+		return store.getDefaultBoolean(name);
+	}
+
+	/*
+	 * @see IPreferenceStore#getDefaultDouble(String)
+	 */
+	public double getDefaultDouble(String name) {
+		return store.getDefaultDouble(name);
+	}
+
+	/*
+	 * @see IPreferenceStore#getDefaultFloat(String)
+	 */
+	public float getDefaultFloat(String name) {
+		return store.getDefaultFloat(name);
+	}
+
+	/*
+	 * @see IPreferenceStore#getDefaultInt(String)
+	 */
+	public int getDefaultInt(String name) {
+		return store.getDefaultInt(name);
+	}
+
+	/*
+	 * @see IPreferenceStore#getDefaultLong(String)
+	 */
+	public long getDefaultLong(String name) {
+		return store.getDefaultLong(name);
+	}
+
+	/*
+	 * @see IPreferenceStore#getDefaultString(String)
+	 */
+	public String getDefaultString(String name) {
+		return store.getDefaultString(name);
+	}
+
+	/*
+	 * @see IPreferenceStore#getDouble(String)
+	 */
+	public double getDouble(String name) {
+		return store.getDouble(name);
+	}
+
+	/*
+	 * @see IPreferenceStore#getFloat(String)
+	 */
+	public float getFloat(String name) {
+		return store.getFloat(name);
+	}
+
+	/*
+	 * @see IPreferenceStore#getInt(String)
+	 */
+	public int getInt(String name) {
+		return store.getInt(name);
+	}
+
+	/*
+	 * @see IPreferenceStore#getLong(String)
+	 */
+	public long getLong(String name) {
+		return store.getLong(name);
+	}
+
+	/*
+	 * @see IPreferenceStore#getString(String)
+	 */
+	public String getString(String name) {
+		return store.getString(name);
+	}
+
+	/*
+	 * @see IPreferenceStore#isDefault(String)
+	 */
+	public boolean isDefault(String name) {
+		return store.isDefault(name);
+	}
+
+	/*
+	 * @see IPreferenceStore#needsSaving()
+	 */
+	public boolean needsSaving() {
+		return store.needsSaving();
+	}
+
+	/*
+	 * @see IPreferenceStore#putValue(String, String)
+	 */
+	public void putValue(String name, String value) {
+		if (covers(name)) {
+			store.putValue(name, value);
+		}
+	}
+
+	/*
+	 * @see IPreferenceStore#setDefault(String, double)
+	 */
+	public void setDefault(String name, double value) {
+		if (covers(name)) {
+			store.setDefault(name, value);
+		}
+	}
+
+	/*
+	 * @see IPreferenceStore#setDefault(String, float)
+	 */
+	public void setDefault(String name, float value) {
+		if (covers(name)) {
+			store.setDefault(name, value);
+		}
+	}
+
+	/*
+	 * @see IPreferenceStore#setDefault(String, int)
+	 */
+	public void setDefault(String name, int value) {
+		if (covers(name)) {
+			store.setDefault(name, value);
+		}
+	}
+
+	/*
+	 * @see IPreferenceStore#setDefault(String, long)
+	 */
+	public void setDefault(String name, long value) {
+		if (covers(name)) {
+			store.setDefault(name, value);
+		}
+	}
+
+	/*
+	 * @see IPreferenceStore#setDefault(String, String)
+	 */
+	public void setDefault(String name, String value) {
+		if (covers(name)) {
+			store.setDefault(name, value);
+		}
+	}
+
+	/*
+	 * @see IPreferenceStore#setDefault(String, boolean)
+	 */
+	public void setDefault(String name, boolean value) {
+		if (covers(name)) {
+			store.setDefault(name, value);
+		}
+	}
+
+	/*
+	 * @see IPreferenceStore#setToDefault(String)
+	 */
+	public void setToDefault(String name) {
+		store.setToDefault(name);
+	}
+
+	/*
+	 * @see IPreferenceStore#setValue(String, double)
+	 */
+	public void setValue(String name, double value) {
+		if (covers(name)) {
+			store.setValue(name, value);
+		}
+	}
+
+	/*
+	 * @see IPreferenceStore#setValue(String, float)
+	 */
+	public void setValue(String name, float value) {
+		if (covers(name)) {
+			store.setValue(name, value);
+		}
+	}
+
+	/*
+	 * @see IPreferenceStore#setValue(String, int)
+	 */
+	public void setValue(String name, int value) {
+		if (covers(name)) {
+			store.setValue(name, value);
+		}
+	}
+
+	/*
+	 * @see IPreferenceStore#setValue(String, long)
+	 */
+	public void setValue(String name, long value) {
+		if (covers(name)) {
+			store.setValue(name, value);
+		}
+	}
+
+	/*
+	 * @see IPreferenceStore#setValue(String, String)
+	 */
+	public void setValue(String name, String value) {
+		if (covers(name)) {
+			store.setValue(name, value);
+		}
+	}
+
+	/*
+	 * @see IPreferenceStore#setValue(String, boolean)
+	 */
+	public void setValue(String name, boolean value) {
+		if (covers(name)) {
+			store.setValue(name, value);
+		}
+	}
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/preferences/PreferenceDescriptor.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/preferences/PreferenceDescriptor.java
new file mode 100644
index 0000000..d8b8610
--- /dev/null
+++ b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/preferences/PreferenceDescriptor.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://solareclipse.sourceforge.net/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ * 
+ * $Id: PreferenceDescriptor.java,v 1.1 2004-09-02 18:26:30 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.ui.preferences;
+
+/**
+ * Preference descriptor.
+ * 
+ * @author Igor Malinin
+ */
+public final class PreferenceDescriptor {
+	public static final Type BOOLEAN = new Type();
+	public static final Type DOUBLE  = new Type();
+	public static final Type FLOAT   = new Type();
+	public static final Type INT     = new Type();
+	public static final Type LONG    = new Type();
+	public static final Type STRING  = new Type();
+
+	public static final class Type {
+		Type() {}
+	}
+
+	public final Type  type;
+	public final String key;
+
+	public PreferenceDescriptor(Type type, String key) {
+		this.type = type;
+		this.key = key;
+	}
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/templates/preferences/TemplatesPreferencePage.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/templates/preferences/TemplatesPreferencePage.java
new file mode 100644
index 0000000..ecdc770
--- /dev/null
+++ b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/templates/preferences/TemplatesPreferencePage.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.ui.templates.preferences;
+
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.eclipse.ui.texteditor.templates.TemplatePreferencePage;
+/**
+ * @see org.eclipse.jface.preference.PreferencePage
+ */
+public class TemplatesPreferencePage extends TemplatePreferencePage implements IWorkbenchPreferencePage {
+	
+	public TemplatesPreferencePage() {
+		setPreferenceStore(WebUI.getDefault().getPreferenceStore());
+		setTemplateStore(WebUI.getDefault().getTemplateStore());
+		setContextTypeRegistry(WebUI.getDefault().getContextTypeRegistry());
+	}
+
+	protected boolean isShowFormatterSetting() {
+		return false;
+	}
+	
+	
+	public boolean performOk() {
+		boolean ok= super.performOk();
+		
+		WebUI.getDefault().savePluginPreferences();
+		
+		return ok;
+	}
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/templates/template/BasicCompletionProcessor.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/templates/template/BasicCompletionProcessor.java
new file mode 100644
index 0000000..1e68c52
--- /dev/null
+++ b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/templates/template/BasicCompletionProcessor.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.ui.templates.template;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.jface.text.templates.Template;
+import org.eclipse.jface.text.templates.TemplateCompletionProcessor;
+import org.eclipse.jface.text.templates.TemplateContext;
+import org.eclipse.jface.text.templates.TemplateContextType;
+import org.eclipse.jface.text.templates.TemplateException;
+import org.eclipse.swt.graphics.Image;
+/**
+ * A completion processor for XML templates.
+ */
+public class BasicCompletionProcessor extends TemplateCompletionProcessor {
+  private static final String DEFAULT_IMAGE = "icons/template.gif"; //$NON-NLS-1$
+
+  /**
+   * We watch for angular brackets since those are often part of XML templates.
+   */
+  protected String extractPrefix(ITextViewer viewer, int offset) {
+    IDocument document = viewer.getDocument();
+    int i = offset;
+    if (i > document.getLength())
+      return ""; //$NON-NLS-1$
+
+    try {
+      while (i > 0) {
+        char ch = document.getChar(i - 1);
+        if (ch != '<' && ch != '&' && ch != '{' && !Character.isJavaIdentifierPart(ch))
+          break;
+        i--;
+      }
+
+      return document.get(i, offset - i);
+    } catch (BadLocationException e) {
+      return ""; //$NON-NLS-1$
+    }
+  }
+
+  /**
+   * Cut out angular brackets for relevance sorting, since the template name does not contain the brackets.
+   */
+  protected int getRelevance(Template template, String prefix) {
+    //		if (prefix.startsWith("<")) //$NON-NLS-1$
+    //			prefix= prefix.substring(1);
+    if (template.getName().startsWith(prefix))
+      return 90;
+    return 0;
+  }
+
+  /**
+   * Simply return all templates.
+   */
+  protected Template[] getTemplates(String contextTypeId) {
+    return WebUI.getDefault().getTemplateStore().getTemplates();
+  }
+
+  /**
+   * Return the XML context type that is supported by this plugin.
+   */
+  protected TemplateContextType getContextType(ITextViewer viewer, IRegion region) {
+    return WebUI.getDefault().getContextTypeRegistry().getContextType(XMLContextType.XML_CONTEXT_TYPE);
+  }
+
+  /**
+   * Always return the default image.
+   */
+  protected Image getImage(Template template) {
+    ImageRegistry registry = WebUI.getDefault().getImageRegistry();
+    Image image = registry.get(DEFAULT_IMAGE);
+    if (image == null) {
+      ImageDescriptor desc = WebUI.imageDescriptorFromPlugin("org.eclipse.ui.examples.javaeditor", DEFAULT_IMAGE); //$NON-NLS-1$
+      registry.put(DEFAULT_IMAGE, desc);
+      image = registry.get(DEFAULT_IMAGE);
+    }
+    return image;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeCompletionProposals(org.eclipse.jface.text.ITextViewer,
+   *      int)
+   */
+  public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) {
+    ITextSelection selection = (ITextSelection) viewer.getSelectionProvider().getSelection();
+
+    // adjust offset to end of normalized selection
+    if (selection.getOffset() == offset)
+      offset = selection.getOffset() + selection.getLength();
+
+    String prefix = extractPrefix(viewer, offset);
+    prefix = prefix.toLowerCase();
+    Region region = new Region(offset - prefix.length(), prefix.length());
+    TemplateContext context = createContext(viewer, region);
+    if (context == null)
+      return new ICompletionProposal[0];
+
+    context.setVariable("selection", selection.getText()); // name of the selection variables {line, word}_selection //$NON-NLS-1$
+
+    Template[] templates = getTemplates(context.getContextType().getId());
+
+    List matches = new ArrayList();
+    for (int i = 0; i < templates.length; i++) {
+      Template template = templates[i];
+      try {
+        context.getContextType().validate(template.getPattern());
+      } catch (TemplateException e) {
+        continue;
+      }
+
+      if (template.getName().startsWith(prefix)) { //&& template.matches(prefix, context.getContextType().getId()))
+        matches.add(createProposal(template, context, region, getRelevance(template, prefix)));
+      }
+    }
+
+    return (ICompletionProposal[]) matches.toArray(new ICompletionProposal[matches.size()]);
+
+  }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/templates/template/HTMLContextType.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/templates/template/HTMLContextType.java
new file mode 100644
index 0000000..908b084
--- /dev/null
+++ b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/templates/template/HTMLContextType.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.ui.templates.template;
+
+import org.eclipse.jface.text.templates.GlobalTemplateVariables;
+import org.eclipse.jface.text.templates.TemplateContextType;
+
+
+/**
+ * A very simple context type.
+ */
+public class HTMLContextType extends TemplateContextType {
+
+	/** This context's id */
+	public static final String HTML_CONTEXT_TYPE= "html"; //$NON-NLS-1$
+
+	/**
+	 * Creates a new XML context type. 
+	 */
+	public HTMLContextType() {
+		addGlobalResolvers();
+	}
+
+	private void addGlobalResolvers() {
+		addResolver(new GlobalTemplateVariables.Cursor());
+		addResolver(new GlobalTemplateVariables.WordSelection());
+		addResolver(new GlobalTemplateVariables.LineSelection());
+		addResolver(new GlobalTemplateVariables.Dollar());
+		addResolver(new GlobalTemplateVariables.Date());
+		addResolver(new GlobalTemplateVariables.Year());
+		addResolver(new GlobalTemplateVariables.Time());
+		addResolver(new GlobalTemplateVariables.User());
+	}
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/templates/template/JSContextType.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/templates/template/JSContextType.java
new file mode 100644
index 0000000..63d51da
--- /dev/null
+++ b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/templates/template/JSContextType.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.ui.templates.template;
+
+import org.eclipse.jface.text.templates.GlobalTemplateVariables;
+import org.eclipse.jface.text.templates.TemplateContextType;
+
+
+/**
+ * A very simple context type.
+ */
+public class JSContextType extends TemplateContextType {
+
+	/** This context's id */
+	public static final String JS_CONTEXT_TYPE= "javascript"; //$NON-NLS-1$
+
+	/**
+	 * Creates a new XML context type. 
+	 */
+	public JSContextType() {
+		addGlobalResolvers();
+	}
+
+	private void addGlobalResolvers() {
+		addResolver(new GlobalTemplateVariables.Cursor());
+		addResolver(new GlobalTemplateVariables.WordSelection());
+		addResolver(new GlobalTemplateVariables.LineSelection());
+		addResolver(new GlobalTemplateVariables.Dollar());
+		addResolver(new GlobalTemplateVariables.Date());
+		addResolver(new GlobalTemplateVariables.Year());
+		addResolver(new GlobalTemplateVariables.Time());
+		addResolver(new GlobalTemplateVariables.User());
+	}
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/templates/template/XMLContextType.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/templates/template/XMLContextType.java
new file mode 100644
index 0000000..9944dfb
--- /dev/null
+++ b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/templates/template/XMLContextType.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.ui.templates.template;
+
+import org.eclipse.jface.text.templates.GlobalTemplateVariables;
+import org.eclipse.jface.text.templates.TemplateContextType;
+
+
+/**
+ * A very simple context type.
+ */
+public class XMLContextType extends TemplateContextType {
+
+	/** This context's id */
+	public static final String XML_CONTEXT_TYPE= "xml"; //$NON-NLS-1$
+
+	/**
+	 * Creates a new XML context type. 
+	 */
+	public XMLContextType() {
+		addGlobalResolvers();
+	}
+
+	private void addGlobalResolvers() {
+		addResolver(new GlobalTemplateVariables.Cursor());
+		addResolver(new GlobalTemplateVariables.WordSelection());
+		addResolver(new GlobalTemplateVariables.LineSelection());
+		addResolver(new GlobalTemplateVariables.Dollar());
+		addResolver(new GlobalTemplateVariables.Date());
+		addResolver(new GlobalTemplateVariables.Year());
+		addResolver(new GlobalTemplateVariables.Time());
+		addResolver(new GlobalTemplateVariables.User());
+	}
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/text/AbstractTextTools.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/text/AbstractTextTools.java
new file mode 100644
index 0000000..38a4f8b
--- /dev/null
+++ b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/text/AbstractTextTools.java
@@ -0,0 +1,279 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://solareclipse.sourceforge.net/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ * 
+ * $Id: AbstractTextTools.java,v 1.1 2004-09-02 18:26:49 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.ui.text;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import net.sourceforge.phpeclipse.ui.ColorManager;
+import net.sourceforge.phpeclipse.ui.preferences.ITextStylePreferences;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.resource.StringConverter;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.RGB;
+
+/**
+ * @author Igor Malinin
+ */
+public class AbstractTextTools {
+
+	/** The preference store */
+	protected IPreferenceStore store;
+
+	/** The color manager */
+	protected ColorManager colorManager;
+
+	private Map tokens;
+
+	private String[] properties;
+
+	private String[] foregroundPropertyNames;
+
+	private String[] backgroundPropertyNames;
+
+	private String[] stylePropertyNames;
+
+	private IPropertyChangeListener listener;
+
+	/**
+	 * Creates a new text tools collection.
+	 */
+	public AbstractTextTools(IPreferenceStore store, String[] properties) {
+	  this(store, properties, new ColorManager());
+	}
+	/**
+	 * Creates a new text tools collection.
+	 */
+	public AbstractTextTools(IPreferenceStore store, String[] properties, ColorManager manager) {
+		this.store = store;
+		this.properties = properties;
+
+		colorManager = manager;
+
+		tokens = new HashMap();
+
+		int length = properties.length;
+
+		foregroundPropertyNames = new String[length];
+		backgroundPropertyNames = new String[length];
+		stylePropertyNames = new String[length];
+
+		for (int i = 0; i < length; i++) {
+			String property = properties[i];
+
+			String foreground = property
+					+ ITextStylePreferences.SUFFIX_FOREGROUND;
+			String background = property
+					+ ITextStylePreferences.SUFFIX_BACKGROUND;
+			String style = property + ITextStylePreferences.SUFFIX_STYLE;
+
+			foregroundPropertyNames[i] = foreground;
+			backgroundPropertyNames[i] = background;
+			stylePropertyNames[i] = style;
+
+			RGB rgb;
+
+			rgb = getColor(store, foreground);
+			if (rgb != null) {
+				colorManager.bindColor(foreground, rgb);
+			}
+
+			rgb = getColor(store, background);
+			if (rgb != null) {
+				colorManager.bindColor(background, rgb);
+			}
+
+			tokens.put(property, new Token(new TextAttribute(colorManager
+					.getColor(foreground), colorManager.getColor(background),
+					getStyle(store, style))));
+		}
+
+		listener = new IPropertyChangeListener() {
+
+			public void propertyChange(PropertyChangeEvent event) {
+				adaptToPreferenceChange(event);
+			}
+		};
+
+		store.addPropertyChangeListener(listener);
+	}
+
+	/**
+	 * Disposes all the individual tools of this tools collection.
+	 */
+	public void dispose() {
+		if (store != null) {
+			store.removePropertyChangeListener(listener);
+
+			store = null;
+			listener = null;
+		}
+
+		if (colorManager != null) {
+			colorManager.dispose();
+
+			colorManager = null;
+		}
+
+		tokens = null;
+
+		properties = null;
+		foregroundPropertyNames = null;
+		backgroundPropertyNames = null;
+		stylePropertyNames = null;
+	}
+
+	/**
+	 * Returns the color manager which is used to manage any XML-specific
+	 * colors needed for such things like syntax highlighting.
+	 * 
+	 * @return the color manager to be used for XML text viewers
+	 */
+	public ColorManager getColorManager() {
+		return colorManager;
+	}
+
+	public Map getTokens() {
+		return tokens;
+	}
+
+	protected Token getToken(String key) {
+		int index = indexOf(key);
+		if (index < 0) {
+			return null;
+		}
+
+		return (Token) tokens.get(properties[index]);
+	}
+
+	/**
+	 * Determines whether the preference change encoded by the given event
+	 * changes the behavior of one its contained components.
+	 * 
+	 * @param event
+	 *            the event to be investigated
+	 * @return true if event causes a behavioral change
+	 */
+	public boolean affectsBehavior(PropertyChangeEvent event) {
+		return (indexOf(event.getProperty()) >= 0);
+	}
+
+	/**
+	 * Adapts the behavior of the contained components to the change encoded in
+	 * the given event.
+	 * 
+	 * @param event
+	 *            the event to whch to adapt
+	 */
+	protected void adaptToPreferenceChange(PropertyChangeEvent event) {
+		String property = event.getProperty();
+
+		Token token = getToken(property);
+		if (token != null) {
+			if (property.endsWith(ITextStylePreferences.SUFFIX_FOREGROUND)
+					|| property
+							.endsWith(ITextStylePreferences.SUFFIX_BACKGROUND)) {
+				adaptToColorChange(token, event);
+			} else if (property.endsWith(ITextStylePreferences.SUFFIX_STYLE)) {
+				adaptToStyleChange(token, event);
+			}
+		}
+	}
+
+	private void adaptToColorChange(Token token, PropertyChangeEvent event) {
+		RGB rgb = getColor(event.getNewValue());
+
+		String property = event.getProperty();
+
+		colorManager.unbindColor(property);
+		if (rgb != null) {
+			colorManager.bindColor(property, rgb);
+		}
+
+		Object data = token.getData();
+		if (data instanceof TextAttribute) {
+			TextAttribute old = (TextAttribute) data;
+
+			int i = indexOf(property);
+
+			token.setData(new TextAttribute(colorManager
+					.getColor(foregroundPropertyNames[i]), colorManager
+					.getColor(backgroundPropertyNames[i]), old.getStyle()));
+		}
+	}
+
+	private void adaptToStyleChange(Token token, PropertyChangeEvent event) {
+		int style = getStyle((String) event.getNewValue());
+
+		Object data = token.getData();
+		if (data instanceof TextAttribute) {
+			TextAttribute old = (TextAttribute) data;
+			if (old.getStyle() != style) {
+				token.setData(new TextAttribute(old.getForeground(), old
+						.getBackground(), style));
+			}
+		}
+	}
+
+	private int indexOf(String property) {
+		if (property != null) {
+			int length = properties.length;
+
+			for (int i = 0; i < length; i++) {
+				if (property.equals(properties[i])
+						|| property.equals(foregroundPropertyNames[i])
+						|| property.equals(backgroundPropertyNames[i])
+						|| property.equals(stylePropertyNames[i])) {
+					return i;
+				}
+			}
+		}
+
+		return -1;
+	}
+
+	private RGB getColor(IPreferenceStore store, String key) {
+		return getColor(store.getString(key));
+	}
+
+	private RGB getColor(Object value) {
+		if (value instanceof RGB) {
+			return (RGB) value;
+		}
+
+		String str = (String) value;
+		if (str.length() > 0) {
+			return StringConverter.asRGB(str);
+		}
+
+		return null;
+	}
+
+	private int getStyle(IPreferenceStore store, String key) {
+		return getStyle(store.getString(key));
+	}
+
+	private int getStyle(String value) {
+		if (value.indexOf(ITextStylePreferences.STYLE_BOLD) >= 0) {
+			return SWT.BOLD;
+		}
+
+		return SWT.NORMAL;
+	}
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/text/IReconcilingParticipant.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/text/IReconcilingParticipant.java
new file mode 100644
index 0000000..26f9f62
--- /dev/null
+++ b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/text/IReconcilingParticipant.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2004 Christopher Lenz and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Christopher Lenz - initial API
+ * 
+ * $Id: IReconcilingParticipant.java,v 1.1 2004-09-02 18:26:49 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.ui.text;
+
+/**
+ *  Interface for classes participating in reconciling.
+ */
+public interface IReconcilingParticipant {
+	
+	/**
+	 * Called after reconciling has been finished.
+	 */
+	void reconciled();
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/text/TextDoubleClickStrategy.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/text/TextDoubleClickStrategy.java
new file mode 100644
index 0000000..c3e70a5
--- /dev/null
+++ b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/text/TextDoubleClickStrategy.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://solareclipse.sourceforge.net/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ * 
+ * $Id: TextDoubleClickStrategy.java,v 1.1 2004-09-02 18:26:49 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.ui.text;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextDoubleClickStrategy;
+import org.eclipse.jface.text.ITextViewer;
+
+/**
+ * @author Igor Malinin
+ */
+public class TextDoubleClickStrategy implements ITextDoubleClickStrategy {
+
+	/*
+	 * @see org.eclipse.jface.text.ITextDoubleClickStrategy#doubleClicked(ITextViewer)
+	 */
+	public void doubleClicked(ITextViewer viewer) {
+		int offset = viewer.getSelectedRange().x;
+		if (offset < 0) { return; }
+
+		selectWord(viewer, viewer.getDocument(), offset);
+	}
+
+	protected void selectWord(ITextViewer textViewer, IDocument document,
+			int offset) {
+		try {
+			int start = offset;
+			while (start >= 0) {
+				char c = document.getChar(start);
+
+				if (!Character.isUnicodeIdentifierPart(c)) {
+					break;
+				}
+
+				--start;
+			}
+
+			int length = document.getLength();
+
+			int end = offset;
+			while (end < length) {
+				char c = document.getChar(end);
+
+				if (!Character.isUnicodeIdentifierPart(c)) {
+					break;
+				}
+
+				++end;
+			}
+
+			if (start == end) {
+				textViewer.setSelectedRange(start, 0);
+			} else {
+				textViewer.setSelectedRange(start + 1, end - start - 1);
+			}
+		} catch (BadLocationException x) {
+		}
+	}
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/text/rules/AbstractPartitioner.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/text/rules/AbstractPartitioner.java
new file mode 100644
index 0000000..981b803
--- /dev/null
+++ b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/text/rules/AbstractPartitioner.java
@@ -0,0 +1,574 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://solareclipse.sourceforge.net/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ * 
+ * $Id: AbstractPartitioner.java,v 1.1 2004-09-02 18:26:29 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.ui.text.rules;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentPartitioner;
+import org.eclipse.jface.text.IDocumentPartitionerExtension;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.TypedRegion;
+import org.eclipse.jface.text.rules.IPartitionTokenScanner;
+import org.eclipse.jface.text.rules.IToken;
+
+/**
+ * Advanced partitioner which maintains partitions as views to connected document. Views have own partitioners themselves. This
+ * class is designed as a base for complex partitioners such as for JSP, PHP, ASP, etc. languages.
+ * 
+ * @author Igor Malinin
+ */
+public abstract class AbstractPartitioner implements IDocumentPartitioner, IDocumentPartitionerExtension {
+  public final static boolean DEBUG = true;
+
+  /** Partition scanner */
+  protected IPartitionTokenScanner scanner;
+
+  /** Connected document */
+  protected IDocument document;
+
+  /** Flat structure of the document */
+  protected List nodes = new ArrayList();
+
+  /** The offset at which the first changed partition starts */
+  protected int regionStart;
+
+  /** The offset at which the last changed partition ends */
+  protected int regionEnd;
+
+  public AbstractPartitioner(IPartitionTokenScanner scanner) {
+    this.scanner = scanner;
+  }
+
+  protected FlatNode createNode(String type, int offset, int length) {
+    if (DEBUG) {
+      Assert.isTrue(offset >= 0, Integer.toString(offset));
+    }
+    FlatNode node = new FlatNode(type);
+    node.offset = offset;
+    node.length = length;
+    return node;
+  }
+
+  protected void addInnerRegion(FlatNode position) {
+    nodes.add(computeFlatNodeIndex(position.offset), position);
+  }
+
+  protected void removeInnerRegion(FlatNode position) {
+    nodes.remove(position); // TODO: Indexed remove?
+  }
+
+  protected void deleteInnerRegion(FlatNode position) {
+    nodes.remove(position); // TODO: Indexed remove?
+  }
+
+  protected void resizeInnerRegion(FlatNode position) {
+  }
+
+  /*
+   * @see org.eclipse.jface.text.IDocumentPartitioner#connect(IDocument)
+   */
+  public void connect(IDocument document) {
+    this.document = document;
+
+    initialize();
+  }
+
+  /*
+   * @see org.eclipse.jface.text.IDocumentPartitioner#disconnect()
+   */
+  public void disconnect() {
+    nodes.clear();
+    document = null;
+  }
+
+  /**
+   * Performs the initial partitioning of the partitioner's document.
+   */
+  protected void initialize() {
+    scanner.setRange(document, 0, document.getLength());
+
+    IToken token = scanner.nextToken();
+    while (!token.isEOF()) {
+      String contentType = getTokenContentType(token);
+
+      if (isSupportedContentType(contentType)) {
+        addInnerRegion(createNode(contentType, scanner.getTokenOffset(), scanner.getTokenLength()));
+      }
+
+      token = scanner.nextToken();
+    }
+  }
+
+  /*
+   * @see org.eclipse.jface.text.IDocumentPartitioner#documentAboutToBeChanged(DocumentEvent)
+   */
+  public void documentAboutToBeChanged(DocumentEvent event) {
+    regionStart = regionEnd = -1;
+  }
+
+  /*
+   * @see org.eclipse.jface.text.IDocumentPartitioner#documentChanged(DocumentEvent)
+   */
+  public boolean documentChanged(DocumentEvent event) {
+    return (documentChanged2(event) != null);
+  }
+
+  /*
+   * @see org.eclipse.jface.text.IDocumentPartitionerExtension#documentChanged2(DocumentEvent)
+   */
+  public IRegion documentChanged2(DocumentEvent event) {
+    int first = fixupPartitions(event);
+
+    FlatNode[] category = (FlatNode[]) nodes.toArray(new FlatNode[nodes.size()]);
+
+    // repartition changed region
+
+    String contentType = IDocument.DEFAULT_CONTENT_TYPE;
+
+    int offset;
+
+    if (first == 0) {
+      offset = 0; // Bug #697414: first offset
+    } else {
+      offset = event.getOffset();
+
+      FlatNode partition = category[first - 1];
+      if (partition.includes(offset)) {
+        offset = partition.offset;
+        contentType = partition.type;
+        --first;
+      } else if (offset == partition.offset + partition.length) {
+        offset = partition.offset;
+        contentType = partition.type;
+        --first;
+      } else {
+        offset = partition.offset + partition.length;
+      }
+    }
+
+    // should not be changed since last conversion
+    // category = (FlatNode[]) nodes.toArray(new FlatNode[nodes.size()]);
+    if (DEBUG) {
+      Assert.isTrue(offset >= 0, Integer.toString(offset));
+    }
+    scanner.setPartialRange(document, offset, document.getLength(), contentType, offset);
+
+    int lastScannedPosition = offset;
+    IToken token = scanner.nextToken();
+    while (!token.isEOF()) {
+      contentType = getTokenContentType(token);
+
+      if (!isSupportedContentType(contentType)) {
+        token = scanner.nextToken();
+        continue;
+      }
+
+      offset = scanner.getTokenOffset();
+      if (DEBUG) {
+        Assert.isTrue(offset >= 0, scanner.toString());
+      }
+      int length = scanner.getTokenLength();
+
+      lastScannedPosition = offset + length;
+
+      // remove all affected positions
+      while (first < category.length) {
+        FlatNode p = category[first];
+        if (p.offset + p.length < lastScannedPosition
+            || (p.overlapsWith(offset, length) && (!containsPosition(offset, length) || !contentType.equals(p.type)))) {
+          removeInnerRegion(p);
+          rememberRegion(p.offset, p.length);
+          ++first;
+        } else {
+          break;
+        }
+      }
+
+      // if position already exists we are done
+      if (containsPosition(offset, length)) {
+        if (lastScannedPosition > event.getOffset()) {
+          // TODO: optional repartition till end of doc
+          return createRegion();
+        }
+
+        ++first;
+      } else {
+        // insert the new type position
+        addInnerRegion(createNode(contentType, offset, length));
+        rememberRegion(offset, length);
+      }
+      //            try {
+      token = scanner.nextToken();
+      //            } catch (ArrayIndexOutOfBoundsException e) {
+      //              System.out.println(this.getClass().toString());
+      //              throw e;
+      //            }
+    }
+
+    // remove all positions behind lastScannedPosition
+    // since there aren't any further types
+
+    // Do not need to recalculate (lost remove events)!
+    // first = computeIndexInInnerDocuments(lastScannedPosition);
+    while (first < category.length) {
+      FlatNode p = category[first++];
+      removeInnerRegion(p);
+      rememberRegion(p.offset, p.length);
+    }
+
+    return createRegion();
+  }
+
+  protected int fixupPartitions(DocumentEvent event) {
+    int offset = event.getOffset();
+    int length = event.getLength();
+    int end = offset + length;
+
+    // fixup flat nodes laying on change boundaries
+
+    int first = computeFlatNodeIndex(offset);
+    if (first > 0) {
+      FlatNode p = (FlatNode) nodes.get(first - 1);
+
+      int right = p.offset + p.length;
+      if (offset < right) {
+        // change overlaps with partition
+        if (end < right) {
+          // cahnge completely inside partition
+          String text = event.getText();
+          p.length -= length;
+          if (text != null) {
+            p.length += text.length();
+          }
+        } else {
+          // cut partition at right
+          int cut = p.offset + p.length - offset;
+          p.length -= cut;
+        }
+      }
+    }
+
+    int last = computeFlatNodeIndex(end);
+    if (first < last) {
+      FlatNode p = (FlatNode) nodes.get(last - 1);
+
+      int right = p.offset + p.length;
+      if (end < right) {
+        // cut partition at left
+        int cut = end - p.offset;
+        p.length -= cut;
+        p.offset = offset;
+
+        String text = event.getText();
+        if (text != null) {
+          p.offset += text.length();
+        }
+
+        --last;
+      }
+    }
+
+    // fixup flat nodes laying afrer change
+
+    String text = event.getText();
+    if (text != null) {
+      length -= text.length();
+    }
+
+    for (int i = last, size = nodes.size(); i < size; i++) {
+      ((FlatNode) nodes.get(i)).offset -= length;
+    }
+
+    // delete flat nodes laying completely inside change boundaries
+
+    if (first < last) {
+      do {
+        deleteInnerRegion((FlatNode) nodes.get(--last));
+      } while (first < last);
+
+      rememberRegion(offset, 0);
+    }
+
+    return first;
+  }
+
+  /**
+   * Returns whether the given type is one of the legal content types.
+   * 
+   * @param contentType
+   *          the content type to check
+   * @return true if the content type is a legal content type
+   */
+  protected boolean isSupportedContentType(String contentType) {
+    /* TODO: implementation */
+    //		if (contentType != null) {
+    //			for (int i= 0; i < fLegalContentTypes.length; i++) {
+    //				if (fLegalContentTypes[i].equals(contentType)) {
+    //					return true;
+    //				}
+    //			}
+    //		}
+    //		return false;
+    return (contentType != null);
+  }
+
+  /**
+   * Returns a content type encoded in the given token. If the token's data is not null and a string it is assumed
+   * that it is the encoded content type.
+   * 
+   * @param token
+   *          the token whose content type is to be determined
+   * @return the token's content type
+   */
+  protected String getTokenContentType(IToken token) {
+    Object data = token.getData();
+    if (data instanceof String) {
+      return (String) data;
+    }
+
+    return null;
+  }
+
+  /*
+   * @see org.eclipse.jface.text.IDocumentPartitioner#getLegalContentTypes()
+   */
+  public String[] getLegalContentTypes() {
+    // TODO: implementation
+    return null;
+  }
+
+  /*
+   * @see org.eclipse.jface.text.IDocumentPartitioner#getContentType(int)
+   */
+  public String getContentType(int offset) {
+    return getPartition(offset).getType();
+  }
+
+  /*
+   * @see org.eclipse.jface.text.IDocumentPartitioner#getPartition(int)
+   */
+  public ITypedRegion getPartition(int offset) {
+    if (nodes.size() == 0) {
+      return new TypedRegion(0, document.getLength(), IDocument.DEFAULT_CONTENT_TYPE);
+    }
+
+    int index = computeFlatNodeIndex(offset);
+    if (index < nodes.size()) {
+      FlatNode next = (FlatNode) nodes.get(index);
+
+      if (offset == next.offset) {
+        return new TypedRegion(next.offset, next.length, next.type);
+      }
+
+      if (index == 0) {
+        return new TypedRegion(0, next.offset, IDocument.DEFAULT_CONTENT_TYPE);
+      }
+
+      FlatNode prev = (FlatNode) nodes.get(index - 1);
+
+      if (prev.includes(offset)) {
+        return new TypedRegion(prev.offset, prev.length, prev.type);
+      }
+
+      int end = prev.offset + prev.length;
+      return new TypedRegion(end, next.offset - end, IDocument.DEFAULT_CONTENT_TYPE);
+    }
+
+    FlatNode prev = (FlatNode) nodes.get(nodes.size() - 1);
+
+    if (prev.includes(offset)) {
+      return new TypedRegion(prev.offset, prev.length, prev.type);
+    }
+
+    int end = prev.offset + prev.length;
+
+    return new TypedRegion(end, document.getLength() - end, IDocument.DEFAULT_CONTENT_TYPE);
+  }
+
+  /*
+   * @see org.eclipse.jface.text.IDocumentPartitioner#computePartitioning(int, int)
+   */
+  public ITypedRegion[] computePartitioning(int offset, int length) {
+    List list = new ArrayList();
+
+    int end = offset + length;
+
+    int index = computeFlatNodeIndex(offset);
+    while (true) {
+      FlatNode prev = (index > 0) ? (FlatNode) nodes.get(index - 1) : null;
+
+      if (prev != null) {
+        if (prev.overlapsWith(offset, length)) {
+          list.add(new TypedRegion(prev.offset, prev.length, prev.type));
+        }
+
+        if (end <= prev.offset + prev.length) {
+          break;
+        }
+      }
+
+      FlatNode next = (index < nodes.size()) ? (FlatNode) nodes.get(index) : null;
+
+      if (next == null || offset < next.offset) {
+        int off0 = offset;
+        int off1 = offset + length;
+
+        if (prev != null && off0 < prev.offset + prev.length) {
+          off0 = prev.offset + prev.length;
+        }
+
+        if (next != null && next.offset < off1) {
+          off1 = next.offset;
+        }
+
+        if (off0 < off1) {
+          list.add(new TypedRegion(off0, off1 - off0, IDocument.DEFAULT_CONTENT_TYPE));
+        }
+      }
+
+      if (next == null) {
+        break;
+      }
+
+      ++index;
+    }
+
+    return (TypedRegion[]) list.toArray(new TypedRegion[list.size()]);
+  }
+
+  /**
+   * Computes the index in the list of flat nodes at which an flat node with the given offset would be inserted. The flat node is
+   * supposed to become the first in this list of all flat nodes with the same offset.
+   * 
+   * @param offset
+   *          the offset for which the index is computed
+   * @return the computed index
+   */
+  protected int computeFlatNodeIndex(int offset) {
+    if (nodes.size() == 0) {
+      return 0;
+    }
+
+    int left = 0, mid = 0;
+    int right = nodes.size() - 1;
+
+    FlatNode p = null;
+
+    while (left < right) {
+      mid = (left + right) / 2;
+
+      p = (FlatNode) nodes.get(mid);
+
+      if (offset < p.offset) {
+        right = (left == mid) ? left : mid - 1;
+      } else if (offset > p.offset) {
+        left = (right == mid) ? right : mid + 1;
+      } else if (offset == p.offset) {
+        left = right = mid;
+      }
+    }
+
+    int pos = left;
+    p = (FlatNode) nodes.get(pos);
+    if (offset > p.offset) {
+      // append to the end
+      pos++;
+    } else {
+      // entry will became the first of all entries with the same offset
+      do {
+        --pos;
+        if (pos < 0) {
+          break;
+        }
+        p = (FlatNode) nodes.get(pos);
+      } while (offset == p.offset);
+      ++pos;
+    }
+
+    return pos;
+  }
+
+  public boolean containsPosition(int offset, int length) {
+    int size = nodes.size();
+    if (size == 0) {
+      return false;
+    }
+
+    int index = computeFlatNodeIndex(offset);
+    if (index < size) {
+      FlatNode p = (FlatNode) nodes.get(index);
+
+      while (p.offset == offset) {
+        if (p.length == length) {
+          return true;
+        }
+
+        if (++index < size) {
+          p = (FlatNode) nodes.get(index);
+        } else {
+          break;
+        }
+      }
+    }
+
+    return false;
+  }
+
+  /**
+   * Helper method for tracking the minimal region containg all partition changes. If offset is smaller than the
+   * remembered offset, offset will from now on be remembered. If offset + length is greater than the
+   * remembered end offset, it will be remembered from now on.
+   * 
+   * @param offset
+   *          the offset
+   * @param length
+   *          the length
+   */
+  protected final void rememberRegion(int offset, int length) {
+    // remember start offset
+    if (regionStart == -1) {
+      regionStart = offset;
+    } else if (offset < regionStart) {
+      regionStart = offset;
+    }
+
+    // remember end offset
+    int endOffset = offset + length;
+
+    if (regionEnd == -1) {
+      regionEnd = endOffset;
+    } else if (endOffset > regionEnd) {
+      regionEnd = endOffset;
+    }
+  }
+
+  /**
+   * Creates the minimal region containing all partition changes using the remembered offsets.
+   * 
+   * @return the minimal region containing all the partition changes
+   */
+  protected final IRegion createRegion() {
+    if (regionStart == -1 || regionEnd == -1) {
+      return null;
+    }
+
+    return new Region(regionStart, regionEnd - regionStart);
+  }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/text/rules/FlatNode.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/text/rules/FlatNode.java
new file mode 100644
index 0000000..93c6452
--- /dev/null
+++ b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/text/rules/FlatNode.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2003-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://solareclipse.sourceforge.net/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ * 
+ * $Id: FlatNode.java,v 1.1 2004-09-02 18:26:29 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.ui.text.rules;
+
+/**
+ * @author Igor Malinin
+ */
+public class FlatNode {
+
+	/** Content-type of the node */
+	public final String type;
+
+	/** Flat offset of the node */
+	public int offset;
+
+	/** Flat length of the node */
+	public int length;
+
+	public FlatNode(String type) {
+		this.type = type;
+	}
+
+	/**
+	 * Checks whether the given offset is inside of this position's text range.
+	 * 
+	 * @param offset
+	 *            the offset to check
+	 * @return true if offset is inside of this position
+	 */
+	public boolean includes(int offset) {
+		return (this.offset <= offset && offset < this.offset + length);
+	}
+
+	/**
+	 * Checks whether the intersection of the given text range and the text
+	 * range represented by this position is empty or not.
+	 * 
+	 * @param offset
+	 *            the offset of the range to check
+	 * @param length
+	 *            the length of the range to check
+	 * @return true if intersection is not empty
+	 */
+	public boolean overlapsWith(int offset, int length) {
+		int end = offset + length;
+		int thisEnd = this.offset + this.length;
+
+		if (length > 0) {
+			if (this.length > 0) {
+				return (this.offset < end && offset < thisEnd);
+			}
+			return (offset <= this.offset && this.offset < end);
+		}
+
+		if (this.length > 0) {
+			return (this.offset <= offset && offset < thisEnd);
+		}
+
+		return (this.offset == offset);
+	}
+
+	/*
+	 * @see java.lang.Object#toString()
+	 */
+	public String toString() {
+		return "FlatNode[" + type + ", " + offset + ", " + length + "]";
+	}
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/text/rules/IDocumentView.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/text/rules/IDocumentView.java
new file mode 100644
index 0000000..2ec3410
--- /dev/null
+++ b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/text/rules/IDocumentView.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://solareclipse.sourceforge.net/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ * 
+ * $Id: IDocumentView.java,v 1.1 2004-09-02 18:26:29 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.ui.text.rules;
+
+import org.eclipse.jface.text.IDocument;
+
+/**
+ * View to part of parent document. Provides methods for translating character
+ * offsets between this view and parent document.
+ * 
+ * @author Igor Malinin
+ */
+public interface IDocumentView extends IDocument {
+
+	IDocument getParentDocument();
+
+	int getParentOffset(int localOffset);
+
+	int getLocalOffset(int parentOffset);
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/text/rules/InnerDocumentView.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/text/rules/InnerDocumentView.java
new file mode 100644
index 0000000..70cb17e
--- /dev/null
+++ b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/text/rules/InnerDocumentView.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://solareclipse.sourceforge.net/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ * 
+ * $Id: InnerDocumentView.java,v 1.1 2004-09-02 18:26:29 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.ui.text.rules;
+
+import org.eclipse.jface.text.AbstractDocument;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DefaultLineTracker;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextStore;
+
+/**
+ * Inner view to parent document.
+ * 
+ * @author Igor Malinin
+ */
+public class InnerDocumentView extends AbstractDocument implements
+		IDocumentView {
+
+	/**
+	 * Implements ITextStore based on IDocument.
+	 */
+	class TextStore implements ITextStore {
+
+		/*
+		 * @see ITextStore#set
+		 */
+		public void set(String txt) {
+			try {
+				parent.replace(range.offset, range.length, txt);
+			} catch (BadLocationException x) {
+			}
+		}
+
+		/*
+		 * @see ITextStore#replace
+		 */
+		public void replace(int offset, int length, String txt) {
+			try {
+				parent.replace(range.offset + offset, length, txt);
+			} catch (BadLocationException x) {
+			}
+		}
+
+		/*
+		 * @see ITextStore#getLength
+		 */
+		public int getLength() {
+			return range.length;
+		}
+
+		/*
+		 * @see ITextStore#get
+		 */
+		public String get(int offset, int length) {
+			try {
+				return parent.get(range.offset + offset, length);
+			} catch (BadLocationException x) {
+			}
+
+			return null;
+		}
+
+		/*
+		 * @see ITextStore#get
+		 */
+		public char get(int offset) {
+			try {
+				return parent.getChar(range.offset + offset);
+			} catch (BadLocationException x) {
+			}
+
+			return (char) 0;
+		}
+	}
+
+	/** The parent document */
+	IDocument parent;
+
+	/** The section inside the parent document */
+	ViewNode range;
+
+	/**
+	 * Constructs inner view to parent document.
+	 * 
+	 * @param parent
+	 *            parent document
+	 * @param range
+	 */
+	public InnerDocumentView(IDocument parent, ViewNode range) {
+		this.parent = parent;
+		this.range = range;
+
+		setTextStore(new TextStore());
+		setLineTracker(new DefaultLineTracker());
+		getTracker().set(getStore().get(0, getLength()));
+		completeInitialization();
+	}
+
+	/*
+	 * @see net.sourceforge.phpeclipse.text.rules.IDocumentView#getParentDocument()
+	 */
+	public IDocument getParentDocument() {
+		return parent;
+	}
+
+	/*
+	 * @see org.eclipse.jface.text.AbstractDocument#fireDocumentAboutToBeChanged(DocumentEvent)
+	 */
+	protected void fireDocumentAboutToBeChanged(DocumentEvent event) {
+		super.fireDocumentAboutToBeChanged(event);
+	}
+
+	/*
+	 * @see org.eclipse.jface.text.AbstractDocument#fireDocumentChanged(DocumentEvent)
+	 */
+	protected void fireDocumentChanged(DocumentEvent event) {
+		try {
+			// TODO: move to a better place
+			getTracker().replace(event.getOffset(), event.getLength(),
+					event.getText());
+		} catch (BadLocationException x) {
+		}
+
+		super.fireDocumentChanged(event);
+	}
+
+	/*
+	 * @see net.sf.wdte.text.rules.IDocumentView#getParentOffset(int)
+	 */
+	public int getParentOffset(int localOffset) {
+		return localOffset + range.offset;
+	}
+
+	/*
+	 * @see net.sf.wdte.text.rules.IDocumentView#getLocalOffset(int)
+	 */
+	public int getLocalOffset(int parentOffset) {
+		return parentOffset - range.offset;
+	}
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/text/rules/MultiViewPartitioner.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/text/rules/MultiViewPartitioner.java
new file mode 100644
index 0000000..c5aa8ec
--- /dev/null
+++ b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/text/rules/MultiViewPartitioner.java
@@ -0,0 +1,656 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://solareclipse.sourceforge.net/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ * 
+ * $Id: MultiViewPartitioner.java,v 1.1 2004-09-02 18:26:29 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.ui.text.rules;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentPartitioner;
+import org.eclipse.jface.text.IDocumentPartitioningListener;
+import org.eclipse.jface.text.IDocumentPartitioningListenerExtension;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.TypedRegion;
+import org.eclipse.jface.text.rules.IPartitionTokenScanner;
+
+/**
+ * Advanced partitioner which maintains partitions as views to connected document. Views have own partitioners themselves. This
+ * class is designed as a base for complex partitioners such as for JSP, PHP, ASP, etc. languages.
+ * 
+ * @author Igor Malinin
+ */
+public abstract class MultiViewPartitioner extends AbstractPartitioner {
+
+  class ViewListener implements IDocumentPartitioningListener, IDocumentPartitioningListenerExtension {
+
+    /*
+     * @see org.eclipse.jface.text.IDocumentPartitioningListener#documentPartitioningChanged(IDocument)
+     */
+    public void documentPartitioningChanged(IDocument document) {
+      IDocumentView view = (IDocumentView) document;
+
+      int start = view.getParentOffset(0);
+      int end = view.getParentOffset(view.getLength());
+
+      rememberRegion(start, end - start);
+    }
+
+    /*
+     * @see org.eclipse.jface.text.IDocumentPartitioningListenerExtension#documentPartitioningChanged(IDocument, IRegion)
+     */
+    public void documentPartitioningChanged(IDocument document, IRegion region) {
+      IDocumentView view = (IDocumentView) document;
+
+      int offset = region.getOffset();
+
+      int start = view.getParentOffset(offset);
+      int end = view.getParentOffset(offset + region.getLength());
+
+      rememberRegion(start, end - start);
+    }
+  }
+
+  private ViewListener viewListener = new ViewListener();
+
+  private OuterDocumentView outerDocument;
+
+  private DocumentEvent outerDocumentEvent;
+
+  public MultiViewPartitioner(IPartitionTokenScanner scanner) {
+    super(scanner);
+  }
+
+  public void setOuterPartitioner(IDocumentPartitioner partitioner) {
+    if (outerDocument == null) {
+      if (partitioner == null) {
+        return;
+      }
+
+      outerDocument = new OuterDocumentView(document, nodes);
+      outerDocument.addDocumentPartitioningListener(viewListener);
+    }
+
+    IDocumentPartitioner old = outerDocument.getDocumentPartitioner();
+    if (old != null) {
+      outerDocument.setDocumentPartitioner(null);
+      old.disconnect();
+    }
+
+    if (partitioner != null) {
+      partitioner.connect(outerDocument);
+    }
+
+    outerDocument.setDocumentPartitioner(partitioner);
+
+    if (partitioner == null) {
+      outerDocument.removeDocumentPartitioningListener(viewListener);
+      outerDocument = null;
+    }
+  }
+
+  /**
+   * Create subpartitioner.
+   * 
+   * @param contentType
+   *          name of inner partition or null for outer partition
+   */
+  protected abstract IDocumentPartitioner createPartitioner(String contentType);
+
+  protected void addInnerRegion(FlatNode position) {
+    if (outerDocument != null) {
+      if (DEBUG) {
+        Assert.isTrue(position.offset >= 0, Integer.toString(position.offset));
+      }
+      DocumentEvent event = new DocumentEvent(outerDocument, outerDocument.getLocalOffset(position.offset), position.length, null);
+
+      outerDocument.fireDocumentAboutToBeChanged(event);
+      super.addInnerRegion(position);
+      outerDocument.fireDocumentChanged(event);
+    } else {
+      super.addInnerRegion(position);
+    }
+
+    if (position instanceof ViewNode) {
+      // TODO: revisit condition
+      IDocumentPartitioner partitioner = createPartitioner(position.type);
+      if (partitioner != null) {
+        InnerDocumentView innerDocument = new InnerDocumentView(document, (ViewNode) position);
+
+        ((ViewNode) position).view = innerDocument;
+
+        partitioner.connect(innerDocument);
+        innerDocument.setDocumentPartitioner(partitioner);
+        innerDocument.addDocumentPartitioningListener(viewListener);
+      }
+    }
+  }
+
+  protected void removeInnerRegion(FlatNode position) {
+    try {
+      if (outerDocument != null) {
+        DocumentEvent event = null;
+        if (position.offset >= 0) {
+          event = new DocumentEvent(outerDocument, outerDocument.getLocalOffset(position.offset), 0, document.get(position.offset,
+              position.length));
+
+          outerDocument.fireDocumentAboutToBeChanged(event);
+        }
+        super.removeInnerRegion(position);
+        if (position.offset >= 0) {
+          outerDocument.fireDocumentChanged(event);
+        }
+      } else {
+        super.removeInnerRegion(position);
+      }
+
+      if (position instanceof ViewNode) {
+        // TODO: revisit condition
+        InnerDocumentView innerDocument = ((ViewNode) position).view;
+        if (innerDocument != null) {
+          IDocumentPartitioner partitioner = innerDocument.getDocumentPartitioner();
+
+          innerDocument.removeDocumentPartitioningListener(viewListener);
+          innerDocument.setDocumentPartitioner(null);
+          partitioner.disconnect();
+        }
+      }
+    } catch (BadLocationException e) {
+    }
+  }
+
+  protected void deleteInnerRegion(FlatNode position) {
+    super.deleteInnerRegion(position);
+
+    if (position instanceof ViewNode) {
+      // TODO: revisit condition
+      InnerDocumentView innerDocument = ((ViewNode) position).view;
+      if (innerDocument != null) {
+        IDocumentPartitioner partitioner = innerDocument.getDocumentPartitioner();
+
+        innerDocument.removeDocumentPartitioningListener(viewListener);
+        innerDocument.setDocumentPartitioner(null);
+        partitioner.disconnect();
+      }
+    }
+  }
+
+  public void connect(IDocument document) {
+    //		outerDocument = new OuterDocumentView(document, innerPositions);
+
+    super.connect(document);
+
+    setOuterPartitioner(createPartitioner(null));
+    //		IDocumentPartitioner partitioner =
+    //			partitioner.connect(outerDocument);
+    //		outerDocument.setDocumentPartitioner(partitioner);
+    //		outerDocument.addDocumentPartitioningListener(viewListener);
+  }
+
+  public void disconnect() {
+    try {
+      if (outerDocument != null) {
+        outerDocument.removeDocumentPartitioningListener(viewListener);
+
+        IDocumentPartitioner partitioner = outerDocument.getDocumentPartitioner();
+
+        outerDocument.setDocumentPartitioner(null);
+        partitioner.disconnect();
+      }
+    } finally {
+      // TODO: cleanup listeners
+      outerDocument = null;
+    }
+  }
+
+  /*
+   * @see org.eclipse.jface.text.IDocumentPartitioner#documentAboutToBeChanged(DocumentEvent)
+   */
+  public void documentAboutToBeChanged(DocumentEvent event) {
+    super.documentAboutToBeChanged(event);
+
+    outerDocumentEvent = null;
+
+    int offset = event.getOffset();
+    int length = event.getLength();
+    int end = offset + length;
+
+    // find left partition
+    int first = computeFlatNodeIndex(offset);
+    if (first > 0) {
+      FlatNode p = (FlatNode) nodes.get(first - 1);
+
+      int right = p.offset + p.length;
+      if (offset < right) {
+        // change overlaps with partition
+        InnerDocumentView innerDocument = null;
+        if (p instanceof ViewNode) {
+          // TODO: revisit condition
+          innerDocument = ((ViewNode) p).view;
+        }
+
+        if (end < right) {
+          if (innerDocument != null) {
+            // cahnge completely inside partition
+            int start = innerDocument.getLocalOffset(offset);
+            innerDocument.fireDocumentAboutToBeChanged(new DocumentEvent(innerDocument, start, length, event.getText()));
+          }
+
+          return;
+        }
+
+        if (innerDocument != null) {
+          // cut partition at right
+          int start = innerDocument.getLocalOffset(offset);
+          innerDocument.fireDocumentAboutToBeChanged(new DocumentEvent(innerDocument, start, innerDocument.getLength() - start,
+              null));
+        }
+      }
+    }
+
+    // find right partition
+    int last = computeFlatNodeIndex(end);
+    if (last > 0) {
+      FlatNode p = (FlatNode) nodes.get(last - 1);
+
+      if (p instanceof ViewNode) {
+        // TODO: revisit condition
+        InnerDocumentView innerDocument = ((ViewNode) p).view;
+        if (innerDocument != null) {
+          int right = p.offset + p.length;
+          if (end < right) {
+            // cut partition at left
+            int cut = innerDocument.getLocalOffset(end);
+            innerDocument.fireDocumentAboutToBeChanged(new DocumentEvent(innerDocument, 0, cut, null));
+          }
+        }
+      }
+    }
+
+    if (outerDocument != null) {
+      int left = outerDocument.getLocalOffset(offset);
+      int right = outerDocument.getLocalOffset(end);
+
+      String text = event.getText();
+
+      if (left != right || text != null && text.length() > 0) {
+        outerDocumentEvent = new DocumentEvent(outerDocument, left, right - left, text);
+
+        outerDocument.fireDocumentAboutToBeChanged(outerDocumentEvent);
+      }
+    }
+  }
+
+  protected int fixupPartitions(DocumentEvent event) {
+    int offset = event.getOffset();
+    int length = event.getLength();
+    int end = offset + length;
+
+    // fixup/notify inner views laying on change boundaries
+
+    int first = computeFlatNodeIndex(offset);
+    if (first > 0) {
+      FlatNode p = (FlatNode) nodes.get(first - 1);
+
+      int right = p.offset + p.length;
+      if (offset < right) {
+        // change overlaps with partition
+        if (end < right) {
+          // cahnge completely inside partition
+          String text = event.getText();
+          p.length -= length;
+          if (text != null) {
+            p.length += text.length();
+          }
+
+          if (p instanceof ViewNode) {
+            // TODO: revisit condition
+            InnerDocumentView innerDocument = ((ViewNode) p).view;
+            if (innerDocument != null) {
+              int start = innerDocument.getLocalOffset(offset);
+              innerDocument.fireDocumentChanged(new DocumentEvent(innerDocument, start, length, text));
+            }
+          }
+        } else {
+          // cut partition at right
+          int cut = p.offset + p.length - offset;
+          p.length -= cut;
+
+          if (p instanceof ViewNode) {
+            // TODO: revisit condition
+            InnerDocumentView innerDocument = ((ViewNode) p).view;
+            if (innerDocument != null) {
+              int start = innerDocument.getLocalOffset(offset);
+              // TODO: ???fireDocumentAboutToBeChanged???
+              innerDocument.fireDocumentChanged(new DocumentEvent(innerDocument, start, cut, null));
+            }
+          }
+        }
+      }
+    }
+
+    int last = computeFlatNodeIndex(end);
+    if (last > 0 && first != last) {
+      FlatNode p = (FlatNode) nodes.get(last - 1);
+
+      int right = p.offset + p.length;
+      if (end < right) {
+        // cut partition at left
+        int cut = end - p.offset;
+        p.length -= cut;
+        p.offset = offset;
+
+        String text = event.getText();
+        if (text != null) {
+          p.offset += text.length();
+        }
+
+        if (p instanceof ViewNode) {
+          // TODO: revisit condition
+          InnerDocumentView innerDocument = ((ViewNode) p).view;
+          if (innerDocument != null) {
+            // TODO: ???fireDocumentAboutToBeChanged???
+            innerDocument.fireDocumentChanged(new DocumentEvent(innerDocument, 0, cut, null));
+          }
+        }
+
+        --last;
+      }
+    }
+
+    // fixup inner views laying afrer change
+
+    String text = event.getText();
+    if (text != null) {
+      length -= text.length();
+    }
+
+    for (int i = last, size = nodes.size(); i < size; i++) {
+      ((FlatNode) nodes.get(i)).offset -= length;
+    }
+
+    // delete inner views laying completely inside change boundaries
+
+    if (first < last) {
+      do {
+        deleteInnerRegion((FlatNode) nodes.get(--last));
+      } while (first < last);
+
+      rememberRegion(offset, 0);
+    }
+
+    // notify outer view
+
+    if (outerDocumentEvent != null) {
+      outerDocument.fireDocumentChanged(outerDocumentEvent);
+    }
+
+    return first;
+  }
+
+  /*
+   * @see org.eclipse.jface.text.IDocumentPartitioner#computePartitioning(int, int)
+   */
+  protected String getContentType(String parent, String view) {
+    if (view != null) {
+      return view;
+    }
+
+    if (parent != null) {
+      return parent;
+    }
+
+    return IDocument.DEFAULT_CONTENT_TYPE;
+  }
+
+  /*
+   * @see org.eclipse.jface.text.IDocumentPartitioner#computePartitioning(int, int)
+   */
+  public ITypedRegion[] computePartitioning(int offset, int length) {
+    List list = new ArrayList();
+
+    int end = offset + length;
+
+    int index = computeFlatNodeIndex(offset);
+    while (true) {
+      FlatNode prev = (index > 0) ? (FlatNode) nodes.get(index - 1) : null;
+
+      if (prev != null) {
+        if (prev.overlapsWith(offset, length)) {
+          addInnerPartitions(list, offset, length, prev);
+        }
+
+        if (end <= prev.offset + prev.length) {
+          break;
+        }
+      }
+
+      FlatNode next = (index < nodes.size()) ? (FlatNode) nodes.get(index) : null;
+
+      if (next == null || offset < next.offset) {
+        addOuterPartitions(list, offset, length, prev, next);
+      }
+
+      if (next == null) {
+        break;
+      }
+
+      ++index;
+    }
+
+    return (TypedRegion[]) list.toArray(new TypedRegion[list.size()]);
+  }
+
+  private void addOuterPartitions(List list, int offset, int length, FlatNode prev, FlatNode next) {
+    // limit region
+    int start = offset;
+    int end = offset + length;
+
+    if (prev != null && start < prev.offset + prev.length) {
+      start = prev.offset + prev.length;
+    }
+
+    if (next != null && next.offset < end) {
+      end = next.offset;
+    }
+
+    if (start == end) {
+      return;
+    }
+
+    if (outerDocument == null) {
+      list.add(new TypedRegion(start, end - start, getContentType(null, IDocument.DEFAULT_CONTENT_TYPE)));
+      return;
+    }
+
+    try {
+      // convert to outer offsets
+      start = outerDocument.getLocalOffset(start);
+      end = outerDocument.getLocalOffset(end);
+      if (end - start >= 0) {//jsurfer insert line
+        ITypedRegion[] regions = outerDocument.computePartitioning(start, end - start);
+
+        for (int i = 0; i < regions.length; i++) {
+          ITypedRegion region = regions[i];
+
+          // convert back to parent offsets
+          start = outerDocument.getParentOffset(region.getOffset());
+          end = start + region.getLength();
+
+          if (prev != null) {
+            offset = prev.offset + prev.length;
+            if (start < offset) {
+              start = offset;
+            }
+          }
+
+          if (next != null) {
+            offset = next.offset;
+            if (offset < end) {
+              end = offset;
+            }
+          }
+
+          list.add(new TypedRegion(start, end - start, getContentType(null, region.getType())));
+        }
+      }
+    } catch (BadLocationException x) {
+    }
+  }
+
+  private void addInnerPartitions(List list, int offset, int length, FlatNode position) {
+    InnerDocumentView innerDocument = null;
+    if (position instanceof ViewNode) {
+      // TODO: revisit condition
+      innerDocument = ((ViewNode) position).view;
+    }
+
+    if (innerDocument == null) {
+      // simple partition
+      list.add(new TypedRegion(position.offset, position.length, getContentType(position.type, null)));
+      return;
+    }
+
+    // multiplexing to inner view
+    try {
+      // limit region
+      int start = Math.max(offset, position.offset);
+      int end = Math.min(offset + length, position.offset + position.length);
+
+      // convert to document offsets
+      length = end - start;
+      offset = innerDocument.getLocalOffset(start);
+
+      ITypedRegion[] regions = innerDocument.computePartitioning(offset, length);
+
+      for (int i = 0; i < regions.length; i++) {
+        ITypedRegion region = regions[i];
+
+        // convert back to parent offsets
+        offset = innerDocument.getParentOffset(region.getOffset());
+        length = region.getLength();
+
+        list.add(new TypedRegion(offset, length, getContentType(position.type, region.getType())));
+      }
+    } catch (BadLocationException x) {
+    }
+  }
+
+  /*
+   * @see org.eclipse.jface.text.IDocumentPartitioner#getPartition(int)
+   */
+  public ITypedRegion getPartition(int offset) {
+    if (nodes.size() == 0) {
+      return getOuterPartition(offset, null, null);
+    }
+
+    int index = computeFlatNodeIndex(offset);
+    if (index < nodes.size()) {
+      FlatNode next = (FlatNode) nodes.get(index);
+
+      if (offset == next.offset) {
+        return getInnerPartition(offset, next);
+      }
+
+      if (index == 0) {
+        return getOuterPartition(offset, null, next);
+      }
+
+      FlatNode prev = (FlatNode) nodes.get(index - 1);
+
+      if (prev.includes(offset)) {
+        return getInnerPartition(offset, prev);
+      }
+
+      return getOuterPartition(offset, prev, next);
+    }
+
+    FlatNode prev = (FlatNode) nodes.get(nodes.size() - 1);
+
+    if (prev.includes(offset)) {
+      return getInnerPartition(offset, prev);
+    }
+
+    return getOuterPartition(offset, prev, null);
+  }
+
+  protected ITypedRegion getOuterPartition(int offset, FlatNode prev, FlatNode next) {
+    try {
+      int start, end;
+      String type;
+
+      if (outerDocument == null) {
+        start = 0;
+        end = document.getLength();
+        type = getContentType(null, IDocument.DEFAULT_CONTENT_TYPE);
+      } else {
+        ITypedRegion region = outerDocument.getPartition(outerDocument.getLocalOffset(offset));
+
+        start = region.getOffset();
+        end = start + region.getLength();
+
+        // convert to parent offset
+        start = outerDocument.getParentOffset(start);
+        end = outerDocument.getParentOffset(end);
+
+        type = getContentType(null, region.getType());
+      }
+
+      if (prev != null) {
+        offset = prev.offset + prev.length;
+        if (start < offset) {
+          start = offset;
+        }
+      }
+
+      if (next != null) {
+        offset = next.offset;
+        if (offset < end) {
+          end = offset;
+        }
+      }
+
+      return new TypedRegion(start, end - start, type);
+    } catch (BadLocationException x) {
+      throw new IllegalArgumentException();
+    }
+  }
+
+  protected ITypedRegion getInnerPartition(int offset, FlatNode position) {
+    if (position instanceof ViewNode) {
+      // TODO: revisit condition
+      InnerDocumentView innerDocument = ((ViewNode) position).view;
+
+      if (innerDocument != null) {
+        // multiplexing to inner view
+        try {
+          // convert to inner offset
+          ITypedRegion region = innerDocument.getPartition(innerDocument.getLocalOffset(offset));
+
+          // convert to parent offset
+          offset = innerDocument.getParentOffset(region.getOffset());
+
+          return new TypedRegion(offset, region.getLength(), getContentType(position.type, region.getType()));
+        } catch (BadLocationException x) {
+        }
+      }
+    }
+
+    // simple partition
+    return new TypedRegion(position.offset, position.length, position.type);
+  }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/text/rules/OuterDocumentView.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/text/rules/OuterDocumentView.java
new file mode 100644
index 0000000..c438031
--- /dev/null
+++ b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/text/rules/OuterDocumentView.java
@@ -0,0 +1,272 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://solareclipse.sourceforge.net/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ * 
+ * $Id: OuterDocumentView.java,v 1.1 2004-09-02 18:26:29 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.ui.text.rules;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jface.text.AbstractDocument;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DefaultLineTracker;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextStore;
+
+/**
+ * Outer view to parent document.
+ * 
+ * @author Igor Malinin
+ */
+public class OuterDocumentView extends AbstractDocument implements
+		IDocumentView {
+
+	/**
+	 * Implements ITextStore based on IDocument.
+	 */
+	class TextStore implements ITextStore {
+
+		/*
+		 * @see ITextStore#set
+		 */
+		public void set(String txt) {
+			try {
+				parent.replace(0, parent.getLength(), txt);
+			} catch (BadLocationException x) {
+				// cannot happen
+			}
+		}
+
+		/*
+		 * @see ITextStore#replace
+		 */
+		public void replace(int offset, int length, String txt) {
+			try {
+				int start = getParentOffset(offset);
+				int end = getParentOffset(offset + length - 1) + 1;
+
+				parent.replace(start, end - start, txt);
+			} catch (BadLocationException x) {
+				// ignored as surrounding document should have handled this
+			}
+		}
+
+		/*
+		 * @see ITextStore#getLength
+		 */
+		public int getLength() {
+			int length = parent.getLength();
+
+			Iterator i = ranges.iterator();
+			while (i.hasNext()) {
+				length -= ((FlatNode) i.next()).length;
+			}
+
+			return length;
+		}
+
+		/*
+		 * @see ITextStore#get
+		 */
+		public String get(int offset, int length) {
+			StringBuffer buf = new StringBuffer(length);
+
+			try {
+				FlatNode range = null;
+
+				Iterator i = ranges.iterator();
+				while (i.hasNext()) {
+					range = (FlatNode) i.next();
+
+					if (offset < range.offset) {
+						break;
+					}
+
+					offset += range.length;
+
+					range = null;
+				}
+
+				int remainder = length - buf.length();
+				while (remainder > 0) {
+					if (range == null || offset + remainder < range.offset) {
+						buf.append(parent.get(offset, remainder));
+						break;
+					}
+
+					buf.append(parent.get(offset, range.offset - offset));
+					offset = range.offset + range.length;
+					range = i.hasNext() ? (FlatNode) i.next() : null;
+
+					remainder = length - buf.length();
+				}
+			} catch (BadLocationException x) {
+				return null;
+			}
+
+			return buf.toString();
+		}
+
+		/*
+		 * @see ITextStore#get
+		 */
+		public char get(int offset) {
+			try {
+				return parent.getChar(getParentOffset(offset));
+			} catch (BadLocationException x) {
+			}
+
+			return (char) 0;
+		}
+	}
+
+	/** The parent document */
+	IDocument parent;
+
+	/** The section inside the parent document */
+	List ranges;
+
+	/**
+	 * Constructs outer view to parent document.
+	 * 
+	 * @param parent
+	 *            parent document
+	 */
+	public OuterDocumentView(IDocument parent, List ranges) {
+		this.parent = parent;
+		this.ranges = ranges;
+
+		setTextStore(new TextStore());
+		setLineTracker(new DefaultLineTracker());
+		getTracker().set(getStore().get(0, getLength()));
+
+		completeInitialization();
+	}
+
+//	public void addRange(Position range) {
+//		DocumentEvent event = new DocumentEvent(this,
+//			getLocalOffset(range.offset), range.length, "");
+//		fireDocumentAboutToBeChanged(event);
+//		ranges.add(-getIndex(range) - 1, range);
+//		fireDocumentChanged(event);
+//	}
+//
+//	public void removeRange(Position range) {
+//		String text;
+//		try {
+//			text = parent.get(range.offset, range.length);
+//		} catch (BadLocationException e) {
+//			return;
+//		}
+//		DocumentEvent event = new DocumentEvent(this,
+//			getLocalOffset(range.offset), 0, text);
+//		fireDocumentAboutToBeChanged(event);
+//		deleteRange(range);
+//		fireDocumentChanged(event);
+//	}
+//
+//	public void deleteRange(Position range) {
+//		ranges.remove(getIndex(range));
+//	}
+//
+//	private int getIndex(Position range) {
+//		return Collections.binarySearch(ranges, range, new Comparator() {
+//			public int compare(Object o1, Object o2) {
+//				int offset1 = ((Position) o1).offset;
+//				int offset2 = ((Position) o2).offset;
+//
+//				if (offset1 < offset2) return -1;
+//				if (offset1 > offset2) return 1;
+//				return 0;
+//			}
+//		});
+//	}
+
+	/*
+	 * @see org.eclipse.jface.text.AbstractDocument#fireDocumentAboutToBeChanged(DocumentEvent)
+	 */
+	protected void fireDocumentAboutToBeChanged(DocumentEvent event) {
+		super.fireDocumentAboutToBeChanged(event);
+	}
+
+	/*
+	 * @see org.eclipse.jface.text.AbstractDocument#fireDocumentChanged(DocumentEvent)
+	 */
+	protected void fireDocumentChanged(DocumentEvent event) {
+		try {
+			// TODO: move to a better place
+			getTracker().replace(event.getOffset(), event.getLength(),
+					event.getText());
+		} catch (BadLocationException x) {
+		}
+
+		super.fireDocumentChanged(event);
+	}
+
+	/*
+	 * @see net.sourceforge.phpeclipse.text.rules.IDocumentView#getParentDocument()
+	 */
+	public IDocument getParentDocument() {
+		return parent;
+	}
+
+	/*
+	 * @see net.sourceforge.phpeclipse.text.rules.IDocumentView#getParentOffset(int)
+	 */
+	public int getParentOffset(int localOffset) {
+		int offset = localOffset;
+
+		Iterator i = ranges.iterator();
+		while (i.hasNext()) {
+			FlatNode range = (FlatNode) i.next();
+
+			if (offset < range.offset) {
+				break;
+			}
+
+			offset += range.length;
+		}
+
+		return offset;
+	}
+
+	/*
+	 * @see net.sf.wdte.text.rules.IDocumentView#getLocalOffset(int)
+	 */
+	public int getLocalOffset(int parentOffset) {
+//	    Assert.isTrue(parentOffset>=0);
+		int localOffset = parentOffset;
+
+		Iterator i = ranges.iterator();
+		while (i.hasNext()) {
+			FlatNode range = (FlatNode) i.next();
+
+			if (parentOffset <= range.offset) {
+				break;
+			}
+
+			if (parentOffset <= range.offset + range.length) {
+				localOffset -= parentOffset - range.offset;
+				break;
+			}
+
+			localOffset -= range.length;
+		}
+		// TODO jsurfer change start - check this
+//        if (localOffset<0) {
+//          return 0;
+//        }
+        // jsurfer change end
+		return localOffset;
+	}
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/text/rules/ViewNode.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/text/rules/ViewNode.java
new file mode 100644
index 0000000..ef5ab0e
--- /dev/null
+++ b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/text/rules/ViewNode.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://solareclipse.sourceforge.net/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ * 
+ * $Id: ViewNode.java,v 1.1 2004-09-02 18:26:29 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.ui.text.rules;
+
+/**
+ * @author Igor Malinin
+ */
+public class ViewNode extends FlatNode {
+
+	/** Inner view of the document */
+	public InnerDocumentView view;
+
+	public ViewNode(String type) {
+		super(type);
+	}
+
+	/*
+	 * @see java.lang.Object#toString()
+	 */
+	public String toString() {
+		return "ViewNode[" + type + ", " + offset + ", " + length + "]";
+	}
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/text/source/DefaultSourceViewerConfiguration.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/text/source/DefaultSourceViewerConfiguration.java
new file mode 100644
index 0000000..7e7309b
--- /dev/null
+++ b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/text/source/DefaultSourceViewerConfiguration.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://solareclipse.sourceforge.net/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ * 
+ * $Id: DefaultSourceViewerConfiguration.java,v 1.1 2004-09-02 18:26:32 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.ui.text.source;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.SourceViewerConfiguration;
+
+/**
+ * @author Igor Malinin
+ */
+public class DefaultSourceViewerConfiguration extends SourceViewerConfiguration {
+
+	/** Preference key used to look up display tab width. */
+	public static final String PREFERENCE_TAB_WIDTH =
+		"net.sourceforge.phpeclipse.ui.editor.tabWidth"; //$NON-NLS-1$
+
+	/** Preference key for inserting spaces rather than tabs. */
+	public static final String PREFERENCE_SPACES_FOR_TABS =
+		"net.sourceforge.phpeclipse.ui.editor.spacesForTabs"; //$NON-NLS-1$
+
+	private IPreferenceStore store;
+
+	public DefaultSourceViewerConfiguration(IPreferenceStore store) {
+		this.store = store;
+	}
+
+	/*
+	 * @see SourceViewerConfiguration#getIndentPrefixes(ISourceViewer, String)
+	 */
+	public String[] getIndentPrefixes(ISourceViewer sourceViewer,
+			String contentType) {
+		// prefix[0] is either '\t' or ' ' x tabWidth, depending on useSpaces
+
+		int tabWidth = store.getInt(PREFERENCE_TAB_WIDTH);
+		boolean useSpaces = store.getBoolean(PREFERENCE_SPACES_FOR_TABS);
+
+		String[] prefixes = new String[tabWidth + 1];
+
+		for (int i = 0; i <= tabWidth; i++) {
+			StringBuffer prefix = new StringBuffer(tabWidth - 1);
+
+			if (useSpaces) {
+				for (int j = 0; j + i < tabWidth; j++) {
+					prefix.append(' ');
+				}
+
+				if (i != 0) {
+					prefix.append('\t');
+				}
+			} else {
+				for (int j = 0; j < i; j++) {
+					prefix.append(' ');
+				}
+
+				if (i != tabWidth) {
+					prefix.append('\t');
+				}
+			}
+
+			prefixes[i] = prefix.toString();
+		}
+
+		prefixes[tabWidth] = ""; //$NON-NLS-1$
+
+		return prefixes;
+	}
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/views/outline/ModelBasedOutlinePage.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/views/outline/ModelBasedOutlinePage.java
new file mode 100644
index 0000000..8f9fda4
--- /dev/null
+++ b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/views/outline/ModelBasedOutlinePage.java
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2004 Christopher Lenz and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Christopher Lenz - initial implementation
+ * 
+ * $Id: ModelBasedOutlinePage.java,v 1.1 2004-09-02 18:26:28 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.ui.views.outline;
+
+import java.util.List;
+
+import net.sourceforge.phpeclipse.core.model.ISourceModel;
+import net.sourceforge.phpeclipse.core.model.ISourceReference;
+import net.sourceforge.phpeclipse.ui.editor.StructuredTextEditor;
+import net.sourceforge.phpeclipse.ui.internal.WebUIMessages;
+
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IStatusLineManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.texteditor.IUpdate;
+import org.eclipse.ui.texteditor.ResourceAction;
+import org.eclipse.ui.views.contentoutline.ContentOutlinePage;
+
+/**
+ * 
+ */
+public class ModelBasedOutlinePage extends ContentOutlinePage
+	implements IUpdate {
+
+	// Inner Classes -----------------------------------------------------------
+
+	public class ContentProvider implements ITreeContentProvider {
+
+		/*
+		 * ITreeContentProvider#getChildren(Object)
+		 */
+		public Object[] getChildren(Object parentElement) {
+			if (parentElement instanceof ISourceReference) {
+				return model.getChildren((ISourceReference) parentElement);
+			}
+			return new Object[0];
+		}
+
+		/*
+		 * @see ITreeContentProvider#getParent(Object)
+		 */
+		public Object getParent(Object element) {
+			if (element instanceof ISourceReference) {
+				return model.getParent((ISourceReference) element);
+			}
+			return null;
+		}
+
+		/*
+		 * @see ITreeContentProvider#hasChildren(Object)
+		 */
+		public boolean hasChildren(Object element) {
+			return getChildren(element).length > 0;
+		}
+
+		/*
+		 * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(Object)
+		 */
+		public Object[] getElements(Object inputElement) {
+			return model.getElements();
+		}
+
+		/* 
+		 * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+		 */
+		public void dispose() {
+		}
+
+		/*
+		 * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(Viewer, Object, Object)
+		 */
+		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+			if (oldInput != newInput) {
+				if (newInput instanceof ISourceModel) {
+					model = (ISourceModel) newInput;
+				}	   
+			}
+		}
+
+	}
+
+	/**
+	 * This action toggles whether this outline page links its selection
+	 * to the active editor.
+	 */
+	private class ToggleLinkingAction extends ResourceAction {
+		
+		/**
+		 * Constructs a new action.
+		 */
+		public ToggleLinkingAction() {
+			super(WebUIMessages.getResourceBundle(),
+				"OutlinePage.linkWithEditor."); //$NON-NLS-1$
+			if ((preferenceStore != null)
+			 && (linkWithEditorPreferenceKey != null)) {
+				boolean checked = preferenceStore.getBoolean(
+						linkWithEditorPreferenceKey);
+				valueChanged(checked, false);
+			} else {
+				setEnabled(false);
+			}
+		}
+
+		/*
+		 * @see org.eclipse.jface.action.Action#run()
+		 */
+		public void run() {
+			if ((preferenceStore != null)
+			 && (linkWithEditorPreferenceKey != null)) {
+				valueChanged(isChecked(), true);
+			}
+		}
+	
+		// Private Methods -----------------------------------------------------
+
+		/**
+		 * Updates whether the outline page is linked to the active editor.
+		 * 
+		 * @param checked Whether linking is enabled
+		 * @param store Whether the new state should be written back as a 
+		 *        preference
+		 */
+		private void valueChanged(final boolean checked, boolean store) {
+			setChecked(checked);
+			BusyIndicator.showWhile(getTreeViewer().getControl().getDisplay(),
+				new Runnable() {
+					public void run() {
+						editor.synchronizeOutlinePage();
+					}
+				});
+			if (store) {
+				preferenceStore.setValue(
+					linkWithEditorPreferenceKey, checked);
+			}
+		}
+
+	}
+
+	// Instance Variables ------------------------------------------------------
+
+	/**
+	 * The associated editor.
+	 */
+	private StructuredTextEditor editor;
+
+	/**
+	 * The structured source model.
+	 */
+	private ISourceModel model;
+
+	/**
+	 * The preference store.
+	 */
+	private IPreferenceStore preferenceStore;
+
+	/**
+	 * The preference key which specifies whether the outline page is linked to
+	 * the active editor.
+	 */
+	private String linkWithEditorPreferenceKey;
+
+	// Constructors ------------------------------------------------------------
+
+	/**
+	 * Constructor.
+	 * 
+	 * @param editor The associated structured text editor
+	 */
+	public ModelBasedOutlinePage(StructuredTextEditor editor) {
+		this.editor = editor;
+	}
+
+	// ContentOutlinePage Implementation ---------------------------------------
+
+	/*
+	 * @see org.eclipse.ui.part.IPage#createControl(Composite)
+	 */
+	public void createControl(Composite parent) {
+		super.createControl(parent);
+		TreeViewer viewer = getTreeViewer();
+		viewer.setContentProvider(new ContentProvider());
+	}
+
+	/*
+	 * @see org.eclipse.ui.part.IPage#dispose()
+	 */
+	public void dispose() {
+		if (editor != null) {
+			editor.outlinePageClosed();
+			editor = null;
+		}
+		super.dispose();
+	}
+
+	/*
+	 * @see org.eclipse.ui.part.Page#makeContributions(IMenuManager, IToolBarManager, IStatusLineManager)
+	 */
+	public void makeContributions(IMenuManager menuManager,
+		IToolBarManager toolBarManager, IStatusLineManager statusLineManager) {
+		if (toolBarManager != null) {
+			toolBarManager.add(new ToggleLinkingAction());
+		}
+		super.makeContributions(menuManager, toolBarManager, statusLineManager);
+	}
+
+	// IUpdate Implementation --------------------------------------------------
+
+	/**
+	 * @see IUpdate#update()
+	 */
+	public void update() {
+		ISourceModel model = editor.getSourceModel();
+		if (model != null) {
+			TreeViewer viewer = getTreeViewer();
+			if (viewer != null) {
+				Control control = viewer.getControl();
+				if ((control != null) && !control.isDisposed()) {
+					control.setRedraw(false);
+					viewer.setInput(model);
+					viewer.expandAll();
+					control.setRedraw(true);
+				}
+			}
+		}
+	}
+
+	// Public Methods ----------------------------------------------------------
+
+	/**
+	 * Selects a specific element in the outline page.
+	 * 
+	 * @param element the element to select
+	 */
+	public void select(ISourceReference element) {
+		TreeViewer viewer = getTreeViewer();
+		if (viewer != null) {
+			ISelection selection = viewer.getSelection();
+			if (selection instanceof IStructuredSelection) {
+				IStructuredSelection structuredSelection =
+					(IStructuredSelection) selection;
+				List elements = structuredSelection.toList();
+				if (!elements.contains(element)) {
+					if (element == null) {
+						selection = StructuredSelection.EMPTY;
+					} else {
+						selection = new StructuredSelection(element);
+					}
+					viewer.setSelection(selection, true);
+				}
+			}
+		}
+	}
+
+	// Protected Methods -------------------------------------------------------
+
+	protected final StructuredTextEditor getEditor() {
+		return editor;
+	}
+
+	protected final void setPreferenceStore(IPreferenceStore store) {
+		preferenceStore = store;
+	}
+
+	protected final void setLinkWithEditorPreferenceKey(String key) {
+		linkWithEditorPreferenceKey = key;
+	}
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/views/outline/ProblemsLabelDecorator.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/views/outline/ProblemsLabelDecorator.java
new file mode 100644
index 0000000..72a211b
--- /dev/null
+++ b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/views/outline/ProblemsLabelDecorator.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2004 Christopher Lenz and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Christopher Lenz - initial implementation
+ * 
+ * $Id: ProblemsLabelDecorator.java,v 1.1 2004-09-02 18:26:28 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.ui.views.outline;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import net.sourceforge.phpeclipse.core.model.ISourceReference;
+import net.sourceforge.phpeclipse.ui.WebUI;
+import net.sourceforge.phpeclipse.ui.views.util.ImageDescriptorRegistry;
+import net.sourceforge.phpeclipse.ui.views.util.ImageImageDescriptor;
+import net.sourceforge.phpeclipse.ui.views.util.OverlayImageDescriptor;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.viewers.ILabelDecorator;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * Label decorator for the outline page that adds error and warning overlay
+ * icons to elements in the outline. The information is retrieved from the 
+ * annotation model corresponding to the input of the associated text editor.
+ */
+public class ProblemsLabelDecorator extends LabelProvider
+	implements ILabelDecorator {
+
+	// Constants ---------------------------------------------------------------
+
+	private static final String ANNOTATION_TYPE_ERROR =
+		"org.eclipse.ui.workbench.texteditor.error"; //$NON-NLS-1$
+
+	private static final String ANNOTATION_TYPE_WARNING =
+		"org.eclipse.ui.workbench.texteditor.warning"; //$NON-NLS-1$
+
+	// Instance Variables ------------------------------------------------------
+
+	/** The associated text editor if the decorator is used in the outline. */
+	private ITextEditor editor;
+
+	/** Registry of icons and overlay icons. */
+	private ImageDescriptorRegistry registry = new ImageDescriptorRegistry();
+
+	// Constructors ------------------------------------------------------------
+
+	/**
+	 * Constructor.
+	 * 
+	 * @param editor the associated text editor
+	 */
+	public ProblemsLabelDecorator(ITextEditor editor) {
+		this.editor = editor;
+	}
+
+	// ILabelDecorator Implementation ------------------------------------------
+
+	/* 
+	 * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose()
+	 */
+	public void dispose() {
+		super.dispose();
+		registry.dispose();
+	}
+
+	/* 
+	 * @see ILabelDecorator#decorateImage(Image, Object)
+	 */
+	public Image decorateImage(Image image, Object element) {
+		Annotation annotations[] =
+			getAssociatedAnnotations((ISourceReference) element);
+		ImageDescriptor overlay = null;
+		for (int i = 0; i < annotations.length; i++) {
+			if (isError(annotations[i])) {
+				overlay = WebUI.getDefault().getImageRegistry().getDescriptor(
+						WebUI.ICON_OVERLAY_ERROR);
+			} else if (isWarning(annotations[i])) {
+				overlay = WebUI.getDefault().getImageRegistry().getDescriptor(
+						WebUI.ICON_OVERLAY_WARNING);
+			}
+		}
+		if (overlay != null) {
+			ImageDescriptor base = new ImageImageDescriptor(image);
+			return registry.get(new OverlayImageDescriptor(base,
+					new ImageDescriptor[][] { null, null, { overlay }, null },
+					null));
+		} else {
+		}
+		return image;
+	}
+
+	/* 
+	 * @see ILabelDecorator#decorateText(String, Object)
+	 */
+	public String decorateText(String text, Object element) {
+		return text;
+	}
+
+	// Private Methods ---------------------------------------------------------
+
+	/**
+	 * Returns all annotations associated with the given model element.
+	 * 
+	 * @param element the model element for which annotations should be
+	 *        collected
+	 * @return an array containing all annotations for the given element, or an
+	 *         empty array if no annotations are found
+	 */
+	private Annotation[] getAssociatedAnnotations(ISourceReference element) {
+		List retVal = new ArrayList();
+		if (editor != null) {
+			IEditorInput input = editor.getEditorInput();
+			IAnnotationModel model =
+				editor.getDocumentProvider().getAnnotationModel(input);
+			for (Iterator i = model.getAnnotationIterator(); i.hasNext(); ) {
+				Annotation annotation = (Annotation) i.next();
+				Position pos = model.getPosition(annotation);
+				if (pos!=null && isInside(pos.getOffset(), element)) {
+					retVal.add(annotation);
+				}
+			}
+		}
+		return (Annotation[]) retVal.toArray(new Annotation[retVal.size()]);
+	}
+
+	/**
+	 * Determines whether the given annotation is an error.
+	 * 
+	 * @param annotation the annotation to check
+	 * @return true if the annotation is to be displayed as an error,
+	 *         false otherwise
+	 */
+	private boolean isError(Annotation annotation) {
+		return ANNOTATION_TYPE_ERROR.equals(annotation.getType());
+	}
+
+	/**
+	 * Determines whether the given annotation is a warning.
+	 * 
+	 * @param annotation the annotation to check
+	 * @return true if the annotation is to be displayed as a warning,
+	 *         false otherwise
+	 */
+	private boolean isWarning(Annotation annotation) {
+		return ANNOTATION_TYPE_WARNING.equals(annotation.getType());
+	}
+
+	/**
+	 * Tests if the given position is inside the source region of a model
+	 * element.
+	 * 
+	 * @param pos the position to be tested
+	 * @param element the source element
+	 * @return boolean true if position is located inside the
+	 *         element, otherwise false
+	 */
+	private boolean isInside(int pos, ISourceReference element) {
+		IRegion region = element.getSourceRegion();
+		if (region != null) {
+			int offset = region.getOffset();
+			return ((offset <= pos) && (offset + region.getLength() > pos));			
+		}
+		return false;
+	}
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/views/outline/link_editor.gif b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/views/outline/link_editor.gif
new file mode 100644
index 0000000000000000000000000000000000000000..f865f3a39b9c1c39203c6563f28d99f354e14a2a
GIT binary patch
literal 116
zcmZ?wbhEHb6krfwSj50kUvK~a|NQ^=?eEXGua5_^|1*Gr;!hSv1_o9J9S{$smVwza
zVi(UJehUuA86}a5)^SG^dQ{w7nHH{+7Z#e?w6ajKaqHDAIfWRJ_)L=q*Dx)|jms(w
NXCF(SGKqn~8USjICBpy!
literal 0
HcmV?d00001
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/views/preview/BrowserPreview.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/views/preview/BrowserPreview.java
new file mode 100644
index 0000000..f4e0247
--- /dev/null
+++ b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/views/preview/BrowserPreview.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2004 Christopher Lenz and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Christopher Lenz - initial API and implementation
+ * 
+ * $Id: BrowserPreview.java,v 1.1 2004-09-02 18:26:31 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.ui.views.preview;
+
+import net.sourceforge.phpeclipse.ui.internal.WebUIMessages;
+
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.part.IPage;
+import org.eclipse.ui.part.IPageBookViewPage;
+import org.eclipse.ui.part.MessagePage;
+import org.eclipse.ui.part.PageBook;
+import org.eclipse.ui.part.PageBookView;
+
+/**
+ * 
+ */
+public class BrowserPreview extends PageBookView {
+
+	/* 
+	 * @see PageBookView#createDefaultPage(org.eclipse.ui.part.PageBook)
+	 */
+	protected IPage createDefaultPage(PageBook book) {
+		MessagePage page = new MessagePage();
+		page.createControl(book);
+		page.setMessage(WebUIMessages.getString(
+				"BrowserPreview.notAvailable")); //$NON-NLS-1$);
+		return page;
+	}
+
+	/* 
+	 * @see PageBookView#doCreatePage(org.eclipse.ui.IWorkbenchPart)
+	 */
+	protected PageRec doCreatePage(IWorkbenchPart part) {
+		// Try to get an outline page.
+		Object adapter = part.getAdapter(IBrowserPreviewPage.class);
+		if (adapter instanceof IBrowserPreviewPage) {
+			IBrowserPreviewPage page = (IBrowserPreviewPage) adapter;
+			if (page instanceof IPageBookViewPage) {
+				initPage((IPageBookViewPage) page);
+			}
+			page.createControl(getPageBook());
+			return new PageRec(part, page);
+		}
+		// There is no preview
+		return null;
+	}
+
+	/* 
+	 * @see PageBookView#doDestroyPage(IWorkbenchPart, PageBookView.PageRec)
+	 */
+	protected void doDestroyPage(IWorkbenchPart part, PageRec pageRecord) {
+		IBrowserPreviewPage page = (IBrowserPreviewPage) pageRecord.page;
+		page.dispose();
+		pageRecord.dispose();
+	}
+
+	/* 
+	 * @see PageBookView#getBootstrapPart()
+	 */
+	protected IWorkbenchPart getBootstrapPart() {
+		IWorkbenchPage page = getSite().getPage();
+		if (page != null) {
+			return page.getActiveEditor();
+		}
+		return null;
+	}
+
+	/* 
+	 * @see PageBookView#isImportant(IWorkbenchPart)
+	 */
+	protected boolean isImportant(IWorkbenchPart part) {
+		return (part instanceof IEditorPart);
+	}
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/views/preview/IBrowserPreviewPage.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/views/preview/IBrowserPreviewPage.java
new file mode 100644
index 0000000..e076e50
--- /dev/null
+++ b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/views/preview/IBrowserPreviewPage.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2004 Christopher Lenz and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Christopher Lenz - initial implementation
+ * 
+ * $Id: IBrowserPreviewPage.java,v 1.1 2004-09-02 18:26:31 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.ui.views.preview;
+
+import org.eclipse.ui.part.IPage;
+
+/**
+ * 
+ */
+public interface IBrowserPreviewPage extends IPage {
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/views/util/ImageDescriptorRegistry.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/views/util/ImageDescriptorRegistry.java
new file mode 100644
index 0000000..c3b15af
--- /dev/null
+++ b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/views/util/ImageDescriptorRegistry.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2004 Christopher Lenz and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Christopher Lenz - initial implementation based on the internal Eclipse
+ *                        class of the same name, defined in multiple packages
+ * 
+ * $Id: ImageDescriptorRegistry.java,v 1.1 2004-09-02 18:26:28 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.ui.views.util;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Registry that keeps a table of image descriptors and the images created from
+ * those descriptors.
+ */
+public class ImageDescriptorRegistry {
+
+	/**
+	 * Stores all registered image descriptors as keys, and the images created
+	 * from them as values.
+	 */
+	private Map registry = new HashMap(10);
+
+	// Constructors ------------------------------------------------------------
+
+	/**
+	 * Creates a new image descriptor registry for the current or default
+	 * display, respectively.
+	 */
+	public ImageDescriptorRegistry() {
+		this(Display.getCurrent() != null ?
+				Display.getCurrent() : Display.getDefault());
+	}
+
+	/**
+	 * Creates a new image descriptor registry for the given display. All images
+	 * managed by this registry will be disposed when the display gets disposed.
+	 * 
+	 * @param display the display the images managed by this registry are
+	 *        allocated for 
+	 */
+	public ImageDescriptorRegistry(Display display) {
+		display.disposeExec(new Runnable() {
+			public void run() {
+				dispose();
+			}	
+		});
+	}
+	
+	/**
+	 * Returns the image assiciated with the given image descriptor.
+	 * 
+	 * @param descriptor the image descriptor for which the registry manages an
+	 *        image
+	 * @return the image associated with the image descriptor or null
+	 *         if the image descriptor can't create the requested image.
+	 */
+	public Image get(ImageDescriptor descriptor) {
+		if (descriptor == null) {
+			descriptor = ImageDescriptor.getMissingImageDescriptor();
+		}
+		Image result = (Image) registry.get(descriptor);
+		if (result == null) {
+			result = descriptor.createImage();
+			if (result != null) {
+				registry.put(descriptor, result);
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * Disposes all images managed by this registry.
+	 */	
+	public void dispose() {
+		for (Iterator i = registry.values().iterator(); i.hasNext(); ) {
+			((Image) i.next()).dispose();
+		}
+		registry.clear();
+	}
+	
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/views/util/ImageImageDescriptor.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/views/util/ImageImageDescriptor.java
new file mode 100644
index 0000000..e1af923
--- /dev/null
+++ b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/views/util/ImageImageDescriptor.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2004 Christopher Lenz and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Christopher Lenz - initial version based on the Eclipse class of the same
+ *                        name in org.eclipse.jdt.internal.ui.viewsupport
+ * 
+ * $Id: ImageImageDescriptor.java,v 1.1 2004-09-02 18:26:28 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.ui.views.util;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+
+/**
+ * ImageDescriptor implementation that wraps an existing {@link Image}.
+ */
+public class ImageImageDescriptor extends ImageDescriptor {
+
+	// Instance Variables ------------------------------------------------------
+
+	/** The wrapped image. */
+	private Image image;
+
+	// Constructors ------------------------------------------------------------
+
+	/**
+	 * Constructor.
+	 * 
+	 * @param image the image to wrap
+	 */
+	public ImageImageDescriptor(Image image) {
+		this.image= image;
+	}
+
+	// ImageDescriptor Implementation ------------------------------------------
+
+	/*
+	 * @see ImageDescriptor#getImageData()
+	 */
+	public ImageData getImageData() {
+		return image.getImageData();
+	}
+
+	/*
+	 * @see Object#equals(Object)
+	 */
+	public boolean equals(Object o) {
+		if (o instanceof ImageImageDescriptor) {
+			ImageImageDescriptor other = (ImageImageDescriptor) o;
+			if (image.equals(other.image)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/*
+	 * @see Object#hashCode()
+	 */
+	public int hashCode() {
+		return image.hashCode();
+	}
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/views/util/OverlayImageDescriptor.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/views/util/OverlayImageDescriptor.java
new file mode 100644
index 0000000..e9e995a
--- /dev/null
+++ b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/views/util/OverlayImageDescriptor.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2004 Christopher Lenz and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Christopher Lenz - initial version based on the internal Eclipse class
+ *                        org.eclipse.ui.internal.ide.misc.OverlayIcon
+ * 
+ * $Id: OverlayImageDescriptor.java,v 1.1 2004-09-02 18:26:28 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.ui.views.util;
+
+import org.eclipse.jface.resource.CompositeImageDescriptor;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.Point;
+
+/**
+ * An overlay image descriptor can add several overlay icons to a base image.
+ */
+public class OverlayImageDescriptor extends CompositeImageDescriptor {
+
+	// Instance Variables ------------------------------------------------------
+
+	/** Size of the resulting composite image. */
+	private Point size = null;
+
+	/** The base image. */
+	private ImageDescriptor base;
+	
+	/** The overlay images. */
+	private ImageDescriptor overlays[][];
+
+	// Constructors ------------------------------------------------------------
+
+	/**
+	 * Creates the image descriptor. The size of the resulting image will be the
+	 * same as the size of the base image.
+	 * 
+	 * @param base the descriptor of the base image
+	 * @param overlays descriptors of the overlay images
+	 */
+	public OverlayImageDescriptor(ImageDescriptor base,
+			ImageDescriptor[][] overlays) {
+		this(base, overlays, null);
+	}
+
+	/**
+	 * Creates the image descriptor.
+	 * 
+	 * @param base the descriptor of the base image
+	 * @param overlays descriptors of the overlay images
+	 * @param size the size of the composite image, or null to use the
+	 *        size of the base image
+	 */
+	public OverlayImageDescriptor(ImageDescriptor base,
+			ImageDescriptor[][] overlays, Point size) {
+		this.base = base;
+		this.overlays = overlays;
+		if (size == null) {
+			ImageData data = base.getImageData();
+			size = new Point(data.width, data.height); 
+		}
+		this.size = size;
+	}
+
+	// CompositeImageDescriptor Implementation ---------------------------------
+
+	/* 
+	 * @see CompositeImageDescriptor#drawCompositeImage(int, int)
+	 */
+	protected void drawCompositeImage(int width, int height) {
+		ImageData bg;
+		if ((base == null) || ((bg = base.getImageData()) == null)) {
+			bg = DEFAULT_IMAGE_DATA;
+		}
+		drawImage(bg, 0, 0);
+		if (overlays != null) {
+			if (overlays.length > 0) {
+				drawTopRight(overlays[0]);
+			}
+			if (overlays.length > 1) {
+				drawBottomRight(overlays[1]);
+			}
+			if (overlays.length > 2) {
+				drawBottomLeft(overlays[2]);
+			}
+			if (overlays.length > 3) {
+				drawTopLeft(overlays[3]);
+			}
+		}
+	}
+
+	/* 
+	 * @see CompositeImageDescriptor#getSize()
+	 */
+	protected Point getSize() {
+		return size;
+	}
+
+	// Private Methods ---------------------------------------------------------
+
+	private void drawBottomLeft(ImageDescriptor[] descriptors) {
+		if (descriptors == null) {
+			return;
+		}
+		int length = descriptors.length;
+		int x = 0;
+		for (int i = 0; i < 3; i++) {
+			if ((i < length) && (descriptors[i] != null)) {
+				ImageData id = descriptors[i].getImageData();
+				drawImage(id, x, getSize().y - id.height);
+				x += id.width;
+			}
+		}
+	}
+
+	private void drawBottomRight(ImageDescriptor[] descriptors) {
+		if (descriptors == null) {
+			return;
+		}
+		int length = descriptors.length;
+		int x = getSize().x;
+		for (int i = 2; i >= 0; i--) {
+			if (i < length && descriptors[i] != null) {
+				ImageData id = descriptors[i].getImageData();
+				x -= id.width;
+				drawImage(id, x, getSize().y - id.height);
+			}
+		}
+	}
+
+	private void drawTopLeft(ImageDescriptor[] descriptors) {
+		if (descriptors == null) {
+			return;
+		}
+		int length = descriptors.length;
+		int x = 0;
+		for (int i = 0; i < 3; i++) {
+			if (i < length && descriptors[i] != null) {
+				ImageData id = descriptors[i].getImageData();
+				drawImage(id, x, 0);
+				x += id.width;
+			}
+		}
+	}
+
+	private void drawTopRight(ImageDescriptor[] descriptors) {
+		if (descriptors == null) {
+			return;
+		}
+		int length = descriptors.length;
+		int x = getSize().x;
+		for (int i = 2; i >= 0; i--) {
+			if (i < length && descriptors[i] != null) {
+				ImageData id = descriptors[i].getImageData();
+				x -= id.width;
+				drawImage(id, x, 0);
+			}
+		}
+	}
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/templates/default-templates.properties b/net.sourceforge.phpeclipse.ui/templates/default-templates.properties
new file mode 100644
index 0000000..b200f2b
--- /dev/null
+++ b/net.sourceforge.phpeclipse.ui/templates/default-templates.properties
@@ -0,0 +1,10 @@
+###############################################################################
+# Copyright (c) 2000, 2004 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials 
+# are made available under the terms of the Common Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/cpl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
diff --git a/net.sourceforge.phpeclipse.ui/templates/default-templates.xml b/net.sourceforge.phpeclipse.ui/templates/default-templates.xml
new file mode 100644
index 0000000..43746d5
--- /dev/null
+++ b/net.sourceforge.phpeclipse.ui/templates/default-templates.xml
@@ -0,0 +1,468 @@
+
+IAction.
+	 */
+	public void run() {
+		WebBrowser.openURL(new WebBrowserEditorInput(null, WebBrowserEditorInput.SHOW_ALL | WebBrowserEditorInput.FORCE_NEW_PAGE));
+	}
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/OpenBrowserWorkbenchAction.java b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/OpenBrowserWorkbenchAction.java
new file mode 100644
index 0000000..6041214
--- /dev/null
+++ b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/OpenBrowserWorkbenchAction.java
@@ -0,0 +1,68 @@
+/**
+ * Copyright (c) 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *    IBM - Initial API and implementation
+ */
+package net.sourceforge.phpeclipse.webbrowser;
+
+import net.sourceforge.phpeclipse.webbrowser.WebBrowser;
+import net.sourceforge.phpeclipse.webbrowser.WebBrowserEditorInput;
+
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.ui.*;
+/**
+ * Action to open the Web broswer.
+ */
+public class OpenBrowserWorkbenchAction implements IWorkbenchWindowActionDelegate {
+	/**
+	 * OpenBrowserWorkbenchAction constructor comment.
+	 */
+	public OpenBrowserWorkbenchAction() {
+		super();
+	}
+
+	/**
+	 * Disposes this action delegate.  The implementor should unhook any references
+	 * to itself so that garbage collection can occur.
+	 */
+	public void dispose() { }
+
+	/**
+	 * Initializes this action delegate with the workbench window it will work in.
+	 *
+	 * @param window the window that provides the context for this delegate
+	 */
+	public void init(IWorkbenchWindow window) { }
+
+	/**
+	 * Performs this action.
+	 * IElement from the state captured within 
+	 * an IMemento.
+	 *
+	 * @param memento a memento containing the state for an element
+	 * @return an element, or null if the element could not be created
+	 */
+	public IAdaptable createElement(IMemento memento) {
+		URL url2 = null;
+		try {
+			url2 = new URL(WebBrowserPreference.getHomePageURL());
+		} catch (Exception e) {
+			// could not determine the URL
+		}
+
+		int newStyle = SHOW_TOOLBAR | SHOW_STATUSBAR;
+		try {
+			newStyle = memento.getInteger(MEMENTO_STYLE).intValue();
+	
+			if ((newStyle & SAVE_URL) != 0)
+				url = new URL(memento.getString(MEMENTO_URL));
+		} catch (Exception e) {
+			// could not determine the style
+		}
+		
+		String id2 = null;
+		try {
+			id2 = memento.getString(MEMENTO_ID);
+			if (id2 != null && id2.length() < 1)
+				id2 = null;
+		} catch (Exception e) { }
+		
+		return new WebBrowserEditorInput(url2, newStyle, id2);
+	}
+	
+	/**
+	 * Indicates whether some other object is "equal to" this one.
+	 * In this case it means that the underlying IFolders are equal.
+	 */
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (!(obj instanceof WebBrowserEditorInput))
+			return false;
+		WebBrowserEditorInput other = (WebBrowserEditorInput) obj;
+	
+		if (url != null && !url.equals(obj))
+			return false;
+	
+		return canReplaceInput(other);
+	}
+	
+	/**
+	 * Returns whether the editor input exists.  
+	 * exists becomes 
+	 * false or it drops off the bottom of the list.
+	 *
+	 * @return true if the editor input exists; false
+	 *		otherwise
+	 */
+	public boolean exists() {
+		if ((style & TRANSIENT) != 0)
+			return false;
+		else
+			return true;
+	}
+	
+	/**
+	 * Returns an object which is an instance of the given class
+	 * associated with this object. Returns null if
+	 * no such object can be found.
+	 *
+	 * @param adapter the adapter class to look up
+	 * @return a object castable to the given class, 
+	 *    or null if this object does not
+	 *    have an adapter for the given class
+	 */
+	public Object getAdapter(Class adapter) {
+		return null;
+	}
+	
+	/**
+	 * Returns the ID of an element factory which can be used to recreate 
+	 * this object.  An element factory extension with this ID must exist
+	 * within the workbench registry.
+	 * 
+	 * @return the element factory ID
+	 */
+	public String getFactoryId() {
+		return ELEMENT_FACTORY_ID;
+	}
+	
+	public ImageDescriptor getImageDescriptor() {
+		return ImageResource.getImageDescriptor(ImageResource.IMG_INTERNAL_BROWSER);
+	}
+	
+	/**
+	 * Returns the name of this editor input for display purposes.
+	 * "a\b\MyFile.gif", the return value would be just
+	 * "MyFile.gif".
+	 *
+	 * @return the file name string
+	 */
+	public String getName() {
+		return WebBrowserUIPlugin.getResource("%viewWebBrowserTitle");
+	}
+	
+	/*
+	 * Returns an object that can be used to save the state of this editor input.
+	 *
+	 * @return the persistable element, or null if this editor input
+	 *   cannot be persisted
+	 */
+	public IPersistableElement getPersistable() {
+		if ((style & TRANSIENT) != 0)
+			return null;
+		else
+			return this;
+	}
+	
+	public String getToolTipText() {
+		if (url != null)
+			return url.toExternalForm();
+		else
+			return WebBrowserUIPlugin.getResource("%viewWebBrowserTitle");
+	}
+	
+	/**
+	 * Returns the url.
+	 *
+	 * @return java.net.URL
+	 */
+	public URL getURL() {
+		return url;
+	}
+	
+	/**
+	 * Returns the browser id. Browsers with a set id will always & only be
+	 * replaced by browsers with the same id.
+	 * 
+	 * @return String
+	 */
+	public String getBrowserId() {
+		return id;
+	}
+	
+	/**
+	 * Returns true if the status bar should be shown.
+	 *
+	 * @return boolean
+	 */
+	public boolean isStatusbarVisible() {
+		return (style & SHOW_STATUSBAR) != 0;
+	}
+	
+	/**
+	 * Returns true if the toolbar should be shown.
+	 *
+	 * @return boolean
+	 */
+	public boolean isToolbarVisible() {
+		return (style & SHOW_TOOLBAR) != 0;
+	}
+	
+	/**
+	 * Saves the state of an element within a memento.
+	 *
+	 * @param memento the storage area for element state
+	 */
+	public void saveState(IMemento memento) {
+		if ((style & SAVE_URL) != 0 && url != null)
+			memento.putString(MEMENTO_URL, url.toExternalForm());
+
+		memento.putInteger(MEMENTO_STYLE, style);
+		
+		if (id != null)
+			memento.putString(MEMENTO_ID, id);
+	}
+
+	/**
+	 * Converts this object to a string.
+	 *
+	 * @return java.lang.String
+	 */
+	public String toString() {
+		return "WebBrowserEditorInput[" + url + " " + style + " " + id + "]";
+	}
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/BrowserContentProvider.java b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/BrowserContentProvider.java
new file mode 100644
index 0000000..bbbdafc
--- /dev/null
+++ b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/BrowserContentProvider.java
@@ -0,0 +1,73 @@
+/**********************************************************************
+ * Copyright (c) 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *    IBM - Initial API and implementation
+ **********************************************************************/
+package net.sourceforge.phpeclipse.webbrowser.internal;
+
+import java.util.*;
+
+import net.sourceforge.phpeclipse.webbrowser.IWebBrowser;
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+
+/**
+ * Monitor content provider.
+ */
+public class BrowserContentProvider implements IStructuredContentProvider {
+	/**
+	 * BrowserContentProvider constructor comment.
+	 */
+	public BrowserContentProvider() {
+		super();
+	}
+
+	/**
+	 * Disposes of this content provider.  
+	 * This is called by the viewer when it is disposed.
+	 */
+	public void dispose() { }
+
+	/**
+	 * Returns the elements to display in the viewer 
+	 * when its input is set to the given element. 
+	 * These elements can be presented as rows in a table, items in a list, etc.
+	 * The result is not modified by the viewer.
+	 *
+	 * @param inputElement the input element
+	 * @return the array of elements to display in the viewer
+	 */
+	public Object[] getElements(Object inputElement) {
+		List list = new ArrayList();
+		Iterator iterator = BrowserManager.getInstance().getWebBrowsers().iterator();
+		while (iterator.hasNext()) {
+			IWebBrowser browser = (IWebBrowser) iterator.next();
+			list.add(browser);
+		}
+		return list.toArray();
+		}
+
+	/**
+	 * Notifies this content provider that the given viewer's input
+	 * has been switched to a different element.
+	 * null if the viewer
+	 *   did not previously have an input
+	 * @param newInput the new input element, or null if the viewer
+	 *   does not have an input
+	 */
+	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {}
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/BrowserManager.java b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/BrowserManager.java
new file mode 100644
index 0000000..30a22f9
--- /dev/null
+++ b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/BrowserManager.java
@@ -0,0 +1,287 @@
+/**********************************************************************
+ * Copyright (c) 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+  *
+ * Contributors:
+ *    IBM - Initial API and implementation
+ **********************************************************************/
+package net.sourceforge.phpeclipse.webbrowser.internal;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import net.sourceforge.phpeclipse.webbrowser.IExternalWebBrowser;
+import net.sourceforge.phpeclipse.webbrowser.IExternalWebBrowserWorkingCopy;
+import net.sourceforge.phpeclipse.webbrowser.IInternalWebBrowser;
+import net.sourceforge.phpeclipse.webbrowser.IWebBrowser;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Preferences;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.XMLMemento;
+
+/**
+ *  
+ */
+public class BrowserManager {
+  private static final int ADD = 0;
+
+  private static final int CHANGE = 1;
+
+  private static final int REMOVE = 2;
+
+  protected List browsers;
+
+  protected IWebBrowser currentBrowser;
+
+  protected List browserListeners = new ArrayList();
+
+  private Preferences.IPropertyChangeListener pcl;
+
+  protected boolean ignorePreferenceChanges = false;
+
+  protected static BrowserManager instance;
+
+  public static BrowserManager getInstance() {
+    if (instance == null)
+      instance = new BrowserManager();
+    return instance;
+  }
+
+  private BrowserManager() {
+    pcl = new Preferences.IPropertyChangeListener() {
+      public void propertyChange(Preferences.PropertyChangeEvent event) {
+        if (ignorePreferenceChanges)
+          return;
+        String property = event.getProperty();
+        if (property.equals("browsers")) {
+          loadBrowsers();
+        }
+      }
+    };
+
+    WebBrowserUIPlugin.getInstance().getPluginPreferences().addPropertyChangeListener(pcl);
+  }
+
+  protected void dispose() {
+    WebBrowserUIPlugin.getInstance().getPluginPreferences().removePropertyChangeListener(pcl);
+
+    // clear the cache
+    if (browsers != null) {
+      Iterator iterator = browsers.iterator();
+      while (iterator.hasNext()) {
+        Object obj = iterator.next();
+        if (obj instanceof IInternalWebBrowser) {
+          IInternalWebBrowser wb = (IInternalWebBrowser) obj;
+          if (wb.getClearHistoryOnExit())
+            WebBrowserPreference.setInternalWebBrowserHistory(null);
+        }
+      }
+    }
+  }
+
+  public IExternalWebBrowserWorkingCopy createExternalWebBrowser() {
+    return new ExternalWebBrowserWorkingCopy();
+  }
+
+  public List getWebBrowsers() {
+    if (browsers == null)
+      loadBrowsers();
+    return new ArrayList(browsers);
+  }
+
+  protected void loadBrowsers() {
+    Trace.trace(Trace.FINEST, "Loading web browsers");
+
+    Preferences prefs = WebBrowserUIPlugin.getInstance().getPluginPreferences();
+    String xmlString = prefs.getString("browsers");
+    if (xmlString != null && xmlString.length() > 0) {
+      browsers = new ArrayList();
+
+      try {
+        ByteArrayInputStream in = new ByteArrayInputStream(xmlString.getBytes());
+        Reader reader = new InputStreamReader(in);
+        IMemento memento = XMLMemento.createReadRoot(reader);
+
+        IMemento child = memento.getChild("internal");
+        if (child != null) {
+          InternalWebBrowser browser = new InternalWebBrowser();
+          browser.load(child);
+          browsers.add(browser);
+        }
+
+        IMemento[] children = memento.getChildren("external");
+        int size = children.length;
+        for (int i = 0; i < size; i++) {
+          ExternalWebBrowser browser = new ExternalWebBrowser();
+          browser.load(children[i]);
+          browsers.add(browser);
+        }
+
+        Integer current = memento.getInteger("current");
+        if (current != null) {
+          currentBrowser = (IWebBrowser) browsers.get(current.intValue());
+        }
+      } catch (Exception e) {
+        Trace.trace(Trace.WARNING, "Could not load browsers: " + e.getMessage());
+      }
+      addInternalBrowser(browsers);
+      if (currentBrowser == null && browsers.size() > 0)
+        currentBrowser = (IWebBrowser) browsers.get(0);
+    } else {
+      setupDefaultBrowsers();
+      saveBrowsers();
+      return;
+    }
+  }
+
+  protected void saveBrowsers() {
+    try {
+      ignorePreferenceChanges = true;
+      XMLMemento memento = XMLMemento.createWriteRoot("web-browsers");
+
+      Iterator iterator = browsers.iterator();
+      while (iterator.hasNext()) {
+        Object obj = iterator.next();
+        if (obj instanceof InternalWebBrowser) {
+          InternalWebBrowser browser = (InternalWebBrowser) obj;
+          IMemento child = memento.createChild("internal");
+          browser.save(child);
+        } else if (obj instanceof ExternalWebBrowser) {
+          ExternalWebBrowser browser = (ExternalWebBrowser) obj;
+          IMemento child = memento.createChild("external");
+          browser.save(child);
+        }
+      }
+
+      memento.putInteger("current", browsers.indexOf(currentBrowser));
+
+      StringWriter writer = new StringWriter();
+      memento.save(writer);
+      String xmlString = writer.getBuffer().toString();
+      Preferences prefs = WebBrowserUIPlugin.getInstance().getPluginPreferences();
+      prefs.setValue("browsers", xmlString);
+      WebBrowserUIPlugin.getInstance().savePluginPreferences();
+    } catch (Exception e) {
+      Trace.trace(Trace.SEVERE, "Could not save browsers", e);
+    }
+    ignorePreferenceChanges = false;
+  }
+
+  protected void addInternalBrowser(List browserList) {
+    if (browserList == null)
+      return;
+
+    Iterator iterator = browserList.iterator();
+    while (iterator.hasNext()) {
+      IWebBrowser browser = (IWebBrowser) iterator.next();
+      if (browser instanceof IInternalWebBrowser)
+        return;
+    }
+
+    // add the internal browser if we can
+    WebBrowserUIPlugin.getInstance().getLog().log(
+        new Status(IStatus.INFO, WebBrowserUIPlugin.PLUGIN_ID, 0, WebBrowserUtil.canUseInternalWebBrowser() + "/"
+            + WebBrowserUtil.isInternalBrowserOperational(), null));
+    if (!WebBrowserUtil.canUseInternalWebBrowser() || !WebBrowserUtil.isInternalBrowserOperational())
+      return;
+
+    browserList.add(0, new InternalWebBrowser());
+  }
+
+  private void setupDefaultBrowsers() {
+    browsers = new ArrayList();
+
+    addInternalBrowser(browsers);
+
+    // handle all the EXTERNAL browsers by criteria and add those too at startup
+    WebBrowserUtil.addFoundBrowsers(browsers);
+
+    // by default, if internal is there, that is current, else set the first external one
+    if (!browsers.isEmpty())
+      currentBrowser = (IWebBrowser) browsers.get(0);
+  }
+
+  protected void addBrowser(IExternalWebBrowser browser) {
+    if (browsers == null)
+      loadBrowsers();
+    if (!browsers.contains(browser))
+      browsers.add(browser);
+    fireWebBrowserEvent(browser, ADD);
+    saveBrowsers();
+  }
+
+  protected void removeWebBrowser(IExternalWebBrowser browser) {
+    if (browsers == null)
+      loadBrowsers();
+    browsers.remove(browser);
+    fireWebBrowserEvent(browser, REMOVE);
+  }
+
+  // Internal Web browser CAN be "edited", just not created or removed
+  protected void browserChanged(IWebBrowser browser) {
+    fireWebBrowserEvent(browser, CHANGE);
+    saveBrowsers();
+  }
+
+  /**
+   * Add Web browser listener.
+   * 
+   * @param listener
+   */
+  public void addWebBrowserListener(IWebBrowserListener listener) {
+    browserListeners.add(listener);
+  }
+
+  /**
+   * Remove Web browser listener.
+   * 
+   * @param listener
+   */
+  public void removeWebBrowserListener(IWebBrowserListener listener) {
+    browserListeners.remove(listener);
+  }
+
+  /**
+   * Fire a Web browser event.
+   * 
+   * @param browser
+   * @param type
+   */
+  protected void fireWebBrowserEvent(IWebBrowser browser, int type) {
+    Object[] obj = browserListeners.toArray();
+
+    int size = obj.length;
+    for (int i = 0; i < size; i++) {
+      IWebBrowserListener listener = (IWebBrowserListener) obj[i];
+      if (type == ADD)
+        listener.browserAdded(browser);
+      else if (type == CHANGE)
+        listener.browserChanged(browser);
+      else if (type == REMOVE)
+        listener.browserRemoved(browser);
+    }
+  }
+
+  public IWebBrowser getCurrentWebBrowser() {
+    if (browsers == null)
+      loadBrowsers();
+
+    return currentBrowser;
+  }
+
+  public void setCurrentWebBrowser(IWebBrowser wb) {
+    if (browsers.contains(wb))
+      currentBrowser = wb;
+    saveBrowsers();
+  }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/BrowserSearcher.java b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/BrowserSearcher.java
new file mode 100644
index 0000000..4c67268
--- /dev/null
+++ b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/BrowserSearcher.java
@@ -0,0 +1,128 @@
+package net.sourceforge.phpeclipse.webbrowser.internal;
+/**********************************************************************
+ * Copyright (c) 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+  *
+ * Contributors:
+ *    IBM - Initial API and implementation
+ **********************************************************************/
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+import net.sourceforge.phpeclipse.webbrowser.IExternalWebBrowserWorkingCopy;
+
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.swt.widgets.DirectoryDialog;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.core.runtime.IProgressMonitor;
+/**
+ * 
+ */
+public class BrowserSearcher {
+	private static boolean cancelled;
+	private BrowserSearcher() {
+		super();
+	}
+
+	/**
+	 * Search for installed VMs in the file system
+	 */
+	protected static List search(Shell shell) {
+		final List foundBrowsers = new ArrayList();
+		final List existingPaths = WebBrowserUtil.getExternalBrowserPaths();
+
+		// select a target directory for the search
+		DirectoryDialog dialog = new DirectoryDialog(shell);
+		dialog.setMessage(WebBrowserUIPlugin.getResource("%selectDirectory"));
+		dialog.setText(WebBrowserUIPlugin.getResource("%directoryDialogTitle"));
+
+		String path = dialog.open();
+		if (path == null)
+			return null;
+		
+		cancelled = false;
+		
+		final File rootDir = new File(path);
+		ProgressMonitorDialog pm = new ProgressMonitorDialog(shell);
+
+		IRunnableWithProgress r = new IRunnableWithProgress() {
+			public void run(IProgressMonitor monitor) {
+				monitor.beginTask(
+					WebBrowserUIPlugin.getResource("%searchingTaskName"),
+					IProgressMonitor.UNKNOWN);
+				search(rootDir, existingPaths, foundBrowsers, monitor);
+				monitor.done();
+				if (monitor.isCanceled())
+					setCancelled(true);
+			}
+		};
+
+		try {
+			pm.run(true, true, r);
+		} catch (InvocationTargetException e) {
+			Trace.trace(Trace.SEVERE, "Invocation Exception occured running monitor: " + e);
+		} catch (InterruptedException e) {
+			Trace.trace(Trace.SEVERE, "Interrupted exception occured running monitor: " + e);
+			return null;
+		}
+		
+		if (cancelled)
+			return null;
+
+		return foundBrowsers;
+	}
+	
+	protected static void setCancelled(boolean b) {
+		cancelled = b;
+	}
+
+	protected static void search(File directory, List existingPaths, List foundBrowsers, IProgressMonitor monitor) {
+		if (monitor.isCanceled())
+			return;
+
+		String[] names = directory.list();
+		List subDirs = new ArrayList();
+
+		for (int i = 0; i < names.length; i++) {
+			if (monitor.isCanceled())
+				return;
+
+			File file = new File(directory, names[i]);
+			
+			if (existingPaths.contains(file.getAbsolutePath().toLowerCase()))
+				continue;
+
+			IExternalWebBrowserWorkingCopy wc = WebBrowserUtil.createExternalBrowser(file);
+			if (wc != null)
+				foundBrowsers.add(wc);
+
+			try {
+				monitor.subTask(
+					MessageFormat.format(WebBrowserUIPlugin.getResource("%searching"),
+						new String[] { Integer.toString(foundBrowsers.size()), file.getCanonicalPath()}));
+			} catch (IOException ioe) {
+			}
+
+			if (file.isDirectory()) {
+				if (monitor.isCanceled())
+					return;
+				subDirs.add(file);
+			}
+		}
+		while (!subDirs.isEmpty()) {
+			File subDir = (File) subDirs.remove(0);
+			search(subDir, existingPaths, foundBrowsers, monitor);
+			if (monitor.isCanceled()) {
+				return;
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/BrowserTableComposite.java b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/BrowserTableComposite.java
new file mode 100644
index 0000000..4bbd1a8
--- /dev/null
+++ b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/BrowserTableComposite.java
@@ -0,0 +1,273 @@
+/**********************************************************************
+ * Copyright (c) 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *    IBM - Initial API and implementation
+ **********************************************************************/
+package net.sourceforge.phpeclipse.webbrowser.internal;
+
+import java.util.Iterator;
+
+import net.sourceforge.phpeclipse.webbrowser.IExternalWebBrowser;
+import net.sourceforge.phpeclipse.webbrowser.IExternalWebBrowserWorkingCopy;
+import net.sourceforge.phpeclipse.webbrowser.IInternalWebBrowser;
+import net.sourceforge.phpeclipse.webbrowser.IInternalWebBrowserWorkingCopy;
+import net.sourceforge.phpeclipse.webbrowser.IWebBrowser;
+
+import org.eclipse.jface.viewers.*;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.help.WorkbenchHelp;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.ICheckStateListener;
+/**
+ * 
+ */
+public class BrowserTableComposite extends Composite {
+	protected Table table;
+	protected CheckboxTableViewer tableViewer;
+	protected Button edit;
+	protected Button remove;
+	protected Button search;
+	protected IWebBrowser selection;
+	
+	protected Label location;
+	protected Label parameters;
+	
+	public BrowserTableComposite(Composite parent, int style) {
+		super(parent, style);
+		createWidgets();
+	}
+
+	protected void createWidgets() {
+		GridLayout layout = new GridLayout();
+		layout.horizontalSpacing = 5;
+		layout.verticalSpacing = 5;
+		layout.marginWidth = 0;
+		layout.marginHeight = 0;
+		layout.numColumns = 2;
+		setLayout(layout);
+
+		GridData data = new GridData(GridData.FILL_BOTH);
+		setLayoutData(data);
+		
+		Label label = new Label(this, SWT.NONE);
+		label.setText(WebBrowserUIPlugin.getResource("%browserList"));
+		data = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_CENTER);
+		data.horizontalSpan = 2;
+		label.setLayoutData(data);
+		
+		table = new Table(this, SWT.CHECK | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL | SWT.SINGLE | SWT.FULL_SELECTION);
+		data = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL);
+		data.widthHint = 300;
+		table.setLayoutData(data);
+		table.setHeaderVisible(false);
+		table.setLinesVisible(false);
+		
+		TableLayout tableLayout = new TableLayout();
+		new TableColumn(table, SWT.NONE);
+		
+		tableLayout.addColumnData(new ColumnWeightData(100));
+
+		table.setLayout(tableLayout);
+		
+		tableViewer = new CheckboxTableViewer(table);
+		
+		tableViewer.setContentProvider(new BrowserContentProvider());
+		tableViewer.setLabelProvider(new BrowserTableLabelProvider());
+	
+		tableViewer.setInput("root");
+
+		// uncheck any other elements that might be checked and leave only the element checked to
+		// remain checked since one can only chose one brower at a time to be current.
+		tableViewer.addCheckStateListener(new ICheckStateListener() {
+			public void checkStateChanged(CheckStateChangedEvent e) {
+				checkNewDefaultBrowser(e.getElement());
+				IWebBrowser browser = (IWebBrowser) e.getElement();
+				BrowserManager.getInstance().setCurrentWebBrowser(browser);
+				
+				// if no other browsers are checked, don't allow the single one currently
+				// checked to become unchecked, and lose a current browser. That is, don't
+				// permit unchecking if no other item is checked which is supposed to be the case.
+				Object[] obj = tableViewer.getCheckedElements();
+			   if (obj.length == 0)
+			    	tableViewer.setChecked(e.getElement(), true);
+			}
+		});
+		
+		// set a default, checked browser based on the current browser. If there is not a
+		// current browser, but the first item exists, use that instead.
+		// This will work currently until workbench shutdown, because current browser is not yet persisted.
+		IWebBrowser browser = BrowserManager.getInstance().getCurrentWebBrowser();
+		if (browser != null)
+			tableViewer.setChecked(browser, true);
+		else {
+			Object obj = tableViewer.getElementAt(0);
+			if (obj != null)
+				tableViewer.setChecked(obj, true);
+		}
+		
+		tableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
+			public void selectionChanged(SelectionChangedEvent event) {
+				Object obj = getSelection(event.getSelection());
+				
+				if (obj instanceof IInternalWebBrowser) {
+					selection = (IInternalWebBrowser) obj;
+					remove.setEnabled(false);
+					edit.setEnabled(true);
+				} else if (obj instanceof IExternalWebBrowser) {
+					selection = (IExternalWebBrowser) obj;
+					remove.setEnabled(true);
+					edit.setEnabled(true);
+				} else
+					selection = null;
+				
+				if (selection == null) {
+					edit.setEnabled(false);
+					remove.setEnabled(false);
+				}
+			}
+		});
+		
+		Composite buttonComp = new Composite(this, SWT.NONE);
+		layout = new GridLayout();
+		layout.horizontalSpacing = 0;
+		layout.verticalSpacing = 5;
+		layout.marginWidth = 0;
+		layout.marginHeight = 0;
+		layout.numColumns = 1;
+		buttonComp.setLayout(layout);
+		data = new GridData(GridData.HORIZONTAL_ALIGN_END | GridData.VERTICAL_ALIGN_FILL);
+		buttonComp.setLayoutData(data);
+		
+		Button add = SWTUtil.createButton(buttonComp, WebBrowserUIPlugin.getResource("%add"));
+		add.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				ExternalBrowserDialog dialog = new ExternalBrowserDialog(getShell());
+				if (dialog.open() == Window.CANCEL)
+					return;
+				tableViewer.refresh();
+			}
+		});
+		
+		edit = SWTUtil.createButton(buttonComp, WebBrowserUIPlugin.getResource("%edit"));
+		edit.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				IWebBrowser browser2 = getSelectedWebBrowser();
+
+				if (browser2 instanceof IInternalWebBrowser) {
+					IInternalWebBrowserWorkingCopy wc = ((IInternalWebBrowser) browser2).getWorkingCopy();
+					InternalBrowserDialog dialog = new InternalBrowserDialog(getShell(), wc);
+					if (dialog.open() != Window.CANCEL) {
+						try {
+							tableViewer.refresh(wc.save());
+						} catch (Exception ex) { }
+					}
+				}				
+				else if(browser2 instanceof IExternalWebBrowser) {
+					IExternalWebBrowserWorkingCopy wc = ((IExternalWebBrowser) browser2).getWorkingCopy();
+					ExternalBrowserDialog dialog = new ExternalBrowserDialog(getShell(), wc);
+					if (dialog.open() != Window.CANCEL) {
+						try {
+							tableViewer.refresh(wc.save());
+						} catch (Exception ex) { }
+					}
+				}
+		   }     		
+		});
+		edit.setEnabled(false);
+
+		remove = SWTUtil.createButton(buttonComp, WebBrowserUIPlugin.getResource("%remove"));
+		remove.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				IWebBrowser browser2 = getSelectedWebBrowser();
+				try {
+					if (browser2 instanceof IInternalWebBrowser){
+						remove.setEnabled(false);
+						return; // nothing else possible to do
+                    } 
+					else if(browser2 instanceof IExternalWebBrowser) {
+						remove.setEnabled(true);
+                       ((IExternalWebBrowser) browser2).delete();
+                       
+						tableViewer.remove(browser2);
+						
+						// need here to ensure that if the item deleted was checked, ie, was
+						// the current browser, that the new current browser will be the first in the
+						// list, typically, the internal browser, which cannot be deleted, and be current.
+						if(((IExternalWebBrowser) browser2) == BrowserManager.getInstance().getCurrentWebBrowser()){
+							Object obj = tableViewer.getElementAt(0);
+								if(obj != null){
+									BrowserManager.getInstance().setCurrentWebBrowser((InternalWebBrowser)obj);
+									tableViewer.setChecked(obj, true);
+								}
+						}
+					}
+				} catch (Exception ex) { }
+			}
+		});
+		remove.setEnabled(false);
+		
+		search = SWTUtil.createButton(buttonComp, WebBrowserUIPlugin.getResource("%search"));
+		search.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				java.util.List browsersToCreate = BrowserSearcher.search(getShell());
+				
+				if (browsersToCreate == null) // cancelled
+					return;
+				
+				if (browsersToCreate.isEmpty()) { // no browsers found
+					WebBrowserUtil.openMessage(WebBrowserUIPlugin.getResource("%searchingNoneFound"));
+					return;
+				}
+				
+				Iterator iterator = browsersToCreate.iterator();
+				while (iterator.hasNext()) {
+					IExternalWebBrowserWorkingCopy browser2 = (IExternalWebBrowserWorkingCopy) iterator.next();
+					browser2.save();
+				}
+				tableViewer.refresh();
+			}
+		});
+		WorkbenchHelp.setHelp(search, ContextIds.PREF_BROWSER_EXTERNAL_SEARCH);
+		
+		tableViewer.addCheckStateListener(new ICheckStateListener() {
+			public void checkStateChanged(CheckStateChangedEvent e) {
+				checkNewDefaultBrowser(e.getElement());
+				IWebBrowser browser2 = (IWebBrowser) e.getElement();
+				BrowserManager.getInstance().setCurrentWebBrowser(browser2);
+			}
+		});
+		search.setEnabled(true);
+	}
+	
+	public IWebBrowser getSelectedWebBrowser() {
+		return selection;
+	}
+	
+	protected Object getSelection(ISelection sel2) {
+		IStructuredSelection sel = (IStructuredSelection) sel2;
+		return sel.getFirstElement();
+	}
+	
+	// Uncheck all the items except the current one that was just checked
+	protected void checkNewDefaultBrowser(Object browser) {
+		TableItem[] children = tableViewer.getTable().getItems();
+		for (int i = 0; i < children.length; i++) {
+			TableItem item = children[i];
+			
+			if (!(item.getData().equals(browser))) 
+				item.setChecked(false);
+		}
+	}
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/BrowserTableLabelProvider.java b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/BrowserTableLabelProvider.java
new file mode 100644
index 0000000..789387e
--- /dev/null
+++ b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/BrowserTableLabelProvider.java
@@ -0,0 +1,97 @@
+/**********************************************************************
+ * Copyright (c) 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *    IBM - Initial API and implementation
+ **********************************************************************/
+package net.sourceforge.phpeclipse.webbrowser.internal;
+
+import net.sourceforge.phpeclipse.webbrowser.IExternalWebBrowser;
+import net.sourceforge.phpeclipse.webbrowser.IInternalWebBrowser;
+import net.sourceforge.phpeclipse.webbrowser.IWebBrowser;
+
+import org.eclipse.jface.viewers.ILabelProviderListener;
+
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+/**
+ * Web browser table label provider.
+ */
+public class BrowserTableLabelProvider implements ITableLabelProvider {
+	/**
+	 * BrowserTableLabelProvider constructor comment.
+	 */
+	public BrowserTableLabelProvider() {
+		super();
+	}
+
+	/**
+	 * 
+	 */
+	public void addListener(ILabelProviderListener listener) { }
+
+	/**
+	 * 
+	 */
+	public void dispose() { }
+
+	/**
+	 * 
+	 */
+	public Image getColumnImage(Object element, int columnIndex) {
+		if (columnIndex == 0) {
+			if (element instanceof IInternalWebBrowser)
+				return ImageResource.getImage(ImageResource.IMG_INTERNAL_BROWSER);
+			else
+				return ImageResource.getImage(ImageResource.IMG_EXTERNAL_BROWSER);
+		}
+		return null;
+	}
+
+	/**
+	 * Returns the label text for the given column of the given element.
+	 *
+	 * @param element the object representing the entire row, or
+	 *   null indicating that no input object is set
+	 *   in the viewer
+	 * @param columnIndex the zero-based index of the column in which the label appears
+	 */
+	public String getColumnText(Object element, int columnIndex) {
+		IWebBrowser browser = (IWebBrowser)element;
+		if (browser instanceof IExternalWebBrowser) {
+			if (columnIndex == 0)
+				return notNull(((IExternalWebBrowser)browser).getName());
+			else if (columnIndex == 1)
+				return notNull(((IExternalWebBrowser)browser).getLocation());
+			else if (columnIndex == 2)
+				return notNull(((IExternalWebBrowser)browser).getParameters());
+		} else if(browser instanceof IInternalWebBrowser) {
+			if (columnIndex == 0)
+				return notNull(((IInternalWebBrowser)browser).getName());
+		}
+		return "";
+	}
+	
+	protected String notNull(String s) {
+		if (s != null)
+			return s;
+		else
+			return "";
+	}
+
+	/**
+	 * 
+	 */
+	public boolean isLabelProperty(Object element, String property) {
+		return false;
+	}
+
+	/**
+	 * 
+	 */
+	public void removeListener(ILabelProviderListener listener) { }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/BusyIndicator.java b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/BusyIndicator.java
new file mode 100644
index 0000000..baadaeb
--- /dev/null
+++ b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/BusyIndicator.java
@@ -0,0 +1,157 @@
+/**
+ * Copyright (c) 2003 IBM Corporation and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *    IBM - Initial API and implementation
+ */
+package net.sourceforge.phpeclipse.webbrowser.internal;
+
+import org.eclipse.swt.widgets.*;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.graphics.*;
+/**
+ * An animated image to show busy status of the Web browser.
+ */
+public class BusyIndicator extends Canvas {
+	protected Image[] images;
+	protected Image image;
+
+	protected Thread busyThread;
+	protected boolean stop;
+
+	/**
+	 * BusyWidget constructor comment.
+	 * @param parent org.eclipse.swt.widgets.Composite
+	 * @param style int
+	 */
+	public BusyIndicator(Composite parent, int style) {
+		super(parent, style);
+	
+		images = ImageResource.getBusyImages();
+	
+		addPaintListener(new PaintListener() {
+			public void paintControl(PaintEvent event) {
+				onPaint(event);
+			}
+		});
+	
+		image = images[0];
+	}
+	
+	public Point computeSize(int wHint, int hHint, boolean changed) {
+		return new Point(25, 25);
+	}
+	
+	/**
+	 * Creates a thread to animate the image.
+	 */
+	protected synchronized void createBusyThread() {
+		if (busyThread != null)
+			return;
+	
+		stop = false;
+		busyThread = new Thread() {
+			protected int count;
+			public void run() {
+				try {
+					count = 1;
+					while (!stop) {
+						Display.getDefault().syncExec(new Runnable() {
+							public void run() {
+								if (!stop) {
+									if (count < 13)
+										setImage(images[count]);
+									count++;
+									if (count > 12)
+										count = 1;
+								}
+							}
+						});
+						try {
+							sleep(125);
+						} catch (Exception e) { }
+					}
+					if (busyThread == null)
+						Display.getDefault().syncExec(new Thread() {
+							public void run() {
+								setImage(images[0]);
+							}
+						});
+				} catch (Exception e) {
+					Trace.trace(Trace.WARNING, "Busy error", e);
+				}
+			}
+		};
+	
+		busyThread.setPriority(Thread.NORM_PRIORITY + 2);
+		busyThread.setDaemon(true);
+		busyThread.start();
+	}
+	
+	public void dispose() {
+		stop = true;
+		busyThread = null;
+		super.dispose();
+	}
+	
+	/**
+	 * Return the image or null.
+	 */
+	public Image getImage() {
+		return image;
+	}
+
+	/**
+	 * Returns true if it is currently busy.
+	 *
+	 * @return boolean
+	 */
+	public boolean isBusy() {
+		return (busyThread != null);
+	}
+
+	/* 
+	 * Process the paint event
+	 */
+	protected void onPaint(PaintEvent event) {
+		Rectangle rect = getClientArea();
+		if (rect.width == 0 || rect.height == 0)
+			return;
+	
+		GC gc = event.gc;
+		if (image != null)
+			gc.drawImage(image, 2, 2);
+	}
+
+	/**
+	 * Sets the indicators busy count up (true) or down (false) one.
+	 *
+	 * @param busy boolean
+	 */
+	public synchronized void setBusy(boolean busy) {
+		if (busy) {
+			if (busyThread == null)
+				createBusyThread();
+		} else {
+			if (busyThread != null) {
+				stop = true;
+				busyThread = null;
+			}
+		}
+	}
+
+	/**
+	 * Set the image.
+	 * The value null clears it.
+	 */
+	public void setImage(Image image) {
+		if (image != this.image && !isDisposed()) {
+			this.image = image;
+			redraw();
+		}
+	}
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/ContextIds.java b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/ContextIds.java
new file mode 100644
index 0000000..dbfb19e
--- /dev/null
+++ b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/ContextIds.java
@@ -0,0 +1,25 @@
+/**
+ * Copyright (c) 2003 IBM Corporation and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *    IBM - Initial API and implementation
+ */
+package net.sourceforge.phpeclipse.webbrowser.internal;
+/**
+ * Context help id constants.
+ */
+public interface ContextIds {
+	public static final String PREF_BROWSER = WebBrowserUIPlugin.PLUGIN_ID + ".wbpr0000";
+	public static final String PREF_BROWSER_INTERNAL = WebBrowserUIPlugin.PLUGIN_ID + ".wbpr0002";
+	public static final String PREF_BROWSER_EXTERNAL_ADD = WebBrowserUIPlugin.PLUGIN_ID + ".wbpr0004";
+	public static final String PREF_BROWSER_EXTERNAL_EDIT = WebBrowserUIPlugin.PLUGIN_ID + ".wbpr0005";
+	public static final String PREF_BROWSER_EXTERNAL_SEARCH = WebBrowserUIPlugin.PLUGIN_ID + ".wbpr0006";
+
+	public static final String WEB_BROWSER = WebBrowserUIPlugin.PLUGIN_ID + ".sewb0000";
+	public static final String WEB_BROWSER_URL = WebBrowserUIPlugin.PLUGIN_ID + ".sewb0002";
+	public static final String WEB_BROWSER_WEB = WebBrowserUIPlugin.PLUGIN_ID + ".sewb0004";
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/ExternalBrowserDialog.java b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/ExternalBrowserDialog.java
new file mode 100644
index 0000000..f6aadff
--- /dev/null
+++ b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/ExternalBrowserDialog.java
@@ -0,0 +1,203 @@
+/**********************************************************************
+ * Copyright (c) 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *    IBM - Initial API and implementation
+ **********************************************************************/
+package net.sourceforge.phpeclipse.webbrowser.internal;
+
+import java.io.File;
+
+import net.sourceforge.phpeclipse.webbrowser.IExternalWebBrowserWorkingCopy;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.help.WorkbenchHelp;
+/**
+ * 
+ */
+public class ExternalBrowserDialog extends Dialog {
+	protected IExternalWebBrowserWorkingCopy browser;
+	protected boolean isEdit;
+	protected Button newPageCheckbox;
+	protected Button clearHistoryCheckbox;
+	protected Button browseButton;
+	protected Text browserNameTextfield;
+	protected Text browserLocationTextfield;
+	protected Text browserParametersTextfield;
+	private Button okButton;
+	
+	interface StringModifyListener {
+		public void valueChanged(String s);
+	}
+	
+	/**
+	 * @param parentShell
+	 */
+	public ExternalBrowserDialog(Shell parentShell, IExternalWebBrowserWorkingCopy browser) {
+		super(parentShell);
+		this.browser = browser;
+		isEdit = true;
+	}
+
+	public ExternalBrowserDialog(Shell parentShell) {
+		super(parentShell);
+		browser = BrowserManager.getInstance().createExternalWebBrowser();
+		isEdit = false;
+	}
+
+	protected void configureShell(Shell shell) {
+		super.configureShell(shell);
+		
+		if (isEdit)
+			shell.setText(WebBrowserUIPlugin.getResource("%editExternalBrowser"));
+		else
+			shell.setText(WebBrowserUIPlugin.getResource("%createBrowser"));
+	}
+
+	protected Text createText(Composite comp, String txt, final StringModifyListener listener) {
+		final Text text = new Text(comp, SWT.BORDER);
+		if (txt != null)
+			text.setText(txt);
+		GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_BEGINNING);
+		data.widthHint = 250;
+		text.setLayoutData(data);
+		if (listener != null)
+			text.addModifyListener(new ModifyListener() {
+				public void modifyText(ModifyEvent e) {	
+					listener.valueChanged(text.getText());
+				}
+			});
+		return text;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
+	 */
+	protected Control createDialogArea(Composite parent) {
+		Composite composite = (Composite) super.createDialogArea(parent);
+		((GridLayout)composite.getLayout()).numColumns = 3;
+		
+		if (isEdit)
+			WorkbenchHelp.setHelp(composite, ContextIds.PREF_BROWSER_EXTERNAL_EDIT);
+		else
+			WorkbenchHelp.setHelp(composite, ContextIds.PREF_BROWSER_EXTERNAL_ADD);
+		
+		SWTUtil.createLabel(composite, WebBrowserUIPlugin.getResource("%name"));
+		browserNameTextfield = createText(composite, browser.getName(), new StringModifyListener() {
+			public void valueChanged(String s) {
+				browser.setName(s);
+				validateFields();
+			}
+		});
+		
+		new Label(composite, SWT.NONE);
+	
+		SWTUtil.createLabel(composite, WebBrowserUIPlugin.getResource("%location"));
+		browserLocationTextfield = createText(composite, browser.getLocation(), new StringModifyListener() {
+			public void valueChanged(String s) {
+				browser.setLocation(s);
+				validateFields();
+			}
+		});		
+		
+		browseButton = SWTUtil.createButton(composite, WebBrowserUIPlugin.getResource("%browse"));
+		browseButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				FileDialog dialog = new FileDialog(getShell(), SWT.OPEN);
+				dialog.setText(WebBrowserUIPlugin.getResource("%browseMessage"));
+				
+				String fname = browserLocationTextfield.getText();
+				
+				dialog.setFileName(fname);
+				fname = dialog.open();
+				
+				if (fname != null)
+					browserLocationTextfield.setText(fname);
+			}
+		});
+		
+		SWTUtil.createLabel(composite, WebBrowserUIPlugin.getResource("%parameters"));
+		browserParametersTextfield = createText(composite, browser.getParameters(), new StringModifyListener() {
+			public void valueChanged(String s) {
+				browser.setParameters(s);
+			}
+		});
+
+		new Label(composite, SWT.NONE);
+		
+		new Label(composite, SWT.NONE);
+		Label urlLabel = new Label(composite, SWT.NONE);
+		urlLabel.setText(WebBrowserUIPlugin.getResource("%parametersMessage", WebBrowserPreference.URL_PARAMETER));
+	
+		
+		return composite;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.dialogs.Dialog#okPressed()
+	 */
+	protected void okPressed() {
+		// do simple field validation to at least ensure target directory entered is valid pathname
+		try {
+		File file = new File(browser.getLocation());
+			if(!file.isFile()){
+				WebBrowserUtil.openError(WebBrowserUIPlugin.getResource("%locationInvalid"));
+				return;
+			}
+		}
+		catch(Exception e){
+			WebBrowserUtil.openError(WebBrowserUIPlugin.getResource("%locationInvalid"));
+			return;
+		}
+		
+		browser.save();
+		super.okPressed();
+	}
+	
+	private void setOKButtonEnabled(boolean curIsEnabled) {
+		if (okButton == null)
+			okButton = getButton(IDialogConstants.OK_ID);
+		
+		if (okButton != null)
+			okButton.setEnabled(curIsEnabled);
+	}
+	
+	protected Control createButtonBar(Composite parent) {
+		Control buttonControl = super.createButtonBar(parent);
+		validateFields();
+		return buttonControl;
+	}
+	
+	protected void validateFields() {
+		boolean valid = true;
+		
+		String name = browserNameTextfield.getText();
+		if (name == null || name.trim().length() < 1)
+			valid = false;
+		
+		String location = browserLocationTextfield.getText();
+		if (location == null || location.trim().length() < 1)
+			valid = false;
+		
+		setOKButtonEnabled(valid);
+	}
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/ExternalWebBrowser.java b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/ExternalWebBrowser.java
new file mode 100644
index 0000000..10e5086
--- /dev/null
+++ b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/ExternalWebBrowser.java
@@ -0,0 +1,140 @@
+package net.sourceforge.phpeclipse.webbrowser.internal;
+
+import java.net.URL;
+
+import net.sourceforge.phpeclipse.webbrowser.IExternalWebBrowser;
+import net.sourceforge.phpeclipse.webbrowser.IExternalWebBrowserWorkingCopy;
+
+import org.eclipse.swt.program.Program;
+import org.eclipse.ui.IMemento;
+/**
+ * 
+ */
+public class ExternalWebBrowser implements IExternalWebBrowser {
+	private static final String MEMENTO_NAME = "name";
+	private static final String MEMENTO_LOCATION = "location";
+	private static final String MEMENTO_PARAMETERS = "parameters";
+
+	protected String name;
+	protected String location;
+	protected String parameters;
+	
+	/* (non-Javadoc)
+	 * @see net.sourceforge.phpeclipse.webbrowser.IWebBrowser#getName()
+	 */
+	public String getName() {
+		return name;
+	}
+
+	/* (non-Javadoc)
+	 * @see net.sourceforge.phpeclipse.webbrowser.IExternalWebBrowser#getLocation()
+	 */
+	public String getLocation() {
+		return location;
+	}
+
+	/* (non-Javadoc)
+	 * @see net.sourceforge.phpeclipse.webbrowser.IExternalWebBrowser#getParameters()
+	 */
+	public String getParameters() {
+		return parameters;
+	}
+	
+	public void delete() {
+		BrowserManager.getInstance().removeWebBrowser(this);
+	}
+
+	public boolean isWorkingCopy() {
+		return false;
+	}
+
+	public IExternalWebBrowserWorkingCopy getWorkingCopy() {
+		return new ExternalWebBrowserWorkingCopy(this);
+	}
+
+	protected void setInternal(IExternalWebBrowser browser) {
+		name = browser.getName();
+		location = browser.getLocation();
+		parameters = browser.getParameters();
+	}
+
+	/* (non-Javadoc)
+	 * @see net.sourceforge.phpeclipse.webbrowser.IWebBrowser#openURL(java.net.URL)
+	 */
+	public void openURL(URL url) {
+		String urlText = WebBrowserPreference.getHomePageURL();
+		
+		if (url != null)
+			urlText = url.toExternalForm();
+		else if (urlText.startsWith("file:") & urlText.length() > 6) {
+			if (urlText.charAt(5) != '/' && urlText.charAt(5) != '\\')
+				urlText = urlText.substring(0, 5) + "/" + urlText.substring(5);
+		}
+
+		// change spaces to "%20"
+		if (!WebBrowserUtil.isWindows()) {
+			int index = urlText.indexOf(" ");
+			while (index >= 0) {
+				urlText = urlText.substring(0, index) + "%20" + urlText.substring(index + 1);
+				index = urlText.indexOf(" ");
+			}
+		}
+
+		Trace.trace(Trace.FINEST, "Launching external Web browser: " + location + " - " + parameters + " - " + urlText);
+		if (location == null || location.length() == 0) {
+			try {
+				String extension = null;
+				if (url != null)
+					extension = url.getFile();
+				else
+					extension = "html";
+				int index = extension.indexOf(".");
+				if (index >= 0)
+					extension = extension.substring(index + 1);
+				Program program = Program.findProgram(extension);
+				program.execute(urlText);
+			} catch (Exception e) {
+				Trace.trace(Trace.SEVERE, "Error launching default external browser", e);
+				WebBrowserUtil.openError(WebBrowserUIPlugin.getResource("%errorCouldNotLaunchWebBrowser", urlText));
+			}
+			return;
+		}
+		
+		String params = parameters;
+		if (params == null)
+			params = "";
+		
+		int urlIndex = params.indexOf(WebBrowserPreference.URL_PARAMETER);
+		if (urlIndex >= 0)
+			params = params.substring(0, urlIndex) + " " + urlText + " " + params.substring(urlIndex + WebBrowserPreference.URL_PARAMETER.length());
+		else {
+			if (!params.endsWith(" "))
+				params += " ";
+			params += urlText;
+		}
+		
+		try {
+			Trace.trace(Trace.FINEST, "Launching " + location + " " + params);
+			Runtime.getRuntime().exec(location + " " + params);
+		} catch (Exception e) {
+			Trace.trace(Trace.SEVERE, "Could not launch external browser", e);
+			WebBrowserUtil.openError(WebBrowserUIPlugin.getResource("%errorCouldNotLaunchWebBrowser", urlText));
+		}
+	}
+
+	protected void save(IMemento memento) {
+		memento.putString(MEMENTO_NAME, name);
+		memento.putString(MEMENTO_LOCATION, location);
+		memento.putString(MEMENTO_PARAMETERS, parameters);
+	}
+
+	protected void load(IMemento memento) {
+		name = memento.getString(MEMENTO_NAME);
+		location = memento.getString(MEMENTO_LOCATION);
+		parameters = memento.getString(MEMENTO_PARAMETERS);
+	}
+
+	public String toString() {
+		return "External Web browser: " + getName() + " / " + getLocation() + " / " + getParameters();
+	}
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/ExternalWebBrowserWorkingCopy.java b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/ExternalWebBrowserWorkingCopy.java
new file mode 100644
index 0000000..c3ef3c7
--- /dev/null
+++ b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/ExternalWebBrowserWorkingCopy.java
@@ -0,0 +1,63 @@
+package net.sourceforge.phpeclipse.webbrowser.internal;
+
+import net.sourceforge.phpeclipse.webbrowser.IExternalWebBrowser;
+import net.sourceforge.phpeclipse.webbrowser.IExternalWebBrowserWorkingCopy;
+/**
+ * 
+ */
+public class ExternalWebBrowserWorkingCopy extends ExternalWebBrowser implements IExternalWebBrowserWorkingCopy {
+	protected ExternalWebBrowser browser;
+
+	// creation
+	public ExternalWebBrowserWorkingCopy() { }
+
+	// working copy
+	public ExternalWebBrowserWorkingCopy(ExternalWebBrowser browser) {
+		this.browser = browser;
+		setInternal(browser);
+	}
+
+	/* (non-Javadoc)
+	 * @see net.sourceforge.phpeclipse.webbrowser.IExternalWebBrowserWorkingCopy#setName(java.lang.String)
+	 */
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	/* (non-Javadoc)
+	 * @see net.sourceforge.phpeclipse.webbrowser.IExternalWebBrowserWorkingCopy#setLocation(java.lang.String)
+	 */
+	public void setLocation(String location) {
+		this.location = location;
+	}
+
+	/* (non-Javadoc)
+	 * @see net.sourceforge.phpeclipse.webbrowser.IExternalWebBrowserWorkingCopy#setParameters(java.lang.String)
+	 */
+	public void setParameters(String params) {
+		this.parameters = params;
+	}
+
+	public boolean isWorkingCopy() {
+		return true;
+	}
+	
+	public IExternalWebBrowserWorkingCopy getWorkingCopy() {
+		return this;
+	}
+
+	/* (non-Javadoc)
+	 * @see net.sourceforge.phpeclipse.webbrowser.IExternalWebBrowserWorkingCopy#save()
+	 */
+	public IExternalWebBrowser save() {
+		if (browser != null) {
+			browser.setInternal(this);
+			BrowserManager.getInstance().browserChanged(browser);
+		} else {
+			browser = new ExternalWebBrowser();
+			browser.setInternal(this);
+			BrowserManager.getInstance().addBrowser(browser);
+		}
+		return browser;
+	}
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/Favorite.java b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/Favorite.java
new file mode 100644
index 0000000..1009eff
--- /dev/null
+++ b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/Favorite.java
@@ -0,0 +1,57 @@
+/**
+ * Copyright (c) 2003 IBM Corporation and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *    IBM - Initial API and implementation
+ */
+package net.sourceforge.phpeclipse.webbrowser.internal;
+/**
+ * 
+ */
+public class Favorite {
+	protected String url;
+	protected String name;
+
+	public Favorite() { }
+	
+	public Favorite(String name, String url) {
+		if (name == null)
+			name = "";
+		if (url == null)
+			url = "";
+		this.name = name;
+		this.url = url;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public String getURL() {
+		return url;
+	}
+
+	public void setURL(String url) {
+		this.url = url;
+	}
+	
+	public boolean equals(Object obj) {
+		if (!(obj instanceof Favorite))
+			return false;
+		
+		Favorite f = (Favorite) obj;
+		return (name.equals(f.name) && url.equals(f.url));
+	}
+	
+	public String toString() {
+		return "(" + name + "/" + url + ")";
+	}
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/IWebBrowserListener.java b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/IWebBrowserListener.java
new file mode 100644
index 0000000..97e20dc
--- /dev/null
+++ b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/IWebBrowserListener.java
@@ -0,0 +1,24 @@
+/**********************************************************************
+ * Copyright (c) 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *    IBM - Initial API and implementation
+ **********************************************************************/
+package net.sourceforge.phpeclipse.webbrowser.internal;
+
+import net.sourceforge.phpeclipse.webbrowser.IWebBrowser;
+
+/**
+ * 
+ */
+public interface IWebBrowserListener {
+	public void browserAdded(IWebBrowser browser);
+	
+	public void browserChanged(IWebBrowser browser);
+	
+	public void browserRemoved(IWebBrowser browser);
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/ImageResource.java b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/ImageResource.java
new file mode 100644
index 0000000..aaa2c4c
--- /dev/null
+++ b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/ImageResource.java
@@ -0,0 +1,185 @@
+/**
+ * Copyright (c) 2003 IBM Corporation and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *    IBM - Initial API and implementation
+ */
+package net.sourceforge.phpeclipse.webbrowser.internal;
+
+import java.net.URL;
+import java.util.Map;
+import java.util.HashMap;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+/**
+ * Utility class to handle image resources.
+ */
+public class ImageResource {
+	// the image registry
+	private static ImageRegistry imageRegistry;
+
+	// map of image descriptors since these
+	// will be lost by the image registry
+	private static Map imageDescriptors;
+
+	// base urls for images
+	private static URL ICON_BASE_URL;
+
+	static {
+		try {
+			String pathSuffix = "icons/";
+			ICON_BASE_URL = WebBrowserUIPlugin.getInstance().getBundle().getEntry(pathSuffix);
+		} catch (Exception e) {
+			Trace.trace(Trace.SEVERE, "Could not set icon base URL", e);
+		}
+	}
+
+	private static Image[] busyImages;
+
+	private static final String URL_CLCL = "clcl16/";
+	private static final String URL_ELCL = "elcl16/";
+	private static final String URL_DLCL = "dlcl16/";
+
+	private static final String URL_OBJ = "obj16/";
+
+	// --- constants for images ---
+	// toolbar images
+	public static final String IMG_CLCL_NAV_BACKWARD = "IMG_CLCL_NAV_BACKWARD";
+	public static final String IMG_CLCL_NAV_FORWARD = "IMG_CLCL_NAV_FORWARD";
+	public static final String IMG_CLCL_NAV_STOP = "IMG_CLCL_NAV_STOP";
+	public static final String IMG_CLCL_NAV_REFRESH = "IMG_CLCL_NAV_REFRESH";
+	public static final String IMG_CLCL_NAV_GO = "IMG_CLCL_NAV_GO";
+	public static final String IMG_CLCL_NAV_FAVORITES = "cfavorites";
+	public static final String IMG_CLCL_NAV_HOME = "IMG_CLCL_NAV_HOME";
+	public static final String IMG_CLCL_NAV_PRINT = "IMG_CLCL_NAV_PRINT";
+
+	public static final String IMG_ELCL_NAV_BACKWARD = "IMG_ELCL_NAV_BACKWARD";
+	public static final String IMG_ELCL_NAV_FORWARD = "IMG_ELCL_NAV_FORWARD";
+	public static final String IMG_ELCL_NAV_STOP = "IMG_ELCL_NAV_STOP";
+	public static final String IMG_ELCL_NAV_REFRESH = "IMG_ELCL_NAV_REFRESH";
+	public static final String IMG_ELCL_NAV_GO = "IMG_ELCL_NAV_GO";
+	public static final String IMG_ELCL_NAV_FAVORITES = "efavorites";
+	public static final String IMG_ELCL_NAV_HOME = "IMG_ELCL_NAV_HOME";
+	public static final String IMG_ELCL_NAV_PRINT = "IMG_ELCL_NAV_PRINT";
+
+	public static final String IMG_DLCL_NAV_BACKWARD = "IMG_DLCL_NAV_BACKWARD";
+	public static final String IMG_DLCL_NAV_FORWARD = "IMG_DLCL_NAV_FORWARD";
+	public static final String IMG_DLCL_NAV_STOP = "IMG_DLCL_NAV_STOP";
+	public static final String IMG_DLCL_NAV_REFRESH = "IMG_DLCL_NAV_REFRESH";
+	public static final String IMG_DLCL_NAV_GO = "IMG_DLCL_NAV_GO";
+	public static final String IMG_DLCL_NAV_FAVORITES = "dfavorites";
+	public static final String IMG_DLCL_NAV_HOME = "IMG_DLCL_NAV_HOME";
+	public static final String IMG_DLCL_NAV_PRINT = "IMG_DLCL_NAV_PRINT";
+
+	// general object images
+	public static final String IMG_INTERNAL_BROWSER = "internalBrowser";
+	public static final String IMG_EXTERNAL_BROWSER = "externalBrowser";
+	public static final String IMG_FAVORITE = "favorite";
+
+	/**
+	 * Cannot construct an ImageResource. Use static methods only.
+	 */
+	private ImageResource() { }
+
+	/**
+	 * Returns the busy images for the Web browser.
+	 *
+	 * @return org.eclipse.swt.graphics.Image[]
+	 */
+	public static Image[] getBusyImages() {
+		return busyImages;
+	}
+
+	/**
+	 * Return the image with the given key.
+	 *
+	 * @param key java.lang.String
+	 * @return org.eclipse.swt.graphics.Image
+	 */
+	public static Image getImage(String key) {
+		if (imageRegistry == null)
+			initializeImageRegistry();
+		return imageRegistry.get(key);
+	}
+
+	/**
+	 * Return the image descriptor with the given key.
+	 *
+	 * @param key java.lang.String
+	 * @return org.eclipse.jface.resource.ImageDescriptor
+	 */
+	public static ImageDescriptor getImageDescriptor(String key) {
+		if (imageRegistry == null)
+			initializeImageRegistry();
+		return (ImageDescriptor) imageDescriptors.get(key);
+	}
+
+	/**
+	 * Initialize the image resources.
+	 */
+	protected static void initializeImageRegistry() {
+		imageRegistry = new ImageRegistry();
+		imageDescriptors = new HashMap();
+	
+		// load Web browser images
+		registerImage(IMG_ELCL_NAV_BACKWARD, URL_ELCL + "nav_backward.gif");
+		registerImage(IMG_ELCL_NAV_FORWARD, URL_ELCL + "nav_forward.gif");
+		registerImage(IMG_ELCL_NAV_STOP, URL_ELCL + "nav_stop.gif");
+		registerImage(IMG_ELCL_NAV_REFRESH, URL_ELCL + "nav_refresh.gif");
+		registerImage(IMG_ELCL_NAV_GO, URL_ELCL + "nav_go.gif");
+		registerImage(IMG_ELCL_NAV_FAVORITES, URL_ELCL + "add_favorite.gif");
+		registerImage(IMG_ELCL_NAV_HOME, URL_ELCL + "nav_home.gif");
+		registerImage(IMG_ELCL_NAV_PRINT, URL_ELCL + "nav_print.gif");
+	
+		registerImage(IMG_CLCL_NAV_BACKWARD, URL_CLCL + "nav_backward.gif");
+		registerImage(IMG_CLCL_NAV_FORWARD, URL_CLCL + "nav_forward.gif");
+		registerImage(IMG_CLCL_NAV_STOP, URL_CLCL + "nav_stop.gif");
+		registerImage(IMG_CLCL_NAV_REFRESH, URL_CLCL + "nav_refresh.gif");
+		registerImage(IMG_CLCL_NAV_GO, URL_CLCL + "nav_go.gif");
+		registerImage(IMG_CLCL_NAV_FAVORITES, URL_CLCL + "add_favorite.gif");
+		registerImage(IMG_CLCL_NAV_HOME, URL_CLCL + "nav_home.gif");
+		registerImage(IMG_CLCL_NAV_PRINT, URL_CLCL + "nav_print.gif");
+	
+		registerImage(IMG_DLCL_NAV_BACKWARD, URL_DLCL + "nav_backward.gif");
+		registerImage(IMG_DLCL_NAV_FORWARD, URL_DLCL + "nav_forward.gif");
+		registerImage(IMG_DLCL_NAV_STOP, URL_DLCL + "nav_stop.gif");
+		registerImage(IMG_DLCL_NAV_REFRESH, URL_DLCL + "nav_refresh.gif");
+		registerImage(IMG_DLCL_NAV_GO, URL_DLCL + "nav_go.gif");
+		registerImage(IMG_DLCL_NAV_FAVORITES, URL_DLCL + "add_favorite.gif");
+		registerImage(IMG_DLCL_NAV_HOME, URL_DLCL + "nav_home.gif");
+		registerImage(IMG_DLCL_NAV_PRINT, URL_DLCL + "nav_print.gif");
+	
+		registerImage(IMG_INTERNAL_BROWSER, URL_OBJ + "internal_browser.gif");
+		registerImage(IMG_EXTERNAL_BROWSER, URL_OBJ + "external_browser.gif");
+		
+		registerImage(IMG_FAVORITE, URL_OBJ + "favorite.gif");
+		
+		// busy images
+		busyImages = new Image[13];
+		for (int i = 0; i < 13; i++) {
+			registerImage("busy" + i, URL_OBJ + "frames" + java.io.File.separator + "frame" + (i+1) + ".gif");
+			busyImages[i] = getImage("busy" + i);
+		}
+	}
+
+	/**
+	 * Register an image with the registry.
+	 *
+	 * @param key java.lang.String
+	 * @param partialURL java.lang.String
+	 */
+	private static void registerImage(String key, String partialURL) {
+		try {
+			ImageDescriptor id = ImageDescriptor.createFromURL(new URL(ICON_BASE_URL, partialURL));
+			imageRegistry.put(key, id);
+			imageDescriptors.put(key, id);
+		} catch (Exception e) {
+			Trace.trace(Trace.WARNING, "Error registering image " + key + " from " + partialURL, e);
+		}
+	}
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/InternalBrowserDialog.java b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/InternalBrowserDialog.java
new file mode 100644
index 0000000..11cb860
--- /dev/null
+++ b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/InternalBrowserDialog.java
@@ -0,0 +1,84 @@
+/**********************************************************************
+ * Copyright (c) 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *    IBM - Initial API and implementation
+ **********************************************************************/
+package net.sourceforge.phpeclipse.webbrowser.internal;
+
+import net.sourceforge.phpeclipse.webbrowser.IInternalWebBrowserWorkingCopy;
+import net.sourceforge.phpeclipse.webbrowser.internal.SWTUtil;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.help.WorkbenchHelp;
+/**
+ * 
+ */
+public class InternalBrowserDialog extends Dialog {
+	protected IInternalWebBrowserWorkingCopy browser;
+	protected boolean isEdit;
+	protected Button newPageCheckbox;
+	protected Button clearURLHistoryCheckbox;
+	
+	/**
+	 * @param parentShell
+	 */
+	public InternalBrowserDialog(Shell parentShell, IInternalWebBrowserWorkingCopy browser) {
+		super(parentShell);
+		this.browser = browser;
+		isEdit = true;
+	}
+
+	protected void configureShell(Shell shell) {
+		super.configureShell(shell);
+		
+		if (isEdit)
+			shell.setText(WebBrowserUIPlugin.getResource("%editInternalBrowser"));
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
+	 */
+	protected Control createDialogArea(Composite parent) {
+		Composite composite = (Composite) super.createDialogArea(parent);
+		((GridLayout)composite.getLayout()).numColumns = 1;
+		
+		Composite comp = new Composite(composite, SWT.NONE);
+		GridLayout layout = new GridLayout(1, true);
+		layout.marginHeight = 10;
+		layout.marginWidth = 10;
+		comp.setLayout(layout);
+		comp.setLayoutData(new GridData(GridData.FILL_BOTH));
+		WorkbenchHelp.setHelp(composite, ContextIds.PREF_BROWSER_INTERNAL);
+		
+		newPageCheckbox = SWTUtil.createCheckbox(comp, WebBrowserUIPlugin.getResource("%prefBrowserNewPage"), false);
+		clearURLHistoryCheckbox = SWTUtil.createCheckbox(comp, WebBrowserUIPlugin.getResource("%clearURLHistory"), true);
+		
+		newPageCheckbox.setSelection(browser.getUseNewPage());
+		clearURLHistoryCheckbox.setSelection(browser.getClearHistoryOnExit());
+		
+		return composite;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.dialogs.Dialog#okPressed()
+	 */
+	protected void okPressed() {
+		browser.setUseNewPage(newPageCheckbox.getSelection());
+		browser.setClearHistoryOnExit(clearURLHistoryCheckbox.getSelection());
+		browser.save();
+		
+		super.okPressed();
+	}
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/InternalWebBrowser.java b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/InternalWebBrowser.java
new file mode 100644
index 0000000..05a02ac
--- /dev/null
+++ b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/InternalWebBrowser.java
@@ -0,0 +1,77 @@
+package net.sourceforge.phpeclipse.webbrowser.internal;
+
+import java.net.URL;
+
+import net.sourceforge.phpeclipse.webbrowser.IInternalWebBrowser;
+import net.sourceforge.phpeclipse.webbrowser.IInternalWebBrowserWorkingCopy;
+import net.sourceforge.phpeclipse.webbrowser.WebBrowserEditorInput;
+
+import org.eclipse.ui.IMemento;
+/**
+ * 
+ */
+public class InternalWebBrowser implements IInternalWebBrowser {
+	private static final String MEMENTO_NEW_PAGE = "new_page";
+	private static final String MEMENTO_CLEAR_HISTORY_ON_EXIT = "clear_history";
+
+	protected boolean useNewPage;
+	protected boolean clearHistory;
+
+	/* (non-Javadoc)
+	 * @see net.sourceforge.phpeclipse.webbrowser.IWebBrowser#getName()
+	 */
+	public String getName() {
+		return WebBrowserUIPlugin.getResource("%internalWebBrowserName");
+	}
+	
+	public boolean getUseNewPage() {
+		return useNewPage;
+	}
+	
+	public boolean getClearHistoryOnExit() {
+		return clearHistory;
+	}
+	
+	public boolean isWorkingCopy() {
+		return false;
+	}
+
+	public IInternalWebBrowserWorkingCopy getWorkingCopy() {
+		return new InternalWebBrowserWorkingCopy(this);
+	}
+	
+	protected void setInternal(IInternalWebBrowser browser) {
+		useNewPage = browser.getUseNewPage();
+		clearHistory = browser.getClearHistoryOnExit();
+	}
+
+	/* (non-Javadoc)
+	 * @see net.sourceforge.phpeclipse.webbrowser.IWebBrowser#openURL(java.net.URL)
+	 */
+	public void openURL(URL url) {
+		WebBrowserEditor.open(new WebBrowserEditorInput(url));
+	}
+	
+	protected void save(IMemento memento) {
+		memento.putString(MEMENTO_NEW_PAGE, useNewPage ? "true" : "false");
+		memento.putString(MEMENTO_CLEAR_HISTORY_ON_EXIT, clearHistory ? "true" : "false");
+	}
+
+	protected void load(IMemento memento) {
+		String s = memento.getString(MEMENTO_NEW_PAGE);
+		if ("true".equals(s))
+			useNewPage = true;
+		else
+			useNewPage = false;
+		
+		s = memento.getString(MEMENTO_CLEAR_HISTORY_ON_EXIT);
+		if ("true".equals(s))
+			clearHistory = true;
+		else
+			clearHistory = false;
+	}
+	
+	public String toString() {
+		return "Internal Web browser";
+	}
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/InternalWebBrowserWorkingCopy.java b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/InternalWebBrowserWorkingCopy.java
new file mode 100644
index 0000000..671f74b
--- /dev/null
+++ b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/InternalWebBrowserWorkingCopy.java
@@ -0,0 +1,43 @@
+package net.sourceforge.phpeclipse.webbrowser.internal;
+
+import net.sourceforge.phpeclipse.webbrowser.IInternalWebBrowser;
+import net.sourceforge.phpeclipse.webbrowser.IInternalWebBrowserWorkingCopy;
+/**
+ * 
+ */
+public class InternalWebBrowserWorkingCopy extends InternalWebBrowser implements IInternalWebBrowserWorkingCopy {
+	protected InternalWebBrowser browser;
+
+	// working copy
+	public InternalWebBrowserWorkingCopy(InternalWebBrowser browser) {
+		this.browser = browser;
+		setInternal(browser);
+	}
+
+	public void setUseNewPage(boolean b) {
+		useNewPage = b;
+	}
+	
+	public void setClearHistoryOnExit(boolean b) {
+		clearHistory = b;
+	}
+
+	public boolean isWorkingCopy() {
+		return true;
+	}
+	
+	public IInternalWebBrowserWorkingCopy getWorkingCopy() {
+		return this;
+	}
+
+	/* (non-Javadoc)
+	 * @see net.sourceforge.phpeclipse.webbrowser.IExternalWebBrowserWorkingCopy#save()
+	 */
+	public IInternalWebBrowser save() {
+		if (browser != null) {
+			browser.setInternal(this);
+			BrowserManager.getInstance().browserChanged(browser);
+		}
+		return browser;
+	}
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/InternetPreferencePage.java b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/InternetPreferencePage.java
new file mode 100644
index 0000000..cc403d8
--- /dev/null
+++ b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/InternetPreferencePage.java
@@ -0,0 +1,70 @@
+/**
+ * Copyright (c) 2003 IBM Corporation and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *    IBM - Initial API and implementation
+ */
+package net.sourceforge.phpeclipse.webbrowser.internal;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.eclipse.ui.help.WorkbenchHelp;
+/**
+ * A preference page that holds internet preferences.
+ */
+public class InternetPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
+	/**
+	 * InternetPreferencePage constructor comment.
+	 */
+	public InternetPreferencePage() {
+		super();
+		noDefaultAndApplyButton();
+	}
+
+	/**
+	 * Create the preference options.
+	 *
+	 * @param parent org.eclipse.swt.widgets.Composite
+	 * @return org.eclipse.swt.widgets.Control
+	 */
+	protected Control createContents(Composite parent) {
+		initializeDialogUnits(parent);
+		
+		Composite composite = new Composite(parent, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 1;
+		layout.horizontalSpacing = convertHorizontalDLUsToPixels(4);
+		layout.verticalSpacing = convertVerticalDLUsToPixels(4);
+		layout.marginWidth = 0;
+		layout.marginHeight = 0;
+		composite.setLayout(layout);
+		GridData data = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL);
+		composite.setLayoutData(data);
+		WorkbenchHelp.setHelp(composite, ContextIds.PREF_BROWSER);
+		
+		Label label = new Label(composite, SWT.WRAP);
+		label.setText(WebBrowserUIPlugin.getResource("%preferenceInternetDescription"));
+		data = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+		label.setLayoutData(data);
+		
+		Dialog.applyDialogFont(composite);
+		
+		return composite;
+	}
+
+	/**
+	 * Initializes this preference page using the passed desktop.
+	 *
+	 * @param desktop the current desktop
+	 */
+	public void init(IWorkbench workbench) { }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/OpenWithBrowserActionDelegate.java b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/OpenWithBrowserActionDelegate.java
new file mode 100644
index 0000000..c82da80
--- /dev/null
+++ b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/OpenWithBrowserActionDelegate.java
@@ -0,0 +1,90 @@
+/**
+ * Copyright (c) 2003 IBM Corporation and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *    IBM - Initial API and implementation
+ */
+package net.sourceforge.phpeclipse.webbrowser.internal;
+
+import java.net.URL;
+import java.util.Iterator;
+
+import net.sourceforge.phpeclipse.webbrowser.WebBrowser;
+import net.sourceforge.phpeclipse.webbrowser.WebBrowserEditorInput;
+import net.sourceforge.phpeclipse.webbrowser.internal.Trace;
+
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.ui.*;
+import org.eclipse.core.resources.IResource;
+/**
+ * Action to open the Web broswer on a resource.
+ */
+public class OpenWithBrowserActionDelegate implements IActionDelegate {
+	private IResource resource;
+
+	/**
+	 * OpenBrowserAction constructor comment.
+	 */
+	public OpenWithBrowserActionDelegate() {
+		super();
+	}
+
+	/**
+	 * Performs this action.
+	 * IAction.
+	 */
+	public void run() {
+		BrowserManager.getInstance().setCurrentWebBrowser(webbrowser);
+	}
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/TextAction.java b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/TextAction.java
new file mode 100644
index 0000000..fa8c0b6
--- /dev/null
+++ b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/TextAction.java
@@ -0,0 +1,147 @@
+/**
+ * Copyright (c) 2003 IBM Corporation and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *    IBM - Initial API and implementation
+ */
+package net.sourceforge.phpeclipse.webbrowser.internal;
+
+import net.sourceforge.phpeclipse.webbrowser.internal.WebBrowser;
+
+import org.eclipse.swt.SWTError;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.dnd.*;
+import org.eclipse.jface.action.Action;
+/**
+ * Text actions (cut, copy, paste) for the Web browser.
+ */
+public class TextAction extends Action {
+	protected WebBrowser browser;
+	protected byte type;
+
+	public static final byte CUT = 0;
+	public static final byte COPY = 1;
+	public static final byte PASTE = 2;
+	
+	/**
+	 * TextAction constructor comment.
+	 */
+	protected TextAction(WebBrowser browser, byte type) {
+		super(type + "!");
+		this.browser = browser;
+		this.type = type;
+	}
+	
+	/**
+	 * Copies the selected text to the clipboard.  The text will be put in the 
+	 * clipboard in plain text format.
+	 * 
+	 *    
+	 */
+	public void copy() {
+		Point selection = browser.combo.getSelection();
+	
+		int length = selection.y - selection.x;
+		if (length > 0) {
+			TextTransfer plainTextTransfer = TextTransfer.getInstance();
+			try {
+				browser.clipboard.setContents(
+					new String[] { browser.combo.getText().substring(selection.x, selection.y) }, 
+					new Transfer[] { plainTextTransfer });
+			} catch (SWTError error) {
+				// Copy to clipboard failed. This happens when another application 
+				// is accessing the clipboard while we copy. Ignore the error.
+				// Fixes 1GDQAVN
+			}
+		}
+	}
+	
+	/**
+	 * Moves the selected text to the clipboard.  The text will be put in the 
+	 * clipboard in plain text format and RTF format.
+	 * 
+	 *    
+	 */
+	public void cut(){
+		Point selection = browser.combo.getSelection();
+	
+		if (selection.y > selection.x) {
+			copy();
+			delete();
+		}
+	}
+	
+	/**
+	 * Deletes the character to the right of the caret. Delete the selected text if any.
+	 */
+	public void delete() {
+		Point selection = browser.combo.getSelection();
+		String text = browser.combo.getText();
+	
+		if (selection.x != selection.y) {
+			text = text.substring(0, selection.x) + text.substring(selection.y);
+			browser.combo.setText(text);
+			browser.combo.setSelection(new Point(selection.x, selection.x));
+		}
+	}
+	
+	/** 
+	 * Replaces the selection with the clipboard text or insert the text at 
+	 * the current caret offset if there is no selection. 
+	 * If the widget has the SWT.SINGLE style and the clipboard text contains
+	 * more than one line, only the first line without line delimiters is 
+	 * inserted in the widget.
+	 * 
+	 *    
+	 */
+	public void paste() {
+		TextTransfer transfer = TextTransfer.getInstance();
+		Point selection = browser.combo.getSelection();
+		String text = browser.combo.getText();
+		
+		String newText = (String) browser.clipboard.getContents(transfer);
+		if (newText != null && newText.length() > 0) {
+			text = text.substring(0, selection.x) + newText + text.substring(selection.y);
+			browser.combo.setText(text);
+	
+			// set the selection to the end of the paste
+			int x = selection.x + newText.length();
+			browser.combo.setSelection(new Point(x, x));
+		}
+	}
+	
+	/**
+	 * Implementation of method defined on IAction.
+	 */
+	public void run() {
+		if (browser == null || browser.combo == null)
+			return;
+		if (type == CUT)
+			cut();
+		else if (type == COPY)
+			copy();
+		else if (type == PASTE)
+			paste();
+	}
+	
+	/**
+	 * 
+	 */
+	protected void update() {	}
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/Trace.java b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/Trace.java
new file mode 100644
index 0000000..550cd7d
--- /dev/null
+++ b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/Trace.java
@@ -0,0 +1,52 @@
+/**
+ * Copyright (c) 2003 IBM Corporation and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *    IBM - Initial API and implementation
+ */
+package net.sourceforge.phpeclipse.webbrowser.internal;
+/**
+ * Helper class to route trace output.
+ */
+public class Trace {
+	public static int CONFIG = 0;
+	public static int WARNING = 2;
+	public static int SEVERE = 3;
+	public static int FINER = 4;
+	public static int FINEST = 5;
+
+	/**
+	 * Trace constructor comment.
+	 */
+	private Trace() {
+		super();
+	}
+
+	/**
+	 * Trace the given text.
+	 *
+	 * @param s java.lang.String
+	 */
+	public static void trace(int level, String s) {
+		Trace.trace(level, s, null);
+	}
+
+	/**
+	 * Trace the given message and exception.
+	 *
+	 * @param s java.lang.String
+	 * @param t java.lang.Throwable
+	 */
+	public static void trace(int level, String s, Throwable t) {
+		if (!WebBrowserUIPlugin.getInstance().isDebugging())
+			return;
+
+		System.out.println(s);
+		if (t != null)
+			t.printStackTrace();
+	}
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/WebBrowser.java b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/WebBrowser.java
new file mode 100644
index 0000000..829d813
--- /dev/null
+++ b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/WebBrowser.java
@@ -0,0 +1,581 @@
+/**
+ * Copyright (c) 2003 IBM Corporation and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *    IBM - Initial API and implementation
+ */
+
+//TODO 1. Handle the sizing of a popup running in shelled out secondary window.
+//TODO 2. Support printing: waiting on eclipse bug 47937/44823.
+
+package net.sourceforge.phpeclipse.webbrowser.internal;
+
+import java.util.*;
+
+import net.sourceforge.phpeclipse.webbrowser.IURLMap;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.ui.help.WorkbenchHelp;
+import org.eclipse.swt.browser.*;
+
+public class WebBrowser extends Composite {
+	protected Composite toolbarComp;
+	protected Composite statusComp;
+	protected Combo combo;
+	protected Clipboard clipboard;
+	protected boolean showToolbar;
+	protected ToolItem back;
+	protected ToolItem forward;
+	protected ToolItem stop;
+	protected ToolItem favorites;
+	protected ToolItem refresh;
+	protected BusyIndicator busy;
+	protected boolean showStatusbar;
+	protected ProgressBar progress;
+	protected Label status;
+	private static int MAX_HISTORY = 50;
+	protected static java.util.List history;
+	protected Browser browser; 
+	protected Shell shell;
+	protected WebBrowserEditor editor;
+	protected String title;
+	
+	public WebBrowser(Composite parent, final boolean showToolbar, final boolean showStatusbar) {
+		super(parent, SWT.NONE);
+
+		this.showToolbar = showToolbar;
+		this.showStatusbar = showStatusbar;	
+
+		GridLayout layout = new GridLayout();
+		layout.marginHeight = 3;
+		layout.marginWidth = 3;
+		layout.horizontalSpacing = 3;
+		layout.verticalSpacing = 3;
+		layout.numColumns = 1;
+		setLayout(layout);
+		setLayoutData(new GridData(GridData.FILL_BOTH));
+		clipboard = new Clipboard(parent.getDisplay());
+		WorkbenchHelp.setHelp(this, ContextIds.WEB_BROWSER);
+		
+		if (showToolbar) {
+			toolbarComp = new Composite(this, SWT.NONE);
+			GridLayout outerLayout = new GridLayout();
+			outerLayout.numColumns = 2;
+			outerLayout.marginWidth = 0;
+			outerLayout.marginHeight = 0;
+			toolbarComp.setLayout(outerLayout);
+			toolbarComp.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL));
+			
+			// create the top line, with a combo box for history and a "go" button
+			Composite top = new Composite(toolbarComp, SWT.NONE);
+			GridLayout topLayout = new GridLayout();
+			topLayout.numColumns = 2;
+			topLayout.marginWidth = 0;
+			topLayout.marginHeight = 0;
+			top.setLayout(topLayout);
+			top.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_CENTER | GridData.FILL_HORIZONTAL));
+			
+			combo = new Combo(top, SWT.DROP_DOWN);
+			
+			updateHistory();
+			
+			combo.addSelectionListener(new SelectionAdapter() {
+				public void widgetSelected(SelectionEvent we) {
+					try {
+						if (combo.getSelectionIndex() != -1)
+							setURL(combo.getItem(combo.getSelectionIndex()));
+					} catch (Exception e) { }
+				}
+			});
+			combo.addListener(SWT.DefaultSelection, new Listener() {
+				public void handleEvent(Event e) {
+					setURL(combo.getText());
+				}
+			});
+			combo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+			WorkbenchHelp.setHelp(combo, ContextIds.WEB_BROWSER_URL);
+			
+			ToolBar toolbar = new ToolBar(top, SWT.FLAT);
+			fillToolBar(toolbar);
+			
+			new ToolItem(toolbar, SWT.SEPARATOR);
+			
+			busy = new BusyIndicator(toolbarComp, SWT.NONE);
+			busy.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
+		}
+
+		// create a new SWT Web browser widget, checking once again to make sure we can use it in this environment
+		if (WebBrowserUtil.canUseInternalWebBrowser() & WebBrowserUtil.isInternalBrowserOperational())
+			this.browser = new Browser(this, SWT.NONE);
+		else {
+			WebBrowserUtil.openError(WebBrowserUIPlugin.getResource("%errorCouldNotLaunchInternalWebBrowser"));
+			return;
+		}
+		
+		if (showToolbar) {
+			back.setEnabled(browser.isBackEnabled());
+			forward.setEnabled(browser.isForwardEnabled());
+		}
+
+		WorkbenchHelp.setHelp(browser, ContextIds.WEB_BROWSER_WEB);
+		GridData data = new GridData();
+		data.horizontalAlignment = GridData.FILL;
+		data.verticalAlignment = GridData.FILL;
+		data.horizontalSpan = 3;
+		data.grabExcessHorizontalSpace = true;
+		data.grabExcessVerticalSpace = true;
+		browser.setLayoutData(data);
+		
+		if (showStatusbar)
+			createStatusArea(this);
+		
+		addBrowserListeners();
+	}
+	/**
+	 *
+	 */
+	protected void addBrowserListeners() {	
+		if (showStatusbar) {
+			// respond to Browser StatusTextEvents events by updating the status Text label
+			browser.addStatusTextListener(new StatusTextListener() {
+				public void changed(StatusTextEvent event) {
+					status.setText(event.text);	
+				}
+			});
+		}
+
+		/** Add listener for new window creation so that we can instead of opening a separate
+		 *  new window in which the session is lost, we can instead open a new window in a new
+		 *  shell within the browser area thereby maintaining the session.
+		 */
+		browser.addOpenWindowListener(new OpenWindowListener() {
+			public void open(WindowEvent event) {
+				Shell shell2 = new Shell(getDisplay());
+				shell2.setLayout(new FillLayout());
+				shell2.setText(WebBrowserUIPlugin.getResource("%viewWebBrowserTitle"));
+				shell2.setImage(getShell().getImage());
+				WebBrowser browser2 = new WebBrowser(shell2, showToolbar, showStatusbar);
+				browser2.shell = shell2;
+				event.browser = browser2.browser;
+				shell2.open();
+			}
+		});
+		
+		browser.addCloseWindowListener(new CloseWindowListener(){
+			public void close(WindowEvent event) {
+				// if shell is not null, it must be a secondary popup window, else its an editor window
+				if (shell != null)
+					shell.dispose();
+				else
+					editor.closeEditor();
+			}
+		});
+		
+		browser.addProgressListener(new ProgressListener() {
+			public void changed(ProgressEvent event) {
+				if (event.total == 0)
+					return;
+				
+				boolean done = (event.current == event.total);
+
+				int percentProgress = event.current * 100 / event.total;
+				if (showStatusbar) {
+					if (done)
+						progress.setSelection(0);
+					else
+						progress.setSelection(percentProgress);
+				}
+				
+				if (showToolbar) {
+					if (!busy.isBusy() && (percentProgress > 0 && percentProgress < 100)) {
+						busy.setBusy(true);
+					}
+					// Once the progress hits 100 percent, done, set busy to false
+					else if (busy.isBusy() && done) {
+						busy.setBusy(false);
+					}
+				}
+			}
+			
+			public void completed(ProgressEvent event) {
+				if (showStatusbar)
+					progress.setSelection(0);
+				if (showToolbar) {
+					busy.setBusy(false);
+					back.setEnabled(browser.isBackEnabled());
+					forward.setEnabled(browser.isForwardEnabled());
+				}
+			}
+		});
+
+		if (showToolbar) {
+			browser.addLocationListener(new LocationListener() {
+				public void changed(LocationEvent event) {
+					if (!event.top)
+						return;
+					if (!isHome()) {
+						combo.setText(event.location);
+						addToHistory(event.location);
+						updateHistory();
+					} else
+						combo.setText("");
+				}
+				
+				public void changing(LocationEvent event) { }
+			});
+		}
+		
+		browser.addTitleListener(new TitleListener() {
+			public void changed(TitleEvent event) {
+				title = event.title;
+			}
+		});
+	}
+
+	/**
+	 * Return the underlying browser control.
+	 * 
+	 * @return org.eclipse.swt.browser.Browser
+	 */
+	public Browser getBrowser() {
+		return browser;
+	}
+
+	/**
+	 * 
+	 */
+	protected void forward() {
+		browser.forward();
+	}
+
+	/**
+	 * 
+	 */
+	protected void back() {
+		browser.back();
+	}
+	
+	/**
+	 * 
+	 */
+	protected void stop() {
+		browser.stop();
+	}
+
+	/**
+	 * 
+	 */
+	protected void navigate(String url) {
+		Trace.trace(Trace.FINER, "Navigate: " + url);
+		if (url != null && url.equals(getURL())) {
+			refresh();
+			return;
+		}
+		browser.setUrl(url);
+	}
+
+	/**
+	 * Refresh the currently viewed page.
+	 */
+	public void refresh() {
+		browser.refresh();
+	}
+
+	protected void setURL(String url, boolean browse) {
+		Trace.trace(Trace.FINEST, "setURL: " + url + " " + browse);
+		if (url == null) {
+			home();
+			return;
+		}
+		
+		if (url.endsWith(WebBrowserPreference.getHomePageURL().substring(9)))
+			return;
+
+		// check URL maps
+		Iterator iterator = WebBrowserUtil.getURLMaps().iterator();
+		String newURL = null;
+		while (iterator.hasNext() && newURL == null) {
+			try {
+				IURLMap map = (IURLMap) iterator.next();
+				newURL = map.getMappedURL(url);
+			} catch (Exception e) { }
+		}
+		if (newURL != null)
+			url = newURL;
+		
+		if (browse)
+			navigate(url);
+		
+		addToHistory(url);
+		updateHistory();
+	}
+
+	protected void addToHistory(String url) {
+		if (history == null)
+			history = WebBrowserPreference.getInternalWebBrowserHistory();
+		int found = -1;
+		int size = history.size();
+		for (int i = 0; i < size; i++){
+			String s = (String) history.get(i);
+			if (s.equals(url)) {
+				found = i;
+				break;
+			}
+		}
+		
+		if (found == -1) {
+			if (size >= MAX_HISTORY)
+				history.remove(size - 1);
+			history.add(0, url);
+			WebBrowserPreference.setInternalWebBrowserHistory(history);
+		} else if (found != 0) {
+			history.remove(found);
+			history.add(0, url);
+			WebBrowserPreference.setInternalWebBrowserHistory(history);
+		}
+	}
+
+	public void setURL(String url) {
+		setURL(url, true);
+	}
+	
+	/**
+	 * Creates the Web browser status area.
+	 */
+	private void createStatusArea(Composite parent) {
+		Composite composite = new Composite(parent, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 2;
+		layout.marginHeight = 0;
+		layout.marginWidth = 0;
+		layout.horizontalSpacing = 4;
+		layout.verticalSpacing = 0;
+		composite.setLayout(layout);
+		composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+	
+		// Add a label for displaying status messages as they are received from the control
+		status = new Label(composite, SWT.SINGLE | SWT.READ_ONLY);
+		GridData gridData = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL);
+		gridData.horizontalIndent = 2;
+		status.setLayoutData(gridData);
+	
+		// Add a progress bar to display downloading progress information
+		progress = new ProgressBar(composite, SWT.BORDER);
+		gridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_FILL);
+		gridData.widthHint = 100;
+		gridData.heightHint = 10;
+		progress.setLayoutData(gridData);
+	}
+	
+	/**
+	 *
+	 */
+	public void dispose() {
+		super.dispose();
+
+		showStatusbar = false;
+		showToolbar = false;
+	
+		if (busy != null)
+			busy.dispose();
+		busy = null;
+
+		browser = null;
+	}
+	
+	/**
+	 * Populate the toolbar.
+	 * @param toolbar org.eclipse.swt.widgets.ToolBar
+	 */
+	private void fillToolBar(final ToolBar toolbar) {
+		ToolItem go = new ToolItem(toolbar, SWT.NONE);
+		go.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_GO));
+		go.setHotImage(ImageResource.getImage(ImageResource.IMG_CLCL_NAV_GO));
+		go.setDisabledImage(ImageResource.getImage(ImageResource.IMG_DLCL_NAV_GO));
+		go.setToolTipText(WebBrowserUIPlugin.getResource("%actionWebBrowserGo"));
+		go.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent event) {
+				setURL(combo.getText());
+			}
+		});
+	
+		new ToolItem(toolbar, SWT.SEPARATOR);
+		
+		favorites = new ToolItem(toolbar, SWT.DROP_DOWN);
+		favorites.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_FAVORITES));
+		favorites.setHotImage(ImageResource.getImage(ImageResource.IMG_CLCL_NAV_FAVORITES));
+		favorites.setDisabledImage(ImageResource.getImage(ImageResource.IMG_DLCL_NAV_FAVORITES));
+		favorites.setToolTipText(WebBrowserUIPlugin.getResource("%actionWebBrowserFavorites"));
+		
+		favorites.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent event) {
+				if (event.detail == SWT.ARROW) {
+					Rectangle r = favorites.getBounds();
+					showFavorites(toolbar, toolbar.toDisplay(r.x, r.y + r.height));
+				} else
+					addFavorite();
+			}
+		});
+	
+		// create back and forward actions
+		back = new ToolItem(toolbar, SWT.NONE);
+		back.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_BACKWARD));
+		back.setHotImage(ImageResource.getImage(ImageResource.IMG_CLCL_NAV_BACKWARD));
+		back.setDisabledImage(ImageResource.getImage(ImageResource.IMG_DLCL_NAV_BACKWARD));
+		back.setToolTipText(WebBrowserUIPlugin.getResource("%actionWebBrowserBack"));
+		back.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent event) {
+				back();
+			}
+		});
+
+		forward = new ToolItem(toolbar, SWT.NONE);
+		forward.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_FORWARD));
+		forward.setHotImage(ImageResource.getImage(ImageResource.IMG_CLCL_NAV_FORWARD));
+		forward.setDisabledImage(ImageResource.getImage(ImageResource.IMG_DLCL_NAV_FORWARD));
+		forward.setToolTipText(WebBrowserUIPlugin.getResource("%actionWebBrowserForward"));
+		forward.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent event) {
+				forward();
+			}
+		});
+		
+		// create refresh, stop, and print actions
+		stop = new ToolItem(toolbar, SWT.NONE);
+		stop.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_STOP));
+		stop.setHotImage(ImageResource.getImage(ImageResource.IMG_CLCL_NAV_STOP));
+		stop.setDisabledImage(ImageResource.getImage(ImageResource.IMG_DLCL_NAV_STOP));
+		stop.setToolTipText(WebBrowserUIPlugin.getResource("%actionWebBrowserStop"));
+		stop.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent event) {
+				stop();
+			}
+		});
+	
+		refresh = new ToolItem(toolbar, SWT.NONE);
+		refresh.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_REFRESH));
+		refresh.setHotImage(ImageResource.getImage(ImageResource.IMG_CLCL_NAV_REFRESH));
+		refresh.setDisabledImage(ImageResource.getImage(ImageResource.IMG_DLCL_NAV_REFRESH));
+		refresh.setToolTipText(WebBrowserUIPlugin.getResource("%actionWebBrowserRefresh"));
+		refresh.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent event) {
+				refresh();
+			}
+		});
+	}
+	
+	protected void addFavorite() {
+		java.util.List list = WebBrowserPreference.getInternalWebBrowserFavorites();
+		Favorite f = new Favorite(title, browser.getUrl());
+		if (!list.contains(f)) {
+			list.add(f);
+			WebBrowserPreference.setInternalWebBrowserFavorites(list);
+		}
+	}
+	
+	protected void showFavorites(Control parent, Point p) {
+		Menu perspectiveBarMenu = null;
+		if (perspectiveBarMenu == null) {
+			Menu menu = new Menu(parent);
+			
+			// locked favorites
+			Iterator iterator = WebBrowserUtil.getLockedFavorites().iterator();
+			if (iterator.hasNext()) {
+				while (iterator.hasNext()) {
+					final Favorite f = (Favorite) iterator.next();
+					MenuItem item = new MenuItem(menu, SWT.NONE);
+					item.setText(f.getName());
+					item.setImage(ImageResource.getImage(ImageResource.IMG_FAVORITE));
+					item.addSelectionListener(new SelectionAdapter() {
+						public void widgetSelected(SelectionEvent event) {
+							setURL(f.getURL());
+						}
+					});
+				}
+				
+				new MenuItem(menu, SWT.SEPARATOR);
+			}
+			
+			iterator = WebBrowserPreference.getInternalWebBrowserFavorites().iterator();
+			if (!iterator.hasNext()) {
+				MenuItem item = new MenuItem(menu, SWT.NONE);
+				item.setText(WebBrowserUIPlugin.getResource("%actionWebBrowserNoFavorites"));
+			}
+			while (iterator.hasNext()) {
+				final Favorite f = (Favorite) iterator.next();
+				MenuItem item = new MenuItem(menu, SWT.NONE);
+				item.setText(f.getName());
+				item.setImage(ImageResource.getImage(ImageResource.IMG_FAVORITE));
+				item.addSelectionListener(new SelectionAdapter() {
+					public void widgetSelected(SelectionEvent event) {
+						setURL(f.getURL());
+					}
+				});
+			}
+			
+			new MenuItem(menu, SWT.SEPARATOR);
+	
+			MenuItem item = new MenuItem(menu, SWT.NONE);
+			item.setText(WebBrowserUIPlugin.getResource("%actionWebBrowserOrganizeFavorites"));
+			item.addSelectionListener(new SelectionAdapter() {
+				public void widgetSelected(SelectionEvent event) {
+					OrganizeFavoritesDialog dialog = new OrganizeFavoritesDialog(shell);
+					dialog.open();
+				}
+			});
+			
+			perspectiveBarMenu = menu;
+		}
+		
+		if (perspectiveBarMenu != null) {
+			perspectiveBarMenu.setLocation(p.x, p.y);
+			perspectiveBarMenu.setVisible(true);
+		}
+	}
+
+	public void home() {
+	   navigate(WebBrowserPreference.getHomePageURL());
+	}
+
+	/**
+	 * Returns true if the homepage is currently being displayed.
+	 * @return boolean
+	 */
+	protected boolean isHome() {
+		return getURL() != null && getURL().endsWith(WebBrowserPreference.getHomePageURL().substring(9));
+	}
+
+	protected String getURL() {
+		return browser.getUrl();
+	}
+
+	/**
+	 * Update the history list to the global copy.
+	 */
+	protected void updateHistory() {
+		if (combo == null)
+			return;
+	
+		String temp = combo.getText();
+		if (history == null)
+			history = WebBrowserPreference.getInternalWebBrowserHistory();
+	
+		String[] historyList = new String[history.size()];
+		history.toArray(historyList);
+		combo.setItems(historyList);
+	
+		combo.setText(temp);
+	}
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/WebBrowserEditor.java b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/WebBrowserEditor.java
new file mode 100644
index 0000000..cb6fbcf
--- /dev/null
+++ b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/WebBrowserEditor.java
@@ -0,0 +1,373 @@
+/**
+ * Copyright (c) 2003 IBM Corporation and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *    IBM - Initial API and implementation
+ */
+package net.sourceforge.phpeclipse.webbrowser.internal;
+
+import java.net.URL;
+
+import net.sourceforge.phpeclipse.webbrowser.*;
+
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.core.runtime.*;
+import org.eclipse.core.resources.*;
+import org.eclipse.ui.*;
+import org.eclipse.ui.part.*;
+/**
+ * An integrated Web browser, defined as an editor to make
+ * better use of the desktop.
+ */
+public class WebBrowserEditor extends EditorPart {
+	public static final String WEB_BROWSER_EDITOR_ID = "net.sourceforge.phpeclipse.webbrowser";
+	protected WebBrowser webBrowser;
+	protected String initialURL;
+	protected Image image;
+
+	protected TextAction cutAction;
+	protected TextAction copyAction;
+	protected TextAction pasteAction;
+	
+	protected IResourceChangeListener resourceListener;
+
+	/**
+	 * WebBrowserEditor constructor comment.
+	 */
+	public WebBrowserEditor() {
+		super();
+	}
+	
+	/**
+	 * Creates the SWT controls for this workbench part.
+	 * 
+	 *   
+	 * IActionService.IActionService.ISelectionService
+	 *     (optional). 
+	 * Subclasses must override this method to implement the open-save-close lifecycle
+	 * for an editor.  For greater details, see IEditorPart
+	 * 
+	 * Subclasses must override this method to implement the open-save-close lifecycle
+	 * for an editor.  For greater details, see IEditorPart
+	 * 
+	 * Subclasses may override.  For greater details, see IEditorPart
+	 * 
+	 * Subclasses of EditorPart must implement this method.  Within
+	 * the implementation subclasses should verify that the input type is acceptable
+	 * and then save the site and input.  Here is sample code:
+	 * 
+	 *		if (!(input instanceof IFileEditorInput))
+	 *			throw new PartInitException("Invalid Input: Must be IFileEditorInput");
+	 *		setSite(site);
+	 *		setInput(editorInput);
+	 * 
+	 */
+	public void init(IEditorSite site, IEditorInput input) {
+		Trace.trace(Trace.FINEST, "Opening browser: " + input);
+		if (input instanceof IFileEditorInput) {
+			IFileEditorInput fei = (IFileEditorInput) input;
+			IFile file = fei.getFile();
+			URL url = null;
+			try {
+				if (file != null && file.exists())
+					url = file.getLocation().toFile().toURL();
+			} catch (Exception e) {
+				Trace.trace(Trace.SEVERE, "Error getting URL to file");
+			}
+			addResourceListener(file);
+			input = new WebBrowserEditorInput(url, WebBrowserEditorInput.SHOW_ALL | WebBrowserEditorInput.SAVE_URL);
+		}
+		if (input instanceof IWebBrowserEditorInput) {
+			IWebBrowserEditorInput wbei = (IWebBrowserEditorInput) input;
+			initialURL = null;
+			if (wbei.getURL() != null)
+				initialURL = wbei.getURL().toExternalForm();
+			if (webBrowser != null) {
+				webBrowser.setURL(initialURL);
+				site.getWorkbenchWindow().getActivePage().bringToTop(this);
+			}
+	
+			setPartName(wbei.getName());
+			setTitleToolTip(wbei.getToolTipText());
+
+			Image oldImage = image;
+			ImageDescriptor id = wbei.getImageDescriptor();
+			image = id.createImage();
+
+			setTitleImage(image);
+			if (oldImage != null && !oldImage.isDisposed())
+				oldImage.dispose();
+		}
+		setSite(site);
+		setInput(input);
+	}
+	
+	/* (non-Javadoc)
+	 * Returns whether the contents of this editor have changed since the last save
+	 * operation.
+	 * 
+	 * Subclasses must override this method to implement the open-save-close lifecycle
+	 * for an editor.  For greater details, see IEditorPart
+	 * 
+	 * Subclasses must override this method to implement the open-save-close lifecycle
+	 * for an editor.  For greater details, see IEditorPart
+	 * 
+ * Clients should not call this method (the workbench calls this method at + * appropriate times). + *
+ */ + public void setFocus() { + if (webBrowser != null) { + if (webBrowser.combo != null) + webBrowser.combo.setFocus(); + else + webBrowser.browser.setFocus(); + webBrowser.updateHistory(); + } + } + + /** + * Update the actions. + */ + protected void updateActions() { + if (cutAction != null) + cutAction.update(); + if (copyAction != null) + copyAction.update(); + if (pasteAction != null) + pasteAction.update(); + } + + /** + * Close the editor correctly. + */ + protected void closeEditor() { + Display.getDefault().asyncExec(new Runnable() { + public void run() { + getEditorSite().getPage().closeEditor(WebBrowserEditor.this, false); + } + }); + } + + /** + * Adds a resource change listener to see if the file is deleted. + */ + protected void addResourceListener(final IResource resource) { + if (resource == null) + return; + + resourceListener = new IResourceChangeListener() { + public void resourceChanged(IResourceChangeEvent event) { + try { + event.getDelta().accept(new IResourceDeltaVisitor() { + public boolean visit(IResourceDelta delta) { + IResource res = delta.getResource(); + + if (res == null || !res.equals(resource)) + return true; + + if (delta.getKind() != IResourceDelta.REMOVED) + return true; + + Display.getDefault().asyncExec(new Runnable() { + public void run() { + String title = WebBrowserUIPlugin.getResource("%dialogResourceDeletedTitle"); + String message = WebBrowserUIPlugin.getResource("%dialogResourceDeletedMessage", resource.getName()); + String[] labels = new String[] {WebBrowserUIPlugin.getResource("%dialogResourceDeletedIgnore"), IDialogConstants.CLOSE_LABEL}; + MessageDialog dialog = new MessageDialog(getEditorSite().getShell(), title, null, message, MessageDialog.INFORMATION, labels, 0); + + if (dialog.open() != 0) + closeEditor(); + } + }); + return false; + } + }); + } catch (Exception e) { + Trace.trace(Trace.SEVERE, "Error listening for resource deletion", e); + } + } + }; + ResourcesPlugin.getWorkspace().addResourceChangeListener(resourceListener); + } +} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/WebBrowserEditorActionBarContributor.java b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/WebBrowserEditorActionBarContributor.java new file mode 100644 index 0000000..7cb171a --- /dev/null +++ b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/WebBrowserEditorActionBarContributor.java @@ -0,0 +1,62 @@ +/** + * Copyright (c) 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + */ +package net.sourceforge.phpeclipse.webbrowser.internal; + +import org.eclipse.ui.*; +import org.eclipse.ui.actions.ActionFactory; +/** + * ActionBarContributor for the Web browser. + * Just adds cut, copy, paste actions. + */ +public class WebBrowserEditorActionBarContributor implements IEditorActionBarContributor { + protected IActionBars actionBars; + + /** + * WebBrowserEditorActionBarContributor constructor comment. + */ + public WebBrowserEditorActionBarContributor() { + super(); + } + + /** + * Initializes this contributor, which is expected to add contributions as + * required to the given action bars and global action handlers. + * + * @param bars the action bars + */ + public void init(IActionBars bars, IWorkbenchPage page) { + this.actionBars = bars; + } + + /** + * Sets the active editor for the contributor. + * Implementors should disconnect from the old editor, connect to the + * new editor, and update the actions to reflect the new editor. + * + * @param targetEditor the new editor target + */ + public void setActiveEditor(IEditorPart targetEditor) { + if (targetEditor instanceof WebBrowserEditor) { + WebBrowserEditor editor = (WebBrowserEditor) targetEditor; + + actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(), editor.getCopyAction()); + actionBars.setGlobalActionHandler(ActionFactory.CUT.getId(), editor.getCutAction()); + actionBars.setGlobalActionHandler(ActionFactory.PASTE.getId(), editor.getPasteAction()); + + editor.updateActions(); + } + } + + /** + * Disposes this contributor. + */ + public void dispose() { } +} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/WebBrowserPreference.java b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/WebBrowserPreference.java new file mode 100644 index 0000000..2198585 --- /dev/null +++ b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/WebBrowserPreference.java @@ -0,0 +1,164 @@ +/** + * Copyright (c) 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + */ +package net.sourceforge.phpeclipse.webbrowser.internal; + +import java.util.*; +import java.net.URL; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.preference.IPreferenceStore; +/** + * Preferences for the Web browser. + */ +public class WebBrowserPreference { + protected static final String PREF_BROWSER_HISTORY = "webBrowserHistory"; + protected static final String PREF_INTERNAL_WEB_BROWSER_HISTORY = "internalWebBrowserHistory"; + protected static final String PREF_INTERNAL_WEB_BROWSER_FAVORITES = "internalWebBrowserFavorites"; + protected static final String PREF_INTERNAL_WEB_BROWSER_OLD_FAVORITES = "internalWebBrowserOldFavorites"; + protected static final String URL_PARAMETER = "%URL%"; + + /** + * WebBrowserPreference constructor comment. + */ + private WebBrowserPreference() { + super(); + } + + /** + * Returns the URL to the homepage. + * + * @return java.lang.String + */ + public static String getHomePageURL() { + try { + // get the default home page + URL url = WebBrowserUIPlugin.getInstance().getBundle().getEntry("home/home.html"); + url = Platform.resolve(url); + return url.toExternalForm(); + } catch (Exception e) { + return "http://www.eclipse.org"; + } + } + + /** + * Returns the preference store. + * + * @return org.eclipse.jface.preference.IPreferenceStore + */ + protected static IPreferenceStore getPreferenceStore() { + return WebBrowserUIPlugin.getInstance().getPreferenceStore(); + } + + /** + * Returns the Web browser history list. + * + * @return java.util.List + */ + public static List getInternalWebBrowserHistory() { + String temp = getPreferenceStore().getString(PREF_INTERNAL_WEB_BROWSER_HISTORY); + StringTokenizer st = new StringTokenizer(temp, "|*|"); + List l = new ArrayList(); + while (st.hasMoreTokens()) { + String s = st.nextToken(); + l.add(s); + } + return l; + } + + /** + * Returns the Web browser favorites. + * + * @return java.util.List + */ + public static List getInternalWebBrowserFavorites() { + String temp = getPreferenceStore().getString(PREF_INTERNAL_WEB_BROWSER_FAVORITES); + StringTokenizer st = new StringTokenizer(temp, "|*|"); + List l = new ArrayList(); + while (st.hasMoreTokens()) { + l.add(new Favorite(st.nextToken(), st.nextToken())); + } + return l; + } + + /** + * Initialize the default preferences. + */ + public static void initializeDefaultPreferences() { + IPreferenceStore store = getPreferenceStore(); + + String temp = store.getString(PREF_INTERNAL_WEB_BROWSER_OLD_FAVORITES); + StringTokenizer st = new StringTokenizer(temp, "|*|"); + List def = new ArrayList(); + while (st.hasMoreTokens()) { + def.add(new Favorite(st.nextToken(), st.nextToken())); + } + + List list = getInternalWebBrowserFavorites(); + Iterator iterator = WebBrowserUtil.getUnlockedFavorites().iterator(); + while (iterator.hasNext()) { + Favorite f = (Favorite) iterator.next(); + if (!def.contains(f)) + list.add(f); + } + setInternalWebBrowserFavorites(list); + + StringBuffer sb = new StringBuffer(); + iterator = WebBrowserUtil.getUnlockedFavorites().iterator(); + while (iterator.hasNext()) { + Favorite f = (Favorite) iterator.next(); + sb.append(f.getName()); + sb.append("|*|"); + sb.append(f.getURL()); + sb.append("|*|"); + } + store.setValue(PREF_INTERNAL_WEB_BROWSER_OLD_FAVORITES, sb.toString()); + WebBrowserUIPlugin.getInstance().savePluginPreferences(); + } + + /** + * Sets the Web browser history. + * + * @param java.util.List + */ + public static void setInternalWebBrowserHistory(List list) { + StringBuffer sb = new StringBuffer(); + if (list != null) { + Iterator iterator = list.iterator(); + while (iterator.hasNext()) { + String s = (String) iterator.next(); + sb.append(s); + sb.append("|*|"); + } + } + getPreferenceStore().setValue(PREF_INTERNAL_WEB_BROWSER_HISTORY, sb.toString()); + WebBrowserUIPlugin.getInstance().savePluginPreferences(); + } + + /** + * Sets the Web browser favorites. + * + * @param java.util.List + */ + public static void setInternalWebBrowserFavorites(List list) { + StringBuffer sb = new StringBuffer(); + if (list != null) { + Iterator iterator = list.iterator(); + while (iterator.hasNext()) { + Favorite f = (Favorite) iterator.next(); + sb.append(f.getName()); + sb.append("|*|"); + sb.append(f.getURL()); + sb.append("|*|"); + } + } + getPreferenceStore().setValue(PREF_INTERNAL_WEB_BROWSER_FAVORITES, sb.toString()); + WebBrowserUIPlugin.getInstance().savePluginPreferences(); + } +} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/WebBrowserPreferencePage.java b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/WebBrowserPreferencePage.java new file mode 100644 index 0000000..7d01c2e --- /dev/null +++ b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/WebBrowserPreferencePage.java @@ -0,0 +1,84 @@ +/** + * Copyright (c) 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + */ +package net.sourceforge.phpeclipse.webbrowser.internal; + +import org.eclipse.swt.*; +import org.eclipse.swt.layout.*; +import org.eclipse.swt.widgets.*; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.preference.PreferencePage; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; +import org.eclipse.ui.help.WorkbenchHelp; +/** + * The preference page that holds webbrowser preferences. + */ +public class WebBrowserPreferencePage extends PreferencePage implements IWorkbenchPreferencePage { + /** + * WebBrowserPreferencePage constructor comment. + */ + public WebBrowserPreferencePage() { + super(); + noDefaultAndApplyButton(); + } + + /** + * Create the preference options. + * + * @param parent org.eclipse.swt.widgets.Composite + * @return org.eclipse.swt.widgets.Control + */ + protected Control createContents(Composite parent) { + initializeDialogUnits(parent); + + Composite composite = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.numColumns = 1; + layout.horizontalSpacing = convertHorizontalDLUsToPixels(4); + layout.verticalSpacing = convertVerticalDLUsToPixels(4); + layout.marginWidth = 0; + layout.marginHeight = 0; + composite.setLayout(layout); + GridData data = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL); + composite.setLayoutData(data); + WorkbenchHelp.setHelp(composite, ContextIds.PREF_BROWSER); + + Label label = new Label(composite, SWT.WRAP); + label.setText(WebBrowserUIPlugin.getResource("%preferenceWebBrowserDescription")); + data = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); + label.setLayoutData(data); + + BrowserTableComposite browserComposite = new BrowserTableComposite(composite, SWT.NONE); + + data = new GridData(GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL); + browserComposite.setLayoutData(data); + + Dialog.applyDialogFont(composite); + + return composite; + } + + /** + * Initializes this preference page using the passed desktop. + * + * @param desktop the current desktop + */ + public void init(IWorkbench workbench) { } + + /** + * + */ + public void setVisible(boolean visible) { + super.setVisible(visible); + if (visible) + setTitle(WebBrowserUIPlugin.getResource("%preferenceWebBrowserTitleLong")); + } +} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/WebBrowserUIPlugin.java b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/WebBrowserUIPlugin.java new file mode 100644 index 0000000..179e0b4 --- /dev/null +++ b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/WebBrowserUIPlugin.java @@ -0,0 +1,90 @@ +/** + * Copyright (c) 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + */ +package net.sourceforge.phpeclipse.webbrowser.internal; + +import java.text.MessageFormat; + +import org.eclipse.core.runtime.*; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; +/** + * The main web browser plugin class. + */ +public class WebBrowserUIPlugin extends AbstractUIPlugin { + // Web browser plugin id + public static final String PLUGIN_ID = "net.sourceforge.phpeclipse.webbrowser"; + + // singleton instance of this class + private static WebBrowserUIPlugin singleton; + + /** + * Create the WebBrowserUIPlugin + */ + public WebBrowserUIPlugin() { + super(); + singleton = this; + } + + /** + * Returns the singleton instance of this plugin. + * + * @return net.sourceforge.phpeclipse.webbrowser.WebBrowserPlugin + */ + public static WebBrowserUIPlugin getInstance() { + return singleton; + } + + /** + * Returns the translated String found with the given key. + * + * @param key java.lang.String + * @return java.lang.String + */ + public static String getResource(String key) { + try { + return Platform.getResourceString(getInstance().getBundle(), key); + } catch (Exception e) { + return key; + } + } + + /** + * Returns the translated String found with the given key, + * and formatted with the given arguments using java.text.MessageFormat. + * + * @param key java.lang.String + * @param arg java.lang.String + * @return java.lang.String + */ + public static String getResource(String key, String arg) { + try { + String text = getResource(key); + return MessageFormat.format(text, new String[] { arg }); + } catch (Exception e) { + return key; + } + } + + public void start(BundleContext context) throws Exception { + super.start(context); + WebBrowserPreference.initializeDefaultPreferences(); + } + + /** + * Shuts down this plug-in and saves all plug-in state. + * + * @exception Exception + */ + public void stop(BundleContext context) throws Exception { + super.stop(context); + BrowserManager.getInstance().dispose(); + } +} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/WebBrowserUtil.java b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/WebBrowserUtil.java new file mode 100644 index 0000000..372058f --- /dev/null +++ b/net.sourceforge.phpeclipse.webbrowser/src/net/sourceforge/phpeclipse/webbrowser/internal/WebBrowserUtil.java @@ -0,0 +1,377 @@ +/** + * Copyright (c) 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + */ +package net.sourceforge.phpeclipse.webbrowser.internal; + +import java.io.File; +import java.io.InputStreamReader; +import java.io.Reader; +import java.net.URL; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import net.sourceforge.phpeclipse.webbrowser.IExternalWebBrowser; +import net.sourceforge.phpeclipse.webbrowser.IExternalWebBrowserWorkingCopy; +import net.sourceforge.phpeclipse.webbrowser.IURLMap; +import net.sourceforge.phpeclipse.webbrowser.IWebBrowser; + +import org.eclipse.ui.IMemento; +import org.eclipse.ui.XMLMemento; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.core.runtime.*; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.browser.Browser; +/** + * Utility class for the Web browser tooling. + */ +public class WebBrowserUtil { + private static List urlMaps; + private static List lockedFavorites; + private static List unlockedFavorites; + private static final String BROWSER_PACKAGE_NAME = "org.eclipse.swt.browser.Browser"; + public static Boolean isInternalBrowserOperational; + + private static List defaultBrowsers2; + + static class DefaultBrowser { + String name; + String params; + String executable; + String[] locations; + + public DefaultBrowser(String name, String executable, String params, String[] locations) { + if (name == null) + name = "IAction.
-	 */
-	public void run() {
-		WebBrowser.openURL(new WebBrowserEditorInput(null, WebBrowserEditorInput.SHOW_ALL | WebBrowserEditorInput.FORCE_NEW_PAGE));
-	}
-}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/OpenBrowserWorkbenchAction.java b/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/OpenBrowserWorkbenchAction.java
deleted file mode 100644
index 08443e8..0000000
--- a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/OpenBrowserWorkbenchAction.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- * Copyright (c) 2003 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- *
- * Contributors:
- *    IBM - Initial API and implementation
- */
-package org.eclipse.webbrowser;
-
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.action.IAction;
-import org.eclipse.ui.*;
-import org.eclipse.webbrowser.WebBrowser;
-import org.eclipse.webbrowser.WebBrowserEditorInput;
-/**
- * Action to open the Web broswer.
- */
-public class OpenBrowserWorkbenchAction implements IWorkbenchWindowActionDelegate {
-	/**
-	 * OpenBrowserWorkbenchAction constructor comment.
-	 */
-	public OpenBrowserWorkbenchAction() {
-		super();
-	}
-
-	/**
-	 * Disposes this action delegate.  The implementor should unhook any references
-	 * to itself so that garbage collection can occur.
-	 */
-	public void dispose() { }
-
-	/**
-	 * Initializes this action delegate with the workbench window it will work in.
-	 *
-	 * @param window the window that provides the context for this delegate
-	 */
-	public void init(IWorkbenchWindow window) { }
-
-	/**
-	 * Performs this action.
-	 * - * This method is called when the delegating action has been triggered. - * Implement this method to do the actual work. - *
- * - * @param action the action proxy that handles the presentation portion of the - * action - */ - public void run(IAction action) { - WebBrowser.openURL(new WebBrowserEditorInput(null, WebBrowserEditorInput.SHOW_ALL | WebBrowserEditorInput.FORCE_NEW_PAGE)); - } - - /** - * Notifies this action delegate that the selection in the workbench has changed. - *- * Implementers can use this opportunity to change the availability of the - * action or to modify other presentation properties. - *
- * - * @param action the action proxy that handles presentation portion of the action - * @param selection the current selection in the workbench - */ - public void selectionChanged(IAction action, ISelection selection) { } -} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/WebBrowser.java b/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/WebBrowser.java deleted file mode 100644 index c104e6b..0000000 --- a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/WebBrowser.java +++ /dev/null @@ -1,119 +0,0 @@ -/** - * Copyright (c) 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - */ -package org.eclipse.webbrowser; - -import java.net.URL; -import java.util.List; - -import org.eclipse.swt.widgets.Display; -import org.eclipse.webbrowser.internal.*; -/** - * The main interface to the internal Web browser. If allows - * you to query the file types supported by the Web browser - * and open a URL. - */ -public class WebBrowser { - /** - * WebBrowser constructor comment. - */ - private WebBrowser() { - super(); - } - - /** - * Returns true if the internal Web browser is supported on this - * platform and the user has chosen to use it. - * - * @return boolean - */ - public static boolean isUsingInternalBrowser() { - return (getCurrentWebBrowser() instanceof IInternalWebBrowser); - } - - /** - * Display the given URL in a Web browser. If the user has chosen not - * to use the internal browser, an external browser will be used. If - * not, a browser in the current page will be reused if forceNewPage - * is not true and the user preference is not set. Finally, showToolbar - * will decide when the toolbar should be shown in the internal browser. - * - * @param input - */ - public static void openURL(final IWebBrowserEditorInput input) { - Trace.trace(Trace.FINEST, "openURL() " + input); - if (input == null) - return; - - Display.getDefault().asyncExec(new Runnable() { - public void run() { - if (!isUsingInternalBrowser()){ - IWebBrowser browser = getCurrentWebBrowser(); - browser.openURL(input.getURL()); - } else - WebBrowserEditor.open(input); - } - }); - } - - /** - * Return a list of all the installed Web browsers. - * - * @return - */ - public static List getWebBrowsers() { - return BrowserManager.getInstance().getWebBrowsers(); - } - - /** - * Return the current default web browser. - * - * @return - */ - public static IWebBrowser getCurrentWebBrowser() { - return BrowserManager.getInstance().getCurrentWebBrowser(); - } - - /** - * Set the current default web browser. - * - * @return - */ - public static void getCurrentWebBrowser(IWebBrowser browser) { - BrowserManager.getInstance().setCurrentWebBrowser(browser); - } - - /** - * Create a new external Web browser. - * - * @return - */ - public static IExternalWebBrowserWorkingCopy createExternalWebBrowser() { - return new ExternalWebBrowserWorkingCopy(); - } - - /** - * Display the given URL in a Web browser. - * - * @param url java.net.URL - */ - public static void openURL(URL url) { - IWebBrowser browser = getCurrentWebBrowser(); - if (browser != null) - browser.openURL(url); - else { - Display.getDefault().asyncExec(new Runnable() { - public void run() { - WebBrowserUtil.openError(WebBrowserUIPlugin.getResource("%errorNoBrowser")); - } - }); - } - } -} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/WebBrowserEditorInput.java b/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/WebBrowserEditorInput.java deleted file mode 100644 index 5b031ff..0000000 --- a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/WebBrowserEditorInput.java +++ /dev/null @@ -1,315 +0,0 @@ -/** - * Copyright (c) 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - */ -package org.eclipse.webbrowser; - -import java.net.URL; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.ui.*; -import org.eclipse.webbrowser.internal.ImageResource; -import org.eclipse.webbrowser.internal.Trace; -import org.eclipse.webbrowser.internal.WebBrowserPreference; -import org.eclipse.webbrowser.internal.WebBrowserUIPlugin; -import org.eclipse.core.runtime.IAdaptable; -/** - * The editor input for the integrated web browser. - */ -public class WebBrowserEditorInput implements IWebBrowserEditorInput, IPersistableElement, IElementFactory { - // --- constants to pass into constructor --- - - // if used, the toolbar will be available - public static final int SHOW_TOOLBAR = 1 << 1; - - // if used, the status bar will be available - public static final int SHOW_STATUSBAR = 1 << 2; - - // if used, this input will always force a new page - // and will never reuse an open Web browser - public static final int FORCE_NEW_PAGE = 1 << 3; - - // if used, the original URL will be saved and - // the page can reopen to the same URL after - // shutting down - public static final int SAVE_URL = 1 << 5; - - // if used, the browser will be transient and will not appear - // in the most recently used file list, nor will it reopen after - // restarting Eclipse - public static final int TRANSIENT = 1 << 6; - - public static final int SHOW_ALL = SHOW_TOOLBAR | SHOW_STATUSBAR; - - private static final String ELEMENT_FACTORY_ID = "org.eclipse.webbrowser.elementFactory"; - private static final String MEMENTO_URL = "url"; - private static final String MEMENTO_STYLE = "style"; - private static final String MEMENTO_ID = "id"; - - private URL url; - private int style; - private String id = null; - - /** - * WebBrowser editor input for the homepage. - */ - public WebBrowserEditorInput() { - this(null); - } - - /** - * WebBrowserEditorInput constructor comment. - */ - public WebBrowserEditorInput(URL url) { - this(url, SHOW_ALL | SAVE_URL); - } - - /** - * WebBrowserEditorInput constructor comment. - */ - public WebBrowserEditorInput(URL url, int style) { - super(); - this.url = url; - this.style = style; - } - - /** - * WebBrowserEditorInput constructor comment. - */ - public WebBrowserEditorInput(URL url, int style, String browserId) { - super(); - this.url = url; - this.style = style; - this.id = browserId; - } - - /** - * WebBrowserEditorInput constructor comment. - */ - public WebBrowserEditorInput(URL url, boolean b) { - this(url); - } - - /** - * Returns true if this page can reuse the browser that the - * given input is being displayed in, or false if it should - * open up in a new page. - * - * @param input org.eclipse.webbrowser.IWebBrowserEditorInput - * @return boolean - */ - public boolean canReplaceInput(IWebBrowserEditorInput input) { - Trace.trace(Trace.FINEST, "canReplaceInput " + this + " " + input); - if ((style & FORCE_NEW_PAGE) != 0) - return false; - else if (input.isToolbarVisible() != isToolbarVisible()) - return false; - else if (input.isStatusbarVisible() != isStatusbarVisible()) - return false; - else if (id != null) { - if (!(input instanceof WebBrowserEditorInput)) - return false; - String bid = ((WebBrowserEditorInput) input).getBrowserId(); - return id.equals(bid); - } else - return false; - } - - /** - * Creates anIElement from the state captured within 
-	 * an IMemento.
-	 *
-	 * @param memento a memento containing the state for an element
-	 * @return an element, or null if the element could not be created
-	 */
-	public IAdaptable createElement(IMemento memento) {
-		URL url2 = null;
-		try {
-			url2 = new URL(WebBrowserPreference.getHomePageURL());
-		} catch (Exception e) {
-			// could not determine the URL
-		}
-
-		int newStyle = SHOW_TOOLBAR | SHOW_STATUSBAR;
-		try {
-			newStyle = memento.getInteger(MEMENTO_STYLE).intValue();
-	
-			if ((newStyle & SAVE_URL) != 0)
-				url = new URL(memento.getString(MEMENTO_URL));
-		} catch (Exception e) {
-			// could not determine the style
-		}
-		
-		String id2 = null;
-		try {
-			id2 = memento.getString(MEMENTO_ID);
-			if (id2 != null && id2.length() < 1)
-				id2 = null;
-		} catch (Exception e) { }
-		
-		return new WebBrowserEditorInput(url2, newStyle, id2);
-	}
-	
-	/**
-	 * Indicates whether some other object is "equal to" this one.
-	 * In this case it means that the underlying IFolders are equal.
-	 */
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (!(obj instanceof WebBrowserEditorInput))
-			return false;
-		WebBrowserEditorInput other = (WebBrowserEditorInput) obj;
-	
-		if (url != null && !url.equals(obj))
-			return false;
-	
-		return canReplaceInput(other);
-	}
-	
-	/**
-	 * Returns whether the editor input exists.  
-	 * 
-	 * This method is primarily used to determine if an editor input should 
-	 * appear in the "File Most Recently Used" menu.  An editor input will appear 
-	 * in the list until the return value of exists becomes 
-	 * false or it drops off the bottom of the list.
-	 *
-	 * @return true if the editor input exists; false
-	 *		otherwise
-	 */
-	public boolean exists() {
-		if ((style & TRANSIENT) != 0)
-			return false;
-		else
-			return true;
-	}
-	
-	/**
-	 * Returns an object which is an instance of the given class
-	 * associated with this object. Returns null if
-	 * no such object can be found.
-	 *
-	 * @param adapter the adapter class to look up
-	 * @return a object castable to the given class, 
-	 *    or null if this object does not
-	 *    have an adapter for the given class
-	 */
-	public Object getAdapter(Class adapter) {
-		return null;
-	}
-	
-	/**
-	 * Returns the ID of an element factory which can be used to recreate 
-	 * this object.  An element factory extension with this ID must exist
-	 * within the workbench registry.
-	 * 
-	 * @return the element factory ID
-	 */
-	public String getFactoryId() {
-		return ELEMENT_FACTORY_ID;
-	}
-	
-	public ImageDescriptor getImageDescriptor() {
-		return ImageResource.getImageDescriptor(ImageResource.IMG_INTERNAL_BROWSER);
-	}
-	
-	/**
-	 * Returns the name of this editor input for display purposes.
-	 * 
-	 * For instance, if the fully qualified input name is
-	 * "a\b\MyFile.gif", the return value would be just
-	 * "MyFile.gif".
-	 *
-	 * @return the file name string
-	 */
-	public String getName() {
-		return WebBrowserUIPlugin.getResource("%viewWebBrowserTitle");
-	}
-	
-	/*
-	 * Returns an object that can be used to save the state of this editor input.
-	 *
-	 * @return the persistable element, or null if this editor input
-	 *   cannot be persisted
-	 */
-	public IPersistableElement getPersistable() {
-		if ((style & TRANSIENT) != 0)
-			return null;
-		else
-			return this;
-	}
-	
-	public String getToolTipText() {
-		if (url != null)
-			return url.toExternalForm();
-		else
-			return WebBrowserUIPlugin.getResource("%viewWebBrowserTitle");
-	}
-	
-	/**
-	 * Returns the url.
-	 *
-	 * @return java.net.URL
-	 */
-	public URL getURL() {
-		return url;
-	}
-	
-	/**
-	 * Returns the browser id. Browsers with a set id will always & only be
-	 * replaced by browsers with the same id.
-	 * 
-	 * @return String
-	 */
-	public String getBrowserId() {
-		return id;
-	}
-	
-	/**
-	 * Returns true if the status bar should be shown.
-	 *
-	 * @return boolean
-	 */
-	public boolean isStatusbarVisible() {
-		return (style & SHOW_STATUSBAR) != 0;
-	}
-	
-	/**
-	 * Returns true if the toolbar should be shown.
-	 *
-	 * @return boolean
-	 */
-	public boolean isToolbarVisible() {
-		return (style & SHOW_TOOLBAR) != 0;
-	}
-	
-	/**
-	 * Saves the state of an element within a memento.
-	 *
-	 * @param memento the storage area for element state
-	 */
-	public void saveState(IMemento memento) {
-		if ((style & SAVE_URL) != 0 && url != null)
-			memento.putString(MEMENTO_URL, url.toExternalForm());
-
-		memento.putInteger(MEMENTO_STYLE, style);
-		
-		if (id != null)
-			memento.putString(MEMENTO_ID, id);
-	}
-
-	/**
-	 * Converts this object to a string.
-	 *
-	 * @return java.lang.String
-	 */
-	public String toString() {
-		return "WebBrowserEditorInput[" + url + " " + style + " " + id + "]";
-	}
-}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/BrowserContentProvider.java b/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/BrowserContentProvider.java
deleted file mode 100644
index 5fe4aed..0000000
--- a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/BrowserContentProvider.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/**********************************************************************
- * Copyright (c) 2003 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- *
- * Contributors:
- *    IBM - Initial API and implementation
- **********************************************************************/
-package org.eclipse.webbrowser.internal;
-
-import java.util.*;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.jface.viewers.IStructuredContentProvider;
-import org.eclipse.webbrowser.IWebBrowser;
-
-/**
- * Monitor content provider.
- */
-public class BrowserContentProvider implements IStructuredContentProvider {
-	/**
-	 * BrowserContentProvider constructor comment.
-	 */
-	public BrowserContentProvider() {
-		super();
-	}
-
-	/**
-	 * Disposes of this content provider.  
-	 * This is called by the viewer when it is disposed.
-	 */
-	public void dispose() { }
-
-	/**
-	 * Returns the elements to display in the viewer 
-	 * when its input is set to the given element. 
-	 * These elements can be presented as rows in a table, items in a list, etc.
-	 * The result is not modified by the viewer.
-	 *
-	 * @param inputElement the input element
-	 * @return the array of elements to display in the viewer
-	 */
-	public Object[] getElements(Object inputElement) {
-		List list = new ArrayList();
-		Iterator iterator = BrowserManager.getInstance().getWebBrowsers().iterator();
-		while (iterator.hasNext()) {
-			IWebBrowser browser = (IWebBrowser) iterator.next();
-			list.add(browser);
-		}
-		return list.toArray();
-		}
-
-	/**
-	 * Notifies this content provider that the given viewer's input
-	 * has been switched to a different element.
-	 * 
- * A typical use for this method is registering the content provider as a listener - * to changes on the new input (using model-specific means), and deregistering the viewer - * from the old input. In response to these change notifications, the content provider - * propagates the changes to the viewer. - *
- * - * @param viewer the viewer - * @param oldInput the old input element, ornull if the viewer
-	 *   did not previously have an input
-	 * @param newInput the new input element, or null if the viewer
-	 *   does not have an input
-	 */
-	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {}
-}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/BrowserManager.java b/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/BrowserManager.java
deleted file mode 100644
index 55b33d9..0000000
--- a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/BrowserManager.java
+++ /dev/null
@@ -1,274 +0,0 @@
-/**********************************************************************
- * Copyright (c) 2003 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- *
- * Contributors:
- *    IBM - Initial API and implementation
- **********************************************************************/
-package org.eclipse.webbrowser.internal;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Preferences;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.ui.IMemento;
-import org.eclipse.ui.XMLMemento;
-import org.eclipse.webbrowser.IExternalWebBrowser;
-import org.eclipse.webbrowser.IExternalWebBrowserWorkingCopy;
-import org.eclipse.webbrowser.IInternalWebBrowser;
-import org.eclipse.webbrowser.IWebBrowser;
-/**
- * 
- */
-public class BrowserManager {
-	private static final int ADD = 0;
-	private static final int CHANGE = 1;
-	private static final int REMOVE = 2;
-
-	protected List browsers;
-	protected IWebBrowser currentBrowser;
-	protected List browserListeners = new ArrayList();
-	
-	private Preferences.IPropertyChangeListener pcl;
-	protected boolean ignorePreferenceChanges = false;
-
-	protected static BrowserManager instance;
-	
-	public static BrowserManager getInstance() {
-		if (instance == null)
-			instance = new BrowserManager();
-		return instance;
-	}
-	
-	private BrowserManager() {
-		pcl = new Preferences.IPropertyChangeListener() {
-			public void propertyChange(Preferences.PropertyChangeEvent event) {
-				if (ignorePreferenceChanges)
-					return;
-				String property = event.getProperty();
-				if (property.equals("browsers")) {
-					loadBrowsers();
-				}
-			}
-		};
-		
-		WebBrowserUIPlugin.getInstance().getPluginPreferences().addPropertyChangeListener(pcl);
-	}
-	
-	protected void dispose() {
-		WebBrowserUIPlugin.getInstance().getPluginPreferences().removePropertyChangeListener(pcl);
-		
-		// clear the cache
-		Iterator iterator = browsers.iterator();
-		while (iterator.hasNext()) {
-			Object obj = iterator.next();
-			if (obj instanceof IInternalWebBrowser) {
-				IInternalWebBrowser wb = (IInternalWebBrowser) obj;
-				if (wb.getClearHistoryOnExit())
-					WebBrowserPreference.setInternalWebBrowserHistory(null);
-			}
-		}
-	}
-
-	public IExternalWebBrowserWorkingCopy createExternalWebBrowser() {
-		return new ExternalWebBrowserWorkingCopy();
-	}	
-
-	public List getWebBrowsers() {
-		if (browsers == null)
-			loadBrowsers();
-		return new ArrayList(browsers);
-	}
-	
-	protected void loadBrowsers() {
-		Trace.trace(Trace.FINEST, "Loading web browsers");
-		
-		Preferences prefs = WebBrowserUIPlugin.getInstance().getPluginPreferences();
-		String xmlString = prefs.getString("browsers");
-		if (xmlString != null && xmlString.length() > 0) {
-			browsers = new ArrayList();
-			
-			try {
-				ByteArrayInputStream in = new ByteArrayInputStream(xmlString.getBytes());
-				Reader reader = new InputStreamReader(in);
-				IMemento memento = XMLMemento.createReadRoot(reader);
-		
-				IMemento child = memento.getChild("internal");
-				if (child != null) {
-					InternalWebBrowser browser = new InternalWebBrowser();
-					browser.load(child);
-					browsers.add(browser);
-				}
-				
-				IMemento[] children = memento.getChildren("external");
-				int size = children.length;
-				for (int i = 0; i < size; i++) {
-					ExternalWebBrowser browser = new ExternalWebBrowser();
-					browser.load(children[i]);
-					browsers.add(browser);
-				}
-				
-				Integer current = memento.getInteger("current");
-				if (current != null) {
-					currentBrowser = (IWebBrowser) browsers.get(current.intValue()); 
-				}	
-			} catch (Exception e) {
-				Trace.trace(Trace.WARNING, "Could not load browsers: " + e.getMessage());
-			}
-			addInternalBrowser(browsers);
-			if (currentBrowser == null && browsers.size() > 0)
-				currentBrowser = (IWebBrowser) browsers.get(0);
-		} else {
-			setupDefaultBrowsers();
-			saveBrowsers();
-			return;
-		}
-	}
-
-	protected void saveBrowsers() {
-		try {
-			ignorePreferenceChanges = true;
-			XMLMemento memento = XMLMemento.createWriteRoot("web-browsers");
-
-			Iterator iterator = browsers.iterator();
-			while (iterator.hasNext()) {
-				Object obj = iterator.next();
-				if (obj instanceof InternalWebBrowser) {
-					InternalWebBrowser browser = (InternalWebBrowser) obj;
-					IMemento child = memento.createChild("internal");
-					browser.save(child);
-				} else if (obj instanceof ExternalWebBrowser) {
-					ExternalWebBrowser browser = (ExternalWebBrowser) obj;
-					IMemento child = memento.createChild("external");
-					browser.save(child);
-				}
-			}
-			
-			memento.putInteger("current", browsers.indexOf(currentBrowser));
-
-			StringWriter writer = new StringWriter();
-			memento.save(writer);
-			String xmlString = writer.getBuffer().toString();
-			Preferences prefs = WebBrowserUIPlugin.getInstance().getPluginPreferences();
-			prefs.setValue("browsers", xmlString);
-			WebBrowserUIPlugin.getInstance().savePluginPreferences();
-		} catch (Exception e) {
-			Trace.trace(Trace.SEVERE, "Could not save browsers", e);
-		}
-		ignorePreferenceChanges = false;
-	}
-	
-	protected void addInternalBrowser(List browserList) {
-		if (browserList == null)
-			return;
-
-		Iterator iterator = browserList.iterator();
-		while (iterator.hasNext()) {
-			IWebBrowser browser = (IWebBrowser) iterator.next();
-			if (browser instanceof IInternalWebBrowser)
-				return;
-		}
-
-		// add the internal browser if we can
-		WebBrowserUIPlugin.getInstance().getLog().log(new Status(IStatus.INFO,
-			WebBrowserUIPlugin.PLUGIN_ID, 0, WebBrowserUtil.canUseInternalWebBrowser() + "/" + WebBrowserUtil.isInternalBrowserOperational(), null));
-		if (!WebBrowserUtil.canUseInternalWebBrowser() || !WebBrowserUtil.isInternalBrowserOperational())
-			return;
-		
-		browserList.add(0, new InternalWebBrowser());
-	}
-	
-	private void setupDefaultBrowsers() {
-		browsers = new ArrayList();
-		
-		addInternalBrowser(browsers);
-		
-		// handle all the EXTERNAL browsers by criteria and add those too at startup
-		WebBrowserUtil.addFoundBrowsers(browsers);
-		
-		// by default, if internal is there, that is current, else set the first external one
-		if (!browsers.isEmpty())
-			currentBrowser = (IWebBrowser) browsers.get(0);
-	}
-
-	protected void addBrowser(IExternalWebBrowser browser) {
-		if (browsers == null)
-			loadBrowsers();
-		if (!browsers.contains(browser))
-			browsers.add(browser);
-		fireWebBrowserEvent(browser, ADD);
-		saveBrowsers();
-	}
-	
-	protected void removeWebBrowser(IExternalWebBrowser browser) {
-		if (browsers == null)
-			loadBrowsers();
-		browsers.remove(browser);
-		fireWebBrowserEvent(browser, REMOVE);
-	}
-	
-	// Internal Web browser CAN be "edited", just not created or removed
-	protected void browserChanged(IWebBrowser browser) {
-		fireWebBrowserEvent(browser, CHANGE);
-		saveBrowsers();
-	}
-	
-	/**
-	 * Add Web browser listener.
-	 * @param listener
-	 */
-	public void addWebBrowserListener(IWebBrowserListener listener) {
-		browserListeners.add(listener);
-	}
-
-	/**
-	 * Remove Web browser listener.
-	 * @param listener
-	 */
-	public void removeWebBrowserListener(IWebBrowserListener listener) {
-		browserListeners.remove(listener);
-	}
-	
-	/**
-	 * Fire a Web browser event.
-	 * @param browser
-	 * @param type
-	 */
-	protected void fireWebBrowserEvent(IWebBrowser browser, int type) {
-		Object[] obj = browserListeners.toArray();
-		
-		int size = obj.length;
-		for (int i = 0; i < size; i++) {
-			IWebBrowserListener listener = (IWebBrowserListener) obj[i];
-			if (type == ADD)
-				listener.browserAdded(browser);
-			else if (type == CHANGE)
-				listener.browserChanged(browser);
-			else if (type == REMOVE)
-				listener.browserRemoved(browser);
-		}
-	}
-	
-	public IWebBrowser getCurrentWebBrowser() {
-		if (browsers == null)
-			loadBrowsers();
-
-		return currentBrowser; 
-	}
-
-	public void setCurrentWebBrowser(IWebBrowser wb) {
-		if (browsers.contains(wb))
-			currentBrowser = wb;
-		saveBrowsers();
-	}
-}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/BrowserSearcher.java b/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/BrowserSearcher.java
deleted file mode 100644
index c43dff2..0000000
--- a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/BrowserSearcher.java
+++ /dev/null
@@ -1,126 +0,0 @@
-package org.eclipse.webbrowser.internal;
-/**********************************************************************
- * Copyright (c) 2003 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
-  *
- * Contributors:
- *    IBM - Initial API and implementation
- **********************************************************************/
-import java.io.File;
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.List;
-import org.eclipse.jface.dialogs.ProgressMonitorDialog;
-import org.eclipse.jface.operation.IRunnableWithProgress;
-import org.eclipse.swt.widgets.DirectoryDialog;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.webbrowser.IExternalWebBrowserWorkingCopy;
-import org.eclipse.core.runtime.IProgressMonitor;
-/**
- * 
- */
-public class BrowserSearcher {
-	private static boolean cancelled;
-	private BrowserSearcher() {
-		super();
-	}
-
-	/**
-	 * Search for installed VMs in the file system
-	 */
-	protected static List search(Shell shell) {
-		final List foundBrowsers = new ArrayList();
-		final List existingPaths = WebBrowserUtil.getExternalBrowserPaths();
-
-		// select a target directory for the search
-		DirectoryDialog dialog = new DirectoryDialog(shell);
-		dialog.setMessage(WebBrowserUIPlugin.getResource("%selectDirectory"));
-		dialog.setText(WebBrowserUIPlugin.getResource("%directoryDialogTitle"));
-
-		String path = dialog.open();
-		if (path == null)
-			return null;
-		
-		cancelled = false;
-		
-		final File rootDir = new File(path);
-		ProgressMonitorDialog pm = new ProgressMonitorDialog(shell);
-
-		IRunnableWithProgress r = new IRunnableWithProgress() {
-			public void run(IProgressMonitor monitor) {
-				monitor.beginTask(
-					WebBrowserUIPlugin.getResource("%searchingTaskName"),
-					IProgressMonitor.UNKNOWN);
-				search(rootDir, existingPaths, foundBrowsers, monitor);
-				monitor.done();
-				if (monitor.isCanceled())
-					setCancelled(true);
-			}
-		};
-
-		try {
-			pm.run(true, true, r);
-		} catch (InvocationTargetException e) {
-			Trace.trace(Trace.SEVERE, "Invocation Exception occured running monitor: " + e);
-		} catch (InterruptedException e) {
-			Trace.trace(Trace.SEVERE, "Interrupted exception occured running monitor: " + e);
-			return null;
-		}
-		
-		if (cancelled)
-			return null;
-
-		return foundBrowsers;
-	}
-	
-	protected static void setCancelled(boolean b) {
-		cancelled = b;
-	}
-
-	protected static void search(File directory, List existingPaths, List foundBrowsers, IProgressMonitor monitor) {
-		if (monitor.isCanceled())
-			return;
-
-		String[] names = directory.list();
-		List subDirs = new ArrayList();
-
-		for (int i = 0; i < names.length; i++) {
-			if (monitor.isCanceled())
-				return;
-
-			File file = new File(directory, names[i]);
-			
-			if (existingPaths.contains(file.getAbsolutePath().toLowerCase()))
-				continue;
-
-			IExternalWebBrowserWorkingCopy wc = WebBrowserUtil.createExternalBrowser(file);
-			if (wc != null)
-				foundBrowsers.add(wc);
-
-			try {
-				monitor.subTask(
-					MessageFormat.format(WebBrowserUIPlugin.getResource("%searching"),
-						new String[] { Integer.toString(foundBrowsers.size()), file.getCanonicalPath()}));
-			} catch (IOException ioe) {
-			}
-
-			if (file.isDirectory()) {
-				if (monitor.isCanceled())
-					return;
-				subDirs.add(file);
-			}
-		}
-		while (!subDirs.isEmpty()) {
-			File subDir = (File) subDirs.remove(0);
-			search(subDir, existingPaths, foundBrowsers, monitor);
-			if (monitor.isCanceled()) {
-				return;
-			}
-		}
-	}
-}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/BrowserTableComposite.java b/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/BrowserTableComposite.java
deleted file mode 100644
index 32e38e5..0000000
--- a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/BrowserTableComposite.java
+++ /dev/null
@@ -1,272 +0,0 @@
-/**********************************************************************
- * Copyright (c) 2003 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- *
- * Contributors:
- *    IBM - Initial API and implementation
- **********************************************************************/
-package org.eclipse.webbrowser.internal;
-
-import java.util.Iterator;
-
-import org.eclipse.jface.viewers.*;
-import org.eclipse.jface.window.Window;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.*;
-import org.eclipse.ui.help.WorkbenchHelp;
-import org.eclipse.webbrowser.IExternalWebBrowser;
-import org.eclipse.webbrowser.IExternalWebBrowserWorkingCopy;
-import org.eclipse.webbrowser.IInternalWebBrowser;
-import org.eclipse.webbrowser.IInternalWebBrowserWorkingCopy;
-import org.eclipse.webbrowser.IWebBrowser;
-import org.eclipse.jface.viewers.CheckStateChangedEvent;
-import org.eclipse.jface.viewers.CheckboxTableViewer;
-import org.eclipse.jface.viewers.ICheckStateListener;
-/**
- * 
- */
-public class BrowserTableComposite extends Composite {
-	protected Table table;
-	protected CheckboxTableViewer tableViewer;
-	protected Button edit;
-	protected Button remove;
-	protected Button search;
-	protected IWebBrowser selection;
-	
-	protected Label location;
-	protected Label parameters;
-	
-	public BrowserTableComposite(Composite parent, int style) {
-		super(parent, style);
-		createWidgets();
-	}
-
-	protected void createWidgets() {
-		GridLayout layout = new GridLayout();
-		layout.horizontalSpacing = 5;
-		layout.verticalSpacing = 5;
-		layout.marginWidth = 0;
-		layout.marginHeight = 0;
-		layout.numColumns = 2;
-		setLayout(layout);
-
-		GridData data = new GridData(GridData.FILL_BOTH);
-		setLayoutData(data);
-		
-		Label label = new Label(this, SWT.NONE);
-		label.setText(WebBrowserUIPlugin.getResource("%browserList"));
-		data = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_CENTER);
-		data.horizontalSpan = 2;
-		label.setLayoutData(data);
-		
-		table = new Table(this, SWT.CHECK | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL | SWT.SINGLE | SWT.FULL_SELECTION);
-		data = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL);
-		data.widthHint = 300;
-		table.setLayoutData(data);
-		table.setHeaderVisible(false);
-		table.setLinesVisible(false);
-		
-		TableLayout tableLayout = new TableLayout();
-		new TableColumn(table, SWT.NONE);
-		
-		tableLayout.addColumnData(new ColumnWeightData(100));
-
-		table.setLayout(tableLayout);
-		
-		tableViewer = new CheckboxTableViewer(table);
-		
-		tableViewer.setContentProvider(new BrowserContentProvider());
-		tableViewer.setLabelProvider(new BrowserTableLabelProvider());
-	
-		tableViewer.setInput("root");
-
-		// uncheck any other elements that might be checked and leave only the element checked to
-		// remain checked since one can only chose one brower at a time to be current.
-		tableViewer.addCheckStateListener(new ICheckStateListener() {
-			public void checkStateChanged(CheckStateChangedEvent e) {
-				checkNewDefaultBrowser(e.getElement());
-				IWebBrowser browser = (IWebBrowser) e.getElement();
-				BrowserManager.getInstance().setCurrentWebBrowser(browser);
-				
-				// if no other browsers are checked, don't allow the single one currently
-				// checked to become unchecked, and lose a current browser. That is, don't
-				// permit unchecking if no other item is checked which is supposed to be the case.
-				Object[] obj = tableViewer.getCheckedElements();
-			   if (obj.length == 0)
-			    	tableViewer.setChecked(e.getElement(), true);
-			}
-		});
-		
-		// set a default, checked browser based on the current browser. If there is not a
-		// current browser, but the first item exists, use that instead.
-		// This will work currently until workbench shutdown, because current browser is not yet persisted.
-		IWebBrowser browser = BrowserManager.getInstance().getCurrentWebBrowser();
-		if (browser != null)
-			tableViewer.setChecked(browser, true);
-		else {
-			Object obj = tableViewer.getElementAt(0);
-			if (obj != null)
-				tableViewer.setChecked(obj, true);
-		}
-		
-		tableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
-			public void selectionChanged(SelectionChangedEvent event) {
-				Object obj = getSelection(event.getSelection());
-				
-				if (obj instanceof IInternalWebBrowser) {
-					selection = (IInternalWebBrowser) obj;
-					remove.setEnabled(false);
-					edit.setEnabled(true);
-				} else if (obj instanceof IExternalWebBrowser) {
-					selection = (IExternalWebBrowser) obj;
-					remove.setEnabled(true);
-					edit.setEnabled(true);
-				} else
-					selection = null;
-				
-				if (selection == null) {
-					edit.setEnabled(false);
-					remove.setEnabled(false);
-				}
-			}
-		});
-		
-		Composite buttonComp = new Composite(this, SWT.NONE);
-		layout = new GridLayout();
-		layout.horizontalSpacing = 0;
-		layout.verticalSpacing = 5;
-		layout.marginWidth = 0;
-		layout.marginHeight = 0;
-		layout.numColumns = 1;
-		buttonComp.setLayout(layout);
-		data = new GridData(GridData.HORIZONTAL_ALIGN_END | GridData.VERTICAL_ALIGN_FILL);
-		buttonComp.setLayoutData(data);
-		
-		Button add = SWTUtil.createButton(buttonComp, WebBrowserUIPlugin.getResource("%add"));
-		add.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				ExternalBrowserDialog dialog = new ExternalBrowserDialog(getShell());
-				if (dialog.open() == Window.CANCEL)
-					return;
-				tableViewer.refresh();
-			}
-		});
-		
-		edit = SWTUtil.createButton(buttonComp, WebBrowserUIPlugin.getResource("%edit"));
-		edit.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				IWebBrowser browser2 = getSelectedWebBrowser();
-
-				if (browser2 instanceof IInternalWebBrowser) {
-					IInternalWebBrowserWorkingCopy wc = ((IInternalWebBrowser) browser2).getWorkingCopy();
-					InternalBrowserDialog dialog = new InternalBrowserDialog(getShell(), wc);
-					if (dialog.open() != Window.CANCEL) {
-						try {
-							tableViewer.refresh(wc.save());
-						} catch (Exception ex) { }
-					}
-				}				
-				else if(browser2 instanceof IExternalWebBrowser) {
-					IExternalWebBrowserWorkingCopy wc = ((IExternalWebBrowser) browser2).getWorkingCopy();
-					ExternalBrowserDialog dialog = new ExternalBrowserDialog(getShell(), wc);
-					if (dialog.open() != Window.CANCEL) {
-						try {
-							tableViewer.refresh(wc.save());
-						} catch (Exception ex) { }
-					}
-				}
-		   }     		
-		});
-		edit.setEnabled(false);
-
-		remove = SWTUtil.createButton(buttonComp, WebBrowserUIPlugin.getResource("%remove"));
-		remove.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				IWebBrowser browser2 = getSelectedWebBrowser();
-				try {
-					if (browser2 instanceof IInternalWebBrowser){
-						remove.setEnabled(false);
-						return; // nothing else possible to do
-                    } 
-					else if(browser2 instanceof IExternalWebBrowser) {
-						remove.setEnabled(true);
-                       ((IExternalWebBrowser) browser2).delete();
-                       
-						tableViewer.remove(browser2);
-						
-						// need here to ensure that if the item deleted was checked, ie, was
-						// the current browser, that the new current browser will be the first in the
-						// list, typically, the internal browser, which cannot be deleted, and be current.
-						if(((IExternalWebBrowser) browser2) == BrowserManager.getInstance().getCurrentWebBrowser()){
-							Object obj = tableViewer.getElementAt(0);
-								if(obj != null){
-									BrowserManager.getInstance().setCurrentWebBrowser((InternalWebBrowser)obj);
-									tableViewer.setChecked(obj, true);
-								}
-						}
-					}
-				} catch (Exception ex) { }
-			}
-		});
-		remove.setEnabled(false);
-		
-		search = SWTUtil.createButton(buttonComp, WebBrowserUIPlugin.getResource("%search"));
-		search.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				java.util.List browsersToCreate = BrowserSearcher.search(getShell());
-				
-				if (browsersToCreate == null) // cancelled
-					return;
-				
-				if (browsersToCreate.isEmpty()) { // no browsers found
-					WebBrowserUtil.openMessage(WebBrowserUIPlugin.getResource("%searchingNoneFound"));
-					return;
-				}
-				
-				Iterator iterator = browsersToCreate.iterator();
-				while (iterator.hasNext()) {
-					IExternalWebBrowserWorkingCopy browser2 = (IExternalWebBrowserWorkingCopy) iterator.next();
-					browser2.save();
-				}
-				tableViewer.refresh();
-			}
-		});
-		WorkbenchHelp.setHelp(search, ContextIds.PREF_BROWSER_EXTERNAL_SEARCH);
-		
-		tableViewer.addCheckStateListener(new ICheckStateListener() {
-			public void checkStateChanged(CheckStateChangedEvent e) {
-				checkNewDefaultBrowser(e.getElement());
-				IWebBrowser browser2 = (IWebBrowser) e.getElement();
-				BrowserManager.getInstance().setCurrentWebBrowser(browser2);
-			}
-		});
-		search.setEnabled(true);
-	}
-	
-	public IWebBrowser getSelectedWebBrowser() {
-		return selection;
-	}
-	
-	protected Object getSelection(ISelection sel2) {
-		IStructuredSelection sel = (IStructuredSelection) sel2;
-		return sel.getFirstElement();
-	}
-	
-	// Uncheck all the items except the current one that was just checked
-	protected void checkNewDefaultBrowser(Object browser) {
-		TableItem[] children = tableViewer.getTable().getItems();
-		for (int i = 0; i < children.length; i++) {
-			TableItem item = children[i];
-			
-			if (!(item.getData().equals(browser))) 
-				item.setChecked(false);
-		}
-	}
-}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/BrowserTableLabelProvider.java b/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/BrowserTableLabelProvider.java
deleted file mode 100644
index 2ef12b7..0000000
--- a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/BrowserTableLabelProvider.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/**********************************************************************
- * Copyright (c) 2003 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- *
- * Contributors:
- *    IBM - Initial API and implementation
- **********************************************************************/
-package org.eclipse.webbrowser.internal;
-
-import org.eclipse.jface.viewers.ILabelProviderListener;
-
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.webbrowser.IExternalWebBrowser;
-import org.eclipse.webbrowser.IInternalWebBrowser;
-import org.eclipse.webbrowser.IWebBrowser;
-import org.eclipse.jface.viewers.ITableLabelProvider;
-/**
- * Web browser table label provider.
- */
-public class BrowserTableLabelProvider implements ITableLabelProvider {
-	/**
-	 * BrowserTableLabelProvider constructor comment.
-	 */
-	public BrowserTableLabelProvider() {
-		super();
-	}
-
-	/**
-	 * 
-	 */
-	public void addListener(ILabelProviderListener listener) { }
-
-	/**
-	 * 
-	 */
-	public void dispose() { }
-
-	/**
-	 * 
-	 */
-	public Image getColumnImage(Object element, int columnIndex) {
-		if (columnIndex == 0) {
-			if (element instanceof IInternalWebBrowser)
-				return ImageResource.getImage(ImageResource.IMG_INTERNAL_BROWSER);
-			else
-				return ImageResource.getImage(ImageResource.IMG_EXTERNAL_BROWSER);
-		}
-		return null;
-	}
-
-	/**
-	 * Returns the label text for the given column of the given element.
-	 *
-	 * @param element the object representing the entire row, or
-	 *   null indicating that no input object is set
-	 *   in the viewer
-	 * @param columnIndex the zero-based index of the column in which the label appears
-	 */
-	public String getColumnText(Object element, int columnIndex) {
-		IWebBrowser browser = (IWebBrowser)element;
-		if (browser instanceof IExternalWebBrowser) {
-			if (columnIndex == 0)
-				return notNull(((IExternalWebBrowser)browser).getName());
-			else if (columnIndex == 1)
-				return notNull(((IExternalWebBrowser)browser).getLocation());
-			else if (columnIndex == 2)
-				return notNull(((IExternalWebBrowser)browser).getParameters());
-		} else if(browser instanceof IInternalWebBrowser) {
-			if (columnIndex == 0)
-				return notNull(((IInternalWebBrowser)browser).getName());
-		}
-		return "";
-	}
-	
-	protected String notNull(String s) {
-		if (s != null)
-			return s;
-		else
-			return "";
-	}
-
-	/**
-	 * 
-	 */
-	public boolean isLabelProperty(Object element, String property) {
-		return false;
-	}
-
-	/**
-	 * 
-	 */
-	public void removeListener(ILabelProviderListener listener) { }
-}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/BusyIndicator.java b/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/BusyIndicator.java
deleted file mode 100644
index 4f984bc..0000000
--- a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/BusyIndicator.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/**
- * Copyright (c) 2003 IBM Corporation and others.
- * All rights reserved.   This program and the accompanying materials
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- *
- * Contributors:
- *    IBM - Initial API and implementation
- */
-package org.eclipse.webbrowser.internal;
-
-import org.eclipse.swt.widgets.*;
-import org.eclipse.swt.events.*;
-import org.eclipse.swt.graphics.*;
-/**
- * An animated image to show busy status of the Web browser.
- */
-public class BusyIndicator extends Canvas {
-	protected Image[] images;
-	protected Image image;
-
-	protected Thread busyThread;
-	protected boolean stop;
-
-	/**
-	 * BusyWidget constructor comment.
-	 * @param parent org.eclipse.swt.widgets.Composite
-	 * @param style int
-	 */
-	public BusyIndicator(Composite parent, int style) {
-		super(parent, style);
-	
-		images = ImageResource.getBusyImages();
-	
-		addPaintListener(new PaintListener() {
-			public void paintControl(PaintEvent event) {
-				onPaint(event);
-			}
-		});
-	
-		image = images[0];
-	}
-	
-	public Point computeSize(int wHint, int hHint, boolean changed) {
-		return new Point(25, 25);
-	}
-	
-	/**
-	 * Creates a thread to animate the image.
-	 */
-	protected synchronized void createBusyThread() {
-		if (busyThread != null)
-			return;
-	
-		stop = false;
-		busyThread = new Thread() {
-			protected int count;
-			public void run() {
-				try {
-					count = 1;
-					while (!stop) {
-						Display.getDefault().syncExec(new Runnable() {
-							public void run() {
-								if (!stop) {
-									if (count < 13)
-										setImage(images[count]);
-									count++;
-									if (count > 12)
-										count = 1;
-								}
-							}
-						});
-						try {
-							sleep(125);
-						} catch (Exception e) { }
-					}
-					if (busyThread == null)
-						Display.getDefault().syncExec(new Thread() {
-							public void run() {
-								setImage(images[0]);
-							}
-						});
-				} catch (Exception e) {
-					Trace.trace(Trace.WARNING, "Busy error", e);
-				}
-			}
-		};
-	
-		busyThread.setPriority(Thread.NORM_PRIORITY + 2);
-		busyThread.setDaemon(true);
-		busyThread.start();
-	}
-	
-	public void dispose() {
-		stop = true;
-		busyThread = null;
-		super.dispose();
-	}
-	
-	/**
-	 * Return the image or null.
-	 */
-	public Image getImage() {
-		return image;
-	}
-
-	/**
-	 * Returns true if it is currently busy.
-	 *
-	 * @return boolean
-	 */
-	public boolean isBusy() {
-		return (busyThread != null);
-	}
-
-	/* 
-	 * Process the paint event
-	 */
-	protected void onPaint(PaintEvent event) {
-		Rectangle rect = getClientArea();
-		if (rect.width == 0 || rect.height == 0)
-			return;
-	
-		GC gc = event.gc;
-		if (image != null)
-			gc.drawImage(image, 2, 2);
-	}
-
-	/**
-	 * Sets the indicators busy count up (true) or down (false) one.
-	 *
-	 * @param busy boolean
-	 */
-	public synchronized void setBusy(boolean busy) {
-		if (busy) {
-			if (busyThread == null)
-				createBusyThread();
-		} else {
-			if (busyThread != null) {
-				stop = true;
-				busyThread = null;
-			}
-		}
-	}
-
-	/**
-	 * Set the image.
-	 * The value null clears it.
-	 */
-	public void setImage(Image image) {
-		if (image != this.image && !isDisposed()) {
-			this.image = image;
-			redraw();
-		}
-	}
-}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/ContextIds.java b/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/ContextIds.java
deleted file mode 100644
index 3f27027..0000000
--- a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/ContextIds.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/**
- * Copyright (c) 2003 IBM Corporation and others.
- * All rights reserved.   This program and the accompanying materials
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- *
- * Contributors:
- *    IBM - Initial API and implementation
- */
-package org.eclipse.webbrowser.internal;
-/**
- * Context help id constants.
- */
-public interface ContextIds {
-	public static final String PREF_BROWSER = WebBrowserUIPlugin.PLUGIN_ID + ".wbpr0000";
-	public static final String PREF_BROWSER_INTERNAL = WebBrowserUIPlugin.PLUGIN_ID + ".wbpr0002";
-	public static final String PREF_BROWSER_EXTERNAL_ADD = WebBrowserUIPlugin.PLUGIN_ID + ".wbpr0004";
-	public static final String PREF_BROWSER_EXTERNAL_EDIT = WebBrowserUIPlugin.PLUGIN_ID + ".wbpr0005";
-	public static final String PREF_BROWSER_EXTERNAL_SEARCH = WebBrowserUIPlugin.PLUGIN_ID + ".wbpr0006";
-
-	public static final String WEB_BROWSER = WebBrowserUIPlugin.PLUGIN_ID + ".sewb0000";
-	public static final String WEB_BROWSER_URL = WebBrowserUIPlugin.PLUGIN_ID + ".sewb0002";
-	public static final String WEB_BROWSER_WEB = WebBrowserUIPlugin.PLUGIN_ID + ".sewb0004";
-}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/ExternalBrowserDialog.java b/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/ExternalBrowserDialog.java
deleted file mode 100644
index 22cce23..0000000
--- a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/ExternalBrowserDialog.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/**********************************************************************
- * Copyright (c) 2003 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- *
- * Contributors:
- *    IBM - Initial API and implementation
- **********************************************************************/
-package org.eclipse.webbrowser.internal;
-
-import java.io.File;
-
-import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.FileDialog;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.ui.help.WorkbenchHelp;
-import org.eclipse.webbrowser.IExternalWebBrowserWorkingCopy;
-/**
- * 
- */
-public class ExternalBrowserDialog extends Dialog {
-	protected IExternalWebBrowserWorkingCopy browser;
-	protected boolean isEdit;
-	protected Button newPageCheckbox;
-	protected Button clearHistoryCheckbox;
-	protected Button browseButton;
-	protected Text browserNameTextfield;
-	protected Text browserLocationTextfield;
-	protected Text browserParametersTextfield;
-	private Button okButton;
-	
-	interface StringModifyListener {
-		public void valueChanged(String s);
-	}
-	
-	/**
-	 * @param parentShell
-	 */
-	public ExternalBrowserDialog(Shell parentShell, IExternalWebBrowserWorkingCopy browser) {
-		super(parentShell);
-		this.browser = browser;
-		isEdit = true;
-	}
-
-	public ExternalBrowserDialog(Shell parentShell) {
-		super(parentShell);
-		browser = BrowserManager.getInstance().createExternalWebBrowser();
-		isEdit = false;
-	}
-
-	protected void configureShell(Shell shell) {
-		super.configureShell(shell);
-		
-		if (isEdit)
-			shell.setText(WebBrowserUIPlugin.getResource("%editExternalBrowser"));
-		else
-			shell.setText(WebBrowserUIPlugin.getResource("%createBrowser"));
-	}
-
-	protected Text createText(Composite comp, String txt, final StringModifyListener listener) {
-		final Text text = new Text(comp, SWT.BORDER);
-		if (txt != null)
-			text.setText(txt);
-		GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_BEGINNING);
-		data.widthHint = 250;
-		text.setLayoutData(data);
-		if (listener != null)
-			text.addModifyListener(new ModifyListener() {
-				public void modifyText(ModifyEvent e) {	
-					listener.valueChanged(text.getText());
-				}
-			});
-		return text;
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
-	 */
-	protected Control createDialogArea(Composite parent) {
-		Composite composite = (Composite) super.createDialogArea(parent);
-		((GridLayout)composite.getLayout()).numColumns = 3;
-		
-		if (isEdit)
-			WorkbenchHelp.setHelp(composite, ContextIds.PREF_BROWSER_EXTERNAL_EDIT);
-		else
-			WorkbenchHelp.setHelp(composite, ContextIds.PREF_BROWSER_EXTERNAL_ADD);
-		
-		SWTUtil.createLabel(composite, WebBrowserUIPlugin.getResource("%name"));
-		browserNameTextfield = createText(composite, browser.getName(), new StringModifyListener() {
-			public void valueChanged(String s) {
-				browser.setName(s);
-				validateFields();
-			}
-		});
-		
-		new Label(composite, SWT.NONE);
-	
-		SWTUtil.createLabel(composite, WebBrowserUIPlugin.getResource("%location"));
-		browserLocationTextfield = createText(composite, browser.getLocation(), new StringModifyListener() {
-			public void valueChanged(String s) {
-				browser.setLocation(s);
-				validateFields();
-			}
-		});		
-		
-		browseButton = SWTUtil.createButton(composite, WebBrowserUIPlugin.getResource("%browse"));
-		browseButton.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				FileDialog dialog = new FileDialog(getShell(), SWT.OPEN);
-				dialog.setText(WebBrowserUIPlugin.getResource("%browseMessage"));
-				
-				String fname = browserLocationTextfield.getText();
-				
-				dialog.setFileName(fname);
-				fname = dialog.open();
-				
-				if (fname != null)
-					browserLocationTextfield.setText(fname);
-			}
-		});
-		
-		SWTUtil.createLabel(composite, WebBrowserUIPlugin.getResource("%parameters"));
-		browserParametersTextfield = createText(composite, browser.getParameters(), new StringModifyListener() {
-			public void valueChanged(String s) {
-				browser.setParameters(s);
-			}
-		});
-
-		new Label(composite, SWT.NONE);
-		
-		new Label(composite, SWT.NONE);
-		Label urlLabel = new Label(composite, SWT.NONE);
-		urlLabel.setText(WebBrowserUIPlugin.getResource("%parametersMessage", WebBrowserPreference.URL_PARAMETER));
-	
-		
-		return composite;
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.jface.dialogs.Dialog#okPressed()
-	 */
-	protected void okPressed() {
-		// do simple field validation to at least ensure target directory entered is valid pathname
-		try {
-		File file = new File(browser.getLocation());
-			if(!file.isFile()){
-				WebBrowserUtil.openError(WebBrowserUIPlugin.getResource("%locationInvalid"));
-				return;
-			}
-		}
-		catch(Exception e){
-			WebBrowserUtil.openError(WebBrowserUIPlugin.getResource("%locationInvalid"));
-			return;
-		}
-		
-		browser.save();
-		super.okPressed();
-	}
-	
-	private void setOKButtonEnabled(boolean curIsEnabled) {
-		if (okButton == null)
-			okButton = getButton(IDialogConstants.OK_ID);
-		
-		if (okButton != null)
-			okButton.setEnabled(curIsEnabled);
-	}
-	
-	protected Control createButtonBar(Composite parent) {
-		Control buttonControl = super.createButtonBar(parent);
-		validateFields();
-		return buttonControl;
-	}
-	
-	protected void validateFields() {
-		boolean valid = true;
-		
-		String name = browserNameTextfield.getText();
-		if (name == null || name.trim().length() < 1)
-			valid = false;
-		
-		String location = browserLocationTextfield.getText();
-		if (location == null || location.trim().length() < 1)
-			valid = false;
-		
-		setOKButtonEnabled(valid);
-	}
-}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/ExternalWebBrowser.java b/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/ExternalWebBrowser.java
deleted file mode 100644
index 03eaefb..0000000
--- a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/ExternalWebBrowser.java
+++ /dev/null
@@ -1,139 +0,0 @@
-package org.eclipse.webbrowser.internal;
-
-import java.net.URL;
-
-import org.eclipse.swt.program.Program;
-import org.eclipse.ui.IMemento;
-import org.eclipse.webbrowser.IExternalWebBrowser;
-import org.eclipse.webbrowser.IExternalWebBrowserWorkingCopy;
-/**
- * 
- */
-public class ExternalWebBrowser implements IExternalWebBrowser {
-	private static final String MEMENTO_NAME = "name";
-	private static final String MEMENTO_LOCATION = "location";
-	private static final String MEMENTO_PARAMETERS = "parameters";
-
-	protected String name;
-	protected String location;
-	protected String parameters;
-	
-	/* (non-Javadoc)
-	 * @see org.eclipse.webbrowser.IWebBrowser#getName()
-	 */
-	public String getName() {
-		return name;
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.webbrowser.IExternalWebBrowser#getLocation()
-	 */
-	public String getLocation() {
-		return location;
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.webbrowser.IExternalWebBrowser#getParameters()
-	 */
-	public String getParameters() {
-		return parameters;
-	}
-	
-	public void delete() {
-		BrowserManager.getInstance().removeWebBrowser(this);
-	}
-
-	public boolean isWorkingCopy() {
-		return false;
-	}
-
-	public IExternalWebBrowserWorkingCopy getWorkingCopy() {
-		return new ExternalWebBrowserWorkingCopy(this);
-	}
-
-	protected void setInternal(IExternalWebBrowser browser) {
-		name = browser.getName();
-		location = browser.getLocation();
-		parameters = browser.getParameters();
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.webbrowser.IWebBrowser#openURL(java.net.URL)
-	 */
-	public void openURL(URL url) {
-		String urlText = WebBrowserPreference.getHomePageURL();
-		
-		if (url != null)
-			urlText = url.toExternalForm();
-		else if (urlText.startsWith("file:") & urlText.length() > 6) {
-			if (urlText.charAt(5) != '/' && urlText.charAt(5) != '\\')
-				urlText = urlText.substring(0, 5) + "/" + urlText.substring(5);
-		}
-
-		// change spaces to "%20"
-		if (!WebBrowserUtil.isWindows()) {
-			int index = urlText.indexOf(" ");
-			while (index >= 0) {
-				urlText = urlText.substring(0, index) + "%20" + urlText.substring(index + 1);
-				index = urlText.indexOf(" ");
-			}
-		}
-
-		Trace.trace(Trace.FINEST, "Launching external Web browser: " + location + " - " + parameters + " - " + urlText);
-		if (location == null || location.length() == 0) {
-			try {
-				String extension = null;
-				if (url != null)
-					extension = url.getFile();
-				else
-					extension = "html";
-				int index = extension.indexOf(".");
-				if (index >= 0)
-					extension = extension.substring(index + 1);
-				Program program = Program.findProgram(extension);
-				program.execute(urlText);
-			} catch (Exception e) {
-				Trace.trace(Trace.SEVERE, "Error launching default external browser", e);
-				WebBrowserUtil.openError(WebBrowserUIPlugin.getResource("%errorCouldNotLaunchWebBrowser", urlText));
-			}
-			return;
-		}
-		
-		String params = parameters;
-		if (params == null)
-			params = "";
-		
-		int urlIndex = params.indexOf(WebBrowserPreference.URL_PARAMETER);
-		if (urlIndex >= 0)
-			params = params.substring(0, urlIndex) + " " + urlText + " " + params.substring(urlIndex + WebBrowserPreference.URL_PARAMETER.length());
-		else {
-			if (!params.endsWith(" "))
-				params += " ";
-			params += urlText;
-		}
-		
-		try {
-			Trace.trace(Trace.FINEST, "Launching " + location + " " + params);
-			Runtime.getRuntime().exec(location + " " + params);
-		} catch (Exception e) {
-			Trace.trace(Trace.SEVERE, "Could not launch external browser", e);
-			WebBrowserUtil.openError(WebBrowserUIPlugin.getResource("%errorCouldNotLaunchWebBrowser", urlText));
-		}
-	}
-
-	protected void save(IMemento memento) {
-		memento.putString(MEMENTO_NAME, name);
-		memento.putString(MEMENTO_LOCATION, location);
-		memento.putString(MEMENTO_PARAMETERS, parameters);
-	}
-
-	protected void load(IMemento memento) {
-		name = memento.getString(MEMENTO_NAME);
-		location = memento.getString(MEMENTO_LOCATION);
-		parameters = memento.getString(MEMENTO_PARAMETERS);
-	}
-
-	public String toString() {
-		return "External Web browser: " + getName() + " / " + getLocation() + " / " + getParameters();
-	}
-}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/ExternalWebBrowserWorkingCopy.java b/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/ExternalWebBrowserWorkingCopy.java
deleted file mode 100644
index 0f231a6..0000000
--- a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/ExternalWebBrowserWorkingCopy.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package org.eclipse.webbrowser.internal;
-
-import org.eclipse.webbrowser.IExternalWebBrowser;
-import org.eclipse.webbrowser.IExternalWebBrowserWorkingCopy;
-/**
- * 
- */
-public class ExternalWebBrowserWorkingCopy extends ExternalWebBrowser implements IExternalWebBrowserWorkingCopy {
-	protected ExternalWebBrowser browser;
-
-	// creation
-	public ExternalWebBrowserWorkingCopy() { }
-
-	// working copy
-	public ExternalWebBrowserWorkingCopy(ExternalWebBrowser browser) {
-		this.browser = browser;
-		setInternal(browser);
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.webbrowser.IExternalWebBrowserWorkingCopy#setName(java.lang.String)
-	 */
-	public void setName(String name) {
-		this.name = name;
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.webbrowser.IExternalWebBrowserWorkingCopy#setLocation(java.lang.String)
-	 */
-	public void setLocation(String location) {
-		this.location = location;
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.webbrowser.IExternalWebBrowserWorkingCopy#setParameters(java.lang.String)
-	 */
-	public void setParameters(String params) {
-		this.parameters = params;
-	}
-
-	public boolean isWorkingCopy() {
-		return true;
-	}
-	
-	public IExternalWebBrowserWorkingCopy getWorkingCopy() {
-		return this;
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.webbrowser.IExternalWebBrowserWorkingCopy#save()
-	 */
-	public IExternalWebBrowser save() {
-		if (browser != null) {
-			browser.setInternal(this);
-			BrowserManager.getInstance().browserChanged(browser);
-		} else {
-			browser = new ExternalWebBrowser();
-			browser.setInternal(this);
-			BrowserManager.getInstance().addBrowser(browser);
-		}
-		return browser;
-	}
-}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/Favorite.java b/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/Favorite.java
deleted file mode 100644
index fda20d0..0000000
--- a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/Favorite.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * Copyright (c) 2003 IBM Corporation and others.
- * All rights reserved.   This program and the accompanying materials
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- *
- * Contributors:
- *    IBM - Initial API and implementation
- */
-package org.eclipse.webbrowser.internal;
-/**
- * 
- */
-public class Favorite {
-	protected String url;
-	protected String name;
-
-	public Favorite() { }
-	
-	public Favorite(String name, String url) {
-		if (name == null)
-			name = "";
-		if (url == null)
-			url = "";
-		this.name = name;
-		this.url = url;
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public void setName(String name) {
-		this.name = name;
-	}
-
-	public String getURL() {
-		return url;
-	}
-
-	public void setURL(String url) {
-		this.url = url;
-	}
-	
-	public boolean equals(Object obj) {
-		if (!(obj instanceof Favorite))
-			return false;
-		
-		Favorite f = (Favorite) obj;
-		return (name.equals(f.name) && url.equals(f.url));
-	}
-	
-	public String toString() {
-		return "(" + name + "/" + url + ")";
-	}
-}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/IWebBrowserListener.java b/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/IWebBrowserListener.java
deleted file mode 100644
index d04666b..0000000
--- a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/IWebBrowserListener.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/**********************************************************************
- * Copyright (c) 2003 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- *
- * Contributors:
- *    IBM - Initial API and implementation
- **********************************************************************/
-package org.eclipse.webbrowser.internal;
-
-import org.eclipse.webbrowser.IWebBrowser;
-
-/**
- * 
- */
-public interface IWebBrowserListener {
-	public void browserAdded(IWebBrowser browser);
-	
-	public void browserChanged(IWebBrowser browser);
-	
-	public void browserRemoved(IWebBrowser browser);
-}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/ImageResource.java b/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/ImageResource.java
deleted file mode 100644
index a1637ec..0000000
--- a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/ImageResource.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/**
- * Copyright (c) 2003 IBM Corporation and others.
- * All rights reserved.   This program and the accompanying materials
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- *
- * Contributors:
- *    IBM - Initial API and implementation
- */
-package org.eclipse.webbrowser.internal;
-
-import java.net.URL;
-import java.util.Map;
-import java.util.HashMap;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.jface.resource.ImageRegistry;
-/**
- * Utility class to handle image resources.
- */
-public class ImageResource {
-	// the image registry
-	private static ImageRegistry imageRegistry;
-
-	// map of image descriptors since these
-	// will be lost by the image registry
-	private static Map imageDescriptors;
-
-	// base urls for images
-	private static URL ICON_BASE_URL;
-
-	static {
-		try {
-			String pathSuffix = "icons/";
-			ICON_BASE_URL = WebBrowserUIPlugin.getInstance().getBundle().getEntry(pathSuffix);
-		} catch (Exception e) {
-			Trace.trace(Trace.SEVERE, "Could not set icon base URL", e);
-		}
-	}
-
-	private static Image[] busyImages;
-
-	private static final String URL_CLCL = "clcl16/";
-	private static final String URL_ELCL = "elcl16/";
-	private static final String URL_DLCL = "dlcl16/";
-
-	private static final String URL_OBJ = "obj16/";
-
-	// --- constants for images ---
-	// toolbar images
-	public static final String IMG_CLCL_NAV_BACKWARD = "IMG_CLCL_NAV_BACKWARD";
-	public static final String IMG_CLCL_NAV_FORWARD = "IMG_CLCL_NAV_FORWARD";
-	public static final String IMG_CLCL_NAV_STOP = "IMG_CLCL_NAV_STOP";
-	public static final String IMG_CLCL_NAV_REFRESH = "IMG_CLCL_NAV_REFRESH";
-	public static final String IMG_CLCL_NAV_GO = "IMG_CLCL_NAV_GO";
-	public static final String IMG_CLCL_NAV_FAVORITES = "cfavorites";
-	public static final String IMG_CLCL_NAV_HOME = "IMG_CLCL_NAV_HOME";
-	public static final String IMG_CLCL_NAV_PRINT = "IMG_CLCL_NAV_PRINT";
-
-	public static final String IMG_ELCL_NAV_BACKWARD = "IMG_ELCL_NAV_BACKWARD";
-	public static final String IMG_ELCL_NAV_FORWARD = "IMG_ELCL_NAV_FORWARD";
-	public static final String IMG_ELCL_NAV_STOP = "IMG_ELCL_NAV_STOP";
-	public static final String IMG_ELCL_NAV_REFRESH = "IMG_ELCL_NAV_REFRESH";
-	public static final String IMG_ELCL_NAV_GO = "IMG_ELCL_NAV_GO";
-	public static final String IMG_ELCL_NAV_FAVORITES = "efavorites";
-	public static final String IMG_ELCL_NAV_HOME = "IMG_ELCL_NAV_HOME";
-	public static final String IMG_ELCL_NAV_PRINT = "IMG_ELCL_NAV_PRINT";
-
-	public static final String IMG_DLCL_NAV_BACKWARD = "IMG_DLCL_NAV_BACKWARD";
-	public static final String IMG_DLCL_NAV_FORWARD = "IMG_DLCL_NAV_FORWARD";
-	public static final String IMG_DLCL_NAV_STOP = "IMG_DLCL_NAV_STOP";
-	public static final String IMG_DLCL_NAV_REFRESH = "IMG_DLCL_NAV_REFRESH";
-	public static final String IMG_DLCL_NAV_GO = "IMG_DLCL_NAV_GO";
-	public static final String IMG_DLCL_NAV_FAVORITES = "dfavorites";
-	public static final String IMG_DLCL_NAV_HOME = "IMG_DLCL_NAV_HOME";
-	public static final String IMG_DLCL_NAV_PRINT = "IMG_DLCL_NAV_PRINT";
-
-	// general object images
-	public static final String IMG_INTERNAL_BROWSER = "internalBrowser";
-	public static final String IMG_EXTERNAL_BROWSER = "externalBrowser";
-	public static final String IMG_FAVORITE = "favorite";
-
-	/**
-	 * Cannot construct an ImageResource. Use static methods only.
-	 */
-	private ImageResource() { }
-
-	/**
-	 * Returns the busy images for the Web browser.
-	 *
-	 * @return org.eclipse.swt.graphics.Image[]
-	 */
-	public static Image[] getBusyImages() {
-		return busyImages;
-	}
-
-	/**
-	 * Return the image with the given key.
-	 *
-	 * @param key java.lang.String
-	 * @return org.eclipse.swt.graphics.Image
-	 */
-	public static Image getImage(String key) {
-		if (imageRegistry == null)
-			initializeImageRegistry();
-		return imageRegistry.get(key);
-	}
-
-	/**
-	 * Return the image descriptor with the given key.
-	 *
-	 * @param key java.lang.String
-	 * @return org.eclipse.jface.resource.ImageDescriptor
-	 */
-	public static ImageDescriptor getImageDescriptor(String key) {
-		if (imageRegistry == null)
-			initializeImageRegistry();
-		return (ImageDescriptor) imageDescriptors.get(key);
-	}
-
-	/**
-	 * Initialize the image resources.
-	 */
-	protected static void initializeImageRegistry() {
-		imageRegistry = new ImageRegistry();
-		imageDescriptors = new HashMap();
-	
-		// load Web browser images
-		registerImage(IMG_ELCL_NAV_BACKWARD, URL_ELCL + "nav_backward.gif");
-		registerImage(IMG_ELCL_NAV_FORWARD, URL_ELCL + "nav_forward.gif");
-		registerImage(IMG_ELCL_NAV_STOP, URL_ELCL + "nav_stop.gif");
-		registerImage(IMG_ELCL_NAV_REFRESH, URL_ELCL + "nav_refresh.gif");
-		registerImage(IMG_ELCL_NAV_GO, URL_ELCL + "nav_go.gif");
-		registerImage(IMG_ELCL_NAV_FAVORITES, URL_ELCL + "add_favorite.gif");
-		registerImage(IMG_ELCL_NAV_HOME, URL_ELCL + "nav_home.gif");
-		registerImage(IMG_ELCL_NAV_PRINT, URL_ELCL + "nav_print.gif");
-	
-		registerImage(IMG_CLCL_NAV_BACKWARD, URL_CLCL + "nav_backward.gif");
-		registerImage(IMG_CLCL_NAV_FORWARD, URL_CLCL + "nav_forward.gif");
-		registerImage(IMG_CLCL_NAV_STOP, URL_CLCL + "nav_stop.gif");
-		registerImage(IMG_CLCL_NAV_REFRESH, URL_CLCL + "nav_refresh.gif");
-		registerImage(IMG_CLCL_NAV_GO, URL_CLCL + "nav_go.gif");
-		registerImage(IMG_CLCL_NAV_FAVORITES, URL_CLCL + "add_favorite.gif");
-		registerImage(IMG_CLCL_NAV_HOME, URL_CLCL + "nav_home.gif");
-		registerImage(IMG_CLCL_NAV_PRINT, URL_CLCL + "nav_print.gif");
-	
-		registerImage(IMG_DLCL_NAV_BACKWARD, URL_DLCL + "nav_backward.gif");
-		registerImage(IMG_DLCL_NAV_FORWARD, URL_DLCL + "nav_forward.gif");
-		registerImage(IMG_DLCL_NAV_STOP, URL_DLCL + "nav_stop.gif");
-		registerImage(IMG_DLCL_NAV_REFRESH, URL_DLCL + "nav_refresh.gif");
-		registerImage(IMG_DLCL_NAV_GO, URL_DLCL + "nav_go.gif");
-		registerImage(IMG_DLCL_NAV_FAVORITES, URL_DLCL + "add_favorite.gif");
-		registerImage(IMG_DLCL_NAV_HOME, URL_DLCL + "nav_home.gif");
-		registerImage(IMG_DLCL_NAV_PRINT, URL_DLCL + "nav_print.gif");
-	
-		registerImage(IMG_INTERNAL_BROWSER, URL_OBJ + "internal_browser.gif");
-		registerImage(IMG_EXTERNAL_BROWSER, URL_OBJ + "external_browser.gif");
-		
-		registerImage(IMG_FAVORITE, URL_OBJ + "favorite.gif");
-		
-		// busy images
-		busyImages = new Image[13];
-		for (int i = 0; i < 13; i++) {
-			registerImage("busy" + i, URL_OBJ + "frames" + java.io.File.separator + "frame" + (i+1) + ".gif");
-			busyImages[i] = getImage("busy" + i);
-		}
-	}
-
-	/**
-	 * Register an image with the registry.
-	 *
-	 * @param key java.lang.String
-	 * @param partialURL java.lang.String
-	 */
-	private static void registerImage(String key, String partialURL) {
-		try {
-			ImageDescriptor id = ImageDescriptor.createFromURL(new URL(ICON_BASE_URL, partialURL));
-			imageRegistry.put(key, id);
-			imageDescriptors.put(key, id);
-		} catch (Exception e) {
-			Trace.trace(Trace.WARNING, "Error registering image " + key + " from " + partialURL, e);
-		}
-	}
-}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/InternalBrowserDialog.java b/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/InternalBrowserDialog.java
deleted file mode 100644
index dda0f88..0000000
--- a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/InternalBrowserDialog.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/**********************************************************************
- * Copyright (c) 2003 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- *
- * Contributors:
- *    IBM - Initial API and implementation
- **********************************************************************/
-package org.eclipse.webbrowser.internal;
-
-import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.ui.help.WorkbenchHelp;
-import org.eclipse.webbrowser.IInternalWebBrowserWorkingCopy;
-import org.eclipse.webbrowser.internal.SWTUtil;
-/**
- * 
- */
-public class InternalBrowserDialog extends Dialog {
-	protected IInternalWebBrowserWorkingCopy browser;
-	protected boolean isEdit;
-	protected Button newPageCheckbox;
-	protected Button clearURLHistoryCheckbox;
-	
-	/**
-	 * @param parentShell
-	 */
-	public InternalBrowserDialog(Shell parentShell, IInternalWebBrowserWorkingCopy browser) {
-		super(parentShell);
-		this.browser = browser;
-		isEdit = true;
-	}
-
-	protected void configureShell(Shell shell) {
-		super.configureShell(shell);
-		
-		if (isEdit)
-			shell.setText(WebBrowserUIPlugin.getResource("%editInternalBrowser"));
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
-	 */
-	protected Control createDialogArea(Composite parent) {
-		Composite composite = (Composite) super.createDialogArea(parent);
-		((GridLayout)composite.getLayout()).numColumns = 1;
-		
-		Composite comp = new Composite(composite, SWT.NONE);
-		GridLayout layout = new GridLayout(1, true);
-		layout.marginHeight = 10;
-		layout.marginWidth = 10;
-		comp.setLayout(layout);
-		comp.setLayoutData(new GridData(GridData.FILL_BOTH));
-		WorkbenchHelp.setHelp(composite, ContextIds.PREF_BROWSER_INTERNAL);
-		
-		newPageCheckbox = SWTUtil.createCheckbox(comp, WebBrowserUIPlugin.getResource("%prefBrowserNewPage"), false);
-		clearURLHistoryCheckbox = SWTUtil.createCheckbox(comp, WebBrowserUIPlugin.getResource("%clearURLHistory"), true);
-		
-		newPageCheckbox.setSelection(browser.getUseNewPage());
-		clearURLHistoryCheckbox.setSelection(browser.getClearHistoryOnExit());
-		
-		return composite;
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.jface.dialogs.Dialog#okPressed()
-	 */
-	protected void okPressed() {
-		browser.setUseNewPage(newPageCheckbox.getSelection());
-		browser.setClearHistoryOnExit(clearURLHistoryCheckbox.getSelection());
-		browser.save();
-		
-		super.okPressed();
-	}
-}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/InternalWebBrowser.java b/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/InternalWebBrowser.java
deleted file mode 100644
index 4071a7c..0000000
--- a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/InternalWebBrowser.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package org.eclipse.webbrowser.internal;
-
-import java.net.URL;
-
-import org.eclipse.ui.IMemento;
-import org.eclipse.webbrowser.IInternalWebBrowser;
-import org.eclipse.webbrowser.IInternalWebBrowserWorkingCopy;
-import org.eclipse.webbrowser.WebBrowserEditorInput;
-/**
- * 
- */
-public class InternalWebBrowser implements IInternalWebBrowser {
-	private static final String MEMENTO_NEW_PAGE = "new_page";
-	private static final String MEMENTO_CLEAR_HISTORY_ON_EXIT = "clear_history";
-
-	protected boolean useNewPage;
-	protected boolean clearHistory;
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.webbrowser.IWebBrowser#getName()
-	 */
-	public String getName() {
-		return WebBrowserUIPlugin.getResource("%internalWebBrowserName");
-	}
-	
-	public boolean getUseNewPage() {
-		return useNewPage;
-	}
-	
-	public boolean getClearHistoryOnExit() {
-		return clearHistory;
-	}
-	
-	public boolean isWorkingCopy() {
-		return false;
-	}
-
-	public IInternalWebBrowserWorkingCopy getWorkingCopy() {
-		return new InternalWebBrowserWorkingCopy(this);
-	}
-	
-	protected void setInternal(IInternalWebBrowser browser) {
-		useNewPage = browser.getUseNewPage();
-		clearHistory = browser.getClearHistoryOnExit();
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.webbrowser.IWebBrowser#openURL(java.net.URL)
-	 */
-	public void openURL(URL url) {
-		WebBrowserEditor.open(new WebBrowserEditorInput(url));
-	}
-	
-	protected void save(IMemento memento) {
-		memento.putString(MEMENTO_NEW_PAGE, useNewPage ? "true" : "false");
-		memento.putString(MEMENTO_CLEAR_HISTORY_ON_EXIT, clearHistory ? "true" : "false");
-	}
-
-	protected void load(IMemento memento) {
-		String s = memento.getString(MEMENTO_NEW_PAGE);
-		if ("true".equals(s))
-			useNewPage = true;
-		else
-			useNewPage = false;
-		
-		s = memento.getString(MEMENTO_CLEAR_HISTORY_ON_EXIT);
-		if ("true".equals(s))
-			clearHistory = true;
-		else
-			clearHistory = false;
-	}
-	
-	public String toString() {
-		return "Internal Web browser";
-	}
-}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/InternalWebBrowserWorkingCopy.java b/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/InternalWebBrowserWorkingCopy.java
deleted file mode 100644
index 3dac171..0000000
--- a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/InternalWebBrowserWorkingCopy.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package org.eclipse.webbrowser.internal;
-
-import org.eclipse.webbrowser.IInternalWebBrowser;
-import org.eclipse.webbrowser.IInternalWebBrowserWorkingCopy;
-/**
- * 
- */
-public class InternalWebBrowserWorkingCopy extends InternalWebBrowser implements IInternalWebBrowserWorkingCopy {
-	protected InternalWebBrowser browser;
-
-	// working copy
-	public InternalWebBrowserWorkingCopy(InternalWebBrowser browser) {
-		this.browser = browser;
-		setInternal(browser);
-	}
-
-	public void setUseNewPage(boolean b) {
-		useNewPage = b;
-	}
-	
-	public void setClearHistoryOnExit(boolean b) {
-		clearHistory = b;
-	}
-
-	public boolean isWorkingCopy() {
-		return true;
-	}
-	
-	public IInternalWebBrowserWorkingCopy getWorkingCopy() {
-		return this;
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.webbrowser.IExternalWebBrowserWorkingCopy#save()
-	 */
-	public IInternalWebBrowser save() {
-		if (browser != null) {
-			browser.setInternal(this);
-			BrowserManager.getInstance().browserChanged(browser);
-		}
-		return browser;
-	}
-}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/InternetPreferencePage.java b/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/InternetPreferencePage.java
deleted file mode 100644
index 65a7efb..0000000
--- a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/InternetPreferencePage.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
- * Copyright (c) 2003 IBM Corporation and others.
- * All rights reserved.   This program and the accompanying materials
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- *
- * Contributors:
- *    IBM - Initial API and implementation
- */
-package org.eclipse.webbrowser.internal;
-
-import org.eclipse.swt.*;
-import org.eclipse.swt.layout.*;
-import org.eclipse.swt.widgets.*;
-import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.preference.PreferencePage;
-import org.eclipse.ui.IWorkbench;
-import org.eclipse.ui.IWorkbenchPreferencePage;
-import org.eclipse.ui.help.WorkbenchHelp;
-/**
- * A preference page that holds internet preferences.
- */
-public class InternetPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
-	/**
-	 * InternetPreferencePage constructor comment.
-	 */
-	public InternetPreferencePage() {
-		super();
-		noDefaultAndApplyButton();
-	}
-
-	/**
-	 * Create the preference options.
-	 *
-	 * @param parent org.eclipse.swt.widgets.Composite
-	 * @return org.eclipse.swt.widgets.Control
-	 */
-	protected Control createContents(Composite parent) {
-		initializeDialogUnits(parent);
-		
-		Composite composite = new Composite(parent, SWT.NONE);
-		GridLayout layout = new GridLayout();
-		layout.numColumns = 1;
-		layout.horizontalSpacing = convertHorizontalDLUsToPixels(4);
-		layout.verticalSpacing = convertVerticalDLUsToPixels(4);
-		layout.marginWidth = 0;
-		layout.marginHeight = 0;
-		composite.setLayout(layout);
-		GridData data = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL);
-		composite.setLayoutData(data);
-		WorkbenchHelp.setHelp(composite, ContextIds.PREF_BROWSER);
-		
-		Label label = new Label(composite, SWT.WRAP);
-		label.setText(WebBrowserUIPlugin.getResource("%preferenceInternetDescription"));
-		data = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
-		label.setLayoutData(data);
-		
-		Dialog.applyDialogFont(composite);
-		
-		return composite;
-	}
-
-	/**
-	 * Initializes this preference page using the passed desktop.
-	 *
-	 * @param desktop the current desktop
-	 */
-	public void init(IWorkbench workbench) { }
-}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/OpenWithBrowserActionDelegate.java b/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/OpenWithBrowserActionDelegate.java
deleted file mode 100644
index 063f730..0000000
--- a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/OpenWithBrowserActionDelegate.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/**
- * Copyright (c) 2003 IBM Corporation and others.
- * All rights reserved.   This program and the accompanying materials
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- *
- * Contributors:
- *    IBM - Initial API and implementation
- */
-package org.eclipse.webbrowser.internal;
-
-import java.net.URL;
-import java.util.Iterator;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.action.IAction;
-import org.eclipse.ui.*;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.webbrowser.WebBrowser;
-import org.eclipse.webbrowser.WebBrowserEditorInput;
-import org.eclipse.webbrowser.internal.Trace;
-/**
- * Action to open the Web broswer on a resource.
- */
-public class OpenWithBrowserActionDelegate implements IActionDelegate {
-	private IResource resource;
-
-	/**
-	 * OpenBrowserAction constructor comment.
-	 */
-	public OpenWithBrowserActionDelegate() {
-		super();
-	}
-
-	/**
-	 * Performs this action.
-	 * - * This method is called when the delegating action has been triggered. - * Implement this method to do the actual work. - *
- * - * @param action the action proxy that handles the presentation portion of the - * action - */ - public void run(IAction action) { - URL url = null; - try { - url = new URL("file://" + resource.getLocation()); - WebBrowser.openURL(new WebBrowserEditorInput(url, WebBrowserEditorInput.SHOW_ALL | WebBrowserEditorInput.FORCE_NEW_PAGE)); - } catch (Exception e) { - Trace.trace(Trace.SEVERE, "Error opening browser on file", e); - } - } - - /** - * Notifies this action delegate that the selection in the workbench has changed. - *- * Implementers can use this opportunity to change the availability of the - * action or to modify other presentation properties. - *
- * - * @param action the action proxy that handles presentation portion of the action - * @param selection the current selection in the workbench - */ - public void selectionChanged(IAction action, ISelection sel) { - if (sel.isEmpty() || !(sel instanceof IStructuredSelection)) { - action.setEnabled(false); - return; - } - - IStructuredSelection select = (IStructuredSelection) sel; - Iterator iterator = select.iterator(); - Object selection = iterator.next(); - if (iterator.hasNext()) { // more than one selection (should never happen) - action.setEnabled(false); - return; - } - - if (!(selection instanceof IResource)) { - action.setEnabled(false); - return; - } - - resource = (IResource) selection; - action.setEnabled(true); - } -} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/OrganizeFavoritesDialog.java b/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/OrganizeFavoritesDialog.java deleted file mode 100644 index a19146c..0000000 --- a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/OrganizeFavoritesDialog.java +++ /dev/null @@ -1,211 +0,0 @@ -package org.eclipse.webbrowser.internal; -/********************************************************************** - * Copyright (c) 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - **********************************************************************/ -import java.util.List; - -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.viewers.*; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Item; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Table; -import org.eclipse.swt.widgets.TableColumn; -/** - * Dialog to manage the favorites list. - */ -public class OrganizeFavoritesDialog extends Dialog { - protected List favorites = WebBrowserPreference.getInternalWebBrowserFavorites(); - - public class FavoriteContentProvider implements IStructuredContentProvider { - public FavoriteContentProvider() { - super(); - } - - public void dispose() { } - - public Object[] getElements(Object inputElement) { - return favorites.toArray(); - } - - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {} - } - - public class FavoriteLabelProvider implements ITableLabelProvider { - public FavoriteLabelProvider() { - super(); - } - - public void addListener(ILabelProviderListener listener) { } - - public void dispose() { } - - public Image getColumnImage(Object element, int columnIndex) { - if (columnIndex == 0) - return ImageResource.getImage(ImageResource.IMG_FAVORITE); - return null; - } - - public String getColumnText(Object element, int columnIndex) { - Favorite favorite = (Favorite) element; - if (columnIndex == 0) - return favorite.getName(); - else - return favorite.getURL(); - } - - public boolean isLabelProperty(Object element, String property) { - return false; - } - - public void removeListener(ILabelProviderListener listener) { } - } - - /** - * ManageFavoritesDialog constructor comment. - * @param parentShell org.eclipse.swt.widgets.Shell - * @ - */ - public OrganizeFavoritesDialog(Shell parentShell) { - super(parentShell); - - setBlockOnOpen(true); - } - - /** - * - */ - protected void configureShell(Shell newShell) { - super.configureShell(newShell); - newShell.setText(WebBrowserUIPlugin.getResource("%dialogOrganizeFavoritesTitle")); - } - - /** - * - */ - protected Control createDialogArea(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - GridLayout layout = new GridLayout(); - layout.numColumns = 2; - layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN); - layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN); - layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING); - layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING); - composite.setLayout(layout); - composite.setLayoutData(new GridData(GridData.FILL_BOTH)); - composite.setFont(parent.getFont()); - //WorkbenchHelp.setHelp(composite, ContextIds.TERMINATE_SERVER_DIALOG); - - Label label = new Label(composite, SWT.NONE); - label.setText(WebBrowserUIPlugin.getResource("%dialogOrganizeFavoritesMessage")); - GridData data = new GridData(); - data.horizontalSpan = 2; - label.setLayoutData(data); - - final Table table = new Table(composite, SWT.BORDER | SWT.FULL_SELECTION | SWT.V_SCROLL | SWT.H_SCROLL | SWT.SINGLE); - data = new GridData(GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL); - data.widthHint = 300; - data.heightHint = 150; - table.setLayoutData(data); - table.setLinesVisible(true); - - TableLayout tableLayout = new TableLayout(); - table.setLayout(tableLayout); - table.setHeaderVisible(true); - - tableLayout.addColumnData(new ColumnWeightData(5, 50, true)); - TableColumn col = new TableColumn(table, SWT.NONE); - col.setText(WebBrowserUIPlugin.getResource("%dialogOrganizeFavoritesName")); - - tableLayout.addColumnData(new ColumnWeightData(6, 60, true)); - col = new TableColumn(table, SWT.NONE); - col.setText(WebBrowserUIPlugin.getResource("%dialogOrganizeFavoritesURL")); - table.setLayout(tableLayout); - - final TableViewer tableViewer = new TableViewer(table); - tableViewer.setContentProvider(new FavoriteContentProvider()); - tableViewer.setLabelProvider(new FavoriteLabelProvider()); - tableViewer.setInput("root"); - tableViewer.setColumnProperties(new String[] {"name", "url"}); - - tableViewer.setCellEditors(new CellEditor[] {new TextCellEditor(table), new TextCellEditor(table)}); - - ICellModifier cellModifier = new ICellModifier() { - public Object getValue(Object element, String property) { - Favorite f = (Favorite) element; - if ("name".equals(property)) - return f.getName(); - else - return f.getURL(); - } - - public boolean canModify(Object element, String property) { - return true; - } - - public void modify(Object element, String property, Object value) { - if (element instanceof Item) - element = ((Item) element).getData(); - - try { - Favorite f = (Favorite) element; - String s = (String) value; - if ("name".equals(property)) - f.setName(s); - else - f.setURL(s); - tableViewer.refresh(f); - } catch (Exception ex) { - ex.printStackTrace(); - } - } - }; - tableViewer.setCellModifier(cellModifier); - - final Button remove = SWTUtil.createButton(composite, WebBrowserUIPlugin.getResource("%remove")); - remove.setEnabled(false); - - tableViewer.addSelectionChangedListener(new ISelectionChangedListener() { - public void selectionChanged(SelectionChangedEvent event) { - remove.setEnabled(!event.getSelection().isEmpty()); - } - }); - - remove.addSelectionListener(new SelectionAdapter() { - public void widgetSelected(SelectionEvent e) { - int index = table.getSelectionIndex(); - if (index < 0 || index >= favorites.size()) - return; - - tableViewer.remove(favorites.get(index)); - favorites.remove(index); - } - }); - - Dialog.applyDialogFont(composite); - - return composite; - } - - protected void okPressed() { - WebBrowserPreference.setInternalWebBrowserFavorites(favorites); - super.okPressed(); - } -} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/SWTUtil.java b/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/SWTUtil.java deleted file mode 100644 index e40b947..0000000 --- a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/SWTUtil.java +++ /dev/null @@ -1,77 +0,0 @@ -/********************************************************************** - * Copyright (c) 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - **********************************************************************/ -package org.eclipse.webbrowser.internal; - -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.FontMetrics; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -/** - * SWT Utility class. - */ -public class SWTUtil { - private static FontMetrics fontMetrics; - - protected static void initializeDialogUnits(Control testControl) { - // Compute and store a font metric - GC gc = new GC(testControl); - gc.setFont(JFaceResources.getDialogFont()); - fontMetrics = gc.getFontMetrics(); - gc.dispose(); - } - - /** - * Returns a width hint for a button control. - */ - protected static int getButtonWidthHint(Button button) { - int widthHint = Dialog.convertHorizontalDLUsToPixels(fontMetrics, IDialogConstants.BUTTON_WIDTH); - return Math.max(widthHint, button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x); - } - - public static Button createButton(Composite comp, String label) { - Button b = new Button(comp, SWT.PUSH); - b.setText(label); - if (fontMetrics == null) - initializeDialogUnits(comp); - GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_BEGINNING); - data.widthHint = getButtonWidthHint(b); - data.heightHint = Dialog.convertVerticalDLUsToPixels(fontMetrics, IDialogConstants.BUTTON_HEIGHT); - b.setLayoutData(data); - return b; - } - - public static Button createCheckbox(Composite comp, String txt, boolean isSelected){ - Button button = new Button(comp, SWT.CHECK); - button.setText(txt); - GridLayout layout = new GridLayout(); - comp.setLayout(layout); - GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_BEGINNING); - data.horizontalIndent = 10; - button.setLayoutData(data); - button.setSelection(isSelected); - return button; - } - - public static Label createLabel(Composite comp, String txt) { - Label label = new Label(comp, SWT.NONE); - label.setText(txt); - label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING)); - return label; - } -} diff --git a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/StandardURLMap.java b/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/StandardURLMap.java deleted file mode 100644 index 400da31..0000000 --- a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/StandardURLMap.java +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Copyright (c) 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - */ -package org.eclipse.webbrowser.internal; - -import org.eclipse.webbrowser.IURLMap; -/** - * Standard URL mappings. - */ -public class StandardURLMap implements IURLMap { - /** - * @see IURLMap#getMappedURL(String) - */ - public String getMappedURL(String url) { - if (url.equalsIgnoreCase("eclipse")) - return "http://www.eclipse.org"; - else if (url.equalsIgnoreCase("webtools")) - return "http://www.eclipse.org/webtools/"; - else - return null; - } -} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/SwitchBrowserWorkbenchAction.java b/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/SwitchBrowserWorkbenchAction.java deleted file mode 100644 index 7fa5d87..0000000 --- a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/SwitchBrowserWorkbenchAction.java +++ /dev/null @@ -1,137 +0,0 @@ -/** - * Copyright (c) 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - */ -package org.eclipse.webbrowser.internal; - -import java.util.Iterator; - -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.action.ActionContributionItem; -import org.eclipse.jface.action.IAction; -import org.eclipse.swt.events.MenuAdapter; -import org.eclipse.swt.events.MenuEvent; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.widgets.MenuItem; -import org.eclipse.ui.*; -import org.eclipse.webbrowser.IWebBrowser; -/** - * Action to open the Web broswer. - */ -public class SwitchBrowserWorkbenchAction implements IWorkbenchWindowPulldownDelegate2 { - /** - * The menu created by this action - */ - private Menu fMenu; - - protected boolean recreateMenu = false; - - /** - * SwitchBrowserWorkbenchAction constructor comment. - */ - public SwitchBrowserWorkbenchAction() { - super(); - } - - public void dispose() { - setMenu(null); - } - - /** - * Sets this action's drop-down menu, disposing the previous menu. - * - * @param menu the new menu - */ - private void setMenu(Menu menu) { - if (fMenu != null) { - fMenu.dispose(); - } - fMenu = menu; - } - - public void init(IWorkbenchWindow window) { } - - /** - * Adds the given action to the specified menu with an accelerator specified - * by the given number. - * - * @param menu the menu to add the action to - * @param action the action to add - * @param accelerator the number that should appear as an accelerator - */ - protected void addToMenu(Menu menu, IAction action, int accelerator) { - StringBuffer label= new StringBuffer(); - if (accelerator >= 0 && accelerator < 10) { - //add the numerical accelerator - label.append('&'); - label.append(accelerator); - label.append(' '); - } - label.append(action.getText()); - action.setText(label.toString()); - ActionContributionItem item= new ActionContributionItem(action); - item.fill(menu, -1); - } - - /** - * Fills the drop-down menu with favorites and launch history, - * launch shortcuts, and an action to open the launch configuration dialog. - * - * @param menu the menu to fill - */ - protected void fillMenu(Menu menu) { - IWebBrowser current = BrowserManager.getInstance().getCurrentWebBrowser(); - Iterator iterator = BrowserManager.getInstance().getWebBrowsers().iterator(); - int i = 0; - while (iterator.hasNext()) { - IWebBrowser browser = (IWebBrowser) iterator.next(); - addToMenu(menu, new SwitchDefaultBrowserAction(browser, browser.equals(current)), i++); - } - } - - /** - * Creates the menu for the action - */ - private void initMenu() { - // Add listener to repopulate the menu each time - // it is shown because of dynamic history list - fMenu.addMenuListener(new MenuAdapter() { - public void menuShown(MenuEvent e) { - //if (recreateMenu) { - Menu m = (Menu) e.widget; - MenuItem[] items = m.getItems(); - for (int i = 0; i < items.length; i++) { - items[i].dispose(); - } - fillMenu(m); - recreateMenu = false; - //} - } - }); - } - - public void selectionChanged(IAction action, ISelection selection) { } - - public void run(IAction action) { } - - public Menu getMenu(Menu parent) { - setMenu(new Menu(parent)); - //fillMenu(fMenu); - initMenu(); - return fMenu; - } - - public Menu getMenu(Control parent) { - setMenu(new Menu(parent)); - //fillMenu(fMenu); - initMenu(); - return fMenu; - } -} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/SwitchDefaultBrowserAction.java b/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/SwitchDefaultBrowserAction.java deleted file mode 100644 index 4271d3f..0000000 --- a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/SwitchDefaultBrowserAction.java +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Copyright (c) 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - */ -package org.eclipse.webbrowser.internal; - -import org.eclipse.jface.action.Action; -import org.eclipse.webbrowser.IInternalWebBrowser; -import org.eclipse.webbrowser.IWebBrowser; -/** - * Action to open the Web browser. - */ -public class SwitchDefaultBrowserAction extends Action { - protected IWebBrowser webbrowser; - - /** - * SwitchDefaultBrowserAction constructor comment. - */ - public SwitchDefaultBrowserAction(IWebBrowser webbrowser, boolean current) { - super(); - - this.webbrowser = webbrowser; - setText(webbrowser.getName()); - if (webbrowser instanceof IInternalWebBrowser) - setImageDescriptor(ImageResource.getImageDescriptor(ImageResource.IMG_INTERNAL_BROWSER)); - else - setImageDescriptor(ImageResource.getImageDescriptor(ImageResource.IMG_EXTERNAL_BROWSER)); - - if (current) - setChecked(true); - } - - /** - * Implementation of method defined onIAction.
-	 */
-	public void run() {
-		BrowserManager.getInstance().setCurrentWebBrowser(webbrowser);
-	}
-}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/TextAction.java b/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/TextAction.java
deleted file mode 100644
index 430910b..0000000
--- a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/TextAction.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/**
- * Copyright (c) 2003 IBM Corporation and others.
- * All rights reserved.   This program and the accompanying materials
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- *
- * Contributors:
- *    IBM - Initial API and implementation
- */
-package org.eclipse.webbrowser.internal;
-
-import org.eclipse.swt.SWTError;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.dnd.*;
-import org.eclipse.webbrowser.internal.WebBrowser;
-import org.eclipse.jface.action.Action;
-/**
- * Text actions (cut, copy, paste) for the Web browser.
- */
-public class TextAction extends Action {
-	protected WebBrowser browser;
-	protected byte type;
-
-	public static final byte CUT = 0;
-	public static final byte COPY = 1;
-	public static final byte PASTE = 2;
-	
-	/**
-	 * TextAction constructor comment.
-	 */
-	protected TextAction(WebBrowser browser, byte type) {
-		super(type + "!");
-		this.browser = browser;
-		this.type = type;
-	}
-	
-	/**
-	 * Copies the selected text to the clipboard.  The text will be put in the 
-	 * clipboard in plain text format.
-	 * - * - * @exception SWTException
- * - * @exception SWTException
- * - * @exception SWTException
IAction.
-	 */
-	public void run() {
-		if (browser == null || browser.combo == null)
-			return;
-		if (type == CUT)
-			cut();
-		else if (type == COPY)
-			copy();
-		else if (type == PASTE)
-			paste();
-	}
-	
-	/**
-	 * 
-	 */
-	protected void update() {	}
-}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/Trace.java b/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/Trace.java
deleted file mode 100644
index 5c448bd..0000000
--- a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/Trace.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * Copyright (c) 2003 IBM Corporation and others.
- * All rights reserved.   This program and the accompanying materials
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- *
- * Contributors:
- *    IBM - Initial API and implementation
- */
-package org.eclipse.webbrowser.internal;
-/**
- * Helper class to route trace output.
- */
-public class Trace {
-	public static int CONFIG = 0;
-	public static int WARNING = 2;
-	public static int SEVERE = 3;
-	public static int FINER = 4;
-	public static int FINEST = 5;
-
-	/**
-	 * Trace constructor comment.
-	 */
-	private Trace() {
-		super();
-	}
-
-	/**
-	 * Trace the given text.
-	 *
-	 * @param s java.lang.String
-	 */
-	public static void trace(int level, String s) {
-		Trace.trace(level, s, null);
-	}
-
-	/**
-	 * Trace the given message and exception.
-	 *
-	 * @param s java.lang.String
-	 * @param t java.lang.Throwable
-	 */
-	public static void trace(int level, String s, Throwable t) {
-		if (!WebBrowserUIPlugin.getInstance().isDebugging())
-			return;
-
-		System.out.println(s);
-		if (t != null)
-			t.printStackTrace();
-	}
-}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/WebBrowser.java b/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/WebBrowser.java
deleted file mode 100644
index 254913c..0000000
--- a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/WebBrowser.java
+++ /dev/null
@@ -1,579 +0,0 @@
-/**
- * Copyright (c) 2003 IBM Corporation and others.
- * All rights reserved.   This program and the accompanying materials
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- *
- * Contributors:
- *    IBM - Initial API and implementation
- */
-
-//TODO 1. Handle the sizing of a popup running in shelled out secondary window.
-//TODO 2. Support printing: waiting on eclipse bug 47937/44823.
-
-package org.eclipse.webbrowser.internal;
-
-import java.util.*;
-import org.eclipse.webbrowser.IURLMap;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.*;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.dnd.Clipboard;
-import org.eclipse.swt.events.*;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.ui.help.WorkbenchHelp;
-import org.eclipse.swt.browser.*;
-
-public class WebBrowser extends Composite {
-	protected Composite toolbarComp;
-	protected Composite statusComp;
-	protected Combo combo;
-	protected Clipboard clipboard;
-	protected boolean showToolbar;
-	protected ToolItem back;
-	protected ToolItem forward;
-	protected ToolItem stop;
-	protected ToolItem favorites;
-	protected ToolItem refresh;
-	protected BusyIndicator busy;
-	protected boolean showStatusbar;
-	protected ProgressBar progress;
-	protected Label status;
-	private static int MAX_HISTORY = 50;
-	protected static java.util.List history;
-	protected Browser browser; 
-	protected Shell shell;
-	protected WebBrowserEditor editor;
-	protected String title;
-	
-	public WebBrowser(Composite parent, final boolean showToolbar, final boolean showStatusbar) {
-		super(parent, SWT.NONE);
-
-		this.showToolbar = showToolbar;
-		this.showStatusbar = showStatusbar;	
-
-		GridLayout layout = new GridLayout();
-		layout.marginHeight = 3;
-		layout.marginWidth = 3;
-		layout.horizontalSpacing = 3;
-		layout.verticalSpacing = 3;
-		layout.numColumns = 1;
-		setLayout(layout);
-		setLayoutData(new GridData(GridData.FILL_BOTH));
-		clipboard = new Clipboard(parent.getDisplay());
-		WorkbenchHelp.setHelp(this, ContextIds.WEB_BROWSER);
-		
-		if (showToolbar) {
-			toolbarComp = new Composite(this, SWT.NONE);
-			GridLayout outerLayout = new GridLayout();
-			outerLayout.numColumns = 2;
-			outerLayout.marginWidth = 0;
-			outerLayout.marginHeight = 0;
-			toolbarComp.setLayout(outerLayout);
-			toolbarComp.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL));
-			
-			// create the top line, with a combo box for history and a "go" button
-			Composite top = new Composite(toolbarComp, SWT.NONE);
-			GridLayout topLayout = new GridLayout();
-			topLayout.numColumns = 2;
-			topLayout.marginWidth = 0;
-			topLayout.marginHeight = 0;
-			top.setLayout(topLayout);
-			top.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_CENTER | GridData.FILL_HORIZONTAL));
-			
-			combo = new Combo(top, SWT.DROP_DOWN);
-			
-			updateHistory();
-			
-			combo.addSelectionListener(new SelectionAdapter() {
-				public void widgetSelected(SelectionEvent we) {
-					try {
-						if (combo.getSelectionIndex() != -1)
-							setURL(combo.getItem(combo.getSelectionIndex()));
-					} catch (Exception e) { }
-				}
-			});
-			combo.addListener(SWT.DefaultSelection, new Listener() {
-				public void handleEvent(Event e) {
-					setURL(combo.getText());
-				}
-			});
-			combo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-			WorkbenchHelp.setHelp(combo, ContextIds.WEB_BROWSER_URL);
-			
-			ToolBar toolbar = new ToolBar(top, SWT.FLAT);
-			fillToolBar(toolbar);
-			
-			new ToolItem(toolbar, SWT.SEPARATOR);
-			
-			busy = new BusyIndicator(toolbarComp, SWT.NONE);
-			busy.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
-		}
-
-		// create a new SWT Web browser widget, checking once again to make sure we can use it in this environment
-		if (WebBrowserUtil.canUseInternalWebBrowser() & WebBrowserUtil.isInternalBrowserOperational())
-			this.browser = new Browser(this, SWT.NONE);
-		else {
-			WebBrowserUtil.openError(WebBrowserUIPlugin.getResource("%errorCouldNotLaunchInternalWebBrowser"));
-			return;
-		}
-		
-		if (showToolbar) {
-			back.setEnabled(browser.isBackEnabled());
-			forward.setEnabled(browser.isForwardEnabled());
-		}
-
-		WorkbenchHelp.setHelp(browser, ContextIds.WEB_BROWSER_WEB);
-		GridData data = new GridData();
-		data.horizontalAlignment = GridData.FILL;
-		data.verticalAlignment = GridData.FILL;
-		data.horizontalSpan = 3;
-		data.grabExcessHorizontalSpace = true;
-		data.grabExcessVerticalSpace = true;
-		browser.setLayoutData(data);
-		
-		if (showStatusbar)
-			createStatusArea(this);
-		
-		addBrowserListeners();
-	}
-	/**
-	 *
-	 */
-	protected void addBrowserListeners() {	
-		if (showStatusbar) {
-			// respond to Browser StatusTextEvents events by updating the status Text label
-			browser.addStatusTextListener(new StatusTextListener() {
-				public void changed(StatusTextEvent event) {
-					status.setText(event.text);	
-				}
-			});
-		}
-
-		/** Add listener for new window creation so that we can instead of opening a separate
-		 *  new window in which the session is lost, we can instead open a new window in a new
-		 *  shell within the browser area thereby maintaining the session.
-		 */
-		browser.addOpenWindowListener(new OpenWindowListener() {
-			public void open(WindowEvent event) {
-				Shell shell2 = new Shell(getDisplay());
-				shell2.setLayout(new FillLayout());
-				shell2.setText(WebBrowserUIPlugin.getResource("%viewWebBrowserTitle"));
-				shell2.setImage(getShell().getImage());
-				WebBrowser browser2 = new WebBrowser(shell2, showToolbar, showStatusbar);
-				browser2.shell = shell2;
-				event.browser = browser2.browser;
-				shell2.open();
-			}
-		});
-		
-		browser.addCloseWindowListener(new CloseWindowListener(){
-			public void close(WindowEvent event) {
-				// if shell is not null, it must be a secondary popup window, else its an editor window
-				if (shell != null)
-					shell.dispose();
-				else
-					editor.closeEditor();
-			}
-		});
-		
-		browser.addProgressListener(new ProgressListener() {
-			public void changed(ProgressEvent event) {
-				if (event.total == 0)
-					return;
-				
-				boolean done = (event.current == event.total);
-
-				int percentProgress = event.current * 100 / event.total;
-				if (showStatusbar) {
-					if (done)
-						progress.setSelection(0);
-					else
-						progress.setSelection(percentProgress);
-				}
-				
-				if (showToolbar) {
-					if (!busy.isBusy() && (percentProgress > 0 && percentProgress < 100)) {
-						busy.setBusy(true);
-					}
-					// Once the progress hits 100 percent, done, set busy to false
-					else if (busy.isBusy() && done) {
-						busy.setBusy(false);
-					}
-				}
-			}
-			
-			public void completed(ProgressEvent event) {
-				if (showStatusbar)
-					progress.setSelection(0);
-				if (showToolbar) {
-					busy.setBusy(false);
-					back.setEnabled(browser.isBackEnabled());
-					forward.setEnabled(browser.isForwardEnabled());
-				}
-			}
-		});
-
-		if (showToolbar) {
-			browser.addLocationListener(new LocationListener() {
-				public void changed(LocationEvent event) {
-					if (!event.top)
-						return;
-					if (!isHome()) {
-						combo.setText(event.location);
-						addToHistory(event.location);
-						updateHistory();
-					} else
-						combo.setText("");
-				}
-				
-				public void changing(LocationEvent event) { }
-			});
-		}
-		
-		browser.addTitleListener(new TitleListener() {
-			public void changed(TitleEvent event) {
-				title = event.title;
-			}
-		});
-	}
-
-	/**
-	 * Return the underlying browser control.
-	 * 
-	 * @return org.eclipse.swt.browser.Browser
-	 */
-	public Browser getBrowser() {
-		return browser;
-	}
-
-	/**
-	 * 
-	 */
-	protected void forward() {
-		browser.forward();
-	}
-
-	/**
-	 * 
-	 */
-	protected void back() {
-		browser.back();
-	}
-	
-	/**
-	 * 
-	 */
-	protected void stop() {
-		browser.stop();
-	}
-
-	/**
-	 * 
-	 */
-	protected void navigate(String url) {
-		Trace.trace(Trace.FINER, "Navigate: " + url);
-		if (url != null && url.equals(getURL())) {
-			refresh();
-			return;
-		}
-		browser.setUrl(url);
-	}
-
-	/**
-	 * Refresh the currently viewed page.
-	 */
-	public void refresh() {
-		browser.refresh();
-	}
-
-	protected void setURL(String url, boolean browse) {
-		Trace.trace(Trace.FINEST, "setURL: " + url + " " + browse);
-		if (url == null) {
-			home();
-			return;
-		}
-		
-		if (url.endsWith(WebBrowserPreference.getHomePageURL().substring(9)))
-			return;
-
-		// check URL maps
-		Iterator iterator = WebBrowserUtil.getURLMaps().iterator();
-		String newURL = null;
-		while (iterator.hasNext() && newURL == null) {
-			try {
-				IURLMap map = (IURLMap) iterator.next();
-				newURL = map.getMappedURL(url);
-			} catch (Exception e) { }
-		}
-		if (newURL != null)
-			url = newURL;
-		
-		if (browse)
-			navigate(url);
-		
-		addToHistory(url);
-		updateHistory();
-	}
-
-	protected void addToHistory(String url) {
-		if (history == null)
-			history = WebBrowserPreference.getInternalWebBrowserHistory();
-		int found = -1;
-		int size = history.size();
-		for (int i = 0; i < size; i++){
-			String s = (String) history.get(i);
-			if (s.equals(url)) {
-				found = i;
-				break;
-			}
-		}
-		
-		if (found == -1) {
-			if (size >= MAX_HISTORY)
-				history.remove(size - 1);
-			history.add(0, url);
-			WebBrowserPreference.setInternalWebBrowserHistory(history);
-		} else if (found != 0) {
-			history.remove(found);
-			history.add(0, url);
-			WebBrowserPreference.setInternalWebBrowserHistory(history);
-		}
-	}
-
-	public void setURL(String url) {
-		setURL(url, true);
-	}
-	
-	/**
-	 * Creates the Web browser status area.
-	 */
-	private void createStatusArea(Composite parent) {
-		Composite composite = new Composite(parent, SWT.NONE);
-		GridLayout layout = new GridLayout();
-		layout.numColumns = 2;
-		layout.marginHeight = 0;
-		layout.marginWidth = 0;
-		layout.horizontalSpacing = 4;
-		layout.verticalSpacing = 0;
-		composite.setLayout(layout);
-		composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-	
-		// Add a label for displaying status messages as they are received from the control
-		status = new Label(composite, SWT.SINGLE | SWT.READ_ONLY);
-		GridData gridData = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL);
-		gridData.horizontalIndent = 2;
-		status.setLayoutData(gridData);
-	
-		// Add a progress bar to display downloading progress information
-		progress = new ProgressBar(composite, SWT.BORDER);
-		gridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_FILL);
-		gridData.widthHint = 100;
-		gridData.heightHint = 10;
-		progress.setLayoutData(gridData);
-	}
-	
-	/**
-	 *
-	 */
-	public void dispose() {
-		super.dispose();
-
-		showStatusbar = false;
-		showToolbar = false;
-	
-		if (busy != null)
-			busy.dispose();
-		busy = null;
-
-		browser = null;
-	}
-	
-	/**
-	 * Populate the toolbar.
-	 * @param toolbar org.eclipse.swt.widgets.ToolBar
-	 */
-	private void fillToolBar(final ToolBar toolbar) {
-		ToolItem go = new ToolItem(toolbar, SWT.NONE);
-		go.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_GO));
-		go.setHotImage(ImageResource.getImage(ImageResource.IMG_CLCL_NAV_GO));
-		go.setDisabledImage(ImageResource.getImage(ImageResource.IMG_DLCL_NAV_GO));
-		go.setToolTipText(WebBrowserUIPlugin.getResource("%actionWebBrowserGo"));
-		go.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent event) {
-				setURL(combo.getText());
-			}
-		});
-	
-		new ToolItem(toolbar, SWT.SEPARATOR);
-		
-		favorites = new ToolItem(toolbar, SWT.DROP_DOWN);
-		favorites.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_FAVORITES));
-		favorites.setHotImage(ImageResource.getImage(ImageResource.IMG_CLCL_NAV_FAVORITES));
-		favorites.setDisabledImage(ImageResource.getImage(ImageResource.IMG_DLCL_NAV_FAVORITES));
-		favorites.setToolTipText(WebBrowserUIPlugin.getResource("%actionWebBrowserFavorites"));
-		
-		favorites.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent event) {
-				if (event.detail == SWT.ARROW) {
-					Rectangle r = favorites.getBounds();
-					showFavorites(toolbar, toolbar.toDisplay(r.x, r.y + r.height));
-				} else
-					addFavorite();
-			}
-		});
-	
-		// create back and forward actions
-		back = new ToolItem(toolbar, SWT.NONE);
-		back.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_BACKWARD));
-		back.setHotImage(ImageResource.getImage(ImageResource.IMG_CLCL_NAV_BACKWARD));
-		back.setDisabledImage(ImageResource.getImage(ImageResource.IMG_DLCL_NAV_BACKWARD));
-		back.setToolTipText(WebBrowserUIPlugin.getResource("%actionWebBrowserBack"));
-		back.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent event) {
-				back();
-			}
-		});
-
-		forward = new ToolItem(toolbar, SWT.NONE);
-		forward.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_FORWARD));
-		forward.setHotImage(ImageResource.getImage(ImageResource.IMG_CLCL_NAV_FORWARD));
-		forward.setDisabledImage(ImageResource.getImage(ImageResource.IMG_DLCL_NAV_FORWARD));
-		forward.setToolTipText(WebBrowserUIPlugin.getResource("%actionWebBrowserForward"));
-		forward.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent event) {
-				forward();
-			}
-		});
-		
-		// create refresh, stop, and print actions
-		stop = new ToolItem(toolbar, SWT.NONE);
-		stop.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_STOP));
-		stop.setHotImage(ImageResource.getImage(ImageResource.IMG_CLCL_NAV_STOP));
-		stop.setDisabledImage(ImageResource.getImage(ImageResource.IMG_DLCL_NAV_STOP));
-		stop.setToolTipText(WebBrowserUIPlugin.getResource("%actionWebBrowserStop"));
-		stop.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent event) {
-				stop();
-			}
-		});
-	
-		refresh = new ToolItem(toolbar, SWT.NONE);
-		refresh.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_REFRESH));
-		refresh.setHotImage(ImageResource.getImage(ImageResource.IMG_CLCL_NAV_REFRESH));
-		refresh.setDisabledImage(ImageResource.getImage(ImageResource.IMG_DLCL_NAV_REFRESH));
-		refresh.setToolTipText(WebBrowserUIPlugin.getResource("%actionWebBrowserRefresh"));
-		refresh.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent event) {
-				refresh();
-			}
-		});
-	}
-	
-	protected void addFavorite() {
-		java.util.List list = WebBrowserPreference.getInternalWebBrowserFavorites();
-		Favorite f = new Favorite(title, browser.getUrl());
-		if (!list.contains(f)) {
-			list.add(f);
-			WebBrowserPreference.setInternalWebBrowserFavorites(list);
-		}
-	}
-	
-	protected void showFavorites(Control parent, Point p) {
-		Menu perspectiveBarMenu = null;
-		if (perspectiveBarMenu == null) {
-			Menu menu = new Menu(parent);
-			
-			// locked favorites
-			Iterator iterator = WebBrowserUtil.getLockedFavorites().iterator();
-			if (iterator.hasNext()) {
-				while (iterator.hasNext()) {
-					final Favorite f = (Favorite) iterator.next();
-					MenuItem item = new MenuItem(menu, SWT.NONE);
-					item.setText(f.getName());
-					item.setImage(ImageResource.getImage(ImageResource.IMG_FAVORITE));
-					item.addSelectionListener(new SelectionAdapter() {
-						public void widgetSelected(SelectionEvent event) {
-							setURL(f.getURL());
-						}
-					});
-				}
-				
-				new MenuItem(menu, SWT.SEPARATOR);
-			}
-			
-			iterator = WebBrowserPreference.getInternalWebBrowserFavorites().iterator();
-			if (!iterator.hasNext()) {
-				MenuItem item = new MenuItem(menu, SWT.NONE);
-				item.setText(WebBrowserUIPlugin.getResource("%actionWebBrowserNoFavorites"));
-			}
-			while (iterator.hasNext()) {
-				final Favorite f = (Favorite) iterator.next();
-				MenuItem item = new MenuItem(menu, SWT.NONE);
-				item.setText(f.getName());
-				item.setImage(ImageResource.getImage(ImageResource.IMG_FAVORITE));
-				item.addSelectionListener(new SelectionAdapter() {
-					public void widgetSelected(SelectionEvent event) {
-						setURL(f.getURL());
-					}
-				});
-			}
-			
-			new MenuItem(menu, SWT.SEPARATOR);
-	
-			MenuItem item = new MenuItem(menu, SWT.NONE);
-			item.setText(WebBrowserUIPlugin.getResource("%actionWebBrowserOrganizeFavorites"));
-			item.addSelectionListener(new SelectionAdapter() {
-				public void widgetSelected(SelectionEvent event) {
-					OrganizeFavoritesDialog dialog = new OrganizeFavoritesDialog(shell);
-					dialog.open();
-				}
-			});
-			
-			perspectiveBarMenu = menu;
-		}
-		
-		if (perspectiveBarMenu != null) {
-			perspectiveBarMenu.setLocation(p.x, p.y);
-			perspectiveBarMenu.setVisible(true);
-		}
-	}
-
-	public void home() {
-	   navigate(WebBrowserPreference.getHomePageURL());
-	}
-
-	/**
-	 * Returns true if the homepage is currently being displayed.
-	 * @return boolean
-	 */
-	protected boolean isHome() {
-		return getURL() != null && getURL().endsWith(WebBrowserPreference.getHomePageURL().substring(9));
-	}
-
-	protected String getURL() {
-		return browser.getUrl();
-	}
-
-	/**
-	 * Update the history list to the global copy.
-	 */
-	protected void updateHistory() {
-		if (combo == null)
-			return;
-	
-		String temp = combo.getText();
-		if (history == null)
-			history = WebBrowserPreference.getInternalWebBrowserHistory();
-	
-		String[] historyList = new String[history.size()];
-		history.toArray(historyList);
-		combo.setItems(historyList);
-	
-		combo.setText(temp);
-	}
-}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/WebBrowserEditor.java b/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/WebBrowserEditor.java
deleted file mode 100644
index 1015a2d..0000000
--- a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/WebBrowserEditor.java
+++ /dev/null
@@ -1,371 +0,0 @@
-/**
- * Copyright (c) 2003 IBM Corporation and others.
- * All rights reserved.   This program and the accompanying materials
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- *
- * Contributors:
- *    IBM - Initial API and implementation
- */
-package org.eclipse.webbrowser.internal;
-
-import java.net.URL;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.core.runtime.*;
-import org.eclipse.core.resources.*;
-import org.eclipse.ui.*;
-import org.eclipse.ui.part.*;
-import org.eclipse.webbrowser.*;
-/**
- * An integrated Web browser, defined as an editor to make
- * better use of the desktop.
- */
-public class WebBrowserEditor extends EditorPart {
-	public static final String WEB_BROWSER_EDITOR_ID = "org.eclipse.webbrowser";
-	protected WebBrowser webBrowser;
-	protected String initialURL;
-	protected Image image;
-
-	protected TextAction cutAction;
-	protected TextAction copyAction;
-	protected TextAction pasteAction;
-	
-	protected IResourceChangeListener resourceListener;
-
-	/**
-	 * WebBrowserEditor constructor comment.
-	 */
-	public WebBrowserEditor() {
-		super();
-	}
-	
-	/**
-	 * Creates the SWT controls for this workbench part.
-	 * - * Clients should not call this method (the workbench calls this method at - * appropriate times). - *
- *- * For implementors this is a multi-step process: - *
IActionService.IActionService.ISelectionService
-	 *     (optional). 
-	 * Subclasses must override this method to implement the open-save-close lifecycle
-	 * for an editor.  For greater details, see IEditorPart
-	 * 
-	 * Subclasses must override this method to implement the open-save-close lifecycle
-	 * for an editor.  For greater details, see IEditorPart
-	 * 
-	 * Subclasses may override.  For greater details, see IEditorPart
-	 * 
-	 * Subclasses of EditorPart must implement this method.  Within
-	 * the implementation subclasses should verify that the input type is acceptable
-	 * and then save the site and input.  Here is sample code:
-	 * 
-	 *		if (!(input instanceof IFileEditorInput))
-	 *			throw new PartInitException("Invalid Input: Must be IFileEditorInput");
-	 *		setSite(site);
-	 *		setInput(editorInput);
-	 * 
-	 */
-	public void init(IEditorSite site, IEditorInput input) {
-		Trace.trace(Trace.FINEST, "Opening browser: " + input);
-		if (input instanceof IFileEditorInput) {
-			IFileEditorInput fei = (IFileEditorInput) input;
-			IFile file = fei.getFile();
-			URL url = null;
-			try {
-				if (file != null && file.exists())
-					url = file.getLocation().toFile().toURL();
-			} catch (Exception e) {
-				Trace.trace(Trace.SEVERE, "Error getting URL to file");
-			}
-			addResourceListener(file);
-			input = new WebBrowserEditorInput(url, WebBrowserEditorInput.SHOW_ALL | WebBrowserEditorInput.SAVE_URL);
-		}
-		if (input instanceof IWebBrowserEditorInput) {
-			IWebBrowserEditorInput wbei = (IWebBrowserEditorInput) input;
-			initialURL = null;
-			if (wbei.getURL() != null)
-				initialURL = wbei.getURL().toExternalForm();
-			if (webBrowser != null) {
-				webBrowser.setURL(initialURL);
-				site.getWorkbenchWindow().getActivePage().bringToTop(this);
-			}
-	
-			setPartName(wbei.getName());
-			setTitleToolTip(wbei.getToolTipText());
-
-			Image oldImage = image;
-			ImageDescriptor id = wbei.getImageDescriptor();
-			image = id.createImage();
-
-			setTitleImage(image);
-			if (oldImage != null && !oldImage.isDisposed())
-				oldImage.dispose();
-		}
-		setSite(site);
-		setInput(input);
-	}
-	
-	/* (non-Javadoc)
-	 * Returns whether the contents of this editor have changed since the last save
-	 * operation.
-	 * 
-	 * Subclasses must override this method to implement the open-save-close lifecycle
-	 * for an editor.  For greater details, see IEditorPart
-	 * 
-	 * Subclasses must override this method to implement the open-save-close lifecycle
-	 * for an editor.  For greater details, see IEditorPart
-	 * 
- * Clients should not call this method (the workbench calls this method at - * appropriate times). - *
- */ - public void setFocus() { - if (webBrowser != null) { - if (webBrowser.combo != null) - webBrowser.combo.setFocus(); - else - webBrowser.browser.setFocus(); - webBrowser.updateHistory(); - } - } - - /** - * Update the actions. - */ - protected void updateActions() { - if (cutAction != null) - cutAction.update(); - if (copyAction != null) - copyAction.update(); - if (pasteAction != null) - pasteAction.update(); - } - - /** - * Close the editor correctly. - */ - protected void closeEditor() { - Display.getDefault().asyncExec(new Runnable() { - public void run() { - getEditorSite().getPage().closeEditor(WebBrowserEditor.this, false); - } - }); - } - - /** - * Adds a resource change listener to see if the file is deleted. - */ - protected void addResourceListener(final IResource resource) { - if (resource == null) - return; - - resourceListener = new IResourceChangeListener() { - public void resourceChanged(IResourceChangeEvent event) { - try { - event.getDelta().accept(new IResourceDeltaVisitor() { - public boolean visit(IResourceDelta delta) { - IResource res = delta.getResource(); - - if (res == null || !res.equals(resource)) - return true; - - if (delta.getKind() != IResourceDelta.REMOVED) - return true; - - Display.getDefault().asyncExec(new Runnable() { - public void run() { - String title = WebBrowserUIPlugin.getResource("%dialogResourceDeletedTitle"); - String message = WebBrowserUIPlugin.getResource("%dialogResourceDeletedMessage", resource.getName()); - String[] labels = new String[] {WebBrowserUIPlugin.getResource("%dialogResourceDeletedIgnore"), IDialogConstants.CLOSE_LABEL}; - MessageDialog dialog = new MessageDialog(getEditorSite().getShell(), title, null, message, MessageDialog.INFORMATION, labels, 0); - - if (dialog.open() != 0) - closeEditor(); - } - }); - return false; - } - }); - } catch (Exception e) { - Trace.trace(Trace.SEVERE, "Error listening for resource deletion", e); - } - } - }; - ResourcesPlugin.getWorkspace().addResourceChangeListener(resourceListener); - } -} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/WebBrowserEditorActionBarContributor.java b/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/WebBrowserEditorActionBarContributor.java deleted file mode 100644 index fd36893..0000000 --- a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/WebBrowserEditorActionBarContributor.java +++ /dev/null @@ -1,62 +0,0 @@ -/** - * Copyright (c) 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - */ -package org.eclipse.webbrowser.internal; - -import org.eclipse.ui.*; -import org.eclipse.ui.actions.ActionFactory; -/** - * ActionBarContributor for the Web browser. - * Just adds cut, copy, paste actions. - */ -public class WebBrowserEditorActionBarContributor implements IEditorActionBarContributor { - protected IActionBars actionBars; - - /** - * WebBrowserEditorActionBarContributor constructor comment. - */ - public WebBrowserEditorActionBarContributor() { - super(); - } - - /** - * Initializes this contributor, which is expected to add contributions as - * required to the given action bars and global action handlers. - * - * @param bars the action bars - */ - public void init(IActionBars bars, IWorkbenchPage page) { - this.actionBars = bars; - } - - /** - * Sets the active editor for the contributor. - * Implementors should disconnect from the old editor, connect to the - * new editor, and update the actions to reflect the new editor. - * - * @param targetEditor the new editor target - */ - public void setActiveEditor(IEditorPart targetEditor) { - if (targetEditor instanceof WebBrowserEditor) { - WebBrowserEditor editor = (WebBrowserEditor) targetEditor; - - actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(), editor.getCopyAction()); - actionBars.setGlobalActionHandler(ActionFactory.CUT.getId(), editor.getCutAction()); - actionBars.setGlobalActionHandler(ActionFactory.PASTE.getId(), editor.getPasteAction()); - - editor.updateActions(); - } - } - - /** - * Disposes this contributor. - */ - public void dispose() { } -} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/WebBrowserPreference.java b/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/WebBrowserPreference.java deleted file mode 100644 index ea39724..0000000 --- a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/WebBrowserPreference.java +++ /dev/null @@ -1,164 +0,0 @@ -/** - * Copyright (c) 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - */ -package org.eclipse.webbrowser.internal; - -import java.util.*; -import java.net.URL; -import org.eclipse.core.runtime.Platform; -import org.eclipse.jface.preference.IPreferenceStore; -/** - * Preferences for the Web browser. - */ -public class WebBrowserPreference { - protected static final String PREF_BROWSER_HISTORY = "webBrowserHistory"; - protected static final String PREF_INTERNAL_WEB_BROWSER_HISTORY = "internalWebBrowserHistory"; - protected static final String PREF_INTERNAL_WEB_BROWSER_FAVORITES = "internalWebBrowserFavorites"; - protected static final String PREF_INTERNAL_WEB_BROWSER_OLD_FAVORITES = "internalWebBrowserOldFavorites"; - protected static final String URL_PARAMETER = "%URL%"; - - /** - * WebBrowserPreference constructor comment. - */ - private WebBrowserPreference() { - super(); - } - - /** - * Returns the URL to the homepage. - * - * @return java.lang.String - */ - public static String getHomePageURL() { - try { - // get the default home page - URL url = WebBrowserUIPlugin.getInstance().getBundle().getEntry("home/home.html"); - url = Platform.resolve(url); - return url.toExternalForm(); - } catch (Exception e) { - return "http://www.eclipse.org"; - } - } - - /** - * Returns the preference store. - * - * @return org.eclipse.jface.preference.IPreferenceStore - */ - protected static IPreferenceStore getPreferenceStore() { - return WebBrowserUIPlugin.getInstance().getPreferenceStore(); - } - - /** - * Returns the Web browser history list. - * - * @return java.util.List - */ - public static List getInternalWebBrowserHistory() { - String temp = getPreferenceStore().getString(PREF_INTERNAL_WEB_BROWSER_HISTORY); - StringTokenizer st = new StringTokenizer(temp, "|*|"); - List l = new ArrayList(); - while (st.hasMoreTokens()) { - String s = st.nextToken(); - l.add(s); - } - return l; - } - - /** - * Returns the Web browser favorites. - * - * @return java.util.List - */ - public static List getInternalWebBrowserFavorites() { - String temp = getPreferenceStore().getString(PREF_INTERNAL_WEB_BROWSER_FAVORITES); - StringTokenizer st = new StringTokenizer(temp, "|*|"); - List l = new ArrayList(); - while (st.hasMoreTokens()) { - l.add(new Favorite(st.nextToken(), st.nextToken())); - } - return l; - } - - /** - * Initialize the default preferences. - */ - public static void initializeDefaultPreferences() { - IPreferenceStore store = getPreferenceStore(); - - String temp = store.getString(PREF_INTERNAL_WEB_BROWSER_OLD_FAVORITES); - StringTokenizer st = new StringTokenizer(temp, "|*|"); - List def = new ArrayList(); - while (st.hasMoreTokens()) { - def.add(new Favorite(st.nextToken(), st.nextToken())); - } - - List list = getInternalWebBrowserFavorites(); - Iterator iterator = WebBrowserUtil.getUnlockedFavorites().iterator(); - while (iterator.hasNext()) { - Favorite f = (Favorite) iterator.next(); - if (!def.contains(f)) - list.add(f); - } - setInternalWebBrowserFavorites(list); - - StringBuffer sb = new StringBuffer(); - iterator = WebBrowserUtil.getUnlockedFavorites().iterator(); - while (iterator.hasNext()) { - Favorite f = (Favorite) iterator.next(); - sb.append(f.getName()); - sb.append("|*|"); - sb.append(f.getURL()); - sb.append("|*|"); - } - store.setValue(PREF_INTERNAL_WEB_BROWSER_OLD_FAVORITES, sb.toString()); - WebBrowserUIPlugin.getInstance().savePluginPreferences(); - } - - /** - * Sets the Web browser history. - * - * @param java.util.List - */ - public static void setInternalWebBrowserHistory(List list) { - StringBuffer sb = new StringBuffer(); - if (list != null) { - Iterator iterator = list.iterator(); - while (iterator.hasNext()) { - String s = (String) iterator.next(); - sb.append(s); - sb.append("|*|"); - } - } - getPreferenceStore().setValue(PREF_INTERNAL_WEB_BROWSER_HISTORY, sb.toString()); - WebBrowserUIPlugin.getInstance().savePluginPreferences(); - } - - /** - * Sets the Web browser favorites. - * - * @param java.util.List - */ - public static void setInternalWebBrowserFavorites(List list) { - StringBuffer sb = new StringBuffer(); - if (list != null) { - Iterator iterator = list.iterator(); - while (iterator.hasNext()) { - Favorite f = (Favorite) iterator.next(); - sb.append(f.getName()); - sb.append("|*|"); - sb.append(f.getURL()); - sb.append("|*|"); - } - } - getPreferenceStore().setValue(PREF_INTERNAL_WEB_BROWSER_FAVORITES, sb.toString()); - WebBrowserUIPlugin.getInstance().savePluginPreferences(); - } -} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/WebBrowserPreferencePage.java b/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/WebBrowserPreferencePage.java deleted file mode 100644 index 8fa36fd..0000000 --- a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/WebBrowserPreferencePage.java +++ /dev/null @@ -1,84 +0,0 @@ -/** - * Copyright (c) 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - */ -package org.eclipse.webbrowser.internal; - -import org.eclipse.swt.*; -import org.eclipse.swt.layout.*; -import org.eclipse.swt.widgets.*; -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.preference.PreferencePage; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchPreferencePage; -import org.eclipse.ui.help.WorkbenchHelp; -/** - * The preference page that holds webbrowser preferences. - */ -public class WebBrowserPreferencePage extends PreferencePage implements IWorkbenchPreferencePage { - /** - * WebBrowserPreferencePage constructor comment. - */ - public WebBrowserPreferencePage() { - super(); - noDefaultAndApplyButton(); - } - - /** - * Create the preference options. - * - * @param parent org.eclipse.swt.widgets.Composite - * @return org.eclipse.swt.widgets.Control - */ - protected Control createContents(Composite parent) { - initializeDialogUnits(parent); - - Composite composite = new Composite(parent, SWT.NONE); - GridLayout layout = new GridLayout(); - layout.numColumns = 1; - layout.horizontalSpacing = convertHorizontalDLUsToPixels(4); - layout.verticalSpacing = convertVerticalDLUsToPixels(4); - layout.marginWidth = 0; - layout.marginHeight = 0; - composite.setLayout(layout); - GridData data = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL); - composite.setLayoutData(data); - WorkbenchHelp.setHelp(composite, ContextIds.PREF_BROWSER); - - Label label = new Label(composite, SWT.WRAP); - label.setText(WebBrowserUIPlugin.getResource("%preferenceWebBrowserDescription")); - data = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); - label.setLayoutData(data); - - BrowserTableComposite browserComposite = new BrowserTableComposite(composite, SWT.NONE); - - data = new GridData(GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL); - browserComposite.setLayoutData(data); - - Dialog.applyDialogFont(composite); - - return composite; - } - - /** - * Initializes this preference page using the passed desktop. - * - * @param desktop the current desktop - */ - public void init(IWorkbench workbench) { } - - /** - * - */ - public void setVisible(boolean visible) { - super.setVisible(visible); - if (visible) - setTitle(WebBrowserUIPlugin.getResource("%preferenceWebBrowserTitleLong")); - } -} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/WebBrowserUIPlugin.java b/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/WebBrowserUIPlugin.java deleted file mode 100644 index ac4ded9..0000000 --- a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/WebBrowserUIPlugin.java +++ /dev/null @@ -1,90 +0,0 @@ -/** - * Copyright (c) 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - */ -package org.eclipse.webbrowser.internal; - -import java.text.MessageFormat; - -import org.eclipse.core.runtime.*; -import org.eclipse.ui.plugin.AbstractUIPlugin; -import org.osgi.framework.BundleContext; -/** - * The main web browser plugin class. - */ -public class WebBrowserUIPlugin extends AbstractUIPlugin { - // Web browser plugin id - public static final String PLUGIN_ID = "net.sourceforge.phpeclipse.webbrowser"; - - // singleton instance of this class - private static WebBrowserUIPlugin singleton; - - /** - * Create the WebBrowserUIPlugin - */ - public WebBrowserUIPlugin() { - super(); - singleton = this; - } - - /** - * Returns the singleton instance of this plugin. - * - * @return org.eclipse.webbrowser.WebBrowserPlugin - */ - public static WebBrowserUIPlugin getInstance() { - return singleton; - } - - /** - * Returns the translated String found with the given key. - * - * @param key java.lang.String - * @return java.lang.String - */ - public static String getResource(String key) { - try { - return Platform.getResourceString(getInstance().getBundle(), key); - } catch (Exception e) { - return key; - } - } - - /** - * Returns the translated String found with the given key, - * and formatted with the given arguments using java.text.MessageFormat. - * - * @param key java.lang.String - * @param arg java.lang.String - * @return java.lang.String - */ - public static String getResource(String key, String arg) { - try { - String text = getResource(key); - return MessageFormat.format(text, new String[] { arg }); - } catch (Exception e) { - return key; - } - } - - public void start(BundleContext context) throws Exception { - super.start(context); - WebBrowserPreference.initializeDefaultPreferences(); - } - - /** - * Shuts down this plug-in and saves all plug-in state. - * - * @exception Exception - */ - public void stop(BundleContext context) throws Exception { - super.stop(context); - BrowserManager.getInstance().dispose(); - } -} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/WebBrowserUtil.java b/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/WebBrowserUtil.java deleted file mode 100644 index 266de1c..0000000 --- a/net.sourceforge.phpeclipse.webbrowser/src/org/eclipse/webbrowser/internal/WebBrowserUtil.java +++ /dev/null @@ -1,376 +0,0 @@ -/** - * Copyright (c) 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - */ -package org.eclipse.webbrowser.internal; - -import java.io.File; -import java.io.InputStreamReader; -import java.io.Reader; -import java.net.URL; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.eclipse.ui.IMemento; -import org.eclipse.ui.XMLMemento; -import org.eclipse.webbrowser.IExternalWebBrowser; -import org.eclipse.webbrowser.IExternalWebBrowserWorkingCopy; -import org.eclipse.webbrowser.IURLMap; -import org.eclipse.webbrowser.IWebBrowser; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.core.runtime.*; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.swt.SWT; -import org.eclipse.swt.browser.Browser; -/** - * Utility class for the Web browser tooling. - */ -public class WebBrowserUtil { - private static List urlMaps; - private static List lockedFavorites; - private static List unlockedFavorites; - private static final String BROWSER_PACKAGE_NAME = "org.eclipse.swt.browser.Browser"; - public static Boolean isInternalBrowserOperational; - - private static List defaultBrowsers2; - - static class DefaultBrowser { - String name; - String params; - String executable; - String[] locations; - - public DefaultBrowser(String name, String executable, String params, String[] locations) { - if (name == null) - name = "true if the problem is an error, false
+	 *         otherwise
+	 */
+	boolean isError();
+
+	/**
+	 * Returns whether the problem is a warning.
+	 * 
+	 * @return true if the problem is a warning, false
+	 *         otherwise
+	 */
+	boolean isWarning();
+
+}
diff --git a/net.sourceforge.phpeclipse.xml.core/src/net/sourceforge/phpeclipse/xml/core/parser/IProblemCollector.java b/net.sourceforge.phpeclipse.xml.core/src/net/sourceforge/phpeclipse/xml/core/parser/IProblemCollector.java
new file mode 100644
index 0000000..72b88fa
--- /dev/null
+++ b/net.sourceforge.phpeclipse.xml.core/src/net/sourceforge/phpeclipse/xml/core/parser/IProblemCollector.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2004 Christopher Lenz and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Christopher Lenz - initial API
+ * 
+ * $Id: IProblemCollector.java,v 1.1 2004-09-02 18:26:55 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.core.parser;
+
+/**
+ * 
+ */
+public interface IProblemCollector {
+
+	/**
+	 * Notification of an error or warning.
+	 * 
+	 * @param problem the discovered problem
+	 */
+	void addProblem(IProblem problem);
+
+}
diff --git a/net.sourceforge.phpeclipse.xml.core/src/net/sourceforge/phpeclipse/xml/core/parser/IProblemReporter.java b/net.sourceforge.phpeclipse.xml.core/src/net/sourceforge/phpeclipse/xml/core/parser/IProblemReporter.java
new file mode 100644
index 0000000..6d74ec8
--- /dev/null
+++ b/net.sourceforge.phpeclipse.xml.core/src/net/sourceforge/phpeclipse/xml/core/parser/IProblemReporter.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2004 Christopher Lenz and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Christopher Lenz - initial API
+ * 
+ * $Id: IProblemReporter.java,v 1.1 2004-09-02 18:26:55 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.core.parser;
+
+/**
+ * Basic interface for classes that report errors to a problem collector.
+ */
+public interface IProblemReporter {
+
+	/**
+	 * Sets the problem collector that should be used by the reporter.
+	 * 
+	 * @param problemCollector the problem collector to use
+	 */
+	void setProblemCollector(IProblemCollector problemCollector);
+
+}
diff --git a/net.sourceforge.phpeclipse.xml.core/src/net/sourceforge/phpeclipse/xml/core/parser/IXMLParser.java b/net.sourceforge.phpeclipse.xml.core/src/net/sourceforge/phpeclipse/xml/core/parser/IXMLParser.java
new file mode 100644
index 0000000..c48a1d3
--- /dev/null
+++ b/net.sourceforge.phpeclipse.xml.core/src/net/sourceforge/phpeclipse/xml/core/parser/IXMLParser.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2004 Christopher Lenz and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Christopher Lenz - initial API
+ * 
+ * $Id: IXMLParser.java,v 1.1 2004-09-02 18:26:55 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.core.parser;
+
+import net.sourceforge.phpeclipse.xml.core.model.IXMLDocument;
+
+import org.eclipse.jface.text.IDocument;
+
+/**
+ * Interface for classes that implement parsing of XML files.
+ */
+public interface IXMLParser extends IProblemReporter {
+
+	IXMLDocument parse();
+
+	void setSource(IDocument source);
+
+	void setSystemId(String systemId);
+}
-- 
1.7.1