*** empty log message ***
diff --git a/org.eclipse.help.ui/.classpath b/org.eclipse.help.ui/.classpath
new file mode 100644
index 0000000..7a59d3b
--- /dev/null
+++ b/org.eclipse.help.ui/.classpath
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+    <classpathentry kind="src" path="Eclipse Help UI"/>
+    <classpathentry kind="src" path="Eclipse Help UI Motif"/>
+    <classpathentry kind="src" path="Eclipse Help UI Win32"/>
+    <classpathentry kind="src" path="\org.eclipse.help"/>
+    <classpathentry kind="lib" path="C:\eclipse\jre\lib\rt.jar"/>
+    <classpathentry kind="lib" path="C:\eclipse\plugins\org.eclipse.core.runtime\runtime.jar"/>
+    <classpathentry kind="lib" path="C:\eclipse\plugins\org.eclipse.ui\workbench.jar"/>
+    <classpathentry kind="lib" path="C:\eclipse\plugins\org.apache.xerces\xerces.jar"/>
+    <classpathentry kind="lib" path="C:\eclipse\plugins\org.eclipse.core.resources\resources.jar"/>
+    <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.eclipse.help.ui/.cvsignore b/org.eclipse.help.ui/.cvsignore
new file mode 100644
index 0000000..c5e82d7
--- /dev/null
+++ b/org.eclipse.help.ui/.cvsignore
@@ -0,0 +1 @@
+bin
\ No newline at end of file
diff --git a/org.eclipse.help.ui/.vcm_meta b/org.eclipse.help.ui/.vcm_meta
new file mode 100644
index 0000000..7655f8d
--- /dev/null
+++ b/org.eclipse.help.ui/.vcm_meta
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<project-description>

+	<comment></comment>

+	<nature id="org.eclipse.jdt.core.javanature"/>

+	<builder name="org.eclipse.jdt.core.javabuilder">

+	</builder>

+</project-description>

diff --git a/org.eclipse.help.ui/Eclipse Help UI Motif/org/eclipse/help/internal/ui/motif/BrowserFactory.java b/org.eclipse.help.ui/Eclipse Help UI Motif/org/eclipse/help/internal/ui/motif/BrowserFactory.java
new file mode 100644
index 0000000..cc8c2cc
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI Motif/org/eclipse/help/internal/ui/motif/BrowserFactory.java
@@ -0,0 +1,28 @@
+package org.eclipse.help.internal.ui.motif;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+

+import org.eclipse.swt.widgets.Composite;

+import org.eclipse.help.internal.ui.*;

+

+/**

+ * BrowserFactory

+ */

+public class BrowserFactory implements IBrowserFactory {

+	/**

+	 * BrowserFactory constructor.

+	 */

+	public BrowserFactory() {

+		super();

+	}

+	/**

+	 * Creates a browser control instance

+	 */

+	public IBrowser createBrowser(Composite parent) {

+		return new WebBrowser(parent);

+	}

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI Motif/org/eclipse/help/internal/ui/motif/WebBrowser.java b/org.eclipse.help.ui/Eclipse Help UI Motif/org/eclipse/help/internal/ui/motif/WebBrowser.java
new file mode 100644
index 0000000..f30a0fa
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI Motif/org/eclipse/help/internal/ui/motif/WebBrowser.java
@@ -0,0 +1,127 @@
+package org.eclipse.help.internal.ui.motif;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+

+import java.io.IOException;

+import org.eclipse.swt.widgets.*;

+import org.eclipse.swt.*;

+import org.eclipse.swt.layout.GridData;

+import org.eclipse.jface.action.*;

+import org.eclipse.help.internal.ui.*;

+import org.eclipse.help.internal.HelpSystem;

+import org.eclipse.help.internal.ui.util.StreamConsumer;

+import org.eclipse.help.internal.contributions.Topic;

+

+/**

+ * Netscape based browser. It opens an external window.

+ */

+class WebBrowser implements IBrowser {

+	Composite controlFrame;

+	private static boolean opened = false;

+	// time when browser will be fully opened

+	private static long browserFullyOpenedAt;

+

+	private static String browserPath;

+

+	class BrowserThread extends Thread {

+		String url;

+

+		public BrowserThread(String urlName) {

+			this.url = urlName;

+		}

+

+		public synchronized void run() {

+			if (!opened) {

+				openBrowser(url);

+			} else {

+				reuseBrowser(url);

+			}

+		}

+

+		public void reuseBrowser(String url) {

+			try {

+				// If browser has been  recently opened,

+				// wait until anticipated time that it fully opens,

+				while (System.currentTimeMillis() < browserFullyOpenedAt)

+					try {

+						Thread.currentThread().sleep(500);

+					} catch (InterruptedException ie) {

+					}

+				Process pr =

+					Runtime.getRuntime().exec(browserPath + " -remote openURL(" + url + ")");

+				(new StreamConsumer(pr.getInputStream())).start();

+				(new StreamConsumer(pr.getErrorStream())).start();

+				pr.waitFor();

+			} catch (InterruptedException e) {

+			} catch (IOException e) {

+			}

+		}

+	}

+

+	/**

+	 */

+	public WebBrowser(Composite parent) {

+		controlFrame = new Composite(parent, SWT.NONE);

+		controlFrame.setLayoutData(

+			new GridData(

+				GridData.GRAB_HORIZONTAL

+					| GridData.GRAB_VERTICAL

+					| GridData.HORIZONTAL_ALIGN_FILL

+					| GridData.VERTICAL_ALIGN_FILL));

+		browserPath = HelpSystem.getBrowserPath();

+		if (browserPath == null || "".equals(browserPath))

+			browserPath = "netscape";

+	}

+	public int back() {

+		return 0;

+	}

+	public int copy() {

+		return 0;

+	}

+	public int forward() {

+		return 0;

+	}

+	public Control getControl() {

+		return controlFrame;

+	}

+	public String getLocationURL() {

+		return null;

+	}

+	public int home() {

+		return 0;

+	}

+	/**

+	 */

+	public int navigate(String url) {

+		new BrowserThread(url).start();

+		return 0;

+	}

+	private static synchronized void openBrowser(String url) {

+		opened = true;

+		browserFullyOpenedAt = System.currentTimeMillis() + 4000;

+		try {

+			Process pr = Runtime.getRuntime()

+				//.exec("netscape -geometry =570x410+270+155 " + url);

+	.exec(browserPath + " " + url);

+			(new StreamConsumer(pr.getInputStream())).start();

+			(new StreamConsumer(pr.getErrorStream())).start();

+			pr.waitFor();

+		} catch (InterruptedException e) {

+		} catch (IOException e) {

+		} finally {

+			opened = false;

+		}

+	}

+	public void print() {

+	}

+	/**

+	 * Print a Topic and all it's children.

+	 */

+	public void printFullTopic(Topic rootTopic) {

+		// This feature is temporarily not supported on Linux.      

+	}

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI Win32/org/eclipse/help/internal/ui/win32/BrowserFactory.java b/org.eclipse.help.ui/Eclipse Help UI Win32/org/eclipse/help/internal/ui/win32/BrowserFactory.java
new file mode 100644
index 0000000..dd7b008
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI Win32/org/eclipse/help/internal/ui/win32/BrowserFactory.java
@@ -0,0 +1,29 @@
+package org.eclipse.help.internal.ui.win32;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+

+import org.eclipse.swt.widgets.Composite;

+import org.eclipse.help.internal.ui.*;

+import org.eclipse.help.internal.ui.util.HelpWorkbenchException;

+

+/**

+ * Browser Factory

+ */

+public class BrowserFactory implements IBrowserFactory {

+	/**

+	 * BrowserFactory constructor.

+	 */

+	public BrowserFactory() {

+		super();

+	}

+	/**

+	 * Creates a browser control instance

+	 */

+	public IBrowser createBrowser(Composite parent) throws HelpWorkbenchException {

+		return new WebBrowser(parent);

+	}

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI Win32/org/eclipse/help/internal/ui/win32/HelpControlSite.java b/org.eclipse.help.ui/Eclipse Help UI Win32/org/eclipse/help/internal/ui/win32/HelpControlSite.java
new file mode 100644
index 0000000..5c40af7
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI Win32/org/eclipse/help/internal/ui/win32/HelpControlSite.java
@@ -0,0 +1,84 @@
+package org.eclipse.help.internal.ui.win32;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+

+import org.eclipse.swt.widgets.*;

+import org.eclipse.swt.ole.win32.*;

+import org.eclipse.help.internal.ui.util.WorkbenchResources;

+

+/**

+ * Needed for the OLE implementation

+ */

+public class HelpControlSite extends OleControlSite {

+	protected boolean beenBuilt = false;

+	protected boolean startedDownload = false;

+	// Web Browser

+	private String webHome;

+	private ProgressBar webProgress;

+	private Label webStatus;

+

+	/**

+	 * HelpControlSite constructor

+	 */

+	public HelpControlSite(Composite parent, int style, String progId) {

+		super(parent, style, progId);

+

+		addEventListener(WebBrowser.DownloadBegin, new OleListener() {

+			public void handleEvent(OleEvent event) {

+				startedDownload = true;

+			}

+		});

+

+		addEventListener(WebBrowser.DownloadComplete, new OleListener() {

+			public void handleEvent(OleEvent event) {

+				startedDownload = false;

+			}

+		});

+

+		addEventListener(WebBrowser.BeforeNavigate2, new OleListener() {

+			public void handleEvent(OleEvent event) {

+				Variant urlVar = event.arguments[1];

+			}

+		});

+

+		// Respond to ProgressChange events by updating the Progress bar

+		addEventListener(WebBrowser.ProgressChange, new OleListener() {

+			public void handleEvent(OleEvent event) {

+				if (!startedDownload) {

+					return;

+				}

+

+				Variant progress = event.arguments[0];

+				Variant maxProgress = event.arguments[1];

+

+				if (progress == null || maxProgress == null || progress.getInt() == -1) {

+					return;

+				}

+

+				if (progress.getInt() != 0) {

+				}

+			}

+		});

+

+		addEventListener(WebBrowser.StatusTextChange, new OleListener() {

+			public void handleEvent(OleEvent event) {

+				Variant newText = event.arguments[0];

+				String msg = newText.getString();

+				if (msg != null) {

+					if ((msg.indexOf("http://") != -1)

+						|| (msg.indexOf("javascript:") != -1)

+						|| (msg.indexOf(WorkbenchResources.getString("Connecting_to")) != -1)

+						|| (msg.indexOf(WorkbenchResources.getString("Web_site_found")) != -1)

+						|| (msg.indexOf(WorkbenchResources.getString("Finding_site")) != -1)

+						|| (msg.indexOf(WorkbenchResources.getString("Javascript_called")) != -1))

+						return;

+				}

+			}

+		});

+

+	}

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI Win32/org/eclipse/help/internal/ui/win32/NestedPrintDelegate.java b/org.eclipse.help.ui/Eclipse Help UI Win32/org/eclipse/help/internal/ui/win32/NestedPrintDelegate.java
new file mode 100644
index 0000000..3744335
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI Win32/org/eclipse/help/internal/ui/win32/NestedPrintDelegate.java
@@ -0,0 +1,302 @@
+package org.eclipse.help.internal.ui.win32;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+

+import java.util.*;

+import org.eclipse.swt.ole.win32.*;

+import org.eclipse.swt.*;

+import org.eclipse.swt.widgets.*;

+import org.eclipse.jface.operation.IRunnableWithProgress;

+import org.eclipse.jface.dialogs.ProgressMonitorDialog;

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.help.internal.HelpSystem;

+import org.eclipse.help.internal.contributions.*;

+import org.eclipse.help.internal.util.*;

+import org.eclipse.help.internal.ui.util.*;

+import org.eclipse.help.internal.server.*;

+import java.net.URLEncoder;

+

+/**

+ * This class handles the Nested Printing action from the Topics Viewer

+ */

+public class NestedPrintDelegate {

+

+	private WebBrowser webBrowser = null;

+	// The automation object and Control for printing

+	protected OleAutomation backOleObject;

+	protected HelpControlSite backControlSite;

+

+	private PrintMonitorDialog progressDialog = null;

+

+	private IProgressMonitor pm = null;

+	private boolean printingComplete = false;

+	private IRunnableWithProgress printOperation = null;

+	private Topic[] topicList = null;

+	private Topic rootTopic = null;

+	private int topicsPrinted = -1;

+

+	/**

+	 * Operation class for a NestedPrint task issued by a WebBrowser

+	 */

+	public class NestedPrintOperation implements IRunnableWithProgress {

+

+		public synchronized void run(IProgressMonitor monitor) {

+			try {

+				Display.getDefault().asyncExec(new Runnable() {

+					public void run() {

+						try {

+							pm = progressDialog.getProgressMonitor();

+							if (pm == null)

+								return;

+							// add one to topicList size to compensate for TableOfContents

+							pm.beginTask(

+								WorkbenchResources.getString("Printing_Topic_Tree"),

+								topicList.length + 1);

+

+							// create the special url to kick off creating the TableOfContents.

+							// This url is handeled as a special case in the TempURL class. 

+							String tableOfContentsURL = createTableOfContentsURL();

+							if (tableOfContentsURL != null)

+								webBrowser.navigate(backOleObject, tableOfContentsURL);

+							if (pm.isCanceled())

+								return;

+

+						} catch (Exception e) {

+							e.printStackTrace();

+						}

+					}

+				});

+

+				while (!printingComplete) {

+					try {

+						Thread.currentThread().sleep(200);

+					} catch (InterruptedException e) {

+						e.printStackTrace();

+					}

+				}

+

+			} catch (Exception e) {

+				// log and die

+			}

+		}

+	}

+

+	/**

+	 * ProgressMonitorDialog sublass for a NestedPrint task.

+	 */

+	public class PrintMonitorDialog extends ProgressMonitorDialog {

+		public PrintMonitorDialog(Shell parent) {

+			super(parent);

+			// override parent behavior to make dialog modeless.

+			setShellStyle(SWT.BORDER | SWT.TITLE | SWT.MODELESS);

+			setBlockOnOpen(false);

+		}

+	}

+

+	/**

+	 * Ole Listener class for a NestedPrint task

+	 */

+	public class PrintOleListener implements OleListener, Runnable {

+

+		public synchronized void run() {

+			if (topicList == null)

+				return;

+			if (pm.isCanceled()) {

+				doCleanUp();

+				return;

+			}

+			if (topicsPrinted == -1)

+				// this means that we are printing the TableOfContents

+				pm.subTask(

+					WorkbenchResources.getString("Printing")

+						+ WorkbenchResources.getString("Table_Of_Contents"));

+			else

+				pm.subTask(

+					WorkbenchResources.getString("Printing") + topicList[topicsPrinted].getLabel());

+

+			topicsPrinted++;

+			webBrowser.print(backControlSite, false);

+

+			// add one to compensate for the TableOfContents

+			if (topicsPrinted < topicList.length) {

+				if (Logger.DEBUG)

+					Logger.logDebugMessage(

+						"NestedPrintDelegate",

+						"OLE listener: printing from:  " + Thread.currentThread().toString());

+				printTopic(topicsPrinted);

+				pm.worked(1);

+			} else {

+				doCleanUp();

+				return;

+			}

+		}

+

+		public synchronized void handleEvent(OleEvent event) {

+			try {

+				Display.getCurrent().asyncExec(this);

+			} catch (Exception e) {

+				e.printStackTrace();

+			}

+

+		}

+

+		private void doCleanUp() {

+			// do clean up

+			topicsPrinted = -1;

+			topicList = null;

+			if (Logger.DEBUG)

+				Logger.logDebugMessage(

+					"NestedPrintDelegate",

+					"OLE listener: finishing:  " + Thread.currentThread().toString());

+			if (progressDialog != null)

+				pm.done();

+			progressDialog = null;

+			webBrowser.dispose();

+			printingComplete = true;

+		}

+

+	}

+	public NestedPrintDelegate(

+		WebBrowser aWebBrowser,

+		OleAutomation aOleObject,

+		HelpControlSite aControlSite) {

+		super();

+

+		// The automation object and Control associated with printing

+		backControlSite = aControlSite;

+		backOleObject = aOleObject;

+		webBrowser = aWebBrowser;

+

+		backControlSite.addEventListener(

+			WebBrowser.DocumentComplete,

+			new PrintOleListener());

+

+	}

+	/**

+	 * Retruns the fully qualified URL that identifies a Table of Contents URL.

+	 * Table of Contents for a given Nested print action is generated

+	 * on the fly using the Topic list captured in this class.

+	 * No separate class was created for this URL, but instead it 

+	 * is handled as a "special" url in the TempURL class.

+	 * In this special case, the TempURL class does not read from

+	 * a file in the working directory, but actually uses this class 

+	 * to dynamically create a table of contents. 

+	 */

+	private String createTableOfContentsURL() {

+		// make sure to append the TempURL prefix first. 

+		// Example: http://localhost:80/temp/TableOfContents

+		//              /?topicId=org.eclipse.help.examples.ex1.someTopicId

+		//              &viewId=org.eclipse.help.examples.ex1.someViewId 

+		//              &infosetId=org.eclipse.help.examples.ex1.someInfosetId  

+		StringBuffer url = new StringBuffer();

+		url.append(HelpSystem.getLocalHelpServerURL());

+		url.append("/");

+		url.append(TempURL.getPrefix());

+		url.append("/");

+		url.append(TempURL.TABLE_OF_CONTENTS_PREFIX);

+		url.append("/");

+

+		// add query, which is the infosetId, viewId, and TopicID

+		// add topicId

+		url.append("?topicId=");

+		url.append(URLEncoder.encode(rootTopic.getID()));

+

+		// add viewId

+		url.append("&viewId=");

+		Contribution parent = rootTopic.getParent();

+		boolean foundParent = false;

+		while (!foundParent) {

+			if (parent instanceof InfoView)

+				foundParent = true;

+			else

+				parent = parent.getParent();

+		}

+

+		InfoView view = (InfoView) parent;

+		url.append(URLEncoder.encode(view.getID()));

+

+		// get to Infoset

+		url.append("&infosetId=");

+		parent = parent.getParent();

+		InfoSet infoSet = (InfoSet) parent;

+

+		// add infosetId

+		url.append(URLEncoder.encode(infoSet.getID()));

+

+		return url.toString();

+	}

+	/** 

+	 * creates the fully qualified url name for a given topic

+	 * returns null if no topic is associated with the input object.

+	 */

+	private String createURL(Topic topic) {

+		if (topic == null)

+			return null;

+

+		String url = topic.getHref();

+		if (url == null || url.equals(""))

+			return null; // no content in this topic

+

+		if (url.indexOf("?resultof=") != -1) {

+			Locale locale = Locale.getDefault();

+			url = url.concat("&lang=") + locale.getDefault().toString();

+		} else {

+			Locale locale = Locale.getDefault();

+			url = url.concat("?lang=") + locale.getDefault().toString();

+		}

+		if (url.indexOf("http:") == -1)

+			url = HelpSystem.getLocalHelpServerURL() + url;

+		return url;

+	}

+	/** 

+	 * confirms with the user if Nested Printing is ok with given number of Topics.

+	 */

+	private boolean okToPrint(int numberOfTopics) {

+		String topics = Integer.toString(numberOfTopics);

+		if (numberOfTopics == 0) {

+			String msg = WorkbenchResources.getString("no_Topics_To_Print");

+			Util.displayInfoDialog(msg);

+			return false;

+		} else {

+			String question = WorkbenchResources.getString("ok_To_Print", topics);

+			return Util.displayQuestionDialog(question);

+		}

+	}

+	public void printFullTopic(Topic rootTopic) {

+		if (Logger.DEBUG)

+			Logger.logDebugMessage("NestedPrintDelegate", "printTopicTree ");

+		try {

+

+			this.rootTopic = rootTopic;

+			this.topicList = TableOfContentsGenerator.getTopicList(rootTopic);

+			if ((webBrowser == null) || (topicList == null))

+				return; // should never be here

+

+			if (okToPrint(topicList.length)) {

+

+				printOperation = new NestedPrintOperation();

+

+				progressDialog = new PrintMonitorDialog(Display.getCurrent().getActiveShell());

+				progressDialog.run(true, true, printOperation);

+

+			}

+

+		} catch (Exception e) {

+			Logger.logError(WorkbenchResources.getString("WE006"), e);

+			return;

+		}

+

+	}

+	private void printTopic(int i) {

+		if (Logger.DEBUG)

+			Logger.logDebugMessage("NestedPrintDelegate", "printTopic " + i);

+		String topicURL = createURL(topicList[i]);

+		if (topicURL != null)

+			webBrowser.navigate(backOleObject, topicURL);

+

+	}

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI Win32/org/eclipse/help/internal/ui/win32/WebBrowser.java b/org.eclipse.help.ui/Eclipse Help UI Win32/org/eclipse/help/internal/ui/win32/WebBrowser.java
new file mode 100644
index 0000000..4e073c9
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI Win32/org/eclipse/help/internal/ui/win32/WebBrowser.java
@@ -0,0 +1,467 @@
+package org.eclipse.help.internal.ui.win32;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+

+import org.eclipse.swt.widgets.*;

+import org.eclipse.swt.ole.win32.*;

+import org.eclipse.swt.*;

+import org.eclipse.swt.layout.GridData;

+import org.eclipse.help.internal.util.*;

+import org.eclipse.help.internal.ui.util.*;

+import org.eclipse.help.internal.ui.*;

+import org.eclipse.help.internal.contributions.Topic;

+

+/**

+ * ActiveX based web browser control.

+ */

+public class WebBrowser implements OleListener, IBrowser {

+	// Generated from typelib filename: shdocvw.dll

+

+	// Constants for WebBrowser CommandStateChange

+

+	public static final short CSC_UPDATECOMMANDS = -1;

+	public static final short CSC_NAVIGATEFORWARD = 1;

+	public static final short CSC_NAVIGATEBACK = 2;

+

+	// Web Browser Control Events 

+	public static final int BeforeNavigate = 100;

+	// Fired when a new hyperlink is being navigated to.

+	public static final int NavigateComplete = 101;

+	// Fired when the document being navigated to becomes visible and enters the navigation stack.

+	public static final int StatusTextChange = 102; // Statusbar text changed.

+	public static final int ProgressChange = 108;

+	// Fired when download progress is updated.

+	public static final int DownloadComplete = 104; // Download of page complete.

+	public static final int CommandStateChange = 105;

+	// The enabled state of a command changed

+	public static final int DownloadBegin = 106; // Download of a page started.

+	public static final int NewWindow = 107;

+	// Fired when a new window should be created.

+	public static final int TitleChange = 113; // Document title changed.

+	public static final int FrameBeforeNavigate = 200;

+	// Fired when a new hyperlink is being navigated to in a frame.

+	public static final int FrameNavigateComplete = 201;

+	// Fired when a new hyperlink is being navigated to in a frame.

+	public static final int FrameNewWindow = 204;

+	// Fired when a new window should be created.

+	public static final int Quit = 103; // Fired when application is quiting.

+	public static final int WindowMove = 109; // Fired when window has been moved.

+	public static final int WindowResize = 110;

+	// Fired when window has been sized.

+	public static final int WindowActivate = 111;

+	// Fired when window has been activated.

+	public static final int PropertyChange = 112;

+	// Fired when the PutProperty method has been called.

+	public static final int BeforeNavigate2 = 250;

+	// Fired when a new hyperlink is being navigated to.

+	public static final int NewWindow2 = 251;

+	// Fired when a new window should be created.

+	public static final int DocumentComplete = 259;

+	// Fired when the document being navigated to reaches ReadyState_Complete.

+

+	// Web Browser properties

+	public static final int DISPID_READYSTATE = -525;

+

+	// Web Browser state

+	public static final int READYSTATE_UNINITIALIZED = 0;

+	public static final int READYSTATE_LOADING = 1;

+	public static final int READYSTATE_LOADED = 2;

+	public static final int READYSTATE_INTERACTIVE = 3;

+	public static final int READYSTATE_COMPLETE = 4;

+

+	// Keep track of the whether it is possible to navigate in the forward and backward directions

+	private boolean backwardEnabled;

+	private boolean forwardEnabled;

+

+	// The automation object and Control associated with the main OLE control

+	private OleAutomation oleObject;

+	private HelpControlSite controlSite;

+

+	// The OLE frame (there should only be one)

+	private OleFrame controlFrame;

+

+	private NestedPrintDelegate aPrintDelegate = null;

+

+	/**

+	 */

+	public WebBrowser(Composite parent) throws HelpWorkbenchException {

+

+		// Create the OLE frame. 

+		controlFrame = createOleFrame(parent);

+

+		// Creates the IE5 OLE Control

+		// The constructor also registers all the necessary OLE listeners.

+		// for now, only catch the execption if creating and activating the 

+		// control fails. No checking if the correct version of the OLE control 

+		// is installed.

+		try {

+			controlSite = new HelpControlSite(controlFrame, SWT.NONE, "Shell.Explorer");

+			oleObject = new OleAutomation(controlSite);

+

+			backwardEnabled = false;

+			forwardEnabled = false;

+

+			// Listen for changes to the Command States

+			controlSite.addEventListener(CommandStateChange, this);

+

+			// initialize control

+			controlSite.doVerb(OLE.OLEIVERB_SHOW);

+

+			// create print Delegate (has to be done early, here!).

+			aPrintDelegate = new NestedPrintDelegate(this, oleObject, controlSite);

+

+		} catch (Exception e) {

+			// Display and log error, then delegate to parent UI class. 

+			// The actual translated message goes all the way back to the calling

+			// UI class, for display.

+			String msg = WorkbenchResources.getString("WE001");

+			Util.displayErrorDialog(msg, e);

+			throw new HelpWorkbenchException(msg);

+		}

+

+	}

+	/**

+	 */

+	public int back() {

+

+		if (!backwardEnabled)

+			return OLE.S_FALSE;

+		forwardEnabled = true;

+

+		// dispid=100, type=METHOD, name="GoBack"

+

+		// You can hard code the DISPID if you know it before hand - this is of course the fastest way

+		//int dispIdMember = 100;

+

+		// Alternatively, you can look up the DISPID dynamically

+		int[] rgdispid = oleObject.getIDsOfNames(new String[] { "GoBack" });

+		int dispIdMember = rgdispid[0];

+

+		Variant pVarResult = oleObject.invoke(dispIdMember);

+

+		if (pVarResult == null)

+			return 0;

+		return pVarResult.getInt();

+	}

+	/**

+	 */

+	public int copy() {

+		int result = controlSite.queryStatus(OLE.OLECMDID_COPY);

+		if ((result & OLE.OLECMDF_ENABLED) == OLE.OLECMDF_ENABLED) {

+			result =

+				controlSite.exec(OLE.OLECMDID_COPY, OLE.OLECMDEXECOPT_DODEFAULT, null, null);

+		}

+		return result;

+	}

+	protected OleFrame createOleFrame(Composite parent) {

+		if (controlFrame == null) {

+			controlFrame = new OleFrame(parent, SWT.NONE);

+			controlFrame.setLayoutData(

+				new GridData(

+					GridData.GRAB_HORIZONTAL

+						| GridData.GRAB_VERTICAL

+						| GridData.HORIZONTAL_ALIGN_FILL

+						| GridData.VERTICAL_ALIGN_FILL));

+		}

+		return controlFrame;

+

+	}

+	/**

+	 * clean up

+	 */

+	public void dispose() {

+		//** clean up

+		if (oleObject != null)

+			oleObject.dispose();

+		oleObject = null;

+

+		if (controlSite != null)

+			controlSite.dispose();

+		controlSite = null;

+

+		if (controlFrame != null)

+			controlFrame.dispose();

+		controlFrame = null;

+

+	}

+	/**

+	 */

+	public int forward() {

+		if (!forwardEnabled)

+			return OLE.S_FALSE;

+		backwardEnabled = true;

+		// dispid=101, type=METHOD, name="GoForward"

+

+		// You can hard code the DISPID if you know it before hand - this is of course the fastest way

+		//int dispIdMember = 101;

+

+		// Alternatively, you can look up the DISPID dynamically

+		int[] rgdispid = oleObject.getIDsOfNames(new String[] { "GoForward" });

+		int dispIdMember = rgdispid[0];

+

+		Variant pVarResult = oleObject.invoke(dispIdMember);

+		if (pVarResult == null)

+			return 0;

+		return pVarResult.getInt();

+	}

+	public Control getControl() {

+		return controlFrame;

+	}

+	/**

+	 */

+	public String getLocationName() {

+		// dispid=210, type=PROPGET, name="LocationName"

+

+		// You can hard code the DISPID if you know it before hand - this is of course the fastest way

+		//int dispIdMember = 210;

+

+		// Alternatively, you can look up the DISPID dynamically

+		int[] rgdispid = oleObject.getIDsOfNames(new String[] { "LocationName" });

+		int dispIdMember = rgdispid[0];

+		Variant pVarResult = oleObject.getProperty(dispIdMember);

+		if (pVarResult == null)

+			return null;

+		return pVarResult.getString();

+	}

+	/**

+	 */

+	public String getLocationURL() {

+		// dispid=211, type=PROPGET, name="LocationURL"

+		// You can hard code the DISPID if you know it before hand - this is of course the fastest way

+		//int dispIdMember = 211;

+

+		// Alternatively, you can look up the DISPID dynamically

+		int[] rgdispid = oleObject.getIDsOfNames(new String[] { "LocationURL" });

+		int dispIdMember = rgdispid[0];

+

+		Variant pVarResult = oleObject.getProperty(dispIdMember);

+		if (pVarResult == null)

+			return null;

+		return pVarResult.getString();

+	}

+	protected OleFrame getOleFrame() {

+		return controlFrame;

+

+	}

+	/**

+	 */

+	public int getReadyState() {

+		// dispid=4294966771, type=PROPGET, name="ReadyState"

+		// READYSTATE_UNINITIALIZED = 0;

+		// READYSTATE_LOADING = 1;

+		// READYSTATE_LOADED = 2;

+		// READYSTATE_INTERACTIVE = 3;

+		// READYSTATE_COMPLETE = 4;

+

+		// You can hard code the DISPID if you know it before hand - this is of course the fastest way

+		//int dispIdMember = -525;

+

+		// Alternatively, you can look up the DISPID dynamically

+		int[] rgdispid = oleObject.getIDsOfNames(new String[] { "ReadyState" });

+		int dispIdMember = rgdispid[0];

+

+		Variant pVarResult = oleObject.getProperty(dispIdMember);

+		if (pVarResult == null)

+			return -1;

+		return pVarResult.getInt();

+	}

+	/**

+	 */

+	public void handleEvent(OleEvent event) {

+		switch (event.type) {

+			case (CommandStateChange) :

+				int command = 0;

+				boolean enabled = false;

+

+				Variant varResult = event.arguments[0];

+				if (varResult != null) {

+					command = varResult.getInt();

+				}

+

+				varResult = event.arguments[1];

+				if (varResult != null) {

+					enabled = varResult.getBoolean();

+				}

+

+				if (command == CSC_NAVIGATEBACK)

+					backwardEnabled = enabled;

+				if (command == CSC_NAVIGATEFORWARD)

+					forwardEnabled = enabled;

+

+				return;

+

+			case (DocumentComplete) :

+				varResult = event.arguments[0];

+				return;

+				/*

+					case (BeforeNavigate2) :

+						varResult = eventInfo[1];

+						String url = varResult.getString();

+						if (url.indexOf("test1") != -1)

+						{

+							Stop();

+							Navigate(url);

+							Variant  out = new Variant(true);

+							eventInfo[6] = out;

+						}

+						return;

+				*/

+

+				/*

+					case NewWindow2:

+					   System.out.println("NEw window : " + eventInfo.length);

+					   eventInfo[1] = new Variant(true);

+						return;

+				*/

+		}

+		//throw new OleError(OLE.ERROR_NOT_IMPLEMENTED);

+	}

+	/**

+	 */

+	public int home() {

+		// dispid=102, type=METHOD, name="GoHome"

+

+		// You can hard code the DISPID if you know it before hand - this is of course the fastest way

+		//int dispIdMember = 102;

+

+		// Alternatively, you can look up the DISPID dynamically

+		int[] rgdispid = oleObject.getIDsOfNames(new String[] { "GoHome" });

+		int dispIdMember = rgdispid[0];

+

+		Variant pVarResult = oleObject.invoke(dispIdMember);

+		if (pVarResult == null)

+			return 0;

+		return pVarResult.getInt();

+	}

+	/**

+	 */

+	public int navigate(String url) {

+		return navigate(oleObject, url);

+	}

+	/**

+	 */

+	protected int navigate(OleAutomation aOleAutomation, String url) {

+		if (Logger.DEBUG)

+			Logger.logDebugMessage("WebBrowser", "navigate to: " + url);

+		// dispid=104, type=METHOD, name="Navigate"

+

+		// You can hard code the DISPID if you know it before hand - this is of course the fastest way

+		//int dispIdMember = 104;

+

+		// Alternatively, you can look up the DISPID dynamically

+		// Here we are looking up the id of the argument as well

+		int[] rgdispid =

+			aOleAutomation.getIDsOfNames(new String[] { "Navigate", "URL" });

+		int dispIdMember = rgdispid[0];

+

+		Variant[] rgvarg = new Variant[1];

+		rgvarg[0] = new Variant(url);

+		int[] rgdispidNamedArgs = new int[1];

+		rgdispidNamedArgs[0] = rgdispid[1]; // identifier of argument

+		Variant pVarResult =

+			aOleAutomation.invoke(dispIdMember, rgvarg, rgdispidNamedArgs);

+		if (pVarResult == null)

+			return 0;

+		return pVarResult.getInt();

+

+	}

+	/**

+	 */

+	public void print() {

+		print(controlSite, true);

+	}

+	/**

+	 */

+	protected synchronized void print(

+		HelpControlSite aControlSite,

+		boolean promptuser) {

+		if (Logger.DEBUG)

+			Logger.logDebugMessage("WebBrowser", "print: ");

+

+		int result = aControlSite.queryStatus(OLE.OLECMDID_PRINT);

+		if ((result & OLE.OLECMDF_ENABLED) == OLE.OLECMDF_ENABLED) {

+			if (promptuser)

+				result =

+					aControlSite.exec(OLE.OLECMDID_PRINT, OLE.OLECMDEXECOPT_PROMPTUSER, null, null);

+			else

+				result =

+					aControlSite.exec(

+						OLE.OLECMDID_PRINT,

+						OLE.OLECMDEXECOPT_DONTPROMPTUSER,

+						null,

+						null);

+

+			if (result == OLE.S_OK)

+				return;

+		}

+	}

+	/*

+	 * Print a List of Topics

+	 */

+	public void printFullTopic(Topic rootTopic) {

+		try {

+			// now delegate action

+			if (aPrintDelegate != null) {

+				aPrintDelegate.printFullTopic(rootTopic);

+			}

+

+			if (Logger.DEBUG)

+				Logger.logDebugMessage("WebBrowser", "printTopicTree about to exit");

+

+		} catch (Exception e) {

+

+		}

+

+	}

+	/**

+	 * Refresh the currently viewed page.

+	 */

+	public void refresh() {

+

+		// dispid= 4294966746, type=METHOD, name="Refresh"

+

+		// You can hard code the DISPID if you know it before hand - this is of course the fastest way

+		//int dispIdMember =  4294966746;

+

+		// Alternatively, you can look up the DISPID dynamically

+		int[] rgdispid = oleObject.getIDsOfNames(new String[] { "Refresh" });

+		int dispIdMember = rgdispid[0];

+

+		oleObject.invokeNoReply(dispIdMember);

+	}

+	/**

+	 */

+	public int search() {

+		// dispid=103, type=METHOD, name="GoSearch"

+

+		// You can hard code the DISPID if you know it before hand - this is of course the fastest way

+		//int dispIdMember = 103;

+

+		// Alternatively, you can look up the DISPID dynamically

+		int[] rgdispid = oleObject.getIDsOfNames(new String[] { "GoSearch" });

+		int dispIdMember = rgdispid[0];

+

+		Variant pVarResult = oleObject.invoke(dispIdMember);

+		if (pVarResult == null)

+			return 0;

+		return pVarResult.getInt();

+	}

+	/**

+	 */

+	public void stop() {

+		// dispid=106, type=METHOD, name="Stop"

+

+		// You can hard code the DISPID if you know it before hand - this is of course the fastest way

+		//int dispIdMember = 106;

+

+		// Alternatively, you can look up the DISPID dynamically

+		int[] rgdispid = oleObject.getIDsOfNames(new String[] { "Stop" });

+		int dispIdMember = rgdispid[0];

+

+		Variant pVarResult = oleObject.invoke(dispIdMember);

+	}

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI/HelpWorkbench.properties b/org.eclipse.help.ui/Eclipse Help UI/HelpWorkbench.properties
new file mode 100644
index 0000000..d8cb6a2
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI/HelpWorkbench.properties
@@ -0,0 +1,119 @@
+# =============================================

+# Eclipse Help System Workbench Properties File

+# =============================================

+

+# Part 1. (DO NOT TRANSLATE Part 1)

+# These are the non-translable properties.

+# -----------------------------------------

+resynch_icon = resynch.gif

+home_icon = home.gif

+back_icon= back.gif

+forward_icon = forward.gif

+printer_icon = printer.gif

+copy_icon = copy.gif

+shownav_icon = shownav.gif

+hidenav_icon = hidenav.gif

+actions_icon = actions.gif

+go_icon= go.gif

+topic_icon = topic.gif

+topicfolder_icon = topicfolder.gif

+topicandfolder_icon = topicandfolder.gif

+moreImage = more.gif

+

+

+

+# Part 2. (DO TRANSLATE Part 2)

+# These are the translable properties.

+# -----------------------------------------

+icons = icons

+copy = copy

+Copy_1 = Copy the selection to the clipboard

+home = home

+Home_page = Home page

+back = back

+Previous_page = Previous page

+Show_TOC = Show navigation

+Hide_TOC = Hide navigation

+toggle = toggle

+synchronize = synchronize

+Synchronize_with_TOC = Synchronize with TOC

+forward = forward

+Next_page = Next page

+print = print

+Actions = Actions

+Print_page = Print page

+Connecting_to = Connecting to

+Web_site_found = Web site found

+Finding_site = Finding site

+Javascript_called = Javascript called

+Search = Search

+Search_within_results = Search within results

+Search_headers_only = Search headers only

+Enter_search_string = Enter search string...

+Search_results = Search results

+No_results_found = No results found for your query.

+Results = Results 

+File = File 

+OR = OR

+NOT = NOT

+AND = AND

+Plugin = Plugin

+Advanced = Advanced ...

+Enable_Filtering = Enable filtering by:

+Disable_Filtering = Disable Filtering

+Search_only_within = Search only within

+Context_Help = Context Help

+Related_Topics = Related Topics:

+Show_More_Related = More links ...

+No_more_links_exist = There are no more links.

+RelatedTopics_viewLabel = Related

+Help_Error = Help Error

+Help_Question = Help Question

+Help_Info = Help Information

+Errors_only = Errors only

+Warnings_and_errors = Warnings and errors

+Everything = Everything

+Installation_Options = Documentaton is installed

+Local_install = Locally

+Client_only = Remotely on a Server

+Local_server_config = Internal Help Server Configuration

+Local_server_config_automatic = Automatic

+Local_server_config_manual = Manual

+Server_address = Local Help Server IP Address:

+Server_port = Local Help Server Port:

+Server_path = Remote Server URL:

+Browser_path = Browser path

+Print_Topic_Tree = Print Topic Tree

+Printing_Topic_Tree = Printing topic tree...

+Printing= Printing: \n

+ok_To_Print = You are about to print %1 separate document(s).\nContinue?

+no_Topics_To_Print = There are no topics to print.

+Table_Of_Contents = Table Of Contents

+Advanced_Properties = Advanced

+Logging_Options = Logging Options

+

+# Error Messages 

+# --------------

+WE001 = Could not initialize Help System Viewer.\n\

+	Check to see if the correct version of Internet Explorer is installed on your system.

+WE002 = Could not create Help System Perspective. 

+WE003 = No Help System Perspective available.

+WE004 = Help System View could not be launched.

+WE005 = Errors encountered while launching the Help System

+WE006 = Could not perform Nested print action. 

+

+# Warning Messages 

+# ----------------

+WW001 = It appears that documentation is not installed on this machine. \

+	If it is installed on a remote server, then from Windows -> Preferences, \

+	select the Help page and configure the required parameters.

+WW002 = Context Help not found.

+

+

+

+   

+

+

+	

+

+

diff --git a/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/Actions.java b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/Actions.java
new file mode 100644
index 0000000..0ee2cdf
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/Actions.java
@@ -0,0 +1,235 @@
+package org.eclipse.help.internal.ui;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+

+import java.io.File;

+import org.eclipse.core.runtime.*;

+import org.eclipse.jface.resource.ImageDescriptor;

+import org.eclipse.jface.window.Window;

+import org.eclipse.jface.action.*;

+import org.eclipse.jface.viewers.ISelectionProvider;

+import org.eclipse.jface.viewers.StructuredSelection;

+import org.eclipse.ui.help.WorkbenchHelp;

+import org.eclipse.help.internal.ui.util.WorkbenchResources;

+

+/**

+ * Actions

+ */

+public class Actions {

+	// Images

+	static ImageDescriptor home;

+	static ImageDescriptor forward;

+	static ImageDescriptor back;

+	static ImageDescriptor print;

+	static ImageDescriptor copy;

+	static ImageDescriptor synchronize;

+

+	static ImageDescriptor actionsImage;

+	static ImageDescriptor hidenav;

+	static ImageDescriptor shownav;

+	static {

+		synchronize =

+			ImageDescriptor.createFromURL(WorkbenchResources.getImagePath("resynch_icon"));

+		home =

+			ImageDescriptor.createFromURL(WorkbenchResources.getImagePath("home_icon"));

+		back =

+			ImageDescriptor.createFromURL(WorkbenchResources.getImagePath("back_icon"));

+		forward =

+			ImageDescriptor.createFromURL(WorkbenchResources.getImagePath("forward_icon"));

+		print =

+			ImageDescriptor.createFromURL(WorkbenchResources.getImagePath("printer_icon"));

+		copy =

+			ImageDescriptor.createFromURL(WorkbenchResources.getImagePath("copy_icon"));

+		shownav =

+			ImageDescriptor.createFromURL(WorkbenchResources.getImagePath("shownav_icon"));

+		hidenav =

+			ImageDescriptor.createFromURL(WorkbenchResources.getImagePath("hidenav_icon"));

+		actionsImage =

+			ImageDescriptor.createFromURL(WorkbenchResources.getImagePath("actions_icon"));

+	}

+

+	/**

+	 */

+	public static abstract class WebAction extends Action {

+		protected IBrowser web;

+		public WebAction(IBrowser web, String name) {

+			super(name);

+			this.web = web;

+		}

+	}

+

+	/**

+	 */

+	public static class CopyAction extends WebAction {

+		public CopyAction(IBrowser web) {

+			super(web, WorkbenchResources.getString("copy"));

+			setText("&Copy@Ctrl+C");

+			setImageDescriptor(copy);

+			setToolTipText(WorkbenchResources.getString("Copy_1"));

+			WorkbenchHelp.setHelp(

+				this,

+				new String[] {

+					IHelpUIConstants.COPY_ACTION,

+					IHelpUIConstants.EMBEDDED_HELP_VIEW});

+		}

+		public void run() {

+			web.copy();

+		}

+	}

+

+	/**

+	 */

+	public static class HomeAction extends WebAction {

+		protected String fHome;

+		public HomeAction(IBrowser web, String homeURL) {

+			super(web, WorkbenchResources.getString("home"));

+			this.fHome = homeURL;

+			setToolTipText(WorkbenchResources.getString("Home_page"));

+			setImageDescriptor(home);

+			setText("&Home@Ctrl+H");

+			WorkbenchHelp.setHelp(

+				this,

+				new String[] {

+					IHelpUIConstants.HOME_ACTION,

+					IHelpUIConstants.EMBEDDED_HELP_VIEW});

+		}

+

+		public HomeAction(IBrowser web) {

+			this(web, null);

+		}

+

+		public void run() {

+			web.navigate(this.fHome);

+		}

+

+		public void setHome(String homeURL) {

+			this.fHome = homeURL;

+		}

+	}

+

+	/**

+	 */

+	public static class BackAction extends WebAction {

+		public BackAction(IBrowser web) {

+			super(web, WorkbenchResources.getString("back"));

+			setToolTipText(WorkbenchResources.getString("Previous_page"));

+			setImageDescriptor(back);

+			setText("&Back@BACKSPACE");

+			WorkbenchHelp.setHelp(

+				this,

+				new String[] {

+					IHelpUIConstants.BACK_ACTION,

+					IHelpUIConstants.EMBEDDED_HELP_VIEW });

+		}

+		public void run() {

+			web.back();

+		}

+

+		public void update() {

+

+		}

+	}

+

+	/**

+	 */

+	public static class ForwardAction extends WebAction {

+		public ForwardAction(IBrowser web) {

+			super(web, WorkbenchResources.getString("forward"));

+			setToolTipText(WorkbenchResources.getString("Next_page"));

+			setImageDescriptor(forward);

+			setText("Forward@Alt+RIGHT_ARROW");

+			WorkbenchHelp.setHelp(

+				this,

+				new String[] {

+					IHelpUIConstants.FORWARD_ACTION,

+					IHelpUIConstants.EMBEDDED_HELP_VIEW });

+		}

+		public void run() {

+			web.forward();

+		}

+	}

+

+	/**

+	 */

+	public static class PrintAction extends WebAction {

+		public PrintAction(IBrowser web) {

+			super(web, WorkbenchResources.getString("print"));

+			setToolTipText(WorkbenchResources.getString("Print_page"));

+			setImageDescriptor(print);

+			setText("&Print@Ctrl+P");

+			WorkbenchHelp.setHelp(

+				this,

+				new String[] {

+					IHelpUIConstants.PRINT_ACTION,

+					IHelpUIConstants.EMBEDDED_HELP_VIEW});

+		}

+		public void run() {

+			web.print();

+		}

+	}

+

+	/**

+	 * Action that synchronizes document viewed in the browser with TOC

+	 */

+	public static class SynchronizeAction extends WebAction {

+		ISelectionProvider selectionProvider;

+		public SynchronizeAction(IBrowser web, ISelectionProvider selectionProvider) {

+			super(web, WorkbenchResources.getString("synchronize"));

+			setText("&Synchronize@Ctrl+S");

+			setImageDescriptor(synchronize);

+			setToolTipText(WorkbenchResources.getString("Synchronize_with_TOC"));

+			this.selectionProvider = selectionProvider;

+			WorkbenchHelp.setHelp(

+				this,

+				new String[] {

+					IHelpUIConstants.SYNCH_ACTION,

+					IHelpUIConstants.EMBEDDED_HELP_VIEW});

+		}

+		public void run() {

+			String currentURL = web.getLocationURL();

+			if (currentURL == null)

+				return;

+			if (this.selectionProvider != null)

+				selectionProvider.setSelection(new StructuredSelection(currentURL));

+		}

+	}

+

+	/**

+	 * Action that shows/hides the TOC   */

+	public static class ShowHideAction extends WebAction {

+		EmbeddedHelpView view;

+		public ShowHideAction(EmbeddedHelpView view) {

+			super(null, WorkbenchResources.getString("toggle"));

+			setText("&Hide navigation@Ctrl+H");

+			setImageDescriptor(hidenav);

+			setToolTipText(WorkbenchResources.getString("Hide_TOC"));

+			this.view = view;

+			WorkbenchHelp.setHelp(

+				this,

+				new String[] {

+					IHelpUIConstants.SHOW_HIDE_ACTION,

+					IHelpUIConstants.EMBEDDED_HELP_VIEW});

+		}

+		public void run() {

+			boolean hidden = view.toggleNavigation();

+			if (hidden) {

+				setText("&Show navigation@Ctrl+H");

+				setImageDescriptor(shownav);

+				setToolTipText(WorkbenchResources.getString("Show_TOC"));

+			} else {

+				setText("&Hide navigation@Ctrl+H");

+				setImageDescriptor(hidenav);

+				setToolTipText(WorkbenchResources.getString("Hide_TOC"));

+			}

+		}

+	}

+	/**

+	 */

+	private Actions() {

+		super();

+	}

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/ContextHelpDialog.java b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/ContextHelpDialog.java
new file mode 100644
index 0000000..430618c
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/ContextHelpDialog.java
@@ -0,0 +1,476 @@
+package org.eclipse.help.internal.ui;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+

+import java.util.*;

+import org.eclipse.swt.*;

+import org.eclipse.swt.graphics.*;

+import org.eclipse.swt.widgets.*;

+import org.eclipse.swt.layout.*;

+import org.eclipse.swt.events.*;

+import org.eclipse.swt.custom.*;

+import org.eclipse.jface.window.Window;

+import org.eclipse.jface.resource.ImageRegistry;

+import org.eclipse.jface.resource.ImageDescriptor;

+import org.eclipse.ui.help.WorkbenchHelp;

+import org.eclipse.help.internal.contributors.ContextManager;

+import org.eclipse.help.*;

+import org.eclipse.help.internal.HelpSystem;

+import org.eclipse.help.internal.ui.util.*;

+import org.eclipse.help.internal.util.*;

+

+/**

+ * ContextHelpDialog

+ */

+public class ContextHelpDialog implements Runnable {

+

+	private Cursor defaultCursor = null;

+	private Cursor waitCursor = null;

+	private ContextManager cmgr = HelpSystem.getContextManager();

+	private Object contexts[];

+	private IHelpTopic farRelatedTopics[] = null;

+	private Thread getMoreRelatedTopicsThread = null;

+	private Map menuItems;

+	private IHelpTopic relatedTopics[] = null;

+

+	// TO DO:

+	// Register these resources with the HelpSystem and have them disposed

+	private Color backgroundColour = null;

+	private Color foregroundColour = null;

+	private Color linkColour = null;

+	private static HyperlinkHandler linkManager = new HyperlinkHandler();

+

+	private final static String IMAGE_MORE = "moreImage";

+	private static ImageRegistry imgRegistry = null;

+

+	private Shell shell;

+

+	private int x;

+	private int y;

+

+	class LinkListener extends HyperlinkAdapter {

+		IHelpTopic topic;

+

+		public LinkListener(IHelpTopic topic) {

+			this.topic = topic;

+		}

+		public void linkActivated(Control c) {

+			launchFullViewHelp(topic);

+		}

+	}

+

+	class MenuItemsListener implements SelectionListener {

+		public void widgetSelected(SelectionEvent e) {

+			IHelpTopic t = (IHelpTopic) menuItems.get(e.widget);

+			shell.close();

+			launchFullViewHelp(t);

+		}

+		public void widgetDefaultSelected(SelectionEvent e) {

+			widgetSelected(e);

+		}

+	}

+

+	class ShowMoreListener implements Listener {

+		public void handleEvent(Event e) {

+			if (e.type == SWT.MouseDown) {

+				if (getMoreRelatedTopicsThread.isAlive()) {

+					Display d = shell.getDisplay();

+					if (waitCursor == null)

+						waitCursor = new Cursor(d, SWT.CURSOR_WAIT);

+					((Label) e.widget).setCursor(waitCursor);

+					try {

+						getMoreRelatedTopicsThread.join();

+					} catch (InterruptedException ie) {

+						return;

+					}

+					if (defaultCursor == null)

+						defaultCursor = new Cursor(d, SWT.CURSOR_ARROW);

+					((Label) e.widget).setCursor(defaultCursor);

+				}

+

+				showMoreLinks();

+			}

+		}

+	}

+

+	ContextHelpDialog(Object[] contexts, int x, int y) {

+		this.contexts = contexts;

+		this.x = x;

+		this.y = y;

+

+		backgroundColour =

+			Display.getCurrent().getSystemColor(SWT.COLOR_INFO_BACKGROUND);

+		foregroundColour =

+			Display.getCurrent().getSystemColor(SWT.COLOR_INFO_FOREGROUND);

+		linkColour = Display.getCurrent().getSystemColor(SWT.COLOR_BLUE);

+

+		if (imgRegistry == null) {

+			imgRegistry = WorkbenchHelpPlugin.getDefault().getImageRegistry();

+			imgRegistry.put(

+				IMAGE_MORE,

+				ImageDescriptor.createFromURL(WorkbenchResources.getImagePath("moreImage")));

+		}

+

+		shell = new Shell(Display.getCurrent().getActiveShell(), SWT.NONE);

+

+		if (Logger.DEBUG)

+			Logger.logDebugMessage(

+				"ContextHelpDialog",

+				" Constructor: Shell is:" + shell.toString());

+

+		WorkbenchHelp.setHelp(shell, new String[] { IHelpUIConstants.F1_SHELL });

+

+		shell.addDisposeListener(new DisposeListener() {

+			public void widgetDisposed(DisposeEvent e) {

+				if (Logger.DEBUG)

+					Logger.logDebugMessage("ContextHelpDialog", "widgetDisposed: called. ");

+				if (waitCursor != null)

+					waitCursor.dispose();

+				if (defaultCursor != null)

+					defaultCursor.dispose();

+			}

+		});

+

+		// This is commented out for now because it does not work on Linux

+		// Using addListener for now.

+		/*shell.addShellListener(new ShellAdapter() {

+			public void shellDeactivated(ShellEvent e) {

+				e.widget.getDisplay().asyncExec(new Runnable() {

+					public void run() {

+						close();

+					}

+				});

+			}

+		});*/

+

+		shell.addListener(SWT.Deactivate, new Listener() {

+			public void handleEvent(Event e) {

+				if (Logger.DEBUG)

+					Logger.logDebugMessage(

+						"ContextHelpDialog",

+						"handleEvent: SWT.Deactivate called. ");

+				close();

+			};

+		});

+

+		shell.addControlListener(new ControlAdapter() {

+			public void controlMoved(ControlEvent e) {

+				if (Logger.DEBUG)

+					Logger.logDebugMessage("ContextHelpDialog", "controlMoved: called. ");

+				Rectangle clientArea = shell.getClientArea();

+				shell.redraw(

+					clientArea.x,

+					clientArea.y,

+					clientArea.width,

+					clientArea.height,

+					true);

+				shell.update();

+			}

+		});

+

+		if (Logger.DEBUG)

+			Logger.logDebugMessage(

+				"ContextHelpDialog",

+				"Constructor: Focus owner is: "

+					+ Display.getCurrent().getFocusControl().toString());

+

+		linkManager.setHyperlinkUnderlineMode(HyperlinkHandler.UNDERLINE_ROLLOVER);

+

+		createContents(shell);

+

+		shell.pack();

+

+		// Correct x and y of the shell if it not contained within the screen

+		int width = shell.getBounds().width;

+		int height = shell.getBounds().height;

+		// check lower boundaries

+		x = x >= 0 ? x : 0;

+		y = y >= 0 ? y : 0;

+		// check upper boundaries

+		int margin = 0;

+		if (System.getProperty("os.name").startsWith("Win"))

+			margin = 28; // for the Windows task bar in the ussual place;

+		Rectangle screen = Display.getCurrent().getBounds();

+		x = x + width <= screen.width ? x : screen.width - width;

+		y = y + height <= screen.height - margin ? y : screen.height - margin - height;

+

+		shell.setLocation(x, y);

+

+	}

+	public synchronized void close() {

+		try {

+			if (Logger.DEBUG)

+				Logger.logDebugMessage("ContextHelpDialog", "close: called. ");

+			if (shell != null) {

+				shell.close();

+				if (!shell.isDisposed())

+					shell.dispose();

+				shell = null;

+			}

+

+			if (getMoreRelatedTopicsThread != null

+				&& getMoreRelatedTopicsThread.isAlive()) {

+				try {

+					getMoreRelatedTopicsThread.join();

+				} catch (InterruptedException ie) {

+				}

+			}

+		} catch (Throwable ex) {

+		}

+	}

+	/**

+	 */

+	protected Control createContents(Composite contents) {

+

+		contents.setBackground(backgroundColour);

+

+		GridLayout layout = new GridLayout();

+		layout.marginHeight = 5;

+		layout.marginWidth = 5;

+		contents.setLayout(layout);

+		contents.setLayoutData(new GridData(GridData.FILL_BOTH));

+

+		// create the dialog area and button bar

+		createInfoArea(contents);

+		createLinksArea(contents);

+

+		// if any errors or parsing errors have occurred, display them in a pop-up

+		Util.displayStatus();

+

+		return contents;

+	}

+	protected Control createInfoArea(Composite parent) {

+		Composite composite = new Composite(parent, SWT.NONE);

+		GridLayout layout = new GridLayout();

+		layout.marginHeight = 0;

+		layout.marginWidth = 0;

+		composite.setLayout(layout);

+		composite.setBackground(backgroundColour);

+

+		GridData data =

+			new GridData(

+				GridData.FILL_BOTH

+					| GridData.HORIZONTAL_ALIGN_CENTER

+					| GridData.VERTICAL_ALIGN_CENTER);

+		composite.setLayoutData(data);

+		/*

+			// Create the text field.    

+			StyledText text = new StyledText(composite, SWT.MULTI | SWT.READ_ONLY | SWT.WRAP );

+			text.setBackground(backgroundColour);

+			text.setForeground(foregroundColour);

+		

+			// Text with possibly <b> .. </b> styles

+			String styledText = cmgr.getDescription(contexts);

+			

+			if (styledText != null) {   

+				text.setText(getStrippedText(styledText));

+				text.setStyleRanges(getStyleRanges(styledText));

+			} else {

+				// no description found in context objects.

+				String msg = WorkbenchResources.getString("WW002");

+				text.setText(msg);

+			}

+			

+		

+			data = new GridData();

+			// Use the shell bounds here...

+			//data.heightHint = HEIGHT-100;

+			//data.widthHint = WIDTH-10;

+			data.horizontalAlignment = data.FILL;

+			data.grabExcessHorizontalSpace = true;

+			data.verticalAlignment = data.FILL;

+			data.grabExcessVerticalSpace = true;

+			text.setLayoutData(data);

+		*/

+

+		// Create the text field.    

+		InfopopText text =

+			new InfopopText(composite, SWT.MULTI | SWT.READ_ONLY | SWT.WRAP);

+		text.setBackground(backgroundColour);

+		text.setForeground(foregroundColour);

+

+		//String styledText = "This is some sample <b>code</b> with <b>bold</b>";

+		String styledText = cmgr.getDescription(contexts);

+

+		if (styledText != null) {

+			text.setText(styledText);

+		} else {

+			// no description found in context objects.

+			String msg = WorkbenchResources.getString("WW002");

+			text.setText(msg);

+		}

+

+		data = new GridData();

+		// Use the shell bounds here...

+		//data.heightHint = HEIGHT-100;

+		//data.widthHint = WIDTH-10;

+		data.horizontalAlignment = data.FILL;

+		data.grabExcessHorizontalSpace = true;

+		data.verticalAlignment = data.FILL;

+		data.grabExcessVerticalSpace = true;

+		text.setLayoutData(data);

+

+		return composite;

+	}

+	protected Control createLink(Composite parent, IHelpTopic topic) {

+		Label link = new Label(parent, SWT.NONE);

+		link.setText(topic.getLabel());

+		link.setBackground(backgroundColour);

+		link.setForeground(linkColour);

+

+		// RGB colors do not need be disposed

+		//link.setFont(regularFont);

+		GridData data = new GridData();

+		data.horizontalAlignment = data.HORIZONTAL_ALIGN_BEGINNING;

+		data.verticalAlignment = data.VERTICAL_ALIGN_BEGINNING;

+		data.horizontalIndent = 4;

+		link.setLayoutData(data);

+

+		linkManager.registerHyperlink(link, new LinkListener(topic));

+		return link;

+	}

+	protected Control createLinksArea(Composite parent) {

+		// get links from first context with links

+		relatedTopics = cmgr.getRelatedTopics(contexts);

+

+		if (relatedTopics == null)

+			// non of the contexts have Topics

+			return null;

+

+		// Create control

+		Composite composite = new Composite(parent, SWT.NONE);

+		composite.setBackground(backgroundColour);

+

+		GridLayout layout = new GridLayout();

+		layout.marginHeight = 0;

+		layout.marginWidth = 0;

+		layout.verticalSpacing = 3;

+		composite.setLayout(layout);

+

+		GridData data =

+			new GridData(

+				GridData.FILL_BOTH

+					| GridData.HORIZONTAL_ALIGN_BEGINNING

+					| GridData.VERTICAL_ALIGN_CENTER);

+		composite.setLayoutData(data);

+

+		// Create separator.    

+		Label label = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL);

+		label.setBackground(backgroundColour);

+		label.setForeground(foregroundColour);

+		//label.setText(WorkbenchResources.getString("Related_Topics"));

+		data =

+			new GridData(

+				GridData.HORIZONTAL_ALIGN_BEGINNING

+					| GridData.VERTICAL_ALIGN_BEGINNING

+					| GridData.FILL_HORIZONTAL);

+		/*

+		data.horizontalAlignment = data.HORIZONTAL_ALIGN_BEGINNING;

+		data.verticalAlignment = data.VERTICAL_ALIGN_BEGINNING;

+		*/

+		label.setLayoutData(data);

+

+		// Create related links

+		for (int i = 0; i < relatedTopics.length; i++) {

+			createLink(composite, relatedTopics[i]);

+		}

+

+		// Create Show More button

+		CLabel showMoreButton = new CLabel(composite, SWT.NONE);

+		showMoreButton.setBackground(backgroundColour);

+		//showMoreButton.setText(WorkbenchResources.getString("Show_More_Related"));

+		//showMoreButton.setFont(italicFont);

+		showMoreButton.setImage(imgRegistry.get(IMAGE_MORE));

+

+		Listener l = new ShowMoreListener();

+		showMoreButton.addListener(SWT.MouseDown, l);

+

+		// Before returning start thread obtaining more related links in the bacground

+		getMoreRelatedTopicsInBackground();

+		return composite;

+	}

+	protected void getMoreRelatedTopicsInBackground() {

+		getMoreRelatedTopicsThread = new Thread(this);

+		getMoreRelatedTopicsThread.setDaemon(true);

+		getMoreRelatedTopicsThread.setName("MoreRelatedTopics");

+		getMoreRelatedTopicsThread.setPriority(

+			Thread.currentThread().getPriority() - 1);

+		getMoreRelatedTopicsThread.start();

+	}

+	/**

+	 */

+	protected void launchFullViewHelp(IHelpTopic selectedTopic) {

+		// wait for more related links

+		if (getMoreRelatedTopicsThread.isAlive()) {

+			Display d = Display.getCurrent();

+			if (waitCursor == null)

+				waitCursor = new Cursor(d, SWT.CURSOR_WAIT);

+			shell.setCursor(waitCursor);

+			try {

+				getMoreRelatedTopicsThread.join();

+			} catch (InterruptedException ie) {

+				return;

+			}

+		}

+

+		// group related topics, and far related topics together

+		IHelpTopic allTopics[] =

+			new IHelpTopic[relatedTopics.length + farRelatedTopics.length];

+		System.arraycopy(relatedTopics, 0, allTopics, 0, relatedTopics.length);

+		System.arraycopy(

+			farRelatedTopics,

+			0,

+			allTopics,

+			relatedTopics.length,

+			farRelatedTopics.length);

+

+		// launch help view

+		DefaultHelp.getInstance().displayHelp(allTopics, selectedTopic);

+

+		// now close the infopop

+		close();

+		if (Logger.DEBUG)

+			Logger.logDebugMessage("ContextHelpDialog", "launchFullViewHelp: closes shell");

+	}

+	public synchronized void open() {

+		try {

+			shell.open();

+			if (Logger.DEBUG)

+				Logger.logDebugMessage(

+					"ContextHelpDialog",

+					"open: Focus owner after open is: "

+						+ Display.getCurrent().getFocusControl().toString());

+

+		} catch (Throwable e) {

+		}

+	}

+	/**

+	 * Obtains more related Links

+	 */

+	public void run() {

+		farRelatedTopics = cmgr.getMoreRelatedTopics(contexts);

+	}

+	protected void showMoreLinks() {

+		Menu menu = new Menu(shell);

+		if (farRelatedTopics == null || farRelatedTopics.length < 1) {

+			// show "no more links" menu item only

+			MenuItem item = new MenuItem(menu, SWT.CASCADE);

+			item.setText(WorkbenchResources.getString("No_more_links_exist"));

+		} else {

+			// create and show menu items with related links

+			menuItems = new HashMap();

+			SelectionListener l = new MenuItemsListener();

+			for (int i = 0; i < farRelatedTopics.length; i++) {

+				MenuItem item = new MenuItem(menu, SWT.CASCADE);

+				item.setText(((IHelpTopic) farRelatedTopics[i]).getLabel());

+				menuItems.put(item, (IHelpTopic) farRelatedTopics[i]);

+				item.addSelectionListener(l);

+			}

+		}

+		menu.setVisible(true);

+	}

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/DefaultHelp.java b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/DefaultHelp.java
new file mode 100644
index 0000000..190a30d
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/DefaultHelp.java
@@ -0,0 +1,267 @@
+package org.eclipse.help.internal.ui;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+import org.eclipse.ui.*;

+import org.eclipse.help.*;

+import org.eclipse.core.runtime.*;

+import org.eclipse.core.resources.*;

+import org.eclipse.help.internal.ui.util.WorkbenchResources;

+import org.eclipse.help.internal.navigation.NavigationModel;

+import org.eclipse.help.internal.*;

+import org.eclipse.help.internal.util.Logger;

+import org.eclipse.help.internal.contributions.InfoSet;

+import org.eclipse.help.internal.ui.util.Util;

+

+/**

+ * This class is an implementation of the pluggable help support.

+ * In is registered into the support extension point, and all 

+ * requests to display help are delegated to this class.

+ * The methods on this class interact with the actual

+ * UI component handling the display

+ */

+public class DefaultHelp implements IHelp {

+	private static DefaultHelp instance;

+	private IWorkbenchPage helpPage = null;

+	private ContextHelpDialog f1Dialog = null;

+

+	/**

+	 * BaseHelpViewer constructor comment.

+	 */

+	public DefaultHelp() {

+		super();

+		instance = this;

+	}

+	/**

+	 * Makes Help Page Active (visible)

+	 */

+	private void activateHelpPage() {

+		// Make Help Page active

+		IWorkbench workbench = WorkbenchHelpPlugin.getDefault().getWorkbench();

+		IWorkbenchWindow workbenchWindow = workbench.getActiveWorkbenchWindow();

+		if (workbenchWindow.getActivePage() != helpPage)

+			if (helpPage != null)

+				workbenchWindow.setActivePage(helpPage);

+	}

+	/**

+	 * Displays context-sensitive help for specified contexts

+	 * @param contextIds java.lang.String[]. If a context id is a string, context is looked-up.

+	 * @param x int positioning information

+	 * @param y int positioning information

+	 */

+	public void displayHelp(String[] contextIds, int x, int y) {

+

+		if (f1Dialog != null)

+			f1Dialog.close();

+

+		f1Dialog = new ContextHelpDialog(contextIds, x, y);

+		f1Dialog.open();

+	}

+	/**

+	 * Displays context-sensitive help for specified contexts

+	 * @param contexts org.eclipse.help.IContext[] dyanmically computed by the application.

+	 * @param x int positioning information

+	 * @param y int positioning information

+	 */

+	public void displayHelp(IContext[] contexts, int x, int y) {

+

+		if (f1Dialog != null)

+			f1Dialog.close();

+

+		f1Dialog = new ContextHelpDialog(contexts, x, y);

+		f1Dialog.open();

+	}

+	/**

+	 * Display help for the a given topic and related topics.

+	 * @param topic topic to be displayed by the help browser

+	 * @param relatedTopics topics that will populate related topics view

+	 */

+	public void displayHelp(IHelpTopic[] relatedTopics, IHelpTopic topic) {

+		if (topic == null || topic.getHref() == null)

+			return;

+

+		// Do not start help view if documentaton is not available, display error

+		if (HelpSystem.getNavigationManager().getCurrentInfoSet() == null) {

+			Util.displayErrorDialog(WorkbenchResources.getString("WW001"));

+			return;

+		}

+

+		EmbeddedHelpView helpView = getHelpViewInCurrentPerpective();

+

+		// if no infoset is available, helpview will be null.

+		if (helpView == null)

+			return;

+		helpView.displayHelp(relatedTopics, topic);

+

+		//activateHelpPage();

+	}

+	/**

+	  * Display help.

+	  */

+	public void displayHelp(String url) {

+

+		if (url != null && !"".equals(url)) {

+			// Verify if this url is a views id or a real url

+			NavigationModel navModel =

+				HelpSystem.getNavigationManager().getNavigationModel(url);

+			if (navModel == null) {

+				// external URL

+				try {

+					String cmd[] = { "rundll32.exe", "url.dll,FileProtocolHandler", url };

+					Runtime.getRuntime().exec(cmd);

+				} catch (Exception ioe) {

+				}

+				return;

+			} else {

+				HelpSystem.getNavigationManager().setCurrentInfoSet(url);

+				HelpSystem.getNavigationManager().setCurrentNavigationModel(navModel);

+			}

+

+		}

+

+		// Do not start help view if documentaton is not available, display error

+		if (HelpSystem.getNavigationManager().getCurrentInfoSet() == null) {

+			Util.displayErrorDialog(WorkbenchResources.getString("WW001"));

+			return;

+		}

+

+		// First check the current perspective

+		EmbeddedHelpView helpView = getHelpViewInCurrentPerpective();

+		if (helpView == null) {

+			// not found, so open the help in the help perspective

+			helpView = getHelpViewInHelpPerspective();

+		}

+		if (helpView == null)

+			return;

+		else

+			activateHelpPage();

+	}

+	/**

+	 * Computes context information for a given context ID.

+	 * @param contextID java.lang.String ID of the context

+	 * @return IContext

+	 */

+	public IContext findContext(String contextID) {

+		//return HelpSystem.getContextManager().getContext(contextID);

+		return new ContextImpl(contextID);

+	}

+	/**

+	 * Obtains HelpView existing in current perspective.  If it does not

+	 * exists, obtains HelpView in HelpPerspective.

+	 * @return org.eclipse.help.internal.ui.EmbeddedHelpView

+	 */

+	public EmbeddedHelpView getHelpViewInCurrentPerpective() {

+		// returning null in this method is the cleanest way to handle error.

+		// what we do is log the error, then die cleanly.

+

+		IWorkbench workbench = WorkbenchHelpPlugin.getDefault().getWorkbench();

+		IWorkbenchWindow workbenchWindow = workbench.getActiveWorkbenchWindow();

+		helpPage = null;

+

+		IWorkbenchPage activeP = workbenchWindow.getActivePage();

+

+		if (activeP == null || activeP.findView(EmbeddedHelpView.ID) == null) {

+			EmbeddedHelpView aEmbeddedHelpView = getHelpViewInHelpPerspective();

+			activateHelpPage();

+			return aEmbeddedHelpView;

+		}

+

+		try {

+			EmbeddedHelpView aEmbeddedHelpView =

+				(EmbeddedHelpView) activeP.showView(EmbeddedHelpView.ID);

+			// check to see if the view was created successfully, with a valid Infoset

+			if (aEmbeddedHelpView.isCreationSuccessful())

+				return aEmbeddedHelpView;

+			else

+				// no need to log anything here because it would already be logged

+				// in the UI classes.

+				return null;

+		} catch (Exception e) {

+			// should never be here.

+			Logger.logError(WorkbenchResources.getString("WE004"), e);

+			return null;

+		}

+

+	}

+	/**

+	 * Obtains HelpView in HelpPerspective.  Opens new HelpPerspective

+	 * if necessary.

+	 * @return org.eclipse.help.internal.ui.EmbeddedHelpView

+	 */

+	public EmbeddedHelpView getHelpViewInHelpPerspective() {

+		// returning null in this method is the cleanest way to handle error.

+		// what we do is log the error, then die cleanly.

+

+		IWorkbench workbench = WorkbenchHelpPlugin.getDefault().getWorkbench();

+		IWorkbenchWindow workbenchWindow = workbench.getActiveWorkbenchWindow();

+		helpPage = null;

+

+		// Check if active perspective is a help perspective

+		IWorkbenchPage activeP = workbenchWindow.getActivePage();

+		if (activeP != null)

+			if (activeP.getPerspective().getId().equals(HelpPerspective.ID))

+				helpPage = workbenchWindow.getActivePage();

+

+		if (helpPage == null) {

+			// Find first Help Page out of not active pages

+			IWorkbenchPage[] pages = workbenchWindow.getPages();

+			for (int i = 0; i < pages.length; i++) {

+				if (pages[i].getPerspective().getId().equals(HelpPerspective.ID)) {

+					helpPage = pages[i];

+					break;

+				}

+			}

+		}

+

+		if (helpPage == null) {

+			if (activeP != null) {

+				IAdaptable oldInput = activeP.getInput();

+				try {

+					helpPage = workbenchWindow.openPage(HelpPerspective.ID, oldInput);

+				} catch (WorkbenchException e) {

+					// should never be here.

+					Logger.logError(WorkbenchResources.getString("WE002"), e);

+					return null;

+				}

+			} else {

+				try {

+					helpPage =

+						workbenchWindow.openPage(

+							HelpPerspective.ID,

+							ResourcesPlugin.getWorkspace().getRoot());

+				} catch (WorkbenchException e) {

+					// should never be here.

+					Logger.logError(WorkbenchResources.getString("WE002"), e);

+					return null;

+				}

+			}

+		}

+		if (helpPage == null) {

+			// should never be here.

+			Logger.logError(WorkbenchResources.getString("WE003"), null);

+			return null;

+		} else {

+			try {

+				EmbeddedHelpView aEmbeddedHelpView =

+					(EmbeddedHelpView) helpPage.showView(EmbeddedHelpView.ID);

+				// check to see if the view was created successfully, with a valid Infoset

+				if (aEmbeddedHelpView.isCreationSuccessful())

+					return aEmbeddedHelpView;

+				else

+					// no need to log anything here because it would already be logged

+					// in the UI classes.

+					return null;

+			} catch (Exception e) {

+				// should never be here.

+				Logger.logError(WorkbenchResources.getString("WE004"), e);

+				return null;

+			}

+		}

+	}

+	public static DefaultHelp getInstance() {

+		return instance;

+	}

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/ElementLabelProvider.java b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/ElementLabelProvider.java
new file mode 100644
index 0000000..f12ea78
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/ElementLabelProvider.java
@@ -0,0 +1,64 @@
+package org.eclipse.help.internal.ui;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+

+import java.util.Iterator;

+import org.eclipse.swt.graphics.Image;

+import org.eclipse.jface.viewers.*;

+import org.eclipse.jface.resource.ImageRegistry;

+import org.eclipse.jface.resource.ImageDescriptor;

+import org.eclipse.help.internal.contributions.*;

+import org.eclipse.help.internal.ui.util.WorkbenchResources;

+

+/**

+ * Label and image provider for topic elements

+ */

+public class ElementLabelProvider extends LabelProvider {

+	static ElementLabelProvider instance = null;

+

+	static final String IMAGE_TOPIC = "topic_icon";

+	static final String IMAGE_TOPIC_FOLDER = "topicfolder_icon";

+	static final String IMAGE_TOPIC_AND_FOLDER = "topicandfolder_icon";

+	static ImageRegistry imgRegistry = null;

+

+	/**

+	 * ElementLabelProvider Constructor

+	 */

+	ElementLabelProvider() {

+		imgRegistry = WorkbenchHelpPlugin.getDefault().getImageRegistry();

+		imgRegistry.put(

+			IMAGE_TOPIC,

+			ImageDescriptor.createFromURL(WorkbenchResources.getImagePath(IMAGE_TOPIC)));

+		imgRegistry.put(

+			IMAGE_TOPIC_AND_FOLDER,

+			ImageDescriptor.createFromURL(

+				WorkbenchResources.getImagePath(IMAGE_TOPIC_AND_FOLDER)));

+		imgRegistry.put(

+			IMAGE_TOPIC_FOLDER,

+			ImageDescriptor.createFromURL(

+				WorkbenchResources.getImagePath(IMAGE_TOPIC_FOLDER)));

+	}

+	public static ElementLabelProvider getDefault() {

+		if (instance == null)

+			instance = new ElementLabelProvider();

+		return instance;

+	}

+	public Image getImage(Object element) {

+		Topic topic = (Topic) element;

+		Iterator children = topic.getChildren();

+		if (children == null || !children.hasNext())

+			return imgRegistry.get(IMAGE_TOPIC);

+		else

+			if (("".equals(topic.getHref())) || (null == topic.getHref()))

+				return imgRegistry.get(IMAGE_TOPIC_FOLDER);

+			else

+				return imgRegistry.get(IMAGE_TOPIC_AND_FOLDER);

+	}

+	public String getText(Object element) {

+		return ((Contribution) element).getLabel();

+	}

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/EmbeddedHelpView.java b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/EmbeddedHelpView.java
new file mode 100644
index 0000000..4cdf3e6
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/EmbeddedHelpView.java
@@ -0,0 +1,418 @@
+package org.eclipse.help.internal.ui;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+

+import org.eclipse.swt.events.*;

+import org.eclipse.swt.*;

+import org.eclipse.swt.widgets.*;

+import org.eclipse.swt.graphics.*;

+import org.eclipse.jface.action.*;

+import org.eclipse.jface.viewers.*;

+import org.eclipse.ui.*;

+import org.eclipse.ui.help.WorkbenchHelp;

+import org.eclipse.ui.part.ViewPart;

+import org.eclipse.help.*;

+import org.eclipse.help.internal.contributions.InfoSet;

+import org.eclipse.help.internal.contributions.Contribution;

+import org.eclipse.help.internal.HelpSystem;

+import org.eclipse.help.internal.contributors.*;

+import org.eclipse.help.internal.contributions.xml.*;

+import org.eclipse.help.internal.ui.util.*;

+import org.eclipse.help.internal.navigation.*;

+

+/**

+ * EmbeddedHelpView

+ */

+public class EmbeddedHelpView extends ViewPart {

+

+	public final static String ID = "org.eclipse.help.internal.ui.EmbeddedHelpView";

+	/* Constants */

+	static final int SASH_WIDTH = 3;

+	protected Composite viewContainer = null;

+	protected Sash vSash;

+	protected int lastSash;

+

+	// this flag captures if the UI of this view has been created successfully

+	// (ie: perspective & view)

+	protected boolean creationSuccessful = false;

+	protected float viewsWidthPercentage = 0.25f;

+

+	protected HTMLHelpViewer htmlViewer = null;

+	protected NavigationViewer navigationViewer = null;

+

+	private String lastInfosetId;

+	private String lastTopicUrl;

+

+	private Action showHideAction;

+	private Action backAction;

+	private Action forwardAction;

+	private Action printAction;

+	private Action copyAction;

+	private Action synchronizeAction;

+	/**

+	 * EmbeddedHelpView constructor comment.

+	 */

+	public EmbeddedHelpView() {

+		super();

+	}

+	/**

+	 * Adds action contributions.

+	 */

+	private void addContributions() {

+		makeActions();

+		fillToolbar();

+		fillContextMenu();

+		fillMenu();

+	}

+	/**

+	 * Creates the SWT controls for a part.

+	 */

+	public void createPartControl(Composite parent) {

+		viewContainer = new Composite(parent, SWT.NULL);

+		WorkbenchHelp.setHelp(

+			viewContainer,

+			new String[] {IHelpUIConstants.EMBEDDED_HELP_VIEW});

+

+		try {

+			// get proper InfoSet. 

+			InfoSet infoSet = null;

+			

+			if (lastInfosetId != null) // mememto was saved

+				{

+				infoSet = HelpSystem.getNavigationManager().getInfoSet(lastInfosetId);

+				if (infoSet != null) // plugin still exists

+					HelpSystem.getNavigationManager().setCurrentInfoSet(lastInfosetId);

+			}

+			

+			infoSet = HelpSystem.getNavigationManager().getCurrentInfoSet();

+

+			// no InsoSets installed at all. Display error dialog, but also handle

+			// empty view. Since view is already created, do *not* close for safety. 

+			if (infoSet == null) {

+				String msg= WorkbenchResources.getString("WW001");

+				Util.displayErrorDialog(msg);

+				viewContainer.dispose();

+				Text text = new Text(parent, SWT.BORDER | SWT.MULTI 

+										| SWT.READ_ONLY | SWT.WRAP);

+				text.setText(msg);

+

+				// capture that the view was not created successfully

+				creationSuccessful = false;

+				return;

+			}

+

+			// try creating the view. If anything goes wrong. put up

+			// a Text area with the captured error message. 

+

+			htmlViewer = new HTMLHelpViewer(viewContainer);

+			navigationViewer = new NavigationViewer(viewContainer);

+			// htmlViewer should be updated when selected topic changes 

+			navigationViewer.addSelectionChangedListener(htmlViewer);

+

+			// only add actions for windows.

+			// when we have an embedded browser on linux, remove the if()

+			if (System.getProperty("os.name").startsWith("Win"))

+				addContributions();

+

+			vSash = new Sash(viewContainer, SWT.VERTICAL);

+			vSash.addSelectionListener(new SelectionAdapter() {

+				public void widgetSelected(SelectionEvent event) {

+					if (event.detail != SWT.DRAG) {

+						vSash.setBounds(event.x, event.y, event.width, event.height);

+						layout();

+					}

+				}

+			});

+			viewContainer.addControlListener(new ControlAdapter() {

+				public void controlResized(ControlEvent event) {

+					shellResized();

+				}

+			});

+

+			// update parts

+			navigationViewer.setInput(infoSet);

+

+			// navigate to specific topic if known from memento

+			if (lastTopicUrl != null)

+				navigationViewer.setSelection(new StructuredSelection(lastTopicUrl));

+

+			// if any errors or parsing errors have occurred, display them in a pop-up

+			Util.displayStatus();

+

+			creationSuccessful = true;

+

+		} catch (HelpWorkbenchException e) {

+			// something we know about failed.

+			viewContainer.dispose();

+			Text text = new Text(parent, SWT.BORDER | SWT.MULTI | SWT.READ_ONLY | SWT.WRAP );

+			text.setText(e.getMessage());

+

+			// capture that the view was not created successfully

+			creationSuccessful = false;

+

+		} catch (Exception e) {

+			// now handle worst case scenario. Should never be here!

+			viewContainer.dispose();

+			Text text = new Text(parent, SWT.BORDER | SWT.MULTI | SWT.READ_ONLY | SWT.WRAP );

+			text.setText("Help View Failed to Launch");

+

+			// capture that the view was not created successfully

+			creationSuccessful = false;

+		}

+	}

+	/**

+	 * Shows the related links, and current information set

+	 */

+	public void displayHelp(IHelpTopic[] relatedTopics, IHelpTopic topic) {

+		InfoSet infoSet = HelpSystem.getNavigationManager().getCurrentInfoSet();

+		if (infoSet == null)

+			return;

+

+		HelpInfoView relatedTopicsTree = new HelpInfoView(null);

+		relatedTopicsTree.setRawLabel(

+			WorkbenchResources.getString("RelatedTopics_viewLabel"));

+		HelpTopic selectedChild = null;

+		for (int i = 0; i < relatedTopics.length; i++) {

+			HelpTopic child = new HelpTopicRef((HelpTopic) relatedTopics[i]);

+			relatedTopicsTree.addChild(child);

+			if (relatedTopics[i] == topic) {

+				selectedChild = child;

+			}

+		}

+		Contribution contributions[] = new Contribution[2];

+		// We create another tree that will populate additional "Links" tab.

+		contributions[0] = relatedTopicsTree;

+		contributions[1] = infoSet;

+

+		// populate navigation viewer

+		navigationViewer.setInput(contributions);

+

+		// select topic

+		if (selectedChild != null) {

+			navigationViewer.setSelection(new StructuredSelection(selectedChild));

+		}

+

+		if (infoSet != null)

+			setTitle(infoSet.getLabel());

+

+		// if any errors or parsing errors have occurred, display them in a pop-up

+		Util.displayStatus();

+	}

+	/**

+	 * Fill the context menu with actions.

+	 */

+	private void fillContextMenu() {

+		// Currently not needed...

+		/*

+		MenuManager manager = new MenuManager("helpActions");

+		manager.setRemoveAllWhenShown(true);

+		manager.addMenuListener(new IMenuListener() {

+			public void menuAboutToShow(IMenuManager mgr) {

+				mgr.add(copyAction);

+				mgr.add(printAction);

+			}

+		});

+		Menu contextMenu = manager.createContextMenu(viewContainer);

+		viewContainer.setMenu(contextMenu);

+		*/

+	}

+	/**

+	 * Fill the workbench menu with actions.

+	 */

+	private void fillMenu() {

+		// Currently not needed...

+		/*

+		IActionBars actionBars = getViewSite().getActionBars();

+		if (actionBars != null) {

+			actionBars.setGlobalActionHandler(IWorkbenchActionConstants.COPY, copyAction);

+			actionBars.setGlobalActionHandler(

+				IWorkbenchActionConstants.M_FILE,

+				printAction);

+		}

+		*/

+	}

+	/**

+	 * Fill the local tool bar with actions.

+	 */

+	private void fillToolbar() {

+

+		IToolBarManager tbm = getViewSite().getActionBars().getToolBarManager();

+		tbm.removeAll();

+

+		tbm.add(showHideAction);

+		tbm.add(new Separator());

+		tbm.add(backAction);

+		tbm.add(forwardAction);

+		tbm.add(new Separator());

+		tbm.add(synchronizeAction);

+		tbm.add(new Separator());

+		// NOTE: when print support is added in the platform

+		// move this to File -> Print

+		tbm.add(printAction);

+		tbm.add(new Separator());

+

+		// require update because toolbar control has been created by this point,

+		// but manager does not update it automatically once it has been created

+		tbm.update(true);

+	}

+	NavigationViewer getNavigationViewer() {

+		return navigationViewer;

+	}

+	public Composite getViewComposite() {

+		return viewContainer;

+	}

+	/* (non-Javadoc)

+	 * Initializes this view with the given view site.  A memento is passed to

+	 * the view which contains a snapshot of the views state from a previous

+	 * session.  Where possible, the view should try to recreate that state

+	 * within the part controls.

+	 */

+	public void init(IViewSite site, IMemento memento) throws PartInitException {

+		init(site);

+		if (memento == null)

+			return;

+

+		lastInfosetId = memento.getString("lastInfoSet");

+		lastTopicUrl = memento.getString("lastTopicUrl");

+	}

+	public boolean isCreationSuccessful() {

+		return creationSuccessful;

+	}

+	/**

+	* Layout the list and text widgets according to the new

+	* positions of the sashes..events.SelectionEvent

+	*/

+	void layout() {

+

+		Rectangle viewContainerBounds = viewContainer.getClientArea();

+		Rectangle vSashBounds = vSash.getBounds();

+		viewsWidthPercentage =

+			(float) vSashBounds.x / (viewContainerBounds.width - vSashBounds.width);

+

+		navigationViewer.getControl().setBounds(

+			0,

+			0,

+			vSashBounds.x,

+			viewContainerBounds.height);

+		htmlViewer.getControl().setBounds(

+			vSashBounds.x + vSashBounds.width,

+			0,

+			viewContainerBounds.width - (vSashBounds.x + vSashBounds.width),

+			viewContainerBounds.height);

+	}

+	/**

+	 * Fill the local tool bar with actions.

+	 */

+	private void makeActions() {

+		IBrowser browser = htmlViewer.getWebBrowser();

+		if (browser == null)

+			return;

+

+		showHideAction = new Actions.ShowHideAction(this);

+		backAction = new Actions.BackAction(browser);

+		forwardAction = new Actions.ForwardAction(browser);

+

+		synchronizeAction =

+			new Actions.SynchronizeAction(browser, this.getNavigationViewer());

+		copyAction = new Actions.CopyAction(browser);

+		printAction = new Actions.PrintAction(browser);

+

+	}

+	/* (non-Javadoc)

+	 * Method declared on IViewPart.

+	 */

+	public void saveState(IMemento memento) {

+		try {

+			if (navigationViewer != null) {

+				InfoSet infoSet = (InfoSet) navigationViewer.getInput();

+				if (infoSet != null)

+					memento.putString("lastInfoSet", infoSet.getID());

+

+				ISelection sel = navigationViewer.getSelection();

+				if (!sel.isEmpty() && sel instanceof IStructuredSelection) {

+					Object selectedTopic = ((IStructuredSelection) sel).getFirstElement();

+					if (selectedTopic != null && selectedTopic instanceof IHelpTopic)

+						memento.putString("lastTopicUrl", ((IHelpTopic) selectedTopic).getHref());

+				}

+			}

+		} catch (Exception e) {

+			// this is to guard agains platform UI exceptions

+		}

+	}

+	/**

+	 * Asks the part to take focus within the workbench.

+	 */

+	public void setFocus() {

+		try {

+			InfoSet infoSet = (InfoSet) navigationViewer.getInput();

+			if (infoSet != null)

+				// set global infoset and navigation model

+				HelpSystem.getNavigationManager().setCurrentInfoSet(infoSet.getID());

+		} catch (Exception e) {

+			// unexpected error, it should not happen.

+			// This is to guard agains platform UI bugs.

+		}

+	}

+	/**

+	* Handle the shell resized event.

+	*/

+	void shellResized() {

+

+		/* Get the client area for the shell */

+		Rectangle viewContainerBounds = viewContainer.getClientArea();

+

+		/* Position the sash according to same proportions as before*/

+		vSash.setLocation(

+			(int) ((viewContainerBounds.width - SASH_WIDTH) * viewsWidthPercentage),

+			vSash.getLocation().y);

+

+		/*

+		* Make list 1 half the width and half the height of the tab leaving room for the sash.

+		* Place list 1 in the top left quadrant of the tab.

+		*/

+		Rectangle navigationBrowserBounds =

+			new Rectangle(0, 0, vSash.getLocation().x, viewContainerBounds.height);

+		navigationViewer.getControl().setBounds(

+			navigationBrowserBounds.x,

+			navigationBrowserBounds.y,

+			navigationBrowserBounds.width,

+			navigationBrowserBounds.height);

+

+		/*

+		* Make list 2 half the width and half the height of the tab leaving room for the sash.

+		* Place list 2 in the top right quadrant of the tab.

+		*/

+		htmlViewer.getControl().setBounds(

+			navigationBrowserBounds.width + SASH_WIDTH,

+			0,

+			viewContainerBounds.width - (navigationBrowserBounds.width + SASH_WIDTH),

+			navigationBrowserBounds.height);

+

+		/* Position the sash */

+		vSash.setBounds(

+			navigationBrowserBounds.width,

+			0,

+			SASH_WIDTH,

+			navigationBrowserBounds.height);

+	}

+	public boolean toggleNavigation() {

+		boolean hidden;

+		Rectangle bounds = vSash.getBounds();

+		if (bounds.x == 0) {

+			bounds.x = lastSash;

+			hidden = false;

+		} else {

+			lastSash = bounds.x;

+			bounds.x = 0;

+			hidden = true;

+		}

+		vSash.setBounds(bounds);

+		layout();

+

+		return hidden;

+	}

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/HTMLHelpViewer.java b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/HTMLHelpViewer.java
new file mode 100644
index 0000000..cdc7887
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/HTMLHelpViewer.java
@@ -0,0 +1,135 @@
+package org.eclipse.help.internal.ui;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+

+import java.util.*;

+import java.net.*;

+import org.eclipse.swt.widgets.*;

+import org.eclipse.swt.widgets.*;

+import org.eclipse.jface.*;

+import org.eclipse.jface.viewers.*;

+import org.eclipse.jface.dialogs.MessageDialog;

+import org.eclipse.ui.help.WorkbenchHelp;

+import org.eclipse.help.internal.contributions.*;

+import org.eclipse.help.internal.HelpSystem;

+import org.eclipse.help.internal.ui.util.*;

+

+/**

+ * Help viewer based on the IE5 ActiveX component.

+ */

+public class HTMLHelpViewer implements ISelectionChangedListener {

+	private IBrowser webBrowser;

+	/**

+	 * HelpViewer constructor comment.

+	 */

+	public HTMLHelpViewer(Composite parent) throws HelpWorkbenchException {

+		super();

+		createControl(parent);

+	}

+	/**

+	 */

+	protected Control createControl(Composite parent)

+		throws HelpWorkbenchException {

+		//Object in= getInput();

+		Contribution url = null;

+		//if (in instanceof Contribution)

+		//url = (Contribution)in;

+

+		String factoryClass = "org.eclipse.help.internal.ui.win32.BrowserFactory";

+		try {

+			if (!System.getProperty("os.name").startsWith("Win"))

+				factoryClass =

+					factoryClass = "org.eclipse.help.internal.ui.motif.BrowserFactory";

+

+			Class c = Class.forName(factoryClass);

+			IBrowserFactory factory = (IBrowserFactory) c.newInstance();

+

+			// this could throw a HelpDesktopException

+			webBrowser = factory.createBrowser(parent);

+			WorkbenchHelp.setHelp(

+				webBrowser.getControl(),

+				new String[] {

+					IHelpUIConstants.BROWSER,

+					IHelpUIConstants.EMBEDDED_HELP_VIEW});

+

+			return webBrowser.getControl();

+		} catch (HelpWorkbenchException e) {

+			// delegate to calling class

+			throw e;

+

+		} catch (Exception e) {

+			// worst case scenario. Should never be here!

+			throw new HelpWorkbenchException(e.getLocalizedMessage());

+

+		}

+	}

+	public Control getControl() {

+		if (webBrowser != null)

+			return webBrowser.getControl();

+		else

+			return null;

+	}

+	/**

+	 * @return org.eclipse.help.internal.ui.IBrowser

+	 */

+	public IBrowser getWebBrowser() {

+		return webBrowser;

+	}

+	/**

+	 * @private

+	 */

+	protected void navigate(Object input) {

+		if (input == null || webBrowser == null)

+			return;

+		if (input instanceof Topic) {

+			Topic topicElement = (Topic) input;

+			String url = topicElement.getHref();

+			if (url == null || url.equals(""))

+				return; // no content in this topic

+			if (url.indexOf("?resultof=") != -1) {

+				Locale locale = Locale.getDefault();

+				url = url.concat("&lang=") + locale.getDefault().toString();

+			} else {

+				Locale locale = Locale.getDefault();

+				url = url.concat("?lang=") + locale.getDefault().toString();

+			}

+			if (url.indexOf("http:") == -1) {

+				try {

+					url = (new URL(HelpSystem.getLocalHelpServerURL(), url)).toExternalForm();

+				} catch (MalformedURLException mue) {

+				}

+			}

+			webBrowser.navigate(url);

+		} else

+			if (input instanceof InfoSet) {

+				InfoSet infoset = (InfoSet) input;

+				String url = infoset.getHref();

+				if (url == null || url.equals(""))

+					return; // no content in this topic

+				Locale locale = Locale.getDefault();

+				url = url.concat("?lang=") + locale.getDefault().toString();

+				if (url.indexOf("http:") == -1) {

+					try {

+						url = (new URL(HelpSystem.getLocalHelpServerURL(), url)).toExternalForm();

+					} catch (MalformedURLException mue) {

+					}

+				}

+				webBrowser.navigate(url);

+			}

+	}

+	/**

+	 * Notifies that the selection has changed.

+	 *

+	 * @param event event object describing the change

+	 */

+	public void selectionChanged(SelectionChangedEvent event) {

+		ISelection selection = event.getSelection();

+		if (selection instanceof IStructuredSelection) {

+			navigate(((IStructuredSelection) selection).getFirstElement());

+		}

+	}

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/HelpActionSet.java b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/HelpActionSet.java
new file mode 100644
index 0000000..72f9fd6
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/HelpActionSet.java
@@ -0,0 +1,84 @@
+package org.eclipse.help.internal.ui;

+

+import java.util.*;

+import org.eclipse.jface.*;

+import org.eclipse.jface.preference.*;

+import org.eclipse.jface.action.*;

+import org.eclipse.ui.*;

+import org.eclipse.ui.internal.dialogs.*;

+import org.eclipse.ui.actions.*;

+import org.eclipse.core.resources.*;

+import org.eclipse.help.internal.contributors.*;

+import org.eclipse.help.internal.contributions.InfoSet;

+import org.eclipse.help.internal.HelpSystem;

+

+/**

+ * An action set for help.

+ */

+public class HelpActionSet //implements IActionSet

+

+{

+	private IWorkbenchWindow window;

+	private IActionBars bars;

+	private ShowHelp showHelpAction;

+	private ArrayList helpActions;

+	/**

+	 * ResourceActionSet constructor comment.

+	 */

+	public HelpActionSet() {

+		super();

+	}

+	/**

+	 * Create the actions for this set.

+	 */

+	protected void createActions() {

+		/*

+		Iterator infosets = HelpSystem

+					.getInstance()

+					.getContributionManager()

+					.getContributionsOfType(ViewContributor.INFOSET_ELEM);

+		

+		helpActions = new ArrayList();

+		while(infosets.hasNext())

+		{

+			InfoSet infoset = (InfoSet)infosets.next();

+			ShowHelp action = new ShowHelp(infoset);

+			helpActions.add(action);

+		}

+		

+		// Add a test context action, Help on Help

+		helpActions.add(new ContextHelpAction());

+		

+		// Add Help menu actions.

+		IMenuManager helpMenuManager = bars.getMenuManager().findMenuUsingPath(IWorkbenchActionConstants.M_HELP);

+		for (Iterator actions=helpActions.iterator(); actions.hasNext(); )

+			helpMenuManager.appendToGroup(IWorkbenchActionConstants.HELP_START, (Action)actions.next());

+		bars.updateActionBars();

+		*/

+	}

+	/**

+	 * Disposes of this action set.

+	 * <p>

+	 * Implementation should remove any references to the window and action bars 

+	 * created in the <code>init</code>.

+	 * </p>

+	 * <p>

+	 * [Issue: Should this say: "...should remove anything they contributed

+	 *  in <code>init</code>? Or is most of the withdrawal done automatically?

+	 * ]

+	 * </p>

+	 */

+	public void dispose() {

+	}

+	/**

+	 * Adds actions to the page action bars.

+	 */

+	public void init(IWorkbenchWindow window, IActionBars bars) {

+		// Save state for dispose.

+		this.window = window;

+		this.bars = bars;

+

+		// Add actions to the window.

+		createActions();

+	}

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/HelpPerspective.java b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/HelpPerspective.java
new file mode 100644
index 0000000..16e0940
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/HelpPerspective.java
@@ -0,0 +1,38 @@
+package org.eclipse.help.internal.ui;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+

+import org.eclipse.ui.*;

+import org.eclipse.ui.part.*;

+import org.eclipse.core.runtime.*;

+

+/**

+ * Perspective for holding the help view

+ */

+public class HelpPerspective implements IPerspectiveFactory {

+	public static final String ID = "org.eclipse.help.internal.ui.HelpPerspective";

+

+	/**

+	 * Defines the initial layout for a perspective.

+	 * This method is only called when a new perspective is created.  If

+	 * an old perspective is restored from a persistence file then

+	 * this method is not called.

+	 *

+	 * @param factory the factory used to add views to the perspective

+	 */

+	public void createInitialLayout(IPageLayout layout) {

+		String editorArea = layout.getEditorArea();

+		layout.addView(EmbeddedHelpView.ID, IPageLayout.TOP, 0.50f, editorArea);

+		layout.setEditorAreaVisible(false);

+	}

+	/**

+	 * Returns the visible set of action bars for a perspective.

+	 */

+	public String[] getVisibleActionSets() {

+		return new String[0];

+	}

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/HyperlinkAdapter.java b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/HyperlinkAdapter.java
new file mode 100644
index 0000000..dcfe247
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/HyperlinkAdapter.java
@@ -0,0 +1,33 @@
+package org.eclipse.help.internal.ui;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+

+import org.eclipse.swt.widgets.*;

+

+public class HyperlinkAdapter implements IHyperlinkListener {

+	/**

+	 * HyperlinkAdapter constructor comment.

+	 */

+	public HyperlinkAdapter() {

+		super();

+	}

+	/**

+	 * @param linkLabel org.eclipse.swt.widgets.Label

+	 */

+	public void linkActivated(Control linkLabel) {

+	}

+	/**

+	 * @param linkLabel org.eclipse.swt.widgets.Label

+	 */

+	public void linkEntered(Control linkLabel) {

+	}

+	/**

+	 * @param linkLabel org.eclipse.swt.widgets.Label

+	 */

+	public void linkExited(Control linkLabel) {

+	}

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/HyperlinkHandler.java b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/HyperlinkHandler.java
new file mode 100644
index 0000000..b800d8f
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/HyperlinkHandler.java
@@ -0,0 +1,240 @@
+package org.eclipse.help.internal.ui;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+

+import java.util.*;

+import org.eclipse.swt.widgets.*;

+import org.eclipse.swt.events.*;

+import org.eclipse.swt.graphics.*;

+import org.eclipse.swt.*;

+

+public class HyperlinkHandler

+	implements MouseListener, MouseTrackListener, PaintListener {

+	public static final int UNDERLINE_NEVER = 1;

+	public static final int UNDERLINE_ROLLOVER = 2;

+	public static final int UNDERLINE_ALWAYS = 3;

+

+	private Cursor hyperlinkCursor;

+	private Cursor busyCursor;

+	private boolean hyperlinkCursorUsed = true;

+	private int hyperlinkUnderlineMode = UNDERLINE_ALWAYS;

+	private Color background;

+	private Color foreground;

+	private Color activeBackground;

+	private Color activeForeground;

+	private Hashtable hyperlinkListeners;

+	private Control lastLink;

+	/**

+	 * HyperlinkHandler constructor comment.

+	 */

+	public HyperlinkHandler() {

+		hyperlinkListeners = new Hashtable();

+		hyperlinkCursor = new Cursor(Display.getCurrent(), SWT.CURSOR_HAND);

+		busyCursor = new Cursor(Display.getCurrent(), SWT.CURSOR_WAIT);

+	}

+	/**

+	 */

+	public void dispose() {

+		hyperlinkCursor.dispose();

+		busyCursor.dispose();

+	}

+	/**

+	 * @return org.eclipse.swt.graphics.Color

+	 */

+	public Color getActiveBackground() {

+		return activeBackground;

+	}

+	/**

+	 * @return org.eclipse.swt.graphics.Color

+	 */

+	public Color getActiveForeground() {

+		return activeForeground;

+	}

+	/**

+	 * @return org.eclipse.swt.graphics.Color

+	 */

+	public Color getBackground() {

+		return background;

+	}

+	/**

+	 * @return org.eclipse.swt.graphics.Cursor

+	 */

+	public Cursor getBusyCursor() {

+		return busyCursor;

+	}

+	/**

+	 * @return org.eclipse.swt.graphics.Color

+	 */

+	public Color getForeground() {

+		return foreground;

+	}

+	/**

+	 * @return org.eclipse.swt.graphics.Cursor

+	 */

+	public Cursor getHyperlinkCursor() {

+		return hyperlinkCursor;

+	}

+	/**

+	 * @return int

+	 */

+	public int getHyperlinkUnderlineMode() {

+		return hyperlinkUnderlineMode;

+	}

+	/**

+	 * @return org.eclipse.swt.widgets.Control

+	 */

+	public Control getLastLink() {

+		return lastLink;

+	}

+	/**

+	 * @return boolean

+	 */

+	public boolean isHyperlinkCursorUsed() {

+		return hyperlinkCursorUsed;

+	}

+	public void mouseDoubleClick(MouseEvent e) {

+	}

+	public void mouseDown(MouseEvent e) {

+		if (e.button == 1)

+			return;

+		lastLink = (Control) e.widget;

+	}

+	public void mouseEnter(MouseEvent e) {

+		Control control = (Control) e.widget;

+		if (isHyperlinkCursorUsed())

+			control.setCursor(hyperlinkCursor);

+		if (activeBackground != null)

+			control.setBackground(activeBackground);

+		if (activeForeground != null)

+			control.setForeground(activeForeground);

+		if (hyperlinkUnderlineMode == UNDERLINE_ROLLOVER)

+			underline(control, true);

+

+		IHyperlinkListener action =

+			(IHyperlinkListener) hyperlinkListeners.get(control);

+		if (action != null)

+			action.linkEntered(control);

+	}

+	public void mouseExit(MouseEvent e) {

+		Control control = (Control) e.widget;

+		if (isHyperlinkCursorUsed())

+			control.setCursor(null);

+		if (hyperlinkUnderlineMode == UNDERLINE_ROLLOVER)

+			underline(control, false);

+		if (background != null)

+			control.setBackground(background);

+		if (foreground != null)

+			control.setForeground(foreground);

+		IHyperlinkListener action =

+			(IHyperlinkListener) hyperlinkListeners.get(control);

+		if (action != null)

+			action.linkExited(control);

+	}

+	public void mouseHover(MouseEvent e) {

+	}

+	public void mouseUp(MouseEvent e) {

+		if (e.button != 1)

+			return;

+		IHyperlinkListener action =

+			(IHyperlinkListener) hyperlinkListeners.get(e.widget);

+		if (action != null) {

+			Control c = (Control) e.widget;

+			c.setCursor(busyCursor);

+			action.linkActivated(c);

+			if (!c.isDisposed())

+				c.setCursor(isHyperlinkCursorUsed() ? hyperlinkCursor : null);

+		}

+	}

+	public void paintControl(PaintEvent e) {

+		Control label = (Control) e.widget;

+		if (hyperlinkUnderlineMode == UNDERLINE_ALWAYS)

+			HyperlinkHandler.underline(label, true);

+	}

+	/**

+	 * @param control org.eclipse.swt.widgets.Control

+	 * @param listener com.ibm.pde.internal.forms.IHyperlinkListener

+	 */

+	public void registerHyperlink(Control control, IHyperlinkListener listener) {

+		if (background != null)

+			control.setBackground(background);

+		if (foreground != null)

+			control.setForeground(foreground);

+		control.addMouseListener(this);

+		control.addMouseTrackListener(this);

+		if (hyperlinkUnderlineMode == UNDERLINE_ALWAYS)

+			control.addPaintListener(this);

+		hyperlinkListeners.put(control, listener);

+		removeDisposedLinks();

+	}

+	private void removeDisposedLinks() {

+		for (Enumeration keys = hyperlinkListeners.keys(); keys.hasMoreElements();) {

+			Control control = (Control) keys.nextElement();

+			if (control.isDisposed()) {

+				hyperlinkListeners.remove(control);

+			}

+		}

+	}

+	/**

+	 */

+	public void reset() {

+		hyperlinkListeners.clear();

+	}

+	/**

+	 * @param newActiveBackground org.eclipse.swt.graphics.Color

+	 */

+	public void setActiveBackground(

+		Color newActiveBackground) {

+		activeBackground = newActiveBackground;

+	}

+	/**

+	 * @param newActiveForeground org.eclipse.swt.graphics.Color

+	 */

+	public void setActiveForeground(

+		Color newActiveForeground) {

+		activeForeground = newActiveForeground;

+	}

+	/**

+	 * @param newBackground org.eclipse.swt.graphics.Color

+	 */

+	public void setBackground(Color newBackground) {

+		background = newBackground;

+	}

+	/**

+	 * @param newForeground org.eclipse.swt.graphics.Color

+	 */

+	public void setForeground(Color newForeground) {

+		foreground = newForeground;

+	}

+	/**

+	 * @param newHyperlinkCursorUsed boolean

+	 */

+	public void setHyperlinkCursorUsed(boolean newHyperlinkCursorUsed) {

+		hyperlinkCursorUsed = newHyperlinkCursorUsed;

+	}

+	/**

+	 * @param newHyperlinkUnderlineMode int

+	 */

+	public void setHyperlinkUnderlineMode(int newHyperlinkUnderlineMode) {

+		hyperlinkUnderlineMode = newHyperlinkUnderlineMode;

+	}

+	/**

+	 * @param control org.eclipse.swt.widgets.Control

+	 * @param inside boolean

+	 */

+	public static void underline(Control control, boolean inside) {

+		if (!(control instanceof Label))

+			return;

+		Composite parent = control.getParent();

+		Rectangle bounds = control.getBounds();

+		GC gc = new GC(parent);

+		Color color = inside ? control.getForeground() : control.getBackground();

+		gc.setForeground(color);

+		int y = bounds.y + bounds.height;

+		gc.drawLine(bounds.x, y, bounds.x + bounds.width, y);

+		gc.dispose();

+	}

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/IBrowser.java b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/IBrowser.java
new file mode 100644
index 0000000..256dce5
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/IBrowser.java
@@ -0,0 +1,35 @@
+package org.eclipse.help.internal.ui;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+

+import org.eclipse.swt.widgets.Control;

+import org.eclipse.help.internal.contributions.Topic;

+

+/**

+ * Help browser

+ */

+public interface IBrowser {

+

+	public int back();

+	public int copy();

+	public int forward();

+	/**

+	 * Returns the actual control object

+	 */

+	public Control getControl();

+	public String getLocationURL();

+	public int home();

+	/**

+	 * Navigate to the specified URL

+	 */

+	public int navigate(String url);

+	public void print();

+	/**

+	 * Print a Topic and all it's children.

+	 */

+	public void printFullTopic(Topic rootTopic);

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/IBrowserFactory.java b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/IBrowserFactory.java
new file mode 100644
index 0000000..0040b05
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/IBrowserFactory.java
@@ -0,0 +1,20 @@
+package org.eclipse.help.internal.ui;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+

+import org.eclipse.swt.widgets.Composite;

+import org.eclipse.help.internal.ui.util.HelpWorkbenchException;

+

+/**

+ * Factory for creating a help browser

+ */

+public interface IBrowserFactory {

+	/**

+	 * Creates a browser control instance

+	 */

+	public IBrowser createBrowser(Composite parent) throws HelpWorkbenchException;

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/IHelpUIConstants.java b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/IHelpUIConstants.java
new file mode 100644
index 0000000..d9f5bd2
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/IHelpUIConstants.java
@@ -0,0 +1,42 @@
+package org.eclipse.help.internal.ui;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+

+import java.lang.*;

+

+/**

+ * Interface for holding UI constants

+ */

+

+public interface IHelpUIConstants {

+

+	// Help UI pluging id with a "." for convenience.

+	public static final String HELP_UI_ID = "org.eclipse.help.ui.";

+

+	// F1 ids

+	public static final String EMBEDDED_HELP_VIEW = HELP_UI_ID + "embeddedHelpView";

+	public static final String COPY_ACTION = HELP_UI_ID + "copyAction";

+	public static final String HOME_ACTION = HELP_UI_ID + "homeAction";

+	public static final String BACK_ACTION = HELP_UI_ID + "backAction";

+	public static final String FORWARD_ACTION = HELP_UI_ID + "forwardAction";

+	public static final String PRINT_ACTION = HELP_UI_ID + "printAction";

+	public static final String SYNCH_ACTION = HELP_UI_ID + "synchronizeAction";

+	public static final String SHOW_HIDE_ACTION = HELP_UI_ID + "showHideAction";

+	public static final String F1_SHELL = HELP_UI_ID + "f1Shell";

+	public static final String PREF_PAGE = HELP_UI_ID + "prefPage";

+	public static final String INSTALL_OPTIONS = HELP_UI_ID + "installOptions";

+	public static final String BROWSER_PATH = HELP_UI_ID + "browserPath";

+	public static final String LOGGING_OPTIONS = HELP_UI_ID + "loggingOptions";

+	public static final String LOCAL_SERVER_CONFIG =

+		HELP_UI_ID + "localServerConfig";

+	public static final String BROWSER = HELP_UI_ID + "browser";

+	public static final String NAVIGATION_VIEWER = HELP_UI_ID + "navigationViewer";

+	public static final String SEARCH_PAGE = HELP_UI_ID + "searchPage";

+	public static final String TOPICS_VIEWER = HELP_UI_ID + "topicsViewer";

+	public static final String RESULTS_VIEWER = HELP_UI_ID + "resultsViewer";

+

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/IHyperlinkListener.java b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/IHyperlinkListener.java
new file mode 100644
index 0000000..b7068b8
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/IHyperlinkListener.java
@@ -0,0 +1,28 @@
+package org.eclipse.help.internal.ui;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+

+import org.eclipse.swt.widgets.*;

+import org.eclipse.swt.widgets.Label;

+

+/**

+ * 

+ */

+public interface IHyperlinkListener {

+	/**

+	 * @param linkLabel org.eclipse.swt.widgets.Label

+	 */

+	public void linkActivated(Control linkLabel);

+	/**

+	 * @param linkLabel org.eclipse.swt.widgets.Label

+	 */

+	public void linkEntered(Control linkLabel);

+	/**

+	 * @param linkLabel org.eclipse.swt.widgets.Label

+	 */

+	public void linkExited(Control linkLabel);

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/InfopopText.java b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/InfopopText.java
new file mode 100644
index 0000000..aea2da4
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/InfopopText.java
@@ -0,0 +1,355 @@
+package org.eclipse.help.internal.ui;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+

+import java.text.*;

+import java.util.*;

+import org.eclipse.swt.*;

+import org.eclipse.swt.graphics.*;

+import org.eclipse.swt.widgets.*;

+import org.eclipse.swt.events.*;

+import org.eclipse.swt.custom.*;

+import org.eclipse.help.internal.ui.util.TString;

+import org.eclipse.help.internal.contributors.ContextContributor;

+

+/**

+ */

+public class InfopopText extends Canvas {

+	/** Text to display */

+	private String text;

+

+	/** Line breaker */

+	private static BreakIterator lineBreaker = BreakIterator.getLineInstance();

+	/** Lines after splitting */

+	ArrayList lines = new ArrayList(10);

+	/** Style ranges, per line */

+	ArrayList lineStyleRanges = new ArrayList(10);

+

+	/**

+	 * Constructor

+	 */

+	public InfopopText(Composite parent, int style) {

+		super(parent, style);

+

+		//setBackground();

+

+		// cleanup any resources here

+		addDisposeListener(new DisposeListener() {

+			public void widgetDisposed(DisposeEvent e) {

+				//white.dispose();

+			}

+		});

+		addPaintListener(new PaintListener() {

+			public void paintControl(PaintEvent e) {

+				InfopopText.this.paintControl(e);

+			}

+		});

+

+	}

+	/**

+	 * Adjusts the style ranges from a line that was split

+	 */

+	private void adjustStyles(int oldLineIndex) {

+		ArrayList styles = (ArrayList) lineStyleRanges.get(oldLineIndex);

+		if (styles.isEmpty())

+			lineStyleRanges.add(oldLineIndex + 1, styles);

+		else {

+			String line = (String) lines.get(oldLineIndex);

+			for (int i = 0; i < styles.size(); i++) {

+				StyleRange style = (StyleRange) styles.get(i);

+				if (style.start >= line.length()) {

+					// move all the remaining styles to the new line

+					ArrayList newStyles = new ArrayList(styles.size() - i + 1);

+					for (int j = i; j < styles.size();) {

+						StyleRange s = (StyleRange) styles.get(j);

+						styles.remove(s);

+						s.start = s.start - line.length();

+						newStyles.add(s);

+					}

+					lineStyleRanges.add(oldLineIndex + 1, newStyles);

+					return;

+				} else

+					if (style.start + style.length > line.length()) {

+						// split this style over two lines and

+						// move the remaining styles to the new line as well

+						ArrayList newStyles = new ArrayList(styles.size() - i + 1);

+						StyleRange splitRange1 =

+							new StyleRange(style.start, line.length() - style.start, null, null);

+						StyleRange splitRange2 =

+							new StyleRange(0, style.start + style.length - line.length(), null, null);

+						styles.remove(style);

+						styles.add(splitRange1);

+						newStyles.add(splitRange2);

+						for (int j = i + 1; j < styles.size();) {

+							StyleRange s = (StyleRange) styles.get(j);

+							styles.remove(s);

+							s.start = s.start - line.length();

+							newStyles.add(s);

+						}

+						lineStyleRanges.add(oldLineIndex + 1, newStyles);

+						return;

+					}

+			}

+			// all the styles were applied to the remaining of the line

+			lineStyleRanges.add(oldLineIndex + 1, new ArrayList(0));

+		}

+	}

+	private Point computeLineSize(int lineIndex, int wHint, int hHint) {

+		String line = (String) lines.get(lineIndex);

+		ArrayList styles = (ArrayList) lineStyleRanges.get(lineIndex);

+		if (styles.isEmpty())

+			return computeStringSize(line, wHint, hHint, SWT.NONE);

+

+		// Compute the styled and unstyled string sizes

+		int offset = 0;

+		StringBuffer unstyled = new StringBuffer();

+		StringBuffer styled = new StringBuffer();

+		for (Iterator iterator = styles.iterator(); iterator.hasNext();) {

+			StyleRange range = (StyleRange) iterator.next();

+			unstyled.append(line.substring(offset, range.start));

+			styled.append(line.substring(range.start, range.start + range.length));

+			offset = range.start + range.length;

+		}

+		if (offset < line.length())

+			unstyled.append(line.substring(offset));

+

+		String unstyledText = unstyled.toString();

+		String styledText = styled.toString();

+		Point unstyledSize = computeStringSize(unstyledText, wHint, hHint, SWT.NONE);

+		Point styledSize = computeStringSize(styledText, wHint, hHint, SWT.BOLD);

+

+		return new Point(

+			unstyledSize.x + styledSize.x,

+			Math.max(unstyledSize.y, styledSize.y));

+	}

+	public Point computeSize(int wHint, int hHint, boolean changed) {

+		Point[] lineSizes = new Point[lines.size()];

+		for (int i = 0; i < lineSizes.length; i++)

+			lineSizes[i] = computeLineSize(i, wHint, hHint);

+

+		int maxWidth = 0, maxHeight = 0;

+		for (int i = 0; i < lineSizes.length; i++) {

+			maxWidth = Math.max(maxWidth, lineSizes[i].x);

+			maxHeight += lineSizes[i].y;

+		}

+

+		return new Point(maxWidth + 2, maxHeight + 2);

+	}

+	private Point computeStringSize(

+		String string,

+		int wHint,

+		int hHint,

+		int style) {

+		int width = 0, height = 0;

+

+		GC gc = new GC(this);

+		Font defaultFont = gc.getFont();

+		FontData fd = gc.getFont().getFontData()[0];

+		fd.setStyle(SWT.BOLD);

+		Font boldFont = new Font(Display.getCurrent(), fd);

+

+		if (string != null) {

+			if (style == SWT.BOLD)

+				gc.setFont(boldFont);

+			Point extent = gc.stringExtent(string);

+			if (style == SWT.BOLD)

+				gc.setFont(defaultFont);

+			width += extent.x;

+			height = Math.max(height, extent.y);

+		}

+		if (wHint != SWT.DEFAULT)

+			width = wHint;

+		if (hHint != SWT.DEFAULT)

+			height = hHint;

+

+		// cleanup

+		boldFont.dispose();

+		gc.dispose();

+

+		return new Point(width, height);

+	}

+	private static int getLineBreak(String line) {

+		int max = getMaxLineChars();

+		lineBreaker.setText(line);

+		int lastGoodIndex = 0;

+		int currentIndex = lineBreaker.first();

+		while (currentIndex < max && currentIndex != BreakIterator.DONE) {

+			lastGoodIndex = currentIndex;

+			currentIndex = lineBreaker.next();

+		}

+

+		return lastGoodIndex;

+	}

+	/**

+	 * Returns the maximum number of characters on a line

+	 */

+	private static int getMaxLineChars() {

+		return 72;

+	}

+	/**

+	 * Returns the styles ranges from the text.

+	 * Ranges are relative to the stripped text.

+	 */

+	private static ArrayList getStyleRanges(String styledText) {

+		ArrayList styles = new ArrayList(4);

+

+		int offset = 0;

+		int adjustment = 0;

+		int tagLength = ContextContributor.BOLD_TAG.length();

+		int tagEndLength = ContextContributor.BOLD_CLOSE_TAG.length();

+

+		while (offset < styledText.length()) {

+			int begin = styledText.indexOf(ContextContributor.BOLD_TAG, offset);

+			if (begin == -1) {

+				int end =

+					styledText.indexOf(ContextContributor.BOLD_CLOSE_TAG, offset + tagLength);

+				if (end == -1) {

+					break; // no tags left in the string    

+				} else {

+					//.... text ... </b> ....

+					StyleRange range =

+						new StyleRange(offset - adjustment, end - offset, null, null, SWT.BOLD);

+					styles.add(range);

+					offset = end + tagEndLength;

+					adjustment += tagEndLength;

+				}

+			} else {

+				int end =

+					styledText.indexOf(ContextContributor.BOLD_CLOSE_TAG, offset + tagLength);

+				if (end == -1) {

+					// .... text <b> ... [EOS]

+					StyleRange range =

+						new StyleRange(

+							offset + tagLength - adjustment,

+							styledText.length() - offset - tagLength,

+							null,

+							null,

+							SWT.BOLD);

+					styles.add(range);

+					break; // no tags left in the string    

+				} else {

+					//.... text ..<b> .. text.. </b> ....

+					StyleRange range =

+						new StyleRange(

+							begin - adjustment,

+							end - begin - tagLength,

+							null,

+							null,

+							SWT.BOLD);

+					styles.add(range);

+					offset = end + tagEndLength;

+					adjustment += tagLength + tagEndLength;

+				}

+			}

+		}

+		return styles;

+	}

+	public String getText() {

+		return text;

+	}

+	/**

+	 * Returns the text without the style

+	 */

+	private static String getUnstyledText(String styledText) {

+		String s = TString.change(styledText, ContextContributor.BOLD_TAG, "");

+		s = TString.change(s, ContextContributor.BOLD_CLOSE_TAG, "");

+		s = s.trim();

+		return s;

+	}

+	/**

+	 * Paint the control when asked for.

+	 */

+	void paintControl(PaintEvent e) {

+		GC gc = e.gc;

+		if (text != null) {

+			Font defaultFont = gc.getFont();

+			FontData fd = gc.getFont().getFontData()[0];

+			fd.setStyle(SWT.BOLD);

+			Font boldFont = new Font(Display.getCurrent(), fd);

+			int fontHeight = gc.getFontMetrics().getHeight();

+

+			for (int i = 0; i < lines.size(); i++) {

+				Point lineSize = computeLineSize(i, e.width, e.height);

+				String line = (String) lines.get(i);

+				ArrayList styles = (ArrayList) lineStyleRanges.get(i);

+				if (styles.isEmpty()) {

+					gc.drawString(line, e.x, e.y + fontHeight * i);

+					continue;

+				}

+

+				// Compute the styled and unstyled string sizes

+				int offset = 0;

+				int x = 0;

+				for (Iterator iterator = styles.iterator(); iterator.hasNext();) {

+					StyleRange range = (StyleRange) iterator.next();

+					String unstyled = line.substring(offset, range.start);

+					String styled = line.substring(range.start, range.start + range.length);

+					offset = range.start + range.length;

+					gc.drawString(unstyled, e.x + x, e.y + fontHeight * i);

+					x += gc.stringExtent(unstyled).x;

+					gc.setFont(boldFont);

+					gc.drawString(styled, e.x + x, e.y + fontHeight * i);

+					x += gc.stringExtent(styled).x;

+					gc.setFont(defaultFont);

+				}

+

+				if (offset < line.length())

+					gc.drawString(line.substring(offset), x, e.y + fontHeight * i);

+			}

+

+			boldFont.dispose();

+		}

+	}

+	private void processLineBreaks(String text) {

+		// Create the original lines with style stripped

+		// and keep track of styles

+		StringTokenizer st = new StringTokenizer(text, "\r\n");

+		while (st.hasMoreTokens()) {

+			String line = st.nextToken();

+			lines.add(getUnstyledText(line));

+			lineStyleRanges.add(getStyleRanges(line));

+		}

+

+		// Break long lines

+		for (int i = 0; i < lines.size(); i++) {

+			String line = (String) lines.get(i);

+			while (line.length() > 0) {

+				int linebreak = getLineBreak(line);

+

+				if (linebreak == 0 || linebreak == line.length())

+					break;

+

+				String newline = line.substring(0, linebreak);

+				lines.remove(i);

+				lines.add(i, newline);

+				line = line.substring(linebreak);

+				lines.add(++i, line);

+				i--; // may need to split more...

+

+				adjustStyles(i);

+			}

+		}

+	}

+	/**

+	 * Set the text to display

+	 */

+	public void setText(String text) {

+		// Break long lines, and also update the style ranges

+		// if new lines have been introduced.

+		processLineBreaks(text);

+

+		StringBuffer sb = new StringBuffer();

+		Iterator it = lines.iterator();

+		if (it.hasNext())

+			sb.append((String) it.next());

+		while (it.hasNext())

+			sb.append('\n').append((String) it.next());

+		this.text = sb.toString();

+

+		redraw();

+	}

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/NavigationPage.java b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/NavigationPage.java
new file mode 100644
index 0000000..5aa4dec
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/NavigationPage.java
@@ -0,0 +1,49 @@
+package org.eclipse.help.internal.ui;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+

+import org.eclipse.jface.viewers.*;

+import org.eclipse.swt.widgets.*;

+import org.eclipse.swt.*;

+import org.eclipse.swt.custom.CTabFolder;

+import org.eclipse.swt.custom.CTabItem;

+

+/**

+ * Base page class for topics and search pages

+ */

+public abstract class NavigationPage implements ISelectionProvider {

+	private NavigationWorkbook workbook;

+	private CTabItem tabItem;

+

+	public NavigationPage(NavigationWorkbook workbook, String label) {

+		super();

+		this.workbook = workbook;

+		tabItem = new CTabItem(workbook.getTabFolder(), SWT.NONE);

+		tabItem.setData(this);

+		tabItem.setText(label);

+		tabItem.setToolTipText(label);

+	}

+	public void activate() {

+		if (tabItem.getControl() == null)

+			tabItem.setControl(createControl(tabItem.getParent()));

+	}

+	protected abstract Control createControl(Composite parent);

+	public boolean deactivate() {

+		return true;

+	}

+	public void dispose() {

+		if (tabItem == null)

+			return;

+

+		CTabItem oldItem = tabItem;

+		tabItem = null;

+		oldItem.dispose();

+	}

+	protected CTabItem getTabItem() {

+		return tabItem;

+	}

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/NavigationViewer.java b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/NavigationViewer.java
new file mode 100644
index 0000000..f855322
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/NavigationViewer.java
@@ -0,0 +1,180 @@
+package org.eclipse.help.internal.ui;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+

+import java.util.*;

+import org.eclipse.jface.viewers.*;

+import org.eclipse.swt.graphics.*;

+import org.eclipse.swt.*;

+import org.eclipse.swt.widgets.*;

+import org.eclipse.swt.layout.*;

+import org.eclipse.swt.events.*;

+import org.eclipse.ui.help.WorkbenchHelp;

+import org.eclipse.help.internal.contributions.InfoSet;

+import org.eclipse.help.internal.navigation.*;

+import org.eclipse.help.internal.contributors.*;

+import org.eclipse.help.internal.HelpSystem;

+

+/**

+ * Navigation Viewer.  Contains combo for InfoSet selection and Workbook for display

+ * of views.

+ */

+public class NavigationViewer implements ISelectionProvider {

+	private Composite contents;

+	private NavigationWorkbook workbook;

+

+	private ArrayList infoSetIds;

+	private Combo infoSetsCombo;

+

+	private InfoSet currentInfoset;

+

+	/**

+	 * NavigationViewer constructor comment.

+	 */

+	public NavigationViewer(Composite parent) {

+		super();

+

+		// Create a list of available Info Sets

+		infoSetIds = new ArrayList();

+		ContributionManager cmgr = HelpSystem.getContributionManager();

+		Iterator infoSetContributors =

+			cmgr.getContributionsOfType(ViewContributor.INFOSET_ELEM);

+		while (infoSetContributors.hasNext()) {

+			String infoSet = ((InfoSet) infoSetContributors.next()).getID();

+			if (infoSet != null)

+				infoSetIds.add(infoSet);

+		}

+

+		createControl(parent);

+	}

+	public void addSelectionChangedListener(ISelectionChangedListener listener) {

+		workbook.addSelectionChangedListener(listener);

+	}

+	/**

+	 */

+	protected Control createControl(Composite parent) {

+		contents = new Composite(parent, SWT.NONE);

+

+		GridLayout layout = new GridLayout();

+		layout.numColumns = 1;

+		layout.verticalSpacing = 5;

+		layout.marginHeight = 0;

+		layout.marginWidth = 0;

+		contents.setLayout(layout);

+		contents.setLayoutData(new GridData(GridData.FILL_BOTH));

+

+		GridData gd = new GridData();

+		gd.horizontalAlignment = gd.FILL;

+		gd.grabExcessHorizontalSpace = true;

+		gd.verticalAlignment = gd.BEGINNING;

+		gd.grabExcessVerticalSpace = false;

+

+		// Create combo for selection of Info Sets

+		if (infoSetIds.size() > 1) {

+			infoSetsCombo =

+				new Combo(contents, SWT.DROP_DOWN | SWT.READ_ONLY /*| SWT.FLAT*/);

+			infoSetsCombo.setLayoutData(gd);

+			infoSetsCombo.setBackground(

+				Display.getCurrent().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));

+

+			HelpNavigationManager navManager = HelpSystem.getNavigationManager();

+			for (int i = 0; i < infoSetIds.size(); i++) {

+				infoSetsCombo.add(navManager.getInfoSet((String) infoSetIds.get(i)).getLabel());

+			}

+			infoSetsCombo.addSelectionListener(new SelectionListener() {

+				public void widgetSelected(SelectionEvent e) {

+					int index = ((Combo) e.widget).getSelectionIndex();

+					String id = (String) infoSetIds.get(index);

+					currentInfoset = HelpSystem.getNavigationManager().getInfoSet(id);

+					setInput(currentInfoset);

+				}

+				public void widgetDefaultSelected(SelectionEvent e) {

+					widgetSelected(e);

+				}

+			});

+		}

+

+		gd = new GridData();

+		gd.horizontalAlignment = gd.FILL;

+		gd.grabExcessHorizontalSpace = true;

+		gd.verticalAlignment = gd.FILL;

+		gd.grabExcessVerticalSpace = true;

+

+		workbook = new NavigationWorkbook(contents);

+		workbook.getControl().setLayoutData(gd);

+

+		WorkbenchHelp.setHelp(

+			contents,

+			new String[] {

+				IHelpUIConstants.NAVIGATION_VIEWER,

+				IHelpUIConstants.EMBEDDED_HELP_VIEW});

+		return contents;

+	}

+	public Control getControl() {

+		return contents;

+	}

+	public Object getInput() {

+		return currentInfoset;

+	}

+	/**

+	 * Returns the current selection for this provider.

+	 * 

+	 * @return the current selection

+	 */

+	public ISelection getSelection() {

+		return workbook.getSelection();

+	}

+	/**

+	 * Removes the given selection change listener from this selection provider.

+	 * Has no affect if an identical listener is not registered.

+	 *

+	 * @param listener a selection changed listener

+	 */

+	public void removeSelectionChangedListener(ISelectionChangedListener listener) {

+		workbook.removeSelectionChangedListener(listener);

+	}

+	/**

+	 * @param input an InfoSet or Contribution[]

+	 *  if Infoset, then Pages will be created containing trees representations

+	 *   of Infoset's children (InfoViews)

+	 *  If Array of Contribution, the elements can be either InfoView or InfoSet.

+	 *   Pages will be created containing trees representations

+	 *   of InfoView element and each of Infoset's children (InfoViews)

+	 */

+	public void setInput(Object input) {

+		if (input instanceof InfoSet) {

+			currentInfoset = (InfoSet) input;

+			// If more than 1 infoset, then select it from the combo box

+			if (infoSetIds.size() > 1) {

+				int index = infoSetIds.indexOf(currentInfoset.getID());

+				if (index != -1)

+					infoSetsCombo.select(index);

+

+				// remove selection, so it is gray not blue;

+				infoSetsCombo.clearSelection();

+			}

+

+			// set global infoset and navigation model

+			HelpSystem.getNavigationManager().setCurrentInfoSet(currentInfoset.getID());

+

+			// show this infoset    

+			workbook.display(currentInfoset);

+

+			// update htmlViewer

+			setSelection(new StructuredSelection(currentInfoset));

+		}

+		workbook.display(input);

+	}

+	/**

+	 * Sets the selection current selection for this selection provider.

+	 *

+	 * @param selection the new selection

+	 */

+	public void setSelection(ISelection selection) {

+		workbook.setSelection(selection);

+	}

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/NavigationWorkbook.java b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/NavigationWorkbook.java
new file mode 100644
index 0000000..b4959ef
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/NavigationWorkbook.java
@@ -0,0 +1,224 @@
+package org.eclipse.help.internal.ui;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+

+import java.util.*;

+import org.eclipse.swt.*;

+import org.eclipse.swt.widgets.*;

+import org.eclipse.jface.viewers.*;

+import org.eclipse.swt.events.*;

+import org.eclipse.swt.custom.CTabFolder;

+import org.eclipse.swt.custom.CTabItem;

+import org.eclipse.help.internal.contributions.*;

+import org.eclipse.help.internal.ui.search.SearchPage;

+import org.eclipse.help.internal.*;

+

+/**

+ * Navigation workbook.

+ */

+public class NavigationWorkbook implements ISelectionProvider {

+

+	private CTabItem selectedTab;

+	private CTabFolder tabFolder;

+	private Collection selectionChangedListeners = new ArrayList();

+

+	/**

+	 * NavigationWorkbook constructor.

+	 */

+	public NavigationWorkbook(Composite parent) {

+		tabFolder = new CTabFolder(parent, SWT.FLAT | SWT.SMOOTH | SWT.BOTTOM);

+		tabFolder.addSelectionListener(new SelectionAdapter() {

+			public void widgetSelected(SelectionEvent event) {

+				CTabItem newSelectedTab = (CTabItem) event.item;

+				if (selectedTab == newSelectedTab)

+					// Do nothing if the selection did not change.

+					return;

+				if (selectedTab != null && (!selectedTab.isDisposed())) {

+					NavigationPage selectedPage = getPage(selectedTab);

+					if (!selectedPage.deactivate()) {

+						tabFolder.setSelection(selectedTab);

+						return;

+					}

+				}

+				selectedTab = newSelectedTab;

+				NavigationPage newSelectedPage = getPage(newSelectedTab);

+				if (newSelectedPage != null)

+					newSelectedPage.activate();

+			}

+		});

+	}

+	/**

+	 * Adds a listener for selection changes in this selection provider.

+	 * Has no effect if an identical listener is already registered.

+	 *

+	 * @param listener a selection changed listener

+	 */

+	public void addSelectionChangedListener(ISelectionChangedListener listener) {

+		addSelectionChangedListenersToPages();

+		// due to pages being created and destroyed dynamically, we need to store listeners

+		// and register to newly created pages later

+		selectionChangedListeners.add(listener);

+	}

+	/**

+	 * Registers all listeners of this object to each page

+	 */

+	private void addSelectionChangedListenersToPages() {

+		NavigationPage[] pages = getPages();

+		for (int i = 0; i < pages.length; i++) {

+			for (Iterator it = selectionChangedListeners.iterator(); it.hasNext();) {

+				pages[i].addSelectionChangedListener((ISelectionChangedListener) it.next());

+			}

+		}

+	}

+	/**

+	 * @param input an InfoSet or Contribution[]

+	 *  if Infoset, then Pages will be created containing trees representations

+	 *   of Infoset's children (InfoViews)

+	 *  If Array of Contribution, the elements can be either InfoView or InfoSet.

+	 *   Pages will be created containing trees representations

+	 *   of InfoView element and each of Infoset's children (InfoViews)

+	 */

+	public void display(Object input) {

+		Iterator views = null;

+

+		if (input instanceof InfoSet) {

+			views = ((InfoSet) input).getChildren();

+

+			removeAllPages();

+

+			while (views.hasNext())

+				new TopicsPage(this, views.next());

+			if (HelpSystem.getSearchManager() != null)

+				new SearchPage(this);

+

+			addSelectionChangedListenersToPages();

+			setSelectedPage(getPages()[0]);

+		} else

+			if (input instanceof Contribution[]) {

+				removeAllPages();

+

+				for (int i = 0; i < ((Contribution[]) input).length; i++) {

+					if (((Contribution[]) input)[i] instanceof InfoSet) {

+						views = ((InfoSet) ((Contribution[]) input)[i]).getChildren();

+						while (views.hasNext())

+							new TopicsPage(this, views.next());

+						if (HelpSystem.getSearchManager() != null)

+							new SearchPage(this);

+					} else

+						if (((Contribution[]) input)[i] instanceof InfoView) {

+							new TopicsPage(this, ((Contribution[]) input)[i]);

+						}

+				}

+				addSelectionChangedListenersToPages();

+				setSelectedPage(getPages()[0]);

+			}

+		return;

+	}

+	public Control getControl() {

+		return tabFolder;

+	}

+	private NavigationPage getPage(CTabItem item) {

+

+		try {

+			return (NavigationPage) item.getData();

+		} catch (ClassCastException e) {

+			return null;

+		}

+	}

+	private NavigationPage[] getPages() {

+

+		CTabItem[] tabItems = tabFolder.getItems();

+		int nItems = tabItems.length;

+		NavigationPage[] pages = new NavigationPage[nItems];

+		for (int i = 0; i < nItems; i++)

+			pages[i] = getPage(tabItems[i]);

+		return pages;

+	}

+	private NavigationPage getSelectedPage() {

+

+		int index = tabFolder.getSelectionIndex();

+		if (index == -1)

+			return null;

+

+		CTabItem selectedItem = tabFolder.getItem(index);

+

+		return (NavigationPage) selectedItem.getData();

+	}

+	/**

+	 * Returns the current selection for this provider.

+	 * 

+	 * @return the current selection

+	 */

+	public ISelection getSelection() {

+		NavigationPage[] pages = getPages();

+		for (int i = 0; i < pages.length; i++) {

+			NavigationPage aPage = (NavigationPage) pages[i];

+			if ((aPage.getSelection() != null) && !aPage.getSelection().isEmpty())

+				return aPage.getSelection();

+		}

+		return new StructuredSelection();

+	}

+	protected CTabFolder getTabFolder() {

+

+		return tabFolder;

+

+	}

+	private void removeAllPages() {

+		NavigationPage[] pages = getPages();

+		for (int i = 0; i < pages.length; i++)

+			pages[i].dispose();

+	}

+	/**

+	 * Removes the given selection change listener from this selection provider.

+	 * Has no affect if an identical listener is not registered.

+	 *

+	 * @param listener a selection changed listener

+	 */

+	public void removeSelectionChangedListener(ISelectionChangedListener listener) {

+		NavigationPage[] pages = getPages();

+		for (int i = 0; i < pages.length; i++) {

+			for (Iterator it = selectionChangedListeners.iterator(); it.hasNext();) {

+				pages[i].removeSelectionChangedListener((ISelectionChangedListener) it.next());

+			}

+		}

+		// do not add this listener to newly created listener anymore

+		selectionChangedListeners.remove(listener);

+	}

+	protected void setSelectedPage(NavigationPage page) {

+		CTabItem newSelectedTab = page.getTabItem();

+		// ****************

+		// THIS IS COMMENTED OUT IN DRIVER 039.

+		// NEED TO INVESTIGATE IF IT IS NEEDED

+		/////if (selectedTab == newSelectedTab)

+		/////   return;

+		selectedTab = newSelectedTab;

+		page.activate();

+		tabFolder.setSelection(newSelectedTab);

+	}

+	/**

+	 * Sets the selection current selection for this selection provider.

+	 *

+	 * @param selection the new selection

+	 */

+	public void setSelection(ISelection selection) {

+		// if selection contains infoset htmlviewer may need be updated

+		if (selection instanceof IStructuredSelection) {

+			Object o = ((IStructuredSelection) selection).getFirstElement();

+			if (o != null && o instanceof InfoSet)

+				for (Iterator it = selectionChangedListeners.iterator(); it.hasNext();) {

+					((ISelectionChangedListener) it.next()).selectionChanged(

+						new SelectionChangedEvent(this, selection));

+				}

+		}

+		// inform navigation pages

+		NavigationPage[] pages = getPages();

+		for (int i = 0; i < pages.length; i++) {

+			NavigationPage aPage = (NavigationPage) pages[i];

+			aPage.setSelection(selection);

+		}

+	}

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/NestedPrintAction.java b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/NestedPrintAction.java
new file mode 100644
index 0000000..83ad588
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/NestedPrintAction.java
@@ -0,0 +1,110 @@
+package org.eclipse.help.internal.ui;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+

+import org.eclipse.ui.*;

+import org.eclipse.help.internal.util.*;

+import org.eclipse.swt.widgets.Composite;

+import org.eclipse.jface.viewers.*;

+import org.eclipse.help.internal.ui.util.*;

+import org.eclipse.help.internal.contributions.Topic;

+

+/**

+ * Nested priting action class.

+ * Nested printing is only supported on Windows for now.

+ */

+

+public class NestedPrintAction extends org.eclipse.jface.action.Action {

+

+	private IStructuredSelection selection = null;

+

+	// keep state info for tracking printing.

+	private static boolean printingInProgress = false;

+	public NestedPrintAction(IStructuredSelection topicRoot) {

+		super(WorkbenchResources.getString("Print_Topic_Tree"));

+

+		// it is guaranteed here that we have a single selection

+		this.selection = topicRoot;

+

+		// if another nested printing operation is in progress, 

+		// disable Nested printing. This is because the printed transactions

+		// should be synchronized.

+		if (printingInProgress)

+			setEnabled(false);

+		else

+			setEnabled(true);

+	}

+	/*

+	 * Create the Browser dedicated for nested printing. 

+	 * This method will return null to signal errors creating the Browser.

+	 * It is only called when this action's run method is actually called.

+	 */

+	private IBrowser createPrintBrowser(Composite browserParent) throws Exception {

+

+		String factoryClass = "org.eclipse.help.internal.ui.win32.BrowserFactory";

+		try {

+			Class classObject = Class.forName(factoryClass);

+			IBrowserFactory factory = (IBrowserFactory) classObject.newInstance();

+

+			//** this could throw a HelpDesktopException

+			IBrowser webBrowser = factory.createBrowser(browserParent);

+

+			return webBrowser;

+		} catch (Exception e) {

+			// delegate to calling method

+			throw e;

+		}

+

+	}

+	public void run() {

+

+		try {

+			// get the active view part to be able to get to the Composite

+			// and create a Browser for printing

+			IWorkbenchPage activePage =

+				PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();

+			IViewPart activeViewPart = activePage.findView(EmbeddedHelpView.ID);

+			Composite browserParent = null;

+			if (!(activeViewPart instanceof EmbeddedHelpView)) {

+				// can not get to EmbeddedHelpView. Do nothing.

+				Logger.logError(WorkbenchResources.getString("WE006"), null);

+				return;

+			} else {

+				browserParent = ((EmbeddedHelpView) activeViewPart).getViewComposite();

+

+				// create the print Browser

+				IBrowser printBrowser = createPrintBrowser(browserParent);

+

+				if (printBrowser == null) {

+					// encountered problems creating print browser

+					Logger.logError(WorkbenchResources.getString("WE006"), null);

+					return;

+				} else {

+					if (selection != null) {

+						Object rootTopicObject = selection.getFirstElement();

+

+						// make sure we have correct root object first

+						if (rootTopicObject instanceof Topic) {

+							//** disable further Nested Printing Action

+							printingInProgress = true;

+

+							// send the root topic off to nested printing.  

+							printBrowser.printFullTopic((Topic) rootTopicObject);

+

+							// enable printing again.

+							printingInProgress = false;

+						}

+					}

+				}

+			}

+

+		} catch (Exception e) {

+			Logger.logError(WorkbenchResources.getString("WE006"), e);

+			return;

+		}

+	}

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/ShowHelp.java b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/ShowHelp.java
new file mode 100644
index 0000000..485188c
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/ShowHelp.java
@@ -0,0 +1,90 @@
+package org.eclipse.help.internal.ui;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+

+import org.eclipse.jface.viewers.ISelection;

+import org.eclipse.jface.action.*;

+import org.eclipse.core.runtime.*;

+import org.eclipse.ui.*;

+import org.eclipse.help.internal.Help;

+

+//import org.eclipse.help.internal.contributions.InfoSet;

+

+/**

+ * ShowHelp

+ */

+public class ShowHelp //extends Action {

+implements IWorkbenchWindowActionDelegate, IExecutableExtension {

+

+	//  private InfoSet infoset;

+	private String infoset;

+

+	public ShowHelp() {

+

+	}

+	/*

+	public ShowHelp(InfoSet infoset) {

+		super(infoset.getLabel());

+		setToolTipText("Show " + infoset.getLabel());

+		this.infoset = infoset;

+	}

+	*/

+	public void dispose() {

+	}

+	/**

+	 * Initializes the 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) {

+	}

+	/**

+	 * Implementation of method defined on <code>IAction</code>.

+	 *

+	 * [Issue: Will be made abstract. For now, calls <code>actionPerformed()</code> for backwards compatibility.]

+	 */

+	public void run() {

+		//Help.displayHelp(infoset.getID());

+		Help.displayHelp(infoset);

+	}

+	/**

+	 * Implementation of method defined on <code>IAction</code>.

+	 *

+	 * [Issue: Will be made abstract. For now, calls <code>actionPerformed()</code> for backwards compatibility.]

+	 */

+	public void run(IAction a) {

+		//Help.displayHelp(infoset.getID());

+		Help.displayHelp(infoset);

+	}

+	/**

+	 * Selection in the workbench has changed. Plugin provider

+	 * can use it to change the availability of the action

+	 * or to modify other presentation properties.

+	 *

+	 * <p>Action delegate cannot be notified about

+	 * selection changes before it is loaded. For that reason,

+	 * control of action's enable state should also be performed

+	 * through simple XML rules defined for the extension

+	 * point. These rules allow enable state control before

+	 * the delegate has been loaded.</p>

+	 *

+	 * @param action action proxy that handles presentation

+	 * portion of the plugin action

+	 * @param selection current selection in the workbench

+	 */

+	public void selectionChanged(IAction action, ISelection selection) {

+	}

+	/**

+	 * Initializes the action with data from the xml declaration

+	 */

+	public void setInitializationData(

+		IConfigurationElement cfig,

+		String propertyName,

+		Object data) {

+		infoset = (String) data;

+	}

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/TopicsPage.java b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/TopicsPage.java
new file mode 100644
index 0000000..58bef83
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/TopicsPage.java
@@ -0,0 +1,168 @@
+package org.eclipse.help.internal.ui;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+

+import java.util.*;

+import org.eclipse.swt.widgets.*;

+import org.eclipse.swt.SWT;

+import org.eclipse.jface.viewers.*;

+import org.eclipse.jface.action.*;

+import org.eclipse.ui.help.WorkbenchHelp;

+import org.eclipse.help.internal.HelpSystem;

+import org.eclipse.help.internal.contributions.*;

+

+/**

+ * Page to hold a topics view

+ */

+public class TopicsPage extends NavigationPage implements IMenuListener {

+

+	private Object view;

+	private TreeViewer viewer;

+	private NavigationWorkbook navWorkbook;

+	// Listeners to register later, because we use lazy control creation

+	private Collection selectionChangedListeners = new ArrayList();

+	public TopicsPage(NavigationWorkbook workbook, Object view) {

+		super(workbook, ((Contribution) view).getLabel());

+		this.navWorkbook = workbook;

+		this.view = view;

+	}

+	public void addSelectionChangedListener(ISelectionChangedListener listener) {

+		if (viewer != null)

+			viewer.addSelectionChangedListener(listener);

+		selectionChangedListeners.add(listener);

+	}

+	protected Control createControl(Composite parent) {

+		viewer = new TreeViewer(parent, SWT.H_SCROLL | SWT.V_SCROLL);

+		viewer.setContentProvider(TreeContentProvider.getDefault());

+		viewer.setLabelProvider(ElementLabelProvider.getDefault());

+

+		// add all listeners registered before actual control was created

+		for (Iterator it = selectionChangedListeners.iterator(); it.hasNext();) {

+			viewer.addSelectionChangedListener((ISelectionChangedListener) it.next());

+		}

+

+		viewer.addDoubleClickListener(new IDoubleClickListener() {

+			public void doubleClick(DoubleClickEvent event) {

+				handleDoubleClick(event);

+			}

+		});

+

+		viewer.setInput(view);

+		// create the pop-up menus in the viewer

+		createPopUpMenus();

+		WorkbenchHelp.setHelp(

+			viewer.getControl(),

+			new String[] {

+				IHelpUIConstants.TOPICS_VIEWER,

+				IHelpUIConstants.NAVIGATION_VIEWER,

+				IHelpUIConstants.EMBEDDED_HELP_VIEW });

+		return viewer.getControl();

+	}

+	private void createPopUpMenus() {

+		// create the Menu Manager for this control. and do

+		// proper initialization

+		Menu shellMenu;

+		MenuManager mgr = new MenuManager();

+		shellMenu = mgr.createContextMenu(viewer.getControl());

+		mgr.setRemoveAllWhenShown(true);

+		mgr.addMenuListener(this);

+		viewer.getControl().setMenu(shellMenu);

+

+	}

+	public void dispose() {

+		if (viewer != null) // can be null if page has never been activated

+			 ((Tree) viewer.getControl()).removeAll();

+		super.dispose();

+	}

+	public ISelection getSelection() {

+		if (viewer != null)

+			return viewer.getSelection();

+		return null;

+	}

+	/**

+	 * Handles double clicks in viewer.

+	 * Opens editor if file double-clicked.

+	 */

+	void handleDoubleClick(DoubleClickEvent event) {

+

+		IStructuredSelection s = (IStructuredSelection) event.getSelection();

+		Object element = s.getFirstElement();

+		// Double-clicking in navigator should expand/collapse containers

+		if (viewer != null && viewer.isExpandable(element)) {

+			viewer.setExpandedState(element, !viewer.getExpandedState(element));

+		}

+	}

+	public void menuAboutToShow(IMenuManager mgr) {

+		// Add pop-up Menus depending on current selection

+		// if multiple topics are selected, the Nested print menu is not showed.

+		ISelection selection = getSelection();

+		if (!(selection instanceof IStructuredSelection))

+			return; // should never be here. This is gauranteed by Viewer.

+

+		// Show nested printing menu only on win32 platform, and only

+		// if one topic is selected.

+		// make sure to have lazy creation of the printing Browser. 

+		if (System.getProperty("os.name").startsWith("Win")

+			&& ((IStructuredSelection) selection).size() == 1) {

+			mgr.add(new NestedPrintAction((IStructuredSelection) selection));

+			mgr.add(new Separator());

+			mgr.update(true);

+		}

+

+	}

+	public void removeSelectionChangedListener(ISelectionChangedListener listener) {

+		if (viewer != null)

+			viewer.removeSelectionChangedListener(listener);

+		selectionChangedListeners.remove(listener);

+	}

+	public void setSelection(ISelection selection) {

+		if (!(selection instanceof IStructuredSelection))

+			return;

+		Object o = ((IStructuredSelection) selection).getFirstElement();

+		if (o == null)

+			return;

+		Topic t = null;

+		if (o instanceof Topic) { // one of the related links

+			// Check if topic belongs to current view

+			Contribution ancestor = ((Topic) o).getParent();

+			while (ancestor instanceof Topic) {

+				ancestor = ancestor.getParent();

+			}

+			// ancestor is a view

+			if (ancestor == view) {

+				t = ((Topic) o);

+			}

+		} else

+			if (o instanceof String) { // Synchronization to given url

+				String url = (String) o;

+				Topic[] topics =

+					HelpSystem.getNavigationManager().getCurrentNavigationModel().getTopicsWithURL(

+						url);

+				if (topics == null)

+					return;

+				// Check if topic belongs to current view

+				for (int i = 0; i < topics.length; i++) {

+					Contribution ancestor = topics[i].getParent();

+					while (ancestor instanceof Topic) {

+						ancestor = ancestor.getParent();

+					}

+					// ancestor is a view

+					if (ancestor == view) {

+						t = topics[i];

+						break;

+					}

+				}

+			}

+		if (t != null) {

+			navWorkbook.setSelectedPage(this);

+			// Expand all nodes between root of model and the given element, exclusive

+			viewer.expandToLevel(t, 0);

+			// Select given element

+			viewer.setSelection(new StructuredSelection(t), true);

+		}

+	}

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/TreeContentProvider.java b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/TreeContentProvider.java
new file mode 100644
index 0000000..26a22b8
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/TreeContentProvider.java
@@ -0,0 +1,58 @@
+package org.eclipse.help.internal.ui;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+

+import java.util.*;

+import org.eclipse.jface.viewers.*;

+import org.eclipse.help.internal.contributions.*;

+

+/**

+ * A basic tree content provider

+ */

+public class TreeContentProvider implements ITreeContentProvider {

+	static TreeContentProvider instance = new TreeContentProvider();

+	/**

+	 * TreeContentProvider constructor comment.

+	 */

+	public TreeContentProvider() {

+		super();

+	}

+	public void dispose() {

+	}

+	public Object[] getChildren(Object element) {

+		if (element instanceof Contribution) {

+			return ((Contribution) element).getChildrenList().toArray();

+		} else

+			return null;

+	}

+	public static TreeContentProvider getDefault() {

+		return instance;

+	}

+	public Object[] getElements(Object element) {

+		return getChildren(element);

+	}

+	public Object getParent(Object element) {

+		if (element instanceof Contribution)

+			return ((Contribution) element).getParent();

+		else

+			return null;

+	}

+	public boolean hasChildren(Object element) {

+		if (element instanceof Contribution)

+			return ((Contribution) element).getChildren().hasNext();

+		else

+			return false;

+	}

+	public void inputChanged(

+		org.eclipse.jface.viewers.Viewer viewer,

+		Object oldInput,

+		Object newInput) {

+	}

+	public boolean isDeleted(Object element) {

+		return false;

+	}

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/WorkbenchHelpPlugin.java b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/WorkbenchHelpPlugin.java
new file mode 100644
index 0000000..5660f5b
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/WorkbenchHelpPlugin.java
@@ -0,0 +1,89 @@
+package org.eclipse.help.internal.ui;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+

+import org.eclipse.jface.preference.IPreferenceStore;

+import org.eclipse.core.runtime.*;

+import org.eclipse.ui.plugin.AbstractUIPlugin;

+import org.eclipse.help.internal.contributions.*;

+import org.eclipse.help.internal.util.*;

+import org.eclipse.help.internal.navigation.*;

+import org.eclipse.help.internal.ui.util.*;

+import org.eclipse.help.internal.HelpSystem;

+

+/**

+  * This class is a UI plugin. This may need to change to regular 

+  * plugin if the plugin class is moved into the base help.

+  */

+public class WorkbenchHelpPlugin extends AbstractUIPlugin {

+	protected static WorkbenchHelpPlugin plugin;

+

+	/**

+	 * HelpViewerPlugin constructor. It is called as part of plugin

+	 * activation.

+	 */

+	public WorkbenchHelpPlugin(IPluginDescriptor descriptor) {

+		super(descriptor);

+		plugin = this;

+		HelpSystem.setPlugin(plugin);

+	}

+	/**

+	 * @return com.ibm.ua.HelpViewerPlugin

+	 */

+	public static WorkbenchHelpPlugin getDefault() {

+		return plugin;

+	}

+	/** 

+	 * Sets default preference values. These values will be used

+	 * until some preferences are actually set using Preference dialog.

+	 */

+	protected void initializeDefaultPreferences(IPreferenceStore store) {

+		// These settings will show up when Preference dialog

+		// opens up for the first time.

+		//NOTE: this can perhaps be removed when the platform fixes

+		// the loadPreferenceStore method to properly read the ini file

+		// from the plugin directory.

+		store.setDefault(HelpPreferencePage.INSTALL_OPTION_KEY, HelpSystem.INSTALL_LOCAL);

+		store.setDefault(HelpPreferencePage.LOCAL_SERVER_ADDRESS_KEY, "");

+		store.setDefault(HelpPreferencePage.LOCAL_SERVER_PORT_KEY, "");

+		store.setDefault(HelpPreferencePage.SERVER_PATH_KEY, "");

+		store.setDefault(HelpPreferencePage.LOG_LEVEL_KEY, HelpSystem.LOG_ERROR);

+		store.setDefault(HelpPreferencePage.BROWSER_PATH_KEY, "/usr/bin/netscape");

+	}

+	public void initializeFromStore() {

+		IPreferenceStore ini = getPreferenceStore();

+		HelpSystem.setInstall(ini.getInt(HelpPreferencePage.INSTALL_OPTION_KEY));

+		HelpSystem.setRemoteServerInfo(

+			ini.getString(HelpPreferencePage.SERVER_PATH_KEY));

+		if (ini.getInt(HelpPreferencePage.LOCAL_SERVER_CONFIG) > 0) {

+			HelpSystem.setLocalServerInfo(

+				ini.getString(HelpPreferencePage.LOCAL_SERVER_ADDRESS_KEY),

+				ini.getString(HelpPreferencePage.LOCAL_SERVER_PORT_KEY));

+		} else {

+			HelpSystem.setLocalServerInfo(null, "0");

+		}

+		HelpSystem.setDebugLevel(ini.getInt(HelpPreferencePage.LOG_LEVEL_KEY));

+		HelpSystem.setBrowserPath(ini.getString(HelpPreferencePage.BROWSER_PATH_KEY));

+

+	}

+	/**

+	 * Shuts down this plug-in and discards all plug-in state.

+	 * @exception CoreException if this method fails to shut down

+	 *   this plug-in 

+	 */

+	public void shutdown() throws CoreException {

+		super.shutdown();

+		HelpSystem.shutdown();

+	}

+	/**

+	 * Called by Platform after loading the plugin

+	 */

+	public void startup() {

+		initializeFromStore();

+		HelpSystem.startup();

+	}

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/search/AdvancedSearchDialog.java b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/search/AdvancedSearchDialog.java
new file mode 100644
index 0000000..515dc8e
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/search/AdvancedSearchDialog.java
@@ -0,0 +1,119 @@
+package org.eclipse.help.internal.ui.search;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+

+import java.util.*;

+import java.util.List;

+import org.eclipse.ui.help.WorkbenchHelp;

+import org.eclipse.jface.dialogs.*;

+import org.eclipse.jface.dialogs.Dialog;

+import org.eclipse.swt.*;

+import org.eclipse.swt.graphics.Point;

+import org.eclipse.swt.widgets.*;

+import org.eclipse.swt.layout.*;

+import org.eclipse.swt.events.*;

+import org.eclipse.help.internal.*;

+import org.eclipse.help.internal.contributions.*;

+import org.eclipse.help.internal.contributions.xml.*;

+import org.eclipse.help.internal.ui.util.*;

+import org.eclipse.help.internal.ui.IHelpUIConstants;

+

+/**

+ * SearchPage

+ */

+public class AdvancedSearchDialog extends Dialog {

+	private Composite control;

+	private Button withinCheckBox = null;

+	private Button fieldsSearchCheckBox = null;

+	private Button categoryFilteringCheckBox = null;

+	private SearchFilteringOptions options;

+	// the underlying model for the UI; shared with the page

+	private HelpSearchQuery query;

+	/**

+	 * Search Page

+	 * @parameter workbook workbook that this page is part of

+	 */

+	public AdvancedSearchDialog(Shell parent, HelpSearchQuery query) {

+		super(parent);

+		this.query = query;

+	}

+	private Button createCheckBox(Composite parent, String label ) {

+		Button checkBox = new Button(parent, SWT.CHECK);

+		checkBox.setText(label);

+		checkBox.setAlignment(SWT.LEFT);

+		GridData gd = new GridData();

+		gd.horizontalAlignment = gd.FILL;

+		gd.horizontalSpan = 2; // on a row by itself

+		checkBox.setLayoutData(gd);

+		return checkBox;

+	}

+	protected Control createDialogArea(Composite parent) {

+

+		control = new Composite(parent, SWT.NULL);

+		GridLayout layout = new GridLayout();

+		layout.numColumns = 2;

+		//layout.verticalSpacing = 5;

+		layout.marginHeight = 10;

+		layout.marginWidth = 10;

+		control.setLayout(layout);

+		control.setLayoutData(new GridData(GridData.FILL_BOTH));

+

+		// Create the "search headers only" check box

+		fieldsSearchCheckBox = createCheckBox(control, WorkbenchResources.getString("Search_headers_only"));

+		fieldsSearchCheckBox.setSelection(query.isFieldsSearch());

+		

+		// Create the "search within results" check box

+		withinCheckBox = createCheckBox(control, WorkbenchResources.getString("Search_within_results"));

+		withinCheckBox.setSelection(query.isSearchWithinLastResults());

+		

+		// Create the "enable category filtering"

+		categoryFilteringCheckBox = createCheckBox(control, WorkbenchResources.getString("Enable_Filtering"));

+		categoryFilteringCheckBox.setSelection(query.isCategoryFiltering());

+

+		SelectionListener listener2 = new SelectionAdapter() {

+			public void widgetSelected(SelectionEvent e) {

+				if (((Button) e.widget).getSelection()) {

+					//advancedButton.setText(WorkbenchResources.getString("Disable_Filtering"));

+					setOptionsVisible(true);

+				} else {

+					//advancedButton.setText(WorkbenchResources.getString("Enable_Filtering"));

+					setOptionsVisible(false);

+				}

+			}

+		};

+		categoryFilteringCheckBox.addSelectionListener(listener2);

+		options = new SearchFilteringOptions(control, query);

+		setOptionsVisible(query.isCategoryFiltering());

+		

+		WorkbenchHelp.setHelp(

+			control,

+			new String[] {

+				IHelpUIConstants.SEARCH_PAGE,

+				IHelpUIConstants.NAVIGATION_VIEWER,

+				IHelpUIConstants.EMBEDDED_HELP_VIEW});

+		return control;

+	}

+	public Control getControl() {

+		return control;

+	}

+   /**

+ 	* Notifies that the ok button of this dialog has been pressed.

+ 	*/

+	protected void okPressed() {

+		// set the UI values on the query

+		query.setFieldsSearch(fieldsSearchCheckBox.getSelection());

+		query.setSearchWithinLastResults(withinCheckBox.getSelection());

+		query.setCategoryFiltering(categoryFilteringCheckBox.getSelection());

+		query.setExcludedCategories(options.getExcludedCategories());

+		

+		super.okPressed();

+	}

+	protected void setOptionsVisible(boolean enabled) {

+		// enable or disable the control

+		options.setEnabled(enabled);

+	}

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/search/CheckboxLabelProvider.java b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/search/CheckboxLabelProvider.java
new file mode 100644
index 0000000..5a05ea5
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/search/CheckboxLabelProvider.java
@@ -0,0 +1,50 @@
+package org.eclipse.help.internal.ui.search;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+

+import java.util.Iterator;

+import org.eclipse.swt.graphics.Image;

+import org.eclipse.jface.viewers.*;

+import org.eclipse.jface.resource.ImageRegistry;

+import org.eclipse.jface.resource.ImageDescriptor;

+import org.eclipse.help.internal.contributions.*;

+import org.eclipse.help.internal.ui.util.WorkbenchResources;

+import org.eclipse.help.internal.ui.*;

+

+/**

+ * Label and image provider for topic elements

+ */

+public class CheckboxLabelProvider extends LabelProvider {

+	static CheckboxLabelProvider instance = null;

+

+	static final String IMAGE_TOPIC = "topic_icon";

+	static final String IMAGE_TOPIC_FOLDER = "topicfolder_icon";

+	static final String IMAGE_TOPIC_AND_FOLDER = "topicandfolder_icon";

+	static ImageRegistry imgRegistry = null;

+

+	/**

+	 * ElementLabelProvider Constructor

+	 */

+	CheckboxLabelProvider() {

+		imgRegistry = WorkbenchHelpPlugin.getDefault().getImageRegistry();

+		if (imgRegistry.get(IMAGE_TOPIC) == null)

+			imgRegistry.put(

+				IMAGE_TOPIC,

+				ImageDescriptor.createFromURL(WorkbenchResources.getImagePath(IMAGE_TOPIC)));

+	}

+	public static CheckboxLabelProvider getDefault() {

+		if (instance == null)

+			instance = new CheckboxLabelProvider();

+		return instance;

+	}

+	public Image getImage(Object element) {

+		return imgRegistry.get(IMAGE_TOPIC_FOLDER);

+	}

+	public String getText(Object element) {

+		return ((Contribution) element).getLabel();

+	}

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/search/CheckboxTreeContentProvider.java b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/search/CheckboxTreeContentProvider.java
new file mode 100644
index 0000000..9859805
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/search/CheckboxTreeContentProvider.java
@@ -0,0 +1,62 @@
+package org.eclipse.help.internal.ui.search;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+

+import java.util.*;

+import org.eclipse.jface.viewers.*;

+import org.eclipse.help.internal.contributions.*;

+import org.eclipse.help.internal.ui.*;

+

+/**

+ * A basic tree content provider

+ */

+public class CheckboxTreeContentProvider implements ITreeContentProvider {

+	static CheckboxTreeContentProvider instance = new CheckboxTreeContentProvider();

+	/**

+	 * TreeContentProvider constructor comment.

+	 */

+	public CheckboxTreeContentProvider() {

+		super();

+	}

+	public void dispose() {

+	}

+	public Object[] getChildren(Object element) {

+		if (element instanceof InfoView || element instanceof InfoSet) {

+			return ((Contribution) element).getChildrenList().toArray();

+		} else

+			return null;

+	}

+	public static CheckboxTreeContentProvider getDefault() {

+		return instance;

+	}

+	public Object[] getElements(Object element) {

+		if (element instanceof InfoView || element instanceof InfoSet)

+			return getChildren(element);

+		else

+			return null;

+	}

+	public Object getParent(Object element) {

+		if (element instanceof Contribution)

+			return ((Contribution) element).getParent();

+		else

+			return null;

+	}

+	public boolean hasChildren(Object element) {

+		if (element instanceof InfoView || element instanceof InfoSet)

+			return ((Contribution) element).getChildren().hasNext();

+		else

+			return false;

+	}

+	public void inputChanged(

+		org.eclipse.jface.viewers.Viewer viewer,

+		Object oldInput,

+		Object newInput) {

+	}

+	public boolean isDeleted(Object element) {

+		return false;

+	}

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/search/HelpSearchQuery.java b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/search/HelpSearchQuery.java
new file mode 100644
index 0000000..1947433
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/search/HelpSearchQuery.java
@@ -0,0 +1,195 @@
+package org.eclipse.help.internal.ui.search;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+

+import java.util.*;

+import java.net.URLEncoder;

+import org.w3c.dom.*;

+import org.eclipse.help.internal.*;

+import org.eclipse.help.internal.contributions.*;

+

+/**

+ * Help Search Query.

+ */

+public class HelpSearchQuery {

+	/** Filtering info */

+	private boolean searchWithinLastResults = false;

+	private boolean fieldSearch = false;

+	private boolean categoryFiltering = false;

+	

+	private static String lastQueryString = "";

+	private List excludedCategories;

+

+	/** infoset for which the query is performed */

+	private String infoset;

+	/** search keyword(s) */

+	private String key;

+	/** locale to be used for search */

+	private String locale;

+	/** maximum number of hits that a search engine

+	 * will search stop

+	 */

+	private static int MAX_HITS = 500;

+	private int maxHits;

+

+	/** fields that will be searched */

+	private Collection fieldNames = new ArrayList();

+

+

+

+	/**

+	 * HelpSearchQuery constructor.

+	 * @param key java.lang.String

+	 */

+	public HelpSearchQuery(String key) {

+		this(key, MAX_HITS);

+	}

+	/**

+	 * HelpSearchQuery constructor.

+	 * @param key java.lang.String

+	 * @param maxH int

+	 */

+	public HelpSearchQuery(String key, int maxH) {

+		this.key = key;

+		this.maxHits = maxH;

+		fieldNames.add("h1");

+		fieldNames.add("h2");

+		fieldNames.add("h3");

+		fieldNames.add("keyword");

+		fieldNames.add("role");

+		fieldNames.add("solution");

+		fieldNames.add("technology");

+	}

+	/**

+	 * Returns the list of category id's to be excluded from search.

+	 * (A category is a top level topic in an info view)

+	 * When the list is null (note, empty list is not the same as null)

+	 * no filtering is performed.

+	 */

+	public List getExcludedCategories() {

+		return excludedCategories;

+	}

+	/**

+	 * Returns the infoset for which the search will be performed.

+	 */

+	public String getInfoset() {

+		return infoset;

+	}

+	/**

+	 * Returns the locale in which the search will be performed.

+	 */

+	public String getLocale() {

+		return locale;

+	}

+	/**

+	 * Returns true if  category filtering is enabled.

+	 */

+	public boolean isCategoryFiltering() {

+		return categoryFiltering;

+	}

+	/**

+	 * Returns true if search is to be performed on the fields only.

+	 */

+	public boolean isFieldsSearch() {

+		return fieldSearch;

+	}

+	public boolean isSearchWithinLastResults() {

+		return searchWithinLastResults;

+	}

+	private void preprocessQuery() {

+		if (searchWithinLastResults) {

+			key = "(" + lastQueryString + ") AND (" + key + ")";

+		}

+		lastQueryString = key;

+	}

+	/**

+	 * Sets category filtering.

+	 * @param enable true if category filtering is turned on

+	 */

+	public void setCategoryFiltering(boolean enable) {

+		this.categoryFiltering = enable;

+	}

+	/**

+	 * Sets the list of category id's to be excluded from search.

+	 * (A category is a top level topic in an info view)

+	 * When the list is null (note, empty list is not the same as null)

+	 * no filtering is performed.

+	 */

+	public void setExcludedCategories(List excluded) {

+		excludedCategories = excluded;

+	}

+	/**

+	 * Sets search to be performed on the fields only.

+	 * @param fieldSearch true if field only search

+	 */

+	public void setFieldsSearch(boolean fieldSearch) {

+		this.fieldSearch = fieldSearch;

+	}

+	/**

+	 * Sets infoset for which the search will be performed.

+	 * @param infoset java.lang.String

+	 */

+	public void setInfoset(String infoset) {

+		this.infoset = infoset;

+	}

+	/**

+	 * Sets keyword for which the search will be performed.

+	 * @param newKey java.lang.String

+	 */

+	public void setKey(java.lang.String newKey) {

+		key = newKey;

+	}

+	/**

+	 * Sets locale in which the search will be performed.

+	 * @param newLocale java.lang.String

+	 */

+	public void setLocale(String newLocale) {

+		locale = newLocale;

+	}

+	/**

+	 * Changes a limit on number of hits returned by the search engine

+	 * @param newMaxHits int

+	 */

+	public void setMaxHits(int newMaxHits) {

+		maxHits = newMaxHits;

+	}

+	public void setSearchWithinLastResults(boolean within) {

+		searchWithinLastResults = within;

+	}

+	public String toURLQuery() {

+		preprocessQuery();

+

+		String q =

+			"infoset="

+				+ infoset

+				+ "&keyword="

+				+ URLEncoder.encode(key)

+				+ "&maxHits="

+				+ maxHits

+				+ "&within="

+				+ searchWithinLastResults

+				+ "&lang="

+				+ (locale != null ? locale : Locale.getDefault().toString());

+

+		if (fieldNames != null && !fieldNames.isEmpty())

+			for (Iterator iterator = fieldNames.iterator(); iterator.hasNext();) {

+				String field = (String) iterator.next();

+				q += "&field=" + URLEncoder.encode(field);

+			}

+		if (fieldSearch)

+			q += "&fieldSearch=true";

+		else

+			q += "&fieldSearch=false";

+

+		if (categoryFiltering && excludedCategories != null)

+			for (Iterator iterator = excludedCategories.iterator(); iterator.hasNext();) {

+				Contribution category = (Contribution) iterator.next();

+				q += "&exclude=" + URLEncoder.encode(category.getID());

+			}

+		return q;

+	}

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/search/SearchFilteringOptions.java b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/search/SearchFilteringOptions.java
new file mode 100644
index 0000000..31778bf
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/search/SearchFilteringOptions.java
@@ -0,0 +1,139 @@
+package org.eclipse.help.internal.ui.search;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+

+import java.util.*;

+import java.util.List;

+import org.eclipse.ui.*;

+import org.eclipse.jface.resource.*;

+import org.eclipse.jface.viewers.*;

+import org.eclipse.swt.*;

+import org.eclipse.swt.layout.*;

+import org.eclipse.swt.events.*;

+import org.eclipse.swt.widgets.*;

+import org.eclipse.swt.custom.*;

+import org.eclipse.help.internal.contributions.*;

+import org.eclipse.help.internal.HelpSystem;

+import org.eclipse.help.internal.ui.util.*;

+

+/**

+ * Displays Search Filtering Options dialog.

+ */

+public class SearchFilteringOptions {

+	

+	private Composite control = null;

+	private CheckboxTreeViewer checkboxTreeViewer;

+	private HelpSearchQuery query;

+	private Collection excludedCategories; // = query.getExcludedCategories()

+

+

+	public SearchFilteringOptions(Composite parent, HelpSearchQuery query) {

+		this.query = query;

+		excludedCategories = query.getExcludedCategories();

+		if (excludedCategories == null)

+			excludedCategories = new ArrayList();

+		createControl(parent);

+	}

+	/**

+	 * Fills in the dialog area with text and checkboxes

+	 * @param the parent composite to contain the dialog area

+	 * @return the dialog area control

+	 */

+	protected Control createControl(Composite parent) {

+		//Group group = new Group((Composite) parent, SWT.SHADOW_NONE);

+		Composite group = new Composite(parent, SWT.SHADOW_NONE);

+		//group.setText(WorkbenchResources.getString("Search_only_within"));

+		group.setLayout(new GridLayout());

+		GridData data = new GridData();

+		data.verticalAlignment = GridData.FILL;

+		data.horizontalAlignment = GridData.FILL;

+		data.horizontalSpan = 2;

+		data.heightHint = 200;

+		data.widthHint = 200;

+		group.setLayoutData(data);

+

+		control = group;

+

+		InfoSet infoset = HelpSystem.getNavigationManager().getCurrentInfoSet();

+		checkboxTreeViewer =

+			new CheckboxTreeViewer(control, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);

+

+		// Listen to check state changes

+		checkboxTreeViewer.addCheckStateListener(new ICheckStateListener() {

+			public void checkStateChanged(CheckStateChangedEvent event) {

+				if (event.getElement() instanceof InfoView)

+					checkboxTreeViewer.setSubtreeChecked(event.getElement(), event.getChecked());

+				else if (event.getElement() instanceof Topic && event.getChecked())

+					checkboxTreeViewer.setChecked(((Contribution)event.getElement()).getParent(), event.getChecked());

+				// we should add another case for unselecting the last topic to also

+				// unselect the parent view

+			}

+		});

+	

+		checkboxTreeViewer.setContentProvider(CheckboxTreeContentProvider.getDefault());

+		checkboxTreeViewer.setLabelProvider(CheckboxLabelProvider.getDefault());

+		checkboxTreeViewer.getTree().setLayoutData(new GridData(GridData.FILL_BOTH));

+		checkboxTreeViewer.setInput(infoset);

+		checkboxTreeViewer.setExpandedElements(infoset.getChildrenList().toArray());

+		

+		setExcludedCategories(query.getExcludedCategories());

+		checkboxTreeViewer.refresh();

+		return control;

+	}

+	public Control getControl() {

+		return control;

+	}

+	/**

+	 * Returns a list of Topics (categories) that are to be excluded from search

+	 */

+	public List getExcludedCategories()

+	{

+		InfoSet infoset = HelpSystem.getNavigationManager().getCurrentInfoSet();

+		ArrayList categories = new ArrayList();

+		for (Iterator viewIterator = infoset.getChildren(); viewIterator.hasNext();	) {

+			InfoView view = (InfoView) viewIterator.next();

+			for (Iterator topicIterator = view.getChildren(); topicIterator.hasNext();) {

+				categories.add(topicIterator.next());

+			}

+		}

+			

+		Object[] checkedElements = checkboxTreeViewer.getCheckedElements();

+		for (int i=0; i<checkedElements.length; i++)

+		{

+			Contribution c = (Contribution)checkedElements[i];

+			categories.remove(c);

+		}

+		return categories;

+	}

+	public void setEnabled(boolean enabled) {

+		control.setEnabled(enabled);

+		Control[] children=control.getChildren();

+		for (int i=0; i<children.length; i++)

+			children[i].setEnabled(enabled);

+	}

+	/**

+	 * Returns a list of Topics (categories) that are to be excluded from search

+	 */

+	public void setExcludedCategories(List categories)

+	{

+		if (categories == null || categories.isEmpty())

+			return;

+			

+		InfoSet infoset = HelpSystem.getNavigationManager().getCurrentInfoSet();

+		

+		for (Iterator viewIterator = infoset.getChildren(); viewIterator.hasNext();	) {

+			InfoView view = (InfoView) viewIterator.next();

+			// First set all, then un-check

+			checkboxTreeViewer.setSubtreeChecked(view,true);

+			for (Iterator topicIterator = view.getChildren(); topicIterator.hasNext();) {

+				Contribution topic = (Contribution)topicIterator.next();

+				if (categories.contains(topic))

+					checkboxTreeViewer.setChecked(topic, false);

+			}

+		}

+	}

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/search/SearchPage.java b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/search/SearchPage.java
new file mode 100644
index 0000000..6d92d61
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/search/SearchPage.java
@@ -0,0 +1,469 @@
+package org.eclipse.help.internal.ui.search;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+

+import java.lang.reflect.InvocationTargetException;

+import java.util.*;

+import java.util.List;

+import org.xml.sax.Attributes;

+import org.eclipse.ui.help.WorkbenchHelp;

+import org.eclipse.jface.viewers.*;

+import org.eclipse.jface.dialogs.*;

+import org.eclipse.jface.operation.*;

+import org.eclipse.jface.resource.ImageRegistry;

+import org.eclipse.jface.resource.ImageDescriptor;

+import org.eclipse.swt.*;

+import org.eclipse.swt.widgets.*;

+import org.eclipse.swt.layout.*;

+import org.eclipse.swt.events.*;

+import org.eclipse.swt.custom.BusyIndicator;

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.core.runtime.OperationCanceledException;

+import org.eclipse.help.internal.*;

+import org.eclipse.help.internal.search.*;

+import org.eclipse.help.internal.contributions.*;

+import org.eclipse.help.internal.contributions.xml.*;

+import org.eclipse.help.internal.ui.util.*;

+import org.eclipse.help.internal.ui.*;

+import org.eclipse.help.internal.server.PluginURL;

+

+/**

+ * SearchPage

+ */

+public class SearchPage extends NavigationPage {

+

+	// Maximum number of displayed hits.

+	// This is different than maximum number of hits returned by GTR.

+	// We allow GTR to search for more hits,

+	// and than display only few top ranked ones.

+	private final static int RESULT_GROUP_SIZE = 15;

+	// Maximum number of search results.

+	// This is how many sets of RESULT_GROUP_SIZE we provide

+	private final static int RESULTS_GROUPS = 6;

+

+	private static final int ENTRY_FIELD_LENGTH = 256;

+	private static final int ENTRY_FIELD_ROW_COUNT = 1;

+	public static final int BASE_HEIGHT = 60;

+

+	private Composite control;

+	private Text searchTextField = null;

+	private Button searchButton = null;

+	private Button advancedButton = null;

+	private Composite searchControl;

+

+	// This is a cheat to keep the last query string around.

+	// This won't work if we need to support multithreaded SearchURLs.

+	private static String lastQuery = null;

+	private TreeViewer resultsViewer = null;

+	private static final String IMAGE_GO = "go_icon";

+	private static ImageRegistry imgRegistry = null;

+

+	// Listeners to register later, because we use lazy control creation

+	private Collection selectionChangedListeners = new ArrayList();

+

+	// Search query based on the data entered in the UI

+	HelpSearchQuery searchQuery;

+

+	// nodes to show in the results tree

+	class SearchElement extends HelpTopic {

+		public SearchElement(String label, String url) {

+			super(null);

+			id = url;

+			this.label = label;

+			if (url != null)

+				href = PluginURL.getPrefix() + "/" + url;

+		}

+		public SearchElement(Attributes atts) {

+			super(atts);

+		}

+	}

+

+	/**

+	 * Search Page

+	 * @parameter workbook workbook that this page is part of

+	 */

+	public SearchPage(NavigationWorkbook workbook) {

+		super(workbook, WorkbenchResources.getString("Search"));

+		if (imgRegistry == null) {

+			imgRegistry = WorkbenchHelpPlugin.getDefault().getImageRegistry();

+			imgRegistry.put(

+				IMAGE_GO,

+				ImageDescriptor.createFromURL(WorkbenchResources.getImagePath("go_icon")));

+		}

+

+		// Create the query to perform search for the current info set

+		String infoSet =

+			HelpSystem

+				.getNavigationManager()

+				.getCurrentNavigationModel()

+				.getRootElement()

+				.getID();

+

+		searchQuery = new HelpSearchQuery("");

+		searchQuery.setInfoset(infoSet);

+		searchQuery.setLocale(Locale.getDefault().toString());

+	}

+	/**

+	 * Adds a listener for selection changes in this selection provider.

+	 * Has no effect if an identical listener is already registered.

+	 *

+	 * @param listener a selection changed listener

+	 */

+	public void addSelectionChangedListener(ISelectionChangedListener listener) {

+		if (resultsViewer != null)

+			resultsViewer.addSelectionChangedListener(listener);

+		selectionChangedListeners.add(listener);

+	}

+	protected Contribution buildSearchTree(String resultsAsXMLString) {

+		XMLSearchContributor searchContributor =

+			new XMLSearchContributor(resultsAsXMLString);

+		HelpContribution root = (HelpContribution) searchContributor.getContribution();

+

+		//SearchElement root =

+		//  new SearchElement(WorkbenchResources.getString("Search_results"), null);

+

+		if (root == null || !root.getChildren().hasNext()) {

+			root.addChild(

+				new SearchElement(WorkbenchResources.getString("No_results_found"), null));

+			return root;

+		}

+

+		List documents = root.getChildrenList();

+		if (documents.size() > RESULT_GROUP_SIZE) {

+			int maxResultsSets =

+				(documents.size() + RESULT_GROUP_SIZE - 1) / RESULT_GROUP_SIZE;

+			int resultSetCount = Math.min(maxResultsSets, RESULTS_GROUPS);

+

+			// Create a duplicate list of all the children

+			List resultsBackup = new ArrayList(documents.size());

+			for (Iterator it = documents.iterator(); it.hasNext();)

+				resultsBackup.add(it.next());

+

+			// Remove all topics from the root, and create groups of GROUP_SIZE topics

+			root.getChildrenList().removeAll(documents);

+			for (int r = 0; r < resultSetCount; r++) {

+				// the range of results displayed

+				int resultsBegin = 1 + r * RESULT_GROUP_SIZE;

+				int resultsEnd = Math.min((r + 1) * RESULT_GROUP_SIZE, resultsBackup.size());

+

+				String label =

+					WorkbenchResources.getString("Results")

+						+ String.valueOf(resultsBegin)

+						+ ".."

+						+ String.valueOf(resultsEnd);

+				HelpTopic resultsGroup = new HelpTopic(null);

+				resultsGroup.setRawLabel(label);

+				root.addChild(resultsGroup);

+

+				//Inserting results rows here

+				int maxRange = Math.min(resultsBackup.size(), resultsEnd);

+				for (int i = r * RESULT_GROUP_SIZE; i < maxRange; i++) {

+					//SearchElement doc = (SearchElement)documents.get(i);

+					//SearchElement child = new SearchElement(doc.getLabel(), doc.getHref());

+					Contribution child = (Contribution) resultsBackup.get(i);

+					resultsGroup.addChild(child);

+				}

+			}

+		}

+

+		return root;

+	}

+	protected Control createControl(Composite parent) {

+		control = new Composite(parent, SWT.NULL);

+		GridLayout layout = new GridLayout();

+		layout.numColumns = 1;

+		//layout.verticalSpacing = 5;

+		layout.marginHeight = 0;

+		layout.marginWidth = 0;

+		control.setLayout(layout);

+		control.setLayoutData(new GridData(GridData.FILL_BOTH));

+

+		// Create the search entry/options part

+		createSearchControl(control);

+

+		// Create the search results tree

+		createResultsControl(control);

+

+		// add all listeners registered before actual control was created

+		for (Iterator it = selectionChangedListeners.iterator(); it.hasNext();) {

+			resultsViewer.addSelectionChangedListener(

+				(ISelectionChangedListener) it.next());

+		}

+

+		WorkbenchHelp.setHelp(

+			control,

+			new String[] {

+				IHelpUIConstants.SEARCH_PAGE,

+				IHelpUIConstants.NAVIGATION_VIEWER,

+				IHelpUIConstants.EMBEDDED_HELP_VIEW});

+		return control;

+	}

+	/**

+	* Returns SWT control for SearchViewer viewer.

+	*/

+	protected Control createResultsControl(Composite parent) {

+

+		resultsViewer =

+			new TreeViewer(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);

+		resultsViewer.setContentProvider(TreeContentProvider.getDefault());

+		resultsViewer.setLabelProvider(ElementLabelProvider.getDefault());

+		resultsViewer.getTree().setLayoutData(new GridData(GridData.FILL_BOTH));

+

+		resultsViewer.addDoubleClickListener(new IDoubleClickListener() {

+			public void doubleClick(DoubleClickEvent event) {

+				handleDoubleClick(event);

+			}

+		});

+

+		WorkbenchHelp.setHelp(

+			resultsViewer.getControl(),

+			new String[] {

+				IHelpUIConstants.RESULTS_VIEWER,

+				IHelpUIConstants.SEARCH_PAGE,

+				IHelpUIConstants.NAVIGATION_VIEWER,

+				IHelpUIConstants.EMBEDDED_HELP_VIEW});

+		return resultsViewer.getControl();

+	}

+	/**

+	 * Returns SWT control for SearchViewer viewer.

+	 */

+	protected Control createSearchControl(Composite parent) {

+		GridData gd = new GridData();

+

+		// Create the search entry/options part

+		Composite searchPart = new Composite(parent, SWT.FLAT);

+		GridLayout gl = new GridLayout();

+		gl.numColumns = 2;

+		gl.marginHeight = 2;

+		gl.marginWidth = 2;

+		searchPart.setLayout(gl);

+		gd.horizontalAlignment = gd.FILL;

+		gd.grabExcessHorizontalSpace = true;

+		gd.verticalAlignment = gd.BEGINNING;

+		gd.grabExcessVerticalSpace = false;

+		searchPart.setLayoutData(gd);

+

+		// Create the entry field.    

+		searchTextField = new Text(searchPart, SWT.BORDER);

+		searchTextField.setTextLimit(ENTRY_FIELD_LENGTH);

+		//searchTextField.getVerticalBar().setVisible(false);

+		gd = new GridData();

+		gd.heightHint = searchTextField.getLineHeight() * ENTRY_FIELD_ROW_COUNT;

+		gd.horizontalAlignment = gd.FILL;

+		gd.grabExcessHorizontalSpace = true;

+		gd.verticalAlignment = gd.FILL;

+		gd.grabExcessVerticalSpace = true;

+		searchTextField.setLayoutData(gd);

+		/*

+		searchTextField.addKeyListener(new KeyListener() {

+			public void keyPressed(KeyEvent e) {

+				// set the focus to the field.

+				// this should not be necessary but it looks likes

+				// the advanced button sometimes gets focus after

+				// showing the results.

+				//if (!searchTextField.isFocusControl())

+				//	searchTextField.setFocus();

+				if (e.character == '\n' || e.character == '\r')

+					doSearch();

+			}

+			public void keyReleased(KeyEvent e) {

+			}

+		});

+		*/

+

+		// Create the button that launchs the search

+		searchButton = new Button(searchPart, SWT.PUSH);

+		//searchButton.setText("Go");

+		searchButton.setImage(imgRegistry.get(IMAGE_GO));

+		//searchButton.setFocus();

+

+		SelectionListener listener = new SelectionAdapter() {

+			public void widgetSelected(SelectionEvent e) {

+				doSearch();

+				searchTextField.setFocus();

+			}

+		};

+

+		searchButton.addSelectionListener(listener);

+

+		gd = new GridData();

+		gd.verticalAlignment = gd.BEGINNING;

+		searchButton.setLayoutData(gd);

+		searchPart.getShell().setDefaultButton(searchButton);

+

+		// Create the "Advanced Search Options" button

+		// opens Options window

+		advancedButton = new Button(searchPart, SWT.FLAT);

+		advancedButton.setText(WorkbenchResources.getString("Advanced"));

+

+		SelectionListener listener2 = new SelectionAdapter() {

+			public void widgetSelected(SelectionEvent e) {

+				AdvancedSearchDialog dialog =

+					new AdvancedSearchDialog(Display.getCurrent().getActiveShell(), searchQuery);

+				dialog.open();

+				//searchButton.setFocus();

+			}

+		};

+		advancedButton.addSelectionListener(listener2);

+		gd = new GridData();

+		gd.verticalAlignment = gd.BEGINNING;

+		gd.horizontalSpan = 2;

+		advancedButton.setLayoutData(gd);

+

+		// If I try to select all the text, the cursor gets

+		// scrolled to the middle of the text box, and you

+		// lose the first 4 characters of the message...

+		searchTextField.setText(WorkbenchResources.getString("Enter_search_string"));

+		//searchTextField.setFocus();

+		searchControl = searchPart;

+		return searchPart;

+	}

+	protected void doSearch() {

+		BusyIndicator.showWhile(Display.getDefault(), new Runnable() {

+			public void run() {

+

+				// May need to index first

+				if (!ensureIndexIsUpdated())

+					return;

+

+				// Create the query and convert it to a URL format

+				searchQuery.setKey(searchTextField.getText());

+				String queryURL = searchQuery.toURLQuery();

+

+				String results = null;

+				if (HelpSystem.isClient())

+					// help server is remote

+					results =

+						HelpSystem.getSearchManager().getRemoteSearchResults(

+							searchQuery.getInfoset(),

+							queryURL);

+				else

+					results =

+						HelpSystem.getSearchManager().getSearchResults(

+							searchQuery.getInfoset(),

+							queryURL);

+

+				Contribution searchRoot = buildSearchTree(results);

+

+				if (resultsViewer != null && searchRoot != null) {

+					resultsViewer.setInput(searchRoot);

+

+					// Expand to and select first result

+					if (searchRoot.getChildren().hasNext()) {

+						HelpTopic firstFolder = (HelpTopic) searchRoot.getChildren().next();

+						if (firstFolder.getChildren().hasNext()) {

+							HelpTopic firstTopic = (HelpTopic) firstFolder.getChildren().next();

+							resultsViewer.expandToLevel(firstTopic, 0);

+							resultsViewer.setSelection(new StructuredSelection(firstTopic), true);

+						} else {

+							//firstFolder is not folder but actually a topic

+							resultsViewer.expandToLevel(firstFolder, 0);

+							resultsViewer.setSelection(new StructuredSelection(firstFolder), true);

+						}

+					}

+

+				}

+			}

+		});

+	}

+	/*

+	 * @return true if has been updated, or does not need update,

+	 *  false if update did not succeed (failed or canceled)

+	 */

+	protected boolean ensureIndexIsUpdated() {

+		// Only verify the index (or do the actual indexing)

+		// when the install is local (same process for both help client/server

+

+		if (HelpSystem.isClient()

+			|| !HelpSystem.getSearchManager().isIndexingNeeded(

+				searchQuery.getInfoset(),

+				searchQuery.getLocale()))

+			return true;

+

+		ProgressMonitorDialog mon =

+			new ProgressMonitorDialog(Display.getDefault().getActiveShell());

+		mon.setCancelable(true);

+

+		IRunnableWithProgress indexingRunnable = new IRunnableWithProgress() {

+			public void run(IProgressMonitor monitor)

+				throws InvocationTargetException, InterruptedException {

+				String infoSet =

+					HelpSystem

+						.getNavigationManager()

+						.getCurrentNavigationModel()

+						.getRootElement()

+						.getID();

+				try {

+					HelpSystem.getSearchManager().updateIndex(

+						searchQuery.getInfoset(),

+						monitor,

+						searchQuery.getLocale());

+				} catch (Exception e) {

+					throw new InvocationTargetException(e);

+				}

+			}

+		};

+

+		try {

+			mon.run(true, true, indexingRunnable); // throws InvocationTargetException

+		} catch (InterruptedException ie) {

+			return false;

+		} catch (InvocationTargetException e) {

+			// wraps OperationCanceledException or Exception in case of error

+			return false;

+		}

+		return true;

+	}

+	public Control getControl() {

+		return control;

+	}

+	/**

+	 * Returns the current selection for this provider.

+	 * 

+	 * @return the current selection

+	 */

+	public ISelection getSelection() {

+		if (resultsViewer != null)

+			return resultsViewer.getSelection();

+		return null;

+	}

+	/**

+	 * Handles double clicks in viewer.

+	 * Opens editor if file double-clicked.

+	 */

+	void handleDoubleClick(DoubleClickEvent event) {

+

+		IStructuredSelection s = (IStructuredSelection) event.getSelection();

+		Object element = s.getFirstElement();

+		// Double-clicking in navigator should expand/collapse containers

+		if (resultsViewer != null && resultsViewer.isExpandable(element)) {

+			resultsViewer.setExpandedState(

+				element,

+				!resultsViewer.getExpandedState(element));

+		}

+	}

+	/**

+	 * Removes the given selection change listener from this selection provider.

+	 * Has no affect if an identical listener is not registered.

+	 *

+	 * @param listener a selection changed listener

+	 */

+	public void removeSelectionChangedListener(ISelectionChangedListener listener) {

+		if (resultsViewer != null)

+			resultsViewer.removeSelectionChangedListener(listener);

+		selectionChangedListeners.remove(listener);

+	}

+	/**

+	 * Sets the selection current selection for this selection provider.

+	 *

+	 * @param selection the new selection

+	 */

+	public void setSelection(ISelection selection) {

+		if (resultsViewer != null)

+			resultsViewer.setSelection((selection), true);

+	}

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/util/HelpPreferencePage.java b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/util/HelpPreferencePage.java
new file mode 100644
index 0000000..63ebcf2
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/util/HelpPreferencePage.java
@@ -0,0 +1,576 @@
+package org.eclipse.help.internal.ui.util;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+import org.eclipse.ui.*;

+import org.eclipse.ui.help.WorkbenchHelp;

+import org.eclipse.jface.preference.*;

+import org.eclipse.swt.widgets.*;

+import org.eclipse.swt.layout.*;

+import org.eclipse.swt.SWT;

+import org.eclipse.swt.graphics.Font;

+import org.eclipse.swt.events.*;

+import org.eclipse.help.internal.HelpSystem;

+import org.eclipse.help.internal.ui.WorkbenchHelpPlugin;

+import org.eclipse.help.internal.ui.IHelpUIConstants;

+

+/**

+ * This class implements a sample preference page that is 

+ * added to the preference dialog based on the registration.

+ */

+public class HelpPreferencePage

+	extends PreferencePage

+	implements IWorkbenchPreferencePage, Listener {

+	// Constants

+	public static final String LOG_LEVEL_KEY = "log_level";

+	public static final String LOCAL_SERVER_CONFIG = "local_server_config";

+	public static final String LOCAL_SERVER_ADDRESS_KEY = "local_server_addr";

+	public static final String LOCAL_SERVER_PORT_KEY = "local_server_port";

+	public static final String INSTALL_OPTION_KEY = "install";

+	public static final String SERVER_PATH_KEY = "server_path";

+	public static final String BROWSER_PATH_KEY = "browser_path";

+

+	private Button radioButtonLocal;

+	private Button radioButtonClient;

+	private Text textServerAddr;

+	private Text textServerPort;

+	private Text textServerPath;

+

+	private Button radioButtonError;

+	private Button radioButtonWarning;

+	private Button radioButtonDebug;

+

+	private Text textBrowserPath; // on linux only

+

+	private Button radioButtonLocalServerAutomatic;

+	private Button radioButtonLocalServerManual;

+

+	/**

+	 * Creates an new checkbox instance and sets the default

+	 * layout data.

+	 *

+	 * @param group  the composite in which to create the checkbox

+	 * @param label  the string to set into the checkbox

+	 * @return the new checkbox

+	 */

+	private Button createCheckBox(Composite group, String label) {

+		Button button = new Button(group, SWT.CHECK | SWT.LEFT);

+		button.setText(label);

+		button.addListener(SWT.Selection, this);

+		GridData data = new GridData();

+		button.setLayoutData(data);

+		return button;

+	}

+	/**

+	 * Creates composite control and sets the default layout data.

+	 *

+	 * @param parent  the parent of the new composite

+	 * @param numColumns  the number of columns for the new composite

+	 * @return the newly-created coposite

+	 */

+	private Composite createComposite(Composite parent, int numColumns) {

+		Composite composite = new Composite(parent, SWT.NULL);

+

+		//GridLayout

+		GridLayout layout = new GridLayout();

+		layout.numColumns = numColumns;

+		composite.setLayout(layout);

+

+		//GridData

+		GridData data = new GridData();

+		data.verticalAlignment = GridData.FILL;

+		data.horizontalAlignment = GridData.FILL;

+		data.grabExcessHorizontalSpace = true;

+		composite.setLayoutData(data);

+		return composite;

+	}

+	/**

+	 * Creates preference page controls on demand.

+	 *

+	 * @param parent  the parent for the preference page

+	 */

+	protected Control createContents(Composite parent) {

+		WorkbenchHelp.setHelp(

+			parent,

+			new String[] { IHelpUIConstants.PREF_PAGE });

+

+		/* Installation Options */

+		//composite_tab << parent

+		Composite composite_tab = createComposite(parent, 1);

+		WorkbenchHelp.setHelp(

+			composite_tab,

+			new String[] {

+				IHelpUIConstants.INSTALL_OPTIONS,

+				IHelpUIConstants.PREF_PAGE});

+

+		Label label1 =

+			createLabel(

+				composite_tab,

+				WorkbenchResources.getString("Installation_Options"),

+				1);

+

+		//radio button composite << tab composite

+		Composite composite_radioButton = createComposite(composite_tab, 2);

+		radioButtonLocal =

+			createRadioButton(

+				composite_radioButton,

+				WorkbenchResources.getString("Local_install"));

+		tabForward(composite_radioButton);

+		radioButtonLocal.addSelectionListener(new SelectionListener() {

+			public void widgetSelected(SelectionEvent event) {

+				if (((Button) event.widget).getSelection()) {

+					textServerPath.setEnabled(false);

+				}

+			}

+			public void widgetDefaultSelected(SelectionEvent event) {

+				widgetSelected(event);

+			}

+		});

+

+		radioButtonClient =

+			createRadioButton(

+				composite_radioButton,

+				WorkbenchResources.getString("Client_only"));

+		tabForward(composite_radioButton);

+		radioButtonClient.addSelectionListener(new SelectionListener() {

+			public void widgetSelected(SelectionEvent event) {

+				if (((Button) event.widget).getSelection()) {

+					textServerPath.setEnabled(true);

+				}

+			}

+			public void widgetDefaultSelected(SelectionEvent event) {

+				widgetSelected(event);

+			}

+		});

+

+		Label label_textField =

+			createLabel(

+				composite_radioButton,

+				WorkbenchResources.getString("Server_path"),

+				1);

+		textServerPath = createTextField(composite_radioButton);

+

+		/* Browser Path */

+		if (!System.getProperty("os.name").startsWith("Win")) {

+			Composite composite_textField2 = createComposite(parent, 2);

+			WorkbenchHelp.setHelp(

+				composite_textField2,

+				new String[] {

+					IHelpUIConstants.BROWSER_PATH,

+					IHelpUIConstants.PREF_PAGE});

+

+			label_textField =

+				createLabel(

+					composite_textField2,

+					WorkbenchResources.getString("Browser_path"),

+					1);

+			textBrowserPath = createTextField(composite_textField2);

+		}

+

+		/* Advanced Group */

+		Group advancedGroup =

+			createGroup(parent, WorkbenchResources.getString("Advanced_Properties"));

+

+		/* Loggin Options */

+		//composite_tab2 << parent

+		Composite composite_tab2 = createComposite(advancedGroup, 1);

+		WorkbenchHelp.setHelp(

+			composite_tab2,

+			new String[] {

+				IHelpUIConstants.LOGGING_OPTIONS,

+				IHelpUIConstants.PREF_PAGE});

+		Label label2 =

+			createLabel(composite_tab2, WorkbenchResources.getString("Logging_Options"), 1);

+

+		//composite_checkBox << composite_tab2

+		Composite composite_radioButton2 = createComposite(composite_tab2, 1);

+		radioButtonError =

+			createRadioButton(

+				composite_radioButton2,

+				WorkbenchResources.getString("Errors_only"));

+		radioButtonWarning =

+			createRadioButton(

+				composite_radioButton2,

+				WorkbenchResources.getString("Warnings_and_errors"));

+		radioButtonDebug =

+			createRadioButton(

+				composite_radioButton2,

+				WorkbenchResources.getString("Everything"));

+

+		/* Local Server Configuration */

+		//composite_tab3 << parent

+		Composite composite_tab3 = createComposite(advancedGroup, 1);

+		WorkbenchHelp.setHelp(

+			composite_tab3,

+			new String[] {

+				IHelpUIConstants.LOCAL_SERVER_CONFIG,

+				IHelpUIConstants.PREF_PAGE});

+		Label label31 =

+			createLabel(

+				composite_tab3,

+				WorkbenchResources.getString("Local_server_config"),

+				1);

+

+		//radio button composite << tab composite

+		Composite composite_radioButton3 = createComposite(composite_tab3, 2);

+		radioButtonLocalServerAutomatic =

+			createRadioButton(

+				composite_radioButton3,

+				WorkbenchResources.getString("Local_server_config_automatic"));

+		tabForward(composite_radioButton3);

+		radioButtonLocalServerAutomatic.addSelectionListener(new SelectionListener() {

+			public void widgetSelected(SelectionEvent event) {

+				if (((Button) event.widget).getSelection()) {

+					textServerAddr.setEnabled(false);

+					textServerPort.setEnabled(false);

+				}

+			}

+			public void widgetDefaultSelected(SelectionEvent event) {

+				widgetSelected(event);

+			}

+		});

+

+		radioButtonLocalServerManual =

+			createRadioButton(

+				composite_radioButton3,

+				WorkbenchResources.getString("Local_server_config_manual"));

+		tabForward(composite_radioButton3);

+		radioButtonLocalServerManual.addSelectionListener(new SelectionListener() {

+			public void widgetSelected(SelectionEvent event) {

+				if (((Button) event.widget).getSelection()) {

+					textServerAddr.setEnabled(true);

+					textServerPort.setEnabled(true);

+				}

+			}

+			public void widgetDefaultSelected(SelectionEvent event) {

+				widgetSelected(event);

+			}

+		});

+		label_textField =

+			createLabel(

+				composite_radioButton3,

+				WorkbenchResources.getString("Server_address"),

+				1);

+		textServerAddr = createTextField(composite_radioButton3);

+

+		label_textField =

+			createLabel(

+				composite_radioButton3,

+				WorkbenchResources.getString("Server_port"),

+				1);

+		textServerPort = createTextField(composite_radioButton3);

+

+		initializeValues();

+

+		//font = null;

+		return new Composite(parent, SWT.NULL);

+	}

+	/**

+	 * Utility method that creates a group instance

+	 * and sets the default layout data.

+	 *

+	 * @param parent  the parent for the new button

+	 * @param label  the label for the new group

+	 * @return the newly-created group

+	 */

+	private Group createGroup(Composite parent, String label) {

+		Group group = new Group(parent, SWT.SHADOW_NONE);

+		group.setText(label);

+		//GridLayout

+		group.setLayout(new GridLayout());

+		//GridData

+		GridData data = new GridData();

+		data.verticalAlignment = GridData.FILL;

+		data.horizontalAlignment = GridData.FILL;

+		data.grabExcessHorizontalSpace = true;

+		group.setLayoutData(data);

+

+		return group;

+	}

+	/**

+	 * Utility method that creates a label instance

+	 * and sets the default layout data.

+	 *

+	 * @param parent  the parent for the new label

+	 * @param text  the text for the new label

+	 * @return the new label

+	 */

+	private Label createLabel(Composite parent, String text, int columns) {

+		Label label = new Label(parent, SWT.LEFT);

+		label.setText(text);

+		GridData data = new GridData();

+		data.horizontalSpan = columns;

+		data.horizontalAlignment = GridData.FILL;

+		label.setLayoutData(data);

+		return label;

+	}

+	/**

+	 * Utility method that creates a push button instance

+	 * and sets the default layout data.

+	 *

+	 * @param parent  the parent for the new button

+	 * @param label  the label for the new button

+	 * @return the newly-created button

+	 */

+	private Button createPushButton(Composite parent, String label) {

+		Button button = new Button(parent, SWT.PUSH);

+		button.setText(label);

+		button.addListener(SWT.Selection, this);

+		GridData data = new GridData();

+		data.horizontalAlignment = GridData.FILL;

+		button.setLayoutData(data);

+		return button;

+	}

+	/**

+	 * Utility method that creates a radio button instance

+	 * and sets the default layout data.

+	 *

+	 * @param parent  the parent for the new button

+	 * @param label  the label for the new button

+	 * @return the newly-created button

+	 */

+	private Button createRadioButton(Composite parent, String label) {

+		Button button = new Button(parent, SWT.RADIO | SWT.LEFT);

+		button.setText(label);

+		button.addListener(SWT.Selection, this);

+		GridData data = new GridData();

+		button.setLayoutData(data);

+		return button;

+	}

+	/**

+	 * Create a text field specific for this application

+	 *

+	 * @param parent  the parent of the new text field

+	 * @return the new text field

+	 */

+	private Text createTextField(Composite parent) {

+		Text text = new Text(parent, SWT.SINGLE | SWT.BORDER);

+		text.addListener(SWT.Modify, this);

+		GridData data = new GridData();

+		data.horizontalAlignment = GridData.FILL;

+		data.grabExcessHorizontalSpace = true;

+		data.verticalAlignment = GridData.CENTER;

+		data.grabExcessVerticalSpace = false;

+		text.setLayoutData(data);

+		return text;

+	}

+	/**

+	 * Returns preference store that belongs to the our plugin.

+	 * This is important because we want to store

+	 * our preferences separately from the desktop.

+	 *

+	 * @return the preference store for this plugin

+	 */

+	protected IPreferenceStore doGetPreferenceStore() {

+		return WorkbenchHelpPlugin.getDefault().getPreferenceStore();

+	}

+	/**

+	 * Handles events generated by controls on this page.

+	 *

+	 * @param e  the event to handle

+	 */

+	public void handleEvent(Event e) {

+		//get widget that generates the event

+		Widget source = e.widget;

+		// add the code that should react to

+		// some widget event

+	}

+	/**

+	 * @see IWorkbenchPreferencePage

+	 */

+	public void init(IWorkbench workbench) {

+	}

+	/**

+	 * Initializes states of the controls using default values

+	 * in the preference store.

+	 */

+	private void initializeDefaults() {

+		IPreferenceStore store = getPreferenceStore();

+

+		// Local Help Server Configuration

+		radioButtonLocalServerAutomatic.setSelection(false);

+		radioButtonLocalServerManual.setSelection(false);

+		textServerAddr.setEnabled(false);

+		textServerPort.setEnabled(false);

+		int serverConfigChoice = store.getDefaultInt(LOCAL_SERVER_CONFIG);

+		switch (serverConfigChoice) {

+			case 0 :

+				radioButtonLocalServerAutomatic.setSelection(true);

+				break;

+			case 1 :

+				radioButtonLocalServerManual.setSelection(true);

+				textServerAddr.setEnabled(true);

+				textServerPort.setEnabled(true);

+				break;

+		}

+		textServerAddr.setText(store.getDefaultString(LOCAL_SERVER_ADDRESS_KEY));

+		textServerPort.setText(store.getDefaultString(LOCAL_SERVER_PORT_KEY));

+

+		// Documentation local/remote

+		radioButtonLocal.setSelection(false);

+		radioButtonClient.setSelection(false);

+		int choice = store.getDefaultInt(INSTALL_OPTION_KEY);

+		switch (choice) {

+			case 0 :

+				radioButtonLocal.setSelection(true);

+				textServerPath.setEnabled(false);

+				break;

+			case 1 :

+				radioButtonClient.setSelection(true);

+				textServerPath.setEnabled(true);

+				break;

+		}

+		textServerPath.setText(store.getDefaultString(SERVER_PATH_KEY));

+

+		radioButtonError.setSelection(false);

+		radioButtonWarning.setSelection(false);

+		radioButtonDebug.setSelection(false);

+		choice = store.getDefaultInt(LOG_LEVEL_KEY);

+		switch (choice) {

+			case HelpSystem.LOG_ERROR :

+				radioButtonError.setSelection(true);

+				break;

+			case HelpSystem.LOG_WARNING :

+				radioButtonWarning.setSelection(true);

+				break;

+			case HelpSystem.LOG_DEBUG :

+				radioButtonDebug.setSelection(true);

+				break;

+		}

+

+		if (!System.getProperty("os.name").startsWith("Win")) {

+			textBrowserPath.setText(store.getDefaultString(BROWSER_PATH_KEY));

+		}

+	}

+	/**

+	 * Initializes states of the controls from the preference store.

+	 */

+	private void initializeValues() {

+		IPreferenceStore store = getPreferenceStore();

+

+		// Local Help Server Configuration

+		radioButtonLocalServerAutomatic.setSelection(false);

+		radioButtonLocalServerManual.setSelection(false);

+		textServerAddr.setEnabled(false);

+		textServerPort.setEnabled(false);

+		int serverConfigChoice = store.getInt(LOCAL_SERVER_CONFIG);

+		switch (serverConfigChoice) {

+			case 0 :

+				radioButtonLocalServerAutomatic.setSelection(true);

+				break;

+			case 1 :

+				radioButtonLocalServerManual.setSelection(true);

+				textServerAddr.setEnabled(true);

+				textServerPort.setEnabled(true);

+				break;

+		}

+		textServerAddr.setText(store.getString(LOCAL_SERVER_ADDRESS_KEY));

+		textServerPort.setText(store.getString(LOCAL_SERVER_PORT_KEY));

+

+		// Documentation local/remote

+		radioButtonLocal.setSelection(false);

+		radioButtonClient.setSelection(false);

+		int choice = store.getInt(INSTALL_OPTION_KEY);

+		switch (choice) {

+			case 0 :

+				radioButtonLocal.setSelection(true);

+				textServerPath.setEnabled(false);

+				break;

+			case 1 :

+				radioButtonClient.setSelection(true);

+				textServerPath.setEnabled(true);

+				break;

+		}

+		textServerPath.setText(store.getString(SERVER_PATH_KEY));

+

+		radioButtonError.setSelection(false);

+		radioButtonWarning.setSelection(false);

+		radioButtonDebug.setSelection(false);

+		choice = store.getInt(LOG_LEVEL_KEY);

+		switch (choice) {

+			case HelpSystem.LOG_ERROR :

+				radioButtonError.setSelection(true);

+				break;

+			case HelpSystem.LOG_WARNING :

+				radioButtonWarning.setSelection(true);

+				break;

+			case HelpSystem.LOG_DEBUG :

+				radioButtonDebug.setSelection(true);

+				break;

+		}

+

+		if (!System.getProperty("os.name").startsWith("Win")) {

+			textBrowserPath.setText(store.getString(BROWSER_PATH_KEY));

+		}

+	}

+	/**

+	 * Does anything necessary because the default button has been pressed.

+	 */

+	protected void performDefaults() {

+		super.performDefaults();

+		initializeDefaults();

+	}

+	/**

+	 * Do anything necessary because the OK button has been pressed.

+	 *

+	 * @return whether it is okay to close the preference page

+	 */

+	public boolean performOk() {

+		storeValues();

+		return true;

+	}

+	/**

+	 * Stores the values of the controls back to the preference store.

+	 */

+	private void storeValues() {

+		IPreferenceStore store = getPreferenceStore();

+

+		int choice = 0;

+		if (radioButtonClient.getSelection())

+			choice = 1;

+		//else if (radioButtonServer.getSelection()) choice = 2;

+		store.setValue(INSTALL_OPTION_KEY, choice);

+

+		choice = 0;

+		if (radioButtonLocalServerManual.getSelection())

+			choice = 1;

+		store.setValue(LOCAL_SERVER_CONFIG, choice);

+

+		store.setValue(LOCAL_SERVER_ADDRESS_KEY, textServerAddr.getText());

+		store.setValue(LOCAL_SERVER_PORT_KEY, textServerPort.getText());

+		store.setValue(SERVER_PATH_KEY, textServerPath.getText());

+

+		choice = 0;

+		if (radioButtonWarning.getSelection())

+			choice = 1;

+		else

+			if (radioButtonDebug.getSelection())

+				choice = 2;

+		store.setValue(LOG_LEVEL_KEY, choice);

+		HelpSystem.setDebugLevel(choice);

+

+		if (!System.getProperty("os.name").startsWith("Win")) {

+			store.setValue(BROWSER_PATH_KEY, textBrowserPath.getText());

+		}

+		// set the value in the current session 

+		WorkbenchHelpPlugin.getDefault().initializeFromStore();

+	}

+	/**

+	 * Creates a tab of one horizontal spans.

+	 *

+	 * @param parent  the parent in which the tab should be created

+	 */

+	private void tabForward(Composite parent) {

+		Label vfiller = new Label(parent, SWT.LEFT);

+		GridData gridData = new GridData();

+		gridData = new GridData();

+		gridData.horizontalAlignment = GridData.BEGINNING;

+		gridData.grabExcessHorizontalSpace = false;

+		gridData.verticalAlignment = GridData.CENTER;

+		gridData.grabExcessVerticalSpace = false;

+		vfiller.setLayoutData(gridData);

+	}

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/util/HelpWorkbenchException.java b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/util/HelpWorkbenchException.java
new file mode 100644
index 0000000..a427de7
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/util/HelpWorkbenchException.java
@@ -0,0 +1,20 @@
+package org.eclipse.help.internal.ui.util;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+

+// possibly use platform CoreException later. For now, this is

+// handled by the Logger class in base.

+

+public class HelpWorkbenchException extends Exception {

+

+	public HelpWorkbenchException() {

+		super();

+	}

+	public HelpWorkbenchException(String message) {

+		super(message);

+	}

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/util/RuntimeErrorDialog.java b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/util/RuntimeErrorDialog.java
new file mode 100644
index 0000000..5916d36
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/util/RuntimeErrorDialog.java
@@ -0,0 +1,102 @@
+package org.eclipse.help.internal.ui.util;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+

+import org.eclipse.swt.widgets.*;

+import org.eclipse.swt.*;

+import org.eclipse.swt.layout.*;

+import org.eclipse.jface.dialogs.*;

+

+/**

+ * This is the Dialog box that displays all the errors the occur during the

+ * initial load of the Help System. It's data (model) is taken from the

+ * RuntimeHelpStatus object.

+ */

+

+public class RuntimeErrorDialog extends MessageDialog {

+	private static String errorStringToDisplay = null;

+

+	/**

+	 * RuntimeErrorDialog constructor comment.

+	 * @param dialogTitle java.lang.String

+	 * @param dialogTitleImage org.eclipse.swt.graphics.Image

+	 * @param dialogMessage java.lang.String

+	 * @param dialogImageType int

+	 * @param dialogButtonLabels java.lang.String[]

+	 * @param defaultIndex int

+	 */

+	public RuntimeErrorDialog(

+		Shell parentShell,

+		String dialogTitle,

+		org.eclipse.swt.graphics.Image dialogTitleImage,

+		String dialogMessage,

+		int dialogImageType,

+		java.lang.String[] dialogButtonLabels,

+		int defaultIndex) {

+		super(

+			parentShell,

+			dialogTitle,

+			dialogTitleImage,

+			dialogMessage,

+			dialogImageType,

+			dialogButtonLabels,

+			defaultIndex);

+	}

+	protected Control createCustomArea(Composite parent) {

+

+		Composite composite = new Composite(parent, SWT.RESIZE);

+		GridLayout layout = new GridLayout();

+		layout.numColumns = 2;

+		layout.marginHeight =

+			convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);

+		layout.marginWidth =

+			convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);

+		layout.horizontalSpacing =

+			convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);

+		composite.setLayout(layout);

+		composite.setLayoutData(new GridData(GridData.FILL_BOTH));

+

+		// set error message

+		if (errorStringToDisplay != null) {

+			Text text =

+				new Text(

+					composite,

+					SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.READ_ONLY | SWT.MULTI);

+			text.setText(errorStringToDisplay);

+			GridData data =

+				new GridData(

+					GridData.GRAB_HORIZONTAL

+						| GridData.GRAB_VERTICAL

+						| GridData.HORIZONTAL_ALIGN_FILL

+						| GridData.VERTICAL_ALIGN_CENTER);

+			data.widthHint = getMinimumMessageWidth();

+			text.setLayoutData(data);

+			text.setBackground(composite.getDisplay().getSystemColor(SWT.COLOR_WHITE));

+

+		}

+		return composite;

+

+	}

+	public static void open(

+		Shell parentShell,

+		String title,

+		String message,

+		String errorString) {

+		errorStringToDisplay = errorString;

+			RuntimeErrorDialog dialog =

+				new RuntimeErrorDialog(

+					parentShell,

+					title,

+					null,

+		// accept the default window icon

+	message, ERROR, new String[] { IDialogConstants.OK_LABEL }, 0);

+		// ok is the default

+		dialog.open();

+		return;

+

+	}

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/util/StreamConsumer.java b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/util/StreamConsumer.java
new file mode 100644
index 0000000..2b44424
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/util/StreamConsumer.java
@@ -0,0 +1,30 @@
+package org.eclipse.help.internal.ui.util;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+

+import java.io.*;

+

+/**

+ * Used to destroy output from processes

+ */

+public class StreamConsumer extends Thread {

+	InputStream is;

+	byte[] buf;

+	public StreamConsumer(InputStream inputStream) {

+		super();

+		this.is = inputStream;

+		buf = new byte[512];

+	}

+	public void run() {

+		try {

+			int n = 0;

+			while (n >= 0)

+				n = is.read(buf);

+		} catch (IOException ioe) {

+		}

+	}

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/util/TString.java b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/util/TString.java
new file mode 100644
index 0000000..0c50bfb
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/util/TString.java
@@ -0,0 +1,325 @@
+package org.eclipse.help.internal.ui.util;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+

+import java.util.StringTokenizer;

+

+/**

+ * This class provides static methods for some of the

+ * very used IString operations

+ */

+public class TString {

+	private static final String ALPHABET =

+		"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

+	private static final String ALPHANUMERIC =

+		"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

+	private static final String NUMERIC = "0123456789";

+

+	// change all occurrences of oldPat to newPat

+	public static String change(String in, String oldPat, String newPat) {

+		if (oldPat.length() == 0)

+			return in;

+		if (oldPat.length() == 1 && newPat.length() == 1)

+			return in.replace(oldPat.charAt(0), newPat.charAt(0));

+

+		int lastIndex = 0;

+		int newIndex = 0;

+		StringBuffer newString = new StringBuffer();

+		for (;;) {

+			newIndex = in.indexOf(oldPat, lastIndex);

+			if (newIndex != -1) {

+				newString.append(in.substring(lastIndex, newIndex) + newPat);

+				lastIndex = newIndex + oldPat.length();

+			} else {

+				newString.append(in.substring(lastIndex));

+				break;

+			}

+		}

+		return newString.toString();

+	}

+	// change the occurrences of oldPat to newPat starting at startPosition

+	// for number of numChanges

+	// Note: the 1st char in the string has position of 0

+

+	public static String change(

+		String in,

+		String oldPat,

+		String newPat,

+		int startPos,

+		int numChanges) {

+		if (oldPat.length() == 0)

+			return in;

+		if (oldPat.length() == 1 && newPat.length() == 1)

+			return in.replace(oldPat.charAt(0), newPat.charAt(0));

+

+		int inLen = in.length();

+

+		if (startPos >= inLen)

+			return in;

+

+		int lastIndex = startPos;

+		int newIndex = 0;

+		int countChanges = 0;

+

+		StringBuffer newString = new StringBuffer();

+

+		for (;;) {

+			newIndex = in.indexOf(oldPat, lastIndex);

+			if (newIndex != -1) {

+				newString.append(in.substring(lastIndex, newIndex) + newPat);

+				lastIndex = newIndex + oldPat.length();

+				countChanges++;

+			} else {

+				newString.append(in.substring(lastIndex));

+				break;

+			}

+

+			if (countChanges == numChanges) {

+				newString.append(in.substring(lastIndex));

+				break;

+			}

+		}

+

+		return newString.toString();

+	}

+	// return true if the "  " appears within srcString

+	// example:

+	//   srcString = "a  m"

+	//   return = true

+

+	public static boolean containsDoubleBlanks(String srcString) {

+		String bb = "  ";

+		char b = bb.charAt(0);

+

+		if (srcString.length() > 0) {

+			for (int i = 0; i < (srcString.length() - 1); i++) {

+				if ((b == srcString.charAt(i)) & (b == srcString.charAt(i + 1)))

+					return true;

+			}

+		}

+		return false;

+	}

+	// return a string that contains number of copies of srcString

+	// example:

+	//   srcString = "abc"

+	//   numberOfCopies = 2

+	//   return string = "abcabc"

+

+	public static String copy(String srcString, int numberOfCopies) {

+		StringBuffer result = new StringBuffer();

+

+		if (numberOfCopies > 0) {

+			for (int i = 1; i <= numberOfCopies; i++)

+				result.append(srcString);

+		} else

+			result = new StringBuffer(srcString);

+

+		return result.toString();

+	}

+	public static long getLong(String str) {

+		try {

+			return Long.parseLong(str);

+		} catch (Exception m) {

+			return 0;

+		}

+	}

+	// return the first index within srcString that is not in the validString

+	// example:

+	//   srcString = "abcdefg"

+	//   validString = "bcfg"

+	//   return = 0 (i.e. char a is not in "bcfg")  - 1st index = 0

+

+	public static int indexOfAnyBut(String srcString, String validString) {

+		int result = -1;

+		int srcLen = srcString.length();

+

+		// walk backward to find if a char within srcString is in validString

+		for (int i = 0; i < srcLen; i++) {

+			// not found, stop it

+			if (validString.indexOf(srcString.charAt(i)) == -1) {

+				result = i;

+				break;

+			}

+

+		}

+

+		return result;

+	}

+	//

+	// return true if all chars in srcString are in {a...z} or {A...Z}

+

+	public static boolean isAlphabetic(String srcString) {

+		return (lastIndexOfAnyBut(srcString, ALPHABET) == -1);

+	}

+	//

+	// return true if all chars in srcString are in {a...z,} or {A...Z} {0...9}

+

+	public static boolean isAlphanumeric(String srcString) {

+		return (lastIndexOfAnyBut(srcString, ALPHANUMERIC) == -1);

+	}

+	//

+	// return true if all chars are in '0' - '9'

+

+	public static boolean isDigits(String srcString) {

+		return (lastIndexOfAnyBut(srcString, NUMERIC) == -1);

+	}

+	// return the last index within srcString that is not in the validString

+	// example:

+	//   srcString = "abcdefg"

+	//   validString = "bcfg"

+	//   return = 4 (i.e. char e is not in "bcfg")  - 1st index = 0

+

+	public static int lastIndexOfAnyBut(String srcString, String validString) {

+		int result = -1;

+		int srcLen = srcString.length();

+

+		// walk backward to find if a char within srcString is in validString

+		for (int i = srcLen - 1; i >= 0; i--) {

+			// not found, stop it

+			if (validString.indexOf(srcString.charAt(i)) == -1) {

+				result = i;

+				break;

+			}

+

+		}

+

+		return result;

+	}

+	//

+	// return the string after the matching token is removed

+	public static String match(String in, String token) throws Exception {

+		if (in == null)

+			return null;

+

+		in = in.trim();

+		if (in.startsWith(token))

+			return in.substring(token.length(), in.length());

+		else

+			throw new Exception(

+				WorkbenchResources.getString("Expected", token, word(in, 1)));

+

+	}

+	public static int numWords(String in) {

+		StringTokenizer st = new StringTokenizer(in);

+		return st.countTokens();

+	}

+	// return number of occurrences of searchChar within srcString

+	// example:

+	//   srcString = "::f::f::g"

+	//   seachrChar = ':'

+	//   return = 6

+

+	public static int occurrenceOf(String srcString, char searchChar) {

+		int result = 0;

+		// walk backward to find if a char within srcString is in validString

+		if (srcString.length() > 0) {

+

+			for (int i = 0; i < srcString.length(); i++) {

+				//  found, increment the count

+				if (searchChar == srcString.charAt(i))

+					result++;

+			}

+		}

+

+		return result;

+	}

+	// strip the leading pString in the srcString

+	// example:

+	//   srcString = "::f::f::g"

+	//   pString "::"

+	//   return = "f::f::g"

+

+	public static String stripLeading(String srcString, String pString) {

+		String result;

+

+		if (srcString.startsWith(pString)) // leading patString found

+			result = srcString.substring(pString.length(), srcString.length());

+		else // not found

+			result = srcString;

+

+		return result;

+	}

+	public static String stripSpace(String srcString) {

+		String b1 = " ";

+		int lastIndex = 0;

+		int newIndex = 0;

+		StringBuffer newString = new StringBuffer();

+		for (;;) {

+			newIndex = srcString.indexOf(b1, lastIndex);

+			if (newIndex != -1) {

+				newString.append(srcString.substring(lastIndex, newIndex));

+				lastIndex = newIndex + 1;

+			} else {

+				newString.append(srcString.substring(lastIndex));

+				break;

+			}

+		}

+		return newString.toString();

+	}

+	// strip the trailing pString in the srcString

+	// example:

+	//   srcString = "f::f::g::"

+	//   pString "::"

+	//   return = "f::f::g"

+

+	public static String stripTrailing(String srcString, String pString) {

+		String result;

+

+		if (srcString.endsWith(pString)) // leading patString found

+			result = srcString.substring(0, srcString.lastIndexOf(pString));

+		else // not found

+			result = srcString;

+

+		return result;

+	}

+	/**

+	 *  strip the trailing blanks in the src

+	 */

+	public static String stripTrailingBlanks(String src) {

+

+		if (src != null) {

+			while (src.length() > 0) {

+				if (src.endsWith(" "))

+					src = src.substring(0, src.length() - 1);

+				else

+					break;

+			}

+		}

+

+		return src;

+	}

+	public static String word(String in, int i) {

+		StringTokenizer st = new StringTokenizer(in);

+		if (i <= 0 || i > st.countTokens())

+			return "";

+		else {

+			String ret = new String();

+			while (st.hasMoreTokens()) {

+				ret = st.nextToken();

+				if (--i == 0)

+					return ret;

+			}

+		}

+		return "";

+	}

+	public static String words(String in, int i) {

+		StringTokenizer st = new StringTokenizer(in);

+		if (i <= 0 || i > st.countTokens())

+			return "";

+		else {

+			while (st.hasMoreTokens()) {

+				if (--i == 0)

+					break;

+				st.nextToken();

+			}

+			if (st.hasMoreTokens())

+				return st.nextToken("");

+			else

+				return "";

+		}

+	}

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/util/Util.java b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/util/Util.java
new file mode 100644
index 0000000..2fab207
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/util/Util.java
@@ -0,0 +1,87 @@
+package org.eclipse.help.internal.ui.util;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+

+

+import org.eclipse.jface.dialogs.MessageDialog;

+import org.eclipse.swt.widgets.Shell;

+import org.eclipse.ui.*;

+import org.eclipse.help.internal.util.*;

+

+/**

+ * Utiliy class for common tasks

+ */

+

+public class Util {

+/**

+ * Immidiately displays error dialog with a given string,

+ * also logs the error using Logger.logError().

+ * msg error message to display and log.

+ */

+public static void displayErrorDialog(String msg) {

+	String title = WorkbenchResources.getString("Help_Error");

+	Shell parent = getActiveWorkbenchWindow().getShell();

+	MessageDialog.openError(parent, title, msg);

+	Logger.logError(msg, null);

+}

+/**

+ * Immidiately displays error dialog with a given string,

+ * also logs the error using Logger.logError().

+ * msg error message to display and log.

+ * ex  the exception to be passed to Logger.logError()

+ */

+public static void displayErrorDialog(String msg, Throwable ex) {

+	String title = WorkbenchResources.getString("Help_Error");

+	Shell parent = getActiveWorkbenchWindow().getShell();

+	MessageDialog.openError(parent, title, msg);

+	Logger.logError(msg, ex);

+}

+/**

+ * Immidiately displays an Information dialog with a given string,

+ * also logs the info using Logger.logInfo().

+ * msg error message to display and log.

+ */

+public static void displayInfoDialog(String msg) {

+	String title = WorkbenchResources.getString("Help_Info");

+	Shell parent = getActiveWorkbenchWindow().getShell();

+	MessageDialog.openInformation(parent, title, msg);

+	Logger.logInfo(msg);

+}

+/**

+ * Immidiately displays a Question dialog with a given string (question).

+ * No logging is done.

+ * returns which button(Yes/No) was pressed by user

+ */

+public static boolean displayQuestionDialog(String msg) {

+	String title = WorkbenchResources.getString("Help_Question");

+	Shell parent = getActiveWorkbenchWindow().getShell();

+	return MessageDialog.openQuestion(parent, title, msg);

+}

+/**

+ * Display all errors in the Help Status object. If no errors occurred,

+ * or if errors have already been displayed, return.

+ */

+public static void displayStatus() {

+	// show error dialog box if errors have occurred

+	if (RuntimeHelpStatus.getInstance().errorsExist()) {

+		String title = WorkbenchResources.getString("Help_Error");

+		String msg = WorkbenchResources.getString("WE005");

+		String errorMessage = RuntimeHelpStatus.getInstance().toString();

+		Shell parent = getActiveWorkbenchWindow().getShell();

+		

+		RuntimeErrorDialog.open(parent, title, msg, errorMessage);

+

+		// for now, reset status object so that errors are not

+		// displayed again.

+		RuntimeHelpStatus.getInstance().reset();

+	}

+	return;

+}

+	public static IWorkbenchWindow getActiveWorkbenchWindow() {

+		return PlatformUI.getWorkbench().getActiveWorkbenchWindow();

+	}

+}

diff --git a/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/util/WorkbenchResources.java b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/util/WorkbenchResources.java
new file mode 100644
index 0000000..1c96399
--- /dev/null
+++ b/org.eclipse.help.ui/Eclipse Help UI/org/eclipse/help/internal/ui/util/WorkbenchResources.java
@@ -0,0 +1,202 @@
+package org.eclipse.help.internal.ui.util;

+

+/*

+ * Licensed Materials - Property of IBM,

+ * WebSphere Studio Workbench

+ * (c) Copyright IBM Corp 2000

+ */

+

+import java.util.*;

+import java.io.File;

+import java.net.URL;

+import java.net.MalformedURLException;

+import org.eclipse.help.internal.HelpSystem;

+

+/**

+ * Uses a resource bundle to load images and strings from

+ * a property file.

+ * This class needs to properly use the desired locale.

+ */

+public class WorkbenchResources {

+	//*** NOTE: change this to properly load a resource bundle help.properties

+	//***       for a desired locale....

+	private static ResourceBundle resBundle;

+	private static URL imageURL;

+

+	static {

+		//      System.out.println("WorkbenchResource: " + "HelpWorkbench_" + Locale.getDefault().toString());

+		resBundle = ResourceBundle.getBundle("HelpWorkbench", Locale.getDefault());

+		try {

+			imageURL =

+				new URL(HelpSystem.getPlugin().getDescriptor().getInstallURL(), "icons/");

+		} catch (MalformedURLException e) {

+		}

+

+	}

+	/**

+	 * WorkbenchResources constructor comment.

+	 */

+	public WorkbenchResources() {

+		super();

+	}

+	/**

+	 * Returns a string from a property file

+	 */

+	public static URL getImagePath(String name) {

+		URL imagePathURL = null;

+		try {

+			imagePathURL = new URL(imageURL, resBundle.getString(name));

+			return imagePathURL;

+		} catch (MalformedURLException e) {

+		}

+		//return image;

+		return null;

+	}

+	/**

+	 * Returns a string from a property file

+	 */

+	public static String getString(String name) {

+		try {

+			return resBundle.getString(name);

+		} catch (Exception e) {

+			return name;

+		}

+

+	}

+	/**

+	 * Returns a string from a property file

+	 */

+	public static String getString(String name, String replace1) {

+		try {

+			String stringFromPropertiesFile = resBundle.getString(name);

+			stringFromPropertiesFile =

+				TString.change(stringFromPropertiesFile, "%1", replace1);

+			return stringFromPropertiesFile;

+		} catch (Exception e) {

+			return name;

+		}

+

+	}

+	/**

+	 * Returns a string from a property file

+	 */

+	public static String getString(String name, String replace1, String replace2) {

+		try {

+			String stringFromPropertiesFile = resBundle.getString(name);

+			stringFromPropertiesFile =

+				TString.change(stringFromPropertiesFile, "%1", replace1);

+			stringFromPropertiesFile =

+				TString.change(stringFromPropertiesFile, "%2", replace2);

+			return stringFromPropertiesFile;

+		} catch (Exception e) {

+			return name;

+		}

+

+	}

+	/**

+	 * Returns a string from a property file

+	 */

+	public static String getString(

+		String name,

+		String replace1,

+		String replace2,

+		String replace3) {

+		try {

+			String stringFromPropertiesFile = resBundle.getString(name);

+			stringFromPropertiesFile =

+				TString.change(stringFromPropertiesFile, "%1", replace1);

+			stringFromPropertiesFile =

+				TString.change(stringFromPropertiesFile, "%2", replace2);

+			stringFromPropertiesFile =

+				TString.change(stringFromPropertiesFile, "%3", replace3);

+			return stringFromPropertiesFile;

+		} catch (Exception e) {

+			return name;

+		}

+

+	}

+	/**

+	 * Returns a string from a property file

+	 */

+	public static String getString(

+		String name,

+		String replace1,

+		String replace2,

+		String replace3,

+		String replace4) {

+		try {

+			String stringFromPropertiesFile = resBundle.getString(name);

+			stringFromPropertiesFile =

+				TString.change(stringFromPropertiesFile, "%1", replace1);

+			stringFromPropertiesFile =

+				TString.change(stringFromPropertiesFile, "%2", replace2);

+			stringFromPropertiesFile =

+				TString.change(stringFromPropertiesFile, "%3", replace3);

+			stringFromPropertiesFile =

+				TString.change(stringFromPropertiesFile, "%4", replace4);

+			return stringFromPropertiesFile;

+		} catch (Exception e) {

+			return name;

+		}

+

+	}

+	/**

+	 * Returns a string from a property file

+	 */

+	public static String getString(

+		String name,

+		String replace1,

+		String replace2,

+		String replace3,

+		String replace4,

+		String replace5) {

+		try {

+			String stringFromPropertiesFile = resBundle.getString(name);

+			stringFromPropertiesFile =

+				TString.change(stringFromPropertiesFile, "%1", replace1);

+			stringFromPropertiesFile =

+				TString.change(stringFromPropertiesFile, "%2", replace2);

+			stringFromPropertiesFile =

+				TString.change(stringFromPropertiesFile, "%3", replace3);

+			stringFromPropertiesFile =

+				TString.change(stringFromPropertiesFile, "%4", replace4);

+			stringFromPropertiesFile =

+				TString.change(stringFromPropertiesFile, "%5", replace5);

+			return stringFromPropertiesFile;

+		} catch (Exception e) {

+			return name;

+		}

+

+	}

+	/**

+	 * Returns a string from a property file

+	 */

+	public static String getString(

+		String name,

+		String replace1,

+		String replace2,

+		String replace3,

+		String replace4,

+		String replace5,

+		String replace6) {

+		try {

+			String stringFromPropertiesFile = resBundle.getString(name);

+			stringFromPropertiesFile =

+				TString.change(stringFromPropertiesFile, "%1", replace1);

+			stringFromPropertiesFile =

+				TString.change(stringFromPropertiesFile, "%2", replace2);

+			stringFromPropertiesFile =

+				TString.change(stringFromPropertiesFile, "%3", replace3);

+			stringFromPropertiesFile =

+				TString.change(stringFromPropertiesFile, "%4", replace4);

+			stringFromPropertiesFile =

+				TString.change(stringFromPropertiesFile, "%5", replace5);

+			stringFromPropertiesFile =

+				TString.change(stringFromPropertiesFile, "%6", replace6);

+			return stringFromPropertiesFile;

+		} catch (Exception e) {

+			return name;

+		}

+

+	}

+}

diff --git a/org.eclipse.help.ui/HelpContexts.xml b/org.eclipse.help.ui/HelpContexts.xml
new file mode 100644
index 0000000..755dc66
--- /dev/null
+++ b/org.eclipse.help.ui/HelpContexts.xml
@@ -0,0 +1,97 @@
+<contexts>

+   <context  id="f1Shell" >

+      <description>Pressing <b>F1</b> provides context sensitive help.</description>

+      <topic href="contexts/f1Shell1.html"  label="f1Shell Related Topic 1"/>

+      <topic href="contexts/f1Shell2.html"  label="f1Shell Related Topic 2"/>

+   </context>

+   <context  id="embeddedHelpView" >

+      <description><b>Navigate</b> to the desired topic in the <b>left</b> part of Help view.  <b>Topics</b> will be displayed on the <b>right</b>.</description>

+      <topic href="contexts/embeddedHelpView1.html"  label="embeddedHelpView Related Topic 1"/>

+      <topic href="contexts/embeddedHelpView2.html"  label="embeddedHelpView Related Topic 1"/>

+   </context>

+   <context  id="browser" >

+      <description>This displays <b>content of the document</b> that you select to view.</description>

+      <topic href="contexts/browser1.html"  label="browser Related Topic 1"/>

+      <topic href="contexts/browser2.html"  label="browser Related Topic 2"/>

+   </context>

+   <context  id="navigationViewer" >

+      <description>Select an <b>Information Set</b> from the drop down, and choose a tab with the <b>View</b> you prefer.</description>

+      <topic href="contexts/navigationViewer1.html"  label="navigationViewer Related Topic 1"/>

+      <topic href="contexts/navigationViewer2.html"  label="navigationViewer Related Topic 2"/>

+   </context>

+   <context  id="topicsViewer" >

+      <description>Expand <b>topic tree</b> to the desired topic and click on the topic to select it.</description>

+      <topic href="contexts/topicsViewer1.html"  label="topicsViewer Related Topic 1"/>

+      <topic href="contexts/topicsViewer2.html"  label="topicsViewer Related Topic 2"/>

+   </context>

+   <context  id="searchPage" >

+      <description><b>Type your query</b> in the text field, then select <b>GO</b> to perform search.</description>

+      <topic href="contexts/searchPage1.html"  label="searchPage Related Topic 1"/>

+      <topic href="contexts/searchPage2.html"  label="searchPage Related Topic 2"/>

+   </context>

+   <context  id="resultsViewer" >

+      <description>Expand <b>topic tree</b> to the desired topic and click on the topic to select it.</description>

+      <topic href="contexts/resultsViewer1.html"  label="resultsViewer Related Topic 1"/>

+      <topic href="contexts/resultsViewer2.html"  label="resultsViewer Related Topic 2"/>

+   </context>

+   <context  id="prefPage" >

+      <description>This options change <b>help configuration</b>.</description>

+      <topic href="contexts/prefPage1.html"  label="prefPage Related Topic 1"/>

+      <topic href="contexts/prefPage2.html"  label="prefPage Related Topic 2"/>

+   </context>

+   <context  id="installOptions" >

+      <description>This options allow you to specify <b>location of your documentation</b>.</description>

+      <topic href="contexts/installOptions1.html"  label="installOptions Related Topic 1"/>

+      <topic href="contexts/installOptions2.html"  label="installOptions Related Topic 2"/>

+   </context>

+   <context  id="browserPath" >

+      <description>This options allow you to specify <b>path to your browser</b>.</description>

+      <topic href="contexts/browserPath1.html"  label="browserPath Related Topic 1"/>

+      <topic href="contexts/browserPath2.html"  label="browserPath Related Topic 2"/>

+   </context>

+   <context  id="loggingOptions" >

+      <description>This options allow you to specify <b>level of logging</b>.</description>

+      <topic href="contexts/loggingOptions1.html"  label="loggingOptions Related Topic 1"/>

+      <topic href="contexts/loggingOptions2.html"  label="loggingOptions Related Topic 2"/>

+   </context>

+   <context  id="localServerConfig" >

+      <description>This options allow you to override <b>network address that help will use internally</b>.</description>

+      <topic href="contexts/localServerConfig1.html"  label="localServerConfig Related Topic 1"/>

+      <topic href="contexts/localServerConfig2.html"  label="localServerConfig Related Topic 2"/>

+   </context>

+   <context  id="synchronizeAction" >

+      <description>This action will <b>synchrozie navigation</b> with the document presently viewed.</description>

+      <topic href="contexts/synchronizeAction1.html"  label="synchronizeAction Related Topic 1"/>

+      <topic href="contexts/synchronizeAction2.html"  label="synchronizeAction Related Topic 2"/>

+   </context>

+   <context  id="copyAction" >

+      <description>This action <b>copies selected document</b> fragment onto the clipboard.</description>

+      <topic href="contexts/copyAction1.html"  label="copyAction Related Topic 1"/>

+      <topic href="contexts/copyAction2.html"  label="copyAction Related Topic 2"/>

+   </context>

+   <context  id="printAction" >

+      <description>This action will display <b>print dialog</b> that allows printing of the current topic.</description>

+      <topic href="contexts/printAction1.html"  label="printAction Related Topic 1"/>

+      <topic href="contexts/printAction2.html"  label="printAction Related Topic 2"/>

+   </context>

+   <context  id="backAction" >

+      <description>This action navigates to the <b>last viewed topic</b>.</description>

+      <topic href="contexts/backAction1.html"  label="backAction Related Topic 1"/>

+      <topic href="contexts/backAction2.html"  label="backAction Related Topic 2"/>

+   </context>

+   <context  id="forwardAction" >

+      <description>This action navigates to the topics viewed <b>before using Back</b> Action.</description>

+      <topic href="contexts/forwardAction1.html"  label="forwardAction Related Topic 1"/>

+      <topic href="contexts/forwardAction2.html"  label="forwardAction Related Topic 2"/>

+   </context>

+   <context  id="homeAction" >

+      <description>This loads the <b>default</b> document.</description>

+      <topic href="contexts/homeAction1.html"  label="homeAction Related Topic 1"/>

+      <topic href="contexts/homeAction2.html"  label="homeAction Related Topic 2"/>

+   </context>

+   <context  id="showHideAction" >

+      <description>This action <b>hides or shows navigation</b> part of the help view.</description>

+      <topic href="contexts/showHideAction1.html"  label="showHideAction Related Topic 1"/>

+      <topic href="contexts/showHideAction2.html"  label="showHideAction Related Topic 2"/>

+   </context>

+</contexts>
\ No newline at end of file
diff --git a/org.eclipse.help.ui/build.properties b/org.eclipse.help.ui/build.properties
new file mode 100644
index 0000000..272aa3d
--- /dev/null
+++ b/org.eclipse.help.ui/build.properties
@@ -0,0 +1,2 @@
+build.includes=icons,doc.zip,HelpContexts.xml,plugin.jars,plugin.properties,plugin.xml,pref_store.ini

+build.source.helpworkbench.jar=Eclipse Help UI,Eclipse Help UI Win32,Eclipse Help UI Motif

diff --git a/org.eclipse.help.ui/doc.zip b/org.eclipse.help.ui/doc.zip
new file mode 100644
index 0000000..28c9e40
--- /dev/null
+++ b/org.eclipse.help.ui/doc.zip
Binary files differ
diff --git a/org.eclipse.help.ui/icons/actions.gif b/org.eclipse.help.ui/icons/actions.gif
new file mode 100644
index 0000000..7675318
--- /dev/null
+++ b/org.eclipse.help.ui/icons/actions.gif
Binary files differ
diff --git a/org.eclipse.help.ui/icons/back.gif b/org.eclipse.help.ui/icons/back.gif
new file mode 100644
index 0000000..621ddd7
--- /dev/null
+++ b/org.eclipse.help.ui/icons/back.gif
Binary files differ
diff --git a/org.eclipse.help.ui/icons/copy.gif b/org.eclipse.help.ui/icons/copy.gif
new file mode 100644
index 0000000..c003ac1
--- /dev/null
+++ b/org.eclipse.help.ui/icons/copy.gif
Binary files differ
diff --git a/org.eclipse.help.ui/icons/forward.gif b/org.eclipse.help.ui/icons/forward.gif
new file mode 100644
index 0000000..ef1339f
--- /dev/null
+++ b/org.eclipse.help.ui/icons/forward.gif
Binary files differ
diff --git a/org.eclipse.help.ui/icons/go.gif b/org.eclipse.help.ui/icons/go.gif
new file mode 100644
index 0000000..bcf1ce7
--- /dev/null
+++ b/org.eclipse.help.ui/icons/go.gif
Binary files differ
diff --git a/org.eclipse.help.ui/icons/hidenav.gif b/org.eclipse.help.ui/icons/hidenav.gif
new file mode 100644
index 0000000..7003af3
--- /dev/null
+++ b/org.eclipse.help.ui/icons/hidenav.gif
Binary files differ
diff --git a/org.eclipse.help.ui/icons/home.gif b/org.eclipse.help.ui/icons/home.gif
new file mode 100644
index 0000000..bd12819
--- /dev/null
+++ b/org.eclipse.help.ui/icons/home.gif
Binary files differ
diff --git a/org.eclipse.help.ui/icons/more.gif b/org.eclipse.help.ui/icons/more.gif
new file mode 100644
index 0000000..09966dc
--- /dev/null
+++ b/org.eclipse.help.ui/icons/more.gif
Binary files differ
diff --git a/org.eclipse.help.ui/icons/printer.gif b/org.eclipse.help.ui/icons/printer.gif
new file mode 100644
index 0000000..7931221
--- /dev/null
+++ b/org.eclipse.help.ui/icons/printer.gif
Binary files differ
diff --git a/org.eclipse.help.ui/icons/resynch.gif b/org.eclipse.help.ui/icons/resynch.gif
new file mode 100644
index 0000000..0003bfc
--- /dev/null
+++ b/org.eclipse.help.ui/icons/resynch.gif
Binary files differ
diff --git a/org.eclipse.help.ui/icons/searchview.gif b/org.eclipse.help.ui/icons/searchview.gif
new file mode 100644
index 0000000..91a43f3
--- /dev/null
+++ b/org.eclipse.help.ui/icons/searchview.gif
Binary files differ
diff --git a/org.eclipse.help.ui/icons/shownav.gif b/org.eclipse.help.ui/icons/shownav.gif
new file mode 100644
index 0000000..5a1eb1c
--- /dev/null
+++ b/org.eclipse.help.ui/icons/shownav.gif
Binary files differ
diff --git a/org.eclipse.help.ui/icons/splash.gif b/org.eclipse.help.ui/icons/splash.gif
new file mode 100644
index 0000000..1ea194b
--- /dev/null
+++ b/org.eclipse.help.ui/icons/splash.gif
Binary files differ
diff --git a/org.eclipse.help.ui/icons/topic.gif b/org.eclipse.help.ui/icons/topic.gif
new file mode 100644
index 0000000..1015036
--- /dev/null
+++ b/org.eclipse.help.ui/icons/topic.gif
Binary files differ
diff --git a/org.eclipse.help.ui/icons/topicandfolder.gif b/org.eclipse.help.ui/icons/topicandfolder.gif
new file mode 100644
index 0000000..75e6b8b
--- /dev/null
+++ b/org.eclipse.help.ui/icons/topicandfolder.gif
Binary files differ
diff --git a/org.eclipse.help.ui/icons/topicfolder.gif b/org.eclipse.help.ui/icons/topicfolder.gif
new file mode 100644
index 0000000..b76f961
--- /dev/null
+++ b/org.eclipse.help.ui/icons/topicfolder.gif
Binary files differ
diff --git a/org.eclipse.help.ui/icons/view.gif b/org.eclipse.help.ui/icons/view.gif
new file mode 100644
index 0000000..b77edf2
--- /dev/null
+++ b/org.eclipse.help.ui/icons/view.gif
Binary files differ
diff --git a/org.eclipse.help.ui/plugin.jars b/org.eclipse.help.ui/plugin.jars
new file mode 100644
index 0000000..fcbfb24
--- /dev/null
+++ b/org.eclipse.help.ui/plugin.jars
@@ -0,0 +1,4 @@
+helpworkbench.jar=\

+	Eclipse Help UI,\

+	Eclipse Help UI Win32,\

+	Eclipse Help UI Motif
\ No newline at end of file
diff --git a/org.eclipse.help.ui/plugin.properties b/org.eclipse.help.ui/plugin.properties
new file mode 100644
index 0000000..6198618
--- /dev/null
+++ b/org.eclipse.help.ui/plugin.properties
@@ -0,0 +1,6 @@
+help_system_plugin_name = Default Help System Workbench

+help_preferences_page_name = Help

+helpcontents = Help Contents

+help = Help

+help_view = Help

+help_perspective = Help

diff --git a/org.eclipse.help.ui/plugin.xml b/org.eclipse.help.ui/plugin.xml
new file mode 100644
index 0000000..764cec9
--- /dev/null
+++ b/org.eclipse.help.ui/plugin.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0"?>

+

+<!-- ========================================================== -->

+<!-- This is a Default implementation of the Eclipse Workbench  -->

+<!-- Help System. It uses the extension points defined by       -->

+<!-- the base help system (id="org.eclipse.help").          -->

+<!-- ========================================================== -->

+

+<plugin

+   name = "%help_system_plugin_name"

+   id = "org.eclipse.help.ui"

+   version = "0.5"

+   vendor-name = "IBM"

+   class="org.eclipse.help.internal.ui.WorkbenchHelpPlugin">

+

+   <requires>

+	<import plugin="org.eclipse.core.runtime"/>

+	<import plugin="org.eclipse.ui"/>

+	<import plugin="org.eclipse.help"/>

+	<import plugin="org.apache.xerces"/>

+   </requires>

+

+

+   <runtime>

+      <library name="helpworkbench.jar">

+         <export name="org.eclipse.help.workbench.*"/>

+      </library>

+   </runtime>

+

+

+   <!-- ========================================================================== -->

+   <!-- Internal configuration for this plugin                                     -->

+   <!-- ========================================================================== -->

+   <!-- The Help System  --> 

+   <!-- ================ -->

+   <extension point="org.eclipse.help.support">

+      <config class="org.eclipse.help.internal.ui.DefaultHelp"/>

+   </extension>

+

+   <!-- The Help System View  --> 

+   <!-- ===================== -->

+   <extension point="org.eclipse.ui.views">

+      <category

+           id="org.eclipse.help"

+           name="%help">

+      </category>

+

+      <view

+      	id="org.eclipse.help.internal.ui.EmbeddedHelpView"

+      	name="%help_view"

+      	icon="icons/view.gif"

+      	category="org.eclipse.help"

+      	class="org.eclipse.help.internal.ui.EmbeddedHelpView">

+    	</view>

+   </extension>

+

+   <!-- The Help System Perspective  --> 

+   <!-- ============================ -->

+

+   <extension 

+	point="org.eclipse.ui.perspectives">

+	<perspective

+		id="org.eclipse.help.internal.ui.HelpPerspective"

+		name="%help_perspective"

+		class="org.eclipse.help.internal.ui.HelpPerspective">

+	</perspective>

+   </extension>

+

+   <!-- Help system preference page -->

+   <!-- =========================== -->

+   <extension

+      point = "org.eclipse.ui.preferencePages">

+       <page id="org.eclipse.help.workbench.preferencePages.Page1"

+	      class="org.eclipse.help.internal.ui.util.HelpPreferencePage"

+            name="%help_preferences_page_name">

+       </page>

+   </extension>

+

+

+   <!-- Context Help contribution for this plugin  --> 

+   <!-- ========================================== -->

+   <extension point="org.eclipse.help.contexts"> 

+      <contexts name="HelpContexts.xml"/> 

+   </extension>

+  

+   <!-- Define the help menu action set -->

+   <!-- =============================== -->

+   <extension point="org.eclipse.ui.actionSets">

+     <actionSet

+          id="org.eclipse.help.internal.ui.HelpActionSet"

+          label="%help"

+          visible="true">

+

+          <action id="org.eclipse.help.internal.ui.HelpAction"

+                  menubarPath="help/helpEnd"

+                  label="%helpcontents"

+                  class="org.eclipse.help.internal.ui.ShowHelp"/>

+             

+     </actionSet>

+ </extension>

+

+</plugin>

diff --git a/org.eclipse.help.ui/pref_store.ini b/org.eclipse.help.ui/pref_store.ini
new file mode 100644
index 0000000..fba88ad
--- /dev/null
+++ b/org.eclipse.help.ui/pref_store.ini
@@ -0,0 +1,7 @@
+log_level=0

+local_server_config=0

+local_server_addr=

+local_server_port=

+install=0

+server_path=http://www.yourhost.com/eclipse/servlet/help

+browser_path=/usr/bin/netscape