diff --git a/dev/windows/src/org/eclipse/swt/browser/Browser.java b/dev/windows/src/org/eclipse/swt/browser/Browser.java
new file mode 100644
index 0000000..e501d6e
--- /dev/null
+++ b/dev/windows/src/org/eclipse/swt/browser/Browser.java
@@ -0,0 +1,1453 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 2006 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
+ *******************************************************************************/
+// Modified by Google
+package org.eclipse.swt.browser;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.internal.ole.win32.*;
+import org.eclipse.swt.internal.win32.*;
+import org.eclipse.swt.ole.win32.*;
+import org.eclipse.swt.widgets.*;
+
+/**
+ * Instances of this class implement the browser user interface
+ * metaphor.  It allows the user to visualize and navigate through
+ * HTML documents.
+ * <p>
+ * Note that although this class is a subclass of <code>Composite</code>,
+ * it does not make sense to set a layout on it.
+ * </p><p>
+ * IMPORTANT: This class is <em>not</em> intended to be subclassed.
+ * </p>
+ * 
+ * @since 3.0
+ */
+public class Browser extends Composite {
+
+	OleFrame frame;
+	OleControlSite site;
+	OleAutomation auto;
+
+	boolean back, forward, navigate, delaySetText, ignoreDispose;
+	Point location;
+	Point size;
+	boolean addressBar = true, menuBar = true, statusBar = true, toolBar = true;
+	int info;
+	
+	int globalDispatch;
+	String html;
+
+	/* External Listener management */
+	CloseWindowListener[] closeWindowListeners = new CloseWindowListener[0];
+	LocationListener[] locationListeners = new LocationListener[0];
+	OpenWindowListener[] openWindowListeners = new OpenWindowListener[0];
+	ProgressListener[] progressListeners = new ProgressListener[0];
+	StatusTextListener[] statusTextListeners = new StatusTextListener[0];
+	TitleListener[] titleListeners = new TitleListener[0];
+	VisibilityWindowListener[] visibilityWindowListeners = new VisibilityWindowListener[0];
+	
+	static final int BeforeNavigate2 = 0xfa;
+	static final int CommandStateChange = 0x69;
+	static final int DocumentComplete = 0x103;
+	static final int NavigateComplete2 = 0xfc;
+	static final int NewWindow2 = 0xfb;
+	static final int OnMenuBar = 0x100;
+	static final int OnStatusBar = 0x101;
+	static final int OnToolBar = 0xff;
+	static final int OnVisible = 0xfe;
+	static final int ProgressChange = 0x6c;
+	static final int RegisterAsBrowser = 0x228;
+	static final int StatusTextChange = 0x66;
+	static final int TitleChange = 0x71;
+	static final int WindowClosing = 0x107;
+	static final int WindowSetHeight = 0x10b;
+	static final int WindowSetLeft = 0x108;
+	static final int WindowSetResizable = 0x106;
+	static final int WindowSetTop = 0x109;
+	static final int WindowSetWidth = 0x10a;
+
+	static final short CSC_NAVIGATEFORWARD = 1;
+	static final short CSC_NAVIGATEBACK = 2;
+	static final int INET_E_DEFAULT_ACTION = 0x800C0011;
+	static final int READYSTATE_COMPLETE = 4;
+	static final int URLPOLICY_ALLOW = 0x00;
+	static final int URLPOLICY_DISALLOW = 0x03;
+	static final int URLZONE_LOCAL_MACHINE = 0;
+	static final int URLZONE_INTRANET = 1;
+	static final int URLACTION_ACTIVEX_MIN = 0x00001200;
+	static final int URLACTION_ACTIVEX_MAX = 0x000013ff;
+	static final int URLACTION_ACTIVEX_RUN = 0x00001200;
+	static final int URLACTION_JAVA_MIN = 0x00001C00;
+	static final int URLPOLICY_JAVA_LOW = 0x00030000;
+	static final int URLACTION_JAVA_MAX = 0x00001Cff;
+	
+	static final int DISPID_AMBIENT_DLCONTROL = -5512;
+	static final int DLCTL_DLIMAGES = 0x00000010;
+	static final int DLCTL_VIDEOS = 0x00000020;
+	static final int DLCTL_BGSOUNDS = 0x00000040;
+	static final int DLCTL_NO_SCRIPTS = 0x00000080;
+	static final int DLCTL_NO_JAVA = 0x00000100;
+	static final int DLCTL_NO_RUNACTIVEXCTLS = 0x00000200;
+	static final int DLCTL_NO_DLACTIVEXCTLS = 0x00000400;
+	static final int DLCTL_DOWNLOADONLY = 0x00000800;
+	static final int DLCTL_NO_FRAMEDOWNLOAD = 0x00001000;
+	static final int DLCTL_RESYNCHRONIZE = 0x00002000;
+	static final int DLCTL_PRAGMA_NO_CACHE = 0x00004000;
+	static final int DLCTL_FORCEOFFLINE = 0x10000000;
+	static final int DLCTL_NO_CLIENTPULL = 0x20000000;
+	static final int DLCTL_SILENT = 0x40000000;
+	static final int DOCHOSTUIFLAG_THEME = 0x00040000;
+	static final int DOCHOSTUIFLAG_NO3DBORDER  = 0x0000004;
+	static final int DOCHOSTUIFLAG_NO3DOUTERBORDER = 0x00200000;
+	
+	static final String ABOUT_BLANK = "about:blank"; //$NON-NLS-1$
+	static final String CLSID_SHELLEXPLORER1 = "{EAB22AC3-30C1-11CF-A7EB-0000C05BAE0B}";
+	static final String URL_DIRECTOR = "http://download.macromedia.com/pub/shockwave/cabs/director/sw.cab"; //$NON-NLS-1$
+
+	/* Package Name */
+	static final String PACKAGE_PREFIX = "org.eclipse.swt.browser."; //$NON-NLS-1$
+
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together 
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a widget which will be the parent of the new instance (cannot be null)
+ * @param style the style of widget to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * </ul>
+ * @exception SWTError <ul>
+ *    <li>ERROR_NO_HANDLES if a handle could not be obtained for browser creation</li>
+ * </ul>
+ * 
+ * @see Widget#getStyle
+ * 
+ * @since 3.0
+ */
+public Browser(Composite parent, int style) {
+	super(parent, style &~ SWT.BORDER);
+	info = Browser.DOCHOSTUIFLAG_THEME;
+	if ((style & SWT.BORDER) == 0) info |= Browser.DOCHOSTUIFLAG_NO3DOUTERBORDER;
+	frame = new OleFrame(this, SWT.NONE);
+
+	/*
+	* Registry entry HKEY_CLASSES_ROOT\Shell.Explorer\CLSID indicates which version of
+	* Shell.Explorer to use by default.  We usually want to use this value because it
+	* typically points at the newest one that is available.  However it is possible for
+	* this registry entry to be changed by another application to point at some other
+	* Shell.Explorer version.
+	*
+	* The Browser depends on the Shell.Explorer version being at least Shell.Explorer.2.
+	* If it is detected in the registry to be Shell.Explorer.1 then change the progId that
+	* will be embedded to explicitly specify Shell.Explorer.2.
+	*/
+	String progId = "Shell.Explorer";	//$NON-NLS-1$
+	TCHAR key = new TCHAR (0, "Shell.Explorer\\CLSID", true);	//$NON-NLS-1$
+	int [] phkResult = new int [1];
+	if (OS.RegOpenKeyEx (OS.HKEY_CLASSES_ROOT, key, 0, OS.KEY_READ, phkResult) == 0) {
+		int [] lpcbData = new int [1];
+		int result = OS.RegQueryValueEx (phkResult [0], null, 0, null, (TCHAR) null, lpcbData);
+		if (result == 0) {
+			TCHAR lpData = new TCHAR (0, lpcbData [0] / TCHAR.sizeof);
+			result = OS.RegQueryValueEx (phkResult [0], null, 0, null, lpData, lpcbData);
+			if (result == 0) {
+				String clsid = lpData.toString (0, lpData.strlen ());
+				if (clsid.equals (CLSID_SHELLEXPLORER1)) {
+					/* Shell.Explorer.1 is the default, ensure that Shell.Explorer.2 is available */
+					key = new TCHAR (0, "Shell.Explorer.2", true);	//$NON-NLS-1$
+					int [] phkResult2 = new int [1];
+					if (OS.RegOpenKeyEx (OS.HKEY_CLASSES_ROOT, key, 0, OS.KEY_READ, phkResult2) == 0) {
+						/* specify that Shell.Explorer.2 is to be used */
+						OS.RegCloseKey (phkResult2 [0]);
+						progId = "Shell.Explorer.2";	//$NON-NLS-1$
+					}
+				}
+			}
+		}
+		OS.RegCloseKey (phkResult [0]);
+	}
+	try {
+		site = new WebSite(frame, SWT.NONE, progId); //$NON-NLS-1$
+	} catch (SWTException e) {
+		dispose();
+		SWT.error(SWT.ERROR_NO_HANDLES);
+	}
+	
+	site.doVerb(OLE.OLEIVERB_INPLACEACTIVATE);
+	auto = new OleAutomation(site);
+
+	Listener listener = new Listener() {
+		public void handleEvent(Event e) {
+			switch (e.type) {
+				case SWT.Dispose: {
+					/* make this handler run after other dispose listeners */
+					if (ignoreDispose) {
+						ignoreDispose = false;
+						break;
+					}
+					ignoreDispose = true;
+					notifyListeners (e.type, e);
+					e.type = SWT.NONE;
+					if (auto != null) auto.dispose();
+					auto = null;
+					break;
+				}
+				case SWT.Resize: {
+					frame.setBounds(getClientArea());
+					break;
+				}
+				case SWT.KeyDown:
+				case SWT.KeyUp: {
+					notifyListeners(e.type, e);
+					break;
+				}
+			}
+		}
+	};
+	addListener(SWT.Dispose, listener);
+	addListener(SWT.Resize, listener);
+	site.addListener(SWT.KeyDown, listener);
+	site.addListener(SWT.KeyUp, listener);
+	
+	OleListener oleListener = new OleListener() {
+		public void handleEvent(OleEvent event) {
+			if (auto == null) return;		/* receiver was disposed, callback is asynchronous */
+			switch (event.type) {
+				case BeforeNavigate2: {
+					Variant varResult = event.arguments[1];
+					String url = varResult.getString();
+					LocationEvent newEvent = new LocationEvent(Browser.this);
+					newEvent.display = getDisplay();
+					newEvent.widget = Browser.this;
+					newEvent.location = url;
+					newEvent.doit = true;
+					for (int i = 0; i < locationListeners.length; i++) {
+						locationListeners[i].changing(newEvent);
+					}
+					Variant cancel = event.arguments[6];
+					if (cancel != null) {
+						int pCancel = cancel.getByRef();
+						COM.MoveMemory(pCancel, new short[]{newEvent.doit ? COM.VARIANT_FALSE : COM.VARIANT_TRUE}, 2);
+				   }					
+					break;
+				}
+				case CommandStateChange: {
+					boolean enabled = false;
+					Variant varResult = event.arguments[0];
+					int command = varResult.getInt();
+					varResult = event.arguments[1];
+					enabled = varResult.getBoolean();
+					switch (command) {
+						case CSC_NAVIGATEBACK : back = enabled; break;
+						case CSC_NAVIGATEFORWARD : forward = enabled; break;
+					}
+					break;
+				}
+				case DocumentComplete: {
+					Variant varResult = event.arguments[0];
+					IDispatch dispatch = varResult.getDispatch();
+
+					varResult = event.arguments[1];
+					String url = varResult.getString();
+					if (html != null && url.equals(ABOUT_BLANK)) {
+						Runnable runnable = new Runnable () {
+							public void run() {
+								if (isDisposed() || html == null) return;
+								int charCount = html.length();
+								char[] chars = new char[charCount];
+								html.getChars(0, charCount, chars, 0);
+								html = null;
+								int byteCount = OS.WideCharToMultiByte(OS.CP_UTF8, 0, chars, charCount, null, 0, null, null);
+								/*
+								* Note. Internet Explorer appears to treat the data loaded with 
+								* nsIPersistStreamInit.Load as if it were encoded using the default
+								* local charset.  There does not seem to be an API to set the
+								* desired charset explicitely in this case.  The fix is to
+								* prepend the UTF-8 Byte Order Mark signature to the data.
+								*/
+								byte[] UTF8BOM = {(byte)0xEF, (byte)0xBB, (byte)0xBF};
+								int	hGlobal = OS.GlobalAlloc(OS.GMEM_FIXED | OS.GMEM_ZEROINIT, UTF8BOM.length + byteCount);
+								if (hGlobal != 0) {
+									OS.MoveMemory(hGlobal, UTF8BOM, UTF8BOM.length);
+									OS.WideCharToMultiByte(OS.CP_UTF8, 0, chars, charCount, hGlobal + UTF8BOM.length, byteCount, null, null);							
+									int[] ppstm = new int[1];
+									/* 
+									* Note.  CreateStreamOnHGlobal is called with the flag fDeleteOnRelease.
+									* If the call succeeds the buffer hGlobal is freed automatically
+									* when the IStream object is released. If the call fails, free the buffer
+									* hGlobal.
+									*/
+									if (OS.CreateStreamOnHGlobal(hGlobal, true, ppstm) == OS.S_OK) {
+										int[] rgdispid = auto.getIDsOfNames(new String[] {"Document"}); //$NON-NLS-1$
+										Variant pVarResult = auto.getProperty(rgdispid[0]);
+										IDispatch dispatchDocument = pVarResult.getDispatch();
+										int[] ppvObject = new int[1];
+										int result = dispatchDocument.QueryInterface(COM.IIDIPersistStreamInit, ppvObject);
+										if (result == OS.S_OK) {
+											IPersistStreamInit persistStreamInit = new IPersistStreamInit(ppvObject[0]);
+											if (persistStreamInit.InitNew() == OS.S_OK) {
+												persistStreamInit.Load(ppstm[0]);
+											}
+											persistStreamInit.Release();
+										}
+										pVarResult.dispose();
+										/*
+										* This code is intentionally commented.  The IDispatch obtained from a Variant
+										* did not increase the reference count for the enclosed interface.
+										*/
+										//dispatchDocument.Release();
+										IUnknown stream = new IUnknown(ppstm[0]);
+										stream.Release();
+									} else {
+										OS.GlobalFree(hGlobal);
+									}
+								}
+							}
+						};
+						if (delaySetText) {
+							delaySetText = false;
+							getDisplay().asyncExec(runnable);
+						} else {
+							runnable.run();
+						}
+					} else {
+						Variant variant = new Variant(auto);
+						IDispatch top = variant.getDispatch();
+						LocationEvent locationEvent = new LocationEvent(Browser.this);
+						locationEvent.display = getDisplay();
+						locationEvent.widget = Browser.this;
+						locationEvent.location = url;
+						locationEvent.top = top.getAddress() == dispatch.getAddress();
+						for (int i = 0; i < locationListeners.length; i++) {
+							locationListeners[i].changed(locationEvent);
+						}
+						/*
+						 * This code is intentionally commented.  A Variant constructed from an
+						 * OleAutomation object does not increase its reference count.  The IDispatch
+						 * obtained from this Variant did not increase the reference count for the
+						 * OleAutomation instance either. 
+						 */
+						//top.Release();
+						//variant.dispose();
+						/*
+						 * Note.  The completion of the page loading is detected as
+						 * described in the MSDN article "Determine when a page is
+						 * done loading in WebBrowser Control". 
+						 */
+						if (globalDispatch != 0 && dispatch.getAddress() == globalDispatch) {
+							/* final document complete */
+							globalDispatch = 0;
+							ProgressEvent progressEvent = new ProgressEvent(Browser.this);
+							progressEvent.display = getDisplay();
+							progressEvent.widget = Browser.this;
+							for (int i = 0; i < progressListeners.length; i++) {
+								progressListeners[i].completed(progressEvent);
+							}
+						}
+					}
+											
+					/*
+					* This code is intentionally commented.  This IDispatch was received
+					* as an argument from the OleEvent and it will be disposed along with
+					* the other arguments.  
+					*/
+					//dispatch.Release();
+					break;
+				}
+				case NavigateComplete2: {
+					Variant varResult = event.arguments[0];
+					IDispatch dispatch = varResult.getDispatch();
+					if (globalDispatch == 0) globalDispatch = dispatch.getAddress();
+					break;
+				}
+				case NewWindow2: {
+					Variant cancel = event.arguments[1];
+					int pCancel = cancel.getByRef();
+					WindowEvent newEvent = new WindowEvent(Browser.this);
+					newEvent.display = getDisplay();
+					newEvent.widget = Browser.this;
+					newEvent.required = false;
+					for (int i = 0; i < openWindowListeners.length; i++) {
+						openWindowListeners[i].open(newEvent);
+					}
+					Browser browser = newEvent.browser;
+					boolean doit = browser != null && !browser.isDisposed();
+					if (doit) {
+						Variant variant = new Variant(browser.auto);
+						IDispatch iDispatch = variant.getDispatch();
+						Variant ppDisp = event.arguments[0];
+						int byref = ppDisp.getByRef();
+						if (byref != 0) COM.MoveMemory(byref, new int[] {iDispatch.getAddress()}, 4);
+						/*
+						* This code is intentionally commented.  A Variant constructed from an
+						* OleAutomation object does not increase its reference count.  The IDispatch
+						* obtained from this Variant did not increase the reference count for the
+						* OleAutomation instance either. 
+						*/
+						//variant.dispose();
+						//iDispatch.Release();
+					}
+					if (newEvent.required) {
+						COM.MoveMemory(pCancel, new short[]{doit ? COM.VARIANT_FALSE : COM.VARIANT_TRUE}, 2);
+					}
+					break;
+				}
+				case OnMenuBar: {
+					Variant arg0 = event.arguments[0];
+					menuBar = arg0.getBoolean();
+					break;
+				}
+				case OnStatusBar: {
+					Variant arg0 = event.arguments[0];
+					statusBar = arg0.getBoolean();
+					break;
+				}
+				case OnToolBar: {
+					Variant arg0 = event.arguments[0];
+					toolBar = arg0.getBoolean();
+					/*
+					* Feature in Internet Explorer.  OnToolBar FALSE is emitted 
+					* when both tool bar, address bar and menu bar must not be visible.
+					* OnToolBar TRUE is emitted when either of tool bar, address bar
+					* or menu bar is visible.
+					*/
+					if (!toolBar) {
+						addressBar = false;
+						menuBar = false;
+					}
+					break;
+				}
+				case OnVisible: {
+					Variant arg1 = event.arguments[0];
+					boolean visible = arg1.getBoolean();
+					WindowEvent newEvent = new WindowEvent(Browser.this);
+					newEvent.display = getDisplay();
+					newEvent.widget = Browser.this;
+					if (visible) {
+						if (addressBar) {
+							/*
+							* Bug in Internet Explorer.  There is no distinct notification for
+							* the address bar.  If neither address, menu or tool bars are visible,
+							* OnToolBar FALSE is emitted. For some reason, querying the value of
+							* AddressBar in this case returns true even though it should not be
+							* set visible.  The workaround is to only query the value of AddressBar
+							* when OnToolBar FALSE has not been emitted.
+							*/
+							int[] rgdispid = auto.getIDsOfNames(new String[] { "AddressBar" }); //$NON-NLS-1$
+							Variant pVarResult = auto.getProperty(rgdispid[0]);
+							if (pVarResult != null && pVarResult.getType() == OLE.VT_BOOL) addressBar = pVarResult.getBoolean();
+						}
+						newEvent.addressBar = addressBar;
+						newEvent.menuBar = menuBar;
+						newEvent.statusBar = statusBar;
+						newEvent.toolBar = toolBar;
+						newEvent.location = location;
+						newEvent.size = size;
+						for (int i = 0; i < visibilityWindowListeners.length; i++) {
+							visibilityWindowListeners[i].show(newEvent);
+						}
+						location = null;
+						size = null;
+					} else {
+						for (int i = 0; i < visibilityWindowListeners.length; i++) {
+							visibilityWindowListeners[i].hide(newEvent);
+						}
+					}
+					break;
+				}
+				case ProgressChange: {
+					Variant arg1 = event.arguments[0];
+					int nProgress = arg1.getType() != OLE.VT_I4 ? 0 : arg1.getInt(); // may be -1
+					Variant arg2 = event.arguments[1];
+					int nProgressMax = arg2.getType() != OLE.VT_I4 ? 0 : arg2.getInt();
+					ProgressEvent newEvent = new ProgressEvent(Browser.this);
+					newEvent.display = getDisplay();
+					newEvent.widget = Browser.this;
+					newEvent.current = nProgress;
+					newEvent.total = nProgressMax;
+					if (nProgress != -1) {
+						for (int i = 0; i < progressListeners.length; i++) {
+							progressListeners[i].changed(newEvent);
+						}
+					}
+					break;
+				}
+				case StatusTextChange: {
+					Variant arg1 = event.arguments[0];
+					if (arg1.getType() == OLE.VT_BSTR) {
+						String text = arg1.getString();
+						StatusTextEvent newEvent = new StatusTextEvent(Browser.this);
+						newEvent.display = getDisplay();
+						newEvent.widget = Browser.this;
+						newEvent.text = text;
+						for (int i = 0; i < statusTextListeners.length; i++) {
+							statusTextListeners[i].changed(newEvent);
+						}
+					}
+					break;
+				}
+				case TitleChange: {
+					Variant arg1 = event.arguments[0];
+					if (arg1.getType() == OLE.VT_BSTR) {
+						String title = arg1.getString();
+						TitleEvent newEvent = new TitleEvent(Browser.this);
+						newEvent.display = getDisplay();
+						newEvent.widget = Browser.this;
+						newEvent.title = title;
+						for (int i = 0; i < titleListeners.length; i++) {
+							titleListeners[i].changed(newEvent);
+						}
+					}
+					break;
+				}
+				case WindowClosing: {
+					WindowEvent newEvent = new WindowEvent(Browser.this);
+					newEvent.display = getDisplay();
+					newEvent.widget = Browser.this;
+					for (int i = 0; i < closeWindowListeners.length; i++) {
+						closeWindowListeners[i].close(newEvent);
+					}
+					Variant cancel = event.arguments[1];
+					int pCancel = cancel.getByRef();
+					Variant arg1 = event.arguments[0];
+					boolean isChildWindow = arg1.getBoolean();
+					COM.MoveMemory(pCancel, new short[]{isChildWindow ? COM.VARIANT_FALSE : COM.VARIANT_TRUE}, 2);
+					dispose();
+					break;
+				}
+				case WindowSetHeight: {
+					if (size == null) size = new Point(0, 0);
+					Variant arg1 = event.arguments[0];
+					size.y = arg1.getInt();
+					break;
+				}
+				case WindowSetLeft: {
+					if (location == null) location = new Point(0, 0);
+					Variant arg1 = event.arguments[0];
+					location.x = arg1.getInt();
+					break;
+				}
+				case WindowSetTop: {
+					if (location == null) location = new Point(0, 0);
+					Variant arg1 = event.arguments[0];
+					location.y = arg1.getInt();
+					break;
+				}
+				case WindowSetWidth: {
+					if (size == null) size = new Point(0, 0);
+					Variant arg1 = event.arguments[0];
+					size.x = arg1.getInt();
+					break;
+				}
+			}			
+			/*
+			* Dispose all arguments passed in the OleEvent.  This must be
+			* done to properly release any IDispatch reference that was
+			* automatically addRef'ed when constructing the OleEvent.  
+			*/
+			Variant[] arguments = event.arguments;
+			for (int i = 0; i < arguments.length; i++) arguments[i].dispose();
+		}
+	};
+	site.addEventListener(BeforeNavigate2, oleListener);
+	site.addEventListener(CommandStateChange, oleListener);
+	site.addEventListener(DocumentComplete, oleListener);
+	site.addEventListener(NavigateComplete2, oleListener);
+	site.addEventListener(NewWindow2, oleListener);
+	site.addEventListener(OnMenuBar, oleListener);
+	site.addEventListener(OnStatusBar, oleListener);
+	site.addEventListener(OnToolBar, oleListener);
+	site.addEventListener(OnVisible, oleListener);
+	site.addEventListener(ProgressChange, oleListener);
+	site.addEventListener(StatusTextChange, oleListener);
+	site.addEventListener(TitleChange, oleListener);
+	site.addEventListener(WindowClosing, oleListener);
+	site.addEventListener(WindowSetHeight, oleListener);
+	site.addEventListener(WindowSetLeft, oleListener);
+	site.addEventListener(WindowSetTop, oleListener);
+	site.addEventListener(WindowSetWidth, oleListener);
+	
+	Variant variant = new Variant(true);
+	auto.setProperty(RegisterAsBrowser, variant);
+	variant.dispose();
+	
+	variant = new Variant(false);
+	int[] rgdispid = auto.getIDsOfNames(new String[] {"RegisterAsDropTarget"}); //$NON-NLS-1$
+	if (rgdispid != null) auto.setProperty(rgdispid[0], variant);
+	variant.dispose();
+    
+    // GOOGLE: Load Google Gears if we can.
+    ((WebSite)site).startGears();
+}
+
+/**
+ * Clears all session cookies from all current Browser instances.
+ * 
+ * @since 3.2
+ */
+public static void clearSessions () {
+	OS.InternetSetOption (0, OS.INTERNET_OPTION_END_BROWSER_SESSION, 0, 0);
+}
+
+/**	 
+ * Adds the listener to the collection of listeners who will be
+ * notified when the window hosting the receiver should be closed.
+ * <p>
+ * This notification occurs when a javascript command such as
+ * <code>window.close</code> gets executed by a <code>Browser</code>.
+ * </p>
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * 
+ * @exception SWTException <ul>
+ *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
+ *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+public void addCloseWindowListener(CloseWindowListener listener) {
+	checkWidget();
+	if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);	
+	CloseWindowListener[] newCloseWindowListeners = new CloseWindowListener[closeWindowListeners.length + 1];
+	System.arraycopy(closeWindowListeners, 0, newCloseWindowListeners, 0, closeWindowListeners.length);
+	closeWindowListeners = newCloseWindowListeners;
+	closeWindowListeners[closeWindowListeners.length - 1] = listener;
+}
+
+/**	 
+ * Adds the listener to the collection of listeners who will be
+ * notified when the current location has changed or is about to change.
+ * <p>
+ * This notification typically occurs when the application navigates
+ * to a new location with {@link #setUrl(String)} or when the user
+ * activates a hyperlink.
+ * </p>
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * 
+ * @exception SWTException <ul>
+ *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
+ *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+public void addLocationListener(LocationListener listener) {
+	checkWidget();
+	if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);	
+	LocationListener[] newLocationListeners = new LocationListener[locationListeners.length + 1];
+	System.arraycopy(locationListeners, 0, newLocationListeners, 0, locationListeners.length);
+	locationListeners = newLocationListeners;
+	locationListeners[locationListeners.length - 1] = listener;
+}
+
+/**	 
+ * Adds the listener to the collection of listeners who will be
+ * notified when a new window needs to be created.
+ * <p>
+ * This notification occurs when a javascript command such as
+ * <code>window.open</code> gets executed by a <code>Browser</code>.
+ * </p>
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * 
+ * @exception SWTException <ul>
+ *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
+ *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+public void addOpenWindowListener(OpenWindowListener listener) {
+	checkWidget();
+	if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+	OpenWindowListener[] newOpenWindowListeners = new OpenWindowListener[openWindowListeners.length + 1];
+	System.arraycopy(openWindowListeners, 0, newOpenWindowListeners, 0, openWindowListeners.length);
+	openWindowListeners = newOpenWindowListeners;
+	openWindowListeners[openWindowListeners.length - 1] = listener;
+}
+
+/**	 
+ * Adds the listener to the collection of listeners who will be
+ * notified when a progress is made during the loading of the current 
+ * URL or when the loading of the current URL has been completed.
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * 
+ * @exception SWTException <ul>
+ *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
+ *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+public void addProgressListener(ProgressListener listener) {
+	checkWidget();
+	if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+	ProgressListener[] newProgressListeners = new ProgressListener[progressListeners.length + 1];
+	System.arraycopy(progressListeners, 0, newProgressListeners, 0, progressListeners.length);
+	progressListeners = newProgressListeners;
+	progressListeners[progressListeners.length - 1] = listener;
+}
+
+/**	 
+ * Adds the listener to the collection of listeners who will be
+ * notified when the status text is changed.
+ * <p>
+ * The status text is typically displayed in the status bar of
+ * a browser application.
+ * </p>
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * 
+ * @exception SWTException <ul>
+ *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
+ *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+public void addStatusTextListener(StatusTextListener listener) {
+	checkWidget();
+	if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+	StatusTextListener[] newStatusTextListeners = new StatusTextListener[statusTextListeners.length + 1];
+	System.arraycopy(statusTextListeners, 0, newStatusTextListeners, 0, statusTextListeners.length);
+	statusTextListeners = newStatusTextListeners;
+	statusTextListeners[statusTextListeners.length - 1] = listener;
+}
+
+/**	 
+ * Adds the listener to the collection of listeners who will be
+ * notified when the title of the current document is available
+ * or has changed.
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * 
+ * @exception SWTException <ul>
+ *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
+ *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+public void addTitleListener(TitleListener listener) {
+	checkWidget();
+	if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+	TitleListener[] newTitleListeners = new TitleListener[titleListeners.length + 1];
+	System.arraycopy(titleListeners, 0, newTitleListeners, 0, titleListeners.length);
+	titleListeners = newTitleListeners;
+	titleListeners[titleListeners.length - 1] = listener;
+}
+
+/**	 
+ * Adds the listener to the collection of listeners who will be
+ * notified when a window hosting the receiver needs to be displayed
+ * or hidden.
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * 
+ * @exception SWTException <ul>
+ *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
+ *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+public void addVisibilityWindowListener(VisibilityWindowListener listener) {
+	checkWidget();
+	if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+	VisibilityWindowListener[] newVisibilityWindowListeners = new VisibilityWindowListener[visibilityWindowListeners.length + 1];
+	System.arraycopy(visibilityWindowListeners, 0, newVisibilityWindowListeners, 0, visibilityWindowListeners.length);
+	visibilityWindowListeners = newVisibilityWindowListeners;
+	visibilityWindowListeners[visibilityWindowListeners.length - 1] = listener;
+}
+
+/**
+ * Navigate to the previous session history item.
+ *
+ * @return <code>true</code> if the operation was successful and <code>false</code> otherwise
+ *
+ * @exception SWTException <ul>
+ *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
+ *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
+ * </ul>
+ *
+ * @see #forward
+ * 
+ * @since 3.0
+ */
+public boolean back() {
+	checkWidget();
+	if (!back) return false;
+	int[] rgdispid = auto.getIDsOfNames(new String[] { "GoBack" }); //$NON-NLS-1$
+	Variant pVarResult = auto.invoke(rgdispid[0]);
+	return pVarResult != null && pVarResult.getType() == OLE.VT_EMPTY;
+}
+
+protected void checkSubclass() {
+	String name = getClass().getName();
+	int index = name.lastIndexOf('.');
+	if (!name.substring(0, index + 1).equals(PACKAGE_PREFIX)) {
+		SWT.error(SWT.ERROR_INVALID_SUBCLASS);
+	}
+}
+
+/**
+ * Execute the specified script.
+ *
+ * <p>
+ * Execute a script containing javascript commands in the context of the current document. 
+ * 
+ * @param script the script with javascript commands
+ *  
+ * @return <code>true</code> if the operation was successful and <code>false</code> otherwise
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_NULL_ARGUMENT - if the script is null</li>
+ * </ul>
+ * 
+ * @exception SWTException <ul>
+ *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
+ *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+public boolean execute(String script) {
+	checkWidget();
+	if (script == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+	
+	/* get IHTMLDocument2 */
+	int[] rgdispid = auto.getIDsOfNames(new String[]{"Document"}); //$NON-NLS-1$
+	int dispIdMember = rgdispid[0];
+	Variant pVarResult = auto.getProperty(dispIdMember);
+	if (pVarResult == null || pVarResult.getType() == COM.VT_EMPTY) return false;
+	OleAutomation document = pVarResult.getAutomation();
+	pVarResult.dispose();
+
+	/* get IHTMLWindow2 */
+	rgdispid = document.getIDsOfNames(new String[]{"parentWindow"}); //$NON-NLS-1$
+	if (rgdispid == null) {
+		/* implies that browser's content is not a IHTMLDocument2 (eg.- acrobat reader) */
+		document.dispose();
+		return false;
+	}
+	dispIdMember = rgdispid[0];
+	pVarResult = document.getProperty(dispIdMember);
+	OleAutomation ihtmlWindow2 = pVarResult.getAutomation();
+	pVarResult.dispose();
+	document.dispose();
+	
+	rgdispid = ihtmlWindow2.getIDsOfNames(new String[] { "execScript", "code" }); //$NON-NLS-1$  //$NON-NLS-2$
+	Variant[] rgvarg = new Variant[1];
+	rgvarg[0] = new Variant(script);
+	int[] rgdispidNamedArgs = new int[1];
+	rgdispidNamedArgs[0] = rgdispid[1];
+	pVarResult = ihtmlWindow2.invoke(rgdispid[0], rgvarg, rgdispidNamedArgs);
+	rgvarg[0].dispose();
+	ihtmlWindow2.dispose();
+	if (pVarResult == null) return false;
+	pVarResult.dispose();
+	return true;
+}
+
+/**
+ * Navigate to the next session history item.
+ *
+ * @return <code>true</code> if the operation was successful and <code>false</code> otherwise
+ *
+ * @exception SWTException <ul>
+ *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
+ *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
+ * </ul>
+ * 
+ * @see #back
+ * 
+ * @since 3.0
+ */
+public boolean forward() {
+	checkWidget();
+	if (!forward) return false;
+	int[] rgdispid = auto.getIDsOfNames(new String[] { "GoForward" }); //$NON-NLS-1$
+	Variant pVarResult = auto.invoke(rgdispid[0]);
+	return pVarResult != null && pVarResult.getType() == OLE.VT_EMPTY;
+}
+
+/**
+ * Returns <code>true</code> if the receiver can navigate to the 
+ * previous session history item, and <code>false</code> otherwise.
+ *
+ * @return the receiver's back command enabled state
+ *
+ * @exception SWTException <ul>
+ *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ * 
+ * @see #back
+ */
+public boolean isBackEnabled() {
+	checkWidget();
+	return back;
+}
+
+/**
+ * Returns <code>true</code> if the receiver can navigate to the 
+ * next session history item, and <code>false</code> otherwise.
+ *
+ * @return the receiver's forward command enabled state
+ *
+ * @exception SWTException <ul>
+ *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ * 
+ * @see #forward
+ */
+public boolean isForwardEnabled() {
+	checkWidget();
+	return forward;
+}
+
+/**
+ * Returns the current URL.
+ *
+ * @return the current URL or an empty <code>String</code> if there is no current URL
+ *
+ * @exception SWTException <ul>
+ *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
+ *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
+ * </ul>
+ *
+ * @see #setUrl
+ * 
+ * @since 3.0
+ */
+public String getUrl() {
+	checkWidget();
+	int[] rgdispid = auto.getIDsOfNames(new String[] { "LocationURL" }); //$NON-NLS-1$
+	Variant pVarResult = auto.getProperty(rgdispid[0]);
+	if (pVarResult == null || pVarResult.getType() != OLE.VT_BSTR)
+		return "";
+	String result = pVarResult.getString();
+	pVarResult.dispose();
+	return result;
+}
+
+public boolean isFocusControl () {
+	checkWidget();
+	if (site.isFocusControl() || frame.isFocusControl()) return true;
+	return super.isFocusControl();
+}
+
+/**
+ * Refresh the current page.
+ *
+ * @exception SWTException <ul>
+ *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
+ *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+public void refresh() {
+	checkWidget();
+	int[] rgdispid = auto.getIDsOfNames(new String[] { "Refresh" }); //$NON-NLS-1$
+	auto.invoke(rgdispid[0]);
+}
+
+/**	 
+ * Removes the listener from the collection of listeners who will
+ * be notified when the window hosting the receiver should be closed.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * 
+ * @exception SWTException <ul>
+ *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
+ *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
+ * </ul>
+ * 
+ * @since 3.0
+ */
+public void removeCloseWindowListener(CloseWindowListener listener) {
+	checkWidget();
+	if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+	if (closeWindowListeners.length == 0) return;
+	int index = -1;
+	for (int i = 0; i < closeWindowListeners.length; i++) {
+		if (listener == closeWindowListeners[i]){
+			index = i;
+			break;
+		}
+	}
+	if (index == -1) return;
+	if (closeWindowListeners.length == 1) {
+		closeWindowListeners = new CloseWindowListener[0];
+		return;
+	}
+	CloseWindowListener[] newCloseWindowListeners = new CloseWindowListener[closeWindowListeners.length - 1];
+	System.arraycopy(closeWindowListeners, 0, newCloseWindowListeners, 0, index);
+	System.arraycopy(closeWindowListeners, index + 1, newCloseWindowListeners, index, closeWindowListeners.length - index - 1);
+	closeWindowListeners = newCloseWindowListeners;
+}
+
+/**	 
+ * Removes the listener from the collection of listeners who will
+ * be notified when the current location is changed or about to be changed.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * 
+ * @exception SWTException <ul>
+ *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
+ *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
+ * </ul>
+ * 
+ * @since 3.0
+ */
+public void removeLocationListener(LocationListener listener) {
+	checkWidget();
+	if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+	if (locationListeners.length == 0) return;
+	int index = -1;
+	for (int i = 0; i < locationListeners.length; i++) {
+		if (listener == locationListeners[i]){
+			index = i;
+			break;
+		}
+	}
+	if (index == -1) return;
+	if (locationListeners.length == 1) {
+		locationListeners = new LocationListener[0];
+		return;
+	}
+	LocationListener[] newLocationListeners = new LocationListener[locationListeners.length - 1];
+	System.arraycopy(locationListeners, 0, newLocationListeners, 0, index);
+	System.arraycopy(locationListeners, index + 1, newLocationListeners, index, locationListeners.length - index - 1);
+	locationListeners = newLocationListeners;
+}
+
+/**	 
+ * Removes the listener from the collection of listeners who will
+ * be notified when a new window needs to be created.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * 
+ * @exception SWTException <ul>
+ *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
+ *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
+ * </ul>
+ * 
+ * @since 3.0
+ */
+public void removeOpenWindowListener(OpenWindowListener listener) {
+	checkWidget();
+	if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+	if (openWindowListeners.length == 0) return;
+	int index = -1;
+	for (int i = 0; i < openWindowListeners.length; i++) {
+		if (listener == openWindowListeners[i]){
+			index = i;
+			break;
+		}
+	}
+	if (index == -1) return;
+	if (openWindowListeners.length == 1) {
+		openWindowListeners = new OpenWindowListener[0];
+		return;
+	}
+	OpenWindowListener[] newOpenWindowListeners = new OpenWindowListener[openWindowListeners.length - 1];
+	System.arraycopy(openWindowListeners, 0, newOpenWindowListeners, 0, index);
+	System.arraycopy(openWindowListeners, index + 1, newOpenWindowListeners, index, openWindowListeners.length - index - 1);
+	openWindowListeners = newOpenWindowListeners;
+}
+
+/**	 
+ * Removes the listener from the collection of listeners who will
+ * be notified when a progress is made during the loading of the current 
+ * URL or when the loading of the current URL has been completed.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * 
+ * @exception SWTException <ul>
+ *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
+ *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
+ * </ul>
+ * 
+ * @since 3.0
+ */
+public void removeProgressListener(ProgressListener listener) {
+	checkWidget();
+	if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+	if (progressListeners.length == 0) return;
+	int index = -1;
+	for (int i = 0; i < progressListeners.length; i++) {
+		if (listener == progressListeners[i]){
+			index = i;
+			break;
+		}
+	}
+	if (index == -1) return;
+	if (progressListeners.length == 1) {
+		progressListeners = new ProgressListener[0];
+		return;
+	}
+	ProgressListener[] newProgressListeners = new ProgressListener[progressListeners.length - 1];
+	System.arraycopy(progressListeners, 0, newProgressListeners, 0, index);
+	System.arraycopy(progressListeners, index + 1, newProgressListeners, index, progressListeners.length - index - 1);
+	progressListeners = newProgressListeners;
+}
+
+/**	 
+ * Removes the listener from the collection of listeners who will
+ * be notified when the status text is changed.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * 
+ * @exception SWTException <ul>
+ *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
+ *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
+ * </ul>
+ * 
+ * @since 3.0
+ */
+public void removeStatusTextListener(StatusTextListener listener) {
+	checkWidget();
+	if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+	if (statusTextListeners.length == 0) return;
+	int index = -1;
+	for (int i = 0; i < statusTextListeners.length; i++) {
+		if (listener == statusTextListeners[i]){
+			index = i;
+			break;
+		}
+	}
+	if (index == -1) return;
+	if (statusTextListeners.length == 1) {
+		statusTextListeners = new StatusTextListener[0];
+		return;
+	}
+	StatusTextListener[] newStatusTextListeners = new StatusTextListener[statusTextListeners.length - 1];
+	System.arraycopy(statusTextListeners, 0, newStatusTextListeners, 0, index);
+	System.arraycopy(statusTextListeners, index + 1, newStatusTextListeners, index, statusTextListeners.length - index - 1);
+	statusTextListeners = newStatusTextListeners;
+}
+
+/**	 
+ * Removes the listener from the collection of listeners who will
+ * be notified when the title of the current document is available
+ * or has changed.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * 
+ * @exception SWTException <ul>
+ *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
+ *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
+ * </ul>
+ * 
+ * @since 3.0
+ */
+public void removeTitleListener(TitleListener listener) {
+	checkWidget();
+	if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+	if (titleListeners.length == 0) return;
+	int index = -1;
+	for (int i = 0; i < titleListeners.length; i++) {
+		if (listener == titleListeners[i]){
+			index = i;
+			break;
+		}
+	}
+	if (index == -1) return;
+	if (titleListeners.length == 1) {
+		titleListeners = new TitleListener[0];
+		return;
+	}
+	TitleListener[] newTitleListeners = new TitleListener[titleListeners.length - 1];
+	System.arraycopy(titleListeners, 0, newTitleListeners, 0, index);
+	System.arraycopy(titleListeners, index + 1, newTitleListeners, index, titleListeners.length - index - 1);
+	titleListeners = newTitleListeners;
+}
+
+/**	 
+ * Removes the listener from the collection of listeners who will
+ * be notified when a window hosting the receiver needs to be displayed
+ * or hidden.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * 
+ * @exception SWTException <ul>
+ *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
+ *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
+ * </ul>
+ * 
+ * @since 3.0
+ */
+public void removeVisibilityWindowListener(VisibilityWindowListener listener) {
+	checkWidget();
+	if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+	if (visibilityWindowListeners.length == 0) return;
+	int index = -1;
+	for (int i = 0; i < visibilityWindowListeners.length; i++) {
+		if (listener == visibilityWindowListeners[i]){
+			index = i;
+			break;
+		}
+	}
+	if (index == -1) return;
+	if (visibilityWindowListeners.length == 1) {
+		visibilityWindowListeners = new VisibilityWindowListener[0];
+		return;
+	}
+	VisibilityWindowListener[] newVisibilityWindowListeners = new VisibilityWindowListener[visibilityWindowListeners.length - 1];
+	System.arraycopy(visibilityWindowListeners, 0, newVisibilityWindowListeners, 0, index);
+	System.arraycopy(visibilityWindowListeners, index + 1, newVisibilityWindowListeners, index, visibilityWindowListeners.length - index - 1);
+	visibilityWindowListeners = newVisibilityWindowListeners;
+}
+
+/**
+ * Renders HTML.
+ * 
+ * <p>
+ * The html parameter is Unicode encoded since it is a java <code>String</code>.
+ * As a result, the HTML meta tag charset should not be set. The charset is implied
+ * by the <code>String</code> itself.
+ * 
+ * @param html the HTML content to be rendered
+ *
+ * @return true if the operation was successful and false otherwise.
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_NULL_ARGUMENT - if the html is null</li>
+ * </ul>
+ * 
+ * @exception SWTException <ul>
+ *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
+ *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
+ * </ul>
+ *  
+ * @see #setUrl
+ * 
+ * @since 3.0
+ */
+public boolean setText(String html) {
+	checkWidget();
+	if (html == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+
+	/*
+	* If the html field is non-null then the about:blank page is already being
+	* loaded, so no Stop or Navigate is required.  Just set the html that is to
+	* be shown.
+	*/
+	boolean blankLoading = this.html != null;
+	this.html = html;
+	if (blankLoading) return true;
+	
+	/*
+	* Navigate to the blank page and insert the given html when
+	* receiving the next DocumentComplete notification.  See the
+	* MSDN article "Loading HTML content from a Stream".
+	* 
+	* Note.  Stop any pending request.  This is required to avoid displaying a
+	* blank page as a result of consecutive calls to setUrl and/or setText.  
+	* The previous request would otherwise render the new html content and
+	* reset the html field before the browser actually navigates to the blank
+	* page as requested below.
+	* 
+	* Feature in Internet Explorer.  Stopping pending requests when no request
+	* is pending causes a default page 'Action cancelled' to be displayed.  The
+	* workaround is to not invoke 'stop' when no request has been set since
+	* that instance was created.
+	*/
+	int[] rgdispid;
+	if (navigate) {
+		/*
+		* Stopping the loading of a page causes DocumentComplete events from previous
+		* requests to be received before the DocumentComplete for this page.  In such
+		* cases we must be sure to not set the html into the browser too soon, since
+		* doing so could result in its page being cleared out by a subsequent
+		* DocumentComplete.  The Browser's ReadyState can be used to determine whether
+		* these extra events will be received or not.
+		*/
+		rgdispid = auto.getIDsOfNames(new String[] { "ReadyState" }); //$NON-NLS-1$
+		Variant pVarResult = auto.getProperty(rgdispid[0]);
+		if (pVarResult == null) return false;
+		delaySetText = pVarResult.getInt() != READYSTATE_COMPLETE;
+		pVarResult.dispose();
+		rgdispid = auto.getIDsOfNames(new String[] { "Stop" }); //$NON-NLS-1$
+		auto.invoke(rgdispid[0]);
+	}
+	rgdispid = auto.getIDsOfNames(new String[] { "Navigate", "URL" }); //$NON-NLS-1$ //$NON-NLS-2$
+	navigate = true;
+	Variant[] rgvarg = new Variant[1];
+	rgvarg[0] = new Variant(ABOUT_BLANK);
+	int[] rgdispidNamedArgs = new int[1];
+	rgdispidNamedArgs[0] = rgdispid[1];
+	Variant pVarResult = auto.invoke(rgdispid[0], rgvarg, rgdispidNamedArgs);
+	rgvarg[0].dispose();
+	if (pVarResult == null) return false;
+	boolean result = pVarResult.getType() == OLE.VT_EMPTY;
+	pVarResult.dispose();
+	return result;
+}
+
+/**
+ * Loads a URL.
+ * 
+ * @param url the URL to be loaded
+ *
+ * @return true if the operation was successful and false otherwise.
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_NULL_ARGUMENT - if the url is null</li>
+ * </ul>
+ * 
+ * @exception SWTException <ul>
+ *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
+ *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
+ * </ul>
+ *  
+ * @see #getUrl
+ * 
+ * @since 3.0
+ */
+public boolean setUrl(String url) {
+	checkWidget();
+	if (url == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+	html = null;
+
+	/*
+	* Bug in Internet Explorer.  For some reason, Navigating to an xml document before
+	* a previous Navigate has completed will leave the Browser in a bad state if the
+	* Navigate to the xml document does not complete.  This bad state causes a GP when
+	* the parent window is eventually disposed.  The workaround is to issue a Stop before
+	* navigating to any xml document. 
+	*/
+	if (url.endsWith(".xml")) {	//$NON-NLS-1$
+		/*
+		* Feature in Internet Explorer.  Stopping pending requests when no request has been
+		* issued causes a default 'Action cancelled' page to be displayed.  Since Stop must
+		* be issued here, the workaround is to first Navigate to the about:blank page before
+		* issuing Stop so that the 'Action cancelled' page is not displayed.
+		*/
+		if (!navigate) {
+			int[] rgdispid = auto.getIDsOfNames(new String[] { "Navigate", "URL" }); //$NON-NLS-1$ //$NON-NLS-2$
+			Variant[] rgvarg = new Variant[1];
+			rgvarg[0] = new Variant(ABOUT_BLANK);
+			int[] rgdispidNamedArgs = new int[1];
+			rgdispidNamedArgs[0] = rgdispid[1];
+			auto.invoke(rgdispid[0], rgvarg, rgdispidNamedArgs);
+			rgvarg[0].dispose();
+		}
+		int[] rgdispid = auto.getIDsOfNames(new String[] { "Stop" }); //$NON-NLS-1$
+		auto.invoke(rgdispid[0]);
+	}
+
+	int[] rgdispid = auto.getIDsOfNames(new String[] { "Navigate", "URL" }); //$NON-NLS-1$ //$NON-NLS-2$
+	navigate = true;
+	Variant[] rgvarg = new Variant[1];
+	rgvarg[0] = new Variant(url);
+	int[] rgdispidNamedArgs = new int[1];
+	rgdispidNamedArgs[0] = rgdispid[1];
+	Variant pVarResult = auto.invoke(rgdispid[0], rgvarg, rgdispidNamedArgs);
+	rgvarg[0].dispose();
+	if (pVarResult == null) return false;
+	boolean result = pVarResult.getType() == OLE.VT_EMPTY;
+	pVarResult.dispose();
+	return result;
+}
+
+/**
+ * Stop any loading and rendering activity.
+ *
+ * @exception SWTException <ul>
+ *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
+ *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+public void stop() {
+	checkWidget();
+	int[] rgdispid = auto.getIDsOfNames(new String[] { "Stop" }); //$NON-NLS-1$
+	auto.invoke(rgdispid[0]);
+}
+}
diff --git a/dev/windows/src/org/eclipse/swt/browser/WebSite.java b/dev/windows/src/org/eclipse/swt/browser/WebSite.java
new file mode 100644
index 0000000..f0c1a63
--- /dev/null
+++ b/dev/windows/src/org/eclipse/swt/browser/WebSite.java
@@ -0,0 +1,514 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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
+ *******************************************************************************/
+// Modified by Google
+package org.eclipse.swt.browser;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.internal.ole.win32.*;
+import org.eclipse.swt.ole.win32.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.swt.internal.win32.*;
+
+class WebSite extends OleControlSite {
+	COMObject iDocHostUIHandler;
+	COMObject iDocHostShowUI;
+	COMObject iServiceProvider;
+	COMObject iInternetSecurityManager;
+	COMObject iOleCommandTarget;
+
+	static final int OLECMDID_SHOWSCRIPTERROR = 40;
+
+public WebSite(Composite parent, int style, String progId) {
+	super(parent, style, progId);
+}
+
+// GOOGLE: attempt to load Gears
+/**
+ * Load the Google Gears BHO if possible.
+ * 
+ * @return true if Gears was successfully loaded and initialized
+ */
+public boolean startGears() {
+  // Get the classID of the Gears BHO.
+  GUID appClsid = getClassID("gears.BHO");
+  if (appClsid == null) {
+    return false;
+  }
+  
+  // Create an instance of the Gears BHO.
+  int[] address = new int[1];
+  if (COM.CoCreateInstance(appClsid, 0, COM.CLSCTX_INPROC_SERVER,
+      COM.IIDIUnknown, address) != COM.S_OK) {
+    return false;
+  }
+  
+  // Get the IObjectWithSite interface and call SetSite. 
+  IUnknown obj = new IUnknown(address[0]);
+  int[] ppvObject = new int[1];
+  if (obj.QueryInterface(COM.IIDIObjectWithSite, ppvObject) == COM.S_OK) {
+    IObjectWithSite objectWithSite = new IObjectWithSite(ppvObject[0]);
+    /*
+     * TODO: Gears currently does not check the parameter passed other than
+     * to see if it is non-null.  If Gears ever changes to actually use the
+     * passed object, we will need to make sure that this works as expected.
+     */
+    objectWithSite.SetSite(objIUnknown);
+    objectWithSite.Release();
+    return true;
+  }
+  return false;
+}
+
+protected void createCOMInterfaces () {
+	super.createCOMInterfaces();
+	iDocHostUIHandler = new COMObject(new int[]{2, 0, 0, 4, 1, 5, 0, 0, 1, 1, 1, 3, 3, 2, 2, 1, 3, 2}){
+		public int method0(int[] args) {return QueryInterface(args[0], args[1]);}
+		public int method1(int[] args) {return AddRef();}
+		public int method2(int[] args) {return Release();}
+		public int method3(int[] args) {return ShowContextMenu(args[0], args[1], args[2], args[3]);}
+		public int method4(int[] args) {return GetHostInfo(args[0]);}
+		public int method5(int[] args) {return ShowUI(args[0], args[1], args[2], args[3], args[4]);}
+		public int method6(int[] args) {return HideUI();}
+		public int method7(int[] args) {return UpdateUI();}
+		public int method8(int[] args) {return EnableModeless(args[0]);}
+		public int method9(int[] args) {return OnDocWindowActivate(args[0]);}
+		public int method10(int[] args) {return OnFrameWindowActivate(args[0]);}
+		public int method11(int[] args) {return ResizeBorder(args[0], args[1], args[2]);}
+		public int method12(int[] args) {return TranslateAccelerator(args[0], args[1], args[2]);}
+		public int method13(int[] args) {return GetOptionKeyPath(args[0], args[1]);}
+		public int method14(int[] args) {return GetDropTarget(args[0], args[1]);}
+		public int method15(int[] args) {return GetExternal(args[0]);}
+		public int method16(int[] args) {return TranslateUrl(args[0], args[1], args[2]);}		
+		public int method17(int[] args) {return FilterDataObject(args[0], args[1]);}
+	};
+	iDocHostShowUI = new COMObject(new int[]{2, 0, 0, 7, 7}){
+		public int method0(int[] args) {return QueryInterface(args[0], args[1]);}
+		public int method1(int[] args) {return AddRef();}
+		public int method2(int[] args) {return Release();}
+		public int method3(int[] args) {return ShowMessage(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);}
+		public int method4(int[] args) {return ShowHelp(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);}
+	};
+	iServiceProvider = new COMObject(new int[]{2, 0, 0, 3}){
+		public int method0(int[] args) {return QueryInterface(args[0], args[1]);}
+		public int method1(int[] args) {return AddRef();}
+		public int method2(int[] args) {return Release();}
+		public int method3(int[] args) {return QueryService(args[0], args[1], args[2]);}
+	};
+	iInternetSecurityManager = new COMObject(new int[]{2, 0, 0, 1, 1, 3, 4, 8, 7, 3, 3}){
+		public int method0(int[] args) {return QueryInterface(args[0], args[1]);}
+		public int method1(int[] args) {return AddRef();}
+		public int method2(int[] args) {return Release();}
+		public int method3(int[] args) {return SetSecuritySite(args[0]);}
+		public int method4(int[] args) {return GetSecuritySite(args[0]);}
+		public int method5(int[] args) {return MapUrlToZone(args[0], args[1], args[2]);}
+		public int method6(int[] args) {return GetSecurityId(args[0], args[1], args[2], args[3]);}
+		public int method7(int[] args) {return ProcessUrlAction(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]);}
+		public int method8(int[] args) {return QueryCustomPolicy(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);}
+		public int method9(int[] args) {return SetZoneMapping(args[0], args[1], args[2]);}
+		public int method10(int[] args) {return GetZoneMappings(args[0], args[1], args[2]);}
+	};
+	iOleCommandTarget = new COMObject(new int[]{2, 0, 0, 4, 5}) {
+		public int method0(int[] args) {return QueryInterface(args[0], args[1]);}
+		public int method1(int[] args) {return AddRef();}
+		public int method2(int[] args) {return Release();}		
+		public int method3(int[] args) {return QueryStatus(args[0], args[1], args[2], args[3]);}		
+		public int method4(int[] args) {return Exec(args[0], args[1], args[2], args[3], args[4]);}
+	};
+}
+
+protected void disposeCOMInterfaces() {
+	super.disposeCOMInterfaces();
+	if (iDocHostUIHandler != null) {
+		iDocHostUIHandler.dispose();
+		iDocHostUIHandler = null;
+	}
+	if (iDocHostShowUI != null) {
+		iDocHostShowUI.dispose();
+		iDocHostShowUI = null;
+	}
+	if (iServiceProvider != null) {
+		iServiceProvider.dispose();
+		iServiceProvider = null;
+	}
+	if (iInternetSecurityManager != null) {
+		iInternetSecurityManager.dispose();
+		iInternetSecurityManager = null;
+	}
+	if (iOleCommandTarget != null) {
+		iOleCommandTarget.dispose();
+		iOleCommandTarget = null;
+	}
+}
+
+protected int AddRef() {
+	/* Workaround for javac 1.1.8 bug */
+	return super.AddRef();
+}
+
+protected int QueryInterface(int riid, int ppvObject) {
+	int result = super.QueryInterface(riid, ppvObject);
+	if (result == COM.S_OK) return result;
+	if (riid == 0 || ppvObject == 0) return COM.E_INVALIDARG;
+	GUID guid = new GUID();
+	COM.MoveMemory(guid, riid, GUID.sizeof);
+	if (COM.IsEqualGUID(guid, COM.IIDIDocHostUIHandler)) {
+		COM.MoveMemory(ppvObject, new int[] {iDocHostUIHandler.getAddress()}, 4);
+		AddRef();
+		return COM.S_OK;
+	}
+	if (COM.IsEqualGUID(guid, COM.IIDIDocHostShowUI)) {
+		COM.MoveMemory(ppvObject, new int[] {iDocHostShowUI.getAddress()}, 4);
+		AddRef();
+		return COM.S_OK;
+	}
+	if (COM.IsEqualGUID(guid, COM.IIDIServiceProvider)) {
+		COM.MoveMemory(ppvObject, new int[] {iServiceProvider.getAddress()}, 4);
+		AddRef();
+		return COM.S_OK;
+	}
+    if (COM.IsEqualGUID(guid, COM.IIDIInternetSecurityManager)) {
+        COM.MoveMemory(ppvObject, new int[] {iInternetSecurityManager.getAddress()}, 4);
+        AddRef();
+        return COM.S_OK;
+    }
+	if (COM.IsEqualGUID(guid, COM.IIDIOleCommandTarget)) {
+		COM.MoveMemory(ppvObject, new int[] {iOleCommandTarget.getAddress()}, 4);
+		AddRef();
+		return COM.S_OK;
+	}
+	COM.MoveMemory(ppvObject, new int[] {0}, 4);
+	return COM.E_NOINTERFACE;
+}
+
+/* IDocHostUIHandler */
+
+int EnableModeless(int EnableModeless) {
+	return COM.E_NOTIMPL;
+}
+
+int FilterDataObject(int pDO, int ppDORet) {
+	return COM.E_NOTIMPL;
+}
+
+int GetDropTarget(int pDropTarget, int ppDropTarget) {
+	return COM.E_NOTIMPL;
+}
+
+int GetExternal(int ppDispatch) {
+	OS.MoveMemory(ppDispatch, new int[] {0}, 4);
+	return COM.S_FALSE;
+}
+
+int GetHostInfo(int pInfo) {
+	Browser browser = (Browser)getParent().getParent();
+	OS.MoveMemory(pInfo + 4, new int[] {browser.info}, 4);
+	return COM.S_OK;
+}
+
+int GetOptionKeyPath(int pchKey, int dw) {
+	return COM.E_NOTIMPL;
+}
+
+int HideUI() {
+	return COM.E_NOTIMPL;
+}
+
+int OnDocWindowActivate(int fActivate) {
+	return COM.E_NOTIMPL;
+}
+
+int OnFrameWindowActivate(int fActivate) {
+	return COM.E_NOTIMPL;
+}
+
+protected int Release() {
+	/* Workaround for javac 1.1.8 bug */
+	return super.Release();
+}
+
+int ResizeBorder(int prcBorder, int pUIWindow, int fFrameWindow) {
+	return COM.E_NOTIMPL;
+}
+
+int ShowContextMenu(int dwID, int ppt, int pcmdtReserved, int pdispReserved) {
+	Browser browser = (Browser)getParent().getParent();
+	Event event = new Event();
+	POINT pt = new POINT();
+	OS.MoveMemory(pt, ppt, POINT.sizeof);
+	event.x = pt.x;
+	event.y = pt.y;
+	browser.notifyListeners(SWT.MenuDetect, event);
+	if (!event.doit) return COM.S_OK;
+	Menu menu = browser.getMenu();
+	if (menu != null && !menu.isDisposed ()) {
+		if (pt.x != event.x || pt.y != event.y) {
+			menu.setLocation (event.x, event.y);
+		}
+		menu.setVisible (true);
+		return COM.S_OK;
+	}
+	/* Show default IE popup menu */
+	return COM.S_FALSE;
+}
+
+int ShowUI(int dwID, int pActiveObject, int pCommandTarget, int pFrame, int pDoc) {
+	return COM.E_NOTIMPL;
+}
+
+int TranslateAccelerator(int lpMsg, int pguidCmdGroup, int nCmdID) {
+	/*
+	* Feature on Internet Explorer.  By default the embedded Internet Explorer control runs
+	* the Internet Explorer shortcuts (e.g. F5 for refresh).  This overrides the shortcuts
+	* defined by SWT.  The workaround is to forward the accelerator keys to the parent window
+	* and have Internet Explorer ignore the ones handled by the parent window.
+	*/
+	Menu menubar = getShell().getMenuBar();
+	if (menubar != null && !menubar.isDisposed() && menubar.isEnabled()) {
+		Shell shell = menubar.getShell();
+		int hwnd = shell.handle;
+		int hAccel = OS.SendMessage(hwnd, OS.WM_APP+1, 0, 0);
+		if (hAccel != 0) {
+			MSG msg = new MSG();
+			OS.MoveMemory(msg, lpMsg, MSG.sizeof);
+			if (OS.TranslateAccelerator(hwnd, hAccel, msg) != 0) return COM.S_OK;
+		}
+	}
+	/*
+	* Feature on Internet Explorer.  By default the embedded Internet Explorer control runs
+	* the Internet Explorer shortcuts.  F5 causes refresh.  CTRL-N opens a standalone Internet 
+	* Explorer.  These behaviours are undesired when rendering HTML in memory.
+	* The workaround is to block the default CTRL-N and F5 handling by IE when the URL is about:blank.
+	*/
+	OleAutomation auto = new OleAutomation(this);
+	int[] rgdispid = auto.getIDsOfNames(new String[] { "LocationURL" }); //$NON-NLS-1$
+	Variant pVarResult = auto.getProperty(rgdispid[0]);
+	auto.dispose();
+	int result = COM.S_FALSE;
+	if (pVarResult != null) {
+		if (pVarResult.getType() == OLE.VT_BSTR) {
+			String url = pVarResult.getString();
+			if (url.equals(Browser.ABOUT_BLANK)) {
+				MSG msg = new MSG();
+				OS.MoveMemory(msg, lpMsg, MSG.sizeof);
+				if (msg.message == OS.WM_KEYDOWN && msg.wParam == OS.VK_F5) result = COM.S_OK;
+				if (msg.message == OS.WM_KEYDOWN && msg.wParam == OS.VK_N && OS.GetKeyState (OS.VK_CONTROL) < 0) result = COM.S_OK;
+			}
+		}
+		pVarResult.dispose();
+	}
+	return result;
+}
+
+int TranslateUrl(int dwTranslate, int pchURLIn, int ppchURLOut) {
+	return COM.E_NOTIMPL;
+}
+
+int UpdateUI() {
+	return COM.E_NOTIMPL;
+}
+
+/* IDocHostShowUI */
+
+int ShowMessage(int hwnd, int lpstrText, int lpstrCaption, int dwType, int lpstrHelpFile, int dwHelpContext, int plResult) {
+	/*
+	* Feature on IE.  When IE navigates to a website that contains an ActiveX that is prevented from
+	* being executed, IE displays a message "Your current security settings prohibit running ActiveX 
+	* controls on this page ...".  The workaround is to selectively block this alert as indicated
+	* in the MSDN article "WebBrowser customization".
+	*/
+	/* resource identifier in shdoclc.dll for window caption "Your current security settings prohibit 
+	 * running ActiveX controls on this page ..." 
+	 */
+	int IDS_MESSAGE_BOX_CAPTION = 8033;
+		if (lpstrText != 0) {
+		TCHAR lpLibFileName = new TCHAR (0, "SHDOCLC.DLL", true); //$NON-NLS-1$
+		int hModule = OS.LoadLibrary(lpLibFileName);
+		if (hModule != 0) {
+			/* 
+			* Note.  lpstrText is a LPOLESTR, i.e. a null terminated unicode string LPWSTR, i.e. a WCHAR*.
+			* It is not a BSTR.  A BSTR is a null terminated unicode string that contains its length
+			* at the beginning. 
+			*/
+			int cnt = OS.wcslen(lpstrText);
+			char[] buffer = new char[cnt];
+			/* 
+			* Note.  lpstrText is unicode on both unicode and ansi platforms.
+			* The nbr of chars is multiplied by the constant 2 and not by TCHAR.sizeof since
+			* TCHAR.sizeof returns 1 on ansi platforms.
+			*/
+			OS.MoveMemory(buffer, lpstrText, cnt * 2);
+			String text = new String(buffer);
+			/* provide a buffer large enough to hold the string to compare to and a null terminated character */
+			int length = (OS.IsUnicode ? cnt : OS.WideCharToMultiByte (OS.CP_ACP, 0, buffer, cnt, 0, 0, null, null)) + 1;
+
+			TCHAR lpBuffer = new TCHAR(0, length);
+			int result = OS.LoadString(hModule, IDS_MESSAGE_BOX_CAPTION, lpBuffer, length);
+			OS.FreeLibrary(hModule);
+			return result > 0 && text.equals(lpBuffer.toString(0, result)) ? COM.S_OK : COM.S_FALSE;
+		}
+	}
+	return COM.S_FALSE;
+}
+
+/* Note.  One of the arguments of ShowHelp is a POINT struct and not a pointer to a POINT struct. Because
+ * of the way Callback gets int parameters from a va_list of C arguments 2 integer arguments must be declared,
+ * ptMouse_x and ptMouse_y. Otherwise the Browser crashes when the user presses F1 to invoke
+ * the help.
+ */
+int ShowHelp(int hwnd, int pszHelpFile, int uCommand, int dwData, int ptMouse_x, int ptMouse_y, int pDispatchObjectHit) {
+	Browser browser = (Browser)getParent().getParent();
+	Event event = new Event();
+	event.type = SWT.Help;
+	event.display = getDisplay();
+	event.widget = browser;
+	Shell shell = browser.getShell();
+	Control control = browser;
+	do {
+		if (control.isListening(SWT.Help)) {
+			control.notifyListeners(SWT.Help, event);
+			break;
+		}
+		if (control == shell) break;
+		control = control.getParent();
+	} while (true);
+	return COM.S_OK;
+}
+
+/* IServiceProvider */
+
+int QueryService(int guidService, int riid, int ppvObject) {
+	if (riid == 0 || ppvObject == 0) return COM.E_INVALIDARG;
+	GUID guid = new GUID();
+	COM.MoveMemory(guid, riid, GUID.sizeof);
+	if (COM.IsEqualGUID(guid, COM.IIDIInternetSecurityManager)) {
+		COM.MoveMemory(ppvObject, new int[] {iInternetSecurityManager.getAddress()}, 4);
+		AddRef();
+		return COM.S_OK;
+	}
+	COM.MoveMemory(ppvObject, new int[] {0}, 4);
+	return COM.E_NOINTERFACE;
+}
+
+/* IInternetSecurityManager */
+
+int SetSecuritySite(int pSite) {
+	return Browser.INET_E_DEFAULT_ACTION;
+}
+
+int GetSecuritySite(int ppSite) {
+	return Browser.INET_E_DEFAULT_ACTION;
+}
+
+int MapUrlToZone(int pwszUrl, int pdwZone, int dwFlags) {	
+	/*
+	* Feature in IE 6 sp1.  HTML rendered in memory
+	* does not enable local links but the exact same
+	* HTML document loaded through a local file is
+	* permitted to follow local links.  The workaround is
+	* to return URLZONE_INTRANET instead of the default
+	* value URLZONE_LOCAL_MACHINE.
+	*/	
+	COM.MoveMemory(pdwZone, new int[] {Browser.URLZONE_INTRANET}, 4);
+	return COM.S_OK;
+}
+
+int GetSecurityId(int pwszUrl, int pbSecurityId, int pcbSecurityId, int dwReserved) {
+	return Browser.INET_E_DEFAULT_ACTION;
+}
+
+int ProcessUrlAction(int pwszUrl, int dwAction, int pPolicy, int cbPolicy, int pContext, int cbContext, int dwFlags, int dwReserved) {
+	/*
+	* Feature in IE 6 sp1.  HTML rendered in memory
+	* containing an OBJECT tag referring to a local file
+	* brings up a warning dialog asking the user whether
+	* it should proceed or not.  The workaround is to
+	* set the policy to URLPOLICY_ALLOW in this case (dwAction
+	* value of 0x1406).
+	* 
+	* Feature in IE. Security Patches and user settings
+	* affect the way the embedded web control behaves.  The current
+	* approach is to consider the content trusted and allow
+	* all URLs by default.
+	*/
+	int policy = Browser.URLPOLICY_ALLOW;
+	/*
+	* Note. The URLACTION_JAVA flags refer to the applet tag that normally resolve to
+	* the Microsoft VM, not to the java OBJECT tag that resolves to the
+	* Sun plugin. Return URLPOLICY_JAVA_LOW to authorize applets instead of
+	* URLPOLICY_ALLOW that is interpreted as URLPOLICY_JAVA_PROHIBIT in this
+	* context. 
+	*/
+	if (dwAction >= Browser.URLACTION_JAVA_MIN && dwAction <= Browser.URLACTION_JAVA_MAX) {
+		policy = Browser.URLPOLICY_JAVA_LOW;
+	}
+	/*
+	* Note.  Some ActiveX plugins crash when executing
+	* inside the embedded explorer itself running into
+	* a JVM.  The current workaround is to detect when
+	* such ActiveX is about to be started and refuse
+	* to execute it.
+	*/
+	if (dwAction == Browser.URLACTION_ACTIVEX_RUN) {
+		GUID guid = new GUID();
+		COM.MoveMemory(guid, pContext, GUID.sizeof);
+		if (COM.IsEqualGUID(guid, COM.IIDJavaBeansBridge) || COM.IsEqualGUID(guid, COM.IIDShockwaveActiveXControl)) {
+			policy = Browser.URLPOLICY_DISALLOW;
+		}
+	}
+	if (cbPolicy >= 4) COM.MoveMemory(pPolicy, new int[] {policy}, 4);
+	return COM.S_OK;
+}
+
+int QueryCustomPolicy(int pwszUrl, int guidKey, int ppPolicy, int pcbPolicy, int pContext, int cbContext, int dwReserved) {
+	return Browser.INET_E_DEFAULT_ACTION;
+}
+
+int SetZoneMapping(int dwZone, int lpszPattern, int dwFlags) {
+	return Browser.INET_E_DEFAULT_ACTION;
+}
+
+int GetZoneMappings(int dwZone, int ppenumString, int dwFlags) {
+	return COM.E_NOTIMPL;
+}
+
+/* IOleCommandTarget */
+int QueryStatus(int pguidCmdGroup, int cCmds, int prgCmds, int pCmdText) {
+	return COM.E_NOTSUPPORTED;
+}
+
+int Exec(int pguidCmdGroup, int nCmdID, int nCmdExecOpt, int pvaIn, int pvaOut) {
+	if (pguidCmdGroup != 0) {
+		GUID guid = new GUID();
+		COM.MoveMemory(guid, pguidCmdGroup, GUID.sizeof);
+
+		/*
+		* If a javascript error occurred then suppress IE's default script error dialog.
+		*/
+		if (COM.IsEqualGUID(guid, COM.CGID_DocHostCommandHandler)) {
+			if (nCmdID == OLECMDID_SHOWSCRIPTERROR) return COM.S_OK;
+		}
+
+		/*
+		* Bug in Internet Explorer.  OnToolBar TRUE is also fired when any of the 
+		* address bar or menu bar are requested but not the tool bar.  A workaround
+		* has been posted by a Microsoft developer on the public webbrowser_ctl
+		* newsgroup. The workaround is to implement the IOleCommandTarget interface
+		* to test the argument of an undocumented command.
+		*/
+		if (nCmdID == 1 && COM.IsEqualGUID(guid, COM.CGID_Explorer) && ((nCmdExecOpt & 0xFFFF) == 0xA)) {
+			Browser browser = (Browser)getParent().getParent();
+			browser.toolBar = (nCmdExecOpt & 0xFFFF0000) != 0;
+		}
+	}
+	return COM.E_NOTSUPPORTED;
+}
+
+}
diff --git a/dev/windows/src/org/eclipse/swt/internal/ole/win32/COM.java b/dev/windows/src/org/eclipse/swt/internal/ole/win32/COM.java
index a1df554..9a159d5 100644
--- a/dev/windows/src/org/eclipse/swt/internal/ole/win32/COM.java
+++ b/dev/windows/src/org/eclipse/swt/internal/ole/win32/COM.java
@@ -65,6 +65,7 @@
 	//public static final GUID IIDIMarshal = IIDFromString("{00000003-0000-0000-C000-000000000046}"); //$NON-NLS-1$
 	//public static final GUID IIDIMessageFilter = IIDFromString("{00000016-0000-0000-C000-000000000046}"); //$NON-NLS-1$
 	//public static final GUID IIDIMoniker = IIDFromString("{0000000F-0000-0000-C000-000000000046}"); //$NON-NLS-1$
+    public static final GUID IIDIObjectWithSite = IIDFromString("{FC4801A3-2BA9-11CF-A229-00AA003D7352}"); //$NON-NLS-1$ // GOOGLE
 	//public static final GUID IIDIOleAdviseHolder = IIDFromString("{00000111-0000-0000-C000-000000000046}"); //$NON-NLS-1$
 	//public static final GUID IIDIOleCache = IIDFromString("{0000011E-0000-0000-C000-000000000046}"); //$NON-NLS-1$
 	//public static final GUID IIDIOleCache2 = IIDFromString("{00000128-0000-0000-C000-000000000046}"); //$NON-NLS-1$
diff --git a/dev/windows/src/org/eclipse/swt/internal/ole/win32/IObjectWithSite.java b/dev/windows/src/org/eclipse/swt/internal/ole/win32/IObjectWithSite.java
new file mode 100644
index 0000000..90beaec
--- /dev/null
+++ b/dev/windows/src/org/eclipse/swt/internal/ole/win32/IObjectWithSite.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2007 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.eclipse.swt.internal.ole.win32;
+
+/**
+ * Provide the interface IObjectWithSite, a lighter-weight siting mechanism
+ * than IOleObject.
+ * 
+ * This interface is used by IE Browser Helper Objects, such as Google Gears.
+ * See http://msdn2.microsoft.com/en-us/library/aa768220.aspx
+ */
+public class IObjectWithSite extends IUnknown {
+  public IObjectWithSite(int address) {
+    super(address);
+  }
+  
+  /**
+   * Return the last site set with SetSite.
+   * 
+   * @param riid IID of the interface to be returned
+   * @param ppvObject return value of the IObjectWithSite interface
+   * @return COM.S_OK on success, COM.E_FAIL if no site has been set, or
+   *     COM.E_NOINTERFACE if the requested interface is not supported
+   */
+  public int GetSite(GUID riid, int ppvObject[]) {
+    return COM.VtblCall(4, address, riid, ppvObject);
+  }
+  
+  /**
+   * Sets the IUnknown interface of the site managing this object.
+   * 
+   * @param site an IUnknown interface to the browser object
+   * @return COM.S_OK always
+   */
+  public int SetSite(IUnknown site) {
+    return COM.VtblCall(3, address, site.getAddress());
+  }
+}
