/*******************************************************************************
 * Copyright (c) 2003, 2009 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.swt.browser;

import java.io.*;
import java.lang.reflect.*;
import java.util.*;

import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.internal.*;
import org.eclipse.swt.internal.mozilla.*;
import org.eclipse.swt.internal.mozilla.init.*;
import org.eclipse.swt.layout.*;

class Mozilla extends WebBrowser {
	int /*long*/ embedHandle;
	nsIWebBrowser webBrowser;
	Object webBrowserObject;
	MozillaDelegate delegate;

	/* Interfaces for this Mozilla embedding notification */
	XPCOMObject supports;
	XPCOMObject weakReference;
	XPCOMObject webProgressListener;
	XPCOMObject	webBrowserChrome;
	XPCOMObject webBrowserChromeFocus;
	XPCOMObject embeddingSiteWindow;
	XPCOMObject interfaceRequestor;
	XPCOMObject supportsWeakReference;
	XPCOMObject contextMenuListener;	
	XPCOMObject uriContentListener;
	XPCOMObject tooltipListener;
	XPCOMObject domEventListener;
	int chromeFlags = nsIWebBrowserChrome.CHROME_DEFAULT;
	int refCount, lastKeyCode, lastCharCode, authCount;
	int /*long*/ request;
	Point location, size;
	boolean visible, isChild, ignoreDispose;
	Shell tip = null;
	Listener listener;
	Vector unhookedDOMWindows = new Vector ();
	String lastNavigateURL;
	byte[] htmlBytes;

	static nsIAppShell AppShell;
	static AppFileLocProvider LocationProvider;
	static WindowCreator2 WindowCreator;
	static int BrowserCount, NextJSFunctionIndex = 1;
	static Hashtable AllFunctions = new Hashtable (); 
	static boolean Initialized, IsPre_1_8, IsPre_1_9, PerformedVersionCheck, XPCOMWasGlued, XPCOMInitWasGlued;

	/* XULRunner detect constants */
	static final String GRERANGE_LOWER = "1.8.1.2"; //$NON-NLS-1$
	static final String GRERANGE_LOWER_FALLBACK = "1.8"; //$NON-NLS-1$
	static final boolean LowerRangeInclusive = true;
	static final String GRERANGE_UPPER = "1.9.*"; //$NON-NLS-1$
	static final boolean UpperRangeInclusive = true;

	static final int MAX_PORT = 65535;
	static final String SEPARATOR_OS = System.getProperty ("file.separator"); //$NON-NLS-1$
	static final String ABOUT_BLANK = "about:blank"; //$NON-NLS-1$
	static final String DISPOSE_LISTENER_HOOKED = "org.eclipse.swt.browser.Mozilla.disposeListenerHooked"; //$NON-NLS-1$
	static final String PREFIX_JAVASCRIPT = "javascript:"; //$NON-NLS-1$
	static final String PREFERENCE_CHARSET = "intl.charset.default"; //$NON-NLS-1$
	static final String PREFERENCE_DISABLEOPENDURINGLOAD = "dom.disable_open_during_load"; //$NON-NLS-1$
	static final String PREFERENCE_DISABLEWINDOWSTATUSCHANGE = "dom.disable_window_status_change"; //$NON-NLS-1$
	static final String PREFERENCE_LANGUAGES = "intl.accept_languages"; //$NON-NLS-1$
	static final String PREFERENCE_PROXYHOST_FTP = "network.proxy.ftp"; //$NON-NLS-1$
	static final String PREFERENCE_PROXYPORT_FTP = "network.proxy.ftp_port"; //$NON-NLS-1$
	static final String PREFERENCE_PROXYHOST_HTTP = "network.proxy.http"; //$NON-NLS-1$
	static final String PREFERENCE_PROXYPORT_HTTP = "network.proxy.http_port"; //$NON-NLS-1$
	static final String PREFERENCE_PROXYHOST_SSL = "network.proxy.ssl"; //$NON-NLS-1$
	static final String PREFERENCE_PROXYPORT_SSL = "network.proxy.ssl_port"; //$NON-NLS-1$
	static final String PREFERENCE_PROXYTYPE = "network.proxy.type"; //$NON-NLS-1$
	static final String PROFILE_AFTER_CHANGE = "profile-after-change"; //$NON-NLS-1$
	static final String PROFILE_BEFORE_CHANGE = "profile-before-change"; //$NON-NLS-1$
	static final String PROFILE_DIR = SEPARATOR_OS + "eclipse" + SEPARATOR_OS; //$NON-NLS-1$
	static final String PROFILE_DO_CHANGE = "profile-do-change"; //$NON-NLS-1$
	static final String PROPERTY_PROXYPORT = "network.proxy_port"; //$NON-NLS-1$
	static final String PROPERTY_PROXYHOST = "network.proxy_host"; //$NON-NLS-1$
	static final String SEPARATOR_LOCALE = "-"; //$NON-NLS-1$
	static final String SHUTDOWN_PERSIST = "shutdown-persist"; //$NON-NLS-1$
	static final String STARTUP = "startup"; //$NON-NLS-1$
	static final String TOKENIZER_LOCALE = ","; //$NON-NLS-1$
	static final String URI_FROMMEMORY = "file:///"; //$NON-NLS-1$
	static final String XULRUNNER_PATH = "org.eclipse.swt.browser.XULRunnerPath"; //$NON-NLS-1$

	// TEMPORARY CODE
	static final String GRE_INITIALIZED = "org.eclipse.swt.browser.XULRunnerInitialized"; //$NON-NLS-1$

	static {
		MozillaClearSessions = new Runnable () {
			public void run () {
				if (!Initialized) return;
				int /*long*/[] result = new int /*long*/[1];
				int rc = XPCOM.NS_GetServiceManager (result);
				if (rc != XPCOM.NS_OK) error (rc);
				if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
				nsIServiceManager serviceManager = new nsIServiceManager (result[0]);
				result[0] = 0;
				byte[] aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_COOKIEMANAGER_CONTRACTID, true);
				rc = serviceManager.GetServiceByContractID (aContractID, nsICookieManager.NS_ICOOKIEMANAGER_IID, result);
				if (rc != XPCOM.NS_OK) error (rc);
				if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
				serviceManager.Release ();

				nsICookieManager manager = new nsICookieManager (result[0]);
				result[0] = 0;
				rc = manager.GetEnumerator (result);
				if (rc != XPCOM.NS_OK) error (rc);

				nsISimpleEnumerator enumerator = new nsISimpleEnumerator (result[0]);
				int[] moreElements = new int[1]; /* PRBool */
				rc = enumerator.HasMoreElements (moreElements);
				if (rc != XPCOM.NS_OK) error (rc);
				while (moreElements[0] != 0) {
					result[0] = 0;
					rc = enumerator.GetNext (result);
					if (rc != XPCOM.NS_OK) error (rc);
					nsICookie cookie = new nsICookie (result[0]);
					long[] expires = new long[1];
					rc = cookie.GetExpires (expires);
					if (expires[0] == 0) {
						/* indicates a session cookie */
						int /*long*/ domain = XPCOM.nsEmbedCString_new ();
						int /*long*/ name = XPCOM.nsEmbedCString_new ();
						int /*long*/ path = XPCOM.nsEmbedCString_new ();
						cookie.GetHost (domain);
						cookie.GetName (name);
						cookie.GetPath (path);
						rc = manager.Remove (domain, name, path, 0);
						XPCOM.nsEmbedCString_delete (domain);
						XPCOM.nsEmbedCString_delete (name);
						XPCOM.nsEmbedCString_delete (path);
						if (rc != XPCOM.NS_OK) error (rc);
					}
					cookie.Release ();
					rc = enumerator.HasMoreElements (moreElements);
					if (rc != XPCOM.NS_OK) error (rc);
				}
				enumerator.Release ();
				manager.Release ();
			}
		};

		MozillaGetCookie = new Runnable() {
			public void run() {
				if (!Initialized) return;

				int /*long*/[] result = new int /*long*/[1];
				int rc = XPCOM.NS_GetServiceManager (result);
				if (rc != XPCOM.NS_OK) error (rc);
				if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);

				nsIServiceManager serviceManager = new nsIServiceManager (result[0]);
				result[0] = 0;
				rc = serviceManager.GetService (XPCOM.NS_IOSERVICE_CID, nsIIOService.NS_IIOSERVICE_IID, result);
				if (rc != XPCOM.NS_OK) error (rc);
				if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);

				nsIIOService ioService = new nsIIOService (result[0]);
				result[0] = 0;
				byte[] bytes = MozillaDelegate.wcsToMbcs (null, CookieUrl, false);
				int /*long*/ aSpec = XPCOM.nsEmbedCString_new (bytes, bytes.length);
				rc = ioService.NewURI (aSpec, null, 0, result);
				XPCOM.nsEmbedCString_delete (aSpec);
				ioService.Release ();
				if (rc != XPCOM.NS_OK) {
					serviceManager.Release ();
					return;
				}
				if (result[0] == 0) error (XPCOM.NS_ERROR_NULL_POINTER);

				nsIURI aURI = new nsIURI (result[0]);
				result[0] = 0;
				byte[] aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_COOKIESERVICE_CONTRACTID, true);
				rc = serviceManager.GetServiceByContractID (aContractID, nsICookieService.NS_ICOOKIESERVICE_IID, result);
				int /*long*/ cookieString;
				if (rc == XPCOM.NS_OK && result[0] != 0) {
					nsICookieService cookieService = new nsICookieService (result[0]);
					result[0] = 0;
					rc = cookieService.GetCookieString (aURI.getAddress(), 0, result);
					cookieService.Release ();
					if (rc != XPCOM.NS_OK) error (rc);
					if (result[0] == 0) {
						aURI.Release ();
						serviceManager.Release ();
						return;
					}
					cookieString = result[0];
				} else {
					result[0] = 0;
					rc = serviceManager.GetServiceByContractID (aContractID, nsICookieService_1_9.NS_ICOOKIESERVICE_IID, result);
					if (rc != XPCOM.NS_OK) error (rc);
					if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
					nsICookieService_1_9 cookieService = new nsICookieService_1_9 (result[0]);
					result[0] = 0;
					rc = cookieService.GetCookieString(aURI.getAddress(), 0, result);
					cookieService.Release ();
					if (rc != XPCOM.NS_OK) error (rc);
					if (result[0] == 0) {
						aURI.Release ();
						serviceManager.Release ();
						return;
					}
					cookieString = result[0];
				}
				aURI.Release ();
				serviceManager.Release ();
				result[0] = 0;

				int length = C.strlen (cookieString);
				bytes = new byte[length];
				XPCOM.memmove (bytes, cookieString, length);
				C.free (cookieString);
				String allCookies = new String (MozillaDelegate.mbcsToWcs (null, bytes));
				StringTokenizer tokenizer = new StringTokenizer (allCookies, ";"); //$NON-NLS-1$
				while (tokenizer.hasMoreTokens ()) {
					String cookie = tokenizer.nextToken ();
					int index = cookie.indexOf ('=');
					if (index != -1) {
						String name = cookie.substring (0, index).trim ();
						if (name.equals (CookieName)) {
							CookieValue = cookie.substring (index + 1).trim ();
							return;
						}
					}
				}
			}
		};

		MozillaSetCookie = new Runnable() {
			public void run() {
				if (!Initialized) return;

				int /*long*/[] result = new int /*long*/[1];
				int rc = XPCOM.NS_GetServiceManager (result);
				if (rc != XPCOM.NS_OK) error (rc);
				if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);

				nsIServiceManager serviceManager = new nsIServiceManager (result[0]);
				result[0] = 0;
				rc = serviceManager.GetService (XPCOM.NS_IOSERVICE_CID, nsIIOService.NS_IIOSERVICE_IID, result);
				if (rc != XPCOM.NS_OK) error (rc);
				if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);

				nsIIOService ioService = new nsIIOService (result[0]);
				result[0] = 0;
				byte[] bytes = MozillaDelegate.wcsToMbcs (null, CookieUrl, false);
				int /*long*/ aSpec = XPCOM.nsEmbedCString_new (bytes, bytes.length);
				rc = ioService.NewURI (aSpec, null, 0, result);
				XPCOM.nsEmbedCString_delete (aSpec);
				ioService.Release ();
				if (rc != XPCOM.NS_OK) {
					serviceManager.Release ();
					return;
				}
				if (result[0] == 0) error (XPCOM.NS_ERROR_NULL_POINTER);

				nsIURI aURI = new nsIURI(result[0]);
				result[0] = 0;
				byte[] aCookie = MozillaDelegate.wcsToMbcs (null, CookieValue, true);
				byte[] aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_COOKIESERVICE_CONTRACTID, true);
				rc = serviceManager.GetServiceByContractID (aContractID, nsICookieService.NS_ICOOKIESERVICE_IID, result);
				if (rc == XPCOM.NS_OK && result[0] != 0) {
					nsICookieService cookieService = new nsICookieService (result[0]);
					rc = cookieService.SetCookieString (aURI.getAddress(), 0, aCookie, 0);
					cookieService.Release ();
				} else {
					result[0] = 0;
					rc = serviceManager.GetServiceByContractID (aContractID, nsICookieService_1_9.NS_ICOOKIESERVICE_IID, result);
					if (rc != XPCOM.NS_OK) error (rc);
					if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
					nsICookieService_1_9 cookieService = new nsICookieService_1_9 (result[0]);
					rc = cookieService.SetCookieString(aURI.getAddress(), 0, aCookie, 0);
					cookieService.Release ();
				}
				result[0] = 0;
				aURI.Release ();
				serviceManager.Release ();
				CookieResult = rc == 0;
			}
		};
	}

public void create (Composite parent, int style) {
	delegate = new MozillaDelegate (browser);
	final Display display = parent.getDisplay ();

	int /*long*/[] result = new int /*long*/[1];
	if (!Initialized) {
		boolean initLoaded = false;
		boolean IsXULRunner = false;

		String greInitialized = System.getProperty (GRE_INITIALIZED); 
		if ("true".equals (greInitialized)) { //$NON-NLS-1$
			/* 
			 * Another browser has already initialized xulrunner in this process,
			 * so just bind to it instead of trying to initialize a new one.
			 */
			Initialized = true;
		}

		String mozillaPath = System.getProperty (XULRUNNER_PATH);
		/*
		* Browser clients that ship XULRunner in a plug-in must have an opportunity 
		* to set the org.eclipse.swt.browser.XULRunnerPath system property to point
		* at their XULRunner before the first Mozilla-based Browser is created.  To
		* facilitate this, reflection is used to reference non-existent class
		* org.eclipse.swt.browser.XULRunnerInitializer the first time a Mozilla-
		* based Browser is created.   A client wishing to use this hook can do so
		* by creating a fragment of org.eclipse.swt that implements this class and
		* sets the system property in its static initializer.
		*/
		if (mozillaPath == null) {
			try {
				Class.forName ("org.eclipse.swt.browser.XULRunnerInitializer"); //$NON-NLS-1$
				mozillaPath = System.getProperty (XULRUNNER_PATH);
			} catch (ClassNotFoundException e) {
				/* no fragment is providing this class, which is the typical case */
			}
		}

		if (mozillaPath == null) {
			try {
				String libName = delegate.getSWTInitLibraryName ();
				Library.loadLibrary (libName);
				initLoaded = true;
			} catch (UnsatisfiedLinkError e) {
				/* 
				* If this library failed to load then do not attempt to detect a
				* xulrunner to use.  The Browser may still be usable if MOZILLA_FIVE_HOME
				* points at a GRE. 
				*/
			}
		} else {
			mozillaPath += SEPARATOR_OS + delegate.getLibraryName ();
			IsXULRunner = true;
		}

		if (initLoaded) {
			/* attempt to discover a XULRunner to use as the GRE */
			GREVersionRange range = new GREVersionRange ();
			byte[] bytes = MozillaDelegate.wcsToMbcs (null, GRERANGE_LOWER, true);
			int /*long*/ lower = C.malloc (bytes.length);
			C.memmove (lower, bytes, bytes.length);
			range.lower = lower;
			range.lowerInclusive = LowerRangeInclusive;

			bytes = MozillaDelegate.wcsToMbcs (null, GRERANGE_UPPER, true);
			int /*long*/ upper = C.malloc (bytes.length);
			C.memmove (upper, bytes, bytes.length);
			range.upper = upper;
			range.upperInclusive = UpperRangeInclusive;

			int length = XPCOMInit.PATH_MAX;
			int /*long*/ greBuffer = C.malloc (length);
			int /*long*/ propertiesPtr = C.malloc (2 * C.PTR_SIZEOF);
			int rc = XPCOMInit.GRE_GetGREPathWithProperties (range, 1, propertiesPtr, 0, greBuffer, length);

			/*
			 * A XULRunner was not found that supports wrapping of XPCOM handles as JavaXPCOM objects.
			 * Drop the lower version bound and try to detect an earlier XULRunner installation.
			 */
			if (rc != XPCOM.NS_OK) {
				C.free (lower);
				bytes = MozillaDelegate.wcsToMbcs (null, GRERANGE_LOWER_FALLBACK, true);
				lower = C.malloc (bytes.length);
				C.memmove (lower, bytes, bytes.length);
				range.lower = lower;
				rc = XPCOMInit.GRE_GetGREPathWithProperties (range, 1, propertiesPtr, 0, greBuffer, length);
			}

			C.free (lower);
			C.free (upper);
			C.free (propertiesPtr);
			if (rc == XPCOM.NS_OK) {
				/* indicates that a XULRunner was found */
				length = C.strlen (greBuffer);
				bytes = new byte[length];
				C.memmove (bytes, greBuffer, length);
				mozillaPath = new String (MozillaDelegate.mbcsToWcs (null, bytes));
				IsXULRunner = mozillaPath.length () > 0;

				/*
				 * Test whether the detected XULRunner can be used as the GRE before loading swt's
				 * XULRunner library.  If it cannot be used then fall back to attempting to use
				 * the GRE pointed to by MOZILLA_FIVE_HOME.
				 * 
				 * One case where this will fail is attempting to use a 64-bit xulrunner while swt
				 * is running in 32-bit mode, or vice versa.
				 */
				if (IsXULRunner) {
					byte[] path = MozillaDelegate.wcsToMbcs (null, mozillaPath, true);
					rc = XPCOMInit.XPCOMGlueStartup (path);
					if (rc != XPCOM.NS_OK) {
						mozillaPath = mozillaPath.substring (0, mozillaPath.lastIndexOf (SEPARATOR_OS));
						if (Device.DEBUG) System.out.println ("cannot use detected XULRunner: " + mozillaPath); //$NON-NLS-1$

						/* attempt to XPCOMGlueStartup the GRE pointed at by MOZILLA_FIVE_HOME */
						int /*long*/ ptr = C.getenv (MozillaDelegate.wcsToMbcs (null, XPCOM.MOZILLA_FIVE_HOME, true));
						if (ptr == 0) {
							IsXULRunner = false;
						} else {
							length = C.strlen (ptr);
							byte[] buffer = new byte[length];
							C.memmove (buffer, ptr, length);
							mozillaPath = new String (MozillaDelegate.mbcsToWcs (null, buffer));
							/*
							 * Attempting to XPCOMGlueStartup a mozilla-based GRE != xulrunner can
							 * crash, so don't attempt unless the GRE appears to be xulrunner.
							 */
							if (mozillaPath.indexOf("xulrunner") == -1) { //$NON-NLS-1$
								IsXULRunner = false;	
							} else {
								mozillaPath += SEPARATOR_OS + delegate.getLibraryName ();
								path = MozillaDelegate.wcsToMbcs (null, mozillaPath, true);
								rc = XPCOMInit.XPCOMGlueStartup (path);
								if (rc != XPCOM.NS_OK) {
									IsXULRunner = false;
									mozillaPath = mozillaPath.substring (0, mozillaPath.lastIndexOf (SEPARATOR_OS));
									if (Device.DEBUG) System.out.println ("failed to start as XULRunner: " + mozillaPath); //$NON-NLS-1$
								}
							}
						} 
					}
					if (IsXULRunner) {
						XPCOMInitWasGlued = true;
					}
				}
			}
			C.free (greBuffer);
		}

		if (IsXULRunner) {
			if (Device.DEBUG) System.out.println ("XULRunner path: " + mozillaPath); //$NON-NLS-1$
			try {
				Library.loadLibrary ("swt-xulrunner"); //$NON-NLS-1$
			} catch (UnsatisfiedLinkError e) {
				SWT.error (SWT.ERROR_NO_HANDLES, e);
			}
			byte[] path = MozillaDelegate.wcsToMbcs (null, mozillaPath, true);
			int rc = XPCOM.XPCOMGlueStartup (path);
			if (rc != XPCOM.NS_OK) {
				browser.dispose ();
				error (rc);
			}
			XPCOMWasGlued = true;

			/*
			 * Remove the trailing xpcom lib name from mozillaPath because the
			 * Mozilla.initialize and NS_InitXPCOM2 invocations require a directory name only.
			 */ 
			mozillaPath = mozillaPath.substring (0, mozillaPath.lastIndexOf (SEPARATOR_OS));
		} else {
			if ((style & SWT.MOZILLA) != 0) {
				browser.dispose ();
				String errorString = (mozillaPath != null && mozillaPath.length () > 0) ?
					" [Failed to use detected XULRunner: " + mozillaPath + "]" :
					" [Could not detect registered XULRunner to use]";	//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				SWT.error (SWT.ERROR_NO_HANDLES, null, errorString);
			}

			/* attempt to use the GRE pointed at by MOZILLA_FIVE_HOME */
			int /*long*/ ptr = C.getenv (MozillaDelegate.wcsToMbcs (null, XPCOM.MOZILLA_FIVE_HOME, true));
			if (ptr != 0) {
				int length = C.strlen (ptr);
				byte[] buffer = new byte[length];
				C.memmove (buffer, ptr, length);
				mozillaPath = new String (MozillaDelegate.mbcsToWcs (null, buffer));
			} else {
				browser.dispose ();
				SWT.error (SWT.ERROR_NO_HANDLES, null, " [Unknown Mozilla path (MOZILLA_FIVE_HOME not set)]"); //$NON-NLS-1$
			}
			if (Device.DEBUG) System.out.println ("Mozilla path: " + mozillaPath); //$NON-NLS-1$

			/*
			* Note.  Embedding a Mozilla GTK1.2 causes a crash.  The workaround
			* is to check the version of GTK used by Mozilla by looking for
			* the libwidget_gtk.so library used by Mozilla GTK1.2. Mozilla GTK2
			* uses the libwidget_gtk2.so library.   
			*/
			if (Compatibility.fileExists (mozillaPath, "components/libwidget_gtk.so")) { //$NON-NLS-1$
				browser.dispose ();
				SWT.error (SWT.ERROR_NO_HANDLES, null, " [Mozilla GTK2 required (GTK1.2 detected)]"); //$NON-NLS-1$							
			}

			try {
				Library.loadLibrary ("swt-mozilla"); //$NON-NLS-1$
			} catch (UnsatisfiedLinkError e) {
				try {
					/* 
					 * The initial loadLibrary attempt may have failed as a result of the user's
					 * system not having libstdc++.so.6 installed, so try to load the alternate
					 * swt mozilla library that depends on libswtc++.so.5 instead.
					 */
					Library.loadLibrary ("swt-mozilla-gcc3"); //$NON-NLS-1$
				} catch (UnsatisfiedLinkError ex) {
					browser.dispose ();
					/*
					 * Print the error from the first failed attempt since at this point it's
					 * known that the failure was not due to the libstdc++.so.6 dependency.
					 */
					SWT.error (SWT.ERROR_NO_HANDLES, e, " [MOZILLA_FIVE_HOME='" + mozillaPath + "']"); //$NON-NLS-1$ //$NON-NLS-2$
				}
			}
		}

		if (!Initialized) {
			LocationProvider = new AppFileLocProvider (mozillaPath);
			LocationProvider.AddRef ();

			/* extract external.xpt to temp */
			String tempPath = System.getProperty ("java.io.tmpdir"); //$NON-NLS-1$
			File componentsDir = new File (tempPath, "eclipse/mozillaComponents"); //$NON-NLS-1$
			java.io.InputStream is = Library.class.getResourceAsStream ("/external.xpt"); //$NON-NLS-1$
			if (is != null) {
				if (!componentsDir.exists ()) {
					componentsDir.mkdirs ();
				}
				int read;
				byte [] buffer = new byte [4096];
				File file = new File (componentsDir, "external.xpt"); //$NON-NLS-1$
				try {
					FileOutputStream os = new FileOutputStream (file);
					while ((read = is.read (buffer)) != -1) {
						os.write(buffer, 0, read);
					}
					os.close ();
					is.close ();
				} catch (FileNotFoundException e) {
				} catch (IOException e) {
				}
			}
			if (componentsDir.exists () && componentsDir.isDirectory ()) {
				LocationProvider.setComponentsPath (componentsDir.getAbsolutePath ());
			}

			int /*long*/[] retVal = new int /*long*/[1];
			nsEmbedString pathString = new nsEmbedString (mozillaPath);
			int rc = XPCOM.NS_NewLocalFile (pathString.getAddress (), 1, retVal);
			pathString.dispose ();
			if (rc != XPCOM.NS_OK) {
				browser.dispose ();
				error (rc);
			}
			if (retVal[0] == 0) {
				browser.dispose ();
				error (XPCOM.NS_ERROR_NULL_POINTER);
			}

			nsIFile localFile = new nsILocalFile (retVal[0]);
			if (IsXULRunner) {
				int size = XPCOM.nsDynamicFunctionLoad_sizeof ();
				/* alloc memory for two structs, the second is empty to signify the end of the list */
				int /*long*/ ptr = C.malloc (size * 2);
				C.memset (ptr, 0, size * 2);
				nsDynamicFunctionLoad functionLoad = new nsDynamicFunctionLoad ();
				byte[] bytes = MozillaDelegate.wcsToMbcs (null, "XRE_InitEmbedding", true); //$NON-NLS-1$
				functionLoad.functionName = C.malloc (bytes.length);
				C.memmove (functionLoad.functionName, bytes, bytes.length);
				functionLoad.function = C.malloc (C.PTR_SIZEOF);
				C.memmove (functionLoad.function, new int /*long*/[] {0} , C.PTR_SIZEOF);
				XPCOM.memmove (ptr, functionLoad, XPCOM.nsDynamicFunctionLoad_sizeof ());
				XPCOM.XPCOMGlueLoadXULFunctions (ptr);
				C.memmove (result, functionLoad.function, C.PTR_SIZEOF);
				int /*long*/ functionPtr = result[0];
				result[0] = 0;
				C.free (functionLoad.function);
				C.free (functionLoad.functionName);
				C.free (ptr);
				rc = XPCOM.Call (functionPtr, localFile.getAddress (), localFile.getAddress (), LocationProvider.getAddress (), 0, 0);
				if (rc == XPCOM.NS_OK) {
					System.setProperty (XULRUNNER_PATH, mozillaPath);
				}
			} else {
				rc = XPCOM.NS_InitXPCOM2 (0, localFile.getAddress(), LocationProvider.getAddress ());
			}
			localFile.Release ();
			if (rc != XPCOM.NS_OK) {
				browser.dispose ();
				SWT.error (SWT.ERROR_NO_HANDLES, null, " [MOZILLA_FIVE_HOME may not point at an embeddable GRE] [NS_InitEmbedding " + mozillaPath + " error " + rc + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			}
			System.setProperty (GRE_INITIALIZED, "true"); //$NON-NLS-1$
		}

		/* If JavaXPCOM is detected then attempt to initialize it with the XULRunner being used */
		if (IsXULRunner) {
			try {
				Class clazz = Class.forName ("org.mozilla.xpcom.Mozilla"); //$NON-NLS-1$
				Method method = clazz.getMethod ("getInstance", new Class[0]); //$NON-NLS-1$
				Object mozilla = method.invoke (null, new Object[0]);
				method = clazz.getMethod ("getComponentManager", new Class[0]); //$NON-NLS-1$
				try {
					method.invoke (mozilla, new Object[0]);
				} catch (InvocationTargetException e) {
					/* indicates that JavaXPCOM has not been initialized yet */
					Class fileClass = Class.forName ("java.io.File"); //$NON-NLS-1$
					method = clazz.getMethod ("initialize", new Class[] {fileClass}); //$NON-NLS-1$
					Constructor constructor = fileClass.getDeclaredConstructor (new Class[] {String.class});
					Object argument = constructor.newInstance (new Object[] {mozillaPath});
					method.invoke (mozilla, new Object[] {argument});
				}
			} catch (ClassNotFoundException e) {
				/* JavaXPCOM is not on the classpath */
			} catch (NoSuchMethodException e) {
				/* the JavaXPCOM on the classpath does not implement initialize() */
			} catch (IllegalArgumentException e) {
			} catch (IllegalAccessException e) {
			} catch (InvocationTargetException e) {
			} catch (InstantiationException e) {
			}
		}

		int rc = XPCOM.NS_GetComponentManager (result);
		if (rc != XPCOM.NS_OK) {
			browser.dispose ();
			error (rc);
		}
		if (result[0] == 0) {
			browser.dispose ();
			error (XPCOM.NS_NOINTERFACE);
		}
		
		nsIComponentManager componentManager = new nsIComponentManager (result[0]);
		result[0] = 0;
		if (delegate.needsSpinup ()) {
			/* nsIAppShell is discontinued as of xulrunner 1.9, so do not fail if it is not found */
			rc = componentManager.CreateInstance (XPCOM.NS_APPSHELL_CID, 0, nsIAppShell.NS_IAPPSHELL_IID, result);
			if (rc != XPCOM.NS_ERROR_NO_INTERFACE) {
				if (rc != XPCOM.NS_OK) {
					browser.dispose ();
					error (rc);
				}
				if (result[0] == 0) {
					browser.dispose ();
					error (XPCOM.NS_NOINTERFACE);
				}
	
				AppShell = new nsIAppShell (result[0]);
				rc = AppShell.Create (0, null);
				if (rc != XPCOM.NS_OK) {
					browser.dispose ();
					error (rc);
				}
				rc = AppShell.Spinup ();
				if (rc != XPCOM.NS_OK) {
					browser.dispose ();
					error (rc);
				}
			}
			result[0] = 0;
		}

		WindowCreator = new WindowCreator2 ();
		WindowCreator.AddRef ();
		
		rc = XPCOM.NS_GetServiceManager (result);
		if (rc != XPCOM.NS_OK) {
			browser.dispose ();
			error (rc);
		}
		if (result[0] == 0) {
			browser.dispose ();
			error (XPCOM.NS_NOINTERFACE);
		}
		
		nsIServiceManager serviceManager = new nsIServiceManager (result[0]);
		result[0] = 0;		
		byte[] aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_WINDOWWATCHER_CONTRACTID, true);
		rc = serviceManager.GetServiceByContractID (aContractID, nsIWindowWatcher.NS_IWINDOWWATCHER_IID, result);
		if (rc != XPCOM.NS_OK) {
			browser.dispose ();
			error (rc);
		}
		if (result[0] == 0) {
			browser.dispose ();
			error (XPCOM.NS_NOINTERFACE);		
		}

		nsIWindowWatcher windowWatcher = new nsIWindowWatcher (result[0]);
		result[0] = 0;
		rc = windowWatcher.SetWindowCreator (WindowCreator.getAddress());
		if (rc != XPCOM.NS_OK) {
			browser.dispose ();
			error (rc);
		}
		windowWatcher.Release ();

		/* compute the profile directory and set it on the AppFileLocProvider */
		if (LocationProvider != null) {
			byte[] buffer = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_DIRECTORYSERVICE_CONTRACTID, true);
			rc = serviceManager.GetServiceByContractID (buffer, nsIDirectoryService.NS_IDIRECTORYSERVICE_IID, result);
			if (rc != XPCOM.NS_OK) {
				browser.dispose ();
				error (rc);
			}
			if (result[0] == 0) {
				browser.dispose ();
				error (XPCOM.NS_NOINTERFACE);
			}

			nsIDirectoryService directoryService = new nsIDirectoryService (result[0]);
			result[0] = 0;
			rc = directoryService.QueryInterface (nsIProperties.NS_IPROPERTIES_IID, result);
			if (rc != XPCOM.NS_OK) {
				browser.dispose ();
				error (rc);
			}
			if (result[0] == 0) {
				browser.dispose ();
				error (XPCOM.NS_NOINTERFACE);
			}
			directoryService.Release ();

			nsIProperties properties = new nsIProperties (result[0]);
			result[0] = 0;
			buffer = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_APP_APPLICATION_REGISTRY_DIR, true);
			rc = properties.Get (buffer, nsIFile.NS_IFILE_IID, result);
			if (rc != XPCOM.NS_OK) {
				browser.dispose ();
				error (rc);
			}
			if (result[0] == 0) {
				browser.dispose ();
				error (XPCOM.NS_NOINTERFACE);
			}
			properties.Release ();

			nsIFile profileDir = new nsIFile (result[0]);
			result[0] = 0;
			int /*long*/ path = XPCOM.nsEmbedCString_new ();
			rc = profileDir.GetNativePath (path);
			if (rc != XPCOM.NS_OK) {
				browser.dispose ();
				error (rc);
			}
			int length = XPCOM.nsEmbedCString_Length (path);
			int /*long*/ ptr = XPCOM.nsEmbedCString_get (path);
			buffer = new byte [length];
			XPCOM.memmove (buffer, ptr, length);
			String profilePath = new String (MozillaDelegate.mbcsToWcs (null, buffer)) + PROFILE_DIR;
			LocationProvider.setProfilePath (profilePath);
			LocationProvider.isXULRunner = IsXULRunner;
			XPCOM.nsEmbedCString_delete (path);
			profileDir.Release ();

			/* notify observers of a new profile directory being used */
			buffer = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_OBSERVER_CONTRACTID, true);
			rc = serviceManager.GetServiceByContractID (buffer, nsIObserverService.NS_IOBSERVERSERVICE_IID, result);
			if (rc != XPCOM.NS_OK) {
				browser.dispose ();
				error (rc);
			}
			if (result[0] == 0) {
				browser.dispose ();
				error (XPCOM.NS_NOINTERFACE);
			}

			nsIObserverService observerService = new nsIObserverService (result[0]);
			result[0] = 0;
			buffer = MozillaDelegate.wcsToMbcs (null, PROFILE_DO_CHANGE, true);
			length = STARTUP.length ();
			char[] chars = new char [length + 1];
			STARTUP.getChars (0, length, chars, 0);
			rc = observerService.NotifyObservers (0, buffer, chars);
			if (rc != XPCOM.NS_OK) {
				browser.dispose ();
				error (rc);
			}
			buffer = MozillaDelegate.wcsToMbcs (null, PROFILE_AFTER_CHANGE, true);
			rc = observerService.NotifyObservers (0, buffer, chars);
			if (rc != XPCOM.NS_OK) {
				browser.dispose ();
				error (rc);
			}
			observerService.Release ();
		}

		/*
		 * As a result of using a common profile the user cannot change their locale
		 * and charset.  The fix for this is to set mozilla's locale and charset
		 * preference values according to the user's current locale and charset.
		 */
		aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_PREFSERVICE_CONTRACTID, true);
		rc = serviceManager.GetServiceByContractID (aContractID, nsIPrefService.NS_IPREFSERVICE_IID, result);
		if (rc != XPCOM.NS_OK) {
			browser.dispose ();
			error (rc);
		}
		if (result[0] == 0) {
			browser.dispose ();
			error (XPCOM.NS_NOINTERFACE);
		}

		nsIPrefService prefService = new nsIPrefService (result[0]);
		result[0] = 0;
		byte[] buffer = new byte[1];
		rc = prefService.GetBranch (buffer, result);	/* empty buffer denotes root preference level */
		prefService.Release ();
		if (rc != XPCOM.NS_OK) {
			browser.dispose ();
			error (rc);
		}
		if (result[0] == 0) {
			browser.dispose ();
			error (XPCOM.NS_NOINTERFACE);
		}

		nsIPrefBranch prefBranch = new nsIPrefBranch (result[0]);
		result[0] = 0;

		/* get Mozilla's current locale preference value */
		String prefLocales = null;
		nsIPrefLocalizedString localizedString = null;
		buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_LANGUAGES, true);
		rc = prefBranch.GetComplexValue (buffer, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, result);
		/* 
		 * Feature of Debian.  For some reason attempting to query for the current locale
		 * preference fails on Debian.  The workaround for this is to assume a value of
		 * "en-us,en" since this is typically the default value when mozilla is used without
		 * a profile.
		 */
		if (rc != XPCOM.NS_OK) {
			prefLocales = "en-us,en" + TOKENIZER_LOCALE;	//$NON-NLS-1$
		} else {
			if (result[0] == 0) {
				browser.dispose ();
				error (XPCOM.NS_NOINTERFACE);
			}
			localizedString = new nsIPrefLocalizedString (result[0]);
			result[0] = 0;
			rc = localizedString.ToString (result);
			if (rc != XPCOM.NS_OK) {
				browser.dispose ();
				error (rc);
			}
			if (result[0] == 0) {
				browser.dispose ();
				error (XPCOM.NS_NOINTERFACE);
			}
			int length = XPCOM.strlen_PRUnichar (result[0]);
			char[] dest = new char[length];
			XPCOM.memmove (dest, result[0], length * 2);
			prefLocales = new String (dest) + TOKENIZER_LOCALE;
		}
		result[0] = 0;

		/*
		 * construct the new locale preference value by prepending the
		 * user's current locale and language to the original value 
		 */
		Locale locale = Locale.getDefault ();
		String language = locale.getLanguage ();
		String country = locale.getCountry ();
		StringBuffer stringBuffer = new StringBuffer (language);
		stringBuffer.append (SEPARATOR_LOCALE);
		stringBuffer.append (country.toLowerCase ());
		stringBuffer.append (TOKENIZER_LOCALE);
		stringBuffer.append (language);
		stringBuffer.append (TOKENIZER_LOCALE);
		String newLocales = stringBuffer.toString ();

		int start, end = -1;
		do {
			start = end + 1;
			end = prefLocales.indexOf (TOKENIZER_LOCALE, start);
			String token;
			if (end == -1) {
				token = prefLocales.substring (start);
			} else {
				token = prefLocales.substring (start, end);
			}
			if (token.length () > 0) {
				token = (token + TOKENIZER_LOCALE).trim ();
				/* ensure that duplicate locale values are not added */
				if (newLocales.indexOf (token) == -1) {
					stringBuffer.append (token);
				}
			}
		} while (end != -1);
		newLocales = stringBuffer.toString ();
		if (!newLocales.equals (prefLocales)) {
			/* write the new locale value */
			newLocales = newLocales.substring (0, newLocales.length () - TOKENIZER_LOCALE.length ()); /* remove trailing tokenizer */
			int length = newLocales.length ();
			char[] charBuffer = new char[length + 1];
			newLocales.getChars (0, length, charBuffer, 0);
			if (localizedString == null) {
				byte[] contractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_PREFLOCALIZEDSTRING_CONTRACTID, true);
				rc = componentManager.CreateInstanceByContractID (contractID, 0, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, result);
				if (rc != XPCOM.NS_OK) {
					browser.dispose ();
					error (rc);
				}
				if (result[0] == 0) {
					browser.dispose ();
					error (XPCOM.NS_NOINTERFACE);
				}
				localizedString = new nsIPrefLocalizedString (result[0]);
				result[0] = 0;
			}
			localizedString.SetDataWithLength (length, charBuffer);
			rc = prefBranch.SetComplexValue (buffer, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, localizedString.getAddress());
		}
		if (localizedString != null) {
			localizedString.Release ();
			localizedString = null;
		}

		/* get Mozilla's current charset preference value */
		String prefCharset = null;
		buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_CHARSET, true);
		rc = prefBranch.GetComplexValue (buffer, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, result);
		/* 
		 * Feature of Debian.  For some reason attempting to query for the current charset
		 * preference fails on Debian.  The workaround for this is to assume a value of
		 * "ISO-8859-1" since this is typically the default value when mozilla is used
		 * without a profile.
		 */
		if (rc != XPCOM.NS_OK) {
			prefCharset = "ISO-8859-1";	//$NON_NLS-1$
		} else {
			if (result[0] == 0) {
				browser.dispose ();
				error (XPCOM.NS_NOINTERFACE);
			}
			localizedString = new nsIPrefLocalizedString (result[0]);
			result[0] = 0;
			rc = localizedString.ToString (result);
			if (rc != XPCOM.NS_OK) {
				browser.dispose ();
				error (rc);
			}
			if (result[0] == 0) {
				browser.dispose ();
				error (XPCOM.NS_NOINTERFACE);
			}
			int length = XPCOM.strlen_PRUnichar (result[0]);
			char[] dest = new char[length];
			XPCOM.memmove (dest, result[0], length * 2);
			prefCharset = new String (dest);
		}
		result[0] = 0;

		String newCharset = System.getProperty ("file.encoding");	// $NON-NLS-1$
		if (!newCharset.equals (prefCharset)) {
			/* write the new charset value */
			int length = newCharset.length ();
			char[] charBuffer = new char[length + 1];
			newCharset.getChars (0, length, charBuffer, 0);
			if (localizedString == null) {
				byte[] contractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_PREFLOCALIZEDSTRING_CONTRACTID, true);
				rc = componentManager.CreateInstanceByContractID (contractID, 0, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, result);
				if (rc != XPCOM.NS_OK) {
					browser.dispose ();
					error (rc);
				}
				if (result[0] == 0) {
					browser.dispose ();
					error (XPCOM.NS_NOINTERFACE);
				}
				localizedString = new nsIPrefLocalizedString (result[0]);
				result[0] = 0;
			}
			localizedString.SetDataWithLength (length, charBuffer);
			rc = prefBranch.SetComplexValue (buffer, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, localizedString.getAddress ());
		}
		if (localizedString != null) localizedString.Release ();

		/*
		* Check for proxy values set as documented java properties and update mozilla's
		* preferences with these values if needed.
		*/
		String proxyHost = System.getProperty (PROPERTY_PROXYHOST);
		String proxyPortString = System.getProperty (PROPERTY_PROXYPORT);

		int port = -1;
		if (proxyPortString != null) {
			try {
				int value = Integer.valueOf (proxyPortString).intValue ();
				if (0 <= value && value <= MAX_PORT) port = value;
			} catch (NumberFormatException e) {
				/* do nothing, java property has non-integer value */
			}
		}

		if (proxyHost != null) {
			byte[] contractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_PREFLOCALIZEDSTRING_CONTRACTID, true);
			rc = componentManager.CreateInstanceByContractID (contractID, 0, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, result);
			if (rc != XPCOM.NS_OK) error (rc);
			if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);

			localizedString = new nsIPrefLocalizedString (result[0]);
			result[0] = 0;
			int length = proxyHost.length ();
			char[] charBuffer = new char[length + 1];
			proxyHost.getChars (0, length, charBuffer, 0);
			rc = localizedString.SetDataWithLength (length, charBuffer);
			if (rc != XPCOM.NS_OK) error (rc);
			buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_PROXYHOST_FTP, true);
			rc = prefBranch.SetComplexValue (buffer, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, localizedString.getAddress ());
			if (rc != XPCOM.NS_OK) error (rc);
			buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_PROXYHOST_HTTP, true);
			rc = prefBranch.SetComplexValue (buffer, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, localizedString.getAddress ());
			if (rc != XPCOM.NS_OK) error (rc);
			buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_PROXYHOST_SSL, true);
			rc = prefBranch.SetComplexValue (buffer, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, localizedString.getAddress ());
			if (rc != XPCOM.NS_OK) error (rc);
			localizedString.Release ();
		}

		if (port != -1) {
			buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_PROXYPORT_FTP, true);
			rc = prefBranch.SetIntPref (buffer, port);
			if (rc != XPCOM.NS_OK) error (rc);
			buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_PROXYPORT_HTTP, true);
			rc = prefBranch.SetIntPref (buffer, port);
			if (rc != XPCOM.NS_OK) error (rc);
			buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_PROXYPORT_SSL, true);
			rc = prefBranch.SetIntPref (buffer, port);
			if (rc != XPCOM.NS_OK) error (rc);
		}

		if (proxyHost != null || port != -1) {
			buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_PROXYTYPE, true);
			rc = prefBranch.SetIntPref (buffer, 1);
			if (rc != XPCOM.NS_OK) error (rc);
		}

		/*
		* Ensure that windows that are shown during page loads are not blocked.  Firefox may
		* try to block these by default since such windows are often unwelcome, but this
		* assumption should not be made in the Browser's context.  Since the Browser client
		* is responsible for creating the new Browser and Shell in an OpenWindowListener,
		* they should decide whether the new window is unwelcome or not and act accordingly. 
		*/
		buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_DISABLEOPENDURINGLOAD, true);
		rc = prefBranch.SetBoolPref (buffer, 0);
		if (rc != XPCOM.NS_OK) {
			browser.dispose ();
			error (rc);
		}

		/* Ensure that the status text can be set through means like javascript */ 
		buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_DISABLEWINDOWSTATUSCHANGE, true);
		rc = prefBranch.SetBoolPref (buffer, 0);
		if (rc != XPCOM.NS_OK) {
			browser.dispose ();
			error (rc);
		}

		prefBranch.Release ();

		PromptService2Factory factory = new PromptService2Factory ();
		factory.AddRef ();

		rc = componentManager.QueryInterface (nsIComponentRegistrar.NS_ICOMPONENTREGISTRAR_IID, result);
		if (rc != XPCOM.NS_OK) {
			browser.dispose ();
			error (rc);
		}
		if (result[0] == 0) {
			browser.dispose ();
			error (XPCOM.NS_NOINTERFACE);
		}
		
		nsIComponentRegistrar componentRegistrar = new nsIComponentRegistrar (result[0]);
		result[0] = 0;
		componentRegistrar.AutoRegister (0);	 /* detect the External component */ 

		aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_PROMPTSERVICE_CONTRACTID, true); 
		byte[] aClassName = MozillaDelegate.wcsToMbcs (null, "Prompt Service", true); //$NON-NLS-1$
		rc = componentRegistrar.RegisterFactory (XPCOM.NS_PROMPTSERVICE_CID, aClassName, aContractID, factory.getAddress ());
		if (rc != XPCOM.NS_OK) {
			browser.dispose ();
			error (rc);
		}
		factory.Release ();

		ExternalFactory externalFactory = new ExternalFactory ();
		externalFactory.AddRef ();
		aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.EXTERNAL_CONTRACTID, true); 
		aClassName = MozillaDelegate.wcsToMbcs (null, "External", true); //$NON-NLS-1$
		rc = componentRegistrar.RegisterFactory (XPCOM.EXTERNAL_CID, aClassName, aContractID, externalFactory.getAddress ());
		if (rc != XPCOM.NS_OK) {
			browser.dispose ();
			error (rc);
		}
		externalFactory.Release ();

		rc = serviceManager.GetService (XPCOM.NS_CATEGORYMANAGER_CID, nsICategoryManager.NS_ICATEGORYMANAGER_IID, result);
		if (rc != XPCOM.NS_OK) error (rc);
		if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
		serviceManager.Release ();

		nsICategoryManager categoryManager = new nsICategoryManager (result[0]);
		result[0] = 0;
		byte[] category = MozillaDelegate.wcsToMbcs (null, "JavaScript global property", true); //$NON-NLS-1$
		byte[] entry = MozillaDelegate.wcsToMbcs (null, "external", true); //$NON-NLS-1$
		rc = categoryManager.AddCategoryEntry(category, entry, aContractID, 1, 1, result);
		result[0] = 0;
		categoryManager.Release ();

		/*
		* This Download factory will be used if the GRE version is < 1.8.
		* If the GRE version is 1.8.x then the Download factory that is registered later for
		*   contract "Transfer" will be used.
		* If the GRE version is >= 1.9 then no Download factory is registered because this
		*   functionality is provided by the GRE.
		*/
		DownloadFactory downloadFactory = new DownloadFactory ();
		downloadFactory.AddRef ();
		aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_DOWNLOAD_CONTRACTID, true);
		aClassName = MozillaDelegate.wcsToMbcs (null, "Download", true); //$NON-NLS-1$
		rc = componentRegistrar.RegisterFactory (XPCOM.NS_DOWNLOAD_CID, aClassName, aContractID, downloadFactory.getAddress ());
		if (rc != XPCOM.NS_OK) {
			browser.dispose ();
			error (rc);
		}
		downloadFactory.Release ();

		FilePickerFactory pickerFactory = IsXULRunner ? new FilePickerFactory_1_8 () : new FilePickerFactory ();
		pickerFactory.AddRef ();
		aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_FILEPICKER_CONTRACTID, true);
		aClassName = MozillaDelegate.wcsToMbcs (null, "FilePicker", true); //$NON-NLS-1$
		rc = componentRegistrar.RegisterFactory (XPCOM.NS_FILEPICKER_CID, aClassName, aContractID, pickerFactory.getAddress ());
		if (rc != XPCOM.NS_OK) {
			browser.dispose ();
			error (rc);
		}
		pickerFactory.Release ();

		componentRegistrar.Release ();
		componentManager.Release ();

		Initialized = true;
	}

	if (display.getData (DISPOSE_LISTENER_HOOKED) == null) {
		display.setData (DISPOSE_LISTENER_HOOKED, DISPOSE_LISTENER_HOOKED);
		display.addListener (SWT.Dispose, new Listener () {
			public void handleEvent (Event event) {
				if (BrowserCount > 0) return; /* another display is still active */

				int /*long*/[] result = new int /*long*/[1];
				int rc = XPCOM.NS_GetServiceManager (result);
				if (rc != XPCOM.NS_OK) error (rc);
				if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);

				nsIServiceManager serviceManager = new nsIServiceManager (result[0]);
				result[0] = 0;		
				byte[] buffer = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_OBSERVER_CONTRACTID, true);
				rc = serviceManager.GetServiceByContractID (buffer, nsIObserverService.NS_IOBSERVERSERVICE_IID, result);
				if (rc != XPCOM.NS_OK) error (rc);
				if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);

				nsIObserverService observerService = new nsIObserverService (result[0]);
				result[0] = 0;
				buffer = MozillaDelegate.wcsToMbcs (null, PROFILE_BEFORE_CHANGE, true);
				int length = SHUTDOWN_PERSIST.length ();
				char[] chars = new char [length + 1];
				SHUTDOWN_PERSIST.getChars (0, length, chars, 0);
				rc = observerService.NotifyObservers (0, buffer, chars);
				if (rc != XPCOM.NS_OK) error (rc);
				observerService.Release ();

				if (LocationProvider != null) {
					String prefsLocation = LocationProvider.profilePath + AppFileLocProvider.PREFERENCES_FILE;
					nsEmbedString pathString = new nsEmbedString (prefsLocation);
					rc = XPCOM.NS_NewLocalFile (pathString.getAddress (), 1, result);
					if (rc != XPCOM.NS_OK) Mozilla.error (rc);
					if (result[0] == 0) Mozilla.error (XPCOM.NS_ERROR_NULL_POINTER);
					pathString.dispose ();

					nsILocalFile localFile = new nsILocalFile (result [0]);
					result[0] = 0;
				    rc = localFile.QueryInterface (nsIFile.NS_IFILE_IID, result); 
					if (rc != XPCOM.NS_OK) Mozilla.error (rc);
					if (result[0] == 0) Mozilla.error (XPCOM.NS_ERROR_NO_INTERFACE);
					localFile.Release ();

					nsIFile prefFile = new nsIFile (result[0]);
					result[0] = 0;

					buffer = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_PREFSERVICE_CONTRACTID, true);
					rc = serviceManager.GetServiceByContractID (buffer, nsIPrefService.NS_IPREFSERVICE_IID, result);
					if (rc != XPCOM.NS_OK) error (rc);
					if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);

					nsIPrefService prefService = new nsIPrefService (result[0]);
					result[0] = 0;
					rc = prefService.SavePrefFile(prefFile.getAddress ());
					prefService.Release ();
					prefFile.Release ();
				}
				serviceManager.Release ();

				if (XPCOMWasGlued) {
					/*
					* XULRunner 1.9 can crash on Windows if XPCOMGlueShutdown is invoked here,
					* presumably because one or more of its unloaded symbols are referenced when
					* this callback returns.  The workaround is to delay invoking XPCOMGlueShutdown
					* so that its symbols are still available once this callback returns.
					*/
					display.asyncExec (new Runnable () {
						public void run () {
							XPCOM.XPCOMGlueShutdown ();
						}
					});

					// the following is intentionally commented, because calling XRE_TermEmbedding
					// causes subsequent browser instantiations within the process to fail

//					int size = XPCOM.nsDynamicFunctionLoad_sizeof ();
//					/* alloc memory for two structs, the second is empty to signify the end of the list */
//					int /*long*/ ptr = C.malloc (size * 2);
//					C.memset (ptr, 0, size * 2);
//					nsDynamicFunctionLoad functionLoad = new nsDynamicFunctionLoad ();
//					byte[] bytes = MozillaDelegate.wcsToMbcs (null, "XRE_TermEmbedding", true); //$NON-NLS-1$
//					functionLoad.functionName = C.malloc (bytes.length);
//					C.memmove (functionLoad.functionName, bytes, bytes.length);
//					functionLoad.function = C.malloc (C.PTR_SIZEOF);
//					C.memmove (functionLoad.function, new int /*long*/[] {0} , C.PTR_SIZEOF);
//					XPCOM.memmove (ptr, functionLoad, XPCOM.nsDynamicFunctionLoad_sizeof ());
//					XPCOM.XPCOMGlueLoadXULFunctions (ptr);
//					C.memmove (result, functionLoad.function, C.PTR_SIZEOF);
//					int /*long*/ functionPtr = result[0];
//					result[0] = 0;
//					C.free (functionLoad.function);
//					C.free (functionLoad.functionName);
//					C.free (ptr);
//					XPCOM.Call (functionPtr);

					XPCOMWasGlued = false;
				}
				if (XPCOMInitWasGlued) {
					XPCOMInit.XPCOMGlueShutdown ();
					XPCOMInitWasGlued = false;
				}
				Initialized = false;
			}
		});
	}

	BrowserCount++;
	int rc = XPCOM.NS_GetComponentManager (result);
	if (rc != XPCOM.NS_OK) {
		browser.dispose ();
		error (rc);
	}
	if (result[0] == 0) {
		browser.dispose ();
		error (XPCOM.NS_NOINTERFACE);
	}
	
	nsIComponentManager componentManager = new nsIComponentManager (result[0]);
	result[0] = 0;
	nsID NS_IWEBBROWSER_CID = new nsID ("F1EAC761-87E9-11d3-AF80-00A024FFC08C"); //$NON-NLS-1$
	rc = componentManager.CreateInstance (NS_IWEBBROWSER_CID, 0, nsIWebBrowser.NS_IWEBBROWSER_IID, result);
	if (rc != XPCOM.NS_OK) {
		browser.dispose ();
		error (rc);
	}
	if (result[0] == 0) {
		browser.dispose ();
		error (XPCOM.NS_NOINTERFACE);	
	}
	
	webBrowser = new nsIWebBrowser (result[0]);
	result[0] = 0;

	createCOMInterfaces ();
	AddRef ();

	rc = webBrowser.SetContainerWindow (webBrowserChrome.getAddress());
	if (rc != XPCOM.NS_OK) {
		browser.dispose ();
		error (rc);
	}
			
	rc = webBrowser.QueryInterface (nsIBaseWindow.NS_IBASEWINDOW_IID, result);
	if (rc != XPCOM.NS_OK) {
		browser.dispose ();
		error (rc);
	}
	if (result[0] == 0) {
		browser.dispose ();
		error (XPCOM.NS_ERROR_NO_INTERFACE);
	}
	
	nsIBaseWindow baseWindow = new nsIBaseWindow (result[0]);
	result[0] = 0;
	Rectangle rect = browser.getClientArea ();
	if (rect.isEmpty ()) {
		rect.width = 1;
		rect.height = 1;
	}

	embedHandle = delegate.getHandle ();

	rc = baseWindow.InitWindow (embedHandle, 0, 0, 0, rect.width, rect.height);
	if (rc != XPCOM.NS_OK) {
		browser.dispose ();
		error (XPCOM.NS_ERROR_FAILURE);
	}
	rc = delegate.createBaseWindow (baseWindow);
	if (rc != XPCOM.NS_OK) {
		browser.dispose ();
		error (XPCOM.NS_ERROR_FAILURE);
	}
	rc = baseWindow.SetVisibility (1);
	if (rc != XPCOM.NS_OK) {
		browser.dispose ();
		error (XPCOM.NS_ERROR_FAILURE);
	}
	baseWindow.Release ();

	if (!PerformedVersionCheck) {
		PerformedVersionCheck = true;

		rc = componentManager.QueryInterface (nsIComponentRegistrar.NS_ICOMPONENTREGISTRAR_IID, result);
		if (rc != XPCOM.NS_OK) {
			browser.dispose ();
			error (rc);
		}
		if (result[0] == 0) {
			browser.dispose ();
			error (XPCOM.NS_NOINTERFACE);
		}
		nsIComponentRegistrar componentRegistrar = new nsIComponentRegistrar (result[0]);
		result[0] = 0;

		HelperAppLauncherDialogFactory dialogFactory = new HelperAppLauncherDialogFactory ();
		dialogFactory.AddRef ();
		byte[] aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_HELPERAPPLAUNCHERDIALOG_CONTRACTID, true);
		byte[] aClassName = MozillaDelegate.wcsToMbcs (null, "Helper App Launcher Dialog", true); //$NON-NLS-1$
		rc = componentRegistrar.RegisterFactory (XPCOM.NS_HELPERAPPLAUNCHERDIALOG_CID, aClassName, aContractID, dialogFactory.getAddress ());
		if (rc != XPCOM.NS_OK) {
			browser.dispose ();
			error (rc);
		}
		dialogFactory.Release ();

		/*
		* Check for the availability of the pre-1.8 implementation of nsIDocShell
		* to determine if the GRE's version is < 1.8.
		*/
		rc = webBrowser.QueryInterface (nsIInterfaceRequestor.NS_IINTERFACEREQUESTOR_IID, result);
		if (rc != XPCOM.NS_OK) {
			browser.dispose ();
			error (XPCOM.NS_ERROR_FAILURE);
		}
		if (result[0] == 0) {
			browser.dispose ();
			error (XPCOM.NS_ERROR_NO_INTERFACE);
		}
		nsIInterfaceRequestor interfaceRequestor = new nsIInterfaceRequestor (result[0]);
		result[0] = 0;

		rc = interfaceRequestor.GetInterface (nsIDocShell.NS_IDOCSHELL_IID, result);
		if (rc == XPCOM.NS_OK && result[0] != 0) {
			IsPre_1_8 = true;
			new nsISupports (result[0]).Release ();
		}
		result[0] = 0;
		IsPre_1_9 = true;

		/*
		* A Download factory for contract "Transfer" must be registered iff the GRE's version is 1.8.x.
		*   Check for the availability of the 1.8 implementation of nsIDocShell to determine if the
		*   GRE's version is 1.8.x.
		* If the GRE version is < 1.8 then the previously-registered Download factory for contract
		*   "Download" will be used.
		* If the GRE version is >= 1.9 then no Download factory is registered because this
		*   functionality is provided by the GRE.
		*/
		if (!IsPre_1_8) {
			rc = interfaceRequestor.GetInterface (nsIDocShell_1_8.NS_IDOCSHELL_IID, result);
			if (rc == XPCOM.NS_OK && result[0] != 0) { /* 1.8 */
				new nsISupports (result[0]).Release ();
				result[0] = 0;

				DownloadFactory_1_8 downloadFactory_1_8 = new DownloadFactory_1_8 ();
				downloadFactory_1_8.AddRef ();
				aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_TRANSFER_CONTRACTID, true);
				aClassName = MozillaDelegate.wcsToMbcs (null, "Transfer", true); //$NON-NLS-1$
				rc = componentRegistrar.RegisterFactory (XPCOM.NS_DOWNLOAD_CID, aClassName, aContractID, downloadFactory_1_8.getAddress ());
				if (rc != XPCOM.NS_OK) {
					browser.dispose ();
					error (rc);
				}
				downloadFactory_1_8.Release ();
			} else { /* >= 1.9 */
				IsPre_1_9 = false;
			}
		}
		result[0] = 0;
		interfaceRequestor.Release ();
		componentRegistrar.Release ();
	}
	componentManager.Release ();

	/*
	 * Bug in XULRunner 1.9.  On win32, Mozilla does not clear its background before content has
	 * been set into it.  As a result, embedders appear broken if they do not immediately display
	 * a URL or text.  The Mozilla bug for this is https://bugzilla.mozilla.org/show_bug.cgi?id=453523.
	 * 
	 * The workaround is to subclass the Mozilla window and clear it whenever WM_ERASEBKGND is received.
	 * This subclass should be removed once content has been set into the browser.
	 */
	if (!IsPre_1_9) {
		delegate.addWindowSubclass ();
	}

	rc = webBrowser.AddWebBrowserListener (weakReference.getAddress (), nsIWebProgressListener.NS_IWEBPROGRESSLISTENER_IID);
	if (rc != XPCOM.NS_OK) {
		browser.dispose ();
		error (rc);
	}

	rc = webBrowser.SetParentURIContentListener (uriContentListener.getAddress ());
	if (rc != XPCOM.NS_OK) {
		browser.dispose ();
		error (rc);
	}

	delegate.init ();

	listener = new Listener () {
		public void handleEvent (Event event) {
			switch (event.type) {
				case SWT.Dispose: {
					/* make this handler run after other dispose listeners */
					if (ignoreDispose) {
						ignoreDispose = false;
						break;
					}
					ignoreDispose = true;
					browser.notifyListeners (event.type, event);
					event.type = SWT.NONE;
					onDispose (event.display);
					break;
				}
				case SWT.Resize: onResize (); break;
				case SWT.FocusIn: Activate (); break;
				case SWT.Activate: Activate (); break;
				case SWT.Deactivate: {
					Display display = event.display;
					if (Mozilla.this.browser == display.getFocusControl ()) Deactivate ();
					break;
				}
				case SWT.Show: {
					/*
					* Feature in GTK Mozilla.  Mozilla does not show up when
					* its container (a GTK fixed handle) is made visible
					* after having been hidden.  The workaround is to reset
					* its size after the container has been made visible. 
					*/
					Display display = event.display;
					display.asyncExec(new Runnable () {
						public void run() {
							if (browser.isDisposed ()) return;
							onResize ();
						}
					});
					break;
				}
			}
		}
	};	
	int[] folderEvents = new int[] {
		SWT.Dispose,
		SWT.Resize,  
		SWT.FocusIn,
		SWT.Activate,
		SWT.Deactivate,
		SWT.Show,
		SWT.KeyDown		// needed to make browser traversable
	};
	for (int i = 0; i < folderEvents.length; i++) {
		browser.addListener (folderEvents[i], listener);
	}
}

public boolean back () {
	htmlBytes = null;

	int /*long*/[] result = new int /*long*/[1];
	int rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result);
	if (rc != XPCOM.NS_OK) error (rc);
	if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
	
	nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]);		 	
	rc = webNavigation.GoBack ();	
	webNavigation.Release ();
	return rc == XPCOM.NS_OK;
}

void createCOMInterfaces () {
	// Create each of the interfaces that this object implements
	supports = new XPCOMObject (new int[] {2, 0, 0}) {
		public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);}
		public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();}
		public int /*long*/ method2 (int /*long*/[] args) {return Release ();}
	};
	
	weakReference = new XPCOMObject (new int[] {2, 0, 0, 2}) {
		public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);}
		public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();}
		public int /*long*/ method2 (int /*long*/[] args) {return Release ();}
		public int /*long*/ method3 (int /*long*/[] args) {return QueryReferent (args[0], args[1]);}
	};

	webProgressListener = new XPCOMObject (new int[] {2, 0, 0, 4, 6, 3, 4, 3}) {
		public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);}
		public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();}
		public int /*long*/ method2 (int /*long*/[] args) {return Release ();}
		public int /*long*/ method3 (int /*long*/[] args) {return OnStateChange (args[0], args[1], (int)/*64*/args[2], (int)/*64*/args[3]);}
		public int /*long*/ method4 (int /*long*/[] args) {return OnProgressChange (args[0], args[1], (int)/*64*/args[2], (int)/*64*/args[3], (int)/*64*/args[4], (int)/*64*/args[5]);}
		public int /*long*/ method5 (int /*long*/[] args) {return OnLocationChange (args[0], args[1], args[2]);}
		public int /*long*/ method6 (int /*long*/[] args) {return OnStatusChange (args[0], args[1], (int)/*64*/args[2], args[3]);}
		public int /*long*/ method7 (int /*long*/[] args) {return OnSecurityChange (args[0], args[1], (int)/*64*/args[2]);}
	};
	
	webBrowserChrome = new XPCOMObject (new int[] {2, 0, 0, 2, 1, 1, 1, 1, 0, 2, 0, 1, 1}) {
		public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);}
		public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();}
		public int /*long*/ method2 (int /*long*/[] args) {return Release ();}
		public int /*long*/ method3 (int /*long*/[] args) {return SetStatus ((int)/*64*/args[0], args[1]);}
		public int /*long*/ method4 (int /*long*/[] args) {return GetWebBrowser (args[0]);}
		public int /*long*/ method5 (int /*long*/[] args) {return SetWebBrowser (args[0]);}
		public int /*long*/ method6 (int /*long*/[] args) {return GetChromeFlags (args[0]);}
		public int /*long*/ method7 (int /*long*/[] args) {return SetChromeFlags ((int)/*64*/args[0]);}
		public int /*long*/ method8 (int /*long*/[] args) {return DestroyBrowserWindow ();}
		public int /*long*/ method9 (int /*long*/[] args) {return SizeBrowserTo ((int)/*64*/args[0], (int)/*64*/args[1]);}
		public int /*long*/ method10 (int /*long*/[] args) {return ShowAsModal ();}
		public int /*long*/ method11 (int /*long*/[] args) {return IsWindowModal (args[0]);}
		public int /*long*/ method12 (int /*long*/[] args) {return ExitModalEventLoop ((int)/*64*/args[0]);}
	};
	
	webBrowserChromeFocus = new XPCOMObject (new int[] {2, 0, 0, 0, 0}) {
		public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);}
		public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();}
		public int /*long*/ method2 (int /*long*/[] args) {return Release ();}
		public int /*long*/ method3 (int /*long*/[] args) {return FocusNextElement ();}
		public int /*long*/ method4 (int /*long*/[] args) {return FocusPrevElement ();}
	};
		
	embeddingSiteWindow = new XPCOMObject (new int[] {2, 0, 0, 5, 5, 0, 1, 1, 1, 1, 1}) {
		public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);}
		public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();}
		public int /*long*/ method2 (int /*long*/[] args) {return Release ();}
		public int /*long*/ method3 (int /*long*/[] args) {return SetDimensions ((int)/*64*/args[0], (int)/*64*/args[1], (int)/*64*/args[2], (int)/*64*/args[3], (int)/*64*/args[4]);}
		public int /*long*/ method4 (int /*long*/[] args) {return GetDimensions ((int)/*64*/args[0], args[1], args[2], args[3], args[4]);}
		public int /*long*/ method5 (int /*long*/[] args) {return SetFocus ();}
		public int /*long*/ method6 (int /*long*/[] args) {return GetVisibility (args[0]);}
		public int /*long*/ method7 (int /*long*/[] args) {return SetVisibility ((int)/*64*/args[0]);}
		public int /*long*/ method8 (int /*long*/[] args) {return GetTitle (args[0]);}
		public int /*long*/ method9 (int /*long*/[] args) {return SetTitle (args[0]);}
		public int /*long*/ method10 (int /*long*/[] args) {return GetSiteWindow (args[0]);}
	};
	
	interfaceRequestor = new XPCOMObject (new int[] {2, 0, 0, 2} ){
		public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);}
		public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();}
		public int /*long*/ method2 (int /*long*/[] args) {return Release ();}
		public int /*long*/ method3 (int /*long*/[] args) {return GetInterface (args[0], args[1]);}
	};
		
	supportsWeakReference = new XPCOMObject (new int[] {2, 0, 0, 1}) {
		public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);}
		public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();}
		public int /*long*/ method2 (int /*long*/[] args) {return Release ();}
		public int /*long*/ method3 (int /*long*/[] args) {return GetWeakReference (args[0]);}
	};
	
	contextMenuListener = new XPCOMObject (new int[] {2, 0, 0, 3}) {
		public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);}
		public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();}
		public int /*long*/ method2 (int /*long*/[] args) {return Release ();}
		public int /*long*/ method3 (int /*long*/[] args) {return OnShowContextMenu ((int)/*64*/args[0], args[1], args[2]);}
	};
	
	uriContentListener = new XPCOMObject (new int[] {2, 0, 0, 2, 5, 3, 4, 1, 1, 1, 1}) {
		public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);}
		public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();}
		public int /*long*/ method2 (int /*long*/[] args) {return Release ();}
		public int /*long*/ method3 (int /*long*/[] args) {return OnStartURIOpen (args[0], args[1]);}
		public int /*long*/ method4 (int /*long*/[] args) {return DoContent (args[0], (int)/*64*/args[1], args[2], args[3], args[4]);}
		public int /*long*/ method5 (int /*long*/[] args) {return IsPreferred (args[0], args[1], args[2]);}
		public int /*long*/ method6 (int /*long*/[] args) {return CanHandleContent (args[0], (int)/*64*/args[1], args[2], args[3]);}
		public int /*long*/ method7 (int /*long*/[] args) {return GetLoadCookie (args[0]);}
		public int /*long*/ method8 (int /*long*/[] args) {return SetLoadCookie (args[0]);}
		public int /*long*/ method9 (int /*long*/[] args) {return GetParentContentListener (args[0]);}
		public int /*long*/ method10 (int /*long*/[] args) {return SetParentContentListener (args[0]);}		
	};
	
	tooltipListener = new XPCOMObject (new int[] {2, 0, 0, 3, 0}) {
		public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);}
		public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();}
		public int /*long*/ method2 (int /*long*/[] args) {return Release ();}
		public int /*long*/ method3 (int /*long*/[] args) {return OnShowTooltip ((int)/*64*/args[0], (int)/*64*/args[1], args[2]);}
		public int /*long*/ method4 (int /*long*/[] args) {return OnHideTooltip ();}		
	};

	domEventListener = new XPCOMObject (new int[] {2, 0, 0, 1}) {
		public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);}
		public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();}
		public int /*long*/ method2 (int /*long*/[] args) {return Release ();}
		public int /*long*/ method3 (int /*long*/[] args) {return HandleEvent (args[0]);}
	};
}

void deregisterFunction (BrowserFunction function) {
	super.deregisterFunction (function);
	AllFunctions.remove (new Integer (function.index));
}

void disposeCOMInterfaces () {
	if (supports != null) {
		supports.dispose ();
		supports = null;
	}	
	if (weakReference != null) {
		weakReference.dispose ();
		weakReference = null;	
	}
	if (webProgressListener != null) {
		webProgressListener.dispose ();
		webProgressListener = null;
	}
	if (webBrowserChrome != null) {
		webBrowserChrome.dispose ();
		webBrowserChrome = null;
	}
	if (webBrowserChromeFocus != null) {
		webBrowserChromeFocus.dispose ();
		webBrowserChromeFocus = null;
	}
	if (embeddingSiteWindow != null) {
		embeddingSiteWindow.dispose ();
		embeddingSiteWindow = null;
	}
	if (interfaceRequestor != null) {
		interfaceRequestor.dispose ();
		interfaceRequestor = null;
	}		
	if (supportsWeakReference != null) {
		supportsWeakReference.dispose ();
		supportsWeakReference = null;
	}	
	if (contextMenuListener != null) {
		contextMenuListener.dispose ();
		contextMenuListener = null;
	}
	if (uriContentListener != null) {
		uriContentListener.dispose ();
		uriContentListener = null;
	}
	if (tooltipListener != null) {
		tooltipListener.dispose ();
		tooltipListener = null;
	}
	if (domEventListener != null) {
		domEventListener.dispose ();
		domEventListener = null;
	}
}

public boolean execute (String script) {
	/*
	* This could be the first content that is set into the browser, so
	* ensure that the custom subclass that works around Mozilla bug
	* https://bugzilla.mozilla.org/show_bug.cgi?id=453523 is removed.
	*/
	delegate.removeWindowSubclass ();

	/*
	* As of mozilla 1.9 executing javascript via the javascript: protocol no
	* longer happens synchronously.  As a result, the result of executing JS
	* is not returned to the java side when expected by the client.  The
	* workaround is to invoke the javascript handler directly via C++, which is
	* exposed as of mozilla 1.9.
	*/
	int /*long*/[] result = new int /*long*/[1];
	if (!IsPre_1_9) {
		int rc = XPCOM.NS_GetServiceManager (result);
		if (rc != XPCOM.NS_OK) error (rc);
		if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);

		nsIServiceManager serviceManager = new nsIServiceManager (result[0]);
		result[0] = 0;
		nsIPrincipal principal = null;
		byte[] aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_SCRIPTSECURITYMANAGER_CONTRACTID, true);
		rc = serviceManager.GetServiceByContractID (aContractID, nsIScriptSecurityManager_1_9_1.NS_ISCRIPTSECURITYMANAGER_IID, result);
		if (rc == XPCOM.NS_OK && result[0] != 0) {
			nsIScriptSecurityManager_1_9_1 securityManager = new nsIScriptSecurityManager_1_9_1 (result[0]);
			result[0] = 0;
			rc = securityManager.GetSystemPrincipal (result);
			if (rc != XPCOM.NS_OK) error (rc);
			if (result[0] == 0) error (XPCOM.NS_ERROR_NULL_POINTER);
			principal = new nsIPrincipal (result[0]);
			result[0] = 0;
			securityManager.Release ();
		} else {
			rc = serviceManager.GetServiceByContractID (aContractID, nsIScriptSecurityManager_1_9.NS_ISCRIPTSECURITYMANAGER_IID, result);
			if (rc == XPCOM.NS_OK && result[0] != 0) {
				nsIScriptSecurityManager_1_9 securityManager = new nsIScriptSecurityManager_1_9 (result[0]);
				result[0] = 0;
				rc = securityManager.GetSystemPrincipal (result);
				if (rc != XPCOM.NS_OK) error (rc);
				if (result[0] == 0) error (XPCOM.NS_ERROR_NULL_POINTER);
				principal = new nsIPrincipal (result[0]);
				result[0] = 0;
				securityManager.Release ();
			}
		}
		serviceManager.Release ();

		if (principal != null) {
			rc = webBrowser.QueryInterface (nsIInterfaceRequestor.NS_IINTERFACEREQUESTOR_IID, result);
			if (rc != XPCOM.NS_OK) error (rc);
			if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);

			nsIInterfaceRequestor interfaceRequestor = new nsIInterfaceRequestor (result[0]);
			result[0] = 0;
			nsID scriptGlobalObjectNSID = new nsID ("6afecd40-0b9a-4cfd-8c42-0f645cd91829"); /* nsIScriptGlobalObject */ //$NON-NLS-1$
			rc = interfaceRequestor.GetInterface (scriptGlobalObjectNSID, result);
			interfaceRequestor.Release ();

			if (rc == XPCOM.NS_OK && result[0] != 0) {
				int /*long*/ scriptGlobalObject = result[0];
				result[0] = 0;
				rc = (int/*64*/)XPCOM.nsIScriptGlobalObject_EnsureScriptEnvironment (scriptGlobalObject, 2); /* nsIProgrammingLanguage.JAVASCRIPT */
				if (rc != XPCOM.NS_OK) error (rc);
				int /*long*/ scriptContext = XPCOM.nsIScriptGlobalObject_GetScriptContext (scriptGlobalObject, 2); /* nsIProgrammingLanguage.JAVASCRIPT */
				int /*long*/ globalJSObject = XPCOM.nsIScriptGlobalObject_GetScriptGlobal (scriptGlobalObject, 2); /* nsIProgrammingLanguage.JAVASCRIPT */
				new nsISupports (scriptGlobalObject).Release ();

				if (scriptContext != 0 && globalJSObject != 0) {
					/* ensure that the received nsIScriptContext implements the expected interface */
					nsID scriptContextNSID = new nsID ("e7b9871d-3adc-4bf7-850d-7fb9554886bf"); /* nsIScriptContext */ //$NON-NLS-1$					
					rc = new nsISupports (scriptContext).QueryInterface (scriptContextNSID, result);
					if (rc == XPCOM.NS_OK && result[0] != 0) {
						new nsISupports (result[0]).Release ();
						result[0] = 0;

						int /*long*/ nativeContext = XPCOM.nsIScriptContext_GetNativeContext (scriptContext);
						if (nativeContext != 0) {
							int length = script.length ();
							char[] scriptChars = new char[length];
							script.getChars(0, length, scriptChars, 0);
							byte[] urlbytes = MozillaDelegate.wcsToMbcs (null, getUrl (), true);
							rc = principal.GetJSPrincipals (nativeContext, result);
							if (rc == XPCOM.NS_OK && result[0] != 0) {
								int /*long*/ principals = result[0];
								result[0] = 0;
								principal.Release ();
								String mozillaPath = LocationProvider.mozillaPath + delegate.getJSLibraryName () + '\0';
								byte[] pathBytes = null;
								try {
									pathBytes = mozillaPath.getBytes ("UTF-8"); //$NON-NLS-1$
								} catch (UnsupportedEncodingException e) {
									pathBytes = mozillaPath.getBytes ();
								}
								rc = XPCOM.JS_EvaluateUCScriptForPrincipals (pathBytes, nativeContext, globalJSObject, principals, scriptChars, length, urlbytes, 0, result);
								return rc != 0;
							}
						}
					}
				}
			}
			principal.Release ();
		}
	}

	/* fall back to the pre-1.9 approach */

	String url = PREFIX_JAVASCRIPT + script + ";void(0);";	//$NON-NLS-1$
	int rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result);
	if (rc != XPCOM.NS_OK) error (rc);
	if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);

	nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]);
    char[] arg = url.toCharArray (); 
    char[] c = new char[arg.length+1];
    System.arraycopy (arg, 0, c, 0, arg.length);
	rc = webNavigation.LoadURI (c, nsIWebNavigation.LOAD_FLAGS_NONE, 0, 0, 0);
	webNavigation.Release ();
	return rc == XPCOM.NS_OK;
}

static Browser findBrowser (int /*long*/ handle) {
	return MozillaDelegate.findBrowser (handle);
}

static Browser findBrowser (nsIDOMWindow aDOMWindow) {
	int /*long*/[] result = new int /*long*/[1];
	int rc = XPCOM.NS_GetServiceManager (result);
	if (rc != XPCOM.NS_OK) Mozilla.error (rc);
	if (result[0] == 0) Mozilla.error (XPCOM.NS_NOINTERFACE);

	nsIServiceManager serviceManager = new nsIServiceManager (result[0]);
	result[0] = 0;
	byte[] aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_WINDOWWATCHER_CONTRACTID, true);
	rc = serviceManager.GetServiceByContractID (aContractID, nsIWindowWatcher.NS_IWINDOWWATCHER_IID, result);
	if (rc != XPCOM.NS_OK) Mozilla.error(rc);
	if (result[0] == 0) Mozilla.error (XPCOM.NS_NOINTERFACE);		
	serviceManager.Release ();

	nsIWindowWatcher windowWatcher = new nsIWindowWatcher (result[0]);
	result[0] = 0;
	/* the chrome will only be answered for the top-level nsIDOMWindow */
	rc = aDOMWindow.GetTop (result);
	if (rc != XPCOM.NS_OK) Mozilla.error (rc);
	if (result[0] == 0) Mozilla.error (XPCOM.NS_NOINTERFACE);
	int /*long*/ topDOMWindow = result[0];
	result[0] = 0;
	rc = windowWatcher.GetChromeForWindow (topDOMWindow, result);
	if (rc != XPCOM.NS_OK) Mozilla.error (rc);
	new nsISupports (topDOMWindow).Release ();
	windowWatcher.Release ();
	if (result[0] == 0) return null;	/* the parent chrome is disconnected */

	nsIWebBrowserChrome webBrowserChrome = new nsIWebBrowserChrome (result[0]);
	result[0] = 0;
	rc = webBrowserChrome.QueryInterface (nsIEmbeddingSiteWindow.NS_IEMBEDDINGSITEWINDOW_IID, result);
	if (rc != XPCOM.NS_OK) Mozilla.error (rc);
	if (result[0] == 0) Mozilla.error (XPCOM.NS_NOINTERFACE);		
	webBrowserChrome.Release ();

	nsIEmbeddingSiteWindow embeddingSiteWindow = new nsIEmbeddingSiteWindow (result[0]);
	result[0] = 0;
	rc = embeddingSiteWindow.GetSiteWindow (result);
	if (rc != XPCOM.NS_OK) Mozilla.error (rc);
	if (result[0] == 0) Mozilla.error (XPCOM.NS_NOINTERFACE);		
	embeddingSiteWindow.Release ();

	return findBrowser (result[0]); 
}

public boolean forward () {
	htmlBytes = null;

	int /*long*/[] result = new int /*long*/[1];
	int rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result);
	if (rc != XPCOM.NS_OK) error (rc);
	if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
	
	nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]);
	rc = webNavigation.GoForward ();
	webNavigation.Release ();

	return rc == XPCOM.NS_OK;
}

public String getBrowserType () {
	return "mozilla"; //$NON-NLS-1$
}

int getNextFunctionIndex () {
	return NextJSFunctionIndex++;
}

public String getText () {
	int /*long*/[] result = new int /*long*/[1];
	int rc = webBrowser.GetContentDOMWindow (result);
	if (rc != XPCOM.NS_OK) error (rc);
	if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);

	nsIDOMWindow window = new nsIDOMWindow (result[0]);
	result[0] = 0;
	rc = window.GetDocument (result);
	if (rc != XPCOM.NS_OK) error (rc);
	if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
	window.Release ();

	int /*long*/ document = result[0];
	result[0] = 0;
	rc = XPCOM.NS_GetComponentManager (result);
	if (rc != XPCOM.NS_OK) error (rc);
	if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);

	nsIComponentManager componentManager = new nsIComponentManager (result[0]);
	result[0] = 0;
	byte[] contractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_DOMSERIALIZER_CONTRACTID, true);
	char[] chars = null;

	rc = componentManager.CreateInstanceByContractID (contractID, 0, nsIDOMSerializer_1_7.NS_IDOMSERIALIZER_IID, result);
	if (rc == XPCOM.NS_OK) {	/* mozilla >= 1.7 */
		if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);

		nsIDOMSerializer_1_7 serializer = new nsIDOMSerializer_1_7 (result[0]);
		result[0] = 0;
		int /*long*/ string = XPCOM.nsEmbedString_new ();
		rc = serializer.SerializeToString (document, string);
		serializer.Release ();

		int length = XPCOM.nsEmbedString_Length (string);
		int /*long*/ buffer = XPCOM.nsEmbedString_get (string);
		chars = new char[length];
		XPCOM.memmove (chars, buffer, length * 2);
		XPCOM.nsEmbedString_delete (string);
	} else {	/* mozilla < 1.7 */
		rc = componentManager.CreateInstanceByContractID (contractID, 0, nsIDOMSerializer.NS_IDOMSERIALIZER_IID, result);
		if (rc != XPCOM.NS_OK) error (rc);
		if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);

		nsIDOMSerializer serializer = new nsIDOMSerializer (result[0]);
		result[0] = 0;
		rc = serializer.SerializeToString (document, result);
		serializer.Release ();

		int length = XPCOM.strlen_PRUnichar (result[0]);
		chars = new char[length];
		XPCOM.memmove (chars, result[0], length * 2);
	}

	componentManager.Release ();
	new nsISupports (document).Release ();
	return new String (chars);
}

public String getUrl () {
	int /*long*/[] result = new int /*long*/[1];
	int rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result);
	if (rc != XPCOM.NS_OK) error (rc);
	if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);

	nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]);
	int /*long*/[] aCurrentURI = new int /*long*/[1];
	rc = webNavigation.GetCurrentURI (aCurrentURI);
	if (rc != XPCOM.NS_OK) error (rc);
	webNavigation.Release ();

	byte[] dest = null;
	if (aCurrentURI[0] != 0) {
		nsIURI uri = new nsIURI (aCurrentURI[0]);
		int /*long*/ aSpec = XPCOM.nsEmbedCString_new ();
		rc = uri.GetSpec (aSpec);
		if (rc != XPCOM.NS_OK) error (rc);
		int length = XPCOM.nsEmbedCString_Length (aSpec);
		int /*long*/ buffer = XPCOM.nsEmbedCString_get (aSpec);
		dest = new byte[length];
		XPCOM.memmove (dest, buffer, length);
		XPCOM.nsEmbedCString_delete (aSpec);
		uri.Release ();
	}
	if (dest == null) return ""; //$NON-NLS-1$

	String location = new String (dest);
	/*
	 * If the URI indicates that the page is being rendered from memory
	 * (via setText()) then set it to about:blank to be consistent with IE.
	 */
	if (location.equals (URI_FROMMEMORY)) location = ABOUT_BLANK;
	return location;
}

public Object getWebBrowser () {
	if ((browser.getStyle () & SWT.MOZILLA) == 0) return null;
	if (webBrowserObject != null) return webBrowserObject;

	try {
		Class clazz = Class.forName ("org.mozilla.xpcom.Mozilla"); //$NON-NLS-1$
		Method method = clazz.getMethod ("getInstance", new Class[0]); //$NON-NLS-1$
		Object mozilla = method.invoke (null, new Object[0]);
		method = clazz.getMethod ("wrapXPCOMObject", new Class[] {Long.TYPE, String.class}); //$NON-NLS-1$
		webBrowserObject = method.invoke (mozilla, new Object[] {new Long (webBrowser.getAddress ()), nsIWebBrowser.NS_IWEBBROWSER_IID_STR});
		/*
		 * The following AddRef() is needed to offset the automatic Release() that
		 * will be performed by JavaXPCOM when webBrowserObject is finalized.
		 */
		webBrowser.AddRef ();
		return webBrowserObject;
	} catch (ClassNotFoundException e) {
	} catch (NoSuchMethodException e) {
	} catch (IllegalArgumentException e) {
	} catch (IllegalAccessException e) {
	} catch (InvocationTargetException e) {
	}
	return null;
}

public boolean isBackEnabled () {
	int /*long*/[] result = new int /*long*/[1];
	int rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result);
	if (rc != XPCOM.NS_OK) error (rc);
	if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
	
	nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]);
	int[] aCanGoBack = new int[1]; /* PRBool */
	rc = webNavigation.GetCanGoBack (aCanGoBack);	
	webNavigation.Release ();
	return aCanGoBack[0] != 0;
}

public boolean isForwardEnabled () {
	int /*long*/[] result = new int /*long*/[1];
	int rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result);
	if (rc != XPCOM.NS_OK) error (rc);
	if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
	
	nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]);
	int[] aCanGoForward = new int[1]; /* PRBool */
	rc = webNavigation.GetCanGoForward (aCanGoForward);
	webNavigation.Release ();
	return aCanGoForward[0] != 0;
}

static String error (int code) {
	throw new SWTError ("XPCOM error " + code); //$NON-NLS-1$
}

void onDispose (Display display) {
	int rc = webBrowser.RemoveWebBrowserListener (weakReference.getAddress (), nsIWebProgressListener.NS_IWEBPROGRESSLISTENER_IID);
	if (rc != XPCOM.NS_OK) error (rc);

	rc = webBrowser.SetParentURIContentListener (0);
	if (rc != XPCOM.NS_OK) error (rc);
	
	rc = webBrowser.SetContainerWindow (0);
	if (rc != XPCOM.NS_OK) error (rc);

	unhookDOMListeners ();
	if (listener != null) {
		int[] folderEvents = new int[] {
			SWT.Dispose,
			SWT.Resize,  
			SWT.FocusIn,
			SWT.Activate,
			SWT.Deactivate,
			SWT.Show,
			SWT.KeyDown,
		};
		for (int i = 0; i < folderEvents.length; i++) {
			browser.removeListener (folderEvents[i], listener);
		}
		listener = null;
	}

	int /*long*/[] result = new int /*long*/[1];
	rc = webBrowser.QueryInterface (nsIBaseWindow.NS_IBASEWINDOW_IID, result);
	if (rc != XPCOM.NS_OK) error (rc);
	if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);

	nsIBaseWindow baseWindow = new nsIBaseWindow (result[0]);
	rc = baseWindow.Destroy ();
	if (rc != XPCOM.NS_OK) error (rc);
	baseWindow.Release ();

	Release ();
	webBrowser.Release ();
	webBrowser = null;
	webBrowserObject = null;
	lastNavigateURL = null;
	htmlBytes = null;

	if (tip != null && !tip.isDisposed ()) tip.dispose ();
	tip = null;
	location = size = null;

	Enumeration elements = unhookedDOMWindows.elements ();
	while (elements.hasMoreElements ()) {
		LONG ptrObject = (LONG)elements.nextElement ();
		new nsISupports (ptrObject.value).Release ();
	}
	unhookedDOMWindows = null;

	elements = functions.elements ();
	while (elements.hasMoreElements ()) {
		BrowserFunction function = ((BrowserFunction)elements.nextElement ());
		AllFunctions.remove (new Integer (function.index));
		function.dispose (false);
	}
	functions = null;

	delegate.onDispose (embedHandle);
	delegate = null;

	embedHandle = 0;
	BrowserCount--;
}

void Activate () {
	int /*long*/[] result = new int /*long*/[1];
	int rc = webBrowser.QueryInterface (nsIWebBrowserFocus.NS_IWEBBROWSERFOCUS_IID, result);
	if (rc != XPCOM.NS_OK) error (rc);
	if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
	
	nsIWebBrowserFocus webBrowserFocus = new nsIWebBrowserFocus (result[0]);
	rc = webBrowserFocus.Activate ();
	if (rc != XPCOM.NS_OK) error (rc);
	webBrowserFocus.Release ();
}

void Deactivate () {
	int /*long*/[] result = new int /*long*/[1];
	int rc = webBrowser.QueryInterface (nsIWebBrowserFocus.NS_IWEBBROWSERFOCUS_IID, result);
	if (rc != XPCOM.NS_OK) error (rc);
	if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
	
	nsIWebBrowserFocus webBrowserFocus = new nsIWebBrowserFocus (result[0]);
	rc = webBrowserFocus.Deactivate ();
	if (rc != XPCOM.NS_OK) error (rc);
	webBrowserFocus.Release ();
}

void onResize () {
	Rectangle rect = browser.getClientArea ();
	int width = Math.max (1, rect.width);
	int height = Math.max (1, rect.height);

	int /*long*/[] result = new int /*long*/[1];
	int rc = webBrowser.QueryInterface (nsIBaseWindow.NS_IBASEWINDOW_IID, result);
	if (rc != XPCOM.NS_OK) error (rc);
	if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);

	delegate.setSize (embedHandle, width, height);
	nsIBaseWindow baseWindow = new nsIBaseWindow (result[0]);
	rc = baseWindow.SetPositionAndSize (0, 0, width, height, 1);
	if (rc != XPCOM.NS_OK) error (rc);
	baseWindow.Release ();
}

public void refresh () {
	htmlBytes = null;

	int /*long*/[] result = new int /*long*/[1];
	int rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result);
	if (rc != XPCOM.NS_OK) error(rc);
	if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
	
	nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]);		 	
	rc = webNavigation.Reload (nsIWebNavigation.LOAD_FLAGS_NONE);
	webNavigation.Release ();
	if (rc == XPCOM.NS_OK) return;
	/*
	* Feature in Mozilla.  Reload returns an error code NS_ERROR_INVALID_POINTER
	* when it is called immediately after a request to load a new document using
	* LoadURI.  The workaround is to ignore this error code.
	*
	* Feature in Mozilla.  Attempting to reload a file that no longer exists
	* returns an error code of NS_ERROR_FILE_NOT_FOUND.  This is equivalent to
	* attempting to load a non-existent local url, which is not a Browser error,
	* so this error code should be ignored. 
	*/
	if (rc != XPCOM.NS_ERROR_INVALID_POINTER && rc != XPCOM.NS_ERROR_FILE_NOT_FOUND) error (rc);
}

void registerFunction (BrowserFunction function) {
	super.registerFunction (function);
	AllFunctions.put (new Integer (function.index), function);
}

public boolean setText (String html) {
	/*
	*  Feature in Mozilla.  The focus memory of Mozilla must be 
	*  properly managed through the nsIWebBrowserFocus interface.
	*  In particular, nsIWebBrowserFocus.deactivate must be called
	*  when the focus moves from the browser (or one of its children
	*  managed by Mozilla to another widget.  We currently do not
	*  get notified when a widget takes focus away from the Browser.
	*  As a result, deactivate is not properly called. This causes
	*  Mozilla to retake focus the next time a document is loaded.
	*  This breaks the case where the HTML loaded in the Browser 
	*  varies while the user enters characters in a text widget. The text
	*  widget loses focus every time new content is loaded.
	*  The current workaround is to call deactivate everytime if 
	*  the browser currently does not have focus. A better workaround
	*  would be to have a way to call deactivate when the Browser
	*  or one of its children loses focus.
	*/
	if (browser != browser.getDisplay ().getFocusControl ()) Deactivate ();
	
	/* convert the String containing HTML to an array of bytes with UTF-8 data */
	byte[] data = null;
	try {
		data = html.getBytes ("UTF-8"); //$NON-NLS-1$
	} catch (UnsupportedEncodingException e) {
		return false;
	}

	/*
	 * This could be the first content that is set into the browser, so
	 * ensure that the custom subclass that works around Mozilla bug
	 * https://bugzilla.mozilla.org/show_bug.cgi?id=453523 is removed.
	 */
	delegate.removeWindowSubclass ();

	int /*long*/[] result = new int /*long*/[1];
	int rc = webBrowser.QueryInterface (nsIWebBrowserStream.NS_IWEBBROWSERSTREAM_IID, result);
	if (rc == XPCOM.NS_OK && result[0] != 0) {
		/*
		* Setting mozilla's content through nsIWebBrowserStream does not cause a page
		* load to occur, so the events that usually accompany a page change are not
		* fired.  To make this behave as expected, navigate to about:blank first and
		* then set the html content once the page has loaded.
		*/
		new nsISupports (result[0]).Release ();
		result[0] = 0;

		/*
		* If htmlBytes is not null then the about:blank page is already being loaded,
		* so no Navigate is required.  Just set the html that is to be shown.
		*/
		boolean blankLoading = htmlBytes != null;
		htmlBytes = data;
		if (blankLoading) return true;

		/* navigate to about:blank */
		rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result);
		if (rc != XPCOM.NS_OK) error (rc);
		if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
		nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]);
		result[0] = 0;
	    char[] uri = new char[ABOUT_BLANK.length () + 1];
	    ABOUT_BLANK.getChars (0, ABOUT_BLANK.length (), uri, 0);
		rc = webNavigation.LoadURI (uri, nsIWebNavigation.LOAD_FLAGS_NONE, 0, 0, 0);
		if (rc != XPCOM.NS_OK) error (rc);
		webNavigation.Release ();
	} else {
		byte[] contentCharsetBuffer = MozillaDelegate.wcsToMbcs (null, "UTF-8", true);	//$NON-NLS-1$
		int /*long*/ aContentCharset = XPCOM.nsEmbedCString_new (contentCharsetBuffer, contentCharsetBuffer.length);
		byte[] contentTypeBuffer = MozillaDelegate.wcsToMbcs (null, "text/html", true); // $NON-NLS-1$
		int /*long*/ aContentType = XPCOM.nsEmbedCString_new (contentTypeBuffer, contentTypeBuffer.length);

		rc = XPCOM.NS_GetServiceManager (result);
		if (rc != XPCOM.NS_OK) error (rc);
		if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);

		nsIServiceManager serviceManager = new nsIServiceManager (result[0]);
		result[0] = 0;
		rc = serviceManager.GetService (XPCOM.NS_IOSERVICE_CID, nsIIOService.NS_IIOSERVICE_IID, result);
		if (rc != XPCOM.NS_OK) error (rc);
		if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
		serviceManager.Release ();

		nsIIOService ioService = new nsIIOService (result[0]);
		result[0] = 0;
		/*
		* Note.  Mozilla ignores LINK tags used to load CSS stylesheets
		* when the URI protocol for the nsInputStreamChannel
		* is about:blank.  The fix is to specify the file protocol.
		*/
		byte[] aString = MozillaDelegate.wcsToMbcs (null, URI_FROMMEMORY, false);
		int /*long*/ aSpec = XPCOM.nsEmbedCString_new (aString, aString.length);
		rc = ioService.NewURI (aSpec, null, 0, result);
		if (rc != XPCOM.NS_OK) error (rc);
		if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
		XPCOM.nsEmbedCString_delete (aSpec);
		ioService.Release ();

		nsIURI uri = new nsIURI (result[0]);
		result[0] = 0;

		rc = webBrowser.QueryInterface (nsIInterfaceRequestor.NS_IINTERFACEREQUESTOR_IID, result);
		if (rc != XPCOM.NS_OK) error (rc);
		if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
		nsIInterfaceRequestor interfaceRequestor = new nsIInterfaceRequestor (result[0]);
		result[0] = 0;

		/*
		* Feature in Mozilla. LoadStream invokes the nsIInputStream argument
		* through a different thread.  The callback mechanism must attach 
		* a non java thread to the JVM otherwise the nsIInputStream Read and
		* Close methods never get called.
		*/
		InputStream inputStream = new InputStream (data);
		inputStream.AddRef ();

		rc = interfaceRequestor.GetInterface (nsIDocShell.NS_IDOCSHELL_IID, result);
		if (rc != XPCOM.NS_OK) error (rc);
		if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
		nsIDocShell docShell = new nsIDocShell (result[0]);
		result[0] = 0;
		rc = docShell.LoadStream (inputStream.getAddress (), uri.getAddress (), aContentType,  aContentCharset, 0);
		docShell.Release ();

		inputStream.Release ();
		interfaceRequestor.Release ();
		uri.Release ();
		XPCOM.nsEmbedCString_delete (aContentType);
		XPCOM.nsEmbedCString_delete (aContentCharset);
	}
	return true;
}

public boolean setUrl (String url) {
	htmlBytes = null;

	int /*long*/[] result = new int /*long*/[1];
	int rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result);
	if (rc != XPCOM.NS_OK) error (rc);
	if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);

	/*
	 * This could be the first content that is set into the browser, so
	 * ensure that the custom subclass that works around Mozilla bug
	 * https://bugzilla.mozilla.org/show_bug.cgi?id=453523 is removed.
	 */
	delegate.removeWindowSubclass ();

	nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]);
    char[] uri = new char[url.length () + 1];
    url.getChars (0, url.length (), uri, 0);
	rc = webNavigation.LoadURI (uri, nsIWebNavigation.LOAD_FLAGS_NONE, 0, 0, 0);
	webNavigation.Release ();
	return rc == XPCOM.NS_OK;
}

public void stop () {
	htmlBytes = null;

	int /*long*/[] result = new int /*long*/[1];
	int rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result);
	if (rc != XPCOM.NS_OK) error (rc);
	if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
	
	nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]);	 	
	rc = webNavigation.Stop (nsIWebNavigation.STOP_ALL);
	if (rc != XPCOM.NS_OK) error (rc);
	webNavigation.Release ();
}

void hookDOMListeners (nsIDOMEventTarget target, boolean isTop) {
	nsEmbedString string = new nsEmbedString (XPCOM.DOMEVENT_FOCUS);
	target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0);
	string.dispose ();
	string = new nsEmbedString (XPCOM.DOMEVENT_UNLOAD);
	target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0);
	string.dispose ();
	string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEDOWN);
	target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0);
	string.dispose ();
	string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEUP);
	target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0);
	string.dispose ();
	string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEMOVE);
	target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0);
	string.dispose ();
	string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEWHEEL);
	target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0);
	string.dispose ();
	string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEDRAG);
	target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0);
	string.dispose ();

	/*
	* Only hook mouseover and mouseout if the target is a top-level frame, so that mouse moves
	* between frames will not generate events.
	*/
	if (isTop && delegate.hookEnterExit ()) {
		string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEOVER);
		target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0);
		string.dispose ();
		string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEOUT);
		target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0);
		string.dispose ();
	}

	string = new nsEmbedString (XPCOM.DOMEVENT_KEYDOWN);
	target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0);
	string.dispose ();
	string = new nsEmbedString (XPCOM.DOMEVENT_KEYPRESS);
	target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0);
	string.dispose ();
	string = new nsEmbedString (XPCOM.DOMEVENT_KEYUP);
	target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0);
	string.dispose ();
}

void unhookDOMListeners () {
	int /*long*/[] result = new int /*long*/[1];
	int rc = webBrowser.GetContentDOMWindow (result);
	if (rc != XPCOM.NS_OK) error (rc);
	if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);

	nsIDOMWindow window = new nsIDOMWindow (result[0]);
	result[0] = 0;
	rc = window.QueryInterface (nsIDOMEventTarget.NS_IDOMEVENTTARGET_IID, result);
	if (rc != XPCOM.NS_OK) error (rc);
	if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);

	nsIDOMEventTarget target = new nsIDOMEventTarget (result[0]);
	result[0] = 0;
	unhookDOMListeners (target);
	target.Release ();

	/* Listeners must be unhooked in pages contained in frames */
	rc = window.GetFrames (result);
	if (rc != XPCOM.NS_OK) error (rc);
	if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
	nsIDOMWindowCollection frames = new nsIDOMWindowCollection (result[0]);
	result[0] = 0;
	int[] frameCount = new int[1];
	rc = frames.GetLength (frameCount); /* PRUint32 */
	if (rc != XPCOM.NS_OK) error (rc);
	int count = frameCount[0];

	if (count > 0) {
		for (int i = 0; i < count; i++) {
			rc = frames.Item (i, result);
			if (rc != XPCOM.NS_OK) error (rc);
			if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);

			nsIDOMWindow frame = new nsIDOMWindow (result[0]);
			result[0] = 0;
			rc = frame.QueryInterface (nsIDOMEventTarget.NS_IDOMEVENTTARGET_IID, result);
			if (rc != XPCOM.NS_OK) error (rc);
			if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);

			target = new nsIDOMEventTarget (result[0]);
			result[0] = 0;
			unhookDOMListeners (target);
			target.Release ();
			frame.Release ();
		}
	}
	frames.Release ();
	window.Release ();
}

void unhookDOMListeners (nsIDOMEventTarget target) {
	nsEmbedString string = new nsEmbedString (XPCOM.DOMEVENT_FOCUS);
	target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), 0);
	string.dispose ();
	string = new nsEmbedString (XPCOM.DOMEVENT_UNLOAD);
	target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), 0);
	string.dispose ();
	string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEDOWN);
	target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), 0);
	string.dispose ();
	string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEUP);
	target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), 0);
	string.dispose ();
	string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEMOVE);
	target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), 0);
	string.dispose ();
	string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEWHEEL);
	target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), 0);
	string.dispose ();
	string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEDRAG);
	target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), 0);
	string.dispose ();
	string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEOVER);
	target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), 0);
	string.dispose ();
	string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEOUT);
	target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), 0);
	string.dispose ();
	string = new nsEmbedString (XPCOM.DOMEVENT_KEYDOWN);
	target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), 0);
	string.dispose ();
	string = new nsEmbedString (XPCOM.DOMEVENT_KEYPRESS);
	target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), 0);
	string.dispose ();
	string = new nsEmbedString (XPCOM.DOMEVENT_KEYUP);
	target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), 0);
	string.dispose ();
}

/* nsISupports */

int QueryInterface (int /*long*/ riid, int /*long*/ ppvObject) {
	if (riid == 0 || ppvObject == 0) return XPCOM.NS_ERROR_NO_INTERFACE;

	nsID guid = new nsID ();
	XPCOM.memmove (guid, riid, nsID.sizeof);

	if (guid.Equals (nsISupports.NS_ISUPPORTS_IID)) {
		XPCOM.memmove (ppvObject, new int /*long*/[] {supports.getAddress ()}, C.PTR_SIZEOF);
		AddRef ();
		return XPCOM.NS_OK;
	}
	if (guid.Equals (nsIWeakReference.NS_IWEAKREFERENCE_IID)) {
		XPCOM.memmove (ppvObject, new int /*long*/[] {weakReference.getAddress ()}, C.PTR_SIZEOF);
		AddRef ();
		return XPCOM.NS_OK;
	}
	if (guid.Equals (nsIWebProgressListener.NS_IWEBPROGRESSLISTENER_IID)) {
		XPCOM.memmove (ppvObject, new int /*long*/[] {webProgressListener.getAddress ()}, C.PTR_SIZEOF);
		AddRef ();
		return XPCOM.NS_OK;
	}
	if (guid.Equals (nsIWebBrowserChrome.NS_IWEBBROWSERCHROME_IID)) {
		XPCOM.memmove (ppvObject, new int /*long*/[] {webBrowserChrome.getAddress ()}, C.PTR_SIZEOF);
		AddRef ();
		return XPCOM.NS_OK;
	}
	if (guid.Equals (nsIWebBrowserChromeFocus.NS_IWEBBROWSERCHROMEFOCUS_IID)) {
		XPCOM.memmove (ppvObject, new int /*long*/[] {webBrowserChromeFocus.getAddress ()}, C.PTR_SIZEOF);
		AddRef ();
		return XPCOM.NS_OK;
	}
	if (guid.Equals (nsIEmbeddingSiteWindow.NS_IEMBEDDINGSITEWINDOW_IID)) {
		XPCOM.memmove (ppvObject, new int /*long*/[] {embeddingSiteWindow.getAddress ()}, C.PTR_SIZEOF);
		AddRef ();
		return XPCOM.NS_OK;
	}
	if (guid.Equals (nsIInterfaceRequestor.NS_IINTERFACEREQUESTOR_IID)) {
		XPCOM.memmove (ppvObject, new int /*long*/[] {interfaceRequestor.getAddress ()}, C.PTR_SIZEOF);
		AddRef ();
		return XPCOM.NS_OK;
	}
	if (guid.Equals (nsISupportsWeakReference.NS_ISUPPORTSWEAKREFERENCE_IID)) {
		XPCOM.memmove (ppvObject, new int /*long*/[] {supportsWeakReference.getAddress ()}, C.PTR_SIZEOF);
		AddRef ();
		return XPCOM.NS_OK;
	}
	if (guid.Equals (nsIContextMenuListener.NS_ICONTEXTMENULISTENER_IID)) {
		XPCOM.memmove (ppvObject, new int /*long*/[] {contextMenuListener.getAddress ()}, C.PTR_SIZEOF);
		AddRef ();
		return XPCOM.NS_OK;
	}
	if (guid.Equals (nsIURIContentListener.NS_IURICONTENTLISTENER_IID)) {
		XPCOM.memmove (ppvObject, new int /*long*/[] {uriContentListener.getAddress ()}, C.PTR_SIZEOF);
		AddRef ();
		return XPCOM.NS_OK;
	}
	if (guid.Equals (nsITooltipListener.NS_ITOOLTIPLISTENER_IID)) {
		XPCOM.memmove (ppvObject, new int /*long*/[] {tooltipListener.getAddress ()}, C.PTR_SIZEOF);
		AddRef ();
		return XPCOM.NS_OK;
	}
	XPCOM.memmove (ppvObject, new int /*long*/[] {0}, C.PTR_SIZEOF);
	return XPCOM.NS_ERROR_NO_INTERFACE;
}

int AddRef () {
	refCount++;
	return refCount;
}

int Release () {
	refCount--;
	if (refCount == 0) disposeCOMInterfaces ();
	return refCount;
}

/* nsIWeakReference */	
	
int QueryReferent (int /*long*/ riid, int /*long*/ ppvObject) {
	return QueryInterface (riid, ppvObject);
}

/* nsIInterfaceRequestor */

int GetInterface (int /*long*/ riid, int /*long*/ ppvObject) {
	if (riid == 0 || ppvObject == 0) return XPCOM.NS_ERROR_NO_INTERFACE;
	nsID guid = new nsID ();
	XPCOM.memmove (guid, riid, nsID.sizeof);
	if (guid.Equals (nsIDOMWindow.NS_IDOMWINDOW_IID)) {
		int /*long*/[] aContentDOMWindow = new int /*long*/[1];
		int rc = webBrowser.GetContentDOMWindow (aContentDOMWindow);
		if (rc != XPCOM.NS_OK) error (rc);
		if (aContentDOMWindow[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
		XPCOM.memmove (ppvObject, aContentDOMWindow, C.PTR_SIZEOF);
		return rc;
	}
	return QueryInterface (riid, ppvObject);
}

int GetWeakReference (int /*long*/ ppvObject) {
	XPCOM.memmove (ppvObject, new int /*long*/[] {weakReference.getAddress ()}, C.PTR_SIZEOF);
	AddRef ();
	return XPCOM.NS_OK;
}

/* nsIWebProgressListener */

int OnStateChange (int /*long*/ aWebProgress, int /*long*/ aRequest, int aStateFlags, int aStatus) {
	if ((aStateFlags & nsIWebProgressListener.STATE_IS_DOCUMENT) == 0) return XPCOM.NS_OK;
	if ((aStateFlags & nsIWebProgressListener.STATE_START) != 0) {
		if (request == 0) request = aRequest;
		/*
		 * Add the page's nsIDOMWindow to the collection of windows that will
		 * have DOM listeners added to them later on in the page loading
		 * process.  These listeners cannot be added yet because the
		 * nsIDOMWindow is not ready to take them at this stage.
		 */
		int /*long*/[] result = new int /*long*/[1];
		nsIWebProgress progress = new nsIWebProgress (aWebProgress);
		int rc = progress.GetDOMWindow (result);
		if (rc != XPCOM.NS_OK) error (rc);
		if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
		unhookedDOMWindows.addElement (new LONG (result[0]));
	} else if ((aStateFlags & nsIWebProgressListener.STATE_REDIRECTING) != 0) {
		if (request == aRequest) request = 0;
	} else if ((aStateFlags & nsIWebProgressListener.STATE_STOP) != 0) {
		/*
		* If this page's nsIDOMWindow handle is still in unhookedDOMWindows then
		* add its DOM listeners now.  It's possible for this to happen since
		* there is no guarantee that a STATE_TRANSFERRING state change will be
		* received for every window in a page, which is when these listeners
		* are typically added.
		*/
		int /*long*/[] result = new int /*long*/[1];
		nsIWebProgress progress = new nsIWebProgress (aWebProgress);
		int rc = progress.GetDOMWindow (result);
		if (rc != XPCOM.NS_OK) error (rc);
		if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
		nsIDOMWindow domWindow = new nsIDOMWindow (result[0]);

		LONG ptrObject = new LONG (result[0]);
		result[0] = 0;
		int index = unhookedDOMWindows.indexOf (ptrObject);
		if (index != -1) {
			rc = webBrowser.GetContentDOMWindow (result);
			if (rc != XPCOM.NS_OK) error (rc);
			if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
			boolean isTop = result[0] == domWindow.getAddress ();
			new nsISupports (result[0]).Release ();
			result[0] = 0;

			rc = domWindow.QueryInterface (nsIDOMEventTarget.NS_IDOMEVENTTARGET_IID, result);
			if (rc != XPCOM.NS_OK) error (rc);
			if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);

			nsIDOMEventTarget target = new nsIDOMEventTarget (result[0]);
			result[0] = 0;
			hookDOMListeners (target, isTop);
			target.Release ();

			/*
			* Remove and unreference the nsIDOMWindow from the collection of windows
			* that are waiting to have DOM listeners hooked on them. 
			*/
			unhookedDOMWindows.remove (ptrObject);
			new nsISupports (ptrObject.value).Release ();
		}

		/*
		 * If htmlBytes is not null then there is html from a previous setText() call
		 * waiting to be set into the about:blank page once it has completed loading. 
		 */
		if (htmlBytes != null) {
			nsIRequest req = new nsIRequest (aRequest);
			int /*long*/ name = XPCOM.nsEmbedCString_new ();
			rc = req.GetName (name);
			if (rc != XPCOM.NS_OK) error (rc);
			int length = XPCOM.nsEmbedCString_Length (name);
			int /*long*/ buffer = XPCOM.nsEmbedCString_get (name);
			byte[] dest = new byte[length];
			XPCOM.memmove (dest, buffer, length);
			String url = new String (dest);
			XPCOM.nsEmbedCString_delete (name);

			if (url.startsWith (ABOUT_BLANK)) {
				/*
				 * Setting mozilla's content with nsIWebBrowserStream invalidates the 
				 * DOM listeners that were hooked on it (about:blank), so remove them and
				 * add new ones after the content has been set.
				 */
				unhookDOMListeners ();

				rc = XPCOM.NS_GetServiceManager (result);
				if (rc != XPCOM.NS_OK) error (rc);
				if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);

				nsIServiceManager serviceManager = new nsIServiceManager (result[0]);
				result[0] = 0;
				rc = serviceManager.GetService (XPCOM.NS_IOSERVICE_CID, nsIIOService.NS_IIOSERVICE_IID, result);
				if (rc != XPCOM.NS_OK) error (rc);
				if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
				serviceManager.Release ();

				nsIIOService ioService = new nsIIOService (result[0]);
				result[0] = 0;
				/*
				* Note.  Mozilla ignores LINK tags used to load CSS stylesheets
				* when the URI protocol for the nsInputStreamChannel
				* is about:blank.  The fix is to specify the file protocol.
				*/
				byte[] aString = MozillaDelegate.wcsToMbcs (null, URI_FROMMEMORY, false);
				int /*long*/ aSpec = XPCOM.nsEmbedCString_new (aString, aString.length);
				rc = ioService.NewURI (aSpec, null, 0, result);
				if (rc != XPCOM.NS_OK) error (rc);
				if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
				XPCOM.nsEmbedCString_delete (aSpec);
				ioService.Release ();

				nsIURI uri = new nsIURI (result[0]);
				result[0] = 0;

				rc = webBrowser.QueryInterface (nsIWebBrowserStream.NS_IWEBBROWSERSTREAM_IID, result);
				if (rc != XPCOM.NS_OK) error (rc);
				if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);

				nsIWebBrowserStream stream = new nsIWebBrowserStream (result[0]);
				result[0] = 0;

				byte[] contentTypeBuffer = MozillaDelegate.wcsToMbcs (null, "text/html", true); // $NON-NLS-1$
				int /*long*/ aContentType = XPCOM.nsEmbedCString_new (contentTypeBuffer, contentTypeBuffer.length);

				rc = stream.OpenStream (uri.getAddress (), aContentType);
				if (rc != XPCOM.NS_OK) error (rc);
				int /*long*/ ptr = C.malloc (htmlBytes.length);
				XPCOM.memmove (ptr, htmlBytes, htmlBytes.length);
				int pageSize = 8192;
				int pageCount = htmlBytes.length / pageSize + 1;
				int /*long*/ current = ptr;
				for (int i = 0; i < pageCount; i++) {
					length = i == pageCount - 1 ? htmlBytes.length % pageSize : pageSize;
					if (length > 0) {
						rc = stream.AppendToStream (current, length);
						if (rc != XPCOM.NS_OK) error (rc);
					}
					current += pageSize;
				}
				rc = stream.CloseStream ();
				if (rc != XPCOM.NS_OK) error (rc);
				C.free (ptr);
				XPCOM.nsEmbedCString_delete (aContentType);
				stream.Release ();
				uri.Release ();
				htmlBytes = null;

				rc = webBrowser.GetContentDOMWindow (result);
				if (rc != XPCOM.NS_OK) error (rc);
				if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
				boolean isTop = result[0] == domWindow.getAddress ();
				new nsISupports (result[0]).Release ();
				result[0] = 0;

				rc = domWindow.QueryInterface (nsIDOMEventTarget.NS_IDOMEVENTTARGET_IID, result);
				if (rc != XPCOM.NS_OK) error (rc);
				if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
				nsIDOMEventTarget target = new nsIDOMEventTarget (result[0]);
				result[0] = 0;
				hookDOMListeners (target, isTop);
				target.Release ();
			}
		}
		domWindow.Release ();

		/*
		* Feature in Mozilla.  When a request is redirected (STATE_REDIRECTING),
		* it never reaches the state STATE_STOP and it is replaced with a new request.
		* The new request is received when it is in the state STATE_STOP.
		* To handle this case,  the variable request is set to 0 when the corresponding
		* request is redirected. The following request received with the state STATE_STOP
		* - the new request resulting from the redirection - is used to send
		* the ProgressListener.completed event.
		*/
		if (request == aRequest || request == 0) {
			request = 0;
			StatusTextEvent event = new StatusTextEvent (browser);
			event.display = browser.getDisplay ();
			event.widget = browser;
			event.text = ""; //$NON-NLS-1$
			for (int i = 0; i < statusTextListeners.length; i++) {
				statusTextListeners[i].changed (event);
			}

			/* re-install registered functions */
			Enumeration elements = functions.elements ();
			while (elements.hasMoreElements ()) {
				BrowserFunction function = (BrowserFunction)elements.nextElement ();
				execute (function.functionString);
			}

			ProgressEvent event2 = new ProgressEvent (browser);
			event2.display = browser.getDisplay ();
			event2.widget = browser;
			for (int i = 0; i < progressListeners.length; i++) {
				progressListeners[i].completed (event2);
			}
		}
	} else if ((aStateFlags & nsIWebProgressListener.STATE_TRANSFERRING) != 0) {
		/*
		* Hook DOM listeners to the page's nsIDOMWindow here because this is
		* the earliest opportunity to do so.    
		*/
		int /*long*/[] result = new int /*long*/[1];
		nsIWebProgress progress = new nsIWebProgress (aWebProgress);
		int rc = progress.GetDOMWindow (result);
		if (rc != XPCOM.NS_OK) error (rc);
		if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
		nsIDOMWindow domWindow = new nsIDOMWindow (result[0]);

		LONG ptrObject = new LONG (result[0]);
		result[0] = 0;
		int index = unhookedDOMWindows.indexOf (ptrObject);
		if (index != -1) {
			rc = webBrowser.GetContentDOMWindow (result);
			if (rc != XPCOM.NS_OK) error (rc);
			if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
			boolean isTop = result[0] == domWindow.getAddress ();
			new nsISupports (result[0]).Release ();
			result[0] = 0;

			rc = domWindow.QueryInterface (nsIDOMEventTarget.NS_IDOMEVENTTARGET_IID, result);
			if (rc != XPCOM.NS_OK) error (rc);
			if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);

			nsIDOMEventTarget target = new nsIDOMEventTarget (result[0]);
			result[0] = 0;
			hookDOMListeners (target, isTop);
			target.Release ();

			/*
			* Remove and unreference the nsIDOMWindow from the collection of windows
			* that are waiting to have DOM listeners hooked on them. 
			*/
			unhookedDOMWindows.remove (ptrObject);
			new nsISupports (ptrObject.value).Release ();
		}
		domWindow.Release ();
	}
	return XPCOM.NS_OK;
}

int OnProgressChange (int /*long*/ aWebProgress, int /*long*/ aRequest, int aCurSelfProgress, int aMaxSelfProgress, int aCurTotalProgress, int aMaxTotalProgress) {
	if (progressListeners.length == 0) return XPCOM.NS_OK;
	ProgressEvent event = new ProgressEvent (browser);
	event.display = browser.getDisplay ();
	event.widget = browser;
	event.current = aCurTotalProgress;
	event.total = aMaxTotalProgress;
	for (int i = 0; i < progressListeners.length; i++) {
		progressListeners[i].changed (event);
	}
	return XPCOM.NS_OK;
}

int OnLocationChange (int /*long*/ aWebProgress, int /*long*/ aRequest, int /*long*/ aLocation) {
	/*
	* Feature in Mozilla.  When a page is loaded via setText before a previous
	* setText page load has completed, the expected OnStateChange STATE_STOP for the
	* original setText never arrives because it gets replaced by the OnStateChange
	* STATE_STOP for the new request.  This results in the request field never being
	* cleared because the original request's OnStateChange STATE_STOP is still expected
	* (but never arrives).  To handle this case, the request field is updated to the new
	* overriding request since its OnStateChange STATE_STOP will be received next.
	*/
	if (request != 0 && request != aRequest) request = aRequest;

	if (locationListeners.length == 0) return XPCOM.NS_OK;

	nsIWebProgress webProgress = new nsIWebProgress (aWebProgress);
	int /*long*/[] aDOMWindow = new int /*long*/[1];
	int rc = webProgress.GetDOMWindow (aDOMWindow);
	if (rc != XPCOM.NS_OK) error (rc);
	if (aDOMWindow[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
	
	nsIDOMWindow domWindow = new nsIDOMWindow (aDOMWindow[0]);
	int /*long*/[] aTop = new int /*long*/[1];
	rc = domWindow.GetTop (aTop);
	if (rc != XPCOM.NS_OK) error (rc);
	if (aTop[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
	domWindow.Release ();
	
	nsIDOMWindow topWindow = new nsIDOMWindow (aTop[0]);
	topWindow.Release ();
	
	nsIURI location = new nsIURI (aLocation);
	int /*long*/ aSpec = XPCOM.nsEmbedCString_new ();
	location.GetSpec (aSpec);
	int length = XPCOM.nsEmbedCString_Length (aSpec);
	int /*long*/ buffer = XPCOM.nsEmbedCString_get (aSpec);
	byte[] dest = new byte[length];
	XPCOM.memmove (dest, buffer, length);
	XPCOM.nsEmbedCString_delete (aSpec);
	String url = new String (dest);

	/*
	 * As of Mozilla 1.8, the first time that a page is displayed, regardless of
	 * whether it's via Browser.setURL() or Browser.setText(), the GRE navigates
	 * to about:blank and fires the corresponding navigation events.  Do not send
	 * this event on to the user since it is not expected.
	 */
	if (!IsPre_1_8 && aRequest == 0 && url.startsWith (ABOUT_BLANK)) return XPCOM.NS_OK;

	LocationEvent event = new LocationEvent (browser);
	event.display = browser.getDisplay ();
	event.widget = browser;
	event.location = url;
	/*
	 * If the URI indicates that the page is being rendered from memory
	 * (via setText()) then set it to about:blank to be consistent with IE.
	 */
	if (event.location.equals (URI_FROMMEMORY)) event.location = ABOUT_BLANK;
	event.top = aTop[0] == aDOMWindow[0];
	for (int i = 0; i < locationListeners.length; i++) {
		locationListeners[i].changed (event);
	}
	return XPCOM.NS_OK;
}

int OnStatusChange (int /*long*/ aWebProgress, int /*long*/ aRequest, int aStatus, int /*long*/ aMessage) {
	if (statusTextListeners.length == 0) return XPCOM.NS_OK;
	StatusTextEvent event = new StatusTextEvent (browser);
	event.display = browser.getDisplay ();
	event.widget = browser;
	int length = XPCOM.strlen_PRUnichar (aMessage);
	char[] dest = new char[length];
	XPCOM.memmove (dest, aMessage, length * 2);
	event.text = new String (dest);
	for (int i = 0; i < statusTextListeners.length; i++) {
		statusTextListeners[i].changed (event);
	}
	return XPCOM.NS_OK;
}		

int OnSecurityChange (int /*long*/ aWebProgress, int /*long*/ aRequest, int state) {
	return XPCOM.NS_OK;
}

/* nsIWebBrowserChrome */

int SetStatus (int statusType, int /*long*/ status) {
	if (statusTextListeners.length == 0) return XPCOM.NS_OK;
	StatusTextEvent event = new StatusTextEvent (browser);
	event.display = browser.getDisplay ();
	event.widget = browser;
	int length = XPCOM.strlen_PRUnichar (status);
	char[] dest = new char[length];
	XPCOM.memmove (dest, status, length * 2);
	String string = new String (dest);
	event.text = string;
	for (int i = 0; i < statusTextListeners.length; i++) {
		statusTextListeners[i].changed (event);
	}
	return XPCOM.NS_OK;
}

int GetWebBrowser (int /*long*/ aWebBrowser) {
	int /*long*/[] ret = new int /*long*/[1];	
	if (webBrowser != null) {
		webBrowser.AddRef ();
		ret[0] = webBrowser.getAddress ();	
	}
	XPCOM.memmove (aWebBrowser, ret, C.PTR_SIZEOF);
	return XPCOM.NS_OK;
}

int SetWebBrowser (int /*long*/ aWebBrowser) {
	if (webBrowser != null) webBrowser.Release ();
	webBrowser = aWebBrowser != 0 ? new nsIWebBrowser (aWebBrowser) : null;  				
	return XPCOM.NS_OK;
}
   
int GetChromeFlags (int /*long*/ aChromeFlags) {
	int[] ret = new int[1];
	ret[0] = chromeFlags;
	XPCOM.memmove (aChromeFlags, ret, 4); /* PRUint32 */
	return XPCOM.NS_OK;
}

int SetChromeFlags (int aChromeFlags) {
	chromeFlags = aChromeFlags;
	return XPCOM.NS_OK;
}

int DestroyBrowserWindow () {
	WindowEvent newEvent = new WindowEvent (browser);
	newEvent.display = browser.getDisplay ();
	newEvent.widget = browser;
	for (int i = 0; i < closeWindowListeners.length; i++) {
		closeWindowListeners[i].close (newEvent);
	}
	/*
	* Note on Mozilla.  The DestroyBrowserWindow notification cannot be cancelled.
	* The browser widget cannot be used after this notification has been received.
	* The application is advised to close the window hosting the browser widget.
	* The browser widget must be disposed in all cases.
	*/
	browser.dispose ();
	return XPCOM.NS_OK;
}
   	
int SizeBrowserTo (int aCX, int aCY) {
	size = new Point (aCX, aCY);
	boolean isChrome = (chromeFlags & nsIWebBrowserChrome.CHROME_OPENAS_CHROME) != 0;
	if (isChrome) {
		Shell shell = browser.getShell ();
		shell.setSize (shell.computeSize (size.x, size.y));
	}
	return XPCOM.NS_OK;
}

int ShowAsModal () {
	int /*long*/[] result = new int /*long*/[1];
	int rc = XPCOM.NS_GetServiceManager (result);
	if (rc != XPCOM.NS_OK) error (rc);
	if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);

	nsIServiceManager serviceManager = new nsIServiceManager (result[0]);
	result[0] = 0;
	byte[] aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_CONTEXTSTACK_CONTRACTID, true);
	rc = serviceManager.GetServiceByContractID (aContractID, nsIJSContextStack.NS_IJSCONTEXTSTACK_IID, result);
	if (rc != XPCOM.NS_OK) error (rc);
	if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
	serviceManager.Release ();

	nsIJSContextStack stack = new nsIJSContextStack (result[0]);
	result[0] = 0;
	rc = stack.Push (0);
	if (rc != XPCOM.NS_OK) error (rc);

	Shell shell = browser.getShell ();
	Display display = browser.getDisplay ();
	while (!shell.isDisposed ()) {
		if (!display.readAndDispatch ()) display.sleep ();
	}

	rc = stack.Pop (result);
	if (rc != XPCOM.NS_OK) error (rc);
	stack.Release ();
	return XPCOM.NS_OK;
}

int IsWindowModal (int /*long*/ retval) {
	int result = (chromeFlags & nsIWebBrowserChrome.CHROME_MODAL) != 0 ? 1 : 0;
	XPCOM.memmove (retval, new int[] {result}, 4); /* PRBool */
	return XPCOM.NS_OK;
}
   
int ExitModalEventLoop (int aStatus) {
	return XPCOM.NS_OK;
}

/* nsIEmbeddingSiteWindow */ 

int SetDimensions (int flags, int x, int y, int cx, int cy) {
	if ((flags & nsIEmbeddingSiteWindow.DIM_FLAGS_POSITION) != 0) {
		location = new Point (x, y);
		browser.getShell ().setLocation (x, y);
	}
	if ((flags & nsIEmbeddingSiteWindow.DIM_FLAGS_SIZE_INNER) != 0) {
		browser.setSize (cx, cy);
	}
	if ((flags & nsIEmbeddingSiteWindow.DIM_FLAGS_SIZE_OUTER) != 0) {
		browser.getShell ().setSize (cx, cy);
	}
	return XPCOM.NS_OK;
}

int GetDimensions (int flags, int /*long*/ x, int /*long*/ y, int /*long*/ cx, int /*long*/ cy) {
	if ((flags & nsIEmbeddingSiteWindow.DIM_FLAGS_POSITION) != 0) {
		Point location = browser.getShell ().getLocation ();
		if (x != 0) C.memmove (x, new int[] {location.x}, 4); /* PRInt32 */
		if (y != 0) C.memmove (y, new int[] {location.y}, 4); /* PRInt32 */
	}
	if ((flags & nsIEmbeddingSiteWindow.DIM_FLAGS_SIZE_INNER) != 0) {
		Point size = browser.getSize ();
		if (cx != 0) C.memmove (cx, new int[] {size.x}, 4); /* PRInt32 */
		if (cy != 0) C.memmove (cy, new int[] {size.y}, 4); /* PRInt32 */
	}
	if ((flags & nsIEmbeddingSiteWindow.DIM_FLAGS_SIZE_OUTER) != 0) {
		Point size = browser.getShell().getSize ();
		if (cx != 0) C.memmove (cx, new int[] {size.x}, 4); /* PRInt32 */
		if (cy != 0) C.memmove (cy, new int[] {size.y}, 4); /* PRInt32 */
	}
	return XPCOM.NS_OK;
}

int SetFocus () {
	int /*long*/[] result = new int /*long*/[1];
	int rc = webBrowser.QueryInterface (nsIBaseWindow.NS_IBASEWINDOW_IID, result);
	if (rc != XPCOM.NS_OK) error (rc);
	if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
	
	nsIBaseWindow baseWindow = new nsIBaseWindow (result[0]);
	rc = baseWindow.SetFocus ();
	if (rc != XPCOM.NS_OK) error (rc);
	baseWindow.Release ();

	/*
	* Note. Mozilla notifies here that one of the children took
	* focus. This could or should be used to fire an SWT.FOCUS_IN
	* event on Browser focus listeners.
	*/
	return XPCOM.NS_OK;     	
}	

int GetVisibility (int /*long*/ aVisibility) {
	boolean visible = browser.isVisible () && !browser.getShell ().getMinimized ();
	XPCOM.memmove (aVisibility, new int[] {visible ? 1 : 0}, 4); /* PRBool */
	return XPCOM.NS_OK;
}

int SetVisibility (int aVisibility) {
	if (isChild) {
		WindowEvent event = new WindowEvent (browser);
		event.display = browser.getDisplay ();
		event.widget = browser;
		if (aVisibility != 0) {
			/*
			* Bug in Mozilla.  When the JavaScript window.open is executed, Mozilla
			* fires multiple SetVisibility 1 notifications.  The workaround is
			* to ignore subsequent notifications. 
			*/
			if (!visible) {
				visible = true;
				event.location = location;
				event.size = size;
				event.addressBar = (chromeFlags & nsIWebBrowserChrome.CHROME_LOCATIONBAR) != 0;
				event.menuBar = (chromeFlags & nsIWebBrowserChrome.CHROME_MENUBAR) != 0;
				event.statusBar = (chromeFlags & nsIWebBrowserChrome.CHROME_STATUSBAR) != 0;
				event.toolBar = (chromeFlags & nsIWebBrowserChrome.CHROME_TOOLBAR) != 0;
				for (int i = 0; i < visibilityWindowListeners.length; i++) {
					visibilityWindowListeners[i].show (event);
				}
				location = null;
				size = null;
			}
		} else {
			visible = false;
			for (int i = 0; i < visibilityWindowListeners.length; i++) {
				visibilityWindowListeners[i].hide (event);
			}
		}
	} else {
		visible = aVisibility != 0;
	}
	return XPCOM.NS_OK;     	
}

int GetTitle (int /*long*/ aTitle) {
	return XPCOM.NS_OK;     	
}
 
int SetTitle (int /*long*/ aTitle) {
	if (titleListeners.length == 0) return XPCOM.NS_OK;
	TitleEvent event = new TitleEvent (browser);
	event.display = browser.getDisplay ();
	event.widget = browser;
	/*
	* To be consistent with other platforms the title event should
	* contain the page's url if the page does not contain a <title>
	* tag. 
	*/
	int length = XPCOM.strlen_PRUnichar (aTitle);
	if (length > 0) {
		char[] dest = new char[length];
		XPCOM.memmove (dest, aTitle, length * 2);
		event.title = new String (dest);
	} else {
		event.title = getUrl ();
	}
	for (int i = 0; i < titleListeners.length; i++) {
		titleListeners[i].changed (event);
	}
	return XPCOM.NS_OK;     	
}

int GetSiteWindow (int /*long*/ aSiteWindow) {
	/*
	* Note.  The handle is expected to be an HWND on Windows and
	* a GtkWidget* on GTK.  This callback is invoked on Windows
	* when the javascript window.print is invoked and the print
	* dialog comes up. If no handle is returned, the print dialog
	* does not come up on this platform.  
	*/
	XPCOM.memmove (aSiteWindow, new int /*long*/[] {embedHandle}, C.PTR_SIZEOF);
	return XPCOM.NS_OK;     	
}  
 
/* nsIWebBrowserChromeFocus */

int FocusNextElement () {
	/*
	* Bug in Mozilla embedding API.  Mozilla takes back the focus after sending
	* this event.  This prevents tabbing out of Mozilla. This behaviour can be reproduced
	* with the Mozilla application TestGtkEmbed.  The workaround is to
	* send the traversal notification after this callback returns.
	*/
	browser.getDisplay ().asyncExec (new Runnable () {
		public void run () {
			if (browser.isDisposed ()) return;
			browser.traverse (SWT.TRAVERSE_TAB_NEXT);
		}
	});
	return XPCOM.NS_OK;  
}

int FocusPrevElement () {
	/*
	* Bug in Mozilla embedding API.  Mozilla takes back the focus after sending
	* this event.  This prevents tabbing out of Mozilla. This behaviour can be reproduced
	* with the Mozilla application TestGtkEmbed.  The workaround is to
	* send the traversal notification after this callback returns.
	*/
	browser.getDisplay ().asyncExec (new Runnable () {
		public void run () {
			if (browser.isDisposed ()) return;
			browser.traverse (SWT.TRAVERSE_TAB_PREVIOUS);
		}
	});
	return XPCOM.NS_OK;     	
}

/* nsIContextMenuListener */

int OnShowContextMenu (int aContextFlags, int /*long*/ aEvent, int /*long*/ aNode) {
	nsIDOMEvent domEvent = new nsIDOMEvent (aEvent);
	int /*long*/[] result = new int /*long*/[1];
	int rc = domEvent.QueryInterface (nsIDOMMouseEvent.NS_IDOMMOUSEEVENT_IID, result);
	if (rc != XPCOM.NS_OK) error (rc);
	if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);

	nsIDOMMouseEvent domMouseEvent = new nsIDOMMouseEvent (result[0]);
	int[] aScreenX = new int[1], aScreenY = new int[1];
	rc = domMouseEvent.GetScreenX (aScreenX);
	if (rc != XPCOM.NS_OK) error (rc);
	rc = domMouseEvent.GetScreenY (aScreenY);
	if (rc != XPCOM.NS_OK) error (rc);
	domMouseEvent.Release ();
	
	Event event = new Event ();
	event.x = aScreenX[0];
	event.y = aScreenY[0];
	browser.notifyListeners (SWT.MenuDetect, event);
	if (!event.doit || browser.isDisposed ()) return XPCOM.NS_OK;
	Menu menu = browser.getMenu ();
	if (menu != null && !menu.isDisposed ()) {
		if (aScreenX[0] != event.x || aScreenY[0] != event.y) {
			menu.setLocation (event.x, event.y);
		}
		menu.setVisible (true);
	}
	return XPCOM.NS_OK;     	
}

/* nsIURIContentListener */

int OnStartURIOpen (int /*long*/ aURI, int /*long*/ retval) {
	authCount = 0;

	nsIURI location = new nsIURI (aURI);
	int /*long*/ aSpec = XPCOM.nsEmbedCString_new ();
	location.GetSpec (aSpec);
	int length = XPCOM.nsEmbedCString_Length (aSpec);
	int /*long*/ buffer = XPCOM.nsEmbedCString_get (aSpec);
	buffer = XPCOM.nsEmbedCString_get (aSpec);
	byte[] dest = new byte[length];
	XPCOM.memmove (dest, buffer, length);
	XPCOM.nsEmbedCString_delete (aSpec);
	String value = new String (dest);
	boolean doit = true;
	if (request == 0) {
		/* 
		 * listeners should not be notified of internal transitions like "javascript:..."
		 * because this is an implementation side-effect, not a true navigate
		 */
		if (!value.startsWith (PREFIX_JAVASCRIPT)) {
			if (locationListeners.length > 0) {
				LocationEvent event = new LocationEvent (browser);
				event.display = browser.getDisplay();
				event.widget = browser;
				event.location = value;
				/*
				 * If the URI indicates that the page is being rendered from memory
				 * (via setText()) then set it to about:blank to be consistent with IE.
				 */
				if (event.location.equals (URI_FROMMEMORY)) event.location = ABOUT_BLANK;
				event.doit = doit;
				for (int i = 0; i < locationListeners.length; i++) {
					locationListeners[i].changing (event);
				}
				doit = event.doit && !browser.isDisposed();
			}

			if (doit) {
				if (jsEnabledChanged) {
					jsEnabledChanged = false;
	
					int /*long*/[] result = new int /*long*/[1];
					int rc = webBrowser.QueryInterface (nsIWebBrowserSetup.NS_IWEBBROWSERSETUP_IID, result);
					if (rc != XPCOM.NS_OK) error (rc);
					if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
	
					nsIWebBrowserSetup setup = new nsIWebBrowserSetup (result[0]);
					result[0] = 0;
					rc = setup.SetProperty (nsIWebBrowserSetup.SETUP_ALLOW_JAVASCRIPT, jsEnabled ? 1 : 0);
					if (rc != XPCOM.NS_OK) error (rc);
					setup.Release ();
				}
				lastNavigateURL = value;
			}
		}
	}
	XPCOM.memmove (retval, new int[] {doit ? 0 : 1}, 4); /* PRBool */
	return XPCOM.NS_OK;
}

int DoContent (int /*long*/ aContentType, int aIsContentPreferred, int /*long*/ aRequest, int /*long*/ aContentHandler, int /*long*/ retval) {
	return XPCOM.NS_ERROR_NOT_IMPLEMENTED;
}

int IsPreferred (int /*long*/ aContentType, int /*long*/ aDesiredContentType, int /*long*/ retval) {
	boolean preferred = false;
	int size = XPCOM.strlen (aContentType);
	if (size > 0) {
		byte[] typeBytes = new byte[size + 1];
		XPCOM.memmove (typeBytes, aContentType, size);
		String contentType = new String (typeBytes, 0, size);

		/* do not attempt to handle known problematic content types */
		if (!contentType.equals (XPCOM.CONTENT_MAYBETEXT) && !contentType.equals (XPCOM.CONTENT_MULTIPART)) {
			/* determine whether browser can handle the content type */
			int /*long*/[] result = new int /*long*/[1];
			int rc = XPCOM.NS_GetServiceManager (result);
			if (rc != XPCOM.NS_OK) error (rc);
			if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
			nsIServiceManager serviceManager = new nsIServiceManager (result[0]);
			result[0] = 0;

			/* First try to use the nsIWebNavigationInfo if it's available (>= mozilla 1.8) */
			byte[] aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_WEBNAVIGATIONINFO_CONTRACTID, true);
			rc = serviceManager.GetServiceByContractID (aContractID, nsIWebNavigationInfo.NS_IWEBNAVIGATIONINFO_IID, result);
			if (rc == XPCOM.NS_OK) {
				byte[] bytes = MozillaDelegate.wcsToMbcs (null, contentType, true);
				int /*long*/ typePtr = XPCOM.nsEmbedCString_new (bytes, bytes.length);
				nsIWebNavigationInfo info = new nsIWebNavigationInfo (result[0]);
				result[0] = 0;
				int[] isSupportedResult = new int[1]; /* PRUint32 */
				rc = info.IsTypeSupported (typePtr, 0, isSupportedResult);
				if (rc != XPCOM.NS_OK) error (rc);
				info.Release ();
				XPCOM.nsEmbedCString_delete (typePtr);
				preferred = isSupportedResult[0] != 0;
			} else {
				/* nsIWebNavigationInfo is not available, so do the type lookup */
				result[0] = 0;
				rc = serviceManager.GetService (XPCOM.NS_CATEGORYMANAGER_CID, nsICategoryManager.NS_ICATEGORYMANAGER_IID, result);
				if (rc != XPCOM.NS_OK) error (rc);
				if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);

				nsICategoryManager categoryManager = new nsICategoryManager (result[0]);
				result[0] = 0;
				byte[] categoryBytes = MozillaDelegate.wcsToMbcs (null, "Gecko-Content-Viewers", true);	//$NON-NLS-1$
				rc = categoryManager.GetCategoryEntry (categoryBytes, typeBytes, result);
				categoryManager.Release ();
				/* if no viewer for the content type is registered then rc == XPCOM.NS_ERROR_NOT_AVAILABLE */
				preferred = rc == XPCOM.NS_OK;
			}
			serviceManager.Release ();
		}
	}

	XPCOM.memmove(retval, new int[] {preferred ? 1 : 0}, 4); /* PRBool */
	if (preferred) {
		XPCOM.memmove (aDesiredContentType, new int /*long*/[] {0}, C.PTR_SIZEOF);
	}
	return XPCOM.NS_OK;
}

int CanHandleContent (int /*long*/ aContentType, int aIsContentPreferred, int /*long*/ aDesiredContentType, int /*long*/ retval) {
	return XPCOM.NS_ERROR_NOT_IMPLEMENTED;
}

int GetLoadCookie (int /*long*/ aLoadCookie) {
	return XPCOM.NS_ERROR_NOT_IMPLEMENTED;
}

int SetLoadCookie (int /*long*/ aLoadCookie) {
	return XPCOM.NS_ERROR_NOT_IMPLEMENTED;
}

int GetParentContentListener (int /*long*/ aParentContentListener) {
	return XPCOM.NS_ERROR_NOT_IMPLEMENTED;
}
	
int SetParentContentListener (int /*long*/ aParentContentListener) {
	return XPCOM.NS_ERROR_NOT_IMPLEMENTED;
}

/* nsITooltipListener */

int OnShowTooltip (int aXCoords, int aYCoords, int /*long*/ aTipText) {
	int length = XPCOM.strlen_PRUnichar (aTipText);
	char[] dest = new char[length];
	XPCOM.memmove (dest, aTipText, length * 2);
	String text = new String (dest);
	if (tip != null && !tip.isDisposed ()) tip.dispose ();
	Display display = browser.getDisplay ();
	Shell parent = browser.getShell ();
	tip = new Shell (parent, SWT.ON_TOP);
	tip.setLayout (new FillLayout());
	Label label = new Label (tip, SWT.CENTER);
	label.setForeground (display.getSystemColor (SWT.COLOR_INFO_FOREGROUND));
	label.setBackground (display.getSystemColor (SWT.COLOR_INFO_BACKGROUND));
	label.setText (text);
	/*
	* Bug in Mozilla embedded API.  Tooltip coordinates are wrong for 
	* elements inside an inline frame (IFrame tag).  The workaround is 
	* to position the tooltip based on the mouse cursor location.
	*/
	Point point = display.getCursorLocation ();
	/* Assuming cursor is 21x21 because this is the size of
	 * the arrow cursor on Windows
	 */ 
	point.y += 21;
	tip.setLocation (point);
	tip.pack ();
	tip.setVisible (true);
	return XPCOM.NS_OK;
}

int OnHideTooltip () {
	if (tip != null && !tip.isDisposed ()) tip.dispose ();
	tip = null;
	return XPCOM.NS_OK;
}

/* nsIDOMEventListener */

int HandleEvent (int /*long*/ event) {
	nsIDOMEvent domEvent = new nsIDOMEvent (event);

	int /*long*/ type = XPCOM.nsEmbedString_new ();
	int rc = domEvent.GetType (type);
	if (rc != XPCOM.NS_OK) error (rc);
	int length = XPCOM.nsEmbedString_Length (type);
	int /*long*/ buffer = XPCOM.nsEmbedString_get (type);
	char[] chars = new char[length];
	XPCOM.memmove (chars, buffer, length * 2);
	String typeString = new String (chars);
	XPCOM.nsEmbedString_delete (type);

	if (XPCOM.DOMEVENT_UNLOAD.equals (typeString)) {
		int /*long*/[] result = new int /*long*/[1];
		rc = domEvent.GetCurrentTarget (result);
		if (rc != XPCOM.NS_OK) error (rc);
		if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);

		nsIDOMEventTarget target = new nsIDOMEventTarget (result[0]);
		unhookDOMListeners (target);
		target.Release ();
		return XPCOM.NS_OK;
	}

	if (XPCOM.DOMEVENT_FOCUS.equals (typeString)) {
		delegate.handleFocus ();
		return XPCOM.NS_OK;
	}

	if (XPCOM.DOMEVENT_KEYDOWN.equals (typeString)) {
		int /*long*/[] result = new int /*long*/[1];
		rc = domEvent.QueryInterface (nsIDOMKeyEvent.NS_IDOMKEYEVENT_IID, result);
		if (rc != XPCOM.NS_OK) error (rc);
		if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
		nsIDOMKeyEvent domKeyEvent = new nsIDOMKeyEvent (result[0]);
		result[0] = 0;

		int[] aKeyCode = new int[1]; /* PRUint32 */
		rc = domKeyEvent.GetKeyCode (aKeyCode);
		if (rc != XPCOM.NS_OK) error (rc);
		int keyCode = translateKey (aKeyCode[0]);

		/*
		* if keyCode == lastKeyCode then either a repeating key like Shift
		* is being held or a key for which key events are not sent has been
		* pressed.  In both of these cases a KeyDown should not be sent.
		*/
		if (keyCode != lastKeyCode) {
			lastKeyCode = keyCode;
			switch (keyCode) {
				case SWT.SHIFT:
				case SWT.CONTROL:
				case SWT.ALT:
				case SWT.CAPS_LOCK:
				case SWT.NUM_LOCK:
				case SWT.SCROLL_LOCK:
				case SWT.COMMAND: {
					/* keypress events will not be received for these keys, so send KeyDowns for them now */
					int[] aAltKey = new int[1], aCtrlKey = new int[1], aShiftKey = new int[1], aMetaKey = new int[1]; /* PRBool */
					rc = domKeyEvent.GetAltKey (aAltKey);
					if (rc != XPCOM.NS_OK) error (rc);
					rc = domKeyEvent.GetCtrlKey (aCtrlKey);
					if (rc != XPCOM.NS_OK) error (rc);
					rc = domKeyEvent.GetShiftKey (aShiftKey);
					if (rc != XPCOM.NS_OK) error (rc);
					rc = domKeyEvent.GetMetaKey (aMetaKey);
					if (rc != XPCOM.NS_OK) error (rc);

					Event keyEvent = new Event ();
					keyEvent.widget = browser;
					keyEvent.type = SWT.KeyDown;
					keyEvent.keyCode = keyCode;
					keyEvent.stateMask = (aAltKey[0] != 0 ? SWT.ALT : 0) | (aCtrlKey[0] != 0 ? SWT.CTRL : 0) | (aShiftKey[0] != 0 ? SWT.SHIFT : 0) | (aMetaKey[0] != 0 ? SWT.COMMAND : 0);
					keyEvent.stateMask &= ~keyCode;		/* remove current keydown if it's a state key */
					browser.notifyListeners (keyEvent.type, keyEvent);
					if (!keyEvent.doit || browser.isDisposed ()) {
						domEvent.PreventDefault ();
					}
					break;
				}
				default: {
					/* 
					* If the keydown has Meta (but not Meta+Ctrl) as a modifier then send a KeyDown event for it here
					* because a corresponding keypress event will not be received for it from the DOM.  If the keydown
					* does not have Meta as a modifier, or has Meta+Ctrl as a modifier, then then do nothing here
					* because its KeyDown event will be sent from the keypress listener.
					*/
					int[] aMetaKey = new int[1]; /* PRBool */
					rc = domKeyEvent.GetMetaKey (aMetaKey);
					if (rc != XPCOM.NS_OK) error (rc);
					if (aMetaKey[0] != 0) {
						int[] aCtrlKey = new int[1]; /* PRBool */
						rc = domKeyEvent.GetCtrlKey (aCtrlKey);
						if (rc != XPCOM.NS_OK) error (rc);
						if (aCtrlKey[0] == 0) {
							int[] aAltKey = new int[1], aShiftKey = new int[1]; /* PRBool */
							rc = domKeyEvent.GetAltKey (aAltKey);
							if (rc != XPCOM.NS_OK) error (rc);
							rc = domKeyEvent.GetShiftKey (aShiftKey);
							if (rc != XPCOM.NS_OK) error (rc);

							Event keyEvent = new Event ();
							keyEvent.widget = browser;
							keyEvent.type = SWT.KeyDown;
							keyEvent.keyCode = lastKeyCode;
							keyEvent.stateMask = (aAltKey[0] != 0 ? SWT.ALT : 0) | (aCtrlKey[0] != 0? SWT.CTRL : 0) | (aShiftKey[0] != 0? SWT.SHIFT : 0) | (aMetaKey[0] != 0? SWT.COMMAND : 0);
							browser.notifyListeners (keyEvent.type, keyEvent);
							if (!keyEvent.doit || browser.isDisposed ()) {
								domEvent.PreventDefault ();
							}
						}
					}
				}
			}
		}

		domKeyEvent.Release ();
		return XPCOM.NS_OK;
	}

	if (XPCOM.DOMEVENT_KEYPRESS.equals (typeString)) {
		/*
		* if keydown could not determine a keycode for this key then it's a
		* key for which key events are not sent (eg.- the Windows key)
		*/
		if (lastKeyCode == 0) return XPCOM.NS_OK;

		/*
		* On linux only, unexpected keypress events are received for some
		* modifier keys.  The workaround is to ignore these events since
		* KeyDown events are sent for these keys in the keydown listener.  
		*/
		switch (lastKeyCode) {
			case SWT.CAPS_LOCK:
			case SWT.NUM_LOCK:
			case SWT.SCROLL_LOCK: return XPCOM.NS_OK;
		}

		int /*long*/[] result = new int /*long*/[1];
		rc = domEvent.QueryInterface (nsIDOMKeyEvent.NS_IDOMKEYEVENT_IID, result);
		if (rc != XPCOM.NS_OK) error (rc);
		if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
		nsIDOMKeyEvent domKeyEvent = new nsIDOMKeyEvent (result[0]);
		result[0] = 0;

		int[] aAltKey = new int[1], aCtrlKey = new int[1], aShiftKey = new int[1], aMetaKey = new int[1]; /* PRBool */
		rc = domKeyEvent.GetAltKey (aAltKey);
		if (rc != XPCOM.NS_OK) error (rc);
		rc = domKeyEvent.GetCtrlKey (aCtrlKey);
		if (rc != XPCOM.NS_OK) error (rc);
		rc = domKeyEvent.GetShiftKey (aShiftKey);
		if (rc != XPCOM.NS_OK) error (rc);
		rc = domKeyEvent.GetMetaKey (aMetaKey);
		if (rc != XPCOM.NS_OK) error (rc);
		domKeyEvent.Release ();

		int[] aCharCode = new int[1]; /* PRUint32 */
		rc = domKeyEvent.GetCharCode (aCharCode);
		if (rc != XPCOM.NS_OK) error (rc);
		lastCharCode = aCharCode[0];
		if (lastCharCode == 0) {
			switch (lastKeyCode) {
				case SWT.TAB: lastCharCode = SWT.TAB; break;
				case SWT.CR: lastCharCode = SWT.CR; break;
				case SWT.BS: lastCharCode = SWT.BS; break;
				case SWT.ESC: lastCharCode = SWT.ESC; break;
				case SWT.DEL: lastCharCode = SWT.DEL; break;
			}
		}
		if (aCtrlKey[0] != 0 && (0 <= lastCharCode && lastCharCode <= 0x7F)) {
			if ('a'  <= lastCharCode && lastCharCode <= 'z') lastCharCode -= 'a' - 'A';
			if (64 <= lastCharCode && lastCharCode <= 95) lastCharCode -= 64;
		}

		Event keyEvent = new Event ();
		keyEvent.widget = browser;
		keyEvent.type = SWT.KeyDown;
		keyEvent.keyCode = lastKeyCode;
		keyEvent.character = (char)lastCharCode;
		keyEvent.stateMask = (aAltKey[0] != 0 ? SWT.ALT : 0) | (aCtrlKey[0] != 0 ? SWT.CTRL : 0) | (aShiftKey[0] != 0 ? SWT.SHIFT : 0) | (aMetaKey[0] != 0 ? SWT.COMMAND : 0);
		browser.notifyListeners (keyEvent.type, keyEvent);
		if (!keyEvent.doit || browser.isDisposed ()) {
			domEvent.PreventDefault ();
		}
		return XPCOM.NS_OK;
	}

	if (XPCOM.DOMEVENT_KEYUP.equals (typeString)) {
		int /*long*/[] result = new int /*long*/[1];
		rc = domEvent.QueryInterface (nsIDOMKeyEvent.NS_IDOMKEYEVENT_IID, result);
		if (rc != XPCOM.NS_OK) error (rc);
		if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
		nsIDOMKeyEvent domKeyEvent = new nsIDOMKeyEvent (result[0]);
		result[0] = 0;

		int[] aKeyCode = new int[1]; /* PRUint32 */
		rc = domKeyEvent.GetKeyCode (aKeyCode);
		if (rc != XPCOM.NS_OK) error (rc);
		int keyCode = translateKey (aKeyCode[0]);
		if (keyCode == 0) {
			/* indicates a key for which key events are not sent */
			domKeyEvent.Release ();
			return XPCOM.NS_OK;
		}
		if (keyCode != lastKeyCode) {
			/* keyup does not correspond to the last keydown */
			lastKeyCode = keyCode;
			lastCharCode = 0;
		}

		int[] aAltKey = new int[1], aCtrlKey = new int[1], aShiftKey = new int[1], aMetaKey = new int[1]; /* PRBool */
		rc = domKeyEvent.GetAltKey (aAltKey);
		if (rc != XPCOM.NS_OK) error (rc);
		rc = domKeyEvent.GetCtrlKey (aCtrlKey);
		if (rc != XPCOM.NS_OK) error (rc);
		rc = domKeyEvent.GetShiftKey (aShiftKey);
		if (rc != XPCOM.NS_OK) error (rc);
		rc = domKeyEvent.GetMetaKey (aMetaKey);
		if (rc != XPCOM.NS_OK) error (rc);
		domKeyEvent.Release ();

		Event keyEvent = new Event ();
		keyEvent.widget = browser;
		keyEvent.type = SWT.KeyUp;
		keyEvent.keyCode = lastKeyCode;
		keyEvent.character = (char)lastCharCode;
		keyEvent.stateMask = (aAltKey[0] != 0 ? SWT.ALT : 0) | (aCtrlKey[0] != 0 ? SWT.CTRL : 0) | (aShiftKey[0] != 0 ? SWT.SHIFT : 0) | (aMetaKey[0] != 0 ? SWT.COMMAND : 0);
		switch (lastKeyCode) {
			case SWT.SHIFT:
			case SWT.CONTROL:
			case SWT.ALT:
			case SWT.COMMAND: {
				keyEvent.stateMask |= lastKeyCode;
			}
		}
		browser.notifyListeners (keyEvent.type, keyEvent);
		if (!keyEvent.doit || browser.isDisposed ()) {
			domEvent.PreventDefault ();
		}
		lastKeyCode = lastCharCode = 0;
		return XPCOM.NS_OK;
	}

	/* mouse event */

	int /*long*/[] result = new int /*long*/[1];
	rc = domEvent.QueryInterface (nsIDOMMouseEvent.NS_IDOMMOUSEEVENT_IID, result);
	if (rc != XPCOM.NS_OK) error (rc);
	if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
	nsIDOMMouseEvent domMouseEvent = new nsIDOMMouseEvent (result[0]);
	result[0] = 0;

	/*
	 * MouseOver and MouseOut events are fired any time the mouse enters or exits
	 * any element within the Browser.  To ensure that SWT events are only
	 * fired for mouse movements into or out of the Browser, do not fire an
	 * event if the element being exited (on MouseOver) or entered (on MouseExit)
	 * is within the Browser.
	 */
	if (XPCOM.DOMEVENT_MOUSEOVER.equals (typeString) || XPCOM.DOMEVENT_MOUSEOUT.equals (typeString)) {
		rc = domMouseEvent.GetRelatedTarget (result);
		if (rc != XPCOM.NS_OK) error (rc);
		if (result[0] != 0) {
			domMouseEvent.Release ();
			return XPCOM.NS_OK;
		}
	}

	int[] aClientX = new int[1], aClientY = new int[1], aDetail = new int[1]; /* PRInt32 */
	rc = domMouseEvent.GetClientX (aClientX);
	if (rc != XPCOM.NS_OK) error (rc);
	rc = domMouseEvent.GetClientY (aClientY);
	if (rc != XPCOM.NS_OK) error (rc);
	rc = domMouseEvent.GetDetail (aDetail);
	if (rc != XPCOM.NS_OK) error (rc);
	short[] aButton = new short[1]; /* PRUint16 */
	rc = domMouseEvent.GetButton (aButton);
	if (rc != XPCOM.NS_OK) error (rc);
	int[] aAltKey = new int[1], aCtrlKey = new int[1], aShiftKey = new int[1], aMetaKey = new int[1]; /* PRBool */
	rc = domMouseEvent.GetAltKey (aAltKey);
	if (rc != XPCOM.NS_OK) error (rc);
	rc = domMouseEvent.GetCtrlKey (aCtrlKey);
	if (rc != XPCOM.NS_OK) error (rc);
	rc = domMouseEvent.GetShiftKey (aShiftKey);
	if (rc != XPCOM.NS_OK) error (rc);
	rc = domMouseEvent.GetMetaKey (aMetaKey);
	if (rc != XPCOM.NS_OK) error (rc);
	domMouseEvent.Release ();

	Event mouseEvent = new Event ();
	mouseEvent.widget = browser;
	mouseEvent.x = aClientX[0]; mouseEvent.y = aClientY[0];
	mouseEvent.stateMask = (aAltKey[0] != 0 ? SWT.ALT : 0) | (aCtrlKey[0] != 0 ? SWT.CTRL : 0) | (aShiftKey[0] != 0 ? SWT.SHIFT : 0) | (aMetaKey[0] != 0 ? SWT.COMMAND : 0);

	if (XPCOM.DOMEVENT_MOUSEDOWN.equals (typeString)) {
		delegate.handleMouseDown ();
		mouseEvent.type = SWT.MouseDown;
		mouseEvent.button = aButton[0] + 1;
		mouseEvent.count = aDetail[0];
	} else if (XPCOM.DOMEVENT_MOUSEUP.equals (typeString)) {
		/*
		 * Bug on OSX.  For some reason multiple mouseup events come from the DOM
		 * when button 3 is released on OSX.  The first of these events has a count
		 * detail and the others do not.  The workaround is to not fire received
		 * button 3 mouseup events that do not have a count since mouse events
		 * without a click count are not valid.
		 */
		int button = aButton[0] + 1;
		int count = aDetail[0];
		if (count == 0 && button == 3) return XPCOM.NS_OK;
		mouseEvent.type = SWT.MouseUp;
		mouseEvent.button = button;
		mouseEvent.count = count;
	} else if (XPCOM.DOMEVENT_MOUSEMOVE.equals (typeString)) {
		mouseEvent.type = SWT.MouseMove;
	} else if (XPCOM.DOMEVENT_MOUSEWHEEL.equals (typeString)) {
		mouseEvent.type = SWT.MouseWheel;
		mouseEvent.count = -aDetail[0];
	} else if (XPCOM.DOMEVENT_MOUSEOVER.equals (typeString)) {
		mouseEvent.type = SWT.MouseEnter;
	} else if (XPCOM.DOMEVENT_MOUSEOUT.equals (typeString)) {
		mouseEvent.type = SWT.MouseExit;
	} else if (XPCOM.DOMEVENT_MOUSEDRAG.equals (typeString)) {
		mouseEvent.type = SWT.DragDetect;
		mouseEvent.button = aButton[0] + 1;
		switch (mouseEvent.button) {
			case 1: mouseEvent.stateMask |= SWT.BUTTON1; break;
			case 2: mouseEvent.stateMask |= SWT.BUTTON2; break;
			case 3: mouseEvent.stateMask |= SWT.BUTTON3; break;
			case 4: mouseEvent.stateMask |= SWT.BUTTON4; break;
			case 5: mouseEvent.stateMask |= SWT.BUTTON5; break;
		}
	}

	browser.notifyListeners (mouseEvent.type, mouseEvent);
	if (browser.isDisposed ()) return XPCOM.NS_OK;
	if (aDetail[0] == 2 && XPCOM.DOMEVENT_MOUSEDOWN.equals (typeString)) {
		mouseEvent = new Event ();
		mouseEvent.widget = browser;
		mouseEvent.x = aClientX[0]; mouseEvent.y = aClientY[0];
		mouseEvent.stateMask = (aAltKey[0] != 0 ? SWT.ALT : 0) | (aCtrlKey[0] != 0 ? SWT.CTRL : 0) | (aShiftKey[0] != 0 ? SWT.SHIFT : 0) | (aMetaKey[0] != 0 ? SWT.COMMAND : 0);
		mouseEvent.type = SWT.MouseDoubleClick;
		mouseEvent.button = aButton[0] + 1;
		mouseEvent.count = aDetail[0];
		browser.notifyListeners (mouseEvent.type, mouseEvent);	
	}
	return XPCOM.NS_OK;
}
}
