[SCM] Debian packaging for swt-gtk. branch, upstream, updated. upstream/3.5.1-1-g8eb5aea

Ahmed El-Mahmoudy aelmahmoudy-guest at alioth.debian.org
Fri Oct 8 14:42:46 UTC 2010


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Debian packaging for swt-gtk.".

The branch, upstream has been updated
       via  8eb5aea09bd465d50f43d9c2d73177bfef42a1e3 (commit)
      from  a0edaa509c59af296334bec1182c39d2f7c3670a (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 8eb5aea09bd465d50f43d9c2d73177bfef42a1e3
Author: أحمد المحمودي (Ahmed El-Mahmoudy) <aelmahmoudy at sabily.org>
Date:   Fri Oct 8 16:19:19 2010 +0200

    Imported Upstream version 3.6.1

-----------------------------------------------------------------------

Summary of changes:
 about.html                                         |   44 +-
 about_files/webkit-bsd.txt                         |   20 +
 atk.c                                              |  503 +++-
 atk.h                                              |   10 +-
 atk_stats.c                                        |   78 +-
 atk_stats.h                                        |   74 +-
 atk_structs.c                                      |  311 ++-
 atk_structs.h                                      |   62 +-
 build.sh                                           |   33 +-
 build.xml                                          |   65 -
 callback.c                                         |  544 +++-
 callback.h                                         |    8 +-
 gnome.c                                            |   46 +-
 gnome_stats.c                                      |    9 +-
 gnome_stats.h                                      |    5 +-
 make_common.mak                                    |    6 +-
 make_freebsd.mak                                   |   40 +-
 make_linux.mak                                     |   67 +-
 make_solaris.mak                                   |   34 +-
 make_solaris_x86.mak                               |   38 +-
 org/eclipse/swt/SWT.java                           |  213 +-
 org/eclipse/swt/accessibility/ACC.java             |  681 ++++-
 org/eclipse/swt/accessibility/Accessible.java      |  586 +++-
 .../swt/accessibility/AccessibleActionAdapter.java |   94 +
 .../swt/accessibility/AccessibleActionEvent.java   |   59 +
 .../accessibility/AccessibleActionListener.java    |   97 +
 .../accessibility/AccessibleAttributeAdapter.java  |   62 +
 .../accessibility/AccessibleAttributeEvent.java    |   65 +
 .../accessibility/AccessibleAttributeListener.java |   65 +
 .../accessibility/AccessibleControlAdapter.java    |   39 +-
 .../accessibility/AccessibleControlListener.java   |   35 +-
 .../swt/accessibility/AccessibleFactory.java       |  471 ++-
 .../accessibility/AccessibleHyperlinkAdapter.java  |   84 +
 .../accessibility/AccessibleHyperlinkEvent.java    |   60 +
 .../accessibility/AccessibleHyperlinkListener.java |   87 +
 .../swt/accessibility/AccessibleObject.java        | 4150 +++++++++++++++-----
 .../swt/accessibility/AccessibleTableAdapter.java  |  341 ++
 .../accessibility/AccessibleTableCellAdapter.java  |  111 +
 .../accessibility/AccessibleTableCellEvent.java    |   57 +
 .../accessibility/AccessibleTableCellListener.java |  114 +
 .../swt/accessibility/AccessibleTableEvent.java    |   70 +
 .../swt/accessibility/AccessibleTableListener.java |  344 ++
 .../AccessibleTextAttributeEvent.java              |   57 +
 .../swt/accessibility/AccessibleTextEvent.java     |   27 +-
 .../AccessibleTextExtendedAdapter.java             |  292 ++
 .../AccessibleTextExtendedListener.java            |  293 ++
 .../swt/accessibility/AccessibleValueAdapter.java  |   71 +
 .../swt/accessibility/AccessibleValueEvent.java    |   50 +
 .../swt/accessibility/AccessibleValueListener.java |   74 +
 org/eclipse/swt/browser/AppFileLocProvider.java    |   48 +-
 org/eclipse/swt/browser/Browser.java               |  168 +-
 org/eclipse/swt/browser/Download.java              |    6 +-
 org/eclipse/swt/browser/Download_1_8.java          |    6 +-
 org/eclipse/swt/browser/External.java              |    7 +-
 org/eclipse/swt/browser/InputStream.java           |    7 +-
 org/eclipse/swt/browser/Mozilla.java               | 2555 ++++++++-----
 org/eclipse/swt/browser/MozillaDelegate.java       |   15 +-
 org/eclipse/swt/browser/PromptDialog.java          |    4 +-
 org/eclipse/swt/browser/PromptService2.java        |   30 +-
 org/eclipse/swt/browser/WebBrowser.java            |  125 +-
 org/eclipse/swt/browser/WebKit.java                | 1861 +++++++++
 org/eclipse/swt/browser/WindowCreator2.java        |    8 +-
 org/eclipse/swt/browser/WindowEvent.java           |    2 +-
 org/eclipse/swt/custom/BidiSegmentEvent.java       |   31 +-
 org/eclipse/swt/custom/CCombo.java                 |  179 +-
 org/eclipse/swt/custom/CLabel.java                 |  223 +-
 org/eclipse/swt/custom/CTabFolder.java             | 1366 ++-----
 org/eclipse/swt/custom/CTabFolderLayout.java       |   22 +-
 org/eclipse/swt/custom/CTabFolderRenderer.java     | 1755 +++++++++
 org/eclipse/swt/custom/CTabItem.java               |  653 +---
 org/eclipse/swt/custom/LineStyleEvent.java         |   18 +-
 org/eclipse/swt/custom/StackLayout.java            |    3 +-
 org/eclipse/swt/custom/StyledText.java             |  897 ++++-
 org/eclipse/swt/custom/StyledTextEvent.java        |    5 +-
 org/eclipse/swt/custom/StyledTextListener.java     |    5 +-
 org/eclipse/swt/custom/StyledTextRenderer.java     |   85 +-
 org/eclipse/swt/custom/ViewFormLayout.java         |    5 +-
 org/eclipse/swt/dnd/ClipboardProxy.java            |   21 +-
 org/eclipse/swt/dnd/DND.java                       |   11 +-
 org/eclipse/swt/dnd/DropTargetListener.java        |    8 +-
 org/eclipse/swt/dnd/ImageTransfer.java             |    5 +-
 org/eclipse/swt/dnd/TableDropTargetEffect.java     |   12 +-
 org/eclipse/swt/dnd/TextTransfer.java              |    6 +
 org/eclipse/swt/dnd/TransferData.java              |   12 +-
 org/eclipse/swt/events/KeyEvent.java               |   37 +-
 org/eclipse/swt/events/MouseEvent.java             |    5 +-
 org/eclipse/swt/graphics/Color.java                |    6 +-
 org/eclipse/swt/graphics/Cursor.java               |   10 +-
 org/eclipse/swt/graphics/Device.java               |   10 +-
 org/eclipse/swt/graphics/DeviceData.java           |   46 +-
 org/eclipse/swt/graphics/Drawable.java             |    6 +-
 org/eclipse/swt/graphics/Font.java                 |    6 +-
 org/eclipse/swt/graphics/FontData.java             |   10 +-
 org/eclipse/swt/graphics/GC.java                   |   75 +-
 org/eclipse/swt/graphics/Image.java                |   65 +-
 org/eclipse/swt/graphics/ImageData.java            |    6 +-
 org/eclipse/swt/graphics/Path.java                 |    4 +-
 org/eclipse/swt/graphics/Pattern.java              |    4 +-
 org/eclipse/swt/graphics/Region.java               |    4 +-
 org/eclipse/swt/graphics/Resource.java             |    5 +-
 org/eclipse/swt/graphics/TextLayout.java           |  293 +-
 org/eclipse/swt/graphics/Transform.java            |    4 +-
 org/eclipse/swt/internal/Compatibility.java        |   28 +-
 org/eclipse/swt/internal/Library.java              |   69 +-
 org/eclipse/swt/internal/SWTMessages.properties    |   23 +-
 org/eclipse/swt/internal/SWTMessages_ar.properties |   25 +
 org/eclipse/swt/internal/SWTMessages_cs.properties |   29 +
 org/eclipse/swt/internal/SWTMessages_da.properties |   25 +
 org/eclipse/swt/internal/SWTMessages_de.properties |   65 +
 org/eclipse/swt/internal/SWTMessages_el.properties |   25 +
 org/eclipse/swt/internal/SWTMessages_es.properties |   66 +
 org/eclipse/swt/internal/SWTMessages_et.properties |   23 +
 org/eclipse/swt/internal/SWTMessages_fi.properties |   25 +
 org/eclipse/swt/internal/SWTMessages_fr.properties |   65 +
 org/eclipse/swt/internal/SWTMessages_hu.properties |   25 +
 org/eclipse/swt/internal/SWTMessages_it.properties |   63 +
 org/eclipse/swt/internal/SWTMessages_iw.properties |   21 +
 org/eclipse/swt/internal/SWTMessages_ja.properties |   65 +
 org/eclipse/swt/internal/SWTMessages_ko.properties |   65 +
 org/eclipse/swt/internal/SWTMessages_mn.properties |    2 +
 org/eclipse/swt/internal/SWTMessages_nl.properties |   25 +
 org/eclipse/swt/internal/SWTMessages_no.properties |   25 +
 org/eclipse/swt/internal/SWTMessages_pl.properties |   42 +
 org/eclipse/swt/internal/SWTMessages_pt.properties |   64 +
 .../swt/internal/SWTMessages_pt_BR.properties      |   25 +
 org/eclipse/swt/internal/SWTMessages_ro.properties |    5 +
 org/eclipse/swt/internal/SWTMessages_ru.properties |   30 +
 org/eclipse/swt/internal/SWTMessages_sv.properties |   25 +
 org/eclipse/swt/internal/SWTMessages_tr.properties |   66 +
 org/eclipse/swt/internal/SWTMessages_uk.properties |   66 +
 org/eclipse/swt/internal/SWTMessages_zh.properties |   65 +
 .../swt/internal/SWTMessages_zh_TW.properties      |   64 +
 .../swt/internal/accessibility/gtk/ATK.java        |  253 ++-
 .../internal/accessibility/gtk/AtkAttribute.java   |   25 +
 .../internal/accessibility/gtk/AtkObjectClass.java |    4 +-
 .../internal/accessibility/gtk/AtkTableIface.java  |   91 +
 .../internal/accessibility/gtk/AtkTextIface.java   |    6 +-
 .../internal/accessibility/gtk/AtkTextRange.java   |   27 +
 .../accessibility/gtk/AtkTextRectangle.java        |   25 +
 .../internal/accessibility/gtk/AtkValueIface.java  |   27 +
 org/eclipse/swt/internal/gnome/GNOME.java          |   39 +-
 org/eclipse/swt/internal/gtk/GdkEventMotion.java   |   84 +-
 org/eclipse/swt/internal/gtk/GdkEventProperty.java |   29 +
 org/eclipse/swt/internal/gtk/OS.java               |  729 ++++-
 org/eclipse/swt/internal/gtk/XButtonEvent.java     |   26 -
 org/eclipse/swt/internal/image/PNGFileFormat.java  |   22 +-
 org/eclipse/swt/internal/image/PngEncoder.java     |   30 +-
 .../swt/internal/image/PngLzBlockReader.java       |   17 +-
 org/eclipse/swt/internal/image/TIFFDirectory.java  |   60 +-
 org/eclipse/swt/internal/image/TIFFFileFormat.java |   18 +-
 .../swt/internal/image/WinBMPFileFormat.java       |  125 +-
 org/eclipse/swt/internal/mozilla/XPCOM.java        |   19 +-
 .../swt/internal/mozilla/nsICookieService.java     |  127 +-
 .../swt/internal/mozilla/nsICookieService_1_9.java |  118 +-
 org/eclipse/swt/internal/mozilla/nsID.java         |   72 +-
 org/eclipse/swt/internal/mozilla/nsIDataType.java  |   28 +-
 .../swt/internal/mozilla/nsIMIMEInputStream.java   |   59 +
 .../mozilla/nsISecurityCheckedComponent.java       |   28 +-
 .../swt/internal/mozilla/nsIWritableVariant.java   |   28 +-
 .../swt/internal/webkit/JSClassDefinition.java     |   54 +
 org/eclipse/swt/internal/webkit/WebKitGTK.java     | 1368 +++++++
 org/eclipse/swt/layout/GridData.java               |   14 +-
 org/eclipse/swt/printing/PrintDialog.java          |    9 +-
 org/eclipse/swt/printing/Printer.java              |   13 +-
 org/eclipse/swt/printing/PrinterData.java          |    6 +-
 org/eclipse/swt/program/Program.java               |  413 ++-
 org/eclipse/swt/widgets/Button.java                |   10 +-
 org/eclipse/swt/widgets/Canvas.java                |   13 +-
 org/eclipse/swt/widgets/ColorDialog.java           |    6 +-
 org/eclipse/swt/widgets/Combo.java                 |  130 +-
 org/eclipse/swt/widgets/Composite.java             |  196 +-
 org/eclipse/swt/widgets/Control.java               |  393 ++-
 org/eclipse/swt/widgets/CoolBar.java               |   13 +
 org/eclipse/swt/widgets/CoolItem.java              |    3 +-
 org/eclipse/swt/widgets/DateTime.java              |   10 +-
 org/eclipse/swt/widgets/Decorations.java           |   17 +-
 org/eclipse/swt/widgets/DirectoryDialog.java       |    6 +-
 org/eclipse/swt/widgets/Display.java               |  277 ++-
 org/eclipse/swt/widgets/Event.java                 |   36 +-
 org/eclipse/swt/widgets/ExpandBar.java             |   11 +
 org/eclipse/swt/widgets/FileDialog.java            |   31 +-
 org/eclipse/swt/widgets/FontDialog.java            |    6 +-
 org/eclipse/swt/widgets/Label.java                 |   10 +-
 org/eclipse/swt/widgets/Link.java                  |   48 +-
 org/eclipse/swt/widgets/List.java                  |    6 +-
 org/eclipse/swt/widgets/Menu.java                  |    9 +
 org/eclipse/swt/widgets/MenuItem.java              |   37 +-
 org/eclipse/swt/widgets/MessageBox.java            |   12 +-
 org/eclipse/swt/widgets/Sash.java                  |    8 +-
 org/eclipse/swt/widgets/Scale.java                 |    2 +-
 org/eclipse/swt/widgets/ScrollBar.java             |  121 +-
 org/eclipse/swt/widgets/Scrollable.java            |    6 +
 org/eclipse/swt/widgets/Shell.java                 |  254 ++-
 org/eclipse/swt/widgets/Slider.java                |   18 +-
 org/eclipse/swt/widgets/Spinner.java               |   36 +-
 org/eclipse/swt/widgets/TabFolder.java             |   23 +-
 org/eclipse/swt/widgets/Table.java                 |  150 +-
 org/eclipse/swt/widgets/TableColumn.java           |   31 +-
 org/eclipse/swt/widgets/TableItem.java             |    6 +-
 org/eclipse/swt/widgets/TaskBar.java               |  181 +
 org/eclipse/swt/widgets/TaskItem.java              |  372 ++
 org/eclipse/swt/widgets/Text.java                  |   59 +-
 org/eclipse/swt/widgets/ToolBar.java               |   13 +-
 org/eclipse/swt/widgets/ToolItem.java              |   21 +-
 org/eclipse/swt/widgets/ToolTip.java               |    9 +-
 org/eclipse/swt/widgets/Tracker.java               |    1 +
 org/eclipse/swt/widgets/Tray.java                  |   11 +
 org/eclipse/swt/widgets/TrayItem.java              |    8 +-
 org/eclipse/swt/widgets/Tree.java                  |  153 +-
 org/eclipse/swt/widgets/TreeColumn.java            |   31 +-
 org/eclipse/swt/widgets/TreeItem.java              |    8 +-
 org/eclipse/swt/widgets/TypedListener.java         |    8 +-
 org/eclipse/swt/widgets/Widget.java                |  178 +-
 os.c                                               | 1442 +++++++-
 os.h                                               |    3 +-
 os_custom.c                                        |   19 +
 os_custom.h                                        |   47 +-
 os_stats.c                                         |  111 +-
 os_stats.h                                         |  107 +-
 os_structs.c                                       |  109 +-
 os_structs.h                                       |   26 +-
 swt_xpcom.rc                                       |    2 +-
 version.txt                                        |    2 +-
 webkitgtk.c                                        | 1232 ++++++
 webkitgtk.h                                        |   34 +
 webkitgtk_stats.c                                  |  143 +
 webkitgtk_stats.h                                  |  129 +
 webkitgtk_structs.c                                |   97 +
 webkitgtk_structs.h                                |   29 +
 xpcom_custom.cpp                                   |   44 +-
 xpcom_custom.h                                     |    1 +
 xpcom_stats.cpp                                    |    4 +-
 xpcom_stats.h                                      |    4 +-
 233 files changed, 27741 insertions(+), 5542 deletions(-)

diff --git a/about.html b/about.html
index ea2d22d..6c5fbd8 100644
--- a/about.html
+++ b/about.html
@@ -70,8 +70,7 @@ work is provided for debugging purposes so there is no need to reverse engineer
 <ul>
 	<li>The contents of the directory org/eclipse/swt/internal/accessibility/gtk (but not including any sub-directories)</li>
 	<li>The contents of the directory org/eclipse/swt/internal/cde (but not including any sub-directories)</li>
-	<li>The contents of the directory org/eclipse/swt/internal/gtk (but not including any sub-directories)</li>
-	<li>The contents of the directory org/eclipse/swt/internal/kde (but not including any sub-directories)</li>				
+	<li>The contents of the directory org/eclipse/swt/internal/gtk (but not including any sub-directories)</li>				
 </ul>
 
 <p>The GTK+ Binding contains portions of GTK+ (&quot;Library&quot;).  GTK+ is made available by The Free Software Foundation.  Use of the Library is governed by the terms and
@@ -85,6 +84,45 @@ other terms and conditions of Section 6 as well as other Sections of the LGPL.
 governed by the terms and conditions of the LGPL.  Also note, the terms of the EPL permit you to modify the combined work and the source code of the combined
 work is provided for debugging purposes so there is no need to reverse engineer the combined work.</p>
 
+<h4>WebKitGTK+ Binding</h4>
+
+<p>The &quot;WebKitGTK+ Binding&quot; is a binding to the WebKitGTK+ API. The Content may include any or all of the following files:</p>
+
+<p>The following files in the plug-in JAR shall be defined as the native code portion of the WebKitGTK+ Binding:</p>
+
+<ul>
+    <li>libswt-webkit-gtk-xxxx.so (where &quot;xxxx&quot; is the version number)</li>
+</ul>
+
+<p>The following files in both the plug-in JAR and the src.zip shall be defined respectively as the bytecode and source code portions of the WebKitGTK+ Binding:</p>
+<ul>
+    <li>The contents of the directory org/eclipse/swt/internal/webkit (but not including any sub-directories)</li>
+</ul>
+
+<p>
+The WebKitGTK+ Binding contains portions of WebKitGTK+ (&quot;Library&quot;). WebKitGTK+ is made available by the WebKitGTK+ open source project (<a href="http://webkitgtk.org/" target="_blank">http://webkit.org/</a>). Use of the Library is governed by the terms and conditions of the GNU Lesser General Public License Version 2.1 (&quot;LGPL&quot;). Use of the WebKitGTK+ Binding on a standalone basis, is also governed by the terms and conditions of the LGPL. A copy of the LGPL is provided with the Content (<a href="about_files/lgpl-v21.txt" target="_blank">lgpl-v21.txt</a>) and is also available at <a href="http://www.gnu.org/licenses/lgpl.html" target="_blank">http://www.gnu.org/licenses/lgpl.html</a>. </p>
+
+<p>
+In accordance with Section 6 of the LGPL, you may combine or link a &quot;work that uses the Library&quot; (e.g. the SWT) with the Library to produce a work containing portions of the Library (e.g. the WebKitGTK+ Binding) and distribute that work under the terms of your choice (e.g. the EPL) provided you comply with all other terms and conditions of Section 6 as well as other Sections of the LGPL. Please note, if you modify the WebKitGTK+ Binding such modifications shall be governed by the terms and conditions of the LGPL. Also note, the terms of the EPL permit you to modify the combined work and the source code of the combined work is provided for debugging purposes so there is no need to reverse engineer the combined work.<p>
+
+<p>The WebKitGTK+ Binding also contains portions of the WebKit JavaScriptCore code which is made available by the WebKit open source project (<a href="http://webkit.org/" target="_blank">http://webkit.org/</a>).  The WebKit JavaScriptCore code was obtained under the terms of the BSD license.  A copy of the BSD license is provided (<a href="about_files/webkit-bsd.txt"target="_blank">webkit-bsd.txt</a>) and is also available at <a href="http://webkit.org/coding/bsd-license.html" target="_blank">http://webkit.org/coding/bsd-license.html</a>. </p>
+
+<h4>libsoup</h4>
+
+<p>The &quot;WebKitGTK+ Binding&quot; also includes a binding to the libsoup API. The Content may include any or all of the following files:</p>
+
+<p>The following files in the plug-in JAR shall be defined as the native code portion of the WebKitGTK+ Binding:</p>
+<ul>
+    <li>libswt-webkit-gtk-xxxx.so (where &quot;xxxx&quot; is the version number)</li>
+</ul>
+
+<p>The following files in both the plug-in JAR and the src.zip shall be defined respectively as the bytecode and source code portions of the WebKitGTK+ Binding:</p>
+<ul>
+    <li>The contents of the directory org/eclipse/swt/internal/webkit (but not including any sub-directories)</li>
+</ul>
+
+<p>The WebKitGTK+ Binding contains portions of libsoup (&quot;Library&quot;). libsoup is made available by The GNOME Project (<a href="http://live.gnome.org/LibSoup" target="_blank">http://live.gnome.org/LibSoup/</a>). Use of the Library is governed by the terms and conditions of the GNU Lesser General Public License Version 2.1 (&quot;LGPL&quot;). Use of the WebKitGTK+ Binding on a standalone basis, is also governed by the terms and conditions of the LGPL. A copy of the LGPL is provided with the Content (<a href="about_files/lgpl-v21.txt" target="_blank">lgpl-v21.txt</a>) and is also available at <a href="http://www.gnu.org/licenses/lgpl.html" target="_blank">http://www.gnu.org/licenses/lgpl.html</a>. </p>
+
 <h4>Mozilla Binding</h4>
 
 <p>The &quot;Mozilla Binding&quot; is a binding to the Mozilla API.  The Content may include any or all of the following files:</p>
@@ -108,7 +146,7 @@ conditions of the Mozilla Public License Version 1.1 (&quot;MPL&quot;).  A copy
 
 <h4>XULRunner 1.9 (subset, derivative work)</h4>
 
-The libraries swt-xulrunner-gtk-xxxx.dll, swt-mozilla-gtk-xxxx.dll, and swt-mozilla-gcc3-gtk-xxxx.dll (where &quot;xxxx&quot; is the version number) contain a small portion of XULRunner 1.9 content (header files)
+The libraries libswt-xulrunner-gtk-xxxx.so, libswt-mozilla-gtk-xxxx.so, and libswt-mozilla-gcc3-gtk-xxxx.so (where &quot;xxxx&quot; is the version number) contain a small portion of XULRunner 1.9 content (header files)
 that have been modified from the Original Code provided by mozilla.org, and whose Initial Developer is Netscape Communications Corporation. Use of this code is governed by
 the terms and conditions of the Mozilla Public License Version 1.1 ("MPL").  A copy of the MPL is provided with the Content (<a href="./about_files/mpl-v11.txt">mpl-v11.txt</a>)
 and is also available at <a href="http://www.mozilla.org/MPL/MPL-1.1.html">http://www.mozilla.org/MPL/MPL-1.1.html</a>.
diff --git a/about_files/webkit-bsd.txt b/about_files/webkit-bsd.txt
new file mode 100644
index 0000000..b3b07c6
--- /dev/null
+++ b/about_files/webkit-bsd.txt
@@ -0,0 +1,20 @@
+BSD License
+
+Copyright (C) 2009 Apple Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided
+that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this list of conditions and
+the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
+the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/atk.c b/atk.c
index b663012..3b25002 100644
--- a/atk.c
+++ b/atk.c
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others. All rights reserved.
+ * Copyright (c) 2000, 2010 IBM Corporation and others. All rights reserved.
  * The contents of this file are made available under the terms
  * of the GNU Lesser General Public License (LGPL) Version 2.1 that
  * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
@@ -19,6 +19,126 @@
 
 #define ATK_NATIVE(func) Java_org_eclipse_swt_internal_accessibility_gtk_ATK_##func
 
+#ifndef NO_ATK_1IS_1NO_1OP_1OBJECT_1FACTORY
+JNIEXPORT jboolean JNICALL ATK_NATIVE(ATK_1IS_1NO_1OP_1OBJECT_1FACTORY)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jboolean rc = 0;
+	ATK_NATIVE_ENTER(env, that, ATK_1IS_1NO_1OP_1OBJECT_1FACTORY_FUNC);
+	rc = (jboolean)ATK_IS_NO_OP_OBJECT_FACTORY(arg0);
+	ATK_NATIVE_EXIT(env, that, ATK_1IS_1NO_1OP_1OBJECT_1FACTORY_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO_ATK_1TYPE_1ACTION
+JNIEXPORT jintLong JNICALL ATK_NATIVE(ATK_1TYPE_1ACTION)
+	(JNIEnv *env, jclass that)
+{
+	jintLong rc = 0;
+	ATK_NATIVE_ENTER(env, that, ATK_1TYPE_1ACTION_FUNC);
+	rc = (jintLong)ATK_TYPE_ACTION;
+	ATK_NATIVE_EXIT(env, that, ATK_1TYPE_1ACTION_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO_ATK_1TYPE_1COMPONENT
+JNIEXPORT jintLong JNICALL ATK_NATIVE(ATK_1TYPE_1COMPONENT)
+	(JNIEnv *env, jclass that)
+{
+	jintLong rc = 0;
+	ATK_NATIVE_ENTER(env, that, ATK_1TYPE_1COMPONENT_FUNC);
+	rc = (jintLong)ATK_TYPE_COMPONENT;
+	ATK_NATIVE_EXIT(env, that, ATK_1TYPE_1COMPONENT_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO_ATK_1TYPE_1HYPERTEXT
+JNIEXPORT jintLong JNICALL ATK_NATIVE(ATK_1TYPE_1HYPERTEXT)
+	(JNIEnv *env, jclass that)
+{
+	jintLong rc = 0;
+	ATK_NATIVE_ENTER(env, that, ATK_1TYPE_1HYPERTEXT_FUNC);
+	rc = (jintLong)ATK_TYPE_HYPERTEXT;
+	ATK_NATIVE_EXIT(env, that, ATK_1TYPE_1HYPERTEXT_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO_ATK_1TYPE_1OBJECT_1FACTORY
+JNIEXPORT jintLong JNICALL ATK_NATIVE(ATK_1TYPE_1OBJECT_1FACTORY)
+	(JNIEnv *env, jclass that)
+{
+	jintLong rc = 0;
+	ATK_NATIVE_ENTER(env, that, ATK_1TYPE_1OBJECT_1FACTORY_FUNC);
+	rc = (jintLong)ATK_TYPE_OBJECT_FACTORY;
+	ATK_NATIVE_EXIT(env, that, ATK_1TYPE_1OBJECT_1FACTORY_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO_ATK_1TYPE_1SELECTION
+JNIEXPORT jintLong JNICALL ATK_NATIVE(ATK_1TYPE_1SELECTION)
+	(JNIEnv *env, jclass that)
+{
+	jintLong rc = 0;
+	ATK_NATIVE_ENTER(env, that, ATK_1TYPE_1SELECTION_FUNC);
+	rc = (jintLong)ATK_TYPE_SELECTION;
+	ATK_NATIVE_EXIT(env, that, ATK_1TYPE_1SELECTION_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO_ATK_1TYPE_1TABLE
+JNIEXPORT jintLong JNICALL ATK_NATIVE(ATK_1TYPE_1TABLE)
+	(JNIEnv *env, jclass that)
+{
+	jintLong rc = 0;
+	ATK_NATIVE_ENTER(env, that, ATK_1TYPE_1TABLE_FUNC);
+	rc = (jintLong)ATK_TYPE_TABLE;
+	ATK_NATIVE_EXIT(env, that, ATK_1TYPE_1TABLE_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO_ATK_1TYPE_1TEXT
+JNIEXPORT jintLong JNICALL ATK_NATIVE(ATK_1TYPE_1TEXT)
+	(JNIEnv *env, jclass that)
+{
+	jintLong rc = 0;
+	ATK_NATIVE_ENTER(env, that, ATK_1TYPE_1TEXT_FUNC);
+	rc = (jintLong)ATK_TYPE_TEXT;
+	ATK_NATIVE_EXIT(env, that, ATK_1TYPE_1TEXT_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO_ATK_1TYPE_1VALUE
+JNIEXPORT jintLong JNICALL ATK_NATIVE(ATK_1TYPE_1VALUE)
+	(JNIEnv *env, jclass that)
+{
+	jintLong rc = 0;
+	ATK_NATIVE_ENTER(env, that, ATK_1TYPE_1VALUE_FUNC);
+	rc = (jintLong)ATK_TYPE_VALUE;
+	ATK_NATIVE_EXIT(env, that, ATK_1TYPE_1VALUE_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO_AtkAttribute_1sizeof
+JNIEXPORT jint JNICALL ATK_NATIVE(AtkAttribute_1sizeof)
+	(JNIEnv *env, jclass that)
+{
+	jint rc = 0;
+	ATK_NATIVE_ENTER(env, that, AtkAttribute_1sizeof_FUNC);
+	rc = (jint)AtkAttribute_sizeof();
+	ATK_NATIVE_EXIT(env, that, AtkAttribute_1sizeof_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO_AtkObjectFactoryClass_1sizeof
 JNIEXPORT jint JNICALL ATK_NATIVE(AtkObjectFactoryClass_1sizeof)
 	(JNIEnv *env, jclass that)
@@ -43,6 +163,42 @@ JNIEXPORT jint JNICALL ATK_NATIVE(AtkObjectFactory_1sizeof)
 }
 #endif
 
+#ifndef NO_AtkTextRange_1sizeof
+JNIEXPORT jint JNICALL ATK_NATIVE(AtkTextRange_1sizeof)
+	(JNIEnv *env, jclass that)
+{
+	jint rc = 0;
+	ATK_NATIVE_ENTER(env, that, AtkTextRange_1sizeof_FUNC);
+	rc = (jint)AtkTextRange_sizeof();
+	ATK_NATIVE_EXIT(env, that, AtkTextRange_1sizeof_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO_AtkTextRectangle_1sizeof
+JNIEXPORT jint JNICALL ATK_NATIVE(AtkTextRectangle_1sizeof)
+	(JNIEnv *env, jclass that)
+{
+	jint rc = 0;
+	ATK_NATIVE_ENTER(env, that, AtkTextRectangle_1sizeof_FUNC);
+	rc = (jint)AtkTextRectangle_sizeof();
+	ATK_NATIVE_EXIT(env, that, AtkTextRectangle_1sizeof_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO_GTK_1TYPE_1ACCESSIBLE
+JNIEXPORT jintLong JNICALL ATK_NATIVE(GTK_1TYPE_1ACCESSIBLE)
+	(JNIEnv *env, jclass that)
+{
+	jintLong rc = 0;
+	ATK_NATIVE_ENTER(env, that, GTK_1TYPE_1ACCESSIBLE_FUNC);
+	rc = (jintLong)GTK_TYPE_ACCESSIBLE;
+	ATK_NATIVE_EXIT(env, that, GTK_1TYPE_1ACCESSIBLE_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO__1ATK_1ACTION_1GET_1IFACE
 JNIEXPORT jintLong JNICALL ATK_NATIVE(_1ATK_1ACTION_1GET_1IFACE)
 	(JNIEnv *env, jclass that, jintLong arg0)
@@ -67,6 +223,18 @@ JNIEXPORT jintLong JNICALL ATK_NATIVE(_1ATK_1COMPONENT_1GET_1IFACE)
 }
 #endif
 
+#ifndef NO__1ATK_1HYPERTEXT_1GET_1IFACE
+JNIEXPORT jintLong JNICALL ATK_NATIVE(_1ATK_1HYPERTEXT_1GET_1IFACE)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	ATK_NATIVE_ENTER(env, that, _1ATK_1HYPERTEXT_1GET_1IFACE_FUNC);
+	rc = (jintLong)ATK_HYPERTEXT_GET_IFACE(arg0);
+	ATK_NATIVE_EXIT(env, that, _1ATK_1HYPERTEXT_1GET_1IFACE_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO__1ATK_1OBJECT_1FACTORY_1CLASS
 JNIEXPORT jintLong JNICALL ATK_NATIVE(_1ATK_1OBJECT_1FACTORY_1CLASS)
 	(JNIEnv *env, jclass that, jintLong arg0)
@@ -91,6 +259,18 @@ JNIEXPORT jintLong JNICALL ATK_NATIVE(_1ATK_1SELECTION_1GET_1IFACE)
 }
 #endif
 
+#ifndef NO__1ATK_1TABLE_1GET_1IFACE
+JNIEXPORT jintLong JNICALL ATK_NATIVE(_1ATK_1TABLE_1GET_1IFACE)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	ATK_NATIVE_ENTER(env, that, _1ATK_1TABLE_1GET_1IFACE_FUNC);
+	rc = (jintLong)ATK_TABLE_GET_IFACE(arg0);
+	ATK_NATIVE_EXIT(env, that, _1ATK_1TABLE_1GET_1IFACE_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO__1ATK_1TEXT_1GET_1IFACE
 JNIEXPORT jintLong JNICALL ATK_NATIVE(_1ATK_1TEXT_1GET_1IFACE)
 	(JNIEnv *env, jclass that, jintLong arg0)
@@ -103,6 +283,18 @@ JNIEXPORT jintLong JNICALL ATK_NATIVE(_1ATK_1TEXT_1GET_1IFACE)
 }
 #endif
 
+#ifndef NO__1ATK_1VALUE_1GET_1IFACE
+JNIEXPORT jintLong JNICALL ATK_NATIVE(_1ATK_1VALUE_1GET_1IFACE)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	ATK_NATIVE_ENTER(env, that, _1ATK_1VALUE_1GET_1IFACE_FUNC);
+	rc = (jintLong)ATK_VALUE_GET_IFACE(arg0);
+	ATK_NATIVE_EXIT(env, that, _1ATK_1VALUE_1GET_1IFACE_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO__1GTK_1ACCESSIBLE
 JNIEXPORT jintLong JNICALL ATK_NATIVE(_1GTK_1ACCESSIBLE)
 	(JNIEnv *env, jclass that, jintLong arg0)
@@ -171,6 +363,16 @@ JNIEXPORT void JNICALL ATK_NATIVE(_1atk_1object_1initialize)
 }
 #endif
 
+#ifndef NO__1atk_1object_1notify_1state_1change
+JNIEXPORT void JNICALL ATK_NATIVE(_1atk_1object_1notify_1state_1change)
+	(JNIEnv *env, jclass that, jintLong arg0, jint arg1, jboolean arg2)
+{
+	ATK_NATIVE_ENTER(env, that, _1atk_1object_1notify_1state_1change_FUNC);
+	atk_object_notify_state_change((AtkObject *)arg0, arg1, arg2);
+	ATK_NATIVE_EXIT(env, that, _1atk_1object_1notify_1state_1change_FUNC);
+}
+#endif
+
 #ifndef NO__1atk_1object_1ref_1relation_1set
 JNIEXPORT jintLong JNICALL ATK_NATIVE(_1atk_1object_1ref_1relation_1set)
 	(JNIEnv *env, jclass that, jintLong arg0)
@@ -239,6 +441,22 @@ JNIEXPORT void JNICALL ATK_NATIVE(_1atk_1relation_1set_1remove)
 }
 #endif
 
+#ifndef NO__1atk_1role_1register
+JNIEXPORT jint JNICALL ATK_NATIVE(_1atk_1role_1register)
+	(JNIEnv *env, jclass that, jbyteArray arg0)
+{
+	jbyte *lparg0=NULL;
+	jint rc = 0;
+	ATK_NATIVE_ENTER(env, that, _1atk_1role_1register_FUNC);
+	if (arg0) if ((lparg0 = (*env)->GetByteArrayElements(env, arg0, NULL)) == NULL) goto fail;
+	rc = (jint)atk_role_register((const gchar *)lparg0);
+fail:
+	if (arg0 && lparg0) (*env)->ReleaseByteArrayElements(env, arg0, lparg0, 0);
+	ATK_NATIVE_EXIT(env, that, _1atk_1role_1register_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO__1atk_1state_1set_1add_1state
 JNIEXPORT jboolean JNICALL ATK_NATIVE(_1atk_1state_1set_1add_1state)
 	(JNIEnv *env, jclass that, jintLong arg0, jint arg1)
@@ -263,6 +481,46 @@ JNIEXPORT jintLong JNICALL ATK_NATIVE(_1atk_1state_1set_1new)
 }
 #endif
 
+#ifndef NO__1atk_1text_1attribute_1get_1name
+JNIEXPORT jintLong JNICALL ATK_NATIVE(_1atk_1text_1attribute_1get_1name)
+	(JNIEnv *env, jclass that, jint arg0)
+{
+	jintLong rc = 0;
+	ATK_NATIVE_ENTER(env, that, _1atk_1text_1attribute_1get_1name_FUNC);
+	rc = (jintLong)atk_text_attribute_get_name(arg0);
+	ATK_NATIVE_EXIT(env, that, _1atk_1text_1attribute_1get_1name_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1atk_1text_1attribute_1get_1value
+JNIEXPORT jintLong JNICALL ATK_NATIVE(_1atk_1text_1attribute_1get_1value)
+	(JNIEnv *env, jclass that, jint arg0, jint arg1)
+{
+	jintLong rc = 0;
+	ATK_NATIVE_ENTER(env, that, _1atk_1text_1attribute_1get_1value_FUNC);
+	rc = (jintLong)atk_text_attribute_get_value(arg0, arg1);
+	ATK_NATIVE_EXIT(env, that, _1atk_1text_1attribute_1get_1value_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1atk_1text_1attribute_1register
+JNIEXPORT jint JNICALL ATK_NATIVE(_1atk_1text_1attribute_1register)
+	(JNIEnv *env, jclass that, jbyteArray arg0)
+{
+	jbyte *lparg0=NULL;
+	jint rc = 0;
+	ATK_NATIVE_ENTER(env, that, _1atk_1text_1attribute_1register_FUNC);
+	if (arg0) if ((lparg0 = (*env)->GetByteArrayElements(env, arg0, NULL)) == NULL) goto fail;
+	rc = (jint)atk_text_attribute_register((const gchar *)lparg0);
+fail:
+	if (arg0 && lparg0) (*env)->ReleaseByteArrayElements(env, arg0, lparg0, 0);
+	ATK_NATIVE_EXIT(env, that, _1atk_1text_1attribute_1register_FUNC);
+	return rc;
+}
+#endif
+
 #if (!defined(NO__1call__II) && !defined(JNI64)) || (!defined(NO__1call__JJ) && defined(JNI64))
 #ifndef JNI64
 JNIEXPORT jintLong JNICALL ATK_NATIVE(_1call__II)(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1)
@@ -401,6 +659,18 @@ JNIEXPORT jintLong JNICALL ATK_NATIVE(_1call__JJJJJJJ)(JNIEnv *env, jclass that,
 }
 #endif
 
+#ifndef NO_g_1strdup
+JNIEXPORT jintLong JNICALL ATK_NATIVE(g_1strdup)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	ATK_NATIVE_ENTER(env, that, g_1strdup_FUNC);
+	rc = (jintLong)g_strdup((char *)arg0);
+	ATK_NATIVE_EXIT(env, that, g_1strdup_FUNC);
+	return rc;
+}
+#endif
+
 #if (!defined(NO_memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkActionIface_2) && !defined(JNI64)) || (!defined(NO_memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkActionIface_2) && defined(JNI64))
 #ifndef JNI64
 JNIEXPORT void JNICALL ATK_NATIVE(memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkActionIface_2)(JNIEnv *env, jclass that, jintLong arg0, jobject arg1)
@@ -422,6 +692,30 @@ JNIEXPORT void JNICALL ATK_NATIVE(memmove__JLorg_eclipse_swt_internal_accessibil
 }
 #endif
 
+#if (!defined(NO_memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkAttribute_2I) && !defined(JNI64)) || (!defined(NO_memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkAttribute_2I) && defined(JNI64))
+#ifndef JNI64
+JNIEXPORT void JNICALL ATK_NATIVE(memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkAttribute_2I)(JNIEnv *env, jclass that, jintLong arg0, jobject arg1, jint arg2)
+#else
+JNIEXPORT void JNICALL ATK_NATIVE(memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkAttribute_2I)(JNIEnv *env, jclass that, jintLong arg0, jobject arg1, jint arg2)
+#endif
+{
+	AtkAttribute _arg1, *lparg1=NULL;
+#ifndef JNI64
+	ATK_NATIVE_ENTER(env, that, memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkAttribute_2I_FUNC);
+#else
+	ATK_NATIVE_ENTER(env, that, memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkAttribute_2I_FUNC);
+#endif
+	if (arg1) if ((lparg1 = getAtkAttributeFields(env, arg1, &_arg1)) == NULL) goto fail;
+	memmove((void *)arg0, (const void *)lparg1, (size_t)arg2);
+fail:
+#ifndef JNI64
+	ATK_NATIVE_EXIT(env, that, memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkAttribute_2I_FUNC);
+#else
+	ATK_NATIVE_EXIT(env, that, memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkAttribute_2I_FUNC);
+#endif
+}
+#endif
+
 #if (!defined(NO_memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkComponentIface_2) && !defined(JNI64)) || (!defined(NO_memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkComponentIface_2) && defined(JNI64))
 #ifndef JNI64
 JNIEXPORT void JNICALL ATK_NATIVE(memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkComponentIface_2)(JNIEnv *env, jclass that, jintLong arg0, jobject arg1)
@@ -527,6 +821,27 @@ JNIEXPORT void JNICALL ATK_NATIVE(memmove__JLorg_eclipse_swt_internal_accessibil
 }
 #endif
 
+#if (!defined(NO_memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkTableIface_2) && !defined(JNI64)) || (!defined(NO_memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkTableIface_2) && defined(JNI64))
+#ifndef JNI64
+JNIEXPORT void JNICALL ATK_NATIVE(memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkTableIface_2)(JNIEnv *env, jclass that, jintLong arg0, jobject arg1)
+#else
+JNIEXPORT void JNICALL ATK_NATIVE(memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkTableIface_2)(JNIEnv *env, jclass that, jintLong arg0, jobject arg1)
+#endif
+{
+#ifndef JNI64
+	ATK_NATIVE_ENTER(env, that, memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkTableIface_2_FUNC);
+#else
+	ATK_NATIVE_ENTER(env, that, memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkTableIface_2_FUNC);
+#endif
+	if (arg1) getAtkTableIfaceFields(env, arg1, (AtkTableIface *)arg0);
+#ifndef JNI64
+	ATK_NATIVE_EXIT(env, that, memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkTableIface_2_FUNC);
+#else
+	ATK_NATIVE_EXIT(env, that, memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkTableIface_2_FUNC);
+#endif
+}
+#endif
+
 #if (!defined(NO_memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkTextIface_2) && !defined(JNI64)) || (!defined(NO_memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkTextIface_2) && defined(JNI64))
 #ifndef JNI64
 JNIEXPORT void JNICALL ATK_NATIVE(memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkTextIface_2)(JNIEnv *env, jclass that, jintLong arg0, jobject arg1)
@@ -548,6 +863,75 @@ JNIEXPORT void JNICALL ATK_NATIVE(memmove__JLorg_eclipse_swt_internal_accessibil
 }
 #endif
 
+#if (!defined(NO_memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkTextRange_2I) && !defined(JNI64)) || (!defined(NO_memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkTextRange_2I) && defined(JNI64))
+#ifndef JNI64
+JNIEXPORT void JNICALL ATK_NATIVE(memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkTextRange_2I)(JNIEnv *env, jclass that, jintLong arg0, jobject arg1, jint arg2)
+#else
+JNIEXPORT void JNICALL ATK_NATIVE(memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkTextRange_2I)(JNIEnv *env, jclass that, jintLong arg0, jobject arg1, jint arg2)
+#endif
+{
+	AtkTextRange _arg1, *lparg1=NULL;
+#ifndef JNI64
+	ATK_NATIVE_ENTER(env, that, memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkTextRange_2I_FUNC);
+#else
+	ATK_NATIVE_ENTER(env, that, memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkTextRange_2I_FUNC);
+#endif
+	if (arg1) if ((lparg1 = getAtkTextRangeFields(env, arg1, &_arg1)) == NULL) goto fail;
+	memmove((void *)arg0, (const void *)lparg1, (size_t)arg2);
+fail:
+#ifndef JNI64
+	ATK_NATIVE_EXIT(env, that, memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkTextRange_2I_FUNC);
+#else
+	ATK_NATIVE_EXIT(env, that, memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkTextRange_2I_FUNC);
+#endif
+}
+#endif
+
+#if (!defined(NO_memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkTextRectangle_2I) && !defined(JNI64)) || (!defined(NO_memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkTextRectangle_2I) && defined(JNI64))
+#ifndef JNI64
+JNIEXPORT void JNICALL ATK_NATIVE(memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkTextRectangle_2I)(JNIEnv *env, jclass that, jintLong arg0, jobject arg1, jint arg2)
+#else
+JNIEXPORT void JNICALL ATK_NATIVE(memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkTextRectangle_2I)(JNIEnv *env, jclass that, jintLong arg0, jobject arg1, jint arg2)
+#endif
+{
+	AtkTextRectangle _arg1, *lparg1=NULL;
+#ifndef JNI64
+	ATK_NATIVE_ENTER(env, that, memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkTextRectangle_2I_FUNC);
+#else
+	ATK_NATIVE_ENTER(env, that, memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkTextRectangle_2I_FUNC);
+#endif
+	if (arg1) if ((lparg1 = getAtkTextRectangleFields(env, arg1, &_arg1)) == NULL) goto fail;
+	memmove((void *)arg0, (const void *)lparg1, (size_t)arg2);
+fail:
+#ifndef JNI64
+	ATK_NATIVE_EXIT(env, that, memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkTextRectangle_2I_FUNC);
+#else
+	ATK_NATIVE_EXIT(env, that, memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkTextRectangle_2I_FUNC);
+#endif
+}
+#endif
+
+#if (!defined(NO_memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkValueIface_2) && !defined(JNI64)) || (!defined(NO_memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkValueIface_2) && defined(JNI64))
+#ifndef JNI64
+JNIEXPORT void JNICALL ATK_NATIVE(memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkValueIface_2)(JNIEnv *env, jclass that, jintLong arg0, jobject arg1)
+#else
+JNIEXPORT void JNICALL ATK_NATIVE(memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkValueIface_2)(JNIEnv *env, jclass that, jintLong arg0, jobject arg1)
+#endif
+{
+#ifndef JNI64
+	ATK_NATIVE_ENTER(env, that, memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkValueIface_2_FUNC);
+#else
+	ATK_NATIVE_ENTER(env, that, memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkValueIface_2_FUNC);
+#endif
+	if (arg1) getAtkValueIfaceFields(env, arg1, (AtkValueIface *)arg0);
+#ifndef JNI64
+	ATK_NATIVE_EXIT(env, that, memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkValueIface_2_FUNC);
+#else
+	ATK_NATIVE_EXIT(env, that, memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkValueIface_2_FUNC);
+#endif
+}
+#endif
+
 #if (!defined(NO_memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkActionIface_2I) && !defined(JNI64)) || (!defined(NO_memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkActionIface_2J) && defined(JNI64))
 #ifndef JNI64
 JNIEXPORT void JNICALL ATK_NATIVE(memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkActionIface_2I)(JNIEnv *env, jclass that, jobject arg0, jintLong arg1)
@@ -569,6 +953,31 @@ JNIEXPORT void JNICALL ATK_NATIVE(memmove__Lorg_eclipse_swt_internal_accessibili
 }
 #endif
 
+#if (!defined(NO_memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkAttribute_2II) && !defined(JNI64)) || (!defined(NO_memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkAttribute_2JI) && defined(JNI64))
+#ifndef JNI64
+JNIEXPORT void JNICALL ATK_NATIVE(memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkAttribute_2II)(JNIEnv *env, jclass that, jobject arg0, jintLong arg1, jint arg2)
+#else
+JNIEXPORT void JNICALL ATK_NATIVE(memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkAttribute_2JI)(JNIEnv *env, jclass that, jobject arg0, jintLong arg1, jint arg2)
+#endif
+{
+	AtkAttribute _arg0, *lparg0=NULL;
+#ifndef JNI64
+	ATK_NATIVE_ENTER(env, that, memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkAttribute_2II_FUNC);
+#else
+	ATK_NATIVE_ENTER(env, that, memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkAttribute_2JI_FUNC);
+#endif
+	if (arg0) if ((lparg0 = getAtkAttributeFields(env, arg0, &_arg0)) == NULL) goto fail;
+	memmove((void *)lparg0, (const void *)arg1, (size_t)arg2);
+fail:
+	if (arg0 && lparg0) setAtkAttributeFields(env, arg0, lparg0);
+#ifndef JNI64
+	ATK_NATIVE_EXIT(env, that, memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkAttribute_2II_FUNC);
+#else
+	ATK_NATIVE_EXIT(env, that, memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkAttribute_2JI_FUNC);
+#endif
+}
+#endif
+
 #if (!defined(NO_memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkComponentIface_2I) && !defined(JNI64)) || (!defined(NO_memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkComponentIface_2J) && defined(JNI64))
 #ifndef JNI64
 JNIEXPORT void JNICALL ATK_NATIVE(memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkComponentIface_2I)(JNIEnv *env, jclass that, jobject arg0, jintLong arg1)
@@ -674,6 +1083,27 @@ JNIEXPORT void JNICALL ATK_NATIVE(memmove__Lorg_eclipse_swt_internal_accessibili
 }
 #endif
 
+#if (!defined(NO_memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTableIface_2I) && !defined(JNI64)) || (!defined(NO_memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTableIface_2J) && defined(JNI64))
+#ifndef JNI64
+JNIEXPORT void JNICALL ATK_NATIVE(memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTableIface_2I)(JNIEnv *env, jclass that, jobject arg0, jintLong arg1)
+#else
+JNIEXPORT void JNICALL ATK_NATIVE(memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTableIface_2J)(JNIEnv *env, jclass that, jobject arg0, jintLong arg1)
+#endif
+{
+#ifndef JNI64
+	ATK_NATIVE_ENTER(env, that, memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTableIface_2I_FUNC);
+#else
+	ATK_NATIVE_ENTER(env, that, memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTableIface_2J_FUNC);
+#endif
+	if (arg0) setAtkTableIfaceFields(env, arg0, (AtkTableIface *)arg1);
+#ifndef JNI64
+	ATK_NATIVE_EXIT(env, that, memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTableIface_2I_FUNC);
+#else
+	ATK_NATIVE_EXIT(env, that, memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTableIface_2J_FUNC);
+#endif
+}
+#endif
+
 #if (!defined(NO_memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTextIface_2I) && !defined(JNI64)) || (!defined(NO_memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTextIface_2J) && defined(JNI64))
 #ifndef JNI64
 JNIEXPORT void JNICALL ATK_NATIVE(memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTextIface_2I)(JNIEnv *env, jclass that, jobject arg0, jintLong arg1)
@@ -695,6 +1125,77 @@ JNIEXPORT void JNICALL ATK_NATIVE(memmove__Lorg_eclipse_swt_internal_accessibili
 }
 #endif
 
+#if (!defined(NO_memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTextRange_2II) && !defined(JNI64)) || (!defined(NO_memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTextRange_2JI) && defined(JNI64))
+#ifndef JNI64
+JNIEXPORT void JNICALL ATK_NATIVE(memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTextRange_2II)(JNIEnv *env, jclass that, jobject arg0, jintLong arg1, jint arg2)
+#else
+JNIEXPORT void JNICALL ATK_NATIVE(memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTextRange_2JI)(JNIEnv *env, jclass that, jobject arg0, jintLong arg1, jint arg2)
+#endif
+{
+	AtkTextRange _arg0, *lparg0=NULL;
+#ifndef JNI64
+	ATK_NATIVE_ENTER(env, that, memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTextRange_2II_FUNC);
+#else
+	ATK_NATIVE_ENTER(env, that, memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTextRange_2JI_FUNC);
+#endif
+	if (arg0) if ((lparg0 = getAtkTextRangeFields(env, arg0, &_arg0)) == NULL) goto fail;
+	memmove((void *)lparg0, (const void *)arg1, (size_t)arg2);
+fail:
+	if (arg0 && lparg0) setAtkTextRangeFields(env, arg0, lparg0);
+#ifndef JNI64
+	ATK_NATIVE_EXIT(env, that, memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTextRange_2II_FUNC);
+#else
+	ATK_NATIVE_EXIT(env, that, memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTextRange_2JI_FUNC);
+#endif
+}
+#endif
+
+#if (!defined(NO_memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTextRectangle_2II) && !defined(JNI64)) || (!defined(NO_memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTextRectangle_2JI) && defined(JNI64))
+#ifndef JNI64
+JNIEXPORT void JNICALL ATK_NATIVE(memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTextRectangle_2II)(JNIEnv *env, jclass that, jobject arg0, jintLong arg1, jint arg2)
+#else
+JNIEXPORT void JNICALL ATK_NATIVE(memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTextRectangle_2JI)(JNIEnv *env, jclass that, jobject arg0, jintLong arg1, jint arg2)
+#endif
+{
+	AtkTextRectangle _arg0, *lparg0=NULL;
+#ifndef JNI64
+	ATK_NATIVE_ENTER(env, that, memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTextRectangle_2II_FUNC);
+#else
+	ATK_NATIVE_ENTER(env, that, memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTextRectangle_2JI_FUNC);
+#endif
+	if (arg0) if ((lparg0 = getAtkTextRectangleFields(env, arg0, &_arg0)) == NULL) goto fail;
+	memmove((void *)lparg0, (const void *)arg1, (size_t)arg2);
+fail:
+	if (arg0 && lparg0) setAtkTextRectangleFields(env, arg0, lparg0);
+#ifndef JNI64
+	ATK_NATIVE_EXIT(env, that, memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTextRectangle_2II_FUNC);
+#else
+	ATK_NATIVE_EXIT(env, that, memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTextRectangle_2JI_FUNC);
+#endif
+}
+#endif
+
+#if (!defined(NO_memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkValueIface_2I) && !defined(JNI64)) || (!defined(NO_memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkValueIface_2J) && defined(JNI64))
+#ifndef JNI64
+JNIEXPORT void JNICALL ATK_NATIVE(memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkValueIface_2I)(JNIEnv *env, jclass that, jobject arg0, jintLong arg1)
+#else
+JNIEXPORT void JNICALL ATK_NATIVE(memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkValueIface_2J)(JNIEnv *env, jclass that, jobject arg0, jintLong arg1)
+#endif
+{
+#ifndef JNI64
+	ATK_NATIVE_ENTER(env, that, memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkValueIface_2I_FUNC);
+#else
+	ATK_NATIVE_ENTER(env, that, memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkValueIface_2J_FUNC);
+#endif
+	if (arg0) setAtkValueIfaceFields(env, arg0, (AtkValueIface *)arg1);
+#ifndef JNI64
+	ATK_NATIVE_EXIT(env, that, memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkValueIface_2I_FUNC);
+#else
+	ATK_NATIVE_EXIT(env, that, memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkValueIface_2J_FUNC);
+#endif
+}
+#endif
+
 #if (!defined(NO_memmove__Lorg_eclipse_swt_internal_accessibility_gtk_GtkAccessible_2I) && !defined(JNI64)) || (!defined(NO_memmove__Lorg_eclipse_swt_internal_accessibility_gtk_GtkAccessible_2J) && defined(JNI64))
 #ifndef JNI64
 JNIEXPORT void JNICALL ATK_NATIVE(memmove__Lorg_eclipse_swt_internal_accessibility_gtk_GtkAccessible_2I)(JNIEnv *env, jclass that, jobject arg0, jintLong arg1)
diff --git a/atk.h b/atk.h
index 1de6af0..e353373 100644
--- a/atk.h
+++ b/atk.h
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others. All rights reserved.
+ * Copyright (c) 2000, 2010 IBM Corporation and others. All rights reserved.
  * The contents of this file are made available under the terms
  * of the GNU Lesser General Public License (LGPL) Version 2.1 that
  * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
@@ -16,3 +16,11 @@
 #include "os.h"
 #include <atk/atk.h>
 #include "atk_custom.h"
+
+#if (GTK_MAJOR_VERSION>=2 && GTK_MINOR_VERSION>=10)
+#define SWT_AtkObjectClass_get_attributes get_attributes
+#define SWT_AtkObjectClass_get_attributes_cast AtkAttributeSet* (*)()
+#else
+#define SWT_AtkObjectClass_get_attributes pad1
+#define SWT_AtkObjectClass_get_attributes_cast AtkFunction
+#endif 
diff --git a/atk_stats.c b/atk_stats.c
index 0527eda..880122a 100644
--- a/atk_stats.c
+++ b/atk_stats.c
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others. All rights reserved.
+ * Copyright (c) 2000, 2010 IBM Corporation and others. All rights reserved.
  * The contents of this file are made available under the terms
  * of the GNU Lesser General Public License (LGPL) Version 2.1 that
  * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
@@ -18,30 +18,51 @@
 
 #ifdef NATIVE_STATS
 
-int ATK_nativeFunctionCount = 42;
-int ATK_nativeFunctionCallCount[42];
+int ATK_nativeFunctionCount = 74;
+int ATK_nativeFunctionCallCount[74];
 char * ATK_nativeFunctionNames[] = {
+	"ATK_1IS_1NO_1OP_1OBJECT_1FACTORY",
+	"ATK_1TYPE_1ACTION",
+	"ATK_1TYPE_1COMPONENT",
+	"ATK_1TYPE_1HYPERTEXT",
+	"ATK_1TYPE_1OBJECT_1FACTORY",
+	"ATK_1TYPE_1SELECTION",
+	"ATK_1TYPE_1TABLE",
+	"ATK_1TYPE_1TEXT",
+	"ATK_1TYPE_1VALUE",
+	"AtkAttribute_1sizeof",
 	"AtkObjectFactoryClass_1sizeof",
 	"AtkObjectFactory_1sizeof",
+	"AtkTextRange_1sizeof",
+	"AtkTextRectangle_1sizeof",
+	"GTK_1TYPE_1ACCESSIBLE",
 	"_1ATK_1ACTION_1GET_1IFACE",
 	"_1ATK_1COMPONENT_1GET_1IFACE",
+	"_1ATK_1HYPERTEXT_1GET_1IFACE",
 	"_1ATK_1OBJECT_1FACTORY_1CLASS",
 	"_1ATK_1SELECTION_1GET_1IFACE",
+	"_1ATK_1TABLE_1GET_1IFACE",
 	"_1ATK_1TEXT_1GET_1IFACE",
+	"_1ATK_1VALUE_1GET_1IFACE",
 	"_1GTK_1ACCESSIBLE",
 	"_1atk_1focus_1tracker_1notify",
 	"_1atk_1get_1default_1registry",
 	"_1atk_1object_1factory_1create_1accessible",
 	"_1atk_1object_1factory_1get_1accessible_1type",
 	"_1atk_1object_1initialize",
+	"_1atk_1object_1notify_1state_1change",
 	"_1atk_1object_1ref_1relation_1set",
 	"_1atk_1registry_1get_1factory",
 	"_1atk_1registry_1set_1factory_1type",
 	"_1atk_1relation_1set_1get_1n_1relations",
 	"_1atk_1relation_1set_1get_1relation",
 	"_1atk_1relation_1set_1remove",
+	"_1atk_1role_1register",
 	"_1atk_1state_1set_1add_1state",
 	"_1atk_1state_1set_1new",
+	"_1atk_1text_1attribute_1get_1name",
+	"_1atk_1text_1attribute_1get_1value",
+	"_1atk_1text_1attribute_1register",
 #ifndef JNI64
 	"_1call__II",
 #else
@@ -72,12 +93,18 @@ char * ATK_nativeFunctionNames[] = {
 #else
 	"_1call__JJJJJJJ",
 #endif
+	"g_1strdup",
 #ifndef JNI64
 	"memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkActionIface_2",
 #else
 	"memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkActionIface_2",
 #endif
 #ifndef JNI64
+	"memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkAttribute_2I",
+#else
+	"memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkAttribute_2I",
+#endif
+#ifndef JNI64
 	"memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkComponentIface_2",
 #else
 	"memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkComponentIface_2",
@@ -103,16 +130,41 @@ char * ATK_nativeFunctionNames[] = {
 	"memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkSelectionIface_2",
 #endif
 #ifndef JNI64
+	"memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkTableIface_2",
+#else
+	"memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkTableIface_2",
+#endif
+#ifndef JNI64
 	"memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkTextIface_2",
 #else
 	"memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkTextIface_2",
 #endif
 #ifndef JNI64
+	"memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkTextRange_2I",
+#else
+	"memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkTextRange_2I",
+#endif
+#ifndef JNI64
+	"memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkTextRectangle_2I",
+#else
+	"memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkTextRectangle_2I",
+#endif
+#ifndef JNI64
+	"memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkValueIface_2",
+#else
+	"memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkValueIface_2",
+#endif
+#ifndef JNI64
 	"memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkActionIface_2I",
 #else
 	"memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkActionIface_2J",
 #endif
 #ifndef JNI64
+	"memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkAttribute_2II",
+#else
+	"memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkAttribute_2JI",
+#endif
+#ifndef JNI64
 	"memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkComponentIface_2I",
 #else
 	"memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkComponentIface_2J",
@@ -138,11 +190,31 @@ char * ATK_nativeFunctionNames[] = {
 	"memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkSelectionIface_2J",
 #endif
 #ifndef JNI64
+	"memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTableIface_2I",
+#else
+	"memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTableIface_2J",
+#endif
+#ifndef JNI64
 	"memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTextIface_2I",
 #else
 	"memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTextIface_2J",
 #endif
 #ifndef JNI64
+	"memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTextRange_2II",
+#else
+	"memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTextRange_2JI",
+#endif
+#ifndef JNI64
+	"memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTextRectangle_2II",
+#else
+	"memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTextRectangle_2JI",
+#endif
+#ifndef JNI64
+	"memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkValueIface_2I",
+#else
+	"memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkValueIface_2J",
+#endif
+#ifndef JNI64
 	"memmove__Lorg_eclipse_swt_internal_accessibility_gtk_GtkAccessible_2I",
 #else
 	"memmove__Lorg_eclipse_swt_internal_accessibility_gtk_GtkAccessible_2J",
diff --git a/atk_stats.h b/atk_stats.h
index d4680ab..10e1400 100644
--- a/atk_stats.h
+++ b/atk_stats.h
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others. All rights reserved.
+ * Copyright (c) 2000, 2010 IBM Corporation and others. All rights reserved.
  * The contents of this file are made available under the terms
  * of the GNU Lesser General Public License (LGPL) Version 2.1 that
  * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
@@ -29,27 +29,48 @@ extern char* ATK_nativeFunctionNames[];
 #endif
 
 typedef enum {
+	ATK_1IS_1NO_1OP_1OBJECT_1FACTORY_FUNC,
+	ATK_1TYPE_1ACTION_FUNC,
+	ATK_1TYPE_1COMPONENT_FUNC,
+	ATK_1TYPE_1HYPERTEXT_FUNC,
+	ATK_1TYPE_1OBJECT_1FACTORY_FUNC,
+	ATK_1TYPE_1SELECTION_FUNC,
+	ATK_1TYPE_1TABLE_FUNC,
+	ATK_1TYPE_1TEXT_FUNC,
+	ATK_1TYPE_1VALUE_FUNC,
+	AtkAttribute_1sizeof_FUNC,
 	AtkObjectFactoryClass_1sizeof_FUNC,
 	AtkObjectFactory_1sizeof_FUNC,
+	AtkTextRange_1sizeof_FUNC,
+	AtkTextRectangle_1sizeof_FUNC,
+	GTK_1TYPE_1ACCESSIBLE_FUNC,
 	_1ATK_1ACTION_1GET_1IFACE_FUNC,
 	_1ATK_1COMPONENT_1GET_1IFACE_FUNC,
+	_1ATK_1HYPERTEXT_1GET_1IFACE_FUNC,
 	_1ATK_1OBJECT_1FACTORY_1CLASS_FUNC,
 	_1ATK_1SELECTION_1GET_1IFACE_FUNC,
+	_1ATK_1TABLE_1GET_1IFACE_FUNC,
 	_1ATK_1TEXT_1GET_1IFACE_FUNC,
+	_1ATK_1VALUE_1GET_1IFACE_FUNC,
 	_1GTK_1ACCESSIBLE_FUNC,
 	_1atk_1focus_1tracker_1notify_FUNC,
 	_1atk_1get_1default_1registry_FUNC,
 	_1atk_1object_1factory_1create_1accessible_FUNC,
 	_1atk_1object_1factory_1get_1accessible_1type_FUNC,
 	_1atk_1object_1initialize_FUNC,
+	_1atk_1object_1notify_1state_1change_FUNC,
 	_1atk_1object_1ref_1relation_1set_FUNC,
 	_1atk_1registry_1get_1factory_FUNC,
 	_1atk_1registry_1set_1factory_1type_FUNC,
 	_1atk_1relation_1set_1get_1n_1relations_FUNC,
 	_1atk_1relation_1set_1get_1relation_FUNC,
 	_1atk_1relation_1set_1remove_FUNC,
+	_1atk_1role_1register_FUNC,
 	_1atk_1state_1set_1add_1state_FUNC,
 	_1atk_1state_1set_1new_FUNC,
+	_1atk_1text_1attribute_1get_1name_FUNC,
+	_1atk_1text_1attribute_1get_1value_FUNC,
+	_1atk_1text_1attribute_1register_FUNC,
 #ifndef JNI64
 	_1call__II_FUNC,
 #else
@@ -80,12 +101,18 @@ typedef enum {
 #else
 	_1call__JJJJJJJ_FUNC,
 #endif
+	g_1strdup_FUNC,
 #ifndef JNI64
 	memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkActionIface_2_FUNC,
 #else
 	memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkActionIface_2_FUNC,
 #endif
 #ifndef JNI64
+	memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkAttribute_2I_FUNC,
+#else
+	memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkAttribute_2I_FUNC,
+#endif
+#ifndef JNI64
 	memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkComponentIface_2_FUNC,
 #else
 	memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkComponentIface_2_FUNC,
@@ -111,16 +138,41 @@ typedef enum {
 	memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkSelectionIface_2_FUNC,
 #endif
 #ifndef JNI64
+	memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkTableIface_2_FUNC,
+#else
+	memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkTableIface_2_FUNC,
+#endif
+#ifndef JNI64
 	memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkTextIface_2_FUNC,
 #else
 	memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkTextIface_2_FUNC,
 #endif
 #ifndef JNI64
+	memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkTextRange_2I_FUNC,
+#else
+	memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkTextRange_2I_FUNC,
+#endif
+#ifndef JNI64
+	memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkTextRectangle_2I_FUNC,
+#else
+	memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkTextRectangle_2I_FUNC,
+#endif
+#ifndef JNI64
+	memmove__ILorg_eclipse_swt_internal_accessibility_gtk_AtkValueIface_2_FUNC,
+#else
+	memmove__JLorg_eclipse_swt_internal_accessibility_gtk_AtkValueIface_2_FUNC,
+#endif
+#ifndef JNI64
 	memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkActionIface_2I_FUNC,
 #else
 	memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkActionIface_2J_FUNC,
 #endif
 #ifndef JNI64
+	memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkAttribute_2II_FUNC,
+#else
+	memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkAttribute_2JI_FUNC,
+#endif
+#ifndef JNI64
 	memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkComponentIface_2I_FUNC,
 #else
 	memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkComponentIface_2J_FUNC,
@@ -146,11 +198,31 @@ typedef enum {
 	memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkSelectionIface_2J_FUNC,
 #endif
 #ifndef JNI64
+	memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTableIface_2I_FUNC,
+#else
+	memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTableIface_2J_FUNC,
+#endif
+#ifndef JNI64
 	memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTextIface_2I_FUNC,
 #else
 	memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTextIface_2J_FUNC,
 #endif
 #ifndef JNI64
+	memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTextRange_2II_FUNC,
+#else
+	memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTextRange_2JI_FUNC,
+#endif
+#ifndef JNI64
+	memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTextRectangle_2II_FUNC,
+#else
+	memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkTextRectangle_2JI_FUNC,
+#endif
+#ifndef JNI64
+	memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkValueIface_2I_FUNC,
+#else
+	memmove__Lorg_eclipse_swt_internal_accessibility_gtk_AtkValueIface_2J_FUNC,
+#endif
+#ifndef JNI64
 	memmove__Lorg_eclipse_swt_internal_accessibility_gtk_GtkAccessible_2I_FUNC,
 #else
 	memmove__Lorg_eclipse_swt_internal_accessibility_gtk_GtkAccessible_2J_FUNC,
diff --git a/atk_structs.c b/atk_structs.c
index cd9a5ed..0f18573 100644
--- a/atk_structs.c
+++ b/atk_structs.c
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others. All rights reserved.
+ * Copyright (c) 2000, 2010 IBM Corporation and others. All rights reserved.
  * The contents of this file are made available under the terms
  * of the GNU Lesser General Public License (LGPL) Version 2.1 that
  * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
@@ -62,6 +62,40 @@ void setAtkActionIfaceFields(JNIEnv *env, jobject lpObject, AtkActionIface *lpSt
 }
 #endif
 
+#ifndef NO_AtkAttribute
+typedef struct AtkAttribute_FID_CACHE {
+	int cached;
+	jclass clazz;
+	jfieldID name, value;
+} AtkAttribute_FID_CACHE;
+
+AtkAttribute_FID_CACHE AtkAttributeFc;
+
+void cacheAtkAttributeFields(JNIEnv *env, jobject lpObject)
+{
+	if (AtkAttributeFc.cached) return;
+	AtkAttributeFc.clazz = (*env)->GetObjectClass(env, lpObject);
+	AtkAttributeFc.name = (*env)->GetFieldID(env, AtkAttributeFc.clazz, "name", I_J);
+	AtkAttributeFc.value = (*env)->GetFieldID(env, AtkAttributeFc.clazz, "value", I_J);
+	AtkAttributeFc.cached = 1;
+}
+
+AtkAttribute *getAtkAttributeFields(JNIEnv *env, jobject lpObject, AtkAttribute *lpStruct)
+{
+	if (!AtkAttributeFc.cached) cacheAtkAttributeFields(env, lpObject);
+	lpStruct->name = (char *)(*env)->GetIntLongField(env, lpObject, AtkAttributeFc.name);
+	lpStruct->value = (char *)(*env)->GetIntLongField(env, lpObject, AtkAttributeFc.value);
+	return lpStruct;
+}
+
+void setAtkAttributeFields(JNIEnv *env, jobject lpObject, AtkAttribute *lpStruct)
+{
+	if (!AtkAttributeFc.cached) cacheAtkAttributeFields(env, lpObject);
+	(*env)->SetIntLongField(env, lpObject, AtkAttributeFc.name, (jintLong)lpStruct->name);
+	(*env)->SetIntLongField(env, lpObject, AtkAttributeFc.value, (jintLong)lpStruct->value);
+}
+#endif
+
 #ifndef NO_AtkComponentIface
 typedef struct AtkComponentIface_FID_CACHE {
 	int cached;
@@ -170,7 +204,7 @@ void setAtkHypertextIfaceFields(JNIEnv *env, jobject lpObject, AtkHypertextIface
 typedef struct AtkObjectClass_FID_CACHE {
 	int cached;
 	jclass clazz;
-	jfieldID get_name, get_description, get_parent, get_n_children, ref_child, get_index_in_parent, ref_relation_set, get_role, get_layer, get_mdi_zorder, ref_state_set, set_name, set_description, set_parent, set_role, connect_property_change_handler, remove_property_change_handler, initialize, children_changed, focus_event, property_change, state_change, visible_data_changed;
+	jfieldID get_name, get_description, get_parent, get_n_children, ref_child, get_index_in_parent, ref_relation_set, get_role, get_layer, get_mdi_zorder, ref_state_set, set_name, set_description, set_parent, set_role, connect_property_change_handler, remove_property_change_handler, initialize, children_changed, focus_event, property_change, state_change, visible_data_changed, get_attributes;
 } AtkObjectClass_FID_CACHE;
 
 AtkObjectClass_FID_CACHE AtkObjectClassFc;
@@ -202,6 +236,7 @@ void cacheAtkObjectClassFields(JNIEnv *env, jobject lpObject)
 	AtkObjectClassFc.property_change = (*env)->GetFieldID(env, AtkObjectClassFc.clazz, "property_change", I_J);
 	AtkObjectClassFc.state_change = (*env)->GetFieldID(env, AtkObjectClassFc.clazz, "state_change", I_J);
 	AtkObjectClassFc.visible_data_changed = (*env)->GetFieldID(env, AtkObjectClassFc.clazz, "visible_data_changed", I_J);
+	AtkObjectClassFc.get_attributes = (*env)->GetFieldID(env, AtkObjectClassFc.clazz, "get_attributes", I_J);
 	AtkObjectClassFc.cached = 1;
 }
 
@@ -231,6 +266,7 @@ AtkObjectClass *getAtkObjectClassFields(JNIEnv *env, jobject lpObject, AtkObject
 	lpStruct->property_change = (void (*)())(*env)->GetIntLongField(env, lpObject, AtkObjectClassFc.property_change);
 	lpStruct->state_change = (void (*)())(*env)->GetIntLongField(env, lpObject, AtkObjectClassFc.state_change);
 	lpStruct->visible_data_changed = (void (*)())(*env)->GetIntLongField(env, lpObject, AtkObjectClassFc.visible_data_changed);
+	lpStruct->SWT_AtkObjectClass_get_attributes = (SWT_AtkObjectClass_get_attributes_cast)(*env)->GetIntLongField(env, lpObject, AtkObjectClassFc.get_attributes);
 	return lpStruct;
 }
 
@@ -260,6 +296,7 @@ void setAtkObjectClassFields(JNIEnv *env, jobject lpObject, AtkObjectClass *lpSt
 	(*env)->SetIntLongField(env, lpObject, AtkObjectClassFc.property_change, (jintLong)lpStruct->property_change);
 	(*env)->SetIntLongField(env, lpObject, AtkObjectClassFc.state_change, (jintLong)lpStruct->state_change);
 	(*env)->SetIntLongField(env, lpObject, AtkObjectClassFc.visible_data_changed, (jintLong)lpStruct->visible_data_changed);
+	(*env)->SetIntLongField(env, lpObject, AtkObjectClassFc.get_attributes, (jintLong)lpStruct->SWT_AtkObjectClass_get_attributes);
 }
 #endif
 
@@ -352,11 +389,147 @@ void setAtkSelectionIfaceFields(JNIEnv *env, jobject lpObject, AtkSelectionIface
 }
 #endif
 
+#ifndef NO_AtkTableIface
+typedef struct AtkTableIface_FID_CACHE {
+	int cached;
+	jclass clazz;
+	jfieldID ref_at, get_index_at, get_column_at_index, get_row_at_index, get_n_columns, get_n_rows, get_column_extent_at, get_row_extent_at, get_caption, get_column_description, get_column_header, get_row_description, get_row_header, get_summary, set_caption, set_column_description, set_column_header, set_row_description, set_row_header, set_summary, get_selected_columns, get_selected_rows, is_column_selected, is_row_selected, is_selected, add_row_selection, remove_row_selection, add_column_selection, remove_column_selection, row_inserted, column_inserted, row_deleted, column_deleted, row_reordered, column_reordered, model_changed;
+} AtkTableIface_FID_CACHE;
+
+AtkTableIface_FID_CACHE AtkTableIfaceFc;
+
+void cacheAtkTableIfaceFields(JNIEnv *env, jobject lpObject)
+{
+	if (AtkTableIfaceFc.cached) return;
+	AtkTableIfaceFc.clazz = (*env)->GetObjectClass(env, lpObject);
+	AtkTableIfaceFc.ref_at = (*env)->GetFieldID(env, AtkTableIfaceFc.clazz, "ref_at", I_J);
+	AtkTableIfaceFc.get_index_at = (*env)->GetFieldID(env, AtkTableIfaceFc.clazz, "get_index_at", I_J);
+	AtkTableIfaceFc.get_column_at_index = (*env)->GetFieldID(env, AtkTableIfaceFc.clazz, "get_column_at_index", I_J);
+	AtkTableIfaceFc.get_row_at_index = (*env)->GetFieldID(env, AtkTableIfaceFc.clazz, "get_row_at_index", I_J);
+	AtkTableIfaceFc.get_n_columns = (*env)->GetFieldID(env, AtkTableIfaceFc.clazz, "get_n_columns", I_J);
+	AtkTableIfaceFc.get_n_rows = (*env)->GetFieldID(env, AtkTableIfaceFc.clazz, "get_n_rows", I_J);
+	AtkTableIfaceFc.get_column_extent_at = (*env)->GetFieldID(env, AtkTableIfaceFc.clazz, "get_column_extent_at", I_J);
+	AtkTableIfaceFc.get_row_extent_at = (*env)->GetFieldID(env, AtkTableIfaceFc.clazz, "get_row_extent_at", I_J);
+	AtkTableIfaceFc.get_caption = (*env)->GetFieldID(env, AtkTableIfaceFc.clazz, "get_caption", I_J);
+	AtkTableIfaceFc.get_column_description = (*env)->GetFieldID(env, AtkTableIfaceFc.clazz, "get_column_description", I_J);
+	AtkTableIfaceFc.get_column_header = (*env)->GetFieldID(env, AtkTableIfaceFc.clazz, "get_column_header", I_J);
+	AtkTableIfaceFc.get_row_description = (*env)->GetFieldID(env, AtkTableIfaceFc.clazz, "get_row_description", I_J);
+	AtkTableIfaceFc.get_row_header = (*env)->GetFieldID(env, AtkTableIfaceFc.clazz, "get_row_header", I_J);
+	AtkTableIfaceFc.get_summary = (*env)->GetFieldID(env, AtkTableIfaceFc.clazz, "get_summary", I_J);
+	AtkTableIfaceFc.set_caption = (*env)->GetFieldID(env, AtkTableIfaceFc.clazz, "set_caption", I_J);
+	AtkTableIfaceFc.set_column_description = (*env)->GetFieldID(env, AtkTableIfaceFc.clazz, "set_column_description", I_J);
+	AtkTableIfaceFc.set_column_header = (*env)->GetFieldID(env, AtkTableIfaceFc.clazz, "set_column_header", I_J);
+	AtkTableIfaceFc.set_row_description = (*env)->GetFieldID(env, AtkTableIfaceFc.clazz, "set_row_description", I_J);
+	AtkTableIfaceFc.set_row_header = (*env)->GetFieldID(env, AtkTableIfaceFc.clazz, "set_row_header", I_J);
+	AtkTableIfaceFc.set_summary = (*env)->GetFieldID(env, AtkTableIfaceFc.clazz, "set_summary", I_J);
+	AtkTableIfaceFc.get_selected_columns = (*env)->GetFieldID(env, AtkTableIfaceFc.clazz, "get_selected_columns", I_J);
+	AtkTableIfaceFc.get_selected_rows = (*env)->GetFieldID(env, AtkTableIfaceFc.clazz, "get_selected_rows", I_J);
+	AtkTableIfaceFc.is_column_selected = (*env)->GetFieldID(env, AtkTableIfaceFc.clazz, "is_column_selected", I_J);
+	AtkTableIfaceFc.is_row_selected = (*env)->GetFieldID(env, AtkTableIfaceFc.clazz, "is_row_selected", I_J);
+	AtkTableIfaceFc.is_selected = (*env)->GetFieldID(env, AtkTableIfaceFc.clazz, "is_selected", I_J);
+	AtkTableIfaceFc.add_row_selection = (*env)->GetFieldID(env, AtkTableIfaceFc.clazz, "add_row_selection", I_J);
+	AtkTableIfaceFc.remove_row_selection = (*env)->GetFieldID(env, AtkTableIfaceFc.clazz, "remove_row_selection", I_J);
+	AtkTableIfaceFc.add_column_selection = (*env)->GetFieldID(env, AtkTableIfaceFc.clazz, "add_column_selection", I_J);
+	AtkTableIfaceFc.remove_column_selection = (*env)->GetFieldID(env, AtkTableIfaceFc.clazz, "remove_column_selection", I_J);
+	AtkTableIfaceFc.row_inserted = (*env)->GetFieldID(env, AtkTableIfaceFc.clazz, "row_inserted", I_J);
+	AtkTableIfaceFc.column_inserted = (*env)->GetFieldID(env, AtkTableIfaceFc.clazz, "column_inserted", I_J);
+	AtkTableIfaceFc.row_deleted = (*env)->GetFieldID(env, AtkTableIfaceFc.clazz, "row_deleted", I_J);
+	AtkTableIfaceFc.column_deleted = (*env)->GetFieldID(env, AtkTableIfaceFc.clazz, "column_deleted", I_J);
+	AtkTableIfaceFc.row_reordered = (*env)->GetFieldID(env, AtkTableIfaceFc.clazz, "row_reordered", I_J);
+	AtkTableIfaceFc.column_reordered = (*env)->GetFieldID(env, AtkTableIfaceFc.clazz, "column_reordered", I_J);
+	AtkTableIfaceFc.model_changed = (*env)->GetFieldID(env, AtkTableIfaceFc.clazz, "model_changed", I_J);
+	AtkTableIfaceFc.cached = 1;
+}
+
+AtkTableIface *getAtkTableIfaceFields(JNIEnv *env, jobject lpObject, AtkTableIface *lpStruct)
+{
+	if (!AtkTableIfaceFc.cached) cacheAtkTableIfaceFields(env, lpObject);
+	lpStruct->ref_at = (AtkObject* (*)())(*env)->GetIntLongField(env, lpObject, AtkTableIfaceFc.ref_at);
+	lpStruct->get_index_at = (gint (*)())(*env)->GetIntLongField(env, lpObject, AtkTableIfaceFc.get_index_at);
+	lpStruct->get_column_at_index = (gint (*)())(*env)->GetIntLongField(env, lpObject, AtkTableIfaceFc.get_column_at_index);
+	lpStruct->get_row_at_index = (gint (*)())(*env)->GetIntLongField(env, lpObject, AtkTableIfaceFc.get_row_at_index);
+	lpStruct->get_n_columns = (gint (*)())(*env)->GetIntLongField(env, lpObject, AtkTableIfaceFc.get_n_columns);
+	lpStruct->get_n_rows = (gint (*)())(*env)->GetIntLongField(env, lpObject, AtkTableIfaceFc.get_n_rows);
+	lpStruct->get_column_extent_at = (gint (*)())(*env)->GetIntLongField(env, lpObject, AtkTableIfaceFc.get_column_extent_at);
+	lpStruct->get_row_extent_at = (gint (*)())(*env)->GetIntLongField(env, lpObject, AtkTableIfaceFc.get_row_extent_at);
+	lpStruct->get_caption = (AtkObject* (*)())(*env)->GetIntLongField(env, lpObject, AtkTableIfaceFc.get_caption);
+	lpStruct->get_column_description = (G_CONST_RETURN gchar* (*)())(*env)->GetIntLongField(env, lpObject, AtkTableIfaceFc.get_column_description);
+	lpStruct->get_column_header = (AtkObject* (*)())(*env)->GetIntLongField(env, lpObject, AtkTableIfaceFc.get_column_header);
+	lpStruct->get_row_description = (G_CONST_RETURN gchar* (*)())(*env)->GetIntLongField(env, lpObject, AtkTableIfaceFc.get_row_description);
+	lpStruct->get_row_header = (AtkObject* (*)())(*env)->GetIntLongField(env, lpObject, AtkTableIfaceFc.get_row_header);
+	lpStruct->get_summary = (AtkObject* (*)())(*env)->GetIntLongField(env, lpObject, AtkTableIfaceFc.get_summary);
+	lpStruct->set_caption = (void (*)())(*env)->GetIntLongField(env, lpObject, AtkTableIfaceFc.set_caption);
+	lpStruct->set_column_description = (void (*)())(*env)->GetIntLongField(env, lpObject, AtkTableIfaceFc.set_column_description);
+	lpStruct->set_column_header = (void (*)())(*env)->GetIntLongField(env, lpObject, AtkTableIfaceFc.set_column_header);
+	lpStruct->set_row_description = (void (*)())(*env)->GetIntLongField(env, lpObject, AtkTableIfaceFc.set_row_description);
+	lpStruct->set_row_header = (void (*)())(*env)->GetIntLongField(env, lpObject, AtkTableIfaceFc.set_row_header);
+	lpStruct->set_summary = (void (*)())(*env)->GetIntLongField(env, lpObject, AtkTableIfaceFc.set_summary);
+	lpStruct->get_selected_columns = (gint (*)())(*env)->GetIntLongField(env, lpObject, AtkTableIfaceFc.get_selected_columns);
+	lpStruct->get_selected_rows = (gint (*)())(*env)->GetIntLongField(env, lpObject, AtkTableIfaceFc.get_selected_rows);
+	lpStruct->is_column_selected = (gboolean (*)())(*env)->GetIntLongField(env, lpObject, AtkTableIfaceFc.is_column_selected);
+	lpStruct->is_row_selected = (gboolean (*)())(*env)->GetIntLongField(env, lpObject, AtkTableIfaceFc.is_row_selected);
+	lpStruct->is_selected = (gboolean (*)())(*env)->GetIntLongField(env, lpObject, AtkTableIfaceFc.is_selected);
+	lpStruct->add_row_selection = (gboolean (*)())(*env)->GetIntLongField(env, lpObject, AtkTableIfaceFc.add_row_selection);
+	lpStruct->remove_row_selection = (gboolean (*)())(*env)->GetIntLongField(env, lpObject, AtkTableIfaceFc.remove_row_selection);
+	lpStruct->add_column_selection = (gboolean (*)())(*env)->GetIntLongField(env, lpObject, AtkTableIfaceFc.add_column_selection);
+	lpStruct->remove_column_selection = (gboolean (*)())(*env)->GetIntLongField(env, lpObject, AtkTableIfaceFc.remove_column_selection);
+	lpStruct->row_inserted = (void (*)())(*env)->GetIntLongField(env, lpObject, AtkTableIfaceFc.row_inserted);
+	lpStruct->column_inserted = (void (*)())(*env)->GetIntLongField(env, lpObject, AtkTableIfaceFc.column_inserted);
+	lpStruct->row_deleted = (void (*)())(*env)->GetIntLongField(env, lpObject, AtkTableIfaceFc.row_deleted);
+	lpStruct->column_deleted = (void (*)())(*env)->GetIntLongField(env, lpObject, AtkTableIfaceFc.column_deleted);
+	lpStruct->row_reordered = (void (*)())(*env)->GetIntLongField(env, lpObject, AtkTableIfaceFc.row_reordered);
+	lpStruct->column_reordered = (void (*)())(*env)->GetIntLongField(env, lpObject, AtkTableIfaceFc.column_reordered);
+	lpStruct->model_changed = (void (*)())(*env)->GetIntLongField(env, lpObject, AtkTableIfaceFc.model_changed);
+	return lpStruct;
+}
+
+void setAtkTableIfaceFields(JNIEnv *env, jobject lpObject, AtkTableIface *lpStruct)
+{
+	if (!AtkTableIfaceFc.cached) cacheAtkTableIfaceFields(env, lpObject);
+	(*env)->SetIntLongField(env, lpObject, AtkTableIfaceFc.ref_at, (jintLong)lpStruct->ref_at);
+	(*env)->SetIntLongField(env, lpObject, AtkTableIfaceFc.get_index_at, (jintLong)lpStruct->get_index_at);
+	(*env)->SetIntLongField(env, lpObject, AtkTableIfaceFc.get_column_at_index, (jintLong)lpStruct->get_column_at_index);
+	(*env)->SetIntLongField(env, lpObject, AtkTableIfaceFc.get_row_at_index, (jintLong)lpStruct->get_row_at_index);
+	(*env)->SetIntLongField(env, lpObject, AtkTableIfaceFc.get_n_columns, (jintLong)lpStruct->get_n_columns);
+	(*env)->SetIntLongField(env, lpObject, AtkTableIfaceFc.get_n_rows, (jintLong)lpStruct->get_n_rows);
+	(*env)->SetIntLongField(env, lpObject, AtkTableIfaceFc.get_column_extent_at, (jintLong)lpStruct->get_column_extent_at);
+	(*env)->SetIntLongField(env, lpObject, AtkTableIfaceFc.get_row_extent_at, (jintLong)lpStruct->get_row_extent_at);
+	(*env)->SetIntLongField(env, lpObject, AtkTableIfaceFc.get_caption, (jintLong)lpStruct->get_caption);
+	(*env)->SetIntLongField(env, lpObject, AtkTableIfaceFc.get_column_description, (jintLong)lpStruct->get_column_description);
+	(*env)->SetIntLongField(env, lpObject, AtkTableIfaceFc.get_column_header, (jintLong)lpStruct->get_column_header);
+	(*env)->SetIntLongField(env, lpObject, AtkTableIfaceFc.get_row_description, (jintLong)lpStruct->get_row_description);
+	(*env)->SetIntLongField(env, lpObject, AtkTableIfaceFc.get_row_header, (jintLong)lpStruct->get_row_header);
+	(*env)->SetIntLongField(env, lpObject, AtkTableIfaceFc.get_summary, (jintLong)lpStruct->get_summary);
+	(*env)->SetIntLongField(env, lpObject, AtkTableIfaceFc.set_caption, (jintLong)lpStruct->set_caption);
+	(*env)->SetIntLongField(env, lpObject, AtkTableIfaceFc.set_column_description, (jintLong)lpStruct->set_column_description);
+	(*env)->SetIntLongField(env, lpObject, AtkTableIfaceFc.set_column_header, (jintLong)lpStruct->set_column_header);
+	(*env)->SetIntLongField(env, lpObject, AtkTableIfaceFc.set_row_description, (jintLong)lpStruct->set_row_description);
+	(*env)->SetIntLongField(env, lpObject, AtkTableIfaceFc.set_row_header, (jintLong)lpStruct->set_row_header);
+	(*env)->SetIntLongField(env, lpObject, AtkTableIfaceFc.set_summary, (jintLong)lpStruct->set_summary);
+	(*env)->SetIntLongField(env, lpObject, AtkTableIfaceFc.get_selected_columns, (jintLong)lpStruct->get_selected_columns);
+	(*env)->SetIntLongField(env, lpObject, AtkTableIfaceFc.get_selected_rows, (jintLong)lpStruct->get_selected_rows);
+	(*env)->SetIntLongField(env, lpObject, AtkTableIfaceFc.is_column_selected, (jintLong)lpStruct->is_column_selected);
+	(*env)->SetIntLongField(env, lpObject, AtkTableIfaceFc.is_row_selected, (jintLong)lpStruct->is_row_selected);
+	(*env)->SetIntLongField(env, lpObject, AtkTableIfaceFc.is_selected, (jintLong)lpStruct->is_selected);
+	(*env)->SetIntLongField(env, lpObject, AtkTableIfaceFc.add_row_selection, (jintLong)lpStruct->add_row_selection);
+	(*env)->SetIntLongField(env, lpObject, AtkTableIfaceFc.remove_row_selection, (jintLong)lpStruct->remove_row_selection);
+	(*env)->SetIntLongField(env, lpObject, AtkTableIfaceFc.add_column_selection, (jintLong)lpStruct->add_column_selection);
+	(*env)->SetIntLongField(env, lpObject, AtkTableIfaceFc.remove_column_selection, (jintLong)lpStruct->remove_column_selection);
+	(*env)->SetIntLongField(env, lpObject, AtkTableIfaceFc.row_inserted, (jintLong)lpStruct->row_inserted);
+	(*env)->SetIntLongField(env, lpObject, AtkTableIfaceFc.column_inserted, (jintLong)lpStruct->column_inserted);
+	(*env)->SetIntLongField(env, lpObject, AtkTableIfaceFc.row_deleted, (jintLong)lpStruct->row_deleted);
+	(*env)->SetIntLongField(env, lpObject, AtkTableIfaceFc.column_deleted, (jintLong)lpStruct->column_deleted);
+	(*env)->SetIntLongField(env, lpObject, AtkTableIfaceFc.row_reordered, (jintLong)lpStruct->row_reordered);
+	(*env)->SetIntLongField(env, lpObject, AtkTableIfaceFc.column_reordered, (jintLong)lpStruct->column_reordered);
+	(*env)->SetIntLongField(env, lpObject, AtkTableIfaceFc.model_changed, (jintLong)lpStruct->model_changed);
+}
+#endif
+
 #ifndef NO_AtkTextIface
 typedef struct AtkTextIface_FID_CACHE {
 	int cached;
 	jclass clazz;
-	jfieldID get_text, get_text_after_offset, get_text_at_offset, get_character_at_offset, get_text_before_offset, get_caret_offset, get_run_attributes, get_default_attributes, get_character_extents, get_character_count, get_offset_at_point, get_n_selections, get_selection, add_selection, remove_selection, set_selection, set_caret_offset, text_changed, text_caret_moved, text_selection_changed;
+	jfieldID get_text, get_text_after_offset, get_text_at_offset, get_character_at_offset, get_text_before_offset, get_caret_offset, get_run_attributes, get_default_attributes, get_character_extents, get_character_count, get_offset_at_point, get_n_selections, get_selection, add_selection, remove_selection, set_selection, set_caret_offset, text_changed, text_caret_moved, text_selection_changed, get_range_extents, get_bounded_ranges;
 } AtkTextIface_FID_CACHE;
 
 AtkTextIface_FID_CACHE AtkTextIfaceFc;
@@ -385,6 +558,8 @@ void cacheAtkTextIfaceFields(JNIEnv *env, jobject lpObject)
 	AtkTextIfaceFc.text_changed = (*env)->GetFieldID(env, AtkTextIfaceFc.clazz, "text_changed", I_J);
 	AtkTextIfaceFc.text_caret_moved = (*env)->GetFieldID(env, AtkTextIfaceFc.clazz, "text_caret_moved", I_J);
 	AtkTextIfaceFc.text_selection_changed = (*env)->GetFieldID(env, AtkTextIfaceFc.clazz, "text_selection_changed", I_J);
+	AtkTextIfaceFc.get_range_extents = (*env)->GetFieldID(env, AtkTextIfaceFc.clazz, "get_range_extents", I_J);
+	AtkTextIfaceFc.get_bounded_ranges = (*env)->GetFieldID(env, AtkTextIfaceFc.clazz, "get_bounded_ranges", I_J);
 	AtkTextIfaceFc.cached = 1;
 }
 
@@ -411,6 +586,8 @@ AtkTextIface *getAtkTextIfaceFields(JNIEnv *env, jobject lpObject, AtkTextIface
 	lpStruct->text_changed = (void (*)())(*env)->GetIntLongField(env, lpObject, AtkTextIfaceFc.text_changed);
 	lpStruct->text_caret_moved = (void (*)())(*env)->GetIntLongField(env, lpObject, AtkTextIfaceFc.text_caret_moved);
 	lpStruct->text_selection_changed = (void (*)())(*env)->GetIntLongField(env, lpObject, AtkTextIfaceFc.text_selection_changed);
+	lpStruct->get_range_extents = (void (*)())(*env)->GetIntLongField(env, lpObject, AtkTextIfaceFc.get_range_extents);
+	lpStruct->get_bounded_ranges = (AtkTextRange** (*)())(*env)->GetIntLongField(env, lpObject, AtkTextIfaceFc.get_bounded_ranges);
 	return lpStruct;
 }
 
@@ -437,6 +614,134 @@ void setAtkTextIfaceFields(JNIEnv *env, jobject lpObject, AtkTextIface *lpStruct
 	(*env)->SetIntLongField(env, lpObject, AtkTextIfaceFc.text_changed, (jintLong)lpStruct->text_changed);
 	(*env)->SetIntLongField(env, lpObject, AtkTextIfaceFc.text_caret_moved, (jintLong)lpStruct->text_caret_moved);
 	(*env)->SetIntLongField(env, lpObject, AtkTextIfaceFc.text_selection_changed, (jintLong)lpStruct->text_selection_changed);
+	(*env)->SetIntLongField(env, lpObject, AtkTextIfaceFc.get_range_extents, (jintLong)lpStruct->get_range_extents);
+	(*env)->SetIntLongField(env, lpObject, AtkTextIfaceFc.get_bounded_ranges, (jintLong)lpStruct->get_bounded_ranges);
+}
+#endif
+
+#ifndef NO_AtkTextRange
+typedef struct AtkTextRange_FID_CACHE {
+	int cached;
+	jclass clazz;
+	jfieldID bounds, start_offset, end_offset, content;
+} AtkTextRange_FID_CACHE;
+
+AtkTextRange_FID_CACHE AtkTextRangeFc;
+
+void cacheAtkTextRangeFields(JNIEnv *env, jobject lpObject)
+{
+	if (AtkTextRangeFc.cached) return;
+	AtkTextRangeFc.clazz = (*env)->GetObjectClass(env, lpObject);
+	AtkTextRangeFc.bounds = (*env)->GetFieldID(env, AtkTextRangeFc.clazz, "bounds", "Lorg/eclipse/swt/internal/accessibility/gtk/AtkTextRectangle;");
+	AtkTextRangeFc.start_offset = (*env)->GetFieldID(env, AtkTextRangeFc.clazz, "start_offset", "I");
+	AtkTextRangeFc.end_offset = (*env)->GetFieldID(env, AtkTextRangeFc.clazz, "end_offset", "I");
+	AtkTextRangeFc.content = (*env)->GetFieldID(env, AtkTextRangeFc.clazz, "content", I_J);
+	AtkTextRangeFc.cached = 1;
+}
+
+AtkTextRange *getAtkTextRangeFields(JNIEnv *env, jobject lpObject, AtkTextRange *lpStruct)
+{
+	if (!AtkTextRangeFc.cached) cacheAtkTextRangeFields(env, lpObject);
+	{
+	jobject lpObject1 = (*env)->GetObjectField(env, lpObject, AtkTextRangeFc.bounds);
+	if (lpObject1 != NULL) getAtkTextRectangleFields(env, lpObject1, &lpStruct->bounds);
+	}
+	lpStruct->start_offset = (*env)->GetIntField(env, lpObject, AtkTextRangeFc.start_offset);
+	lpStruct->end_offset = (*env)->GetIntField(env, lpObject, AtkTextRangeFc.end_offset);
+	lpStruct->content = (gchar *)(*env)->GetIntLongField(env, lpObject, AtkTextRangeFc.content);
+	return lpStruct;
+}
+
+void setAtkTextRangeFields(JNIEnv *env, jobject lpObject, AtkTextRange *lpStruct)
+{
+	if (!AtkTextRangeFc.cached) cacheAtkTextRangeFields(env, lpObject);
+	{
+	jobject lpObject1 = (*env)->GetObjectField(env, lpObject, AtkTextRangeFc.bounds);
+	if (lpObject1 != NULL) setAtkTextRectangleFields(env, lpObject1, &lpStruct->bounds);
+	}
+	(*env)->SetIntField(env, lpObject, AtkTextRangeFc.start_offset, (jint)lpStruct->start_offset);
+	(*env)->SetIntField(env, lpObject, AtkTextRangeFc.end_offset, (jint)lpStruct->end_offset);
+	(*env)->SetIntLongField(env, lpObject, AtkTextRangeFc.content, (jintLong)lpStruct->content);
+}
+#endif
+
+#ifndef NO_AtkTextRectangle
+typedef struct AtkTextRectangle_FID_CACHE {
+	int cached;
+	jclass clazz;
+	jfieldID x, y, width, height;
+} AtkTextRectangle_FID_CACHE;
+
+AtkTextRectangle_FID_CACHE AtkTextRectangleFc;
+
+void cacheAtkTextRectangleFields(JNIEnv *env, jobject lpObject)
+{
+	if (AtkTextRectangleFc.cached) return;
+	AtkTextRectangleFc.clazz = (*env)->GetObjectClass(env, lpObject);
+	AtkTextRectangleFc.x = (*env)->GetFieldID(env, AtkTextRectangleFc.clazz, "x", "I");
+	AtkTextRectangleFc.y = (*env)->GetFieldID(env, AtkTextRectangleFc.clazz, "y", "I");
+	AtkTextRectangleFc.width = (*env)->GetFieldID(env, AtkTextRectangleFc.clazz, "width", "I");
+	AtkTextRectangleFc.height = (*env)->GetFieldID(env, AtkTextRectangleFc.clazz, "height", "I");
+	AtkTextRectangleFc.cached = 1;
+}
+
+AtkTextRectangle *getAtkTextRectangleFields(JNIEnv *env, jobject lpObject, AtkTextRectangle *lpStruct)
+{
+	if (!AtkTextRectangleFc.cached) cacheAtkTextRectangleFields(env, lpObject);
+	lpStruct->x = (*env)->GetIntField(env, lpObject, AtkTextRectangleFc.x);
+	lpStruct->y = (*env)->GetIntField(env, lpObject, AtkTextRectangleFc.y);
+	lpStruct->width = (*env)->GetIntField(env, lpObject, AtkTextRectangleFc.width);
+	lpStruct->height = (*env)->GetIntField(env, lpObject, AtkTextRectangleFc.height);
+	return lpStruct;
+}
+
+void setAtkTextRectangleFields(JNIEnv *env, jobject lpObject, AtkTextRectangle *lpStruct)
+{
+	if (!AtkTextRectangleFc.cached) cacheAtkTextRectangleFields(env, lpObject);
+	(*env)->SetIntField(env, lpObject, AtkTextRectangleFc.x, (jint)lpStruct->x);
+	(*env)->SetIntField(env, lpObject, AtkTextRectangleFc.y, (jint)lpStruct->y);
+	(*env)->SetIntField(env, lpObject, AtkTextRectangleFc.width, (jint)lpStruct->width);
+	(*env)->SetIntField(env, lpObject, AtkTextRectangleFc.height, (jint)lpStruct->height);
+}
+#endif
+
+#ifndef NO_AtkValueIface
+typedef struct AtkValueIface_FID_CACHE {
+	int cached;
+	jclass clazz;
+	jfieldID get_current_value, get_maximum_value, get_minimum_value, set_current_value;
+} AtkValueIface_FID_CACHE;
+
+AtkValueIface_FID_CACHE AtkValueIfaceFc;
+
+void cacheAtkValueIfaceFields(JNIEnv *env, jobject lpObject)
+{
+	if (AtkValueIfaceFc.cached) return;
+	AtkValueIfaceFc.clazz = (*env)->GetObjectClass(env, lpObject);
+	AtkValueIfaceFc.get_current_value = (*env)->GetFieldID(env, AtkValueIfaceFc.clazz, "get_current_value", I_J);
+	AtkValueIfaceFc.get_maximum_value = (*env)->GetFieldID(env, AtkValueIfaceFc.clazz, "get_maximum_value", I_J);
+	AtkValueIfaceFc.get_minimum_value = (*env)->GetFieldID(env, AtkValueIfaceFc.clazz, "get_minimum_value", I_J);
+	AtkValueIfaceFc.set_current_value = (*env)->GetFieldID(env, AtkValueIfaceFc.clazz, "set_current_value", I_J);
+	AtkValueIfaceFc.cached = 1;
+}
+
+AtkValueIface *getAtkValueIfaceFields(JNIEnv *env, jobject lpObject, AtkValueIface *lpStruct)
+{
+	if (!AtkValueIfaceFc.cached) cacheAtkValueIfaceFields(env, lpObject);
+	lpStruct->get_current_value = (void (*)())(*env)->GetIntLongField(env, lpObject, AtkValueIfaceFc.get_current_value);
+	lpStruct->get_maximum_value = (void (*)())(*env)->GetIntLongField(env, lpObject, AtkValueIfaceFc.get_maximum_value);
+	lpStruct->get_minimum_value = (void (*)())(*env)->GetIntLongField(env, lpObject, AtkValueIfaceFc.get_minimum_value);
+	lpStruct->set_current_value = (gboolean (*)())(*env)->GetIntLongField(env, lpObject, AtkValueIfaceFc.set_current_value);
+	return lpStruct;
+}
+
+void setAtkValueIfaceFields(JNIEnv *env, jobject lpObject, AtkValueIface *lpStruct)
+{
+	if (!AtkValueIfaceFc.cached) cacheAtkValueIfaceFields(env, lpObject);
+	(*env)->SetIntLongField(env, lpObject, AtkValueIfaceFc.get_current_value, (jintLong)lpStruct->get_current_value);
+	(*env)->SetIntLongField(env, lpObject, AtkValueIfaceFc.get_maximum_value, (jintLong)lpStruct->get_maximum_value);
+	(*env)->SetIntLongField(env, lpObject, AtkValueIfaceFc.get_minimum_value, (jintLong)lpStruct->get_minimum_value);
+	(*env)->SetIntLongField(env, lpObject, AtkValueIfaceFc.set_current_value, (jintLong)lpStruct->set_current_value);
 }
 #endif
 
diff --git a/atk_structs.h b/atk_structs.h
index 85e11a8..cc692cd 100644
--- a/atk_structs.h
+++ b/atk_structs.h
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others. All rights reserved.
+ * Copyright (c) 2000, 2010 IBM Corporation and others. All rights reserved.
  * The contents of this file are made available under the terms
  * of the GNU Lesser General Public License (LGPL) Version 2.1 that
  * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
@@ -27,6 +27,18 @@ void setAtkActionIfaceFields(JNIEnv *env, jobject lpObject, AtkActionIface *lpSt
 #define AtkActionIface_sizeof() 0
 #endif
 
+#ifndef NO_AtkAttribute
+void cacheAtkAttributeFields(JNIEnv *env, jobject lpObject);
+AtkAttribute *getAtkAttributeFields(JNIEnv *env, jobject lpObject, AtkAttribute *lpStruct);
+void setAtkAttributeFields(JNIEnv *env, jobject lpObject, AtkAttribute *lpStruct);
+#define AtkAttribute_sizeof() sizeof(AtkAttribute)
+#else
+#define cacheAtkAttributeFields(a,b)
+#define getAtkAttributeFields(a,b,c) NULL
+#define setAtkAttributeFields(a,b,c)
+#define AtkAttribute_sizeof() 0
+#endif
+
 #ifndef NO_AtkComponentIface
 void cacheAtkComponentIfaceFields(JNIEnv *env, jobject lpObject);
 AtkComponentIface *getAtkComponentIfaceFields(JNIEnv *env, jobject lpObject, AtkComponentIface *lpStruct);
@@ -87,6 +99,18 @@ void setAtkSelectionIfaceFields(JNIEnv *env, jobject lpObject, AtkSelectionIface
 #define AtkSelectionIface_sizeof() 0
 #endif
 
+#ifndef NO_AtkTableIface
+void cacheAtkTableIfaceFields(JNIEnv *env, jobject lpObject);
+AtkTableIface *getAtkTableIfaceFields(JNIEnv *env, jobject lpObject, AtkTableIface *lpStruct);
+void setAtkTableIfaceFields(JNIEnv *env, jobject lpObject, AtkTableIface *lpStruct);
+#define AtkTableIface_sizeof() sizeof(AtkTableIface)
+#else
+#define cacheAtkTableIfaceFields(a,b)
+#define getAtkTableIfaceFields(a,b,c) NULL
+#define setAtkTableIfaceFields(a,b,c)
+#define AtkTableIface_sizeof() 0
+#endif
+
 #ifndef NO_AtkTextIface
 void cacheAtkTextIfaceFields(JNIEnv *env, jobject lpObject);
 AtkTextIface *getAtkTextIfaceFields(JNIEnv *env, jobject lpObject, AtkTextIface *lpStruct);
@@ -99,6 +123,42 @@ void setAtkTextIfaceFields(JNIEnv *env, jobject lpObject, AtkTextIface *lpStruct
 #define AtkTextIface_sizeof() 0
 #endif
 
+#ifndef NO_AtkTextRange
+void cacheAtkTextRangeFields(JNIEnv *env, jobject lpObject);
+AtkTextRange *getAtkTextRangeFields(JNIEnv *env, jobject lpObject, AtkTextRange *lpStruct);
+void setAtkTextRangeFields(JNIEnv *env, jobject lpObject, AtkTextRange *lpStruct);
+#define AtkTextRange_sizeof() sizeof(AtkTextRange)
+#else
+#define cacheAtkTextRangeFields(a,b)
+#define getAtkTextRangeFields(a,b,c) NULL
+#define setAtkTextRangeFields(a,b,c)
+#define AtkTextRange_sizeof() 0
+#endif
+
+#ifndef NO_AtkTextRectangle
+void cacheAtkTextRectangleFields(JNIEnv *env, jobject lpObject);
+AtkTextRectangle *getAtkTextRectangleFields(JNIEnv *env, jobject lpObject, AtkTextRectangle *lpStruct);
+void setAtkTextRectangleFields(JNIEnv *env, jobject lpObject, AtkTextRectangle *lpStruct);
+#define AtkTextRectangle_sizeof() sizeof(AtkTextRectangle)
+#else
+#define cacheAtkTextRectangleFields(a,b)
+#define getAtkTextRectangleFields(a,b,c) NULL
+#define setAtkTextRectangleFields(a,b,c)
+#define AtkTextRectangle_sizeof() 0
+#endif
+
+#ifndef NO_AtkValueIface
+void cacheAtkValueIfaceFields(JNIEnv *env, jobject lpObject);
+AtkValueIface *getAtkValueIfaceFields(JNIEnv *env, jobject lpObject, AtkValueIface *lpStruct);
+void setAtkValueIfaceFields(JNIEnv *env, jobject lpObject, AtkValueIface *lpStruct);
+#define AtkValueIface_sizeof() sizeof(AtkValueIface)
+#else
+#define cacheAtkValueIfaceFields(a,b)
+#define getAtkValueIfaceFields(a,b,c) NULL
+#define setAtkValueIfaceFields(a,b,c)
+#define AtkValueIface_sizeof() 0
+#endif
+
 #ifndef NO_GtkAccessible
 void cacheGtkAccessibleFields(JNIEnv *env, jobject lpObject);
 GtkAccessible *getGtkAccessibleFields(JNIEnv *env, jobject lpObject, GtkAccessible *lpStruct);
diff --git a/build.sh b/build.sh
index 1431d6d..032587e 100755
--- a/build.sh
+++ b/build.sh
@@ -1,6 +1,6 @@
 #!/bin/sh
 #*******************************************************************************
-# Copyright (c) 2000, 2009 IBM Corporation and others.
+# Copyright (c) 2000, 2010 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
@@ -55,6 +55,9 @@ esac
 if [ "${MODEL}" = "" ]; then
 	if uname -i > /dev/null 2>&1; then
 		MODEL=`uname -i`
+		if [ ${MODEL} = 'unknown' ]; then
+		  MODEL=`uname -m`
+		fi
 	else
 		MODEL=`uname -m`
 	fi
@@ -73,15 +76,26 @@ case $MODEL in
 		AWT_ARCH=$MODEL
 		;;
 esac
-
+echo "Model is ${MODEL}"
 # For 64-bit CPUs, we have a switch
 if [ ${MODEL} = 'x86_64' -o ${MODEL} = 'ppc64' -o ${MODEL} = 'ia64' -o ${MODEL} = 's390x' ]; then
 	SWT_PTR_CFLAGS=-DJNI64
-	export SWT_PTR_CFLAGS
 	if [ -d /lib64 ]; then
 		XLIB64=-L/usr/X11R6/lib64
 		export XLIB64
 	fi
+	if [ ${MODEL} = 'ppc64' ]; then
+		SWT_PTR_CFLAGS="${SWT_PTR_CFLAGS} -m64"	
+		XLIB64="${XLIB64} -L/usr/lib64"
+		SWT_LFLAGS=-m64
+		export SWT_LFLAGS
+	fi
+	export SWT_PTR_CFLAGS
+fi
+if [ ${MODEL} = 's390' ]; then
+	SWT_PTR_CFLAGS="-m31"	
+	SWT_LFLAGS=-m31
+	export SWT_LFLAGS SWT_PTR_CFLAGS
 fi
 
 if [ x`pkg-config --exists gnome-vfs-module-2.0 libgnome-2.0 libgnomeui-2.0 && echo YES` = "xYES" ]; then
@@ -125,9 +139,17 @@ if [ -z "${MOZILLA_INCLUDES}" -a -z "${MOZILLA_LIBS}" ]; then
 	fi
 fi
 
+if [ x`pkg-config --exists webkit-1.0 && echo YES` = "xYES" ]; then
+	echo "WebKit found, compiling webkit embedded browser support."
+	MAKE_WEBKIT=make_webkit
+else
+	echo "WebKit not found:"
+	echo "    *** WebKit embedding support will not be compiled."
+fi
+
 # Find AWT if available
 if [ -z "${AWT_LIB_PATH}" ]; then
-	if [ -d ${JAVA_HOME}/jre/lib/${AWT_ARCH} ]; then
+	if [ -f ${JAVA_HOME}/jre/lib/${AWT_ARCH}/libjawt.so ]; then
 		AWT_LIB_PATH=${JAVA_HOME}/jre/lib/${AWT_ARCH}
 		export AWT_LIB_PATH
 	else
@@ -137,6 +159,7 @@ if [ -z "${AWT_LIB_PATH}" ]; then
 fi
 
 if [ -f ${AWT_LIB_PATH}/libjawt.so ]; then
+	echo "libjawt.so found, the SWT/AWT integration library will be compiled."
 	MAKE_AWT=make_awt
 else
 	echo "libjawt.so not found, the SWT/AWT integration library will not be compiled."
@@ -152,5 +175,5 @@ fi
 if [ "x${1}" = "xclean" ]; then
 	${MAKE_TYPE} -f $MAKEFILE clean
 else
-	${MAKE_TYPE} -f $MAKEFILE all $MAKE_GNOME $MAKE_CAIRO $MAKE_AWT $MAKE_MOZILLA ${1} ${2} ${3} ${4} ${5} ${6} ${7} ${8} ${9}
+	${MAKE_TYPE} -f $MAKEFILE all $MAKE_GNOME $MAKE_CAIRO $MAKE_AWT $MAKE_MOZILLA $MAKE_WEBKIT ${1} ${2} ${3} ${4} ${5} ${6} ${7} ${8} ${9}
 fi
diff --git a/build.xml b/build.xml
deleted file mode 100644
index 1c64217..0000000
--- a/build.xml
+++ /dev/null
@@ -1,65 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
<!--
-    Copyright (c) 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
- -->
-
-<project default="build_gtk_lib" basedir="../../..">
-
-<target name="init">
-	<eclipse.refreshLocal resource="org.eclipse.swt" depth="infinite" />
-	<eclipse.refreshLocal resource="org.eclipse.swt.tools" depth="infinite" />	
-   	<eclipse.incrementalBuild project="org.eclipse.swt" kind="incr" />
-</target>
-	
-<!-- Build swt.so for GTK -->
-<target name="build_gtk_lib" depends="init">
-	<exec dir="./bin/library" executable="sh">
-		<arg line="${basedir}/bin/library/build.sh"/>
-		<arg line="install"/>
-	</exec>
-	<eclipse.refreshLocal resource="org.eclipse.swt.gtk.linux.x86" depth="infinite" />
-</target>
-
-<!-- Build swt.so for PowerPC 32 bit GTK (no Mozilla)-->
-<target name="build_ppc_gtk_lib" depends="init">
-	<exec dir="./bin/library" executable="sh">
-		<env key="MODEL" value="ppc"/>
-		<arg line="${basedir}/bin/library/build.sh"/>
-		<arg line="install"/>
-	</exec>
-	<eclipse.refreshLocal resource="org.eclipse.swt.gtk.linux.ppc" depth="infinite" />
-</target>
-
-<!-- Build swt.so for Solaris GTK (no Mozilla) -->
-<target name="build_solaris_gtk_lib" depends="init">
-	<exec dir="./bin/library" executable="sh">
-		<arg line="${basedir}/bin/library/build.sh"/>
-		<arg line="install"/>
-	</exec>
-	<eclipse.refreshLocal resource="org.eclipse.swt.gtk.solaris.sparc" depth="infinite" />
-</target>
-	
-<!-- Build swt.so for GTK 64 -->
-<target name="build_gtk64_lib" depends="init">
-	<exec dir="./bin/library" executable="sh">
-		<arg line="${basedir}/bin/library/build.sh"/>
-		<arg line="install"/>
-	</exec>
-	<eclipse.refreshLocal resource="org.eclipse.swt.gtk.linux.x86_64" depth="infinite" />	
-</target>
-
-<target name="clean">
-	<exec dir="./bin/library" executable="sh">
-		<arg line="${basedir}/bin/library/build.sh"/>
-		<arg line="clean"/>
-	</exec>
-</target>
-
-</project>
\ No newline at end of file
diff --git a/callback.c b/callback.c
index de5b5c4..a344d01 100644
--- a/callback.c
+++ b/callback.c
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -26,6 +26,9 @@ static int callbackEnabled = 1;
 static int callbackEntryCount = 0;
 static int initialized = 0;
 static jint JNI_VERSION = 0;
+#ifdef COCOA
+static NSException *nsException = nil;
+#endif
 
 #ifdef DEBUG_CALL_PRINTS
 static int counter = 0;
@@ -259,6 +262,264 @@ static unsigned char *callbackCode = NULL;
 	FN_##args(125) \
 	FN_##args(126) \
 	FN_##args(127)
+#elif MAX_CALLBACKS == 256
+#define FN_BLOCK(args) \
+	FN_##args(0) \
+	FN_##args(1) \
+	FN_##args(2) \
+	FN_##args(3) \
+	FN_##args(4) \
+	FN_##args(5) \
+	FN_##args(6) \
+	FN_##args(7) \
+	FN_##args(8) \
+	FN_##args(9) \
+	FN_##args(10) \
+	FN_##args(11) \
+	FN_##args(12) \
+	FN_##args(13) \
+	FN_##args(14) \
+	FN_##args(15) \
+	FN_##args(16) \
+	FN_##args(17) \
+	FN_##args(18) \
+	FN_##args(19) \
+	FN_##args(20) \
+	FN_##args(21) \
+	FN_##args(22) \
+	FN_##args(23) \
+	FN_##args(24) \
+	FN_##args(25) \
+	FN_##args(26) \
+	FN_##args(27) \
+	FN_##args(28) \
+	FN_##args(29) \
+	FN_##args(30) \
+	FN_##args(31) \
+	FN_##args(32) \
+	FN_##args(33) \
+	FN_##args(34) \
+	FN_##args(35) \
+	FN_##args(36) \
+	FN_##args(37) \
+	FN_##args(38) \
+	FN_##args(39) \
+	FN_##args(40) \
+	FN_##args(41) \
+	FN_##args(42) \
+	FN_##args(43) \
+	FN_##args(44) \
+	FN_##args(45) \
+	FN_##args(46) \
+	FN_##args(47) \
+	FN_##args(48) \
+	FN_##args(49) \
+	FN_##args(50) \
+	FN_##args(51) \
+	FN_##args(52) \
+	FN_##args(53) \
+	FN_##args(54) \
+	FN_##args(55) \
+	FN_##args(56) \
+	FN_##args(57) \
+	FN_##args(58) \
+	FN_##args(59) \
+	FN_##args(60) \
+	FN_##args(61) \
+	FN_##args(62) \
+	FN_##args(63) \
+	FN_##args(64) \
+	FN_##args(65) \
+	FN_##args(66) \
+	FN_##args(67) \
+	FN_##args(68) \
+	FN_##args(69) \
+	FN_##args(70) \
+	FN_##args(71) \
+	FN_##args(72) \
+	FN_##args(73) \
+	FN_##args(74) \
+	FN_##args(75) \
+	FN_##args(76) \
+	FN_##args(77) \
+	FN_##args(78) \
+	FN_##args(79) \
+	FN_##args(80) \
+	FN_##args(81) \
+	FN_##args(82) \
+	FN_##args(83) \
+	FN_##args(84) \
+	FN_##args(85) \
+	FN_##args(86) \
+	FN_##args(87) \
+	FN_##args(88) \
+	FN_##args(89) \
+	FN_##args(90) \
+	FN_##args(91) \
+	FN_##args(92) \
+	FN_##args(93) \
+	FN_##args(94) \
+	FN_##args(95) \
+	FN_##args(96) \
+	FN_##args(97) \
+	FN_##args(98) \
+	FN_##args(99) \
+	FN_##args(100) \
+	FN_##args(101) \
+	FN_##args(102) \
+	FN_##args(103) \
+	FN_##args(104) \
+	FN_##args(105) \
+	FN_##args(106) \
+	FN_##args(107) \
+	FN_##args(108) \
+	FN_##args(109) \
+	FN_##args(110) \
+	FN_##args(111) \
+	FN_##args(112) \
+	FN_##args(113) \
+	FN_##args(114) \
+	FN_##args(115) \
+	FN_##args(116) \
+	FN_##args(117) \
+	FN_##args(118) \
+	FN_##args(119) \
+	FN_##args(120) \
+	FN_##args(121) \
+	FN_##args(122) \
+	FN_##args(123) \
+	FN_##args(124) \
+	FN_##args(125) \
+	FN_##args(126) \
+	FN_##args(127) \
+	FN_##args(128) \
+	FN_##args(129) \
+	FN_##args(130) \
+	FN_##args(131) \
+	FN_##args(132) \
+	FN_##args(133) \
+	FN_##args(134) \
+	FN_##args(135) \
+	FN_##args(136) \
+	FN_##args(137) \
+	FN_##args(138) \
+	FN_##args(139) \
+	FN_##args(140) \
+	FN_##args(141) \
+	FN_##args(142) \
+	FN_##args(143) \
+	FN_##args(144) \
+	FN_##args(145) \
+	FN_##args(146) \
+	FN_##args(147) \
+	FN_##args(148) \
+	FN_##args(149) \
+	FN_##args(150) \
+	FN_##args(151) \
+	FN_##args(152) \
+	FN_##args(153) \
+	FN_##args(154) \
+	FN_##args(155) \
+	FN_##args(156) \
+	FN_##args(157) \
+	FN_##args(158) \
+	FN_##args(159) \
+	FN_##args(160) \
+	FN_##args(161) \
+	FN_##args(162) \
+	FN_##args(163) \
+	FN_##args(164) \
+	FN_##args(165) \
+	FN_##args(166) \
+	FN_##args(167) \
+	FN_##args(168) \
+	FN_##args(169) \
+	FN_##args(170) \
+	FN_##args(171) \
+	FN_##args(172) \
+	FN_##args(173) \
+	FN_##args(174) \
+	FN_##args(175) \
+	FN_##args(176) \
+	FN_##args(177) \
+	FN_##args(178) \
+	FN_##args(179) \
+	FN_##args(180) \
+	FN_##args(181) \
+	FN_##args(182) \
+	FN_##args(183) \
+	FN_##args(184) \
+	FN_##args(185) \
+	FN_##args(186) \
+	FN_##args(187) \
+	FN_##args(188) \
+	FN_##args(189) \
+	FN_##args(190) \
+	FN_##args(191) \
+	FN_##args(192) \
+	FN_##args(193) \
+	FN_##args(194) \
+	FN_##args(195) \
+	FN_##args(196) \
+	FN_##args(197) \
+	FN_##args(198) \
+	FN_##args(199) \
+	FN_##args(200) \
+	FN_##args(201) \
+	FN_##args(202) \
+	FN_##args(203) \
+	FN_##args(204) \
+	FN_##args(205) \
+	FN_##args(206) \
+	FN_##args(207) \
+	FN_##args(208) \
+	FN_##args(209) \
+	FN_##args(210) \
+	FN_##args(211) \
+	FN_##args(212) \
+	FN_##args(213) \
+	FN_##args(214) \
+	FN_##args(215) \
+	FN_##args(216) \
+	FN_##args(217) \
+	FN_##args(218) \
+	FN_##args(219) \
+	FN_##args(220) \
+	FN_##args(221) \
+	FN_##args(222) \
+	FN_##args(223) \
+	FN_##args(224) \
+	FN_##args(225) \
+	FN_##args(226) \
+	FN_##args(227) \
+	FN_##args(228) \
+	FN_##args(229) \
+	FN_##args(230) \
+	FN_##args(231) \
+	FN_##args(232) \
+	FN_##args(233) \
+	FN_##args(234) \
+	FN_##args(235) \
+	FN_##args(236) \
+	FN_##args(237) \
+	FN_##args(238) \
+	FN_##args(239) \
+	FN_##args(240) \
+	FN_##args(241) \
+	FN_##args(242) \
+	FN_##args(243) \
+	FN_##args(244) \
+	FN_##args(245) \
+	FN_##args(246) \
+	FN_##args(247) \
+	FN_##args(248) \
+	FN_##args(249) \
+	FN_##args(250) \
+	FN_##args(251) \
+	FN_##args(252) \
+	FN_##args(253) \
+	FN_##args(254) \
+	FN_##args(255)
 #else
 #error Invalid MAX_CALLBACKS
 #endif /* MAX_CALLBACKS == 16 */
@@ -438,6 +699,265 @@ FN_BLOCK(12)
 	(jintLong)FN(126, args), \
 	(jintLong)FN(127, args), \
 },
+#elif MAX_CALLBACKS == 256
+#define FN_A_BLOCK(args) { \
+	(jintLong)FN(0, args), \
+	(jintLong)FN(1, args), \
+	(jintLong)FN(2, args), \
+	(jintLong)FN(3, args), \
+	(jintLong)FN(4, args), \
+	(jintLong)FN(5, args), \
+	(jintLong)FN(6, args), \
+	(jintLong)FN(7, args), \
+	(jintLong)FN(8, args), \
+	(jintLong)FN(9, args), \
+	(jintLong)FN(10, args), \
+	(jintLong)FN(11, args), \
+	(jintLong)FN(12, args), \
+	(jintLong)FN(13, args), \
+	(jintLong)FN(14, args), \
+	(jintLong)FN(15, args), \
+	(jintLong)FN(16, args), \
+	(jintLong)FN(17, args), \
+	(jintLong)FN(18, args), \
+	(jintLong)FN(19, args), \
+	(jintLong)FN(20, args), \
+	(jintLong)FN(21, args), \
+	(jintLong)FN(22, args), \
+	(jintLong)FN(23, args), \
+	(jintLong)FN(24, args), \
+	(jintLong)FN(25, args), \
+	(jintLong)FN(26, args), \
+	(jintLong)FN(27, args), \
+	(jintLong)FN(28, args), \
+	(jintLong)FN(29, args), \
+	(jintLong)FN(30, args), \
+	(jintLong)FN(31, args), \
+	(jintLong)FN(32, args), \
+	(jintLong)FN(33, args), \
+	(jintLong)FN(34, args), \
+	(jintLong)FN(35, args), \
+	(jintLong)FN(36, args), \
+	(jintLong)FN(37, args), \
+	(jintLong)FN(38, args), \
+	(jintLong)FN(39, args), \
+	(jintLong)FN(40, args), \
+	(jintLong)FN(41, args), \
+	(jintLong)FN(42, args), \
+	(jintLong)FN(43, args), \
+	(jintLong)FN(44, args), \
+	(jintLong)FN(45, args), \
+	(jintLong)FN(46, args), \
+	(jintLong)FN(47, args), \
+	(jintLong)FN(48, args), \
+	(jintLong)FN(49, args), \
+	(jintLong)FN(50, args), \
+	(jintLong)FN(51, args), \
+	(jintLong)FN(52, args), \
+	(jintLong)FN(53, args), \
+	(jintLong)FN(54, args), \
+	(jintLong)FN(55, args), \
+	(jintLong)FN(56, args), \
+	(jintLong)FN(57, args), \
+	(jintLong)FN(58, args), \
+	(jintLong)FN(59, args), \
+	(jintLong)FN(60, args), \
+	(jintLong)FN(61, args), \
+	(jintLong)FN(62, args), \
+	(jintLong)FN(63, args), \
+	(jintLong)FN(64, args), \
+	(jintLong)FN(65, args), \
+	(jintLong)FN(66, args), \
+	(jintLong)FN(67, args), \
+	(jintLong)FN(68, args), \
+	(jintLong)FN(69, args), \
+	(jintLong)FN(70, args), \
+	(jintLong)FN(71, args), \
+	(jintLong)FN(72, args), \
+	(jintLong)FN(73, args), \
+	(jintLong)FN(74, args), \
+	(jintLong)FN(75, args), \
+	(jintLong)FN(76, args), \
+	(jintLong)FN(77, args), \
+	(jintLong)FN(78, args), \
+	(jintLong)FN(79, args), \
+	(jintLong)FN(80, args), \
+	(jintLong)FN(81, args), \
+	(jintLong)FN(82, args), \
+	(jintLong)FN(83, args), \
+	(jintLong)FN(84, args), \
+	(jintLong)FN(85, args), \
+	(jintLong)FN(86, args), \
+	(jintLong)FN(87, args), \
+	(jintLong)FN(88, args), \
+	(jintLong)FN(89, args), \
+	(jintLong)FN(90, args), \
+	(jintLong)FN(91, args), \
+	(jintLong)FN(92, args), \
+	(jintLong)FN(93, args), \
+	(jintLong)FN(94, args), \
+	(jintLong)FN(95, args), \
+	(jintLong)FN(96, args), \
+	(jintLong)FN(97, args), \
+	(jintLong)FN(98, args), \
+	(jintLong)FN(99, args), \
+	(jintLong)FN(100, args), \
+	(jintLong)FN(101, args), \
+	(jintLong)FN(102, args), \
+	(jintLong)FN(103, args), \
+	(jintLong)FN(104, args), \
+	(jintLong)FN(105, args), \
+	(jintLong)FN(106, args), \
+	(jintLong)FN(107, args), \
+	(jintLong)FN(108, args), \
+	(jintLong)FN(109, args), \
+	(jintLong)FN(110, args), \
+	(jintLong)FN(111, args), \
+	(jintLong)FN(112, args), \
+	(jintLong)FN(113, args), \
+	(jintLong)FN(114, args), \
+	(jintLong)FN(115, args), \
+	(jintLong)FN(116, args), \
+	(jintLong)FN(117, args), \
+	(jintLong)FN(118, args), \
+	(jintLong)FN(119, args), \
+	(jintLong)FN(120, args), \
+	(jintLong)FN(121, args), \
+	(jintLong)FN(122, args), \
+	(jintLong)FN(123, args), \
+	(jintLong)FN(124, args), \
+	(jintLong)FN(125, args), \
+	(jintLong)FN(126, args), \
+	(jintLong)FN(127, args), \
+	(jintLong)FN(128, args), \
+	(jintLong)FN(129, args), \
+	(jintLong)FN(130, args), \
+	(jintLong)FN(131, args), \
+	(jintLong)FN(132, args), \
+	(jintLong)FN(133, args), \
+	(jintLong)FN(134, args), \
+	(jintLong)FN(135, args), \
+	(jintLong)FN(136, args), \
+	(jintLong)FN(137, args), \
+	(jintLong)FN(138, args), \
+	(jintLong)FN(139, args), \
+	(jintLong)FN(140, args), \
+	(jintLong)FN(141, args), \
+	(jintLong)FN(142, args), \
+	(jintLong)FN(143, args), \
+	(jintLong)FN(144, args), \
+	(jintLong)FN(145, args), \
+	(jintLong)FN(146, args), \
+	(jintLong)FN(147, args), \
+	(jintLong)FN(148, args), \
+	(jintLong)FN(149, args), \
+	(jintLong)FN(150, args), \
+	(jintLong)FN(151, args), \
+	(jintLong)FN(152, args), \
+	(jintLong)FN(153, args), \
+	(jintLong)FN(154, args), \
+	(jintLong)FN(155, args), \
+	(jintLong)FN(156, args), \
+	(jintLong)FN(157, args), \
+	(jintLong)FN(158, args), \
+	(jintLong)FN(159, args), \
+	(jintLong)FN(160, args), \
+	(jintLong)FN(161, args), \
+	(jintLong)FN(162, args), \
+	(jintLong)FN(163, args), \
+	(jintLong)FN(164, args), \
+	(jintLong)FN(165, args), \
+	(jintLong)FN(166, args), \
+	(jintLong)FN(167, args), \
+	(jintLong)FN(168, args), \
+	(jintLong)FN(169, args), \
+	(jintLong)FN(170, args), \
+	(jintLong)FN(171, args), \
+	(jintLong)FN(172, args), \
+	(jintLong)FN(173, args), \
+	(jintLong)FN(174, args), \
+	(jintLong)FN(175, args), \
+	(jintLong)FN(176, args), \
+	(jintLong)FN(177, args), \
+	(jintLong)FN(178, args), \
+	(jintLong)FN(179, args), \
+	(jintLong)FN(180, args), \
+	(jintLong)FN(181, args), \
+	(jintLong)FN(182, args), \
+	(jintLong)FN(183, args), \
+	(jintLong)FN(184, args), \
+	(jintLong)FN(185, args), \
+	(jintLong)FN(186, args), \
+	(jintLong)FN(187, args), \
+	(jintLong)FN(188, args), \
+	(jintLong)FN(189, args), \
+	(jintLong)FN(190, args), \
+	(jintLong)FN(191, args), \
+	(jintLong)FN(192, args), \
+	(jintLong)FN(193, args), \
+	(jintLong)FN(194, args), \
+	(jintLong)FN(195, args), \
+	(jintLong)FN(196, args), \
+	(jintLong)FN(197, args), \
+	(jintLong)FN(198, args), \
+	(jintLong)FN(199, args), \
+	(jintLong)FN(200, args), \
+	(jintLong)FN(201, args), \
+	(jintLong)FN(202, args), \
+	(jintLong)FN(203, args), \
+	(jintLong)FN(204, args), \
+	(jintLong)FN(205, args), \
+	(jintLong)FN(206, args), \
+	(jintLong)FN(207, args), \
+	(jintLong)FN(208, args), \
+	(jintLong)FN(209, args), \
+	(jintLong)FN(210, args), \
+	(jintLong)FN(211, args), \
+	(jintLong)FN(212, args), \
+	(jintLong)FN(213, args), \
+	(jintLong)FN(214, args), \
+	(jintLong)FN(215, args), \
+	(jintLong)FN(216, args), \
+	(jintLong)FN(217, args), \
+	(jintLong)FN(218, args), \
+	(jintLong)FN(219, args), \
+	(jintLong)FN(220, args), \
+	(jintLong)FN(221, args), \
+	(jintLong)FN(222, args), \
+	(jintLong)FN(223, args), \
+	(jintLong)FN(224, args), \
+	(jintLong)FN(225, args), \
+	(jintLong)FN(226, args), \
+	(jintLong)FN(227, args), \
+	(jintLong)FN(228, args), \
+	(jintLong)FN(229, args), \
+	(jintLong)FN(230, args), \
+	(jintLong)FN(231, args), \
+	(jintLong)FN(232, args), \
+	(jintLong)FN(233, args), \
+	(jintLong)FN(234, args), \
+	(jintLong)FN(235, args), \
+	(jintLong)FN(236, args), \
+	(jintLong)FN(237, args), \
+	(jintLong)FN(238, args), \
+	(jintLong)FN(239, args), \
+	(jintLong)FN(240, args), \
+	(jintLong)FN(241, args), \
+	(jintLong)FN(242, args), \
+	(jintLong)FN(243, args), \
+	(jintLong)FN(244, args), \
+	(jintLong)FN(245, args), \
+	(jintLong)FN(246, args), \
+	(jintLong)FN(247, args), \
+	(jintLong)FN(248, args), \
+	(jintLong)FN(249, args), \
+	(jintLong)FN(250, args), \
+	(jintLong)FN(251, args), \
+	(jintLong)FN(252, args), \
+	(jintLong)FN(253, args), \
+	(jintLong)FN(254, args), \
+	(jintLong)FN(255, args), \
+},
 #else
 #error Invalid MAX_CALLBACKS
 #endif /* MAX_CALLBACKS == 16 */
@@ -651,6 +1171,7 @@ jintLong callback(int index, ...)
 	jboolean isArrayBased = callbackData[index].isArrayBased;
 	jint argCount = callbackData[index].argCount;
 	jintLong result = callbackData[index].errorResult;
+	jthrowable ex;
 	int detach = 0;
 	va_list vl;
 
@@ -686,7 +1207,8 @@ jintLong callback(int index, ...)
 	}
 
 	/* If an exception has occurred in previous callbacks do not call into the VM. */
-	if ((*env)->ExceptionOccurred(env)) {
+	if ((ex = (*env)->ExceptionOccurred(env))) {
+		(*env)->DeleteLocalRef(env, ex);
 		goto done;
 	}
 
@@ -724,15 +1246,29 @@ jintLong callback(int index, ...)
 	}
 	va_end(vl);
 	ATOMIC_DEC(callbackEntryCount);
-	
+
+#ifdef COCOA
+	if (callbackEntryCount == 0 && nsException) {
+		[nsException release];
+		nsException = nil;
+	}
+#endif
+				
 done:
 	/* If an exception has occurred in Java, return the error result. */
-	if ((*env)->ExceptionOccurred(env)) {
+	if ((ex = (*env)->ExceptionOccurred(env))) {
+		(*env)->DeleteLocalRef(env, ex);
 #ifdef DEBUG_CALL_PRINTS
 		fprintf(stderr, "* java exception occurred\n");
 		(*env)->ExceptionDescribe(env);
 #endif
 		result = callbackData[index].errorResult;
+#ifdef COCOA
+		if (nsException == NULL) {
+			nsException = [[NSException alloc] initWithName:NSGenericException reason:@"Java exception occurred" userInfo:nil];
+			[nsException raise];
+		}
+#endif
 	}
 
 	if (detach) {
diff --git a/callback.h b/callback.h
index 040ac69..352d67b 100644
--- a/callback.h
+++ b/callback.h
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -23,6 +23,10 @@
 #define RETURN_CAST (LRESULT)
 #endif
 
+#if defined COCOA
+#import <Foundation/Foundation.h>
+#endif
+
 #ifndef RETURN_TYPE
 #define RETURN_TYPE jintLong
 #endif
@@ -41,7 +45,7 @@
 #ifdef REDUCED_CALLBACKS
 #define MAX_CALLBACKS 16
 #else
-#ifdef USE_ASSEMBLER
+#if (defined(USE_ASSEMBLER) || defined(GTK))
 #define MAX_CALLBACKS 256
 #else
 #define MAX_CALLBACKS 128
diff --git a/gnome.c b/gnome.c
index c74ea71..4160de1 100644
--- a/gnome.c
+++ b/gnome.c
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others. All rights reserved.
+ * Copyright (c) 2000, 2010 IBM Corporation and others. All rights reserved.
  * The contents of this file are made available under the terms
  * of the GNU Lesser General Public License (LGPL) Version 2.1 that
  * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
@@ -141,6 +141,18 @@ JNIEXPORT jintLong JNICALL GNOME_NATIVE(_1gnome_1icon_1theme_1new)
 }
 #endif
 
+#ifndef NO__1gnome_1vfs_1get_1mime_1type
+JNIEXPORT jintLong JNICALL GNOME_NATIVE(_1gnome_1vfs_1get_1mime_1type)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	GNOME_NATIVE_ENTER(env, that, _1gnome_1vfs_1get_1mime_1type_FUNC);
+	rc = (jintLong)gnome_vfs_get_mime_type((const char *)arg0);
+	GNOME_NATIVE_EXIT(env, that, _1gnome_1vfs_1get_1mime_1type_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO__1gnome_1vfs_1get_1registered_1mime_1types
 JNIEXPORT jintLong JNICALL GNOME_NATIVE(_1gnome_1vfs_1get_1registered_1mime_1types)
 	(JNIEnv *env, jclass that)
@@ -165,6 +177,22 @@ JNIEXPORT jboolean JNICALL GNOME_NATIVE(_1gnome_1vfs_1init)
 }
 #endif
 
+#ifndef NO__1gnome_1vfs_1is_1executable_1command_1string
+JNIEXPORT jboolean JNICALL GNOME_NATIVE(_1gnome_1vfs_1is_1executable_1command_1string)
+	(JNIEnv *env, jclass that, jbyteArray arg0)
+{
+	jbyte *lparg0=NULL;
+	jboolean rc = 0;
+	GNOME_NATIVE_ENTER(env, that, _1gnome_1vfs_1is_1executable_1command_1string_FUNC);
+	if (arg0) if ((lparg0 = (*env)->GetByteArrayElements(env, arg0, NULL)) == NULL) goto fail;
+	rc = (jboolean)gnome_vfs_is_executable_command_string((const char *)lparg0);
+fail:
+	if (arg0 && lparg0) (*env)->ReleaseByteArrayElements(env, arg0, lparg0, 0);
+	GNOME_NATIVE_EXIT(env, that, _1gnome_1vfs_1is_1executable_1command_1string_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO__1gnome_1vfs_1make_1uri_1from_1input
 JNIEXPORT jintLong JNICALL GNOME_NATIVE(_1gnome_1vfs_1make_1uri_1from_1input)
 	(JNIEnv *env, jclass that, jbyteArray arg0)
@@ -299,6 +327,22 @@ fail:
 }
 #endif
 
+#ifndef NO__1gnome_1vfs_1mime_1type_1get_1equivalence
+JNIEXPORT jintLong JNICALL GNOME_NATIVE(_1gnome_1vfs_1mime_1type_1get_1equivalence)
+	(JNIEnv *env, jclass that, jintLong arg0, jbyteArray arg1)
+{
+	jbyte *lparg1=NULL;
+	jintLong rc = 0;
+	GNOME_NATIVE_ENTER(env, that, _1gnome_1vfs_1mime_1type_1get_1equivalence_FUNC);
+	if (arg1) if ((lparg1 = (*env)->GetByteArrayElements(env, arg1, NULL)) == NULL) goto fail;
+	rc = (jintLong)gnome_vfs_mime_type_get_equivalence((const char *)arg0, (const char *)lparg1);
+fail:
+	if (arg1 && lparg1) (*env)->ReleaseByteArrayElements(env, arg1, lparg1, 0);
+	GNOME_NATIVE_EXIT(env, that, _1gnome_1vfs_1mime_1type_1get_1equivalence_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO__1gnome_1vfs_1url_1show
 JNIEXPORT jint JNICALL GNOME_NATIVE(_1gnome_1vfs_1url_1show)
 	(JNIEnv *env, jclass that, jintLong arg0)
diff --git a/gnome_stats.c b/gnome_stats.c
index e541d8e..27d6a54 100644
--- a/gnome_stats.c
+++ b/gnome_stats.c
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others. All rights reserved.
+ * Copyright (c) 2000, 2010 IBM Corporation and others. All rights reserved.
  * The contents of this file are made available under the terms
  * of the GNU Lesser General Public License (LGPL) Version 2.1 that
  * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
@@ -18,8 +18,8 @@
 
 #ifdef NATIVE_STATS
 
-int GNOME_nativeFunctionCount = 22;
-int GNOME_nativeFunctionCallCount[22];
+int GNOME_nativeFunctionCount = 25;
+int GNOME_nativeFunctionCallCount[25];
 char * GNOME_nativeFunctionNames[] = {
 	"GnomeVFSMimeApplication_1sizeof",
 	"_1g_1free",
@@ -30,8 +30,10 @@ char * GNOME_nativeFunctionNames[] = {
 	"_1gnome_1icon_1lookup",
 	"_1gnome_1icon_1theme_1lookup_1icon",
 	"_1gnome_1icon_1theme_1new",
+	"_1gnome_1vfs_1get_1mime_1type",
 	"_1gnome_1vfs_1get_1registered_1mime_1types",
 	"_1gnome_1vfs_1init",
+	"_1gnome_1vfs_1is_1executable_1command_1string",
 	"_1gnome_1vfs_1make_1uri_1from_1input",
 	"_1gnome_1vfs_1make_1uri_1from_1input_1with_1dirs",
 	"_1gnome_1vfs_1mime_1application_1free",
@@ -41,6 +43,7 @@ char * GNOME_nativeFunctionNames[] = {
 	"_1gnome_1vfs_1mime_1get_1extensions_1list",
 	"_1gnome_1vfs_1mime_1registered_1mime_1type_1list_1free",
 	"_1gnome_1vfs_1mime_1type_1from_1name",
+	"_1gnome_1vfs_1mime_1type_1get_1equivalence",
 	"_1gnome_1vfs_1url_1show",
 	"memmove",
 };
diff --git a/gnome_stats.h b/gnome_stats.h
index 8aea1d9..eea5ffe 100644
--- a/gnome_stats.h
+++ b/gnome_stats.h
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others. All rights reserved.
+ * Copyright (c) 2000, 2010 IBM Corporation and others. All rights reserved.
  * The contents of this file are made available under the terms
  * of the GNU Lesser General Public License (LGPL) Version 2.1 that
  * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
@@ -38,8 +38,10 @@ typedef enum {
 	_1gnome_1icon_1lookup_FUNC,
 	_1gnome_1icon_1theme_1lookup_1icon_FUNC,
 	_1gnome_1icon_1theme_1new_FUNC,
+	_1gnome_1vfs_1get_1mime_1type_FUNC,
 	_1gnome_1vfs_1get_1registered_1mime_1types_FUNC,
 	_1gnome_1vfs_1init_FUNC,
+	_1gnome_1vfs_1is_1executable_1command_1string_FUNC,
 	_1gnome_1vfs_1make_1uri_1from_1input_FUNC,
 	_1gnome_1vfs_1make_1uri_1from_1input_1with_1dirs_FUNC,
 	_1gnome_1vfs_1mime_1application_1free_FUNC,
@@ -49,6 +51,7 @@ typedef enum {
 	_1gnome_1vfs_1mime_1get_1extensions_1list_FUNC,
 	_1gnome_1vfs_1mime_1registered_1mime_1type_1list_1free_FUNC,
 	_1gnome_1vfs_1mime_1type_1from_1name_FUNC,
+	_1gnome_1vfs_1mime_1type_1get_1equivalence_FUNC,
 	_1gnome_1vfs_1url_1show_FUNC,
 	memmove_FUNC,
 } GNOME_FUNCS;
diff --git a/make_common.mak b/make_common.mak
index 7f77d9e..af8082b 100644
--- a/make_common.mak
+++ b/make_common.mak
@@ -1,5 +1,5 @@
 #*******************************************************************************
-# Copyright (c) 2000, 2009 IBM Corporation and others.
+# Copyright (c) 2000, 2010 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
@@ -10,5 +10,5 @@
 #*******************************************************************************
 
 maj_ver=3
-min_ver=555
-comma_ver=3,5,5,5
+min_ver=655
+comma_ver=3,6,5,5
diff --git a/make_freebsd.mak b/make_freebsd.mak
index 82b4dab..6f71c76 100644
--- a/make_freebsd.mak
+++ b/make_freebsd.mak
@@ -1,5 +1,5 @@
 #*******************************************************************************
-# Copyright (c) 2000, 2007 IBM Corporation and others.
+# Copyright (c) 2000, 2010 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
@@ -50,7 +50,8 @@ GTKLIBS = `pkg-config --libs-only-L gtk+-2.0 gthread-2.0` -lgtk-x11-2.0 -lgthrea
 
 CDE_LIBS = -L$(CDE_HOME)/lib -R$(CDE_HOME)/lib -lXt -lX11 -lDtSvc
 
-AWT_LIBS = -L$(AWT_LIB_PATH) -ljawt -shared
+AWT_LFLAGS = -shared
+AWT_LIBS = -L$(AWT_LIB_PATH) -ljawt
 
 ATKCFLAGS = `pkg-config --cflags atk gtk+-2.0`
 ATKLIBS = `pkg-config --libs-only-L atk gtk+-2.0` -latk-1.0 -lgtk-x11-2.0
@@ -58,8 +59,7 @@ ATKLIBS = `pkg-config --libs-only-L atk gtk+-2.0` -latk-1.0 -lgtk-x11-2.0
 GNOMECFLAGS = `pkg-config --cflags gnome-vfs-module-2.0 libgnome-2.0 libgnomeui-2.0`
 GNOMELIBS = `pkg-config --libs-only-L gnome-vfs-module-2.0 libgnome-2.0 libgnomeui-2.0` -lgnomevfs-2 -lgnome-2 -lgnomeui-2
 
-GLXCFLAGS = 
-GLXLIBS = -shared -fPIC -L/usr/X11R6/lib -lGL -lGLU -lm
+GLXLIBS = -L/usr/X11R6/lib -lGL -lGLU -lm
 
 # Uncomment for Native Stats tool
 #NATIVE_STATS = -DNATIVE_STATS
@@ -77,7 +77,7 @@ MOZILLACFLAGS = -O \
 	-I$(JAVA_HOME)/include \
 	-I$(JAVA_HOME)/include/freebsd \
 	${SWT_PTR_CFLAGS}
-MOZILLALIBS = -shared -Wl,--version-script=mozilla_exports -Bsymbolic
+MOZILLALFLAGS = -shared -Wl,--version-script=mozilla_exports -Bsymbolic
 	
 SWT_OBJECTS = swt.o c.o c_stats.o callback.o
 CDE_OBJECTS = swt.o cde.o cde_structs.o cde_stats.o
@@ -99,12 +99,12 @@ CFLAGS = -O -Wall \
 		-I$(JAVA_HOME)/include/freebsd \
 		-fPIC \
 		${SWT_PTR_CFLAGS}
-LIBS = -shared -fPIC
+LFLAGS = -shared -fPIC
 
 ifndef NO_STRIP
-	AWT_LIBS := $(AWT_LIBS) -s
-	MOZILLALIBS := $(MOZILLALIBS) -s
-	LIBS := $(LIBS) -s
+	AWT_LFLAGS := $(AWT_LFLAGS) -s
+	MOZILLALFLAGS := $(MOZILLALFLAGS) -s
+	LFLAGS := $(LFLAGS) -s
 endif
 
 all: make_swt make_atk make_gnome make_glx
@@ -115,13 +115,13 @@ all: make_swt make_atk make_gnome make_glx
 make_swt: $(SWT_LIB) $(SWTPI_LIB)
 
 $(SWT_LIB): $(SWT_OBJECTS)
-	$(CC) $(LIBS) -o $(SWT_LIB) $(SWT_OBJECTS)
+	$(CC) $(LFLAGS) -o $(SWT_LIB) $(SWT_OBJECTS)
 
 callback.o: callback.c callback.h
 	$(CC) $(CFLAGS) -DUSE_ASSEMBLER -c callback.c
 
 $(SWTPI_LIB): $(SWTPI_OBJECTS)
-	$(CC) $(LIBS) $(GTKLIBS) -o $(SWTPI_LIB) $(SWTPI_OBJECTS)
+	$(CC) $(LFLAGS) -o $(SWTPI_LIB) $(SWTPI_OBJECTS) $(GTKLIBS)
 
 swt.o: swt.c swt.h
 	$(CC) $(CFLAGS) -c swt.c
@@ -140,7 +140,7 @@ os_stats.o: os_stats.c os_structs.h os.h os_stats.h swt.h
 make_cairo: $(CAIRO_LIB)
 
 $(CAIRO_LIB): $(CAIRO_OBJECTS)
-	$(CC) $(LIBS) $(CAIROLIBS) -o $(CAIRO_LIB) $(CAIRO_OBJECTS)
+	$(CC) $(LFLAGS) -o $(CAIRO_LIB) $(CAIRO_OBJECTS) $(CAIROLIBS)
 
 cairo.o: cairo.c cairo.h swt.h
 	$(CC) $(CFLAGS) $(CAIROCFLAGS) -c cairo.c
@@ -156,7 +156,7 @@ cairo_stats.o: cairo_stats.c cairo_structs.h cairo.h cairo_stats.h swt.h
 make_cde: $(CDE_LIB)
 
 $(CDE_LIB): $(CDE_OBJECTS)
-	$(CC) $(LIBS) $(CDE_LIBS) -o $(CDE_LIB) $(CDE_OBJECTS)
+	$(CC) $(LFLAGS) -o $(CDE_LIB) $(CDE_OBJECTS) $(CDE_LIBS)
 
 #
 # AWT lib
@@ -164,7 +164,7 @@ $(CDE_LIB): $(CDE_OBJECTS)
 make_awt:$(AWT_LIB)
 
 $(AWT_LIB): $(AWT_OBJECTS)
-	$(CC) $(AWT_LIBS) -o $(AWT_LIB) $(AWT_OBJECTS)
+	$(CC) $(AWT_LFLAGS) -o $(AWT_LIB) $(AWT_OBJECTS) $(AWT_LIBS)
 
 #
 # Atk lib
@@ -172,7 +172,7 @@ $(AWT_LIB): $(AWT_OBJECTS)
 make_atk: $(ATK_LIB)
 
 $(ATK_LIB): $(ATK_OBJECTS)
-	$(CC) $(LIBS) $(ATKLIBS) -o $(ATK_LIB) $(ATK_OBJECTS)
+	$(CC) $(LFLAGS) -o $(ATK_LIB) $(ATK_OBJECTS) $(ATKLIBS)
 
 atk.o: atk.c atk.h
 	$(CC) $(CFLAGS) $(ATKCFLAGS) -c atk.c
@@ -189,7 +189,7 @@ atk_stats.o: atk_stats.c atk_structs.h atk_stats.h atk.h
 make_gnome: $(GNOME_LIB)
 
 $(GNOME_LIB): $(GNOME_OBJECTS)
-	$(CC) $(LIBS) $(GNOMELIBS) -o $(GNOME_LIB) $(GNOME_OBJECTS)
+	$(CC) $(LFLAGS) -o $(GNOME_LIB) $(GNOME_OBJECTS) $(GNOMELIBS)
 
 gnome.o: gnome.c 
 	$(CC) $(CFLAGS) $(GNOMECFLAGS) -c gnome.c
@@ -206,7 +206,7 @@ gnome_stats.o: gnome_stats.c gnome_stats.h
 make_mozilla:$(MOZILLA_LIB)
 
 $(MOZILLA_LIB): $(MOZILLA_OBJECTS)
-	$(CXX) -o $(MOZILLA_LIB) $(MOZILLA_OBJECTS) $(MOZILLALIBS) ${MOZILLA_LIBS}
+	$(CXX) -o $(MOZILLA_LIB) $(MOZILLA_OBJECTS) $(MOZILLALFLAGS) ${MOZILLA_LIBS}
 
 xpcom.o: xpcom.cpp
 	$(CXX) $(MOZILLACFLAGS) ${MOZILLA_INCLUDES} -c xpcom.cpp
@@ -226,7 +226,7 @@ xpcom_stats.o: xpcom_stats.cpp
 make_xulrunner:$(XULRUNNER_LIB)
 
 $(XULRUNNER_LIB): $(XULRUNNER_OBJECTS)
-	$(CXX) -o $(XULRUNNER_LIB) $(XULRUNNER_OBJECTS) $(MOZILLALIBS) ${XULRUNNER_LIBS}
+	$(CXX) -o $(XULRUNNER_LIB) $(XULRUNNER_OBJECTS) $(MOZILLALFLAGS) ${XULRUNNER_LIBS}
 
 xpcomxul.o: xpcom.cpp
 	$(CXX) -o xpcomxul.o $(MOZILLACFLAGS) ${XULRUNNER_INCLUDES} -c xpcom.cpp
@@ -252,7 +252,7 @@ xpcomxulglue_stats.o: xpcomglue_stats.cpp
 make_xpcominit:$(XPCOMINIT_LIB)
 
 $(XPCOMINIT_LIB): $(XPCOMINIT_OBJECTS)
-	$(CXX) -o $(XPCOMINIT_LIB) $(XPCOMINIT_OBJECTS) $(MOZILLALIBS) ${XULRUNNER_LIBS}
+	$(CXX) -o $(XPCOMINIT_LIB) $(XPCOMINIT_OBJECTS) $(MOZILLALFLAGS) ${XULRUNNER_LIBS}
 
 xpcominit.o: xpcominit.cpp
 	$(CXX) $(MOZILLACFLAGS) ${XULRUNNER_INCLUDES} -c xpcominit.cpp
@@ -269,7 +269,7 @@ xpcominit_stats.o: xpcominit_stats.cpp
 make_glx: $(GLX_LIB)
 
 $(GLX_LIB): $(GLX_OBJECTS)
-	$(CC) $(LIBS) $(GLXLIBS) -o $(GLX_LIB) $(GLX_OBJECTS)
+	$(CC) $(LFLAGS) -o $(GLX_LIB) $(GLX_OBJECTS) $(GLXLIBS)
 
 glx.o: glx.c 
 	$(CC) $(CFLAGS) $(GLXCFLAGS) -c glx.c
diff --git a/make_linux.mak b/make_linux.mak
index c1bc1a1..8b8f1a8 100644
--- a/make_linux.mak
+++ b/make_linux.mak
@@ -1,5 +1,5 @@
 #*******************************************************************************
-# Copyright (c) 2000, 2009 IBM Corporation and others.
+# Copyright (c) 2000, 2010 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
@@ -27,6 +27,7 @@ GNOME_PREFIX = swt-gnome
 MOZILLA_PREFIX = swt-mozilla$(GCC_VERSION)
 XULRUNNER_PREFIX = swt-xulrunner
 XPCOMINIT_PREFIX = swt-xpcominit
+WEBKIT_PREFIX = swt-webkit
 GLX_PREFIX = swt-glx
 
 SWT_LIB = lib$(SWT_PREFIX)-$(WS_PREFIX)-$(SWT_VERSION).so
@@ -39,6 +40,7 @@ GNOME_LIB = lib$(GNOME_PREFIX)-$(WS_PREFIX)-$(SWT_VERSION).so
 MOZILLA_LIB = lib$(MOZILLA_PREFIX)-$(WS_PREFIX)-$(SWT_VERSION).so
 XULRUNNER_LIB = lib$(XULRUNNER_PREFIX)-$(WS_PREFIX)-$(SWT_VERSION).so
 XPCOMINIT_LIB = lib$(XPCOMINIT_PREFIX)-$(WS_PREFIX)-$(SWT_VERSION).so
+WEBKIT_LIB = lib$(WEBKIT_PREFIX)-$(WS_PREFIX)-$(SWT_VERSION).so
 GLX_LIB = lib$(GLX_PREFIX)-$(WS_PREFIX)-$(SWT_VERSION).so
 
 CAIROCFLAGS = `pkg-config --cflags cairo`
@@ -46,11 +48,12 @@ CAIROLIBS = `pkg-config --libs-only-L cairo` -lcairo
 
 # Do not use pkg-config to get libs because it includes unnecessary dependencies (i.e. pangoxft-1.0)
 GTKCFLAGS = `pkg-config --cflags gtk+-2.0`
-GTKLIBS = `pkg-config --libs-only-L gtk+-2.0 gthread-2.0` -lgtk-x11-2.0 -lgthread-2.0 -L/usr/X11R6/lib $(XLIB64) -lXtst
+GTKLIBS = `pkg-config --libs-only-L gtk+-2.0 gthread-2.0` $(XLIB64) -L/usr/X11R6/lib -lgtk-x11-2.0 -lgthread-2.0 -lXtst
 
 CDE_LIBS = -L$(CDE_HOME)/lib -R$(CDE_HOME)/lib -lXt -lX11 -lDtSvc
 
-AWT_LIBS = -L$(AWT_LIB_PATH) -ljawt -shared
+AWT_LFLAGS = -shared ${SWT_LFLAGS} 
+AWT_LIBS = -L$(AWT_LIB_PATH) -ljawt
 
 ATKCFLAGS = `pkg-config --cflags atk gtk+-2.0`
 ATKLIBS = `pkg-config --libs-only-L atk gtk+-2.0` -latk-1.0 -lgtk-x11-2.0
@@ -58,8 +61,7 @@ ATKLIBS = `pkg-config --libs-only-L atk gtk+-2.0` -latk-1.0 -lgtk-x11-2.0
 GNOMECFLAGS = `pkg-config --cflags gnome-vfs-module-2.0 libgnome-2.0 libgnomeui-2.0`
 GNOMELIBS = `pkg-config --libs-only-L gnome-vfs-module-2.0 libgnome-2.0 libgnomeui-2.0` -lgnomevfs-2 -lgnome-2 -lgnomeui-2
 
-GLXCFLAGS = 
-GLXLIBS = -shared -fPIC -L/usr/X11R6/lib -lGL -lGLU -lm
+GLXLIBS = -L/usr/X11R6/lib -lGL -lGLU -lm
 
 # Uncomment for Native Stats tool
 #NATIVE_STATS = -DNATIVE_STATS
@@ -77,7 +79,7 @@ MOZILLACFLAGS = -O \
 	-I$(JAVA_HOME)/include \
 	-I$(JAVA_HOME)/include/linux \
 	${SWT_PTR_CFLAGS}
-MOZILLALIBS = -shared -Wl,--version-script=mozilla_exports -Bsymbolic
+MOZILLALFLAGS = -shared -Wl,--version-script=mozilla_exports -Bsymbolic
 MOZILLAEXCLUDES = -DNO__1XPCOMGlueShutdown \
 	-DNO__1XPCOMGlueStartup \
 	-DNO__1XPCOMGlueLoadXULFunctions \
@@ -89,6 +91,9 @@ MOZILLAEXCLUDES = -DNO__1XPCOMGlueShutdown \
 	-DNO_nsDynamicFunctionLoad
 XULRUNNEREXCLUDES = -DNO__1NS_1InitXPCOM2
 
+WEBKITCFLAGS = `pkg-config --cflags gtk+-2.0` -I/usr/include/webkit-1.0 -I/usr/include/libsoup-2.4
+WEBKITLIBS = -lwebkit-1.0
+
 SWT_OBJECTS = swt.o c.o c_stats.o callback.o
 CDE_OBJECTS = swt.o cde.o cde_structs.o cde_stats.o
 AWT_OBJECTS = swt_awt.o
@@ -99,6 +104,7 @@ GNOME_OBJECTS = swt.o gnome.o gnome_structs.o gnome_stats.o
 MOZILLA_OBJECTS = swt.o xpcom.o xpcom_custom.o xpcom_structs.o xpcom_stats.o
 XULRUNNER_OBJECTS = swt.o xpcomxul.o xpcomxul_custom.o xpcomxul_structs.o xpcomxul_stats.o
 XPCOMINIT_OBJECTS = swt.o xpcominit.o xpcominit_structs.o xpcominit_stats.o
+WEBKIT_OBJECTS = swt.o webkit.o webkit_structs.o webkit_stats.o
 GLX_OBJECTS = swt.o glx.o glx_structs.o glx_stats.o
 
 CFLAGS = -O -Wall \
@@ -109,15 +115,15 @@ CFLAGS = -O -Wall \
 		-I$(JAVA_HOME)/include/linux \
 		-fPIC \
 		${SWT_PTR_CFLAGS}
-LIBS = -shared -fPIC
+LFLAGS = -shared -fPIC ${SWT_LFLAGS}
 
 ifndef NO_STRIP
-	AWT_LIBS := $(AWT_LIBS) -s
-	MOZILLALIBS := $(MOZILLALIBS) -s
-	LIBS := $(LIBS) -s
+	AWT_LFLAGS := $(AWT_LFLAGS) -s
+	MOZILLALFLAGS := $(MOZILLALFLAGS) -s
+	LFLAGS := $(LFLAGS) -s
 endif
 
-all: make_swt make_atk make_gnome make_glx
+all: make_swt make_atk make_glx
 
 #
 # SWT libs
@@ -125,13 +131,13 @@ all: make_swt make_atk make_gnome make_glx
 make_swt: $(SWT_LIB) $(SWTPI_LIB)
 
 $(SWT_LIB): $(SWT_OBJECTS)
-	$(CC) $(LIBS) -o $(SWT_LIB) $(SWT_OBJECTS)
+	$(CC) $(LFLAGS) -o $(SWT_LIB) $(SWT_OBJECTS)
 
 callback.o: callback.c callback.h
 	$(CC) $(CFLAGS) -DUSE_ASSEMBLER -c callback.c
 
 $(SWTPI_LIB): $(SWTPI_OBJECTS)
-	$(CC) $(LIBS) $(GTKLIBS) -o $(SWTPI_LIB) $(SWTPI_OBJECTS)
+	$(CC) $(LFLAGS) -o $(SWTPI_LIB) $(SWTPI_OBJECTS) $(GTKLIBS)
 
 swt.o: swt.c swt.h
 	$(CC) $(CFLAGS) -c swt.c
@@ -150,7 +156,7 @@ os_stats.o: os_stats.c os_structs.h os.h os_stats.h swt.h
 make_cairo: $(CAIRO_LIB)
 
 $(CAIRO_LIB): $(CAIRO_OBJECTS)
-	$(CC) $(LIBS) $(CAIROLIBS) -o $(CAIRO_LIB) $(CAIRO_OBJECTS)
+	$(CC) $(LFLAGS) -o $(CAIRO_LIB) $(CAIRO_OBJECTS) $(CAIROLIBS)
 
 cairo.o: cairo.c cairo.h swt.h
 	$(CC) $(CFLAGS) $(CAIROCFLAGS) -c cairo.c
@@ -166,7 +172,7 @@ cairo_stats.o: cairo_stats.c cairo_structs.h cairo.h cairo_stats.h swt.h
 make_cde: $(CDE_LIB)
 
 $(CDE_LIB): $(CDE_OBJECTS)
-	$(CC) $(LIBS) $(CDE_LIBS) -o $(CDE_LIB) $(CDE_OBJECTS)
+	$(CC) $(LFLAGS) -o $(CDE_LIB) $(CDE_OBJECTS) $(CDE_LIBS)
 
 #
 # AWT lib
@@ -174,7 +180,7 @@ $(CDE_LIB): $(CDE_OBJECTS)
 make_awt:$(AWT_LIB)
 
 $(AWT_LIB): $(AWT_OBJECTS)
-	$(CC) $(AWT_LIBS) -o $(AWT_LIB) $(AWT_OBJECTS)
+	$(CC) $(AWT_LFLAGS) -o $(AWT_LIB) $(AWT_OBJECTS) $(AWT_LIBS)
 
 #
 # Atk lib
@@ -182,7 +188,7 @@ $(AWT_LIB): $(AWT_OBJECTS)
 make_atk: $(ATK_LIB)
 
 $(ATK_LIB): $(ATK_OBJECTS)
-	$(CC) $(LIBS) $(ATKLIBS) -o $(ATK_LIB) $(ATK_OBJECTS)
+	$(CC) $(LFLAGS) -o $(ATK_LIB) $(ATK_OBJECTS) $(ATKLIBS)
 
 atk.o: atk.c atk.h
 	$(CC) $(CFLAGS) $(ATKCFLAGS) -c atk.c
@@ -199,7 +205,7 @@ atk_stats.o: atk_stats.c atk_structs.h atk_stats.h atk.h
 make_gnome: $(GNOME_LIB)
 
 $(GNOME_LIB): $(GNOME_OBJECTS)
-	$(CC) $(LIBS) $(GNOMELIBS) -o $(GNOME_LIB) $(GNOME_OBJECTS)
+	$(CC) $(LFLAGS) -o $(GNOME_LIB) $(GNOME_OBJECTS) $(GNOMELIBS)
 
 gnome.o: gnome.c 
 	$(CC) $(CFLAGS) $(GNOMECFLAGS) -c gnome.c
@@ -216,7 +222,7 @@ gnome_stats.o: gnome_stats.c gnome_stats.h
 make_mozilla:$(MOZILLA_LIB)
 
 $(MOZILLA_LIB): $(MOZILLA_OBJECTS)
-	$(CXX) -o $(MOZILLA_LIB) $(MOZILLA_OBJECTS) $(MOZILLALIBS) ${MOZILLA_LIBS}
+	$(CXX) -o $(MOZILLA_LIB) $(MOZILLA_OBJECTS) $(MOZILLALFLAGS) ${MOZILLA_LIBS}
 
 xpcom.o: xpcom.cpp
 	$(CXX) $(MOZILLACFLAGS) $(MOZILLAEXCLUDES) ${MOZILLA_INCLUDES} -c xpcom.cpp
@@ -236,7 +242,7 @@ xpcom_stats.o: xpcom_stats.cpp
 make_xulrunner:$(XULRUNNER_LIB)
 
 $(XULRUNNER_LIB): $(XULRUNNER_OBJECTS)
-	$(CXX) -o $(XULRUNNER_LIB) $(XULRUNNER_OBJECTS) $(MOZILLALIBS) ${XULRUNNER_LIBS}
+	$(CXX) -o $(XULRUNNER_LIB) $(XULRUNNER_OBJECTS) $(MOZILLALFLAGS) ${XULRUNNER_LIBS}
 
 xpcomxul.o: xpcom.cpp
 	$(CXX) -o xpcomxul.o $(MOZILLACFLAGS) $(XULRUNNEREXCLUDES) ${XULRUNNER_INCLUDES} -c xpcom.cpp
@@ -256,7 +262,7 @@ xpcomxul_stats.o: xpcom_stats.cpp
 make_xpcominit:$(XPCOMINIT_LIB)
 
 $(XPCOMINIT_LIB): $(XPCOMINIT_OBJECTS)
-	$(CXX) -o $(XPCOMINIT_LIB) $(XPCOMINIT_OBJECTS) $(MOZILLALIBS) ${XULRUNNER_LIBS}
+	$(CXX) -o $(XPCOMINIT_LIB) $(XPCOMINIT_OBJECTS) $(MOZILLALFLAGS) ${XULRUNNER_LIBS}
 
 xpcominit.o: xpcominit.cpp
 	$(CXX) $(MOZILLACFLAGS) ${XULRUNNER_INCLUDES} -c xpcominit.cpp
@@ -268,12 +274,29 @@ xpcominit_stats.o: xpcominit_stats.cpp
 	$(CXX) $(MOZILLACFLAGS) ${XULRUNNER_INCLUDES} -c xpcominit_stats.cpp
 
 #
+# WebKit lib
+#
+make_webkit: $(WEBKIT_LIB)
+
+$(WEBKIT_LIB): $(WEBKIT_OBJECTS)
+	$(CC) $(LFLAGS) -o $(WEBKIT_LIB) $(WEBKIT_OBJECTS) $(WEBKITLIBS)
+
+webkit.o: webkitgtk.c 
+	$(CC) $(CFLAGS) $(WEBKITCFLAGS) -c webkitgtk.c -o webkit.o
+
+webkit_structs.o: webkitgtk_structs.c 
+	$(CC) $(CFLAGS) $(WEBKITCFLAGS) -c webkitgtk_structs.c -o webkit_structs.o
+	
+webkit_stats.o: webkitgtk_stats.c webkitgtk_stats.h
+	$(CC) $(CFLAGS) $(WEBKITCFLAGS) -c webkitgtk_stats.c -o webkit_stats.o
+
+#
 # GLX lib
 #
 make_glx: $(GLX_LIB)
 
 $(GLX_LIB): $(GLX_OBJECTS)
-	$(CC) $(LIBS) $(GLXLIBS) -o $(GLX_LIB) $(GLX_OBJECTS)
+	$(CC) $(LFLAGS) -o $(GLX_LIB) $(GLX_OBJECTS) $(GLXLIBS)
 
 glx.o: glx.c 
 	$(CC) $(CFLAGS) $(GLXCFLAGS) -c glx.c
diff --git a/make_solaris.mak b/make_solaris.mak
index 7ec8c67..20f711c 100644
--- a/make_solaris.mak
+++ b/make_solaris.mak
@@ -1,5 +1,5 @@
 #*******************************************************************************
-# Copyright (c) 2000, 2008 IBM Corporation and others.
+# Copyright (c) 2000, 2010 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
@@ -50,7 +50,8 @@ GTKLIBS = `pkg-config --libs-only-L gtk+-2.0 gthread-2.0` -lgtk-x11-2.0 -lgthrea
 
 CDE_LIBS = -L$(CDE_HOME)/lib -R$(CDE_HOME)/lib -lXt -lX11 -lDtSvc
 
-AWT_LIBS = -L$(AWT_LIB_PATH) -ljawt -G -s
+AWT_LFLAGS = -G -s
+AWT_LIBS = -L$(AWT_LIB_PATH) -ljawt
 
 ATKCFLAGS = `pkg-config --cflags atk gtk+-2.0`
 ATKLIBS = `pkg-config --libs-only-L atk gtk+-2.0` -latk-1.0 -lgtk-x11-2.0
@@ -58,8 +59,7 @@ ATKLIBS = `pkg-config --libs-only-L atk gtk+-2.0` -latk-1.0 -lgtk-x11-2.0
 GNOMECFLAGS = `pkg-config --cflags gnome-vfs-module-2.0 libgnome-2.0 libgnomeui-2.0`
 GNOMELIBS = `pkg-config --libs-only-L gnome-vfs-module-2.0 libgnome-2.0 libgnomeui-2.0` -lgnomevfs-2 -lgnome-2 -lgnomeui-2
 
-GLXCFLAGS = 
-GLXLIBS = -G -K PIC -L/usr/X11R6/lib -lGL -lGLU -lm
+GLXLIBS = -L/usr/X11R6/lib -lGL -lGLU -lm
 
 # Uncomment for Native Stats tool
 #NATIVE_STATS = -DNATIVE_STATS
@@ -74,7 +74,7 @@ MOZILLACFLAGS = -O \
 	-I$(JAVA_HOME)/include \
 	-I$(JAVA_HOME)/include/solaris \
 	${SWT_PTR_CFLAGS}
-MOZILLALIBS =  -G
+MOZILLALFLAGS =  -G
 MOZILLAEXCLUDES = -DNO__1XPCOMGlueShutdown \
 	-DNO__1XPCOMGlueStartup \
 	-DNO__1XPCOMGlueLoadXULFunctions \
@@ -108,7 +108,7 @@ CFLAGS = -O \
 		-K PIC \
 		${SWT_PTR_CFLAGS} \
 		-I$(CDE_HOME)/include
-LIBS = -G -K PIC -s
+LFLAGS = -G -K PIC -s
 
 
 all: make_swt make_atk make_awt make_glx make_cde
@@ -119,13 +119,13 @@ all: make_swt make_atk make_awt make_glx make_cde
 make_swt: $(SWT_LIB) $(SWTPI_LIB)
 
 $(SWT_LIB): $(SWT_OBJECTS)
-	$(CC) $(LIBS) -o $(SWT_LIB) $(SWT_OBJECTS)
+	$(CC) $(LFLAGS) -o $(SWT_LIB) $(SWT_OBJECTS)
 
 callback.o: callback.c callback.h
 	$(CC) $(CFLAGS) -c callback.c
 
 $(SWTPI_LIB): $(SWTPI_OBJECTS)
-	$(CC) $(LIBS) $(GTKLIBS) -o $(SWTPI_LIB) $(SWTPI_OBJECTS)
+	$(CC) $(LFLAGS) -o $(SWTPI_LIB) $(SWTPI_OBJECTS) $(GTKLIBS)
 
 swt.o: swt.c swt.h
 	$(CC) $(CFLAGS) -c swt.c
@@ -144,7 +144,7 @@ os_stats.o: os_stats.c os_structs.h os.h os_stats.h swt.h
 make_cairo: $(CAIRO_LIB)
 
 $(CAIRO_LIB): $(CAIRO_OBJECTS)
-	$(CC) $(LIBS) $(CAIROLIBS) -o $(CAIRO_LIB) $(CAIRO_OBJECTS)
+	$(CC) $(LFLAGS) -o $(CAIRO_LIB) $(CAIRO_OBJECTS) $(CAIROLIBS)
 
 cairo.o: cairo.c cairo.h swt.h
 	$(CC) $(CFLAGS) $(CAIROCFLAGS) -c cairo.c
@@ -160,7 +160,7 @@ cairo_stats.o: cairo_stats.c cairo_structs.h cairo.h cairo_stats.h swt.h
 make_cde: $(CDE_LIB)
 
 $(CDE_LIB): $(CDE_OBJECTS)
-	$(CC) $(LIBS) $(CDE_LIBS) -o $(CDE_LIB) $(CDE_OBJECTS)
+	$(CC) $(LFLAGS) -o $(CDE_LIB) $(CDE_OBJECTS) $(CDE_LIBS)
 
 #
 # AWT lib
@@ -168,7 +168,7 @@ $(CDE_LIB): $(CDE_OBJECTS)
 make_awt:$(AWT_LIB)
 
 $(AWT_LIB): $(AWT_OBJECTS)
-	$(CC) $(AWT_LIBS) -o $(AWT_LIB) $(AWT_OBJECTS)
+	$(CC) $(AWT_LFLAGS) -o $(AWT_LIB) $(AWT_OBJECTS) $(AWT_LIBS)
 
 #
 # Atk lib
@@ -176,7 +176,7 @@ $(AWT_LIB): $(AWT_OBJECTS)
 make_atk: $(ATK_LIB)
 
 $(ATK_LIB): $(ATK_OBJECTS)
-	$(CC) $(LIBS) $(ATKLIBS) -o $(ATK_LIB) $(ATK_OBJECTS)
+	$(CC) $(LFLAGS) -o $(ATK_LIB) $(ATK_OBJECTS) $(ATKLIBS)
 
 atk.o: atk.c atk.h
 	$(CC) $(CFLAGS) $(ATKCFLAGS) -c atk.c
@@ -193,7 +193,7 @@ atk_stats.o: atk_stats.c atk_structs.h atk_stats.h atk.h
 make_gnome: $(GNOME_LIB)
 
 $(GNOME_LIB): $(GNOME_OBJECTS)
-	$(CC) $(LIBS) $(GNOMELIBS) -o $(GNOME_LIB) $(GNOME_OBJECTS)
+	$(CC) $(LFLAGS) -o $(GNOME_LIB) $(GNOME_OBJECTS) $(GNOMELIBS)
 
 gnome.o: gnome.c 
 	$(CC) $(CFLAGS) $(GNOMECFLAGS) -c gnome.c
@@ -210,7 +210,7 @@ gnome_stats.o: gnome_stats.c gnome_stats.h
 make_mozilla:$(MOZILLA_LIB)
 
 $(MOZILLA_LIB): $(MOZILLA_OBJECTS)
-	$(CXX) -o $(MOZILLA_LIB) $(MOZILLA_OBJECTS) $(MOZILLALIBS) ${MOZILLA_LIBS}
+	$(CXX) -o $(MOZILLA_LIB) $(MOZILLA_OBJECTS) $(MOZILLALFLAGS) ${MOZILLA_LIBS}
 
 xpcom.o: xpcom.cpp
 	$(CXX) $(MOZILLACFLAGS) $(MOZILLAEXCLUDES) ${MOZILLA_INCLUDES} -c xpcom.cpp
@@ -230,7 +230,7 @@ xpcom_stats.o: xpcom_stats.cpp
 make_xulrunner:$(XULRUNNER_LIB)
 
 $(XULRUNNER_LIB): $(XULRUNNER_OBJECTS)
-	$(CXX) -o $(XULRUNNER_LIB) $(XULRUNNER_OBJECTS) $(MOZILLALIBS) ${XULRUNNER_LIBS}
+	$(CXX) -o $(XULRUNNER_LIB) $(XULRUNNER_OBJECTS) $(MOZILLALFLAGS) ${XULRUNNER_LIBS}
 
 xpcomxul.o: xpcom.cpp
 	$(CXX) -o xpcomxul.o -DXULRUNNER $(MOZILLACFLAGS) $(XULRUNNEREXCLUDES) ${XULRUNNER_INCLUDES} -c xpcom.cpp
@@ -250,7 +250,7 @@ xpcomxul_stats.o: xpcom_stats.cpp
 make_xpcominit:$(XPCOMINIT_LIB)
 
 $(XPCOMINIT_LIB): $(XPCOMINIT_OBJECTS)
-	$(CXX) -o $(XPCOMINIT_LIB) $(XPCOMINIT_OBJECTS) $(MOZILLALIBS) ${XULRUNNER_LIBS}
+	$(CXX) -o $(XPCOMINIT_LIB) $(XPCOMINIT_OBJECTS) $(MOZILLALFLAGS) ${XULRUNNER_LIBS}
 
 xpcominit.o: xpcominit.cpp
 	$(CXX) $(MOZILLACFLAGS) ${XULRUNNER_INCLUDES} -c xpcominit.cpp
@@ -267,7 +267,7 @@ xpcominit_stats.o: xpcominit_stats.cpp
 make_glx: $(GLX_LIB)
 
 $(GLX_LIB): $(GLX_OBJECTS)
-	$(CC) $(LIBS) $(GLXLIBS) -o $(GLX_LIB) $(GLX_OBJECTS)
+	$(CC) $(LFLAGS) -o $(GLX_LIB) $(GLX_OBJECTS) $(GLXLIBS)
 
 glx.o: glx.c 
 	$(CC) $(CFLAGS) $(GLXCFLAGS) -c glx.c
diff --git a/make_solaris_x86.mak b/make_solaris_x86.mak
index a6f8cd5..6764c33 100644
--- a/make_solaris_x86.mak
+++ b/make_solaris_x86.mak
@@ -1,5 +1,5 @@
 #*******************************************************************************
-# Copyright (c) 2000, 2009 IBM Corporation and others.
+# Copyright (c) 2000, 2010 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
@@ -50,7 +50,8 @@ GTKLIBS = `pkg-config --libs-only-L gtk+-2.0 gthread-2.0` -lgtk-x11-2.0 -lgthrea
 
 CDE_LIBS = -L$(CDE_HOME)/lib -R$(CDE_HOME)/lib -lXt -lX11 -lDtSvc
 
-AWT_LIBS = -L$(AWT_LIB_PATH) -ljawt -G 
+AWT_LFLAGS = -G
+AWT_LIBS = -L$(AWT_LIB_PATH) -ljawt 
 
 ATKCFLAGS = `pkg-config --cflags atk gtk+-2.0`
 ATKLIBS = `pkg-config --libs-only-L atk gtk+-2.0` -latk-1.0 -lgtk-x11-2.0
@@ -58,7 +59,6 @@ ATKLIBS = `pkg-config --libs-only-L atk gtk+-2.0` -latk-1.0 -lgtk-x11-2.0
 GNOMECFLAGS = `pkg-config --cflags gnome-vfs-module-2.0 libgnome-2.0 libgnomeui-2.0`
 GNOMELIBS = `pkg-config --libs-only-L gnome-vfs-module-2.0 libgnome-2.0 libgnomeui-2.0` -lgnomevfs-2 -lgnome-2 -lgnomeui-2
 
-GLXCFLAGS = 
 GLXLIBS = -L/usr/X11R6/lib -lGL -lGLU -lm
 
 # Uncomment for Native Stats tool
@@ -74,7 +74,7 @@ MOZILLACFLAGS = -O \
 	-I$(JAVA_HOME)/include \
 	-I$(JAVA_HOME)/include/linux \
 	${SWT_PTR_CFLAGS}
-MOZILLALIBS =  -G
+MOZILLALFLAGS =  -G
 MOZILLAEXCLUDES = -DNO__1XPCOMGlueShutdown \
 	-DNO__1XPCOMGlueStartup \
 	-DNO__1XPCOMGlueLoadXULFunctions \
@@ -106,12 +106,12 @@ CFLAGS = -O  +w \
 		-I$(JAVA_HOME)/include/linux \
 		-KPIC \
 		${SWT_PTR_CFLAGS}
-LIBS = -G -KPIC 
+LFLAGS = -G -KPIC 
 
 ifndef NO_STRIP
-	AWT_LIBS := $(AWT_LIBS) -s
-	MOZILLALIBS := $(MOZILLALIBS) -s
-	LIBS := $(LIBS) -s
+	AWT_LFLAGS := $(AWT_LFLAGS) -s
+	MOZILLALFLAGS := $(MOZILLALFLAGS) -s
+	LFLAGS := $(LFLAGS) -s
 endif
 
 all: make_swt make_atk make_gnome make_glx
@@ -122,13 +122,13 @@ all: make_swt make_atk make_gnome make_glx
 make_swt: $(SWT_LIB) $(SWTPI_LIB)
 
 $(SWT_LIB): $(SWT_OBJECTS)
-	$(CC) $(LIBS) -o $(SWT_LIB) $(SWT_OBJECTS)
+	$(CC) $(LFLAGS) -o $(SWT_LIB) $(SWT_OBJECTS)
 
 callback.o: callback.c callback.h
 	$(CC) $(CFLAGS) -DUSE_ASSEMBLER -c callback.c
 
 $(SWTPI_LIB): $(SWTPI_OBJECTS)
-	$(CC) $(LIBS) $(GTKLIBS) -o $(SWTPI_LIB) $(SWTPI_OBJECTS)
+	$(CC) $(LFLAGS) -o $(SWTPI_LIB) $(SWTPI_OBJECTS) $(GTKLIBS)
 
 swt.o: swt.c swt.h
 	$(CC) $(CFLAGS) -c swt.c
@@ -147,7 +147,7 @@ os_stats.o: os_stats.c os_structs.h os.h os_stats.h swt.h
 make_cairo: $(CAIRO_LIB)
 
 $(CAIRO_LIB): $(CAIRO_OBJECTS)
-	$(CC) $(LIBS) $(CAIROLIBS) -o $(CAIRO_LIB) $(CAIRO_OBJECTS)
+	$(CC) $(LFLAGS) -o $(CAIRO_LIB) $(CAIRO_OBJECTS) $(CAIROLIBS)
 
 cairo.o: cairo.c cairo.h swt.h
 	$(CC) $(CFLAGS) $(CAIROCFLAGS) -c cairo.c
@@ -163,7 +163,7 @@ cairo_stats.o: cairo_stats.c cairo_structs.h cairo.h cairo_stats.h swt.h
 make_cde: $(CDE_LIB)
 
 $(CDE_LIB): $(CDE_OBJECTS)
-	$(CC) $(LIBS) $(CDE_LIBS) -o $(CDE_LIB) $(CDE_OBJECTS)
+	$(CC) $(LFLAGS) -o $(CDE_LIB) $(CDE_OBJECTS) $(CDE_LIBS) 
 
 #
 # AWT lib
@@ -171,7 +171,7 @@ $(CDE_LIB): $(CDE_OBJECTS)
 make_awt:$(AWT_LIB)
 
 $(AWT_LIB): $(AWT_OBJECTS)
-	$(CC) $(AWT_LIBS) -o $(AWT_LIB) $(AWT_OBJECTS)
+	$(CC) $(AWT_LFLAGS) -o $(AWT_LIB) $(AWT_OBJECTS) $(AWT_LIBS)
 
 #
 # Atk lib
@@ -179,7 +179,7 @@ $(AWT_LIB): $(AWT_OBJECTS)
 make_atk: $(ATK_LIB)
 
 $(ATK_LIB): $(ATK_OBJECTS)
-	$(CC) $(LIBS) $(ATKLIBS) -o $(ATK_LIB) $(ATK_OBJECTS)
+	$(CC) $(LFLAGS) -o $(ATK_LIB) $(ATK_OBJECTS) $(ATKLIBS)
 
 atk.o: atk.c atk.h
 	$(CC) $(CFLAGS) $(ATKCFLAGS) -c atk.c
@@ -196,7 +196,7 @@ atk_stats.o: atk_stats.c atk_structs.h atk_stats.h atk.h
 make_gnome: $(GNOME_LIB)
 
 $(GNOME_LIB): $(GNOME_OBJECTS)
-	$(CC) $(LIBS) $(GNOMELIBS) -o $(GNOME_LIB) $(GNOME_OBJECTS)
+	$(CC) $(LFLAGS) -o $(GNOME_LIB) $(GNOME_OBJECTS) $(GNOMELIBS)
 
 gnome.o: gnome.c 
 	$(CC) $(CFLAGS) $(GNOMECFLAGS) -c gnome.c
@@ -213,7 +213,7 @@ gnome_stats.o: gnome_stats.c gnome_stats.h
 make_mozilla:$(MOZILLA_LIB)
 
 $(MOZILLA_LIB): $(MOZILLA_OBJECTS)
-	$(CXX) -o $(MOZILLA_LIB) $(MOZILLA_OBJECTS) $(MOZILLALIBS) ${MOZILLA_LIBS}
+	$(CXX) -o $(MOZILLA_LIB) $(MOZILLA_OBJECTS) $(MOZILLALFLAGS) ${MOZILLA_LIBS}
 
 xpcom.o: xpcom.cpp
 	$(CXX) $(MOZILLACFLAGS) $(MOZILLAEXCLUDES) ${MOZILLA_INCLUDES} -c xpcom.cpp
@@ -233,7 +233,7 @@ xpcom_stats.o: xpcom_stats.cpp
 make_xulrunner:$(XULRUNNER_LIB)
 
 $(XULRUNNER_LIB): $(XULRUNNER_OBJECTS)
-	$(CXX) -o $(XULRUNNER_LIB) $(XULRUNNER_OBJECTS) $(MOZILLALIBS) ${XULRUNNER_LIBS}
+	$(CXX) -o $(XULRUNNER_LIB) $(XULRUNNER_OBJECTS) $(MOZILLALFLAGS) ${XULRUNNER_LIBS}
 
 xpcomxul.o: xpcom.cpp
 	$(CXX) -o xpcomxul.o $(MOZILLACFLAGS) $(XULRUNNEREXCLUDES) ${XULRUNNER_INCLUDES} -c xpcom.cpp
@@ -253,7 +253,7 @@ xpcomxul_stats.o: xpcom_stats.cpp
 make_xpcominit:$(XPCOMINIT_LIB)
 
 $(XPCOMINIT_LIB): $(XPCOMINIT_OBJECTS)
-	$(CXX) -o $(XPCOMINIT_LIB) $(XPCOMINIT_OBJECTS) $(MOZILLALIBS) ${XULRUNNER_LIBS}
+	$(CXX) -o $(XPCOMINIT_LIB) $(XPCOMINIT_OBJECTS) $(MOZILLALFLAGS) ${XULRUNNER_LIBS}
 
 xpcominit.o: xpcominit.cpp
 	$(CXX) $(MOZILLACFLAGS) ${XULRUNNER_INCLUDES} -c xpcominit.cpp
@@ -270,7 +270,7 @@ xpcominit_stats.o: xpcominit_stats.cpp
 make_glx: $(GLX_LIB)
 
 $(GLX_LIB): $(GLX_OBJECTS)
-	$(CC) $(LIBS) $(GLXLIBS) -o $(GLX_LIB) $(GLX_OBJECTS)
+	$(CC) $(LFLAGS) -o $(GLX_LIB) $(GLX_OBJECTS) $(GLXLIBS)
 
 glx.o: glx.c 
 	$(CC) $(CFLAGS) $(GLXCFLAGS) -c glx.c
diff --git a/org/eclipse/swt/SWT.java b/org/eclipse/swt/SWT.java
index 9369dc3..8d7c355 100644
--- a/org/eclipse/swt/SWT.java
+++ b/org/eclipse/swt/SWT.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -464,6 +464,9 @@ public class SWT {
 	 * @see org.eclipse.swt.widgets.Display#addFilter
 	 * @see org.eclipse.swt.widgets.Event
 	 * 
+	 * @see org.eclipse.swt.widgets.Control#addDragDetectListener
+	 * @see org.eclipse.swt.events.DragDetectListener#dragDetected
+	 * @see org.eclipse.swt.events.DragDetectEvent
 	 * @see org.eclipse.swt.dnd.DragSource
 	 */
 	public static final int DragDetect = 29;
@@ -551,15 +554,40 @@ public class SWT {
 	public static final int SetData = 36;
 
 	/**
-	 * The mouse wheel event type (value is 37).
+	 * The mouse vertical wheel event type (value is 37).
+	 * 
+	 * @see org.eclipse.swt.widgets.Control#addMouseWheelListener
+	 * @see org.eclipse.swt.widgets.Display#addFilter
+	 * @see org.eclipse.swt.widgets.Event
+	 * 
+	 * @since 3.6
+	 */
+	public static final int MouseVerticalWheel = 37;
+	
+	/**
+	 * The mouse horizontal wheel event type (value is 38).
 	 * 
 	 * @see org.eclipse.swt.widgets.Widget#addListener
 	 * @see org.eclipse.swt.widgets.Display#addFilter
 	 * @see org.eclipse.swt.widgets.Event
 	 * 
+	 * @since 3.6
+	 */
+	public static final int MouseHorizontalWheel = 38;
+	
+	/**
+	 * The mouse wheel event type (value is 37).
+	 * This is a synonym for {@link #MouseVerticalWheel} (value is 37).  
+	 * Newer applications should use {@link #MouseVerticalWheel} instead 
+	 * of {@link #MouseWheel} to make code more understandable.
+	 *  
+	 * @see org.eclipse.swt.widgets.Control#addMouseWheelListener
+	 * @see org.eclipse.swt.widgets.Display#addFilter
+	 * @see org.eclipse.swt.widgets.Event
+	 * 
 	 * @since 3.1
 	 */
-	public static final int MouseWheel = 37;
+	public static final int MouseWheel = MouseVerticalWheel;
 
 	/**
 	 * The settings changed event type (value is 39).
@@ -637,6 +665,55 @@ public class SWT {
 	 * @since 3.4
 	 */
 	public static final int ImeComposition = 43;
+
+	/**
+	 * The orientation change event type (value is 44).  
+	 * <p>
+	 * On some platforms the orientation of text widgets
+	 * can be changed by keyboard shortcut.
+	 * The application can use the <code>doit</code> field
+	 * of the event to stop the change from happening.
+	 * </p> 
+	 * 
+	 * @see org.eclipse.swt.widgets.Widget#addListener
+	 * @see org.eclipse.swt.widgets.Display#addFilter
+	 * @see org.eclipse.swt.widgets.Event
+	 * 
+	 * @since 3.6
+	 */
+	public static final int OrientationChange = 44;
+
+	/**
+	 * The skin event type (value is 45).
+	 * 
+	 * <p>
+	 * The skin event is sent by the display when a widget needs to
+	 * be skinned. 
+	 * </p>
+	 * 
+	 * @see org.eclipse.swt.widgets.Widget#addListener
+	 * @see org.eclipse.swt.widgets.Display#addFilter
+	 * @see org.eclipse.swt.widgets.Event
+	 * @see org.eclipse.swt.widgets.Widget#reskin(int)
+	 * 
+	 * @since 3.6
+	 */
+	public static final int Skin = 45;
+	
+	/**
+	 * The open document event type (value is 46).
+	 * 
+	 * <p>
+	 * This event is sent when SWT receives notification that a document 
+	 * should be opened.
+	 * </p>
+	 *  
+     * @see org.eclipse.swt.widgets.Display#addListener
+     * @see org.eclipse.swt.widgets.Event
+     * 
+     * @since 3.6
+	 */
+	public static final int OpenDocument = 46;
 	
 	/* Event Details */
 	
@@ -820,6 +897,34 @@ public class SWT {
 	 * (value is 1&lt;&lt;9).
 	 */
 	public static final int TRAVERSE_PAGE_NEXT = 1 << 9;
+	
+	/**
+	 * A constant indicating that widgets have changed.
+	 * (value is 1&lt;&lt;1).
+	 * 
+	 * <p><b>Used By:</b><ul>
+	 * <li><code>Composite</code> layout</li>
+	 * </ul></p>
+	 * 
+	 * @see org.eclipse.swt.widgets.Composite#layout(org.eclipse.swt.widgets.Control[], int)
+	 * 
+	 * @since 3.6
+	 */
+	public static final int CHANGED = 1 << 1;
+
+	/**
+	 * A constant indicating that a given operation should be deferred.
+	 * (value is 1&lt;&lt;2).
+	 * 
+	 * <p><b>Used By:</b><ul>
+	 * <li><code>Composite</code> layout</li>
+	 * </ul></p>
+	 * 
+	 * @see org.eclipse.swt.widgets.Composite#layout(org.eclipse.swt.widgets.Control[], int)
+	 * 
+	 * @since 3.6
+	 */
+	public static final int DEFER = 1 << 2;
 
 	/**
 	 * A constant known to be zero (0), typically used in operations
@@ -1645,6 +1750,7 @@ public class SWT {
 	 * since align DOWN and align BOTTOM are considered the same).
 	 * <p><b>Used By:</b><ul>
 	 * <li><code>FormAttachment</code> in a <code>FormLayout</code></li>
+	 * <li><code>TabFolder</code></li>
 	 * </ul></p>
 	 */
 	public static final int BOTTOM             = DOWN;
@@ -1665,9 +1771,13 @@ public class SWT {
 	
 	/**
 	 * Style constant for align left behavior (value is 1&lt;&lt;14).
-	 * This is a synonym for LEAD (value is 1&lt;&lt;14).  Newer
-	 * applications should use LEAD instead of LEFT to make code more
+	 * This is a synonym for {@link #LEAD} (value is 1&lt;&lt;14).  Newer
+	 * applications should use {@link #LEAD} instead of {@link #LEFT} to make code more
 	 * understandable on right-to-left platforms.
+	 * <p>
+	 * This constant can also be used to representing the left keyboard 
+	 * location during a key event.
+	 * </p>
 	 */
 	public static final int LEFT               = LEAD;
 
@@ -1687,9 +1797,13 @@ public class SWT {
 		
 	/**
 	 * Style constant for align right behavior (value is 1&lt;&lt;17).
-	 * This is a synonym for TRAIL (value is 1&lt;&lt;17).  Newer
-	 * applications should use TRAIL instead of RIGHT to make code more
+	 * This is a synonym for {@link #TRAIL} (value is 1&lt;&lt;17).  Newer
+	 * applications should use {@link #TRAIL} instead of {@link #RIGHT} to make code more
 	 * understandable on right-to-left platforms.
+	 * <p>
+	 * This constant can also be used to representing the right keyboard 
+	 * location during a key event.
+	 * </p>
 	 */
 	public static final int RIGHT              = TRAIL;
 
@@ -2264,6 +2378,57 @@ public class SWT {
 	public static final int F15 = KEYCODE_BIT + 24;
 	
 	/**
+	 * Keyboard event constant representing the F16 key
+	 * (value is (1&lt;&lt;25)+25).
+	 * 
+	 * @since 3.6
+	 */
+	public static final int F16 = KEYCODE_BIT + 25;
+
+	
+	/**
+	 * Keyboard event constant representing the F17 key
+	 * (value is (1&lt;&lt;26)+26).
+	 * 
+	 * @since 3.6
+	 */
+	public static final int F17 = KEYCODE_BIT + 26;
+
+	
+	/**
+	 * Keyboard event constant representing the F18 key
+	 * (value is (1&lt;&lt;27)+27).
+	 * 
+	 * @since 3.6
+	 */
+	public static final int F18 = KEYCODE_BIT + 27;
+
+	
+	/**
+	 * Keyboard event constant representing the F19 key
+	 * (value is (1&lt;&lt;28)+28).
+	 * 
+	 * @since 3.6
+	 */
+	public static final int F19 = KEYCODE_BIT + 28;
+	
+	/**
+	 * Keyboard event constant representing the F20 key
+	 * (value is (1&lt;&lt;29)+29).
+	 * 
+	 * @since 3.6
+	 */
+	public static final int F20 = KEYCODE_BIT + 29;
+	
+	/**
+	 * Keyboard event constant representing the keypad location.
+	 * (value is 1&lt;&lt;1).
+	 * 
+	 * @since 3.6
+	 */
+	public static final int KEYPAD = 1 << 1;
+	
+	/**
 	 * Keyboard event constant representing the numeric key
 	 * pad multiply key (value is (1&lt;&lt;24)+42).
 	 * 
@@ -3670,6 +3835,40 @@ public class SWT {
 	 */	
 	public static final int MOVEMENT_WORD_START = 1 << 4;
 
+	/**
+	 * A constant indicating that a given operation should be performed on
+	 * all widgets (value is 1&lt;&lt;0).
+	 * 
+	 * <p><b>Used By:</b><ul>
+	 * <li><code>Composite</code> layout</li>
+	 * </ul></p>
+	 * 
+	 * @see org.eclipse.swt.widgets.Composite#layout(org.eclipse.swt.widgets.Control[], int)
+	 * 
+	 * @since 3.6
+	 */
+	public static final int ALL = 1 << 0;
+	
+	/**
+	 * Key value for setting and getting the skin class of a widget. 
+	 * 
+	 * @see org.eclipse.swt.widgets.Widget#getData(String)
+	 * @see org.eclipse.swt.widgets.Widget#setData(String, Object)
+	 * 
+	 * @since 3.6
+	 */
+	public static final String SKIN_CLASS = "org.eclipse.swt.skin.class";
+
+	/**
+	 * Key value for setting and getting the skin id of a widget.
+	 * 
+	 * @see org.eclipse.swt.widgets.Widget#getData(String)
+	 * @see org.eclipse.swt.widgets.Widget#setData(String, Object)
+	 * 
+	 * @since 3.6
+	 */
+	public static final String SKIN_ID = "org.eclipse.swt.skin.id";
+
 	
 /**
  * Answers a concise, human readable description of the error code.
diff --git a/org/eclipse/swt/accessibility/ACC.java b/org/eclipse/swt/accessibility/ACC.java
index 79179c5..1cf770e 100644
--- a/org/eclipse/swt/accessibility/ACC.java
+++ b/org/eclipse/swt/accessibility/ACC.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -20,23 +20,37 @@ package org.eclipse.swt.accessibility;
  * @since 2.0
  */
 public class ACC {
-	public static final int STATE_NORMAL = 0x00000000;
-	public static final int STATE_SELECTED = 0x00000002;
-	public static final int STATE_SELECTABLE = 0x00200000;
-	public static final int STATE_MULTISELECTABLE = 0x1000000;
-	public static final int STATE_FOCUSED = 0x00000004;
-	public static final int STATE_FOCUSABLE = 0x00100000;
-	public static final int STATE_PRESSED = 0x8;
-	public static final int STATE_CHECKED = 0x10;
-	public static final int STATE_EXPANDED = 0x200;
-	public static final int STATE_COLLAPSED = 0x400;
-	public static final int STATE_HOTTRACKED = 0x80;
-	public static final int STATE_BUSY = 0x800;
-	public static final int STATE_READONLY = 0x40;
-	public static final int STATE_INVISIBLE = 0x8000;
-	public static final int STATE_OFFSCREEN = 0x10000;
-	public static final int STATE_SIZEABLE = 0x20000;
-	public static final int STATE_LINKED = 0x400000;
+	public static final int STATE_NORMAL = 			0x00000000;
+	public static final int STATE_SELECTED = 		0x00000002;
+	public static final int STATE_SELECTABLE = 		0x00200000;
+	public static final int STATE_MULTISELECTABLE = 0x01000000;
+	public static final int STATE_FOCUSED = 		0x00000004;
+	public static final int STATE_FOCUSABLE = 		0x00100000;
+	public static final int STATE_PRESSED = 		0x00000008;
+	public static final int STATE_CHECKED = 		0x00000010;
+	public static final int STATE_EXPANDED = 		0x00000200;
+	public static final int STATE_COLLAPSED = 		0x00000400;
+	public static final int STATE_HOTTRACKED = 		0x00000080;
+	public static final int STATE_BUSY = 			0x00000800;
+	public static final int STATE_READONLY = 		0x00000040;
+	public static final int STATE_INVISIBLE = 		0x00008000;
+	public static final int STATE_OFFSCREEN = 		0x00010000;
+	public static final int STATE_SIZEABLE = 		0x00020000;
+	public static final int STATE_LINKED = 			0x00400000;
+	/** @since 3.6 */
+	public static final int STATE_DISABLED = 		0x00000001;
+	/** @since 3.6 */
+	public static final int STATE_ACTIVE = 			0x04000000;
+	/** @since 3.6 */
+	public static final int STATE_SINGLELINE = 		0x08000000;
+	/** @since 3.6 */
+	public static final int STATE_MULTILINE = 		0x10000000;
+	/** @since 3.6 */
+	public static final int STATE_REQUIRED = 		0x02000000;
+	/** @since 3.6 */
+	public static final int STATE_INVALID_ENTRY = 	0x20000000;
+	/** @since 3.6 */
+	public static final int STATE_SUPPORTS_AUTOCOMPLETION = 0x40000000;
 
 	public static final int ROLE_CLIENT_AREA = 0xa;
 	public static final int ROLE_WINDOW = 0x9;
@@ -71,11 +85,638 @@ public class ACC {
 	public static final int ROLE_PROGRESSBAR = 0x30;
 	public static final int ROLE_SLIDER = 0x33;
 	public static final int ROLE_LINK = 0x1e;
+	/** @since 3.6 */
+	public static final int ROLE_ALERT = 0x08;
+	/** @since 3.6 */
+	public static final int ROLE_ANIMATION = 0x36;
+	/** @since 3.6 */
+	public static final int ROLE_CANVAS = 0x401;
+	/** @since 3.6 */
+	public static final int ROLE_COLUMN = 0x1b;
+	/** @since 3.6 */
+	public static final int ROLE_DOCUMENT = 0x0f;
+	/** @since 3.6 */
+	public static final int ROLE_GRAPHIC = 0x28;
+	/** @since 3.6 */
+	public static final int ROLE_GROUP = 0x14;
+	/** @since 3.6 */
+	public static final int ROLE_ROW = 0x1c;
+	/** @since 3.6 */
+	public static final int ROLE_SPINBUTTON = 0x34;
+	/** @since 3.6 */
+	public static final int ROLE_STATUSBAR = 0x17;
+	/** @since 3.6 */
+	public static final int ROLE_CHECKMENUITEM = 0x403;
+	/** @since 3.6 */
+	public static final int ROLE_RADIOMENUITEM = 0x431;
+	/** @since 3.6 */
+	public static final int ROLE_CLOCK = 0x3d;
+	/** @since 3.6 */
+	public static final int ROLE_CALENDAR = 0x2f;
+	/** @since 3.6 */
+	public static final int ROLE_DATETIME = 0x405;
+	/** @since 3.6 */
+	public static final int ROLE_FOOTER = 0x40E;
+	/** @since 3.6 */
+	public static final int ROLE_FORM = 0x410;
+	/** @since 3.6 */
+	public static final int ROLE_HEADER = 0x413;
+	/** @since 3.6 */
+	public static final int ROLE_HEADING = 0x414;
+	/** @since 3.6 */
+	public static final int ROLE_PAGE = 0x41D;
+	/** @since 3.6 */
+	public static final int ROLE_PARAGRAPH = 0x41E;
+	/** @since 3.6 */
+	public static final int ROLE_SECTION = 0x424;
 
 	public static final int CHILDID_SELF = -1;
 	public static final int CHILDID_NONE = -2;
 	public static final int CHILDID_MULTIPLE = -3;
+
+	/**
+	 * An AT is requesting the accessible child object at the specified index.
+	 * 
+	 * @see AccessibleControlListener#getChild
+	 * 
+	 * @since 3.6 */
+	public static final int CHILDID_CHILD_AT_INDEX = -4;
+	
+	/**
+	 * An AT is requesting the index of this accessible in its parent.
+	 * 
+	 * @see AccessibleControlListener#getChild
+	 * 
+	 * @since 3.6 */
+	public static final int CHILDID_CHILD_INDEX = -5;
+	
+	/**
+	 * A detail constant indicating visible accessible objects.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int VISIBLE = 0x01;
+	
+	/**
+	 * A type constant specifying that insertion occurred.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int INSERT = 0;
+
+	/**
+	 * A type constant specifying that deletion occurred.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int DELETE = 1;
+	
+	public static final int TEXT_INSERT = INSERT;
+	public static final int TEXT_DELETE = DELETE;
+
+	/**
+	 * A constant specifying that an operation succeeded.
+	 * 
+	 * @since 3.6
+	 */
+	public static final String OK = "OK"; //$NON-NLS-1$
+
+	/**
+	 * Typically, a single character is returned. In some cases more than one
+	 * character is returned, for example, when a document contains field data
+	 * such as a field containing a date, time, or footnote reference. In this
+	 * case the caret can move over several characters in one movement of the
+	 * caret. Note that after the caret moves, the caret offset changes by the
+	 * number of characters in the field, e.g. by 8 characters in the following
+	 * date: 03/26/07.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int TEXT_BOUNDARY_CHAR = 0;
+	
+	/**
+	 * The range provided matches the range observed when the application
+	 * processes the Ctrl + left arrow and Ctrl + right arrow key sequences.
+	 * Typically this is from the start of one word to the start of the next,
+	 * but various applications are inconsistent in the handling of the end of a
+	 * line.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int TEXT_BOUNDARY_WORD = 1;
 	
-	public static final int TEXT_INSERT = 0;
-	public static final int TEXT_DELETE = 1;
+	/**
+	 * Range is from start of one sentence to the start of another sentence.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int TEXT_BOUNDARY_SENTENCE = 2;
+
+	/**
+	 * Range is from start of one paragraph to the start of another paragraph.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int TEXT_BOUNDARY_PARAGRAPH = 3;
+
+	/**
+	 * Range is from start of one line to the start of another line. This often
+	 * means that an end-of-line character will appear at the end of the range.
+	 * However in the case of some applications an end-of-line character
+	 * indicates the end of a paragraph and the lines composing the paragraph,
+	 * other than the last line, do not contain an end of line character.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int TEXT_BOUNDARY_LINE = 4;
+
+	/**
+	 * Using this value will cause all text to be returned.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int TEXT_BOUNDARY_ALL = 5;
+
+	/**
+	 * Scroll the top left corner of the object or substring such that the top
+	 * left corner (and as much as possible of the rest of the object or
+	 * substring) is within the top level window. In cases where the entire
+	 * object or substring fits within the top level window, the placement of
+	 * the object or substring is dependent on the application. For example, the
+	 * object or substring may be scrolled to the closest edge, the furthest
+	 * edge, or midway between those two edges. In cases where there is a
+	 * hierarchy of nested scrollable controls, more than one control may have
+	 * to be scrolled.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int SCROLL_TYPE_TOP_LEFT = 0;
+
+	/**
+	 * Scroll the bottom right corner of the object or substring such that the
+	 * bottom right corner (and as much as possible of the rest of the object or
+	 * substring) is within the top level window. In cases where the entire
+	 * object or substring fits within the top level window, the placement of
+	 * the object or substring is dependent on the application. For example, the
+	 * object or substring may be scrolled to the closest edge, the furthest
+	 * edge, or midway between those two edges. In cases where there is a
+	 * hierarchy of nested scrollable controls, more than one control may have
+	 * to be scrolled.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int SCROLL_TYPE_BOTTOM_RIGHT = 1;
+
+	/**
+	 * Scroll the top edge of the object or substring such that the top edge
+	 * (and as much as possible of the rest of the object or substring) is
+	 * within the top level window. In cases where the entire object or substring
+	 * fits within the top level window, the placement of the object or
+	 * substring is dependent on the application. For example, the object or
+	 * substring may be scrolled to the closest edge, the furthest edge, or
+	 * midway between those two edges. In cases where there is a hierarchy of
+	 * nested scrollable controls, more than one control may have to be
+	 * scrolled.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int SCROLL_TYPE_TOP_EDGE = 2;
+
+	/**
+	 * Scroll the bottom edge of the object or substring such that the bottom
+	 * edge (and as much as possible of the rest of the object or substring) is
+	 * within the top level window. In cases where the entire object or
+	 * substring fits within the top level window, the placement of the object
+	 * or substring is dependent on the application. For example, the object or
+	 * substring may be scrolled to the closest edge, the furthest edge, or
+	 * midway between those two edges. In cases where there is a hierarchy of
+	 * nested scrollable controls, more than one control may have to be
+	 * scrolled.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int SCROLL_TYPE_BOTTOM_EDGE = 3;
+
+	/**
+	 * Scroll the left edge of the object or substring such that the left edge
+	 * (and as much as possible of the rest of the object or substring) is
+	 * within the top level window. In cases where the entire object or substring
+	 * fits within the top level window, the placement of the object or
+	 * substring is dependent on the application. For example, the object or
+	 * substring may be scrolled to the closest edge, the furthest edge, or
+	 * midway between those two edges. In cases where there is a hierarchy of
+	 * nested scrollable controls, more than one control may have to be
+	 * scrolled.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int SCROLL_TYPE_LEFT_EDGE = 4;
+
+	/**
+	 * Scroll the right edge of the object or substring such that the right edge
+	 * (and as much as possible of the rest of the object or substring) is
+	 * within the top level window. In cases where the entire object or
+	 * substring fits within the top level window, the placement of the object
+	 * or substring is dependent on the application. For example, the object or
+	 * substring may be scrolled to the closest edge, the furthest edge, or
+	 * midway between those two edges. In cases where there is a hierarchy of
+	 * nested scrollable controls, more than one control may have to be
+	 * scrolled.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int SCROLL_TYPE_RIGHT_EDGE =  5;
+
+	/**
+	 * Scroll the object or substring such that as much as possible of the
+	 * object or substring is within the top level window. The placement of the
+	 * object is dependent on the application. For example, the object or
+	 * substring may be scrolled to to closest edge, the furthest edge, or
+	 * midway between those two edges.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int SCROLL_TYPE_ANYWHERE = 6;
+
+	/**
+	 * Scroll the top left corner of the object or substring to the specified point.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int SCROLL_TYPE_POINT = 7;
+
+	/**
+	 * Send when the selection within a container has changed.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int EVENT_SELECTION_CHANGED = 0x8009;
+	
+	/**
+	 * Send when an object's text selection has changed.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int EVENT_TEXT_SELECTION_CHANGED = 0x8014;
+	
+	/**
+	 * Send when an object's state has changed, for example enabled/disabled, pressed/released, or checked/unchecked.
+	 * <p>
+	 * The eventData object is an array of 2 ints specifying the following:<ul>
+	 * <li>state - the STATE_* constant identifying the state that changed</li>
+	 * <li>newValue - either 1 or 0, indicating whether the state has changed to true or false</li>
+	 * </ul></p>
+	 * 
+	 * @since 3.6
+	 */
+	public static final int EVENT_STATE_CHANGED = 0x800A;
+	
+	/**
+	 * Send when an object has moved.
+	 * <p>
+	 * Note: only send one notification for the topmost object that has changed.
+	 * </p>
+	 * 
+	 * @since 3.6
+	 */
+	public static final int EVENT_LOCATION_CHANGED = 0x800B;
+	
+	/**
+	 * Send when an object's name has changed.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int EVENT_NAME_CHANGED = 0x800C;
+	
+	/**
+	 * Send when an object's description has changed.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int EVENT_DESCRIPTION_CHANGED = 0x800D;
+	
+	/**
+	 * Send when an object's value has changed.
+	 * <p>
+	 * The eventData object is an array of 2 Numbers specifying the following:<ul>
+	 * <li>oldValue - the object's old value</li>
+	 * <li>newValue - the object's new value</li>
+	 * </ul></p>
+	 * 
+	 * @since 3.6
+	 */
+	public static final int EVENT_VALUE_CHANGED = 0x800E;
+
+	/**
+	 * Send when the loading of a document has completed.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int EVENT_DOCUMENT_LOAD_COMPLETE = 0x105;
+
+	/**
+	 * Send when the loading of a document was interrupted.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int EVENT_DOCUMENT_LOAD_STOPPED = 0x106;
+
+	/**
+	 * Send when the document contents are being reloaded.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int EVENT_DOCUMENT_RELOAD = 0x107;
+
+	/**
+	 * Send when a slide changed in a presentation document
+	 * or a page boundary was crossed in a word processing document. 
+	 * 
+	 * @since 3.6
+	 */
+	public static final int EVENT_PAGE_CHANGED = 0x111;
+
+	/**
+	 * Send when the caret moved from one section to the next.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int EVENT_SECTION_CHANGED = 0x112;
+
+	/**
+	 * Send when the count or attributes of an accessible object's actions have changed.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int EVENT_ACTION_CHANGED = 0x100;
+
+	/**
+	 * Send when the starting index of this link within the containing string has changed.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int EVENT_HYPERLINK_START_INDEX_CHANGED = 0x10d;
+
+	/**
+	 * Send when the ending index of this link within the containing string has changed.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int EVENT_HYPERLINK_END_INDEX_CHANGED = 0x108;
+
+	/**
+	 * Send when the number of anchors associated with this hyperlink object has changed.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int EVENT_HYPERLINK_ANCHOR_COUNT_CHANGED = 0x109;
+
+	/**
+	 * Send when the hyperlink selected state changed from selected to unselected
+	 * or from unselected to selected.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int EVENT_HYPERLINK_SELECTED_LINK_CHANGED = 0x10a;
+
+	/**
+	 * Send when the hyperlink has been activated.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int EVENT_HYPERLINK_ACTIVATED = 0x10b;
+
+	/**
+	 * Send when one of the links associated with the hypertext object has been selected.
+	 * <p>
+	 * The eventData object is an Integer that represents the index of the selected link
+	 * in the hypertext object.
+	 * </p>
+	 * 
+	 * @since 3.6
+	 */
+	public static final int EVENT_HYPERTEXT_LINK_SELECTED = 0x10c;
+
+	/**
+	 * Send when the number of hyperlinks associated with a hypertext object has changed.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int EVENT_HYPERTEXT_LINK_COUNT_CHANGED = 0x10f;
+
+	/**
+	 * Send when an object's attributes have changed.
+	 * 
+	 * @see #EVENT_TEXT_ATTRIBUTE_CHANGED
+	 * 
+	 * @since 3.6
+	 */
+	public static final int EVENT_ATTRIBUTE_CHANGED = 0x200;
+
+	/**
+	 * Send when a table caption has changed.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int EVENT_TABLE_CAPTION_CHANGED = 0x203;
+
+	/**
+	 * Send when a table's column description has changed.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED = 0x204;
+
+	/**
+	 * Send when a table's column header has changed.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int EVENT_TABLE_COLUMN_HEADER_CHANGED = 0x205;
+
+	/**
+	 * Send when a table's data has changed.
+	 * <p>
+	 * The eventData object is an array of 5 ints specifying the following:<ul>
+	 * <li>type - {@link ACC#INSERT} or {@link ACC#DELETE} - the type of change</li>
+	 * <li>rowStart - the index of the first row that changed</li>
+	 * <li>rowCount - the number of contiguous rows that changed, or 0 if no rows changed</li>
+	 * <li>columnStart - the index of the first column that changed</li>
+	 * <li>columnCount - the number of contiguous columns that changed, or 0 if no columns changed</li>
+	 * </ul></p>
+	 * 
+	 * @since 3.6
+	 */
+	public static final int EVENT_TABLE_CHANGED = 0x206;
+
+	/**
+	 * Send when a table's row description has changed.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int EVENT_TABLE_ROW_DESCRIPTION_CHANGED = 0x207;
+
+	/**
+	 * Send when a table's row header has changed.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int EVENT_TABLE_ROW_HEADER_CHANGED = 0x208;
+
+	/**
+	 * Send when a table's summary has changed.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int EVENT_TABLE_SUMMARY_CHANGED = 0x209;
+
+	/**
+	 * Send when a text object's attributes have changed.
+	 * 
+	 * @see #EVENT_ATTRIBUTE_CHANGED
+	 * 
+	 * @since 3.6
+	 */
+	public static final int EVENT_TEXT_ATTRIBUTE_CHANGED = 0x20a;
+	 
+	/**
+	 * Send when the caret has moved to a new position.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int EVENT_TEXT_CARET_MOVED = 0x11b;
+
+	/**
+	 * Send when the caret has moved from one column to the next.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int EVENT_TEXT_COLUMN_CHANGED = 0x11d;
+
+	/**
+	 * Send when text was inserted or deleted.
+	 * <p>
+	 * The eventData object is an array of 4 objects specifying the following:<ul>
+	 * <li>type - {@link ACC#INSERT} or {@link ACC#DELETE} - the type of change</li>
+	 * <li>start - the index of the first character that changed</li>
+	 * <li>end - the index of the last character that changed</li>
+	 * <li>text - the text string that was inserted or deleted</li>
+	 * </ul></p>
+	 * 
+	 * @since 3.6
+	 */
+	public static final int EVENT_TEXT_CHANGED = 0x20c;
+
+	/**
+	 * Some attribute of this object is affected by a target object.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int RELATION_CONTROLLED_BY = 0;
+
+	/**
+	 * This object is interactive and controls some attribute of a target object.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int RELATION_CONTROLLER_FOR = 1;
+
+	/**
+	 * This object is described by the target object.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int RELATION_DESCRIBED_BY = 2;
+
+	/**
+	 * This object is describes the target object.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int RELATION_DESCRIPTION_FOR = 3;
+
+	/**
+	 * This object is embedded by a target object.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int RELATION_EMBEDDED_BY = 4;
+
+	/**
+	 * This object embeds a target object. This relation can be used on a
+	 * control's accessible to show where the content areas are.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int RELATION_EMBEDS = 5;
+
+	/**
+	 * Content flows to this object from a target object. 
+	 * This relation and RELATION_FLOWS_TO are useful to tie text and non-text
+	 * objects together in order to allow assistive technology to follow the
+	 * intended reading order.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int RELATION_FLOWS_FROM = 6;
+
+	/**
+	 * Content flows from this object to a target object.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int RELATION_FLOWS_TO = 7;
+
+	/**
+	 * This object is label for a target object.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int RELATION_LABEL_FOR = 8;
+
+	/**
+	 * This object is labelled by a target object.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int RELATION_LABELLED_BY = 9;
+
+	/**
+	 * This object is a member of a group of one or more objects. When 
+	 * there is more than one object in the group each member may have one and the 
+	 * same target, e.g. a grouping object.  It is also possible that each member has 
+	 * multiple additional targets, e.g. one for every other member in the group.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int RELATION_MEMBER_OF = 10;
+
+	/**
+	 * This object is a child of a target object.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int RELATION_NODE_CHILD_OF = 11;
+
+	/**
+	 * This object is a parent window of the target object.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int RELATION_PARENT_WINDOW_OF = 12;
+
+	/**
+	 * This object is a transient component related to the target object. 
+	 * When this object is activated the target object doesn't lose focus.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int RELATION_POPUP_FOR = 13;
+
+	/**
+	 * This object is a sub window of a target object.
+	 * 
+	 * @since 3.6
+	 */
+	public static final int RELATION_SUBWINDOW_OF = 14;	
 }
diff --git a/org/eclipse/swt/accessibility/Accessible.java b/org/eclipse/swt/accessibility/Accessible.java
index 6a2a5d5..f1b21b9 100644
--- a/org/eclipse/swt/accessibility/Accessible.java
+++ b/org/eclipse/swt/accessibility/Accessible.java
@@ -15,6 +15,7 @@ import java.util.*;
 import org.eclipse.swt.*;
 import org.eclipse.swt.events.*;
 import org.eclipse.swt.widgets.*;
+import org.eclipse.swt.internal.gtk.*;
 
 /**
  * Instances of this class provide a bridge between application
@@ -41,23 +42,77 @@ import org.eclipse.swt.widgets.*;
  */
 public class Accessible {
 	Vector accessibleListeners = new Vector ();
-	Vector controlListeners = new Vector ();
-	Vector textListeners = new Vector ();
+	Vector accessibleControlListeners = new Vector ();
+	Vector accessibleTextListeners = new Vector ();
+	Vector accessibleActionListeners = new Vector();
+	Vector accessibleHyperlinkListeners = new Vector();
+	Vector accessibleTableListeners = new Vector();
+	Vector accessibleTableCellListeners = new Vector();
+	Vector accessibleTextExtendedListeners = new Vector();
+	Vector accessibleValueListeners = new Vector();
+	Vector accessibleAttributeListeners = new Vector();
+	Accessible parent;
 	AccessibleObject accessibleObject;
 	Control control;
+	Vector relations;
+	Vector children;
+	
+	static class Relation {
+		int type;
+		Accessible target;
+		
+		public Relation(int type, Accessible target) {
+			this.type = type;
+			this.target = target;
+		}
+
+		public boolean equals(Object object) {
+			if (object == this) return true;
+			if (!(object instanceof Relation)) return false;
+			Relation relation = (Relation)object;
+			return (relation.type == this.type) && (relation.target == this.target);
+		}
+	}
 	
 	/**
+	 * Constructs a new instance of this class given its parent.
+	 * 
+	 * @param parent the Accessible parent, which must not be null
+	 * 
+	 * @exception IllegalArgumentException <ul>
+	 *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+	 * </ul>
+	 * 
+	 * @see Control#getAccessible
+	 * 
+	 * @since 3.6
+	 */
+	public Accessible(Accessible parent) {
+		this.parent = checkNull(parent);
+		this.control = parent.control;
+		if (parent.children == null) parent.children = new Vector();
+		parent.children.addElement(this);
+	}
+
+	/**
 	 * @since 3.5
+	 * @deprecated
 	 */
 	protected Accessible() {
 	}
 
+	static Accessible checkNull (Accessible parent) {
+		if (parent == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
+		return parent;
+	}
+
 	Accessible (Control control) {
 		super ();
 		this.control = control;
 		AccessibleFactory.registerAccessible (this);
 		control.addDisposeListener (new DisposeListener () {
 			public void widgetDisposed (DisposeEvent e) {
+				AccessibleFactory.unregisterAccessible (Accessible.this);
 				release ();
 			}
 		});
@@ -114,7 +169,7 @@ public class Accessible {
 	public void addAccessibleControlListener (AccessibleControlListener listener) {
 		checkWidget ();
 		if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
-		controlListeners.addElement (listener);		
+		accessibleControlListeners.addElement (listener);		
 	}
 
 	/**
@@ -122,7 +177,7 @@ public class Accessible {
 	 * be notified when an accessible client asks for custom text control
 	 * specific information. The listener is notified by sending it
 	 * one of the messages defined in the <code>AccessibleTextListener</code>
-	 * interface.
+	 * and <code>AccessibleTextExtendedListener</code> interfaces.
 	 *
 	 * @param listener the listener that should be notified when the receiver
 	 * is asked for custom text control specific information
@@ -136,6 +191,7 @@ public class Accessible {
 	 * </ul>
 	 *
 	 * @see AccessibleTextListener
+	 * @see AccessibleTextExtendedListener
 	 * @see #removeAccessibleTextListener
 	 * 
 	 * @since 3.0
@@ -143,10 +199,226 @@ public class Accessible {
 	public void addAccessibleTextListener (AccessibleTextListener listener) {
 		checkWidget ();
 		if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
-		textListeners.addElement (listener);		
+		if (listener instanceof AccessibleTextExtendedListener) {
+			accessibleTextExtendedListeners.addElement (listener);		
+		} else {
+			accessibleTextListeners.addElement (listener);
+		}
+	}
+	
+	/**
+	 * Adds the listener to the collection of listeners that will be
+	 * notified when an accessible client asks for any of the properties
+	 * defined in the <code>AccessibleAction</code> interface.
+	 *
+	 * @param listener the listener that should be notified when the receiver
+	 * is asked for <code>AccessibleAction</code> interface properties
+	 *
+	 * @exception IllegalArgumentException <ul>
+	 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+	 * </ul>
+	 * @exception SWTException <ul>
+	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
+	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
+	 * </ul>
+	 *
+	 * @see AccessibleActionListener
+	 * @see #removeAccessibleActionListener
+	 * 
+	 * @since 3.6
+	 */
+	public void addAccessibleActionListener(AccessibleActionListener listener) {
+		checkWidget();
+		if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+		accessibleActionListeners.addElement(listener);
+	}
+
+	/**
+	 * Adds the listener to the collection of listeners that will be
+	 * notified when an accessible client asks for any of the properties
+	 * defined in the <code>AccessibleHyperlink</code> interface.
+	 *
+	 * @param listener the listener that should be notified when the receiver
+	 * is asked for <code>AccessibleHyperlink</code> interface properties
+	 *
+	 * @exception IllegalArgumentException <ul>
+	 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+	 * </ul>
+	 * @exception SWTException <ul>
+	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
+	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
+	 * </ul>
+	 *
+	 * @see AccessibleHyperlinkListener
+	 * @see #removeAccessibleHyperlinkListener
+	 * 
+	 * @since 3.6
+	 */
+	public void addAccessibleHyperlinkListener(AccessibleHyperlinkListener listener) {
+		checkWidget();
+		if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+		accessibleHyperlinkListeners.addElement(listener);
+	}
+
+	/**
+	 * Adds the listener to the collection of listeners that will be
+	 * notified when an accessible client asks for any of the properties
+	 * defined in the <code>AccessibleTable</code> interface.
+	 *
+	 * @param listener the listener that should be notified when the receiver
+	 * is asked for <code>AccessibleTable</code> interface properties
+	 *
+	 * @exception IllegalArgumentException <ul>
+	 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+	 * </ul>
+	 * @exception SWTException <ul>
+	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
+	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
+	 * </ul>
+	 *
+	 * @see AccessibleTableListener
+	 * @see #removeAccessibleTableListener
+	 * 
+	 * @since 3.6
+	 */
+	public void addAccessibleTableListener(AccessibleTableListener listener) {
+		checkWidget();
+		if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+		accessibleTableListeners.addElement(listener);
+	}
+
+	/**
+	 * Adds the listener to the collection of listeners that will be
+	 * notified when an accessible client asks for any of the properties
+	 * defined in the <code>AccessibleTableCell</code> interface.
+	 *
+	 * @param listener the listener that should be notified when the receiver
+	 * is asked for <code>AccessibleTableCell</code> interface properties
+	 *
+	 * @exception IllegalArgumentException <ul>
+	 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+	 * </ul>
+	 * @exception SWTException <ul>
+	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
+	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
+	 * </ul>
+	 *
+	 * @see AccessibleTableCellListener
+	 * @see #removeAccessibleTableCellListener
+	 * 
+	 * @since 3.6
+	 */
+	public void addAccessibleTableCellListener(AccessibleTableCellListener listener) {
+		checkWidget();
+		if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+		accessibleTableCellListeners.addElement(listener);
+	}
+
+	/**
+	 * Adds the listener to the collection of listeners that will be
+	 * notified when an accessible client asks for any of the properties
+	 * defined in the <code>AccessibleValue</code> interface.
+	 *
+	 * @param listener the listener that should be notified when the receiver
+	 * is asked for <code>AccessibleValue</code> interface properties
+	 *
+	 * @exception IllegalArgumentException <ul>
+	 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+	 * </ul>
+	 * @exception SWTException <ul>
+	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
+	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
+	 * </ul>
+	 *
+	 * @see AccessibleValueListener
+	 * @see #removeAccessibleValueListener
+	 * 
+	 * @since 3.6
+	 */
+	public void addAccessibleValueListener(AccessibleValueListener listener) {
+		checkWidget();
+		if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+		accessibleValueListeners.addElement(listener);
+	}
+
+	/**
+	 * Adds the listener to the collection of listeners that will be
+	 * notified when an accessible client asks for any of the properties
+	 * defined in the <code>AccessibleAttribute</code> interface.
+	 *
+	 * @param listener the listener that should be notified when the receiver
+	 * is asked for <code>AccessibleAttribute</code> interface properties
+	 *
+	 * @exception IllegalArgumentException <ul>
+	 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+	 * </ul>
+	 * @exception SWTException <ul>
+	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
+	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
+	 * </ul>
+	 *
+	 * @see AccessibleAttributeListener
+	 * @see #removeAccessibleAttributeListener
+	 * 
+	 * @since 3.6
+	 */
+	public void addAccessibleAttributeListener(AccessibleAttributeListener listener) {
+		checkWidget();
+		if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+		accessibleAttributeListeners.addElement(listener);
+	}
+
+	/**
+	 * Adds a relation with the specified type and target
+	 * to the receiver's set of relations.
+	 * 
+	 * @param type an <code>ACC</code> constant beginning with RELATION_* indicating the type of relation
+	 * @param target the accessible that is the target for this relation
+	 * 
+	 * @since 3.6
+	 */
+	public void addRelation(int type, Accessible target) {
+		checkWidget();
+		if (relations == null) relations = new Vector();
+		Relation relation = new Relation(type, target);
+		if (relations.indexOf(relation) != -1) return;
+		relations.add(relation);
+		if (accessibleObject != null) accessibleObject.addRelation(type, target);
+	}
+	
+	void addRelations () {
+		if (relations == null) return;
+		if (accessibleObject == null) return;
+		for (int i = 0; i < relations.size(); i++) {
+			Relation relation = (Relation)relations.elementAt(i);
+			accessibleObject.addRelation(relation.type, relation.target);
+		}
 	}
 	
 	/**
+	 * Disposes of the operating system resources associated with
+	 * the receiver, and removes the receiver from its parent's
+	 * list of children.
+	 * <p>
+	 * This method should be called when an accessible that was created
+	 * with the public constructor <code>Accessible(Accessible parent)</code>
+	 * is no longer needed. You do not need to call this when the receiver's
+	 * control is disposed, because all <code>Accessible</code> instances
+	 * associated with a control are released when the control is disposed.
+	 * It is also not necessary to call this for instances of <code>Accessible</code>
+	 * that were retrieved with <code>Control.getAccessible()</code>.
+	 * </p>
+	 * 
+	 * @since 3.6
+	 */
+	public void dispose () {
+		if (parent == null) return;
+		release();
+		parent.children.removeElement(this);
+		parent = null;
+	}
+
+	/**
 	 * Returns the control for this Accessible object. 
 	 *
 	 * @return the receiver's control
@@ -161,29 +433,36 @@ public class Accessible {
 		if (!isValidThread ()) SWT.error (SWT.ERROR_THREAD_INVALID_ACCESS);
 		if (control.isDisposed ()) SWT.error (SWT.ERROR_WIDGET_DISPOSED);
 	}
-
-	AccessibleListener[] getAccessibleListeners () {
-		if (accessibleListeners == null) return null;
-		AccessibleListener[] result = new AccessibleListener [accessibleListeners.size ()];
-		accessibleListeners.copyInto (result);
-		return result;
+	
+	AccessibleObject getAccessibleObject () {
+		if (accessibleObject == null) {
+			if (parent == null) {
+				AccessibleFactory.createAccessible(this);
+			} else {
+				accessibleObject = AccessibleFactory.createChildAccessible(this, ACC.CHILDID_SELF);
+				accessibleObject.parent = parent.getAccessibleObject();
+			}
+		}
+		return accessibleObject;
 	}
 
 	int /*long*/ getControlHandle () {
-		return control.handle;
-	}
-
-	AccessibleControlListener[] getControlListeners () {
-		if (controlListeners == null) return null;
-		AccessibleControlListener[] result = new AccessibleControlListener [controlListeners.size ()];
-		controlListeners.copyInto (result);
-		return result;
-	}
-
-	AccessibleTextListener[] getTextListeners () {
-		if (textListeners == null) return null;
-		AccessibleTextListener[] result = new AccessibleTextListener [textListeners.size ()];
-		textListeners.copyInto (result);
+		int /*long*/ result = control.handle;
+		if (control instanceof Label) {
+			int /*long*/ list = OS.gtk_container_get_children (result);
+			if (list != 0) {
+				int /*long*/ temp = list;
+				while (temp != 0) {
+					int /*long*/ widget = OS.g_list_data( temp);
+					if (OS.GTK_WIDGET_VISIBLE (widget)) {
+						result = widget;
+						break;
+					}
+					temp = OS.g_list_next (temp);
+				}
+				OS.g_list_free (list);
+			}
+		}
 		return result;
 	}
 
@@ -199,6 +478,8 @@ public class Accessible {
 	 *
 	 * @param control the control to get the accessible object for
 	 * @return the platform specific accessible object
+	 * 
+	 * @noreference This method is not intended to be referenced by clients.
 	 */
 	public static Accessible internal_new_Accessible (Control control) {
 		return new Accessible (control);
@@ -210,7 +491,12 @@ public class Accessible {
 	}
 	
 	void release () {
-		AccessibleFactory.unregisterAccessible (Accessible.this);
+		if (children != null) {
+			for (int i = 0; i < children.size(); i++) {
+				Accessible child = (Accessible) children.elementAt(i);
+				child.dispose();
+			}
+		}
 		if (accessibleObject != null) {
 			accessibleObject.release ();
 			accessibleObject = null;
@@ -238,7 +524,7 @@ public class Accessible {
 	public void removeAccessibleControlListener (AccessibleControlListener listener) {
 		checkWidget ();
 		if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
-		controlListeners.removeElement (listener);
+		accessibleControlListeners.removeElement (listener);
 	}
 
 	/**
@@ -283,6 +569,7 @@ public class Accessible {
 	 * </ul>
 	 *
 	 * @see AccessibleTextListener
+	 * @see AccessibleTextExtendedListener
 	 * @see #addAccessibleTextListener
 	 * 
 	 * @since 3.0
@@ -290,7 +577,246 @@ public class Accessible {
 	public void removeAccessibleTextListener (AccessibleTextListener listener) {
 		checkWidget ();
 		if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
-		textListeners.removeElement (listener);
+		if (listener instanceof AccessibleTextExtendedListener) {
+			accessibleTextExtendedListeners.removeElement (listener);
+		} else {
+			accessibleTextListeners.removeElement (listener);
+		}
+	}
+	
+	/**
+	 * Removes the listener from the collection of listeners that will be
+	 * notified when an accessible client asks for any of the properties
+	 * defined in the <code>AccessibleAction</code> interface.
+	 *
+	 * @param listener the listener that should no longer be notified when the receiver
+	 * is asked for <code>AccessibleAction</code> interface properties
+	 *
+	 * @exception IllegalArgumentException <ul>
+	 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+	 * </ul>
+	 * @exception SWTException <ul>
+	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
+	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
+	 * </ul>
+	 *
+	 * @see AccessibleActionListener
+	 * @see #addAccessibleActionListener
+	 * 
+	 * @since 3.6
+	 */
+	public void removeAccessibleActionListener(AccessibleActionListener listener) {
+		checkWidget();
+		if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+		accessibleActionListeners.removeElement(listener);
+	}
+
+	/**
+	 * Removes the listener from the collection of listeners that will be
+	 * notified when an accessible client asks for any of the properties
+	 * defined in the <code>AccessibleHyperlink</code> interface.
+	 *
+	 * @param listener the listener that should no longer be notified when the receiver
+	 * is asked for <code>AccessibleHyperlink</code> interface properties
+	 *
+	 * @exception IllegalArgumentException <ul>
+	 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+	 * </ul>
+	 * @exception SWTException <ul>
+	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
+	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
+	 * </ul>
+	 *
+	 * @see AccessibleHyperlinkListener
+	 * @see #addAccessibleHyperlinkListener
+	 * 
+	 * @since 3.6
+	 */
+	public void removeAccessibleHyperlinkListener(AccessibleHyperlinkListener listener) {
+		checkWidget();
+		if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+		accessibleHyperlinkListeners.removeElement(listener);
+	}
+
+	/**
+	 * Removes the listener from the collection of listeners that will be
+	 * notified when an accessible client asks for any of the properties
+	 * defined in the <code>AccessibleTable</code> interface.
+	 *
+	 * @param listener the listener that should no longer be notified when the receiver
+	 * is asked for <code>AccessibleTable</code> interface properties
+	 *
+	 * @exception IllegalArgumentException <ul>
+	 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+	 * </ul>
+	 * @exception SWTException <ul>
+	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
+	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
+	 * </ul>
+	 *
+	 * @see AccessibleTableListener
+	 * @see #addAccessibleTableListener
+	 * 
+	 * @since 3.6
+	 */
+	public void removeAccessibleTableListener(AccessibleTableListener listener) {
+		checkWidget();
+		if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+		accessibleTableListeners.removeElement(listener);
+	}
+
+	/**
+	 * Removes the listener from the collection of listeners that will be
+	 * notified when an accessible client asks for any of the properties
+	 * defined in the <code>AccessibleTableCell</code> interface.
+	 *
+	 * @param listener the listener that should no longer be notified when the receiver
+	 * is asked for <code>AccessibleTableCell</code> interface properties
+	 *
+	 * @exception IllegalArgumentException <ul>
+	 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+	 * </ul>
+	 * @exception SWTException <ul>
+	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
+	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
+	 * </ul>
+	 *
+	 * @see AccessibleTableCellListener
+	 * @see #addAccessibleTableCellListener
+	 * 
+	 * @since 3.6
+	 */
+	public void removeAccessibleTableCellListener(AccessibleTableCellListener listener) {
+		checkWidget();
+		if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+		accessibleTableCellListeners.removeElement(listener);
+	}
+
+	/**
+	 * Removes the listener from the collection of listeners that will be
+	 * notified when an accessible client asks for any of the properties
+	 * defined in the <code>AccessibleValue</code> interface.
+	 *
+	 * @param listener the listener that should no longer be notified when the receiver
+	 * is asked for <code>AccessibleValue</code> interface properties
+	 *
+	 * @exception IllegalArgumentException <ul>
+	 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+	 * </ul>
+	 * @exception SWTException <ul>
+	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
+	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
+	 * </ul>
+	 *
+	 * @see AccessibleValueListener
+	 * @see #addAccessibleValueListener
+	 * 
+	 * @since 3.6
+	 */
+	public void removeAccessibleValueListener(AccessibleValueListener listener) {
+		checkWidget();
+		if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+		accessibleValueListeners.removeElement(listener);
+	}
+
+	/**
+	 * Removes the listener from the collection of listeners that will be
+	 * notified when an accessible client asks for any of the properties
+	 * defined in the <code>AccessibleAttribute</code> interface.
+	 *
+	 * @param listener the listener that should no longer be notified when the receiver
+	 * is asked for <code>AccessibleAttribute</code> interface properties
+	 *
+	 * @exception IllegalArgumentException <ul>
+	 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+	 * </ul>
+	 * @exception SWTException <ul>
+	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
+	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
+	 * </ul>
+	 *
+	 * @see AccessibleAttributeListener
+	 * @see #addAccessibleAttributeListener
+	 * 
+	 * @since 3.6
+	 */
+	public void removeAccessibleAttributeListener(AccessibleAttributeListener listener) {
+		checkWidget();
+		if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+		accessibleAttributeListeners.removeElement(listener);
+	}
+
+	/**
+	 * Removes the relation with the specified type and target
+	 * from the receiver's set of relations.
+	 * 
+	 * @param type an <code>ACC</code> constant beginning with RELATION_* indicating the type of relation
+	 * @param target the accessible that is the target for this relation
+	 * 
+	 * @since 3.6
+	 */
+	public void removeRelation(int type, Accessible target) {
+		checkWidget();
+		if (relations == null) return;
+		Relation relation = new Relation(type, target);
+		int index = relations.indexOf(relation);
+		if (index == -1) return;
+		relations.remove(index);
+		if (accessibleObject != null) accessibleObject.removeRelation(type, target);
+	}
+
+	/**
+	 * Sends a message with event-specific data to accessible clients
+	 * indicating that something has changed within a custom control.
+	 *
+	 * @param event an <code>ACC</code> constant beginning with EVENT_* indicating the message to send
+	 * @param eventData an object containing event-specific data, or null if there is no event-specific data
+	 * 
+	 * @exception SWTException <ul>
+	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
+	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
+	 * </ul>
+	 * 
+	 * @see ACC#EVENT_ACTION_CHANGED
+	 * @see ACC#EVENT_ATTRIBUTE_CHANGED
+	 * @see ACC#EVENT_DESCRIPTION_CHANGED
+	 * @see ACC#EVENT_DOCUMENT_LOAD_COMPLETE
+	 * @see ACC#EVENT_DOCUMENT_LOAD_STOPPED
+	 * @see ACC#EVENT_DOCUMENT_RELOAD
+	 * @see ACC#EVENT_HYPERLINK_ACTIVATED
+	 * @see ACC#EVENT_HYPERLINK_ANCHOR_COUNT_CHANGED
+	 * @see ACC#EVENT_HYPERLINK_END_INDEX_CHANGED
+	 * @see ACC#EVENT_HYPERLINK_SELECTED_LINK_CHANGED
+	 * @see ACC#EVENT_HYPERLINK_START_INDEX_CHANGED
+	 * @see ACC#EVENT_HYPERTEXT_LINK_COUNT_CHANGED
+	 * @see ACC#EVENT_HYPERTEXT_LINK_SELECTED
+	 * @see ACC#EVENT_LOCATION_CHANGED
+	 * @see ACC#EVENT_NAME_CHANGED
+	 * @see ACC#EVENT_PAGE_CHANGED
+	 * @see ACC#EVENT_SECTION_CHANGED
+	 * @see ACC#EVENT_SELECTION_CHANGED
+	 * @see ACC#EVENT_STATE_CHANGED
+	 * @see ACC#EVENT_TABLE_CAPTION_CHANGED
+	 * @see ACC#EVENT_TABLE_CHANGED
+	 * @see ACC#EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED
+	 * @see ACC#EVENT_TABLE_COLUMN_HEADER_CHANGED
+	 * @see ACC#EVENT_TABLE_ROW_DESCRIPTION_CHANGED
+	 * @see ACC#EVENT_TABLE_ROW_HEADER_CHANGED
+	 * @see ACC#EVENT_TABLE_SUMMARY_CHANGED
+	 * @see ACC#EVENT_TEXT_ATTRIBUTE_CHANGED
+	 * @see ACC#EVENT_TEXT_CARET_MOVED
+	 * @see ACC#EVENT_TEXT_CHANGED
+	 * @see ACC#EVENT_TEXT_COLUMN_CHANGED
+	 * @see ACC#EVENT_TEXT_SELECTION_CHANGED
+	 * @see ACC#EVENT_VALUE_CHANGED
+	 * 
+	 * @since 3.6
+	 */
+	public void sendEvent(int event, Object eventData) {
+		checkWidget();
+		if (accessibleObject != null) {
+			accessibleObject.sendEvent(event, eventData);
+		}
 	}
 	
 	/**
@@ -353,8 +879,8 @@ public class Accessible {
 	 * Sends a message to accessible clients that the text
 	 * within a custom control has changed.
 	 *
-	 * @param type the type of change, one of <code>ACC.NOTIFY_TEXT_INSERT</code>
-	 * or <code>ACC.NOTIFY_TEXT_DELETE</code>
+	 * @param type the type of change, one of <code>ACC.TEXT_INSERT</code>
+	 * or <code>ACC.TEXT_DELETE</code>
 	 * @param startIndex the text index within the control where the insertion or deletion begins
 	 * @param length the non-negative length in characters of the insertion or deletion
 	 *
diff --git a/org/eclipse/swt/accessibility/AccessibleActionAdapter.java b/org/eclipse/swt/accessibility/AccessibleActionAdapter.java
new file mode 100644
index 0000000..a8b9608
--- /dev/null
+++ b/org/eclipse/swt/accessibility/AccessibleActionAdapter.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.accessibility;
+
+/**
+ * This adapter class provides default implementations for the
+ * methods in the <code>AccessibleActionListener</code> interface.
+ * <p>
+ * Classes that wish to deal with <code>AccessibleAction</code> events can
+ * extend this class and override only the methods that they are
+ * interested in.
+ * </p>
+ *
+ * @see AccessibleActionListener
+ * @see AccessibleActionEvent
+ *
+ * @since 3.6
+ */
+public class AccessibleActionAdapter implements AccessibleActionListener {
+	/**
+	 * Returns the number of accessible actions available in this object.
+	 * <p>
+	 * If there are more than one, the first one (index 0) is considered the
+	 * "default" action of the object.
+	 * </p>
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] count - the number of actions, or zero if there are no actions</li>
+	 * </ul>
+	 */
+	public void getActionCount(AccessibleActionEvent e) {}
+
+	/**
+	 * Performs the specified action on the object.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] index - a 0 based index specifying the action to perform.
+	 * 		If the index lies outside the valid range no action is performed.</li>
+	 * <li>[out] result - set to {@link ACC#OK} if the action was performed.</li>
+	 * </ul>
+	 */
+	public void doAction(AccessibleActionEvent e) {}
+
+	/**
+	 * Returns a description of the specified action.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] index - a 0 based index specifying which action's description to return</li>
+	 * <li>[out] result - a localized string describing the specified action,
+	 * 		or null if the index lies outside the valid range</li>
+	 * </ul>
+	 */
+	public void getDescription(AccessibleActionEvent e) {}
+
+	/**
+	 * Returns a string representing one or more key bindings, if there
+	 * are any, associated with the specified action.
+	 * <p>
+	 * The returned string is of the following form: mnemonic;accelerator
+	 * for example: "C;CTRL+C" for the Copy item in a typical Edit menu.
+	 * </p>
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] index - a 0 based index specifying which action's key bindings to return</li>
+	 * <li>[out] result - a semicolon-delimited string of localized key bindings
+	 * 		(example: "C;CTRL+C"), or null if the index lies outside the valid range</li>
+	 * </ul>
+	 */
+	public void getKeyBinding(AccessibleActionEvent e) {}
+
+	/**
+	 * Returns the name of the specified action.
+	 * <p>
+	 * There is no need to implement this method for single action controls
+	 * since that would be redundant with AccessibleControlListener.getDefaultAction.
+	 * </p>
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] index - a 0 based index specifying which action's name to return</li>
+	 * <li>[in] localized - a boolean indicating whether or not to return a localized name</li>
+	 * <li>[out] result - the name of the specified action,
+	 * 		or null if the index lies outside the valid range</li>
+	 * </ul>
+	 */
+	public void getName(AccessibleActionEvent e) {}
+}
diff --git a/org/eclipse/swt/accessibility/AccessibleActionEvent.java b/org/eclipse/swt/accessibility/AccessibleActionEvent.java
new file mode 100644
index 0000000..de96073
--- /dev/null
+++ b/org/eclipse/swt/accessibility/AccessibleActionEvent.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.accessibility;
+
+import org.eclipse.swt.internal.*;
+
+/**
+ * Instances of this class are sent as a result of accessibility clients
+ * sending AccessibleAction messages to an accessible object.
+ *
+ * @see AccessibleActionListener
+ * @see AccessibleActionAdapter
+ *
+ * @since 3.6
+ */
+public class AccessibleActionEvent extends SWTEventObject {
+
+	/**
+	 * The value of this field must be set in the accessible action listener method
+	 * before returning. What to set it to depends on the listener method called.
+	 */
+	public String result;
+	public int count;
+	public int index;
+	public boolean localized;
+
+	static final long serialVersionUID = 2849066792640153087L;
+
+/**
+ * Constructs a new instance of this class.
+ *
+ * @param source the object that fired the event
+ */
+public AccessibleActionEvent(Object source) {
+	super(source);
+}
+
+/**
+ * Returns a string containing a concise, human-readable
+ * description of the receiver.
+ *
+ * @return a string representation of the event
+ */
+public String toString () {
+	return "AccessibleActionEvent {"
+		+ "string=" + result   //$NON-NLS-1$
+		+ " count=" + count   //$NON-NLS-1$
+		+ " index=" + index   //$NON-NLS-1$
+		+ "}";  //$NON-NLS-1$
+}
+}
diff --git a/org/eclipse/swt/accessibility/AccessibleActionListener.java b/org/eclipse/swt/accessibility/AccessibleActionListener.java
new file mode 100644
index 0000000..ab679ec
--- /dev/null
+++ b/org/eclipse/swt/accessibility/AccessibleActionListener.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.accessibility;
+
+import org.eclipse.swt.internal.SWTEventListener;
+
+/**
+ * Classes which implement this interface provide methods
+ * that handle AccessibleAction events.
+ * <p>
+ * After creating an instance of a class that implements
+ * this interface it can be added to an accessible using the
+ * <code>addAccessibleActionListener</code> method and removed using
+ * the <code>removeAccessibleActionListener</code> method.
+ * </p>
+ *
+ * @see AccessibleActionAdapter
+ * @see AccessibleActionEvent
+ *
+ * @since 3.6
+ */
+public interface AccessibleActionListener extends SWTEventListener {
+	/**
+	 * Returns the number of accessible actions available in this object.
+	 * <p>
+	 * If there are more than one, the first one (index 0) is considered the
+	 * "default" action of the object.
+	 * </p>
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] count - the number of actions, or zero if there are no actions</li>
+	 * </ul>
+	 */
+	public void getActionCount(AccessibleActionEvent e);
+
+	/**
+	 * Performs the specified action on the object.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] index - a 0 based index specifying the action to perform.
+	 * 		If the index lies outside the valid range no action is performed.</li>
+	 * <li>[out] result - set to {@link ACC#OK} if the action was performed.</li>
+	 * </ul>
+	 */
+	public void doAction(AccessibleActionEvent e);
+
+	/**
+	 * Returns a description of the specified action.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] index - a 0 based index specifying which action's description to return</li>
+	 * <li>[out] result - a localized string describing the specified action,
+	 * 		or null if the index lies outside the valid range</li>
+	 * </ul>
+	 */
+	public void getDescription(AccessibleActionEvent e);
+
+	/**
+	 * Returns a string representing one or more key bindings, if there
+	 * are any, associated with the specified action.
+	 * <p>
+	 * The returned string is of the following form: mnemonic;accelerator
+	 * for example: "C;CTRL+C" for the Copy item in a typical Edit menu.
+	 * </p>
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] index - a 0 based index specifying which action's key bindings to return</li>
+	 * <li>[out] result - a semicolon-delimited string of localized key bindings
+	 * 		(example: "C;CTRL+C"), or null if the index lies outside the valid range</li>
+	 * </ul>
+	 */
+	public void getKeyBinding(AccessibleActionEvent e);
+
+	/**
+	 * Returns the name of the specified action.
+	 * <p>
+	 * There is no need to implement this method for single action controls
+	 * since that would be redundant with AccessibleControlListener.getDefaultAction.
+	 * </p>
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] index - a 0 based index specifying which action's name to return</li>
+	 * <li>[in] localized - a boolean indicating whether or not to return a localized name</li>
+	 * <li>[out] result - the name of the specified action,
+	 * 		or null if the index lies outside the valid range</li>
+	 * </ul>
+	 */
+	public void getName(AccessibleActionEvent e);
+}
diff --git a/org/eclipse/swt/accessibility/AccessibleAttributeAdapter.java b/org/eclipse/swt/accessibility/AccessibleAttributeAdapter.java
new file mode 100644
index 0000000..43df16e
--- /dev/null
+++ b/org/eclipse/swt/accessibility/AccessibleAttributeAdapter.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.accessibility;
+
+/**
+ * This adapter class provides default implementations for the
+ * methods in the <code>AccessibleAttributeListener</code> interface.
+ * <p>
+ * Classes that wish to deal with <code>AccessibleAttribute</code> events can
+ * extend this class and override only the methods that they are
+ * interested in.
+ * </p>
+ *
+ * @see AccessibleAttributeListener
+ * @see AccessibleAttributeEvent
+ * @see AccessibleTextAttributeEvent
+ *
+ * @since 3.6
+ */
+public class AccessibleAttributeAdapter implements AccessibleAttributeListener {
+	/**
+	 * Returns attributes specific to this Accessible object.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] topMargin - the top margin in pixels</li>
+	 * <li>[out] bottomMargin - the bottom margin in pixels</li>
+	 * <li>[out] leftMargin - the left margin in pixels</li>
+	 * <li>[out] rightMargin - the right margin in pixels</li>
+	 * <li>[out] tabStops - an array of pixel locations</li>
+	 * <li>[out] justify - whether or not to justify the text</li>
+	 * <li>[out] alignment - one of <code>SWT#LEFT</code>, <code>SWT#RIGHT</code> or <code>SWT#CENTER</code></li>
+	 * <li>[out] indent - the indent in pixels</li>
+	 * <li>[out] attributes - an array of alternating key and value Strings
+	 * 		which represent additional (i.e. non predefined) attributes</li>
+	 * </ul>
+	 */
+	public void getAttributes(AccessibleAttributeEvent e) {}
+
+	/**
+	 * Returns text attributes specific to this Accessible object.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] offset - the 0 based text offset</li>
+	 * <li>[out] start - the starting offset of the character range
+	 * 		over which all text attributes match those of offset</li>
+	 * <li>[out] end - the 0 based offset after the last character of the character range
+	 * 		over which all text attributes match those of offset</li>
+	 * <li>[out] textStyle - the TextStyle of the character range</li>
+	 * <li>[out] attributes - an array of alternating key and value Strings
+	 * 		which represent additional (i.e. non predefined) attributes</li>
+	 * </ul>
+	 */
+	public void getTextAttributes(AccessibleTextAttributeEvent e) {}
+}
diff --git a/org/eclipse/swt/accessibility/AccessibleAttributeEvent.java b/org/eclipse/swt/accessibility/AccessibleAttributeEvent.java
new file mode 100644
index 0000000..b09ffb0
--- /dev/null
+++ b/org/eclipse/swt/accessibility/AccessibleAttributeEvent.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.accessibility;
+
+import org.eclipse.swt.internal.*;
+
+/**
+ * Instances of this class are sent as a result of accessibility clients
+ * sending AccessibleAttribute messages to an accessible object.
+ *
+ * @see AccessibleAttributeListener
+ * @see AccessibleAttributeAdapter
+ *
+ * @since 3.6
+ */
+public class AccessibleAttributeEvent extends SWTEventObject {
+
+	public int topMargin;
+	public int bottomMargin;
+	public int leftMargin;
+	public int rightMargin;
+	public int[] tabStops;
+	public boolean justify;
+	public int alignment;
+	public int indent;
+	public String [] attributes;
+
+	static final long serialVersionUID = 2237016128901566049L;
+
+/**
+ * Constructs a new instance of this class.
+ *
+ * @param source the object that fired the event
+ */
+public AccessibleAttributeEvent(Object source) {
+	super(source);
+}
+
+/**
+ * Returns a string containing a concise, human-readable
+ * description of the receiver.
+ *
+ * @return a string representation of the event
+ */
+public String toString () {
+	return "AccessibleAttributeEvent {"
+		+ " topMargin=" + topMargin   //$NON-NLS-1$
+		+ " bottomMargin=" + bottomMargin   //$NON-NLS-1$
+		+ " leftMargin=" + leftMargin   //$NON-NLS-1$
+		+ " rightMargin=" + rightMargin   //$NON-NLS-1$
+		+ " tabStops=" + tabStops   //$NON-NLS-1$
+		+ " justify=" + justify   //$NON-NLS-1$
+		+ " alignment=" + alignment   //$NON-NLS-1$
+		+ " indent=" + indent   //$NON-NLS-1$
+		+ "}";  //$NON-NLS-1$
+}
+}
diff --git a/org/eclipse/swt/accessibility/AccessibleAttributeListener.java b/org/eclipse/swt/accessibility/AccessibleAttributeListener.java
new file mode 100644
index 0000000..6d08f26
--- /dev/null
+++ b/org/eclipse/swt/accessibility/AccessibleAttributeListener.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.accessibility;
+
+import org.eclipse.swt.internal.SWTEventListener;
+
+/**
+ * Classes which implement this interface provide methods
+ * that handle AccessibleAttribute events.
+ * <p>
+ * After creating an instance of a class that implements
+ * this interface it can be added to an accessible using the
+ * <code>addAccessibleAttributeListener</code> method and removed using
+ * the <code>removeAccessibleAttributeListener</code> method.
+ * </p>
+ *
+ * @see AccessibleAttributeAdapter
+ * @see AccessibleAttributeEvent
+ * @see AccessibleTextAttributeEvent
+ *
+ * @since 3.6
+ */
+public interface AccessibleAttributeListener extends SWTEventListener {
+	/**
+	 * Returns attributes specific to this Accessible object.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] topMargin - the top margin in pixels</li>
+	 * <li>[out] bottomMargin - the bottom margin in pixels</li>
+	 * <li>[out] leftMargin - the left margin in pixels</li>
+	 * <li>[out] rightMargin - the right margin in pixels</li>
+	 * <li>[out] tabStops - an array of pixel locations</li>
+	 * <li>[out] justify - whether or not to justify the text</li>
+	 * <li>[out] alignment - one of <code>SWT#LEFT</code>, <code>SWT#RIGHT</code> or <code>SWT#CENTER</code></li>
+	 * <li>[out] indent - the indent in pixels</li>
+	 * <li>[out] attributes - an array of alternating key and value Strings
+	 * 		which represent additional (i.e. non predefined) attributes</li>
+	 * </ul>
+	 */
+	public void getAttributes(AccessibleAttributeEvent e);
+
+	/**
+	 * Returns text attributes specific to this Accessible object.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] offset - the 0 based text offset</li>
+	 * <li>[out] start - the starting offset of the character range
+	 * 		over which all text attributes match those of offset</li>
+	 * <li>[out] end - the 0 based offset after the last character of the character range
+	 * 		over which all text attributes match those of offset</li>
+	 * <li>[out] textStyle - the TextStyle of the character range</li>
+	 * <li>[out] attributes - an array of alternating key and value Strings
+	 * 		which represent additional (i.e. non predefined) attributes</li>
+	 * </ul>
+	 */
+	public void getTextAttributes(AccessibleTextAttributeEvent e);
+}
diff --git a/org/eclipse/swt/accessibility/AccessibleControlAdapter.java b/org/eclipse/swt/accessibility/AccessibleControlAdapter.java
index 1dfc718..a9bc78a 100644
--- a/org/eclipse/swt/accessibility/AccessibleControlAdapter.java
+++ b/org/eclipse/swt/accessibility/AccessibleControlAdapter.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -80,18 +80,22 @@ public abstract class AccessibleControlAdapter implements AccessibleControlListe
 	
 	/**
 	 * Sent when an accessibility client requests the accessible object
-	 * for a child of the control.
-	 * The default behavior is to do nothing.
+	 * for a child of the control by index or childID, or when a client
+	 * requests the index of an accessible object in its parent.
 	 * <p>
-	 * Return an <code>Accessible</code> for the specified control or
-	 * child in the <code>accessible</code> field of the event object.
-	 * Return null if the specified child does not have its own
-	 * <code>Accessible</code>.
-	 * </p>
+	 * The childID field in the event object can be one of the following:<ul>
+	 *    <li>an integer child ID - return the accessible object for the specified child ID,
+	 *    	or null if the specified child does not have its own accessible</li>
+	 *    <li>{@link ACC#CHILDID_CHILD_AT_INDEX} - return the accessible child object at the specified index,
+	 *    	or null if this object has no children</li>
+	 *    <li>{@link ACC#CHILDID_CHILD_INDEX} - return the index of this accessible in its parent</li>
+	 * </ul></p>
 	 *
 	 * @param e an event object containing the following fields:<ul>
-	 *    <li>childID [IN] - an identifier specifying a child of the control</li>
-	 *    <li>accessible [OUT] - an Accessible for the specified childID, or null if one does not exist</li>
+	 *    <li>childID [IN] - an identifier specifying a child of the control, or one of the predefined CHILDID constants</li>
+	 *    <li>detail [Optional IN] - the index of the child accessible to be returned when childID = CHILDID_CHILD_AT_INDEX</li>
+	 *    <li>detail [Optional OUT] - the index of this accessible in its parent when childID = CHILDID_CHILD_INDEX</li>
+	 *    <li>accessible [Optional OUT] - an Accessible for the specified childID or index, or null if one does not exist</li>
 	 * </ul>
 	 */
 	public void getChild(AccessibleControlEvent e) {
@@ -186,6 +190,7 @@ public abstract class AccessibleControlAdapter implements AccessibleControlListe
 	 *
 	 * @param e an event object containing the following fields:<ul>
 	 *    <li>childID [Typical OUT] - the ID of the selected child, or CHILDID_SELF, or CHILDID_MULTIPLE, or CHILDID_NONE</li>
+	 *    <li>children [Optional OUT] - the array of childIDs for the selected children if CHILDID_MULTIPLE is returned</li>
 	 *    <li>accessible [Optional OUT] - the accessible object for the control or child may be returned instead of the childID</li>
 	 * </ul>
 	 */
@@ -235,16 +240,20 @@ public abstract class AccessibleControlAdapter implements AccessibleControlListe
 	}
 	
 	/**
-	 * Sent when an accessibility client requests the children of the control.
-	 * The default behavior is to do nothing.
+	 * Sent when an accessibility client requests the children, or visible children,
+	 * of the control. The default behavior is to do nothing.
 	 * <p>
-	 * Return the children as an array of childIDs in the <code>children</code>
-	 * field of the event object.
+	 * Return the children as an array of childIDs or accessibles in the
+	 * <code>children</code> field of the event object.
 	 * </p>
 	 *
 	 * @param e an event object containing the following fields:<ul>
+	 *    <li>detail [IN] - a flag that may have one of the following values:<ul>
+	 *    	<li>0 (default) - return all children</li>
+	 *    	<li>VISIBLE - return all visible children</li>
+	 *    </ul>
 	 *    <li>children [Typical OUT] - an array of childIDs</li>
-	 *    <li>accessible [Optional OUT] - an array of accessible objects for the children may be returned instead of the childIDs</li>
+	 *    <li>children [Optional OUT] - an array of accessible objects for the children may be returned instead of the childIDs</li>
 	 * </ul>
 	 */
 	public void getChildren(AccessibleControlEvent e) {
diff --git a/org/eclipse/swt/accessibility/AccessibleControlListener.java b/org/eclipse/swt/accessibility/AccessibleControlListener.java
index 537f57b..8b50d4b 100644
--- a/org/eclipse/swt/accessibility/AccessibleControlListener.java
+++ b/org/eclipse/swt/accessibility/AccessibleControlListener.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -79,17 +79,22 @@ public interface AccessibleControlListener extends SWTEventListener {
 	
 	/**
 	 * Sent when an accessibility client requests the accessible object
-	 * for a child of the control.
+	 * for a child of the control by index or childID, or when a client
+	 * requests the index of an accessible object in its parent.
 	 * <p>
-	 * Return an <code>Accessible</code> for the specified control or
-	 * child in the <code>accessible</code> field of the event object.
-	 * Return null if the specified child does not have its own
-	 * <code>Accessible</code>.
-	 * </p>
+	 * The childID field in the event object can be one of the following:<ul>
+	 *    <li>an integer child ID - return the accessible object for the specified child ID,
+	 *    	or null if the specified child does not have its own accessible</li>
+	 *    <li>{@link ACC#CHILDID_CHILD_AT_INDEX} - return the accessible child object at the specified index,
+	 *    	or null if this object has no children</li>
+	 *    <li>{@link ACC#CHILDID_CHILD_INDEX} - return the index of this accessible in its parent</li>
+	 * </ul></p>
 	 *
 	 * @param e an event object containing the following fields:<ul>
-	 *    <li>childID [IN] - an identifier specifying a child of the control</li>
-	 *    <li>accessible [OUT] - an Accessible for the specified childID, or null if one does not exist</li>
+	 *    <li>childID [IN] - an identifier specifying a child of the control, or one of the predefined CHILDID constants</li>
+	 *    <li>detail [Optional IN] - the index of the child accessible to be returned when childID = CHILDID_CHILD_AT_INDEX</li>
+	 *    <li>detail [Optional OUT] - the index of this accessible in its parent when childID = CHILDID_CHILD_INDEX</li>
+	 *    <li>accessible [Optional OUT] - an Accessible for the specified childID or index, or null if one does not exist</li>
 	 * </ul>
 	 */
 	public void getChild(AccessibleControlEvent e);
@@ -174,6 +179,7 @@ public interface AccessibleControlListener extends SWTEventListener {
 	 *
 	 * @param e an event object containing the following fields:<ul>
 	 *    <li>childID [Typical OUT] - the ID of the selected child, or CHILDID_SELF, or CHILDID_MULTIPLE, or CHILDID_NONE</li>
+	 *    <li>children [Optional OUT] - the array of childIDs for the selected children if CHILDID_MULTIPLE is returned</li>
 	 *    <li>accessible [Optional OUT] - the accessible object for the control or child may be returned instead of the childID</li>
 	 * </ul>
 	 */
@@ -218,13 +224,18 @@ public interface AccessibleControlListener extends SWTEventListener {
 	public void getValue(AccessibleControlEvent e);
 	
 	/**
-	 * Sent when an accessibility client requests the children of the control.
+	 * Sent when an accessibility client requests the children, or visible children,
+	 * of the control.
 	 * <p>
-	 * Return the children as an array of childIDs in the <code>children</code>
-	 * field of the event object.
+	 * Return the children as an array of childIDs or accessibles in the
+	 * <code>children</code> field of the event object.
 	 * </p>
 	 *
 	 * @param e an event object containing the following fields:<ul>
+	 *    <li>detail [IN] - a flag that may have one of the following values:<ul>
+	 *    	<li>0 (default) - return all children</li>
+	 *    	<li>VISIBLE - return all visible children</li>
+	 *    </ul>
 	 *    <li>children [Typical OUT] - an array of childIDs</li>
 	 *    <li>children [Optional OUT] - an array of accessible objects for the children may be returned instead of the childIDs</li>
 	 * </ul>
diff --git a/org/eclipse/swt/accessibility/AccessibleFactory.java b/org/eclipse/swt/accessibility/AccessibleFactory.java
index c6f6300..47ed177 100644
--- a/org/eclipse/swt/accessibility/AccessibleFactory.java
+++ b/org/eclipse/swt/accessibility/AccessibleFactory.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -18,43 +18,53 @@ import org.eclipse.swt.internal.gtk.*;
 import org.eclipse.swt.*;
 
 class AccessibleFactory {
-	int /*long*/ handle;
-	int /*long*/ objectParentType;
-	int /*long*/ widgetTypeName;
-	Callback atkObjectFactoryCB_create_accessible;
-	Callback gTypeInfo_base_init_factory;
-	Hashtable accessibles = new Hashtable (9);
-	
-	static final Hashtable Types = new Hashtable (9);
+	static final Hashtable Accessibles = new Hashtable (9);
 	static final Hashtable Factories = new Hashtable (9);	
-	static final int /*long*/ DefaultParentType = OS.g_type_from_name (Converter.wcsToMbcs (null, "GtkAccessible", true)); //$NON-NLS-1$
-	static final byte[] FACTORY_PARENTTYPENAME = Converter.wcsToMbcs (null, "AtkObjectFactory", true); //$NON-NLS-1$
-	static final byte[] SWT_TYPE_PREFIX = Converter.wcsToMbcs (null, "SWT", false); //$NON-NLS-1$
-	static final byte[] CHILD_TYPENAME = Converter.wcsToMbcs (null, "Child", false); //$NON-NLS-1$
-	static final byte[] FACTORY_TYPENAME = Converter.wcsToMbcs (null, "SWTFactory", true); //$NON-NLS-1$
+	static final String SWT_TYPE_PREFIX = "SWTAccessible"; //$NON-NLS-1$
+	static final String CHILD_TYPENAME = "Child"; //$NON-NLS-1$
+	static final String FACTORY_TYPENAME = "SWTFactory"; //$NON-NLS-1$
 	static final int[] actionRoles = {
 		ACC.ROLE_CHECKBUTTON, ACC.ROLE_COMBOBOX, ACC.ROLE_LINK,
 		ACC.ROLE_MENUITEM, ACC.ROLE_PUSHBUTTON, ACC.ROLE_RADIOBUTTON,
-		ACC.ROLE_SPLITBUTTON,
+		ACC.ROLE_SPLITBUTTON, ACC.ROLE_SPINBUTTON,
+		ACC.ROLE_CHECKMENUITEM, ACC.ROLE_RADIOMENUITEM,
+	};
+	static final int[] hypertextRoles = {
+		ACC.ROLE_TEXT, ACC.ROLE_LINK, ACC.ROLE_PARAGRAPH,
 	};
-	static final int[] hypertextRoles = {ACC.ROLE_LINK};
 	static final int[] selectionRoles = {
 		ACC.ROLE_LIST, ACC.ROLE_TABFOLDER, ACC.ROLE_TABLE, ACC.ROLE_TREE,
 	};
 	static final int[] textRoles = {
-		ACC.ROLE_COMBOBOX, ACC.ROLE_LINK, ACC.ROLE_LABEL, ACC.ROLE_TEXT,
+		ACC.ROLE_COMBOBOX, ACC.ROLE_LINK, ACC.ROLE_LABEL, ACC.ROLE_TEXT, ACC.ROLE_STATUSBAR,
+		ACC.ROLE_PARAGRAPH,
+	};
+	static final int[] tableRoles = {
+		ACC.ROLE_TABLE, ACC.ROLE_TREE,
+	};
+	static final int[] valueRoles = {
+		ACC.ROLE_SCROLLBAR, ACC.ROLE_SPINBUTTON, ACC.ROLE_PROGRESSBAR,
 	};
 
-	/* AT callbacks*/
+	/* Action callbacks */
+	static final Callback AtkActionCB_do_action;
+	static final Callback AtkActionCB_get_n_actions;	
+	static final Callback AtkActionCB_get_description;
 	static final Callback AtkActionCB_get_keybinding;
 	static final Callback AtkActionCB_get_name;	
+	
+	/* Component callbacks */
 	static final Callback AtkComponentCB_get_extents;
 	static final Callback AtkComponentCB_get_position;
 	static final Callback AtkComponentCB_get_size;
 	static final Callback AtkComponentCB_ref_accessible_at_point;
+	
+	/* Hypertext callbacks */
 	static final Callback AtkHypertextCB_get_link;
 	static final Callback AtkHypertextCB_get_n_links;
 	static final Callback AtkHypertextCB_get_link_index;
+	
+	/* Object callbacks */
 	static final Callback AtkObjectCB_get_description;
 	static final Callback AtkObjectCB_get_index_in_parent;
 	static final Callback AtkObjectCB_get_n_children;
@@ -63,9 +73,47 @@ class AccessibleFactory {
 	static final Callback AtkObjectCB_get_role;
 	static final Callback AtkObjectCB_ref_child;
 	static final Callback AtkObjectCB_ref_state_set;
+	static final Callback AtkObjectCB_get_attributes;
+	
+	/* Selection callbacks */
 	static final Callback AtkSelectionCB_is_child_selected;
 	static final Callback AtkSelectionCB_ref_selection;
+
+	/* Table callbacks */
+	static final Callback AtkTableCB_ref_at;
+	static final Callback AtkTableCB_get_index_at;
+	static final Callback AtkTableCB_get_column_at_index;
+	static final Callback AtkTableCB_get_row_at_index;
+	static final Callback AtkTableCB_get_n_columns;
+	static final Callback AtkTableCB_get_n_rows;
+	static final Callback AtkTableCB_get_column_extent_at;
+	static final Callback AtkTableCB_get_row_extent_at;
+	static final Callback AtkTableCB_get_summary;
+	static final Callback AtkTableCB_get_caption;
+	static final Callback AtkTableCB_get_column_description;
+	static final Callback AtkTableCB_get_row_description;
+	static final Callback AtkTableCB_get_column_header;
+	static final Callback AtkTableCB_get_row_header;
+	static final Callback AtkTableCB_get_selected_columns;
+	static final Callback AtkTableCB_get_selected_rows;
+	static final Callback AtkTableCB_is_column_selected;
+	static final Callback AtkTableCB_is_row_selected;
+	static final Callback AtkTableCB_is_selected;
+	static final Callback AtkTableCB_add_column_selection;
+	static final Callback AtkTableCB_add_row_selection;
+	static final Callback AtkTableCB_remove_column_selection;
+	static final Callback AtkTableCB_remove_row_selection;
+	
+	/* Text callbacks */
+	static final Callback AtkTextCB_get_character_extents;
+	static final Callback AtkTextCB_get_range_extents;
+	static final Callback AtkTextCB_get_run_attributes;
+	static final Callback AtkTextCB_get_offset_at_point;
+	static final Callback AtkTextCB_add_selection;
+	static final Callback AtkTextCB_remove_selection;
+	static final Callback AtkTextCB_set_selection;
 	static final Callback AtkTextCB_get_caret_offset;
+	static final Callback AtkTextCB_set_caret_offset;
 	static final Callback AtkTextCB_get_n_selections;
 	static final Callback AtkTextCB_get_selection;
 	static final Callback AtkTextCB_get_text;
@@ -74,22 +122,39 @@ class AccessibleFactory {
 	static final Callback AtkTextCB_get_text_before_offset;
 	static final Callback AtkTextCB_get_character_at_offset;
 	static final Callback AtkTextCB_get_character_count;
+	static final Callback AtkTextCB_get_bounded_ranges;
+	
+	/* Value callbacks */
+	static final Callback AtkValueCB_get_current_value;
+	static final Callback AtkValueCB_get_maximum_value;
+	static final Callback AtkValueCB_get_minimum_value;
+	static final Callback AtkValueCB_set_current_value;
+	
 	static final Callback GObjectClass_finalize;
+	static final Callback AtkObjectFactoryCB_create_accessible;
+	
 	/* interface initialization callbacks */
 	static final Callback InitActionIfaceCB;		
 	static final Callback InitComponentIfaceCB;
 	static final Callback InitHypertextIfaceCB;
 	static final Callback GTypeInfo_base_init_type;
 	static final Callback InitSelectionIfaceCB;
+	static final Callback InitTableIfaceCB;
 	static final Callback InitTextIfaceCB;
+	static final Callback InitValueIfaceCB;
+	static final Callback GTypeInfo_base_init_factory;
 	/* interface definitions */
-	static int /*long*/ ObjectIfaceDefinition;
 	static final int /*long*/ ActionIfaceDefinition;
 	static final int /*long*/ ComponentIfaceDefinition;
 	static final int /*long*/ HypertextIfaceDefinition;
 	static final int /*long*/ SelectionIfaceDefinition;
+	static final int /*long*/ TableIfaceDefinition;
 	static final int /*long*/ TextIfaceDefinition;
+	static final int /*long*/ ValueIfaceDefinition;
 	static {
+		AtkActionCB_do_action = newCallback (AccessibleObject.class, "atkAction_do_action", 2); //$NON-NLS-1$
+		AtkActionCB_get_n_actions = newCallback (AccessibleObject.class, "atkAction_get_n_actions", 1); //$NON-NLS-1$
+		AtkActionCB_get_description = newCallback (AccessibleObject.class, "atkAction_get_description", 2); //$NON-NLS-1$
 		AtkActionCB_get_keybinding = newCallback (AccessibleObject.class, "atkAction_get_keybinding", 2); //$NON-NLS-1$
 		AtkActionCB_get_name = newCallback (AccessibleObject.class, "atkAction_get_name", 2); //$NON-NLS-1$
 		AtkComponentCB_get_extents = newCallback (AccessibleObject.class, "atkComponent_get_extents", 6); //$NON-NLS-1$
@@ -107,9 +172,41 @@ class AccessibleFactory {
 		AtkObjectCB_ref_state_set = newCallback (AccessibleObject.class, "atkObject_ref_state_set", 1); //$NON-NLS-1$
 		AtkObjectCB_get_index_in_parent = newCallback (AccessibleObject.class, "atkObject_get_index_in_parent", 1); //$NON-NLS-1$
 		AtkObjectCB_ref_child = newCallback (AccessibleObject.class, "atkObject_ref_child", 2); //$NON-NLS-1$
+		AtkObjectCB_get_attributes = newCallback (AccessibleObject.class, "atkObject_get_attributes", 1); //$NON-NLS-1$
 		AtkSelectionCB_is_child_selected = newCallback (AccessibleObject.class, "atkSelection_is_child_selected", 2); //$NON-NLS-1$
 		AtkSelectionCB_ref_selection = newCallback (AccessibleObject.class, "atkSelection_ref_selection", 2); //$NON-NLS-1$
+		AtkTableCB_ref_at = newCallback (AccessibleObject.class, "atkTable_ref_at", 3); //$NON-NLS-1$
+		AtkTableCB_get_index_at = newCallback (AccessibleObject.class, "atkTable_get_index_at", 3); //$NON-NLS-1$
+		AtkTableCB_get_column_at_index = newCallback (AccessibleObject.class, "atkTable_get_column_at_index", 2); //$NON-NLS-1$
+		AtkTableCB_get_row_at_index = newCallback (AccessibleObject.class, "atkTable_get_row_at_index", 2); //$NON-NLS-1$
+		AtkTableCB_get_n_columns = newCallback (AccessibleObject.class, "atkTable_get_n_columns", 1); //$NON-NLS-1$
+		AtkTableCB_get_n_rows = newCallback (AccessibleObject.class, "atkTable_get_n_rows", 1); //$NON-NLS-1$
+		AtkTableCB_get_column_extent_at = newCallback (AccessibleObject.class, "atkTable_get_column_extent_at", 3); //$NON-NLS-1$
+		AtkTableCB_get_row_extent_at = newCallback (AccessibleObject.class, "atkTable_get_row_extent_at", 3); //$NON-NLS-1$
+		AtkTableCB_get_caption = newCallback (AccessibleObject.class, "atkTable_get_caption", 1); //$NON-NLS-1$
+		AtkTableCB_get_summary = newCallback (AccessibleObject.class, "atkTable_get_summary", 1); //$NON-NLS-1$
+		AtkTableCB_get_column_description = newCallback (AccessibleObject.class, "atkTable_get_column_description", 2); //$NON-NLS-1$
+		AtkTableCB_get_row_description = newCallback (AccessibleObject.class, "atkTable_get_row_description", 2); //$NON-NLS-1$
+		AtkTableCB_get_column_header = newCallback (AccessibleObject.class, "atkTable_get_column_header", 2); //$NON-NLS-1$
+		AtkTableCB_get_row_header = newCallback (AccessibleObject.class, "atkTable_get_row_header", 2); //$NON-NLS-1$
+		AtkTableCB_get_selected_columns = newCallback (AccessibleObject.class, "atkTable_get_selected_columns", 2); //$NON-NLS-1$
+		AtkTableCB_get_selected_rows = newCallback (AccessibleObject.class, "atkTable_get_selected_rows", 2); //$NON-NLS-1$
+		AtkTableCB_is_column_selected = newCallback (AccessibleObject.class, "atkTable_is_column_selected", 2); //$NON-NLS-1$
+		AtkTableCB_is_row_selected = newCallback (AccessibleObject.class, "atkTable_is_row_selected", 2); //$NON-NLS-1$
+		AtkTableCB_is_selected = newCallback (AccessibleObject.class, "atkTable_is_selected", 3); //$NON-NLS-1$
+		AtkTableCB_add_column_selection = newCallback (AccessibleObject.class, "atkTable_add_column_selection", 2); //$NON-NLS-1$
+		AtkTableCB_add_row_selection = newCallback (AccessibleObject.class, "atkTable_add_row_selection", 2); //$NON-NLS-1$
+		AtkTableCB_remove_column_selection = newCallback (AccessibleObject.class, "atkTable_remove_column_selection", 2); //$NON-NLS-1$
+		AtkTableCB_remove_row_selection = newCallback (AccessibleObject.class, "atkTable_remove_row_selection", 2); //$NON-NLS-1$
+		AtkTextCB_get_character_extents = newCallback (AccessibleObject.class, "atkText_get_character_extents", 7); //$NON-NLS-1$
+		AtkTextCB_get_range_extents = newCallback (AccessibleObject.class, "atkText_get_range_extents", 5); //$NON-NLS-1$
+		AtkTextCB_get_run_attributes = newCallback (AccessibleObject.class, "atkText_get_run_attributes", 4); //$NON-NLS-1$
+		AtkTextCB_get_offset_at_point = newCallback (AccessibleObject.class, "atkText_get_offset_at_point", 4); //$NON-NLS-1$
+		AtkTextCB_add_selection = newCallback (AccessibleObject.class, "atkText_add_selection", 3); //$NON-NLS-1$
+		AtkTextCB_remove_selection = newCallback (AccessibleObject.class, "atkText_remove_selection", 2); //$NON-NLS-1$
+		AtkTextCB_set_selection = newCallback (AccessibleObject.class, "atkText_set_selection", 4); //$NON-NLS-1$
 		AtkTextCB_get_caret_offset = newCallback (AccessibleObject.class, "atkText_get_caret_offset", 1); //$NON-NLS-1$
+		AtkTextCB_set_caret_offset = newCallback (AccessibleObject.class, "atkText_set_caret_offset", 2); //$NON-NLS-1$
 		AtkTextCB_get_n_selections = newCallback (AccessibleObject.class, "atkText_get_n_selections", 1); //$NON-NLS-1$
 		AtkTextCB_get_selection = newCallback (AccessibleObject.class, "atkText_get_selection", 4); //$NON-NLS-1$
 		AtkTextCB_get_text = newCallback (AccessibleObject.class, "atkText_get_text", 3); //$NON-NLS-1$
@@ -118,8 +215,15 @@ class AccessibleFactory {
 		AtkTextCB_get_text_before_offset = newCallback (AccessibleObject.class, "atkText_get_text_before_offset", 5); //$NON-NLS-1$
 		AtkTextCB_get_character_at_offset = newCallback (AccessibleObject.class, "atkText_get_character_at_offset", 2); //$NON-NLS-1$
 		AtkTextCB_get_character_count = newCallback (AccessibleObject.class, "atkText_get_character_count", 1); //$NON-NLS-1$
+		AtkTextCB_get_bounded_ranges = newCallback (AccessibleObject.class, "atkText_get_bounded_ranges", 5); //$NON-NLS-1$
+		AtkValueCB_get_current_value = newCallback (AccessibleObject.class, "atkValue_get_current_value", 2); //$NON-NLS-1$
+		AtkValueCB_get_maximum_value = newCallback (AccessibleObject.class, "atkValue_get_maximum_value", 2); //$NON-NLS-1$
+		AtkValueCB_get_minimum_value = newCallback (AccessibleObject.class, "atkValue_get_minimum_value", 2); //$NON-NLS-1$
+		AtkValueCB_set_current_value = newCallback (AccessibleObject.class, "atkValue_set_current_value", 2); //$NON-NLS-1$
 		GObjectClass_finalize = newCallback (AccessibleObject.class, "gObjectClass_finalize", 1); //$NON-NLS-1$
 		GTypeInfo_base_init_type = newCallback (AccessibleFactory.class, "gTypeInfo_base_init_type", 1); //$NON-NLS-1$
+		GTypeInfo_base_init_factory = newCallback (AccessibleFactory.class, "gTypeInfo_base_init_factory", 1); //$NON-NLS-1$
+		AtkObjectFactoryCB_create_accessible = newCallback (AccessibleFactory.class, "atkObjectFactory_create_accessible", 1); //$NON-NLS-1$
 		/* Action interface */
 		InitActionIfaceCB = newCallback (AccessibleFactory.class, "initActionIfaceCB", 1); //$NON-NLS-1$
 		GInterfaceInfo interfaceInfo = new GInterfaceInfo ();
@@ -145,11 +249,23 @@ class AccessibleFactory {
 		SelectionIfaceDefinition = OS.g_malloc (GInterfaceInfo.sizeof);  
 		OS.memmove (SelectionIfaceDefinition, interfaceInfo, GInterfaceInfo.sizeof);
 		/* Text interface */
+		InitTableIfaceCB = newCallback (AccessibleFactory.class, "initTableIfaceCB", 1); //$NON-NLS-1$
+		interfaceInfo = new GInterfaceInfo ();
+		interfaceInfo.interface_init = InitTableIfaceCB.getAddress ();
+		TableIfaceDefinition = OS.g_malloc (GInterfaceInfo.sizeof);  
+		OS.memmove (TableIfaceDefinition, interfaceInfo, GInterfaceInfo.sizeof);
+		/* Text interface */
 		InitTextIfaceCB = newCallback (AccessibleFactory.class, "initTextIfaceCB", 1); //$NON-NLS-1$
 		interfaceInfo = new GInterfaceInfo ();
 		interfaceInfo.interface_init = InitTextIfaceCB.getAddress ();
 		TextIfaceDefinition = OS.g_malloc (GInterfaceInfo.sizeof);  
 		OS.memmove (TextIfaceDefinition, interfaceInfo, GInterfaceInfo.sizeof);
+		/* Value interface */
+		InitValueIfaceCB = newCallback (AccessibleFactory.class, "initValueIfaceCB", 1); //$NON-NLS-1$
+		interfaceInfo = new GInterfaceInfo ();
+		interfaceInfo.interface_init = InitValueIfaceCB.getAddress ();
+		ValueIfaceDefinition = OS.g_malloc (GInterfaceInfo.sizeof);  
+		OS.memmove (ValueIfaceDefinition, interfaceInfo, GInterfaceInfo.sizeof);
 	}
 
 	static private Callback newCallback (Object object, String method, int argCount) {
@@ -158,51 +274,31 @@ class AccessibleFactory {
 		return callback;
 	}
 
-	private AccessibleFactory (int /*long*/ widgetType) {
-		super ();
-		widgetTypeName = OS.g_type_name (widgetType);
-		int widgetTypeNameLength = OS.strlen (widgetTypeName) + 1;
+	static String getTypeName (int /*long*/ type) {
+		int /*long*/ typeName = OS.g_type_name (type);
+		int widgetTypeNameLength = OS.strlen (typeName);
 		byte[] buffer = new byte [widgetTypeNameLength];
-		OS.memmove (buffer, widgetTypeName, widgetTypeNameLength);
-		byte[] factoryName = new byte [FACTORY_TYPENAME.length + widgetTypeNameLength - 1];
-		System.arraycopy (FACTORY_TYPENAME, 0, factoryName, 0, FACTORY_TYPENAME.length);
-		System.arraycopy (buffer, 0, factoryName, FACTORY_TYPENAME.length - 1, widgetTypeNameLength);
-		if (OS.g_type_from_name (factoryName) == 0) {
-			/* register the factory */
-			int /*long*/ registry = ATK.atk_get_default_registry ();
-			int /*long*/ previousFactory = ATK.atk_registry_get_factory (registry, widgetType);
-			objectParentType = ATK.atk_object_factory_get_accessible_type (previousFactory);
-			if (objectParentType == 0) objectParentType = DefaultParentType;
-			int /*long*/ factoryParentType = OS.g_type_from_name (FACTORY_PARENTTYPENAME);
-			gTypeInfo_base_init_factory  = new Callback (this, "gTypeInfo_base_init_factory", 1); //$NON-NLS-1$
-			int /*long*/ address = gTypeInfo_base_init_factory.getAddress ();
-			if (address == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS);
-			GTypeInfo typeInfo = new GTypeInfo ();
-			typeInfo.base_init = address;
-			typeInfo.class_size = (short)ATK.AtkObjectFactoryClass_sizeof ();
-			typeInfo.instance_size = (short)ATK.AtkObjectFactory_sizeof ();
-			int /*long*/ info = OS.g_malloc (GTypeInfo.sizeof); 
-			OS.memmove (info, typeInfo, GTypeInfo.sizeof); 
-			int /*long*/ swtFactoryType = OS.g_type_register_static (factoryParentType, factoryName, info, 0);
-			ATK.atk_registry_set_factory_type (registry, widgetType, swtFactoryType);
-			handle = ATK.atk_registry_get_factory (registry, widgetType);
-		}
+		OS.memmove (buffer, typeName, widgetTypeNameLength);
+		return new String(Converter.mbcsToWcs(null, buffer));
 	}
-
-	void addAccessible (Accessible accessible) {
-		int /*long*/ controlHandle = accessible.getControlHandle ();
-		accessibles.put (new LONG (controlHandle), accessible);
-		ATK.atk_object_factory_create_accessible (handle, controlHandle);
+	
+	static int /*long*/ getParentType (int /*long*/ widgetType) {
+		LONG type = null;
+		while (widgetType != 0 && (type = (LONG)Factories.get(new LONG(widgetType))) == null) {
+			widgetType = OS.g_type_parent (widgetType);
+		}
+		if (type == null) return 0;
+		return ((LONG)type).value;
 	}
 
-	int /*long*/ atkObjectFactory_create_accessible (int /*long*/ widget) {
-		Accessible accessible = (Accessible) accessibles.get (new LONG (widget));
+	static int /*long*/ atkObjectFactory_create_accessible (int /*long*/ widget) {
+		Accessible accessible = (Accessible) Accessibles.get (new LONG (widget));
 		if (accessible == null) {
 			/*
 			* we don't care about this control, so create it with the parent's
 			* type so that its accessibility callbacks will not pass though here 
 			*/  
-			int /*long*/ result = OS.g_object_new (objectParentType, 0);
+			int /*long*/ result = OS.g_object_new (getParentType(OS.G_OBJECT_TYPE (widget)), 0);
 			ATK.atk_object_initialize (result, widget);
 			return result;
 		}
@@ -210,31 +306,35 @@ class AccessibleFactory {
 		if (accessible.accessibleObject != null) {
 			return accessible.accessibleObject.handle;
 		}
-		int typeNameLength = OS.strlen (widgetTypeName);
-		byte[] buffer = new byte [typeNameLength];
-		OS.memmove (buffer, widgetTypeName, typeNameLength);
-		int /*long*/ type = getType (buffer, accessible, objectParentType, ACC.CHILDID_SELF);
-		AccessibleObject object = new AccessibleObject (type, widget, accessible, objectParentType, false);
+		int /*long*/ widgetType = OS.G_OBJECT_TYPE (widget);
+		int /*long*/ parentType = getParentType (widgetType);
+		if (parentType == 0) parentType = ATK.GTK_TYPE_ACCESSIBLE();
+		int /*long*/ type = getType (getTypeName(widgetType), accessible, parentType, ACC.CHILDID_SELF);
+		AccessibleObject object = new AccessibleObject (type, widget, accessible, false);
 		accessible.accessibleObject = object;
+		accessible.addRelations ();
 		return object.handle;
 	}
 	
-	static int /*long*/ getChildType (Accessible accessible, int childIndex) {
-		return getType (CHILD_TYPENAME, accessible, DefaultParentType, childIndex);
+	static AccessibleObject createChildAccessible (Accessible accessible, int childId) {
+		int /*long*/ childType = getType (CHILD_TYPENAME, accessible, ATK.GTK_TYPE_ACCESSIBLE(), childId);
+		return new AccessibleObject(childType, 0, accessible, true);
 	}
-
-	static int /*long*/ getDefaultParentType () {
-		return DefaultParentType;
+	
+	static void createAccessible (Accessible accessible) {
+		int /*long*/ controlHandle = accessible.getControlHandle ();
+		OS.gtk_widget_get_accessible(controlHandle);
 	}
 
-	static int /*long*/ getType (byte[] widgetTypeName, Accessible accessible, int /*long*/ parentType, int childId) {
+	static int /*long*/ getType (String widgetTypeName, Accessible accessible, int /*long*/ parentType, int childId) {
 		AccessibleControlEvent event = new AccessibleControlEvent (accessible);
 		event.childID = childId;
-		AccessibleControlListener[] listeners = accessible.getControlListeners ();
-		for (int i = 0; i < listeners.length; i++) {
-			listeners [i].getRole (event);
+		Vector listeners = accessible.accessibleControlListeners;
+		for (int i = 0, length = listeners.size(); i < length; i++) {
+			AccessibleControlListener listener = (AccessibleControlListener)listeners.elementAt (i);
+			listener.getRole (event);
 		}
-		boolean action = false, hypertext = false, selection = false, text = false;
+		boolean action = false, hypertext = false, selection = false, table = false, text = false, value = false;
 		if (event.detail != 0) {	/* a role was specified */
 			for (int i = 0; i < actionRoles.length; i++) {
 				if (event.detail == actionRoles [i]) {
@@ -254,27 +354,39 @@ class AccessibleFactory {
 					break;
 				}
 			}
+			for (int i = 0; i < tableRoles.length; i++) {
+				if (event.detail == tableRoles [i]) {
+					table = true;
+					break;
+				}
+			}
 			for (int i = 0; i < textRoles.length; i++) {
 				if (event.detail == textRoles [i]) {
 					text = true;
 					break;
 				}
 			}
+			for (int i = 0; i < valueRoles.length; i++) {
+				if (event.detail == valueRoles [i]) {
+					value = true;
+					break;
+				}
+			}
 		} else {
-			action = hypertext = selection = text = true;
+			action = hypertext = selection = table = text = value = true;
 		}
-		String swtTypeName = new String (SWT_TYPE_PREFIX);
-		swtTypeName += new String (widgetTypeName);
+		String swtTypeName = SWT_TYPE_PREFIX + widgetTypeName;
 		if (action) swtTypeName += "Action"; //$NON-NLS-1$
 		if (hypertext) swtTypeName += "Hypertext"; //$NON-NLS-1$
 		if (selection) swtTypeName += "Selection"; //$NON-NLS-1$
+		if (table) swtTypeName += "Table"; //$NON-NLS-1$
 		if (text) swtTypeName += "Text"; //$NON-NLS-1$
+		if (value) swtTypeName += "Value"; //$NON-NLS-1$
 
-		int /*long*/ type = 0;
-		LONG typeInt = (LONG)Types.get (swtTypeName);
-		if (typeInt != null) {
-			type = typeInt.value;
-		} else {
+		byte[] nameBytes = Converter.wcsToMbcs(null, swtTypeName, true);
+		int /*long*/ type = OS.g_type_from_name(nameBytes);
+		if (type == 0) {
+			if (AccessibleObject.DEBUG) AccessibleObject.print("-->New Type=" + swtTypeName); //$NON-NLS-1$
 			/* define the type */
 			int /*long*/ queryPtr = OS.g_malloc (GTypeQuery.sizeof);
 			OS.g_type_query (parentType, queryPtr);
@@ -285,29 +397,25 @@ class AccessibleFactory {
 			typeInfo.base_init = GTypeInfo_base_init_type.getAddress ();
 			typeInfo.class_size = (short) query.class_size;
 			typeInfo.instance_size = (short) query.instance_size;
-			ObjectIfaceDefinition = OS.g_malloc (GTypeInfo.sizeof); 
-			OS.memmove (ObjectIfaceDefinition, typeInfo, GTypeInfo.sizeof);
-			byte[] nameBytes = Converter.wcsToMbcs(null, swtTypeName, true);
-			type = OS.g_type_register_static (parentType, nameBytes, ObjectIfaceDefinition, 0);
-			OS.g_type_add_interface_static (type, AccessibleObject.ATK_COMPONENT_TYPE, ComponentIfaceDefinition);
-			if (action) OS.g_type_add_interface_static (type, AccessibleObject.ATK_ACTION_TYPE, ActionIfaceDefinition);
-			if (hypertext) OS.g_type_add_interface_static (type, AccessibleObject.ATK_HYPERTEXT_TYPE, HypertextIfaceDefinition);
-			if (selection) OS.g_type_add_interface_static (type, AccessibleObject.ATK_SELECTION_TYPE, SelectionIfaceDefinition);
-			if (text) OS.g_type_add_interface_static (type, AccessibleObject.ATK_TEXT_TYPE, TextIfaceDefinition);
-			Types.put (swtTypeName, new LONG (type));
+			int /*long*/ definition = OS.g_malloc (GTypeInfo.sizeof); 
+			OS.memmove (definition, typeInfo, GTypeInfo.sizeof);
+			type = OS.g_type_register_static (parentType, nameBytes, definition, 0);
+			OS.g_type_add_interface_static (type, ATK.ATK_TYPE_COMPONENT(), ComponentIfaceDefinition);
+			if (action) OS.g_type_add_interface_static (type, ATK.ATK_TYPE_ACTION(), ActionIfaceDefinition);
+			if (hypertext) OS.g_type_add_interface_static (type, ATK.ATK_TYPE_HYPERTEXT(), HypertextIfaceDefinition);
+			if (selection) OS.g_type_add_interface_static (type, ATK.ATK_TYPE_SELECTION(), SelectionIfaceDefinition);
+			if (table) OS.g_type_add_interface_static (type, ATK.ATK_TYPE_TABLE(), TableIfaceDefinition);
+			if (text) OS.g_type_add_interface_static (type, ATK.ATK_TYPE_TEXT(), TextIfaceDefinition);
+			if (value) OS.g_type_add_interface_static (type, ATK.ATK_TYPE_VALUE(), ValueIfaceDefinition);
 		}
 		return type;
 	}
 
-	int /*long*/ gTypeInfo_base_init_factory (int /*long*/ klass) {
-		int /*long*/ atkObjectFactoryClass = ATK.ATK_OBJECT_FACTORY_CLASS (klass);
-		AtkObjectFactoryClass objectFactoryClassStruct = new AtkObjectFactoryClass ();
-		ATK.memmove (objectFactoryClassStruct, atkObjectFactoryClass);
-		atkObjectFactoryCB_create_accessible = new Callback (this, "atkObjectFactory_create_accessible", 1); //$NON-NLS-1$
-		int /*long*/ address = atkObjectFactoryCB_create_accessible.getAddress ();
-		if (address == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS);
-		objectFactoryClassStruct.create_accessible = address;
-		ATK.memmove (atkObjectFactoryClass, objectFactoryClassStruct); 
+	static int /*long*/ gTypeInfo_base_init_factory (int /*long*/ klass) {
+		AtkObjectFactoryClass objectClass = new AtkObjectFactoryClass ();
+		ATK.memmove (objectClass, klass);
+		objectClass.create_accessible = AtkObjectFactoryCB_create_accessible.getAddress ();
+		ATK.memmove (klass, objectClass); 
 		return 0;
 	}
 	
@@ -322,6 +430,7 @@ class AccessibleFactory {
 		objectClass.ref_state_set = AtkObjectCB_ref_state_set.getAddress ();
 		objectClass.get_index_in_parent = AtkObjectCB_get_index_in_parent.getAddress ();
 		objectClass.ref_child = AtkObjectCB_ref_child.getAddress ();
+		objectClass.get_attributes = AtkObjectCB_get_attributes.getAddress ();
 		int /*long*/ gObjectClass = OS.G_OBJECT_CLASS (klass);
 		GObjectClass objectClassStruct = new GObjectClass ();
 		OS.memmove (objectClassStruct, gObjectClass);
@@ -332,83 +441,143 @@ class AccessibleFactory {
 	}
 	
 	static int /*long*/ initActionIfaceCB (int /*long*/ iface) {
-		AtkActionIface actionIface = new AtkActionIface ();
-		ATK.memmove (actionIface, iface);
-		actionIface.get_keybinding = AtkActionCB_get_keybinding.getAddress (); 
-		actionIface.get_name = AtkActionCB_get_name.getAddress ();
-		ATK.memmove (iface, actionIface);
+		AtkActionIface inter = new AtkActionIface ();
+		ATK.memmove (inter, iface);
+		inter.do_action = AtkActionCB_do_action.getAddress (); 
+		inter.get_n_actions = AtkActionCB_get_n_actions.getAddress ();
+		inter.get_description = AtkActionCB_get_description.getAddress ();
+		inter.get_keybinding = AtkActionCB_get_keybinding.getAddress (); 
+		inter.get_name = AtkActionCB_get_name.getAddress ();
+		ATK.memmove (iface, inter);
 		return 0;
 	}
 	
 	static int /*long*/ initComponentIfaceCB (int /*long*/ iface) {
-		AtkComponentIface componentIface = new AtkComponentIface ();
-		ATK.memmove (componentIface, iface);
-		componentIface.get_extents = AtkComponentCB_get_extents.getAddress ();
-		componentIface.get_position = AtkComponentCB_get_position.getAddress ();
-		componentIface.get_size = AtkComponentCB_get_size.getAddress ();
-		componentIface.ref_accessible_at_point = AtkComponentCB_ref_accessible_at_point.getAddress ();
-		ATK.memmove (iface, componentIface);
+		AtkComponentIface inter = new AtkComponentIface ();
+		ATK.memmove (inter, iface);
+		inter.get_extents = AtkComponentCB_get_extents.getAddress ();
+		inter.get_position = AtkComponentCB_get_position.getAddress ();
+		inter.get_size = AtkComponentCB_get_size.getAddress ();
+		inter.ref_accessible_at_point = AtkComponentCB_ref_accessible_at_point.getAddress ();
+		ATK.memmove (iface, inter);
 		return 0;
 	}
 
 	static int /*long*/ initHypertextIfaceCB (int /*long*/ iface) {
-		AtkHypertextIface hypertextIface = new AtkHypertextIface ();
-		ATK.memmove (hypertextIface, iface);
-		hypertextIface.get_link = AtkHypertextCB_get_link.getAddress (); 
-		hypertextIface.get_link_index = AtkHypertextCB_get_link_index.getAddress ();
-		hypertextIface.get_n_links = AtkHypertextCB_get_n_links.getAddress ();
-		ATK.memmove (iface, hypertextIface);
+		AtkHypertextIface inter = new AtkHypertextIface ();
+		ATK.memmove (inter, iface);
+		inter.get_link = AtkHypertextCB_get_link.getAddress (); 
+		inter.get_link_index = AtkHypertextCB_get_link_index.getAddress ();
+		inter.get_n_links = AtkHypertextCB_get_n_links.getAddress ();
+		ATK.memmove (iface, inter);
 		return 0;
 	}
 
 	static int /*long*/ initSelectionIfaceCB (int /*long*/ iface) {
-		AtkSelectionIface selectionIface = new AtkSelectionIface ();
-		ATK.memmove (selectionIface, iface);
-		selectionIface.is_child_selected = AtkSelectionCB_is_child_selected.getAddress ();
-		selectionIface.ref_selection = AtkSelectionCB_ref_selection.getAddress ();
-		ATK.memmove (iface, selectionIface);
+		AtkSelectionIface inter = new AtkSelectionIface ();
+		ATK.memmove (inter, iface);
+		inter.is_child_selected = AtkSelectionCB_is_child_selected.getAddress ();
+		inter.ref_selection = AtkSelectionCB_ref_selection.getAddress ();
+		ATK.memmove (iface, inter);
+		return 0;
+	}
+
+	static int /*long*/ initTableIfaceCB (int /*long*/ iface) {
+		AtkTableIface inter = new AtkTableIface ();
+		ATK.memmove (inter, iface);
+		inter.ref_at = AtkTableCB_ref_at.getAddress();
+		inter.get_index_at = AtkTableCB_get_index_at.getAddress();
+		inter.get_column_at_index = AtkTableCB_get_column_at_index.getAddress();
+		inter.get_row_at_index = AtkTableCB_get_row_at_index.getAddress();
+		inter.get_n_columns = AtkTableCB_get_n_columns.getAddress();
+		inter.get_n_rows = AtkTableCB_get_n_rows.getAddress();
+		inter.get_column_extent_at = AtkTableCB_get_column_extent_at.getAddress();
+		inter.get_row_extent_at = AtkTableCB_get_row_extent_at.getAddress();
+		inter.get_caption = AtkTableCB_get_caption.getAddress();
+		inter.get_summary = AtkTableCB_get_summary.getAddress();
+		inter.get_column_description = AtkTableCB_get_column_description.getAddress();
+		inter.get_row_description = AtkTableCB_get_row_description.getAddress();
+		inter.get_column_header = AtkTableCB_get_column_header.getAddress();
+		inter.get_row_header = AtkTableCB_get_row_header.getAddress();
+		inter.get_selected_columns = AtkTableCB_get_selected_columns.getAddress();
+		inter.get_selected_rows = AtkTableCB_get_selected_rows.getAddress();
+		inter.is_column_selected = AtkTableCB_is_column_selected.getAddress();
+		inter.is_row_selected = AtkTableCB_is_row_selected.getAddress();
+		inter.is_selected = AtkTableCB_is_selected.getAddress();
+		inter.add_column_selection = AtkTableCB_add_column_selection.getAddress();
+		inter.add_row_selection = AtkTableCB_add_row_selection.getAddress();
+		inter.remove_column_selection = AtkTableCB_remove_column_selection.getAddress();
+		inter.remove_row_selection = AtkTableCB_remove_row_selection.getAddress();
+		ATK.memmove (iface, inter);
 		return 0;
 	}
 
 	static int /*long*/ initTextIfaceCB (int /*long*/ iface) {
-		AtkTextIface textInterface = new AtkTextIface ();
-		ATK.memmove (textInterface, iface);
-		textInterface.get_caret_offset = AtkTextCB_get_caret_offset.getAddress ();
-		textInterface.get_character_at_offset = AtkTextCB_get_character_at_offset.getAddress ();
-		textInterface.get_character_count = AtkTextCB_get_character_count.getAddress ();
-		textInterface.get_n_selections = AtkTextCB_get_n_selections.getAddress ();
-		textInterface.get_selection = AtkTextCB_get_selection.getAddress ();
-		textInterface.get_text = AtkTextCB_get_text.getAddress ();
-		textInterface.get_text_after_offset = AtkTextCB_get_text_after_offset.getAddress ();
-		textInterface.get_text_at_offset = AtkTextCB_get_text_at_offset.getAddress ();
-		textInterface.get_text_before_offset = AtkTextCB_get_text_before_offset.getAddress ();
-		ATK.memmove (iface, textInterface);
+		AtkTextIface inter = new AtkTextIface ();
+		ATK.memmove (inter, iface);
+		inter.get_range_extents = AtkTextCB_get_range_extents.getAddress ();
+		inter.get_character_extents = AtkTextCB_get_character_extents.getAddress ();
+		inter.get_run_attributes= AtkTextCB_get_run_attributes.getAddress ();
+		inter.get_offset_at_point = AtkTextCB_get_offset_at_point.getAddress ();
+		inter.add_selection = AtkTextCB_add_selection.getAddress ();
+		inter.remove_selection = AtkTextCB_remove_selection.getAddress ();
+		inter.set_selection = AtkTextCB_set_selection.getAddress ();
+		inter.get_caret_offset = AtkTextCB_get_caret_offset.getAddress ();
+		inter.set_caret_offset = AtkTextCB_set_caret_offset.getAddress ();
+		inter.get_character_at_offset = AtkTextCB_get_character_at_offset.getAddress ();
+		inter.get_character_count = AtkTextCB_get_character_count.getAddress ();
+		inter.get_n_selections = AtkTextCB_get_n_selections.getAddress ();
+		inter.get_selection = AtkTextCB_get_selection.getAddress ();
+		inter.get_text = AtkTextCB_get_text.getAddress ();
+		inter.get_text_after_offset = AtkTextCB_get_text_after_offset.getAddress ();
+		inter.get_text_at_offset = AtkTextCB_get_text_at_offset.getAddress ();
+		inter.get_text_before_offset = AtkTextCB_get_text_before_offset.getAddress ();
+		inter.get_bounded_ranges = AtkTextCB_get_bounded_ranges.getAddress ();
+		ATK.memmove (iface, inter);
+		return 0;
+	}
+
+	static int /*long*/ initValueIfaceCB (int /*long*/ iface) {
+		AtkValueIface inter = new AtkValueIface ();
+		ATK.memmove (inter, iface);
+		inter.get_current_value = AtkValueCB_get_current_value.getAddress ();
+		inter.get_maximum_value = AtkValueCB_get_maximum_value.getAddress ();
+		inter.get_minimum_value = AtkValueCB_get_minimum_value.getAddress ();
+		inter.set_current_value = AtkValueCB_set_current_value.getAddress ();
+		ATK.memmove (iface, inter);
 		return 0;
 	}
 
 	static void registerAccessible (Accessible accessible) {
-		/* If DefaultParentType is 0 then OS accessibility is not active */
-		if (DefaultParentType == 0) return;
-		int /*long*/ controlHandle = accessible.getControlHandle ();
-		int /*long*/ widgetType = OS.G_OBJECT_TYPE (controlHandle);
-		AccessibleFactory factory = (AccessibleFactory) Factories.get (new LONG (widgetType));
-		if (factory == null) {
-			factory = new AccessibleFactory (widgetType);
-			Factories.put (new LONG (widgetType), factory);
+		int /*long*/ widget = accessible.getControlHandle ();
+		int /*long*/ widgetType = OS.G_OBJECT_TYPE (widget);
+		int /*long*/ registry = ATK.atk_get_default_registry ();
+		int /*long*/ factory = ATK.atk_registry_get_factory (registry, widgetType);
+		/* If NO_OP factory is registered then OS accessibility is not active */
+		if (ATK.ATK_IS_NO_OP_OBJECT_FACTORY(factory)) return;
+		String name = FACTORY_TYPENAME + getTypeName(widgetType);
+		byte[] factoryName = Converter.wcsToMbcs(null, name, true);
+		if (OS.g_type_from_name (factoryName) == 0) {
+			if (AccessibleObject.DEBUG) AccessibleObject.print("-->New Factory=" + name); //$NON-NLS-1$
+			/* register the factory */
+			GTypeInfo typeInfo = new GTypeInfo ();
+			typeInfo.base_init = GTypeInfo_base_init_factory.getAddress ();
+			typeInfo.class_size = (short)ATK.AtkObjectFactoryClass_sizeof ();
+			typeInfo.instance_size = (short)ATK.AtkObjectFactory_sizeof ();
+			int /*long*/ info = OS.g_malloc (GTypeInfo.sizeof); 
+			OS.memmove (info, typeInfo, GTypeInfo.sizeof); 
+			int /*long*/ swtFactoryType = OS.g_type_register_static (ATK.ATK_TYPE_OBJECT_FACTORY(), factoryName, info, 0);
+			int /*long*/ parentType = ATK.atk_object_factory_get_accessible_type(factory);
+			ATK.atk_registry_set_factory_type (registry, widgetType, swtFactoryType);
+			Factories.put (new LONG (widgetType), new LONG (parentType));
 		}
-		factory.addAccessible (accessible);
-	}
-	
-	void removeAccessible (Accessible accessible) {
-		accessibles.remove (new LONG (accessible.getControlHandle ()));
+		if (AccessibleObject.DEBUG) AccessibleObject.print("-->Register=" + accessible.control + " " + widget); //$NON-NLS-1$
+		Accessibles.put (new LONG (widget), accessible);
 	}
 	
 	static void unregisterAccessible (Accessible accessible) {
-		int /*long*/ controlHandle = accessible.getControlHandle ();
-		int /*long*/ widgetType = OS.G_OBJECT_TYPE (controlHandle);
-		AccessibleFactory factory = (AccessibleFactory) Factories.get (new LONG (widgetType));
-		if (factory != null) {
-			factory.removeAccessible (accessible);
-		}
+		int /*long*/ widget = accessible.getControlHandle ();
+		Accessibles.remove (new LONG (widget));
+		if (AccessibleObject.DEBUG) AccessibleObject.print("-->Deregister=" + accessible.control + " " + widget); //$NON-NLS-1$
 	}
 }
diff --git a/org/eclipse/swt/accessibility/AccessibleHyperlinkAdapter.java b/org/eclipse/swt/accessibility/AccessibleHyperlinkAdapter.java
new file mode 100644
index 0000000..693cbc8
--- /dev/null
+++ b/org/eclipse/swt/accessibility/AccessibleHyperlinkAdapter.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.accessibility;
+
+/**
+ * This adapter class provides default implementations for the
+ * methods in the <code>AccessibleHyperlinkListener</code> interface.
+ * <p>
+ * Classes that wish to deal with <code>AccessibleHyperlink</code> events can
+ * extend this class and override only the methods that they are
+ * interested in.
+ * </p>
+ *
+ * @see AccessibleHyperlinkListener
+ * @see AccessibleHyperlinkEvent
+ *
+ * @since 3.6
+ */
+public class AccessibleHyperlinkAdapter implements AccessibleHyperlinkListener {
+	/**
+	 * Returns the anchor for the link at the specified index.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] index - a 0 based index identifying the anchor if this object
+	 * 		has more than one link, as in the case of an image map</li>
+	 * <li>[typical out] result - the returned anchor</li>
+	 * <li>[optional out] accessible - the returned anchor.
+	 * 		Note: The returned anchor can either be a string or an accessible.
+	 * 		For example, for a text link this could be the substring of the containing string
+	 * 		where the substring is overridden with link behavior, and for an image link this could be
+	 * 		the accessible for the image.</li>
+	 * </ul>
+	 */
+	public void getAnchor(AccessibleHyperlinkEvent e) {}
+
+	/**
+	 * Returns the target of the link at the specified index.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] index - a 0 based index identifying the anchor if this object
+	 * 		has more than one link, as in the case of an image map</li>
+	 * <li>[typical out] result - the returned target</li>
+	 * <li>[optional out] accessible - the returned target.
+	 * 		Note: The returned target can either be a string or an accessible.
+	 * 		For example, this could be a string URI, or the accessible for the target
+	 * 		object to be activated when the link is activated.</li>
+	 * </ul>
+	 */
+	public void getAnchorTarget(AccessibleHyperlinkEvent e) {}
+
+	/**
+	 * Returns the 0 based character offset at which the textual representation of the hyperlink starts.
+	 * <p>
+	 * The returned value is related to the AccessibleTextExtended interface of the object that
+	 * owns this hyperlink.
+	 * </p>
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] index</li>
+	 * </ul>
+	 */
+	public void getStartIndex(AccessibleHyperlinkEvent e) {}
+
+	/**
+	 * Returns the 0 based character offset at which the textual representation of the hyperlink ends.
+	 * <p>
+	 * The returned value is related to the AccessibleTextExtended interface of the object that
+	 * owns this hyperlink. The character at the index is not part of the hypertext.
+	 * </p>
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] index</li>
+	 * </ul>
+	 */
+	public void getEndIndex(AccessibleHyperlinkEvent e) {}
+}
diff --git a/org/eclipse/swt/accessibility/AccessibleHyperlinkEvent.java b/org/eclipse/swt/accessibility/AccessibleHyperlinkEvent.java
new file mode 100644
index 0000000..79df0ef
--- /dev/null
+++ b/org/eclipse/swt/accessibility/AccessibleHyperlinkEvent.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.accessibility;
+
+import org.eclipse.swt.internal.*;
+
+/**
+ * Instances of this class are sent as a result of accessibility clients
+ * sending AccessibleHyperlink messages to an accessible object.
+ *
+ * @see AccessibleHyperlinkListener
+ * @see AccessibleHyperlinkAdapter
+ *
+ * @since 3.6
+ */
+public class AccessibleHyperlinkEvent extends SWTEventObject {
+
+	public Accessible accessible;
+
+	/**
+	 * The value of this field must be set in the accessible hyperlink listener method
+	 * before returning. What to set it to depends on the listener method called.
+	 */
+	public String result;
+
+	public int index;
+
+	static final long serialVersionUID = 6253098373844074544L;
+
+/**
+ * Constructs a new instance of this class.
+ *
+ * @param source the object that fired the event
+ */
+public AccessibleHyperlinkEvent(Object source) {
+	super(source);
+}
+
+/**
+ * Returns a string containing a concise, human-readable
+ * description of the receiver.
+ *
+ * @return a string representation of the event
+ */
+public String toString () {
+	return "AccessibleHyperlinkEvent {"
+		+ "accessible=" + accessible   //$NON-NLS-1$
+		+ " string=" + result   //$NON-NLS-1$
+		+ " index=" + index   //$NON-NLS-1$
+		+ "}";  //$NON-NLS-1$
+}
+}
diff --git a/org/eclipse/swt/accessibility/AccessibleHyperlinkListener.java b/org/eclipse/swt/accessibility/AccessibleHyperlinkListener.java
new file mode 100644
index 0000000..34a48fb
--- /dev/null
+++ b/org/eclipse/swt/accessibility/AccessibleHyperlinkListener.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.accessibility;
+
+import org.eclipse.swt.internal.SWTEventListener;
+
+/**
+ * Classes which implement this interface provide methods
+ * that handle AccessibleHyperlink events.
+ * <p>
+ * After creating an instance of a class that implements
+ * this interface it can be added to an accessible using the
+ * <code>addAccessibleHyperlinkListener</code> method and removed using
+ * the <code>removeAccessibleHyperlinkListener</code> method.
+ * </p>
+ *
+ * @see AccessibleHyperlinkAdapter
+ * @see AccessibleHyperlinkEvent
+ *
+ * @since 3.6
+ */
+public interface AccessibleHyperlinkListener extends SWTEventListener {
+	/**
+	 * Returns the anchor for the link at the specified index.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] index - a 0 based index identifying the anchor if this object
+	 * 		has more than one link, as in the case of an image map</li>
+	 * <li>[typical out] result - the returned anchor</li>
+	 * <li>[optional out] accessible - the returned anchor.
+	 * 		Note: The returned anchor can either be a string or an accessible.
+	 * 		For example, for a text link this could be the substring of the containing string
+	 * 		where the substring is overridden with link behavior, and for an image link this could be
+	 * 		the accessible for the image.</li>
+	 * </ul>
+	 */
+	public void getAnchor(AccessibleHyperlinkEvent e);
+
+	/**
+	 * Returns the target of the link at the specified index.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] index - a 0 based index identifying the anchor if this object
+	 * 		has more than one link, as in the case of an image map</li>
+	 * <li>[typical out] result - the returned target</li>
+	 * <li>[optional out] accessible - the returned target.
+	 * 		Note: The returned target can either be a string or an accessible.
+	 * 		For example, this could be a string URI, or the accessible for the target
+	 * 		object to be activated when the link is activated.</li>
+	 * </ul>
+	 */
+	public void getAnchorTarget(AccessibleHyperlinkEvent e);
+
+	/**
+	 * Returns the 0 based character offset at which the textual representation of the hyperlink starts.
+	 * <p>
+	 * The returned value is related to the AccessibleTextExtended interface of the object that
+	 * owns this hyperlink.
+	 * </p>
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] index</li>
+	 * </ul>
+	 */
+	public void getStartIndex(AccessibleHyperlinkEvent e);
+
+	/**
+	 * Returns the 0 based character offset at which the textual representation of the hyperlink ends.
+	 * <p>
+	 * The returned value is related to the AccessibleTextExtended interface of the object that
+	 * owns this hyperlink. The character at the index is not part of the hypertext.
+	 * </p>
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] index</li>
+	 * </ul>
+	 */
+	public void getEndIndex(AccessibleHyperlinkEvent e);
+}
diff --git a/org/eclipse/swt/accessibility/AccessibleObject.java b/org/eclipse/swt/accessibility/AccessibleObject.java
index 00b05d5..07ef376 100644
--- a/org/eclipse/swt/accessibility/AccessibleObject.java
+++ b/org/eclipse/swt/accessibility/AccessibleObject.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -12,18 +12,20 @@ package org.eclipse.swt.accessibility;
 
 
 import java.util.*;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.swt.graphics.*;
 import org.eclipse.swt.internal.*;
 import org.eclipse.swt.internal.accessibility.gtk.*;
 import org.eclipse.swt.internal.gtk.*;
-import org.eclipse.swt.widgets.*;
 
 class AccessibleObject {
 	int /*long*/ handle;
-	int /*long*/ parentType;
 	int index = -1, id = ACC.CHILDID_SELF;
 	Accessible accessible;
 	AccessibleObject parent;
-	Hashtable children = new Hashtable (9);
+	AccessibleObject[] children;
 	/*
 	* a lightweight object does not correspond to a concrete gtk widget, but
 	* to a logical child of a widget (eg.- a CTabItem, which is simply drawn)
@@ -35,1231 +37,3094 @@ class AccessibleObject {
 	static int /*long*/ keybindingPtr = -1;
 	static int /*long*/ namePtr = -1;
 	static final Hashtable AccessibleObjects = new Hashtable (9);
-	static final int /*long*/ ATK_ACTION_TYPE = ATK.g_type_from_name (Converter.wcsToMbcs (null, "AtkAction", true));
-	static final int /*long*/ ATK_COMPONENT_TYPE = ATK.g_type_from_name (Converter.wcsToMbcs (null, "AtkComponent", true));
-	static final int /*long*/ ATK_HYPERTEXT_TYPE = ATK.g_type_from_name (Converter.wcsToMbcs (null, "AtkHypertext", true));
-	static final int /*long*/ ATK_SELECTION_TYPE = ATK.g_type_from_name (Converter.wcsToMbcs (null, "AtkSelection", true));		
-	static final int /*long*/ ATK_TEXT_TYPE = ATK.g_type_from_name (Converter.wcsToMbcs (null, "AtkText", true));
-	static final boolean DEBUG = Display.DEBUG;
-
-	AccessibleObject (int /*long*/ type, int /*long*/ widget, Accessible accessible, int /*long*/ parentType, boolean isLightweight) {
+	static final boolean DEBUG = Device.DEBUG;
+	
+	static final int ROW_ROLE, COLUMN_ROLE;
+	static {
+		ROW_ROLE = ATK.atk_role_register(Converter.wcsToMbcs(null, "row", true)); //$NON-NLS-1$
+		COLUMN_ROLE = ATK.atk_role_register(Converter.wcsToMbcs(null, "column", true)); //$NON-NLS-1$
+	}
+
+	AccessibleObject (int /*long*/ type, int /*long*/ widget, Accessible accessible, boolean isLightweight) {
 		super ();
 		handle = ATK.g_object_new (type, 0);
-		this.parentType = parentType;
 		ATK.atk_object_initialize (handle, widget);
 		this.accessible = accessible;
 		this.isLightweight = isLightweight;
 		AccessibleObjects.put (new LONG (handle), this);
-		if (DEBUG) System.out.println("new AccessibleObject: " + handle);
+		if (DEBUG) print("new AccessibleObject: " + handle + " control=" + accessible.control + " lw=" + isLightweight);
+	}
+	
+	static void print (String str) {
+		System.out.println (str);
+	}
+	
+	static AtkActionIface getActionIface (int /*long*/ atkObject) {
+		if (ATK.g_type_is_a (OS.g_type_parent (OS.G_OBJECT_TYPE (atkObject)), ATK.ATK_TYPE_ACTION())) {
+			AtkActionIface iface = new AtkActionIface ();
+			ATK.memmove (iface, ATK.g_type_interface_peek_parent (ATK.ATK_ACTION_GET_IFACE (atkObject)));
+			return iface;
+		}
+		return null;
+	}
+	
+	static int /*long*/ atkAction_do_action (int /*long*/ atkObject, int /*long*/ index) {
+		if (DEBUG) print ("-->atkAction_do_action");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleActionListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleActionEvent event = new AccessibleActionEvent(accessible);
+				event.index = (int)/*64*/index;
+				for (int i = 0; i < length; i++) {
+					AccessibleActionListener listener = (AccessibleActionListener) listeners.elementAt(i);
+					listener.doAction(event);
+				}
+				return ACC.OK.equals(event.result) ? 1 : 0;
+			}
+		}
+		int /*long*/ parentResult = 0;
+		AtkActionIface iface = getActionIface (atkObject);
+		if (iface != null && iface.do_action != 0) {
+			parentResult = ATK.call (iface.do_action, atkObject, index);
+		}
+		return parentResult; 	
 	}
 
-	void addChild (AccessibleObject child) {
-		children.put (new LONG (child.handle), child);		
-		child.setParent (this);
+	static int /*long*/ atkAction_get_n_actions (int /*long*/ atkObject) {
+		if (DEBUG) print ("-->atkAction_get_n_actions");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleActionListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleActionEvent event = new AccessibleActionEvent(accessible);
+				for (int i = 0; i < length; i++) {
+					AccessibleActionListener listener = (AccessibleActionListener) listeners.elementAt(i);
+					listener.getActionCount(event);
+				}
+				return event.count;
+			}
+		}
+		int /*long*/ parentResult = 0;
+		AtkActionIface iface = getActionIface (atkObject);
+		if (iface != null && iface.get_n_actions != 0) {
+			parentResult = ATK.call (iface.get_n_actions, atkObject);
+		}
+		return parentResult; 	
+	}
+	
+	static int /*long*/ atkAction_get_description (int /*long*/ atkObject, int /*long*/ index) {
+		if (DEBUG) print ("-->atkAction_get_description");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleActionListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleActionEvent event = new AccessibleActionEvent(accessible);
+				event.index = (int)/*64*/index;
+				for (int i = 0; i < length; i++) {
+					AccessibleActionListener listener = (AccessibleActionListener) listeners.elementAt(i);
+					listener.getDescription(event);
+				}
+				if (event.result == null) return 0;
+				if (descriptionPtr != -1) OS.g_free (descriptionPtr);
+				return descriptionPtr = getStringPtr (event.result);
+			}
+		}
+		int /*long*/ parentResult = 0;
+		AtkActionIface iface = getActionIface (atkObject);
+		if (iface != null && iface.get_description != 0) {
+			parentResult = ATK.call (iface.get_description, atkObject, index);
+		}
+		return parentResult; 	
 	}
 	
 	static int /*long*/ atkAction_get_keybinding (int /*long*/ atkObject, int /*long*/ index) {
-		if (DEBUG) System.out.println ("-->atkAction_get_keybinding");
+		if (DEBUG) print ("-->atkAction_get_keybinding");
 		AccessibleObject object = getAccessibleObject (atkObject);
-		if (object == null) return 0;
 		int /*long*/ parentResult = 0;
-		if (ATK.g_type_is_a (object.parentType, ATK_ACTION_TYPE)) {
-			int /*long*/ superType = ATK.g_type_interface_peek_parent (ATK.ATK_ACTION_GET_IFACE (object.handle));
-			AtkActionIface actionIface = new AtkActionIface ();
-			ATK.memmove (actionIface, superType);
-			if (actionIface.get_keybinding != 0) {
-				parentResult = ATK.call (actionIface.get_keybinding, object.handle, index);
-			}
-		}
-		AccessibleListener[] listeners = object.getAccessibleListeners ();
-		if (listeners.length == 0) return parentResult;
-
-		AccessibleEvent event = new AccessibleEvent (object.accessible);
-		event.childID = object.id;
-		if (parentResult != 0) {
-			int length = OS.strlen (parentResult);
-			byte [] buffer = new byte [length];
-			OS.memmove (buffer, parentResult, length);
-			event.result = new String (Converter.mbcsToWcs (null, buffer));
-		}
-		for (int i = 0; i < listeners.length; i++) {
-			listeners [i].getKeyboardShortcut (event);	
-		} 
-		if (event.result == null) return parentResult;
-		if (keybindingPtr != -1) OS.g_free (keybindingPtr);
-		byte[] name = Converter.wcsToMbcs (null, event.result, true);
-		keybindingPtr = OS.g_malloc (name.length);
-		OS.memmove (keybindingPtr, name, name.length);
-		return keybindingPtr; 	
+		AtkActionIface iface = getActionIface (atkObject);
+		if (iface != null && iface.get_keybinding != 0) {
+			parentResult = ATK.call (iface.get_keybinding, atkObject, index);
+		}
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleActionListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleActionEvent event = new AccessibleActionEvent(accessible);
+				event.index = (int)/*64*/index;
+				for (int i = 0; i < length; i++) {
+					AccessibleActionListener listener = (AccessibleActionListener) listeners.elementAt(i);
+					listener.getKeyBinding(event);
+				}
+				if (event.result != null) {
+					if (keybindingPtr != -1) OS.g_free (keybindingPtr);
+					return keybindingPtr = getStringPtr (event.result); 
+				}
+			}
+			listeners = accessible.accessibleListeners;
+			length = listeners.size();
+			if (length > 0) {
+				AccessibleEvent event = new AccessibleEvent (accessible);
+				event.childID = object.id;
+				if (parentResult != 0) event.result = getString (parentResult);
+				for (int i = 0; i < length; i++) {
+					AccessibleListener listener = (AccessibleListener) listeners.elementAt(i);
+					listener.getKeyboardShortcut (event);				
+				} 
+				if (event.result != null) {
+					if (keybindingPtr != -1) OS.g_free (keybindingPtr);
+					return keybindingPtr = getStringPtr (event.result); 
+				}
+			}
+		}
+		return parentResult;
 	}
 
 	static int /*long*/ atkAction_get_name (int /*long*/ atkObject, int /*long*/ index) {
-		if (DEBUG) System.out.println ("-->atkAction_get_name");
+		if (DEBUG) print ("-->atkAction_get_name");
 		AccessibleObject object = getAccessibleObject (atkObject);
-		if (object == null) return 0;
 		int /*long*/ parentResult = 0;
-		if (ATK.g_type_is_a (object.parentType, ATK_ACTION_TYPE)) {
-			int /*long*/ superType = ATK.g_type_interface_peek_parent (ATK.ATK_ACTION_GET_IFACE (object.handle));
-			AtkActionIface actionIface = new AtkActionIface ();
-			ATK.memmove (actionIface, superType);
-			if (actionIface.get_name != 0) {
-				parentResult = ATK.call (actionIface.get_name, object.handle, index);
-			}
-		}
-		AccessibleControlListener[] listeners = object.getControlListeners ();
-		if (listeners.length == 0) return parentResult;
-
-		AccessibleControlEvent event = new AccessibleControlEvent (object.accessible);
-		event.childID = object.id;
-		if (parentResult != 0) {
-			int length = OS.strlen (parentResult);
-			byte [] buffer = new byte [length];
-			OS.memmove (buffer, parentResult, length);
-			event.result = new String (Converter.mbcsToWcs (null, buffer));
-		}
-		for (int i = 0; i < listeners.length; i++) {
-			listeners [i].getDefaultAction (event);				
-		} 
-		if (event.result == null) return parentResult;
-		if (actionNamePtr != -1) OS.g_free (actionNamePtr);
-		byte[] name = Converter.wcsToMbcs (null, event.result, true);
-		actionNamePtr = OS.g_malloc (name.length);
-		OS.memmove (actionNamePtr, name, name.length);
-		return actionNamePtr;
-	}	
+		AtkActionIface iface = getActionIface (atkObject);
+		if (iface != null && iface.get_name != 0) {
+			parentResult = ATK.call (iface.get_name, atkObject, index);
+		}
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleActionListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleActionEvent event = new AccessibleActionEvent(accessible);
+				event.index = (int)/*64*/index;
+				for (int i = 0; i < length; i++) {
+					AccessibleActionListener listener = (AccessibleActionListener) listeners.elementAt(i);
+					listener.getName(event);
+				}
+				if (event.result != null) {
+					if (actionNamePtr != -1) OS.g_free (actionNamePtr);
+					return actionNamePtr = getStringPtr (event.result);
+				}
+			}
+			if (index == 0) {
+				listeners = accessible.accessibleControlListeners;
+				length = listeners.size();
+				if (length > 0) {
+					AccessibleControlEvent event = new AccessibleControlEvent (accessible);
+					event.childID = object.id;
+					if (parentResult != 0) event.result = getString (parentResult);
+					for (int i = 0; i < length; i++) {
+						AccessibleControlListener listener = (AccessibleControlListener) listeners.elementAt(i);
+						listener.getDefaultAction (event);				
+					} 
+					if (event.result != null) {
+						if (actionNamePtr != -1) OS.g_free (actionNamePtr);
+						return actionNamePtr = getStringPtr (event.result);
+					}
+				}
+			}
+		}
+		return parentResult;
+	}
+	
+	static AtkComponentIface getComponentIface (int /*long*/ atkObject) {
+		if (ATK.g_type_is_a (OS.g_type_parent (OS.G_OBJECT_TYPE (atkObject)), ATK.ATK_TYPE_COMPONENT())) {
+			AtkComponentIface iface = new AtkComponentIface ();
+			ATK.memmove (iface, ATK.g_type_interface_peek_parent (ATK.ATK_COMPONENT_GET_IFACE (atkObject)));
+			return iface;
+		}
+		return null;
+	}
 
 	static int /*long*/ atkComponent_get_extents (int /*long*/ atkObject, int /*long*/ x, int /*long*/ y, int /*long*/ width, int /*long*/ height, int /*long*/ coord_type) {
-		if (DEBUG) System.out.println ("-->atkComponent_get_extents");
+		if (DEBUG) print ("-->atkComponent_get_extents: " + atkObject);
 		AccessibleObject object = getAccessibleObject (atkObject);
-		if (object == null) return 0;
 		OS.memmove (x, new int[] {0}, 4);
 		OS.memmove (y, new int[] {0}, 4);
 		OS.memmove (width, new int[] {0}, 4);
 		OS.memmove (height, new int[] {0}, 4);
-		if (ATK.g_type_is_a (object.parentType, ATK_COMPONENT_TYPE)) {
-			int /*long*/ superType = ATK.g_type_interface_peek_parent (ATK.ATK_COMPONENT_GET_IFACE (object.handle));
-			AtkComponentIface componentIface = new AtkComponentIface ();
-			ATK.memmove (componentIface, superType);
-			if (componentIface.get_extents != 0) {
-				ATK.call (componentIface.get_extents, object.handle, x, y, width, height, coord_type);
-			}
-		}
-		AccessibleControlListener[] listeners = object.getControlListeners ();
-		if (listeners.length == 0) return 0;
-		
-		int[] parentX = new int [1], parentY = new int [1];
-		int[] parentWidth = new int [1], parentHeight = new int [1];
-		OS.memmove (parentX, x, 4);
-		OS.memmove (parentY, y, 4);
-		OS.memmove (parentWidth, width, 4);
-		OS.memmove (parentHeight, height, 4);
-		AccessibleControlEvent event = new AccessibleControlEvent (object.accessible);
-		event.childID = object.id;
-		event.x = parentX [0]; event.y = parentY [0];
-		event.width = parentWidth [0]; event.height = parentHeight [0];
-		if (coord_type == ATK.ATK_XY_WINDOW) {
-			/* translate control -> display, for filling in event to be dispatched */
-			int /*long*/ gtkAccessibleHandle = ATK.GTK_ACCESSIBLE (object.handle);
-			GtkAccessible gtkAccessible = new GtkAccessible ();
-			ATK.memmove (gtkAccessible, gtkAccessibleHandle);
-			int /*long*/ topLevel = ATK.gtk_widget_get_toplevel (gtkAccessible.widget);
-			int /*long*/ window = OS.GTK_WIDGET_WINDOW (topLevel);				
-			int[] topWindowX = new int [1], topWindowY = new int [1];
-			OS.gdk_window_get_origin (window, topWindowX, topWindowY);
-			event.x += topWindowX [0];
-			event.y += topWindowY [0]; 
-		}
-		for (int i = 0; i < listeners.length; i++) {
-			listeners [i].getLocation (event);
-		}
-		if (coord_type == ATK.ATK_XY_WINDOW) {
-			/* translate display -> control, for answering to the OS */ 
-			int /*long*/ gtkAccessibleHandle = ATK.GTK_ACCESSIBLE (object.handle);
-			GtkAccessible gtkAccessible = new GtkAccessible ();
-			ATK.memmove (gtkAccessible, gtkAccessibleHandle);
-			int /*long*/ topLevel = ATK.gtk_widget_get_toplevel (gtkAccessible.widget);
-			int /*long*/ window = OS.GTK_WIDGET_WINDOW (topLevel);
-			int[] topWindowX = new int [1], topWindowY = new int [1];
-			OS.gdk_window_get_origin (window, topWindowX, topWindowY);
-			event.x -= topWindowX [0];
-			event.y -= topWindowY [0];
-		}
-		OS.memmove (x, new int[] {event.x}, 4);
-		OS.memmove (y, new int[] {event.y}, 4);
-		OS.memmove (width, new int[] {event.width}, 4);
-		OS.memmove (height, new int[] {event.height}, 4);
+		AtkComponentIface iface = getComponentIface (atkObject);
+		if (iface != null && iface.get_extents != 0) {
+			ATK.call (iface.get_extents, atkObject, x, y, width, height, coord_type);
+		}
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleControlListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				int[] parentX = new int [1], parentY = new int [1];
+				int[] parentWidth = new int [1], parentHeight = new int [1];
+				OS.memmove (parentX, x, 4);
+				OS.memmove (parentY, y, 4);
+				OS.memmove (parentWidth, width, 4);
+				OS.memmove (parentHeight, height, 4);
+				AccessibleControlEvent event = new AccessibleControlEvent (accessible);
+				event.childID = object.id;
+				event.x = parentX [0]; event.y = parentY [0];
+				event.width = parentWidth [0]; event.height = parentHeight [0];
+				int[] topWindowX = new int [1], topWindowY = new int [1];
+				if (coord_type == ATK.ATK_XY_WINDOW) {
+					windowPoint (object, topWindowX, topWindowY);
+					event.x += topWindowX [0];
+					event.y += topWindowY [0]; 
+				}
+				for (int i = 0; i < length; i++) {
+					AccessibleControlListener listener = (AccessibleControlListener)listeners.elementAt (i);
+					listener.getLocation (event);
+				}
+				if (coord_type == ATK.ATK_XY_WINDOW) {
+					event.x -= topWindowX [0];
+					event.y -= topWindowY [0];
+				}
+				OS.memmove (x, new int[] {event.x}, 4);
+				OS.memmove (y, new int[] {event.y}, 4);
+				OS.memmove (width, new int[] {event.width}, 4);
+				OS.memmove (height, new int[] {event.height}, 4);
+				if (DEBUG) print("--->" + event.x + "," + event.y + "," + event.width + "x" + event.height);
+			}
+		}
 		return 0;
 	}
 
 	static int /*long*/ atkComponent_get_position (int /*long*/ atkObject, int /*long*/ x, int /*long*/ y, int /*long*/ coord_type) {
-		if (DEBUG) System.out.println ("-->atkComponent_get_position, object: " + atkObject + " x: " + x + " y: " + y + " coord: " + coord_type);
+		if (DEBUG) print ("-->atkComponent_get_position, object: " + atkObject + " x: " + x + " y: " + y + " coord: " + coord_type);
 		AccessibleObject object = getAccessibleObject (atkObject);
-		if (object == null) return 0;
 		OS.memmove (x, new int[] {0}, 4);
 		OS.memmove (y, new int[] {0}, 4);
-		if (ATK.g_type_is_a (object.parentType, ATK_COMPONENT_TYPE)) {
-			int /*long*/ superType = ATK.g_type_interface_peek_parent (ATK.ATK_COMPONENT_GET_IFACE (object.handle));
-			AtkComponentIface componentIface = new AtkComponentIface ();
-			ATK.memmove (componentIface, superType);
-			if (componentIface.get_extents != 0) {
-				ATK.call (componentIface.get_position, object.handle, x, y, coord_type);
-			}
-		}
-		AccessibleControlListener[] listeners = object.getControlListeners ();
-		if (listeners.length == 0) return 0;
-		
-		int[] parentX = new int [1], parentY = new int [1];
-		OS.memmove (parentX, x, 4);
-		OS.memmove (parentY, y, 4);
-		AccessibleControlEvent event = new AccessibleControlEvent (object.accessible);
-		event.childID = object.id;
-		event.x = parentX [0]; event.y = parentY [0];
-		if (coord_type == ATK.ATK_XY_WINDOW) {
-			/* translate control -> display, for filling in event to be dispatched */
-			int /*long*/ gtkAccessibleHandle = ATK.GTK_ACCESSIBLE (object.handle);
-			GtkAccessible gtkAccessible = new GtkAccessible ();
-			ATK.memmove (gtkAccessible, gtkAccessibleHandle);
-			int /*long*/ topLevel = ATK.gtk_widget_get_toplevel (gtkAccessible.widget);
-			int /*long*/ window = OS.GTK_WIDGET_WINDOW (topLevel);				
-			int[] topWindowX = new int [1], topWindowY = new int [1];
-			OS.gdk_window_get_origin (window, topWindowX, topWindowY);
-			event.x += topWindowX [0];
-			event.y += topWindowY [0]; 
-		}
-		for (int i = 0; i < listeners.length; i++) {
-			listeners [i].getLocation (event);
-		}
-		if (coord_type == ATK.ATK_XY_WINDOW) {
-			/* translate display -> control, for answering to the OS */ 
-			int /*long*/ gtkAccessibleHandle = ATK.GTK_ACCESSIBLE (object.handle);
-			GtkAccessible gtkAccessible = new GtkAccessible ();
-			ATK.memmove (gtkAccessible, gtkAccessibleHandle);
-			int /*long*/ topLevel = ATK.gtk_widget_get_toplevel (gtkAccessible.widget);
-			int /*long*/ window = OS.GTK_WIDGET_WINDOW (topLevel);
-			int[] topWindowX = new int [1], topWindowY = new int [1];
-			OS.gdk_window_get_origin (window, topWindowX, topWindowY);
-			event.x -= topWindowX [0];
-			event.y -= topWindowY [0];
-		}
-		OS.memmove (x, new int[] {event.x}, 4);
-		OS.memmove (y, new int[] {event.y}, 4);
+		AtkComponentIface iface = getComponentIface (atkObject);
+		if (iface != null && iface.get_position != 0) {
+			ATK.call (iface.get_position, atkObject, x, y, coord_type);
+		}
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleControlListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				int[] parentX = new int [1], parentY = new int [1];
+				OS.memmove (parentX, x, 4);
+				OS.memmove (parentY, y, 4);
+				AccessibleControlEvent event = new AccessibleControlEvent (accessible);
+				event.childID = object.id;
+				event.x = parentX [0]; event.y = parentY [0];
+				int[] topWindowX = new int [1], topWindowY = new int [1];
+				if (coord_type == ATK.ATK_XY_WINDOW) {
+					windowPoint (object, topWindowX, topWindowY);
+					event.x += topWindowX [0];
+					event.y += topWindowY [0]; 
+				}
+				for (int i = 0; i < length; i++) {
+					AccessibleControlListener listener = (AccessibleControlListener)listeners.elementAt (i);
+					listener.getLocation (event);
+				}
+				if (coord_type == ATK.ATK_XY_WINDOW) {
+					event.x -= topWindowX [0];
+					event.y -= topWindowY [0];
+				}
+				OS.memmove (x, new int[] {event.x}, 4);
+				OS.memmove (y, new int[] {event.y}, 4);
+			}
+		}
 		return 0;
 	}
 
 	static int /*long*/ atkComponent_get_size (int /*long*/ atkObject, int /*long*/ width, int /*long*/ height, int /*long*/ coord_type) {
-		if (DEBUG) System.out.println ("-->atkComponent_get_size");
+		if (DEBUG) print ("-->atkComponent_get_size");
 		AccessibleObject object = getAccessibleObject (atkObject);
-		if (object == null) return 0;
 		OS.memmove (width, new int[] {0}, 4);
 		OS.memmove (height, new int[] {0}, 4);
-		if (ATK.g_type_is_a (object.parentType, ATK_COMPONENT_TYPE)) {
-			int /*long*/ superType = ATK.g_type_interface_peek_parent (ATK.ATK_COMPONENT_GET_IFACE (object.handle));
-			AtkComponentIface componentIface = new AtkComponentIface ();
-			ATK.memmove (componentIface, superType);
-			if (componentIface.get_extents != 0) {
-				ATK.call (componentIface.get_size, object.handle, width, height, coord_type);
-			}
-		}
-		AccessibleControlListener[] listeners = object.getControlListeners ();
-		if (listeners.length == 0) return 0;
-		
-		int[] parentWidth = new int [1], parentHeight = new int [1];
-		OS.memmove (parentWidth, width, 4);
-		OS.memmove (parentHeight, height, 4);
-		AccessibleControlEvent event = new AccessibleControlEvent (object.accessible);
-		event.childID = object.id;
-		event.width = parentWidth [0]; event.height = parentHeight [0];
-		for (int i = 0; i < listeners.length; i++) {
-			listeners [i].getLocation (event);
-		}
-		OS.memmove (width, new int[] {event.width}, 4);
-		OS.memmove (height, new int[] {event.height}, 4);
+		AtkComponentIface iface = getComponentIface (atkObject);
+		if (iface != null && iface.get_size != 0) {
+			ATK.call (iface.get_size, atkObject, width, height, coord_type);
+		}
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleControlListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				int[] parentWidth = new int [1], parentHeight = new int [1];
+				OS.memmove (parentWidth, width, 4);
+				OS.memmove (parentHeight, height, 4);
+				AccessibleControlEvent event = new AccessibleControlEvent (accessible);
+				event.childID = object.id;
+				event.width = parentWidth [0]; event.height = parentHeight [0];
+				for (int i = 0; i < length; i++) {
+					AccessibleControlListener listener = (AccessibleControlListener)listeners.elementAt (i);
+					listener.getLocation (event);
+				}
+				OS.memmove (width, new int[] {event.width}, 4);
+				OS.memmove (height, new int[] {event.height}, 4);
+			}
+		}
 		return 0;
 	}
 
 	static int /*long*/ atkComponent_ref_accessible_at_point (int /*long*/ atkObject, int /*long*/ x, int /*long*/ y, int /*long*/ coord_type) {
-		if (DEBUG) System.out.println ("-->atkComponent_ref_accessible_at_point");
+		if (DEBUG) print ("-->atkComponent_ref_accessible_at_point: " + atkObject + " " + x + "," + y);
 		AccessibleObject object = getAccessibleObject (atkObject);
-		if (object == null) return 0;
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleControlListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleControlEvent event = new AccessibleControlEvent (accessible);
+				event.childID = object.id;
+				event.x = (int)/*64*/x; event.y = (int)/*64*/y;
+				int[] topWindowX = new int [1], topWindowY = new int [1];
+				if (coord_type == ATK.ATK_XY_WINDOW) {
+					windowPoint (object, topWindowX, topWindowY);
+					event.x += topWindowX [0];
+					event.y += topWindowY [0]; 
+				}
+				for (int i = 0; i < length; i++) {
+					AccessibleControlListener listener = (AccessibleControlListener)listeners.elementAt (i);
+					listener.getChildAtPoint (event);				
+				}
+				if (event.childID == object.id) event.childID = ACC.CHILDID_SELF;
+				Accessible result = event.accessible;
+				AccessibleObject accObj = result != null ? result.getAccessibleObject() : object.getChildByID (event.childID);
+				if (accObj != null) {
+					return OS.g_object_ref (accObj.handle);	
+				}
+			}
+		}
 		int /*long*/ parentResult = 0;
-		if (ATK.g_type_is_a (object.parentType, ATK_COMPONENT_TYPE)) {
-			int /*long*/ superType = ATK.g_type_interface_peek_parent (ATK.ATK_COMPONENT_GET_IFACE (object.handle));
-			AtkComponentIface componentIface = new AtkComponentIface ();
-			ATK.memmove (componentIface, superType);
-			if (componentIface.ref_accessible_at_point != 0) {
-				parentResult = ATK.call (componentIface.ref_accessible_at_point, object.handle, x, y, coord_type);
-			}
-		}
-		AccessibleControlListener[] listeners = object.getControlListeners ();
-		if (listeners.length == 0) return parentResult;
-		
-		AccessibleControlEvent event = new AccessibleControlEvent (object.accessible);
-		event.childID = object.id;
-		event.x = (int)/*64*/x; event.y = (int)/*64*/y;
-		if (coord_type == ATK.ATK_XY_WINDOW) {
-			/* translate control -> display, for filling in the event to be dispatched */
-			int /*long*/ gtkAccessibleHandle = ATK.GTK_ACCESSIBLE (object.handle);
-			GtkAccessible gtkAccessible = new GtkAccessible ();
-			ATK.memmove (gtkAccessible, gtkAccessibleHandle);
-			int /*long*/ topLevel = ATK.gtk_widget_get_toplevel (gtkAccessible.widget);
-			int /*long*/ window = OS.GTK_WIDGET_WINDOW (topLevel);				
-			int[] topWindowX = new int [1], topWindowY = new int [1];
-			OS.gdk_window_get_origin (window, topWindowX, topWindowY);
-			event.x += topWindowX [0];
-			event.y += topWindowY [0]; 
-		}
-		for (int i = 0; i < listeners.length; i++) {
-			listeners [i].getChildAtPoint (event);				
-		}
-		if (event.childID == object.id) event.childID = ACC.CHILDID_SELF;
-		AccessibleObject accObj = object.getChildByID (event.childID);
-		if (accObj != null) {
-			if (parentResult > 0) OS.g_object_unref (parentResult);
-			OS.g_object_ref (accObj.handle);	
-			return accObj.handle;
+		AtkComponentIface iface = getComponentIface (atkObject);
+		if (iface != null && iface.ref_accessible_at_point != 0) {
+			parentResult = ATK.call (iface.ref_accessible_at_point, atkObject, x, y, coord_type);
 		}
 		return parentResult;
 	}	
 
+	static AtkHypertextIface getHypertextIface (int /*long*/ atkObject) {
+		if (ATK.g_type_is_a (OS.g_type_parent (OS.G_OBJECT_TYPE (atkObject)), ATK.ATK_TYPE_HYPERTEXT())) {
+			AtkHypertextIface iface = new AtkHypertextIface ();
+			ATK.memmove (iface, ATK.g_type_interface_peek_parent (ATK.ATK_HYPERTEXT_GET_IFACE (atkObject)));
+			return iface;
+		}
+		return null;
+	}
+	
 	static int /*long*/ atkHypertext_get_link (int /*long*/ atkObject, int /*long*/ link_index) {
-		if (DEBUG) System.out.println ("-->atkHypertext_get_link");
-		return 0;
+		if (DEBUG) print ("-->atkHypertext_get_link");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTextExtendedListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTextEvent event = new AccessibleTextEvent(accessible);
+				event.index = (int)/*int*/link_index;
+				for (int i = 0; i < length; i++) {
+					AccessibleTextExtendedListener listener = (AccessibleTextExtendedListener) listeners.elementAt(i);
+					listener.getHyperlink(event);
+				}
+				Accessible result = event.accessible;
+				return result != null ? result.getAccessibleObject().handle : 0;
+			}
+		}
+		int /*long*/ parentResult = 0;
+		AtkHypertextIface iface = getHypertextIface (atkObject);
+		if (iface != null && iface.get_link != 0) {
+			parentResult = ATK.call (iface.get_link, atkObject, link_index);
+		}
+		return parentResult;
 	}
 
 	static int /*long*/ atkHypertext_get_n_links (int /*long*/ atkObject) {
-		if (DEBUG) System.out.println ("-->atkHypertext_get_n_links");
-		return 0;	/* read hyperlink's name */
+		if (DEBUG) print ("-->atkHypertext_get_n_links");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTextExtendedListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTextEvent event = new AccessibleTextEvent(accessible);
+				for (int i = 0; i < length; i++) {
+					AccessibleTextExtendedListener listener = (AccessibleTextExtendedListener) listeners.elementAt(i);
+					listener.getHyperlinkCount(event);
+				}
+				return event.count;
+			}
+		}
+		int /*long*/ parentResult = 0;
+		AtkHypertextIface iface = getHypertextIface (atkObject);
+		if (iface != null && iface.get_n_links != 0) {
+			parentResult = ATK.call (iface.get_n_links, atkObject);
+		}
+		return parentResult;
 	}
 
 	static int /*long*/ atkHypertext_get_link_index (int /*long*/ atkObject, int /*long*/ char_index) {
-		if (DEBUG) System.out.println ("-->atkHypertext_get_link_index");
-		return 0;
+		if (DEBUG) print ("-->atkHypertext_get_link_index");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTextExtendedListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTextEvent event = new AccessibleTextEvent(accessible);
+				event.offset = (int)/*int*/char_index;
+				event.index = -1;
+				for (int i = 0; i < length; i++) {
+					AccessibleTextExtendedListener listener = (AccessibleTextExtendedListener) listeners.elementAt(i);
+					listener.getHyperlinkIndex(event);
+				}
+				return event.index;
+			}
+		}
+		int /*long*/ parentResult = 0;
+		AtkHypertextIface iface = getHypertextIface (atkObject);
+		if (iface != null && iface.get_link_index != 0) {
+			parentResult = ATK.call (iface.get_link_index, atkObject, char_index);
+		}
+		return parentResult;
+	}
+	
+	static AtkObjectClass getObjectClass (int /*long*/ atkObject) {
+		AtkObjectClass objectClass = new AtkObjectClass ();
+		ATK.memmove (objectClass, ATK.g_type_class_peek (OS.g_type_parent (OS.G_OBJECT_TYPE (atkObject))));
+		return objectClass;
 	}
 
 	static int /*long*/ atkObject_get_description (int /*long*/ atkObject) {
-		if (DEBUG) System.out.println ("-->atkObject_get_description");
+		if (DEBUG) print ("-->atkObject_get_description: " + atkObject);
 		AccessibleObject object = getAccessibleObject (atkObject);
-		if (object == null) return 0;
 		int /*long*/ parentResult = 0;
-		int /*long*/ superType = ATK.g_type_class_peek (object.parentType);
-		AtkObjectClass objectClass = new AtkObjectClass ();
-		ATK.memmove (objectClass, superType);
+		AtkObjectClass objectClass = getObjectClass (atkObject);
 		if (objectClass.get_description != 0) {
-			parentResult = ATK.call (objectClass.get_description, object.handle);
-		}
-		AccessibleListener[] listeners = object.getAccessibleListeners ();
-		if (listeners.length == 0) return parentResult;
-			
-		AccessibleEvent event = new AccessibleEvent (object.accessible);
-		event.childID = object.id;
-		if (parentResult != 0) {
-			int length = OS.strlen (parentResult);
-			byte [] buffer = new byte [length];
-			OS.memmove (buffer, parentResult, length);
-			event.result = new String (Converter.mbcsToWcs (null, buffer));
-		}
-		for (int i = 0; i < listeners.length; i++) {
-			listeners [i].getDescription (event);
-		} 
-		if (event.result == null) return parentResult;
-		if (descriptionPtr != -1) OS.g_free (descriptionPtr);
-		byte[] name = Converter.wcsToMbcs (null, event.result, true);
-		descriptionPtr = OS.g_malloc (name.length);
-		OS.memmove (descriptionPtr, name, name.length);
-		return descriptionPtr; 
+			parentResult = ATK.call (objectClass.get_description, atkObject);
+		}
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleEvent event = new AccessibleEvent (accessible);
+				event.childID = object.id;
+				if (parentResult != 0) event.result = getString (parentResult);
+				for (int i = 0; i < length; i++) {
+					AccessibleListener listener = (AccessibleListener)listeners.elementAt (i);
+					listener.getDescription (event);
+				}
+				if (DEBUG) print ("---> " + event.result);
+				if (event.result == null) return parentResult;
+				if (descriptionPtr != -1) OS.g_free (descriptionPtr);
+				return descriptionPtr = getStringPtr (event.result);
+			}
+		}
+		return parentResult;
+	}
+
+	static int /*long*/ atkObject_get_attributes (int /*long*/ atkObject) {
+		if (DEBUG) print ("-->atkObject_get_attributes: " + atkObject);
+		AccessibleObject object = getAccessibleObject (atkObject);
+		int /*long*/ parentResult = 0;
+		AtkObjectClass objectClass = getObjectClass (atkObject);
+		if (objectClass.get_attributes != 0) {
+			parentResult = ATK.call (objectClass.get_attributes, atkObject);
+		}
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleAttributeListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleAttributeEvent event = new AccessibleAttributeEvent (accessible);
+				event.topMargin = event.bottomMargin = event.leftMargin = event.rightMargin = event.alignment = event.indent = -1;
+				for (int i = 0; i < length; i++) {
+					AccessibleAttributeListener listener = (AccessibleAttributeListener)listeners.elementAt (i);
+					listener.getAttributes (event);
+				}
+				AtkAttribute attr = new AtkAttribute();
+				if (event.leftMargin != -1) {
+					int /*long*/ attrPtr = OS.g_malloc(AtkAttribute.sizeof);
+					attr.name = ATK.g_strdup (ATK.atk_text_attribute_get_name(ATK.ATK_TEXT_ATTR_LEFT_MARGIN));
+					attr.value = getStringPtr (String.valueOf(event.leftMargin));
+					ATK.memmove(attrPtr, attr, AtkAttribute.sizeof);
+					parentResult = OS.g_list_append(parentResult, attrPtr);
+				}
+				if (event.rightMargin != -1) {
+					int /*long*/ attrPtr = OS.g_malloc(AtkAttribute.sizeof);
+					attr.name = ATK.g_strdup (ATK.atk_text_attribute_get_name(ATK.ATK_TEXT_ATTR_RIGHT_MARGIN));
+					attr.value = getStringPtr (String.valueOf(event.rightMargin));
+					ATK.memmove(attrPtr, attr, AtkAttribute.sizeof);
+					parentResult = OS.g_list_append(parentResult, attrPtr);
+				}
+				if (event.topMargin != -1) {
+					int /*long*/ attrPtr = OS.g_malloc(AtkAttribute.sizeof);
+					attr.name = getStringPtr ("top-margin"); //$NON-NLS-1$
+					attr.value = getStringPtr (String.valueOf(event.topMargin));
+					ATK.memmove(attrPtr, attr, AtkAttribute.sizeof);
+					parentResult = OS.g_list_append(parentResult, attrPtr);
+				}
+				if (event.bottomMargin != -1) {
+					int /*long*/ attrPtr = OS.g_malloc(AtkAttribute.sizeof);
+					attr.name = getStringPtr ("bottom-margin"); //$NON-NLS-1$
+					attr.value = getStringPtr (String.valueOf(event.bottomMargin));
+					ATK.memmove(attrPtr, attr, AtkAttribute.sizeof);
+					parentResult = OS.g_list_append(parentResult, attrPtr);
+				}
+				if (event.indent != -1) {
+					int /*long*/ attrPtr = OS.g_malloc(AtkAttribute.sizeof);
+					attr.name = ATK.g_strdup (ATK.atk_text_attribute_get_name(ATK.ATK_TEXT_ATTR_INDENT));
+					attr.value = getStringPtr (String.valueOf(event.indent));
+					ATK.memmove(attrPtr, attr, AtkAttribute.sizeof);
+					parentResult = OS.g_list_append(parentResult, attrPtr);
+				}
+				if (event.justify) {
+					int /*long*/ attrPtr = OS.g_malloc(AtkAttribute.sizeof);
+					attr.name = ATK.g_strdup (ATK.atk_text_attribute_get_name(ATK.ATK_TEXT_ATTR_JUSTIFICATION));
+					attr.value = getStringPtr ("fill"); //$NON-NLS-1$
+					ATK.memmove(attrPtr, attr, AtkAttribute.sizeof);
+					parentResult = OS.g_list_append(parentResult, attrPtr);
+				} else if (event.alignment != -1) {
+					int /*long*/ attrPtr = OS.g_malloc(AtkAttribute.sizeof);
+					attr.name = ATK.g_strdup (ATK.atk_text_attribute_get_name(ATK.ATK_TEXT_ATTR_JUSTIFICATION));
+					String str = "left"; //$NON-NLS-1$
+					switch (event.alignment) {
+						case SWT.LEFT: str = "left"; break; //$NON-NLS-1$
+						case SWT.RIGHT: str = "right"; break; //$NON-NLS-1$
+						case SWT.CENTER: str = "center"; break; //$NON-NLS-1$
+					}
+					attr.value = getStringPtr (str);
+					ATK.memmove(attrPtr, attr, AtkAttribute.sizeof);
+					parentResult = OS.g_list_append(parentResult, attrPtr);
+				}
+				//TODO - tabStops
+				if (event.attributes != null) {
+					int end = event.attributes.length / 2 * 2;
+					for (int i = 0; i < end; i+= 2) {
+						int /*long*/ attrPtr = OS.g_malloc(AtkAttribute.sizeof);
+						attr.name = getStringPtr (event.attributes[i]);
+						attr.value = getStringPtr (event.attributes[i + 1]);
+						ATK.memmove(attrPtr, attr, AtkAttribute.sizeof);
+						parentResult = OS.g_list_append(parentResult, attrPtr);
+					}
+				}
+			}
+		}
+		return parentResult;
 	}
 
 	static int /*long*/ atkObject_get_name (int /*long*/ atkObject) {
-		if (DEBUG) System.out.println ("-->atkObject_get_name: " + atkObject);
+		if (DEBUG) print ("-->atkObject_get_name: " + atkObject);
 		AccessibleObject object = getAccessibleObject (atkObject);
-		if (object == null) return 0;
 		int /*long*/ parentResult = 0;
-		int /*long*/ superType = ATK.g_type_class_peek (object.parentType);
-		AtkObjectClass objectClass = new AtkObjectClass ();
-		ATK.memmove (objectClass, superType);
+		AtkObjectClass objectClass = getObjectClass (atkObject);
 		if (objectClass.get_name != 0) {
-			parentResult = ATK.call (objectClass.get_name, object.handle);
-		}
-		AccessibleListener[] listeners = object.getAccessibleListeners ();
-		if (listeners.length == 0) return parentResult;
-		
-		AccessibleEvent event = new AccessibleEvent (object.accessible);
-		event.childID = object.id;
-		if (parentResult != 0) {
-			int length = OS.strlen (parentResult);
-			byte [] buffer = new byte [length];
-			OS.memmove (buffer, parentResult, length);
-			event.result = new String (Converter.mbcsToWcs (null, buffer));
-		}
-		for (int i = 0; i < listeners.length; i++) {
-			listeners [i].getName (event);				
-		} 
-		if (event.result == null) return parentResult;
-		if (namePtr != -1) OS.g_free (namePtr);
-		byte[] name = Converter.wcsToMbcs (null, event.result, true);
-		namePtr = OS.g_malloc (name.length);
-		OS.memmove (namePtr, name, name.length);
-		return namePtr; 
+			parentResult = ATK.call (objectClass.get_name, atkObject);
+		}
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleEvent event = new AccessibleEvent (accessible);
+				event.childID = object.id;
+				if (parentResult != 0) event.result = getString (parentResult);
+				for (int i = 0; i < length; i++) {
+					AccessibleListener listener = (AccessibleListener)listeners.elementAt (i);
+					listener.getName (event);				
+				}
+				if (DEBUG) print ("---> " + event.result);
+				if (event.result == null) return parentResult;
+				if (namePtr != -1) OS.g_free (namePtr);
+				return namePtr = getStringPtr (event.result);
+			}
+		}
+		return parentResult;
 	}	
 
 	static int /*long*/ atkObject_get_n_children (int /*long*/ atkObject) {
-		if (DEBUG) System.out.println ("-->atkObject_get_n_children: " + atkObject);
+		if (DEBUG) print ("-->atkObject_get_n_children: " + atkObject);
 		AccessibleObject object = getAccessibleObject (atkObject);
-		if (object == null) return 0;
 		int /*long*/ parentResult = 0;
-		int /*long*/ superType = ATK.g_type_class_peek (object.parentType);
-		AtkObjectClass objectClass = new AtkObjectClass ();
-		ATK.memmove (objectClass, superType);
+		AtkObjectClass objectClass = getObjectClass (atkObject);
 		if (objectClass.get_n_children != 0) { 
-			parentResult = ATK.call (objectClass.get_n_children, object.handle);
+			parentResult = ATK.call (objectClass.get_n_children, atkObject);
 		}
-		AccessibleControlListener[] listeners = object.getControlListeners ();
-		if (listeners.length == 0) return parentResult;
-			
-		AccessibleControlEvent event = new AccessibleControlEvent (object.accessible);
-		event.childID = object.id;
-		event.detail = (int)/*64*/parentResult;
-		for (int i = 0; i < listeners.length; i++) {
-			listeners [i].getChildCount (event);
-		} 
-		return event.detail;
+		if (object != null && object.id == ACC.CHILDID_SELF) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleControlListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleControlEvent event = new AccessibleControlEvent (accessible);
+				event.childID = object.id;
+				event.detail = (int)/*64*/parentResult;
+				for (int i = 0; i < length; i++) {
+					AccessibleControlListener listener = (AccessibleControlListener)listeners.elementAt (i);
+					listener.getChildCount (event);
+				}
+				if (DEBUG) print ("--->" + event.detail);
+				return event.detail;
+			}
+		}
+		return parentResult;
 	}
 
 	static int /*long*/ atkObject_get_index_in_parent (int /*long*/ atkObject) {
-		if (DEBUG) System.out.println ("-->atkObjectCB_get_index_in_parent.  ");
+		if (DEBUG) print ("-->atkObject_get_index_in_parent: " + atkObject);
 		AccessibleObject object = getAccessibleObject (atkObject);
-		if (object == null) return 0;
-		if (object.index != -1) return object.index;
-		int /*long*/ superType = ATK.g_type_class_peek (object.parentType);
-		AtkObjectClass objectClass = new AtkObjectClass ();
-		ATK.memmove (objectClass, superType);
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleControlListeners;
+			AccessibleControlEvent event = new AccessibleControlEvent(accessible);
+			event.childID = ACC.CHILDID_CHILD_INDEX;
+			event.detail = -1;
+			for (int i = 0; i < listeners.size(); i++) {
+				AccessibleControlListener listener = (AccessibleControlListener) listeners.elementAt(i);
+				listener.getChild(event);
+			}
+			if (event.detail != -1) {
+				if (DEBUG) print ("---> " + object.index);
+				return event.detail;
+			}
+			if (object.index != -1) {
+				if (DEBUG) print ("---> " + object.index);
+				return object.index;
+			}
+		}
+		AtkObjectClass objectClass = getObjectClass (atkObject);
 		if (objectClass.get_index_in_parent == 0) return 0;
-		return ATK.call (objectClass.get_index_in_parent,object. handle);
+		int /*long*/ result = ATK.call (objectClass.get_index_in_parent, atkObject);
+		if (DEBUG) print ("---*> " + result);
+		return result;
 	}
 
 	static int /*long*/ atkObject_get_parent (int /*long*/ atkObject) {
-		if (DEBUG) System.out.println ("-->atkObject_get_parent: " + atkObject);
+		if (DEBUG) print ("-->atkObject_get_parent: " + atkObject);
 		AccessibleObject object = getAccessibleObject (atkObject);
-		if (object == null) return 0;
-		if (object.parent != null) return object.parent.handle;
-		int /*long*/ superType = ATK.g_type_class_peek (object.parentType);
-		AtkObjectClass objectClass = new AtkObjectClass ();
-		ATK.memmove (objectClass, superType);
+		if (object != null) {
+			if (object.parent != null) {
+				if (DEBUG) print ("---> " + object.parent.accessible.accessibleObject.handle);
+				return object.parent.handle;
+			}
+		}
+		AtkObjectClass objectClass = getObjectClass (atkObject);
 		if (objectClass.get_parent == 0) return 0;
-		return ATK.call (objectClass.get_parent, object.handle);
+		int /*long*/ parentResult = ATK.call (objectClass.get_parent, atkObject);
+		if (DEBUG) print ("---> " + parentResult);
+		return parentResult;
 	}
 
 	static int /*long*/ atkObject_get_role (int /*long*/ atkObject) {
-		if (DEBUG) System.out.println ("-->atkObject_get_role: " + atkObject);
+		if (DEBUG) print ("-->atkObject_get_role: " + atkObject);
 		AccessibleObject object = getAccessibleObject (atkObject);
-		if (object == null) return 0;
-		if (object.getAccessibleListeners ().length != 0) {
-			AccessibleControlListener[] listeners = object.getControlListeners ();
-			AccessibleControlEvent event = new AccessibleControlEvent (object.accessible);
-			event.childID = object.id;
-			event.detail = -1;
-			for (int i = 0; i < listeners.length; i++) {
-				listeners [i].getRole (event);				
-			} 
-			if (event.detail != -1) {
-				switch (event.detail) {
-					/* Convert from win32 role values to atk role values */
-					case ACC.ROLE_CHECKBUTTON: return ATK.ATK_ROLE_CHECK_BOX;
-					case ACC.ROLE_CLIENT_AREA: return ATK.ATK_ROLE_DRAWING_AREA;
-					case ACC.ROLE_COMBOBOX: return ATK.ATK_ROLE_COMBO_BOX;
-					case ACC.ROLE_DIALOG: return ATK.ATK_ROLE_DIALOG;
-					case ACC.ROLE_LABEL: return ATK.ATK_ROLE_LABEL;
-					case ACC.ROLE_LINK: return ATK.ATK_ROLE_TEXT;
-					case ACC.ROLE_LIST: return ATK.ATK_ROLE_LIST;
-					case ACC.ROLE_LISTITEM: return ATK.ATK_ROLE_LIST_ITEM;
-					case ACC.ROLE_MENU: return ATK.ATK_ROLE_MENU;
-					case ACC.ROLE_MENUBAR: return ATK.ATK_ROLE_MENU_BAR;
-					case ACC.ROLE_MENUITEM: return ATK.ATK_ROLE_MENU_ITEM;
-					case ACC.ROLE_PROGRESSBAR: return ATK.ATK_ROLE_PROGRESS_BAR;
-					case ACC.ROLE_PUSHBUTTON: return ATK.ATK_ROLE_PUSH_BUTTON;
-					case ACC.ROLE_SCROLLBAR: return ATK.ATK_ROLE_SCROLL_BAR;
-					case ACC.ROLE_SEPARATOR: return ATK.ATK_ROLE_SEPARATOR;
-					case ACC.ROLE_SLIDER: return ATK.ATK_ROLE_SLIDER;
-					case ACC.ROLE_TABLE: return ATK.ATK_ROLE_LIST;
-					case ACC.ROLE_TABLECELL: return ATK.ATK_ROLE_LIST_ITEM;
-					case ACC.ROLE_TABLECOLUMNHEADER: return ATK.ATK_ROLE_TABLE_COLUMN_HEADER;
-					case ACC.ROLE_TABLEROWHEADER: return ATK.ATK_ROLE_TABLE_ROW_HEADER;
-					case ACC.ROLE_TABFOLDER: return ATK.ATK_ROLE_PAGE_TAB_LIST;
-					case ACC.ROLE_TABITEM: return ATK.ATK_ROLE_PAGE_TAB;
-					case ACC.ROLE_TEXT: return ATK.ATK_ROLE_TEXT;
-					case ACC.ROLE_TOOLBAR: return ATK.ATK_ROLE_TOOL_BAR;
-					case ACC.ROLE_TOOLTIP: return ATK.ATK_ROLE_TOOL_TIP;
-					case ACC.ROLE_TREE: return ATK.ATK_ROLE_TREE;
-					case ACC.ROLE_TREEITEM: return ATK.ATK_ROLE_LIST_ITEM;
-					case ACC.ROLE_RADIOBUTTON: return ATK.ATK_ROLE_RADIO_BUTTON;
-					case ACC.ROLE_SPLITBUTTON: return ATK.ATK_ROLE_PUSH_BUTTON;
-					case ACC.ROLE_WINDOW: return ATK.ATK_ROLE_WINDOW;
-				}
-			}
-		} 
-		int /*long*/ superType = ATK.g_type_class_peek (object.parentType);
-		AtkObjectClass objectClass = new AtkObjectClass ();
-		ATK.memmove (objectClass, superType);
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleControlListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleControlEvent event = new AccessibleControlEvent (accessible);
+				event.childID = object.id;
+				event.detail = -1;
+				for (int i = 0; i < length; i++) {
+					AccessibleControlListener listener = (AccessibleControlListener)listeners.elementAt (i);
+					listener.getRole (event);				
+				}
+				if (DEBUG) print ("---> " + event.detail);
+				if (event.detail != -1) {
+					switch (event.detail) {
+						/* Convert from win32 role values to atk role values */
+						case ACC.ROLE_CHECKBUTTON: return ATK.ATK_ROLE_CHECK_BOX;
+						case ACC.ROLE_CLIENT_AREA: return ATK.ATK_ROLE_DRAWING_AREA;
+						case ACC.ROLE_COMBOBOX: return ATK.ATK_ROLE_COMBO_BOX;
+						case ACC.ROLE_DIALOG: return ATK.ATK_ROLE_DIALOG;
+						case ACC.ROLE_LABEL: return ATK.ATK_ROLE_LABEL;
+						case ACC.ROLE_LINK: return ATK.ATK_ROLE_TEXT;
+						case ACC.ROLE_LIST: return ATK.ATK_ROLE_LIST;
+						case ACC.ROLE_LISTITEM: return ATK.ATK_ROLE_LIST_ITEM;
+						case ACC.ROLE_MENU: return ATK.ATK_ROLE_MENU;
+						case ACC.ROLE_MENUBAR: return ATK.ATK_ROLE_MENU_BAR;
+						case ACC.ROLE_MENUITEM: return ATK.ATK_ROLE_MENU_ITEM;
+						case ACC.ROLE_PROGRESSBAR: return ATK.ATK_ROLE_PROGRESS_BAR;
+						case ACC.ROLE_PUSHBUTTON: return ATK.ATK_ROLE_PUSH_BUTTON;
+						case ACC.ROLE_SCROLLBAR: return ATK.ATK_ROLE_SCROLL_BAR;
+						case ACC.ROLE_SEPARATOR: return ATK.ATK_ROLE_SEPARATOR;
+						case ACC.ROLE_SLIDER: return ATK.ATK_ROLE_SLIDER;
+						case ACC.ROLE_TABLE: return ATK.ATK_ROLE_TABLE;
+						case ACC.ROLE_TABLECELL: return ATK.ATK_ROLE_TABLE_CELL;
+						case ACC.ROLE_TABLECOLUMNHEADER: return ATK.ATK_ROLE_TABLE_COLUMN_HEADER;
+						case ACC.ROLE_TABLEROWHEADER: return ATK.ATK_ROLE_TABLE_ROW_HEADER;
+						case ACC.ROLE_TABFOLDER: return ATK.ATK_ROLE_PAGE_TAB_LIST;
+						case ACC.ROLE_TABITEM: return ATK.ATK_ROLE_PAGE_TAB;
+						case ACC.ROLE_TEXT: return ATK.ATK_ROLE_TEXT;
+						case ACC.ROLE_TOOLBAR: return ATK.ATK_ROLE_TOOL_BAR;
+						case ACC.ROLE_TOOLTIP: return ATK.ATK_ROLE_TOOL_TIP;
+						case ACC.ROLE_TREE: return ATK.ATK_ROLE_TREE;
+						case ACC.ROLE_TREEITEM: return ATK.ATK_ROLE_LIST_ITEM;
+						case ACC.ROLE_RADIOBUTTON: return ATK.ATK_ROLE_RADIO_BUTTON;
+						case ACC.ROLE_SPLITBUTTON: return ATK.ATK_ROLE_PUSH_BUTTON;
+						case ACC.ROLE_WINDOW: return ATK.ATK_ROLE_WINDOW;
+						case ACC.ROLE_ROW: return ROW_ROLE;
+						case ACC.ROLE_COLUMN: return COLUMN_ROLE;
+						case ACC.ROLE_ALERT: return ATK.ATK_ROLE_ALERT;
+						case ACC.ROLE_ANIMATION: return ATK.ATK_ROLE_ANIMATION;
+						case ACC.ROLE_CANVAS: return ATK.ATK_ROLE_CANVAS;
+						case ACC.ROLE_GROUP: return ATK.ATK_ROLE_PANEL;
+						case ACC.ROLE_SPINBUTTON: return ATK.ATK_ROLE_SPIN_BUTTON;
+						case ACC.ROLE_STATUSBAR: return ATK.ATK_ROLE_STATUSBAR;
+						case ACC.ROLE_CHECKMENUITEM: return ATK.ATK_ROLE_CHECK_MENU_ITEM;
+						case ACC.ROLE_RADIOMENUITEM: return ATK.ATK_ROLE_RADIO_MENU_ITEM;
+						case ACC.ROLE_CLOCK: return ATK.ATK_ROLE_UNKNOWN;
+						case ACC.ROLE_CALENDAR: return ATK.ATK_ROLE_CALENDAR;
+						case ACC.ROLE_DATETIME: return ATK.ATK_ROLE_DATE_EDITOR;
+						case ACC.ROLE_FOOTER: return ATK.ATK_ROLE_FOOTER;
+						case ACC.ROLE_FORM: return ATK.ATK_ROLE_FORM;
+						case ACC.ROLE_HEADER: return ATK.ATK_ROLE_HEADER;
+						case ACC.ROLE_HEADING: return ATK.ATK_ROLE_HEADING;
+						case ACC.ROLE_PAGE: return ATK.ATK_ROLE_PAGE;
+						case ACC.ROLE_PARAGRAPH: return ATK.ATK_ROLE_PARAGRAPH;
+						case ACC.ROLE_SECTION: return ATK.ATK_ROLE_SECTION;
+						case ACC.ROLE_DOCUMENT: return ATK.ATK_ROLE_DOCUMENT_FRAME;
+						case ACC.ROLE_GRAPHIC: return ATK.ATK_ROLE_IMAGE;
+					}
+				}
+			}
+		}
+		AtkObjectClass objectClass = getObjectClass (atkObject);
 		if (objectClass.get_role == 0) return 0;
-		return ATK.call (objectClass.get_role, object.handle);
+		return ATK.call (objectClass.get_role, atkObject);
 	}
 
 	static int /*long*/ atkObject_ref_child (int /*long*/ atkObject, int /*long*/ index) {
-		if (DEBUG) System.out.println ("-->atkObject_ref_child: " + index + " of: " + atkObject);
+		if (DEBUG) print ("-->atkObject_ref_child: " + index + " of: " + atkObject);
 		AccessibleObject object = getAccessibleObject (atkObject);
-		if (object == null) return 0;
-		object.updateChildren ();
-		AccessibleObject accObject = object.getChildByIndex ((int)/*64*/index);	
-		if (accObject != null) {
-			OS.g_object_ref (accObject.handle);	
-			return accObject.handle;
+		if (object != null && object.id == ACC.CHILDID_SELF) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleControlListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleControlEvent event = new AccessibleControlEvent(accessible);
+				event.childID = ACC.CHILDID_CHILD_AT_INDEX;
+				event.detail = (int)/*64*/index;
+				for (int i = 0; i < length; i++) {
+					AccessibleControlListener listener = (AccessibleControlListener) listeners.elementAt(i);
+					listener.getChild(event);
+				}
+				if (event.accessible != null) {
+					AccessibleObject accObject = event.accessible.getAccessibleObject();
+					if (accObject != null) {
+						return OS.g_object_ref (accObject.handle);	
+					}
+				}
+			}
+			object.updateChildren ();
+			AccessibleObject accObject = object.getChildByIndex ((int)/*64*/index);	
+			if (accObject != null) {
+				return OS.g_object_ref (accObject.handle);	
+			}
 		}
-		int /*long*/ superType = ATK.g_type_class_peek (object.parentType);
-		AtkObjectClass objectClass = new AtkObjectClass ();
-		ATK.memmove (objectClass, superType);
+		AtkObjectClass objectClass = getObjectClass (atkObject);
 		if (objectClass.ref_child == 0) return 0;
-		return ATK.call (objectClass.ref_child, object.handle, index);
+		return ATK.call (objectClass.ref_child, atkObject, index);
 	}
 
 	static int /*long*/ atkObject_ref_state_set (int /*long*/ atkObject) {
-		if (DEBUG) System.out.println ("-->atkObject_ref_state_set");
+		if (DEBUG) print ("-->atkObject_ref_state_set: " + atkObject);
 		AccessibleObject object = getAccessibleObject (atkObject);
-		if (object == null) return 0;
 		int /*long*/ parentResult = 0;
-		int /*long*/ superType = ATK.g_type_class_peek (object.parentType);
-		AtkObjectClass objectClass = new AtkObjectClass ();
-		ATK.memmove (objectClass, superType);
+		AtkObjectClass objectClass = getObjectClass (atkObject);
 		if (objectClass.ref_state_set != 0) { 
-			parentResult = ATK.call (objectClass.ref_state_set, object.handle);
-		}
-		AccessibleControlListener[] listeners = object.getControlListeners ();
-		if (listeners.length == 0) return parentResult;
-
-		int /*long*/ set = parentResult;
-		AccessibleControlEvent event = new AccessibleControlEvent (object.accessible);
-		event.childID = object.id;
-		event.detail = -1;
-		for (int i = 0; i < listeners.length; i++) {
-			listeners [i].getState (event);
-		} 
-		if (event.detail != -1) {
-			/*	Convert from win32 state values to atk state values */
-			int state = event.detail;
-			if ((state & ACC.STATE_BUSY) != 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_BUSY);
-			if ((state & ACC.STATE_CHECKED) != 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_CHECKED);
-			if ((state & ACC.STATE_EXPANDED) != 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_EXPANDED);
-			if ((state & ACC.STATE_FOCUSABLE) != 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_FOCUSABLE);
-			if ((state & ACC.STATE_FOCUSED) != 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_FOCUSED);
-			if ((state & ACC.STATE_HOTTRACKED) != 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_ARMED);
-			if ((state & ACC.STATE_INVISIBLE) == 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_VISIBLE);
-			if ((state & ACC.STATE_MULTISELECTABLE) != 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_MULTISELECTABLE);
-			if ((state & ACC.STATE_OFFSCREEN) == 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_SHOWING);												
-			if ((state & ACC.STATE_PRESSED) != 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_PRESSED);
-			if ((state & ACC.STATE_READONLY) == 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_EDITABLE);
-			if ((state & ACC.STATE_SELECTABLE) != 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_SELECTABLE);
-			if ((state & ACC.STATE_SELECTED) != 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_SELECTED);
-			if ((state & ACC.STATE_SIZEABLE) != 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_RESIZABLE);
-			/* Note: STATE_COLLAPSED, STATE_LINKED and STATE_NORMAL have no ATK equivalents */
-		}
-		return set;
+			parentResult = ATK.call (objectClass.ref_state_set, atkObject);
+		}
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleControlListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				int /*long*/ set = parentResult;
+				AccessibleControlEvent event = new AccessibleControlEvent (accessible);
+				event.childID = object.id;
+				event.detail = -1;
+				for (int i = 0; i < length; i++) {
+					AccessibleControlListener listener = (AccessibleControlListener)listeners.elementAt (i);
+					listener.getState (event);
+				} 
+				if (event.detail != -1) {
+					/*	Convert from win32 state values to atk state values */
+					int state = event.detail;
+					if ((state & ACC.STATE_BUSY) != 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_BUSY);
+					if ((state & ACC.STATE_CHECKED) != 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_CHECKED);
+					if ((state & ACC.STATE_EXPANDED) != 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_EXPANDED);
+					if ((state & ACC.STATE_FOCUSABLE) != 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_FOCUSABLE);
+					if ((state & ACC.STATE_FOCUSED) != 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_FOCUSED);
+					if ((state & ACC.STATE_HOTTRACKED) != 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_ARMED);
+					if ((state & ACC.STATE_INVISIBLE) == 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_VISIBLE);
+					if ((state & ACC.STATE_MULTISELECTABLE) != 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_MULTISELECTABLE);
+					if ((state & ACC.STATE_OFFSCREEN) == 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_SHOWING);												
+					if ((state & ACC.STATE_PRESSED) != 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_PRESSED);
+					if ((state & ACC.STATE_READONLY) == 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_EDITABLE);
+					if ((state & ACC.STATE_SELECTABLE) != 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_SELECTABLE);
+					if ((state & ACC.STATE_SELECTED) != 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_SELECTED);
+					if ((state & ACC.STATE_SIZEABLE) != 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_RESIZABLE);
+					if ((state & ACC.STATE_DISABLED) == 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_ENABLED);
+					if ((state & ACC.STATE_ACTIVE) != 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_ACTIVE);
+					if ((state & ACC.STATE_SINGLELINE) != 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_SINGLE_LINE);
+					if ((state & ACC.STATE_MULTILINE) != 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_MULTI_LINE);
+					if ((state & ACC.STATE_REQUIRED) != 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_REQUIRED);
+					if ((state & ACC.STATE_INVALID_ENTRY) != 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_INVALID_ENTRY);
+					if ((state & ACC.STATE_SUPPORTS_AUTOCOMPLETION) != 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_SUPPORTS_AUTOCOMPLETION);
+					/* Note: STATE_COLLAPSED, STATE_LINKED and STATE_NORMAL have no ATK equivalents */
+				}
+				return set;
+			}
+		}
+		return parentResult;
 	}
-
+	
+	static AtkSelectionIface getSelectionIface (int /*long*/ atkObject) {
+		if (ATK.g_type_is_a (OS.g_type_parent (OS.G_OBJECT_TYPE (atkObject)), ATK.ATK_TYPE_SELECTION())) {
+			AtkSelectionIface iface = new AtkSelectionIface ();
+			ATK.memmove (iface, ATK.g_type_interface_peek_parent (ATK.ATK_SELECTION_GET_IFACE (atkObject)));
+			return iface;
+		}
+		return null;
+	}
+	
 	static int /*long*/ atkSelection_is_child_selected (int /*long*/ atkObject, int /*long*/ index) {
-		if (DEBUG) System.out.println ("-->atkSelection_is_child_selected");
+		if (DEBUG) print ("-->atkSelection_is_child_selected");
 		AccessibleObject object = getAccessibleObject (atkObject);
-		if (object == null) return 0;
 		int /*long*/ parentResult = 0;
-		if (ATK.g_type_is_a (object.parentType, ATK_SELECTION_TYPE)) {
-			int /*long*/ superType = ATK.g_type_interface_peek_parent (ATK.ATK_SELECTION_GET_IFACE (object.handle));
-			AtkSelectionIface selectionIface = new AtkSelectionIface ();
-			ATK.memmove (selectionIface, superType);
-			if (selectionIface.is_child_selected != 0) {
-				parentResult = ATK.call (selectionIface.is_child_selected, object.handle, index);
-			}
-		}
-		AccessibleControlListener[] listeners = object.getControlListeners ();
-		if (listeners.length == 0) return parentResult;
-			
-		AccessibleControlEvent event = new AccessibleControlEvent (object.accessible);
-		event.childID = object.id;
-		for (int i = 0; i < listeners.length; i++) {
-			listeners [i].getSelection (event);
-		}
-		AccessibleObject accessibleObject = object.getChildByID (event.childID);
-		if (accessibleObject != null) { 
-			return accessibleObject.index == index ? 1 : 0;
+		AtkSelectionIface iface = getSelectionIface (atkObject);
+		if (iface != null && iface.is_child_selected != 0) {
+			parentResult = ATK.call (iface.is_child_selected, atkObject, index);
+		}
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleControlListeners;
+			int length = listeners.size();
+			if (length > 0) {	
+				AccessibleControlEvent event = new AccessibleControlEvent (accessible);
+				event.childID = object.id;
+				for (int i = 0; i < length; i++) {
+					AccessibleControlListener listener = (AccessibleControlListener)listeners.elementAt (i);
+					listener.getSelection (event);
+				}
+				Accessible result = event.accessible;
+				AccessibleObject accessibleObject = result != null ? result.getAccessibleObject() : object.getChildByID (event.childID);
+				if (accessibleObject != null) { 
+					return accessibleObject.index == index ? 1 : 0;
+				}
+			}
 		}
 		return parentResult;
 	}
 
 	static int /*long*/ atkSelection_ref_selection (int /*long*/ atkObject, int /*long*/ index) {
-		if (DEBUG) System.out.println ("-->atkSelection_ref_selection");
+		if (DEBUG) print ("-->atkSelection_ref_selection");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		int /*long*/ parentResult = 0;
+		AtkSelectionIface iface = getSelectionIface (atkObject);
+		if (iface != null && iface.ref_selection != 0) {
+			parentResult = ATK.call (iface.ref_selection, atkObject, index);
+		}
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleControlListeners;
+			int length = listeners.size();
+			if (length > 0) {	
+				AccessibleControlEvent event = new AccessibleControlEvent (accessible);
+				event.childID = object.id;
+				for (int i = 0; i < length; i++) {
+					AccessibleControlListener listener = (AccessibleControlListener)listeners.elementAt (i);
+					listener.getSelection (event);
+				} 
+				AccessibleObject accObj = object.getChildByID (event.childID);
+				if (accObj != null) {
+					if (parentResult != 0) OS.g_object_unref (parentResult);
+					OS.g_object_ref (accObj.handle);	
+					return accObj.handle;
+				}
+			}
+		}
+		return parentResult;
+	}
+
+	static AtkTableIface getTableIface (int /*long*/ atkObject) {
+		if (ATK.g_type_is_a (OS.g_type_parent (OS.G_OBJECT_TYPE (atkObject)), ATK.ATK_TYPE_TABLE())) {
+			AtkTableIface iface = new AtkTableIface ();
+			ATK.memmove (iface, ATK.g_type_interface_peek_parent (ATK.ATK_TABLE_GET_IFACE (atkObject)));
+			return iface;
+		}
+		return null;
+	}
+	
+	static int /*long*/ atkTable_ref_at (int /*long*/ atkObject, int /*long*/ row, int /*long*/ column) {
+		if (DEBUG) print ("-->atkTable_ref_at");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTableListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTableEvent event = new AccessibleTableEvent(accessible);
+				event.row = (int)/*64*/row;
+				event.column = (int)/*64*/column;
+				for (int i = 0; i < length; i++) {
+					AccessibleTableListener listener = (AccessibleTableListener) listeners.elementAt(i);
+					listener.getCell(event);
+				}
+				Accessible result = event.accessible;
+				if (result != null) {
+					AccessibleObject accessibleObject = result.getAccessibleObject();
+					OS.g_object_ref(accessibleObject.handle);
+					return accessibleObject.handle;
+				}
+			}
+		}
+		int /*long*/ parentResult = 0;
+		AtkTableIface iface = getTableIface (atkObject);
+		if (iface != null && iface.ref_at != 0) {
+			parentResult = ATK.call (iface.ref_at, atkObject, row, column);
+		}
+		return parentResult;
+	}
+
+	static int /*long*/ atkTable_get_index_at (int /*long*/ atkObject, int /*long*/ row, int /*long*/ column) {
+		if (DEBUG) print ("-->atkTable_get_index_at");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTableListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTableEvent event = new AccessibleTableEvent(accessible);
+				event.row = (int)/*64*/row;
+				event.column = (int)/*64*/column;
+				for (int i = 0; i < length; i++) {
+					AccessibleTableListener listener = (AccessibleTableListener) listeners.elementAt(i);
+					listener.getCell(event);
+				}
+				Accessible result = event.accessible;
+				if (result == null) return -1;
+				event = new AccessibleTableEvent(accessible);
+				for (int i = 0; i < length; i++) {
+					AccessibleTableListener listener = (AccessibleTableListener) listeners.elementAt(i);
+					listener.getColumnCount(event);
+				}
+				return row * event.count + column;
+			}
+		}
+		int /*long*/ parentResult = 0;
+		AtkTableIface iface = getTableIface (atkObject);
+		if (iface != null && iface.get_index_at != 0) {
+			parentResult = ATK.call (iface.get_index_at, atkObject, row, column);
+		}
+		return parentResult;
+	}
+
+	static int /*long*/ atkTable_get_column_at_index (int /*long*/ atkObject, int /*long*/ index) {
+		if (DEBUG) print ("-->atkTable_get_column_at_index: " + atkObject + " " + index);
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTableListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTableEvent event = new AccessibleTableEvent(accessible);
+				for (int i = 0; i < length; i++) {
+					AccessibleTableListener listener = (AccessibleTableListener) listeners.elementAt(i);
+					listener.getColumnCount(event);
+				}
+				int /*long*/ result = event.count == 0 ? -1 : index % event.count;
+				if (DEBUG) print ("---> " + result);
+				return result;
+			}
+		}
+		int /*long*/ parentResult = 0;
+		AtkTableIface iface = getTableIface (atkObject);
+		if (iface != null && iface.get_column_at_index != 0) {
+			parentResult = ATK.call (iface.get_column_at_index, atkObject, index);
+		}
+		return parentResult;
+	}
+
+	static int /*long*/ atkTable_get_row_at_index (int /*long*/ atkObject, int /*long*/ index) {
+		if (DEBUG) print ("-->atkTable_get_row_at_index: " + atkObject + " " + index);
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTableListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTableEvent event = new AccessibleTableEvent(accessible);
+				for (int i = 0; i < length; i++) {
+					AccessibleTableListener listener = (AccessibleTableListener) listeners.elementAt(i);
+					listener.getColumnCount(event);
+				}
+				int /*long*/ result = event.count == 0 ? -1 : index / event.count;
+				if (DEBUG) print ("---> " + result);
+				return result;
+			}
+		}
+		int /*long*/ parentResult = 0;
+		AtkTableIface iface = getTableIface (atkObject);
+		if (iface != null && iface.get_row_at_index != 0) {
+			parentResult = ATK.call (iface.get_row_at_index, atkObject, index);
+		}
+		return parentResult;
+	}
+
+	static int /*long*/ atkTable_get_n_columns (int /*long*/ atkObject) {
+		if (DEBUG) print ("-->atkTable_get_n_columns");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		int /*long*/ parentResult = 0;
+		AtkTableIface iface = getTableIface (atkObject);
+		if (iface != null && iface.get_n_columns != 0) {
+			parentResult = ATK.call (iface.get_n_columns, atkObject);
+		}
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTableListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTableEvent event = new AccessibleTableEvent(accessible);
+				event.count = (int)/*64*/parentResult;
+				for (int i = 0; i < length; i++) {
+					AccessibleTableListener listener = (AccessibleTableListener) listeners.elementAt(i);
+					listener.getColumnCount(event);
+					parentResult = event.count;
+				}
+			}
+		}
+		return parentResult;
+	}
+
+	static int /*long*/ atkTable_get_n_rows (int /*long*/ atkObject) {
+		if (DEBUG) print ("-->atkTable_get_n_rows");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		int /*long*/ parentResult = 0;
+		AtkTableIface iface = getTableIface (atkObject);
+		if (iface != null && iface.get_n_rows != 0) {
+			parentResult = ATK.call (iface.get_n_rows, atkObject);
+		}
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTableListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTableEvent event = new AccessibleTableEvent(accessible);
+				event.count = (int)/*64*/parentResult;
+				for (int i = 0; i < length; i++) {
+					AccessibleTableListener listener = (AccessibleTableListener) listeners.elementAt(i);
+					listener.getRowCount(event);
+					parentResult = event.count;
+				}
+			}
+		}
+		return parentResult;
+	}
+
+	static int /*long*/ atkTable_get_column_extent_at (int /*long*/ atkObject, int /*long*/ row, int /*long*/ column) {
+		if (DEBUG) print ("-->atkTable_get_column_extent_at");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		int /*long*/ parentResult = 0;
+		AtkTableIface iface = getTableIface (atkObject);
+		if (iface != null && iface.get_column_extent_at != 0) {
+			parentResult = ATK.call (iface.get_column_extent_at, atkObject, row, column);
+		}
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTableListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTableEvent event = new AccessibleTableEvent(accessible);
+				event.row = (int)/*64*/row;
+				event.column = (int)/*64*/column;
+				for (int i = 0; i < length; i++) {
+					AccessibleTableListener listener = (AccessibleTableListener) listeners.elementAt(i);
+					listener.getCell(event);
+				}
+				Accessible result = event.accessible;
+				if (result != null) {
+					listeners = result.accessibleTableCellListeners;
+					length = listeners.size();
+					if (length > 0) {
+						AccessibleTableCellEvent cellEvent = new AccessibleTableCellEvent(result);
+						cellEvent.count = (int)/*64*/parentResult;
+						for (int i = 0; i < length; i++) {
+							AccessibleTableCellListener listener = (AccessibleTableCellListener) listeners.elementAt(i);
+							listener.getColumnSpan(cellEvent);
+						}
+						return cellEvent.count;
+					}
+				}
+			}
+		}
+		return parentResult;
+	}
+
+	static int /*long*/ atkTable_get_row_extent_at (int /*long*/ atkObject, int /*long*/ row, int /*long*/ column) {
+		if (DEBUG) print ("-->atkTable_get_row_extent_at");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		int /*long*/ parentResult = 0;
+		AtkTableIface iface = getTableIface (atkObject);
+		if (iface != null && iface.get_row_extent_at != 0) {
+			parentResult = ATK.call (iface.get_row_extent_at, atkObject, row, column);
+		}
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTableListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTableEvent event = new AccessibleTableEvent(accessible);
+				event.row = (int)/*64*/row;
+				event.column = (int)/*64*/column;
+				for (int i = 0; i < length; i++) {
+					AccessibleTableListener listener = (AccessibleTableListener) listeners.elementAt(i);
+					listener.getCell(event);
+				}
+				Accessible result = event.accessible;
+				if (result != null) {
+					listeners = result.accessibleTableCellListeners;
+					length = listeners.size();
+					if (length > 0) {
+						AccessibleTableCellEvent cellEvent = new AccessibleTableCellEvent(result);
+						cellEvent.count = (int)/*64*/parentResult;
+						for (int i = 0; i < length; i++) {
+							AccessibleTableCellListener listener = (AccessibleTableCellListener) listeners.elementAt(i);
+							listener.getRowSpan(cellEvent);
+						}
+						return cellEvent.count;
+					}
+				}
+			}
+		}
+		return parentResult;
+	}
+
+	static int /*long*/ atkTable_get_caption (int /*long*/ atkObject) {
+		if (DEBUG) print ("-->atkTable_get_caption");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTableListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTableEvent event = new AccessibleTableEvent(accessible);
+				for (int i = 0; i < length; i++) {
+					AccessibleTableListener listener = (AccessibleTableListener) listeners.elementAt(i);
+					listener.getCaption(event);
+				}
+				Accessible result = event.accessible;
+				if (result != null) return result.getAccessibleObject().handle;
+			}
+		}
+		int /*long*/ parentResult = 0;
+		AtkTableIface iface = getTableIface (atkObject);
+		if (iface != null && iface.get_caption != 0) {
+			parentResult = ATK.call (iface.get_caption, atkObject);
+		}
+		return parentResult;
+	}
+
+	static int /*long*/ atkTable_get_summary (int /*long*/ atkObject) {
+		if (DEBUG) print ("-->atkTable_get_summary");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTableListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTableEvent event = new AccessibleTableEvent(accessible);
+				for (int i = 0; i < length; i++) {
+					AccessibleTableListener listener = (AccessibleTableListener) listeners.elementAt(i);
+					listener.getSummary(event);
+				}
+				Accessible result = event.accessible;
+				if (result != null) return result.getAccessibleObject().handle;
+			}
+		}
+		int /*long*/ parentResult = 0;
+		AtkTableIface iface = getTableIface (atkObject);
+		if (iface != null && iface.get_summary != 0) {
+			parentResult = ATK.call (iface.get_summary, atkObject);
+		}
+		return parentResult;
+	}
+	
+	static int /*long*/ atkTable_get_column_description (int /*long*/ atkObject, int /*long*/ column) {
+		if (DEBUG) print ("-->atkTable_get_column_description");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		int /*long*/ parentResult = 0;
+		AtkTableIface iface = getTableIface (atkObject);
+		if (iface != null && iface.get_column_description != 0) {
+			parentResult = ATK.call (iface.get_column_description, atkObject, column);
+		}
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTableListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTableEvent event = new AccessibleTableEvent(accessible);
+				event.column = (int)/*64*/column;
+				if (parentResult != 0) event.result = getString (parentResult);
+				for (int i = 0; i < length; i++) {
+					AccessibleTableListener listener = (AccessibleTableListener) listeners.elementAt(i);
+					listener.getColumnDescription(event);
+				}
+				if (event.result == null) return parentResult;
+				if (descriptionPtr != -1) OS.g_free (descriptionPtr);
+				return descriptionPtr = getStringPtr (event.result);
+			}
+		}
+		return parentResult;
+	}
+	
+	static int /*long*/ atkTable_get_column_header (int /*long*/ atkObject, int /*long*/ column) {
+		if (DEBUG) print ("-->atkTable_get_column_header");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTableListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTableEvent event = new AccessibleTableEvent(accessible);
+				for (int i = 0; i < length; i++) {
+					AccessibleTableListener listener = (AccessibleTableListener) listeners.elementAt(i);
+					listener.getRowHeaderCells(event);
+				}
+				Accessible[] accessibles = event.accessibles;
+				if (accessibles != null) {
+					if (0 <= column && column < accessibles.length) {
+						return accessibles[(int)/*64*/column].getAccessibleObject().handle;
+					}
+				}
+			}
+		}
+		int /*long*/ parentResult = 0;
+		AtkTableIface iface = getTableIface (atkObject);
+		if (iface != null && iface.get_column_header != 0) {
+			parentResult = ATK.call (iface.get_column_header, atkObject, column);
+		}
+		return parentResult;
+	}
+	
+	static int /*long*/ atkTable_get_row_description (int /*long*/ atkObject, int /*long*/ row) {
+		if (DEBUG) print ("-->atkTable_get_row_description");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		int /*long*/ parentResult = 0;
+		AtkTableIface iface = getTableIface (atkObject);
+		if (iface != null && iface.get_row_description != 0) {
+			parentResult = ATK.call (iface.get_row_description, atkObject, row);
+		}
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTableListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTableEvent event = new AccessibleTableEvent(accessible);
+				event.row = (int)/*64*/row;
+				if (parentResult != 0) event.result = getString (parentResult);
+				for (int i = 0; i < length; i++) {
+					AccessibleTableListener listener = (AccessibleTableListener) listeners.elementAt(i);
+					listener.getRowDescription(event);
+				}
+				if (event.result == null) return parentResult;
+				if (descriptionPtr != -1) OS.g_free (descriptionPtr);
+				return descriptionPtr = getStringPtr (event.result);
+			}
+		}
+		return parentResult;
+	}
+
+	static int /*long*/ atkTable_get_row_header (int /*long*/ atkObject, int /*long*/ row) {
+		if (DEBUG) print ("-->atkTable_get_row_header");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTableListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTableEvent event = new AccessibleTableEvent(accessible);
+				for (int i = 0; i < length; i++) {
+					AccessibleTableListener listener = (AccessibleTableListener) listeners.elementAt(i);
+					listener.getRowHeaderCells(event);
+				}
+				Accessible[] accessibles = event.accessibles;
+				if (accessibles != null) {
+					if (0 <= row && row < accessibles.length) {
+						return accessibles[(int)/*64*/row].getAccessibleObject().handle;
+					}
+				}
+			}
+		}
+		int /*long*/ parentResult = 0;
+		AtkTableIface iface = getTableIface (atkObject);
+		if (iface != null && iface.get_row_header != 0) {
+			parentResult = ATK.call (iface.get_row_header, atkObject, row);
+		}
+		return parentResult;
+	}
+
+	static int /*long*/ atkTable_get_selected_columns (int /*long*/ atkObject, int /*long*/ selected) {
+		if (DEBUG) print ("-->atkTable_get_selected_columns");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTableListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTableEvent event = new AccessibleTableEvent(accessible);
+				for (int i = 0; i < length; i++) {
+					AccessibleTableListener listener = (AccessibleTableListener) listeners.elementAt(i);
+					listener.getSelectedColumns(event);
+				}
+				int count = event.selected != null ? event.selected.length : 0;
+				int /*long*/ result = OS.g_malloc(count * 4);
+				if (event.selected != null) OS.memmove(result, event.selected, count * 4);
+				if (selected != 0) OS.memmove(selected, new int /*long*/[]{result}, C.PTR_SIZEOF);
+				return count;
+			}
+		}
+		int /*long*/ parentResult = 0;
+		AtkTableIface iface = getTableIface (atkObject);
+		if (iface != null && iface.get_selected_columns != 0) {
+			parentResult = ATK.call (iface.get_selected_columns, atkObject, selected);
+		}
+		return parentResult;
+	}
+
+	static int /*long*/ atkTable_get_selected_rows (int /*long*/ atkObject, int /*long*/ selected) {
+		if (DEBUG) print ("-->atkTable_get_selected_rows");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTableListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTableEvent event = new AccessibleTableEvent(accessible);
+				for (int i = 0; i < length; i++) {
+					AccessibleTableListener listener = (AccessibleTableListener) listeners.elementAt(i);
+					listener.getSelectedRows(event);
+				}
+				int count = event.selected != null ? event.selected.length : 0;
+				int /*long*/ result = OS.g_malloc(count * 4);
+				if (event.selected != null) OS.memmove(result, event.selected, count * 4);
+				if (selected != 0) OS.memmove(selected, new int /*long*/[]{result}, C.PTR_SIZEOF);
+				return count;
+			}
+		}
+		int /*long*/ parentResult = 0;
+		AtkTableIface iface = getTableIface (atkObject);
+		if (iface != null && iface.get_selected_rows != 0) {
+			parentResult = ATK.call (iface.get_selected_rows, atkObject, selected);
+		}
+		return parentResult;
+	}
+
+	static int /*long*/ atkTable_is_column_selected (int /*long*/ atkObject, int /*long*/ column) {
+		if (DEBUG) print ("-->atkTable_is_column_selected");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		int /*long*/ parentResult = 0;
+		AtkTableIface iface = getTableIface (atkObject);
+		if (iface != null && iface.is_column_selected != 0) {
+			parentResult = ATK.call (iface.is_column_selected, atkObject, column);
+		}
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTableListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTableEvent event = new AccessibleTableEvent(accessible);
+				event.isSelected = parentResult != 0;
+				event.column = (int)/*64*/column;
+				for (int i = 0; i < length; i++) {
+					AccessibleTableListener listener = (AccessibleTableListener) listeners.elementAt(i);
+					listener.isColumnSelected(event);
+				}
+				return event.isSelected ? 1 : 0;
+			}
+		}
+		return parentResult;
+	}
+
+	static int /*long*/ atkTable_is_row_selected (int /*long*/ atkObject, int /*long*/ row) {
+		if (DEBUG) print ("-->atkTable_is_row_selected");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		int /*long*/ parentResult = 0;
+		AtkTableIface iface = getTableIface (atkObject);
+		if (iface != null && iface.is_row_selected != 0) {
+			parentResult = ATK.call (iface.is_row_selected, atkObject, row);
+		}
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTableListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTableEvent event = new AccessibleTableEvent(accessible);
+				event.isSelected = parentResult != 0;
+				event.row = (int)/*64*/row;
+				for (int i = 0; i < length; i++) {
+					AccessibleTableListener listener = (AccessibleTableListener) listeners.elementAt(i);
+					listener.isRowSelected(event);
+				}
+				return event.isSelected ? 1 : 0;
+			}
+		}
+		return parentResult;
+	}
+
+	static int /*long*/ atkTable_is_selected (int /*long*/ atkObject, int /*long*/ row, int /*long*/ column) {
+		if (DEBUG) print ("-->atkTable_is_selected");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		int /*long*/ parentResult = 0;
+		AtkTableIface iface = getTableIface (atkObject);
+		if (iface != null && iface.is_selected != 0) {
+			parentResult = ATK.call (iface.is_selected, atkObject, row, column);
+		}
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTableListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTableEvent event = new AccessibleTableEvent(accessible);
+				event.row = (int)/*64*/row;
+				event.column = (int)/*64*/column;
+				for (int i = 0; i < length; i++) {
+					AccessibleTableListener listener = (AccessibleTableListener) listeners.elementAt(i);
+					listener.getCell(event);
+				}
+				Accessible result = event.accessible;
+				if (result != null) {
+					listeners = result.accessibleTableCellListeners;
+					length = listeners.size();
+					if (length > 0) {
+						AccessibleTableCellEvent cellEvent = new AccessibleTableCellEvent(result);
+						cellEvent.isSelected = parentResult != 0;
+						for (int i = 0; i < length; i++) {
+							AccessibleTableCellListener listener = (AccessibleTableCellListener) listeners.elementAt(i);
+							listener.isSelected(cellEvent);
+						}
+						return cellEvent.isSelected ? 1 : 0;
+					}
+				}
+			}
+		}
+		return parentResult;
+	}
+
+	static int /*long*/ atkTable_add_row_selection (int /*long*/ atkObject, int /*long*/ row) {
+		if (DEBUG) print ("-->atkTable_add_row_selection");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTableListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTableEvent event = new AccessibleTableEvent(accessible);
+				event.row = (int)/*64*/row;
+				for (int i = 0; i < length; i++) {
+					AccessibleTableListener listener = (AccessibleTableListener) listeners.elementAt(i);
+					listener.selectRow(event);
+				}
+				return ACC.OK.equals(event.result) ? 1 : 0;
+			}
+		}
+		int /*long*/ parentResult = 0;
+		AtkTableIface iface = getTableIface (atkObject);
+		if (iface != null && iface.add_row_selection != 0) {
+			parentResult = ATK.call (iface.add_row_selection, atkObject, row);
+		}
+		return parentResult;
+	}
+
+	static int /*long*/ atkTable_remove_row_selection (int /*long*/ atkObject, int /*long*/ row) {
+		if (DEBUG) print ("-->atkTable_remove_row_selection");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTableListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTableEvent event = new AccessibleTableEvent(accessible);
+				event.row = (int)/*64*/row;
+				for (int i = 0; i < length; i++) {
+					AccessibleTableListener listener = (AccessibleTableListener) listeners.elementAt(i);
+					listener.deselectRow(event);
+				}
+				return ACC.OK.equals(event.result) ? 1 : 0;
+			}
+		}
+		int /*long*/ parentResult = 0;
+		AtkTableIface iface = getTableIface (atkObject);
+		if (iface != null && iface.remove_row_selection != 0) {
+			parentResult = ATK.call (iface.remove_row_selection, atkObject, row);
+		}
+		return parentResult;
+	}
+
+	static int /*long*/ atkTable_add_column_selection (int /*long*/ atkObject, int /*long*/ column) {
+		if (DEBUG) print ("-->atkTable_add_column_selection");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTableListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTableEvent event = new AccessibleTableEvent(accessible);
+				event.column = (int)/*64*/column;
+				for (int i = 0; i < length; i++) {
+					AccessibleTableListener listener = (AccessibleTableListener) listeners.elementAt(i);
+					listener.selectColumn(event);
+				}
+				return ACC.OK.equals(event.result) ? 1 : 0;
+			}
+		}
+		int /*long*/ parentResult = 0;
+		AtkTableIface iface = getTableIface (atkObject);
+		if (iface != null && iface.add_column_selection != 0) {
+			parentResult = ATK.call (iface.add_column_selection, atkObject, column);
+		}
+		return parentResult;
+	}
+
+	static int /*long*/ atkTable_remove_column_selection (int /*long*/ atkObject, int /*long*/ column) {
+		if (DEBUG) print ("-->atkTable_remove_column_selection");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTableListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTableEvent event = new AccessibleTableEvent(accessible);
+				event.column = (int)/*64*/column;
+				for (int i = 0; i < length; i++) {
+					AccessibleTableListener listener = (AccessibleTableListener) listeners.elementAt(i);
+					listener.deselectColumn(event);
+				}
+				return ACC.OK.equals(event.result) ? 1 : 0;
+			}
+		}
+		int /*long*/ parentResult = 0;
+		AtkTableIface iface = getTableIface (atkObject);
+		if (iface != null && iface.remove_column_selection != 0) {
+			parentResult = ATK.call (iface.remove_column_selection, atkObject, column);
+		}
+		return parentResult;
+	}
+
+	static AtkTextIface getTextIface (int /*long*/ atkObject) {
+		if (ATK.g_type_is_a (OS.g_type_parent (OS.G_OBJECT_TYPE (atkObject)), ATK.ATK_TYPE_TEXT())) {
+			AtkTextIface iface = new AtkTextIface ();
+			ATK.memmove (iface, ATK.g_type_interface_peek_parent (ATK.ATK_TEXT_GET_IFACE (atkObject)));
+			return iface;
+		}
+		return null;
+	}
+	
+	static int /*long*/ atkText_get_character_extents (int /*long*/ atkObject, int /*long*/ offset, int /*long*/ x, int /*long*/ y, int /*long*/ width, int /*long*/ height, int /*long*/ coords) {
+		if (DEBUG) print ("-->atkText_get_character_extents");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTextExtendedListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTextEvent event = new AccessibleTextEvent(accessible);
+				event.start = (int)/*64*/offset;
+				event.end = (int)/*64*/(offset + 1);
+				for (int i = 0; i < length; i++) {
+					AccessibleTextExtendedListener listener = (AccessibleTextExtendedListener) listeners.elementAt(i);
+					listener.getTextBounds(event);
+				}
+				int[] topWindowX = new int [1], topWindowY = new int [1];
+				if (coords == ATK.ATK_XY_WINDOW) {
+					windowPoint (object, topWindowX, topWindowY);
+					event.x -= topWindowX [0];
+					event.y -= topWindowY [0];
+				}
+				OS.memmove (x, new int[]{event.x}, 4);
+				OS.memmove (y, new int[]{event.y}, 4);
+				OS.memmove (width, new int[]{event.width}, 4);
+				OS.memmove (height, new int[]{event.height}, 4);				
+				return 0;
+			}
+		}
+		AtkTextIface iface = getTextIface (atkObject);
+		if (iface != null && iface.get_character_extents != 0) {
+			ATK.call (iface.get_character_extents, atkObject, offset, x, y, width, height, coords);
+		}
+		return 0;
+	}
+	
+	static String getString (int /*long*/ strPtr) {
+		int length = OS.strlen (strPtr);
+		byte [] buffer = new byte [length];
+		OS.memmove (buffer, strPtr, length);
+		return new String (Converter.mbcsToWcs (null, buffer));
+	}
+	
+	static int /*long*/ getStringPtr (String str) {
+		byte [] buffer = Converter.wcsToMbcs(null, str != null ? str : "", true); 
+		int /*long*/ ptr = OS.g_malloc(buffer.length);
+		OS.memmove(ptr, buffer, buffer.length);
+		return ptr;
+	}
+	
+	static int /*long*/ atkText_get_range_extents (int /*long*/ atkObject, int /*long*/ start_offset, int /*long*/ end_offset, int /*long*/ coord_type, int /*long*/ rect) {
+		if (DEBUG) print ("-->atkText_get_range_extents");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTextExtendedListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTextEvent event = new AccessibleTextEvent(accessible);
+				event.start = (int)/*64*/start_offset;
+				event.end = (int)/*64*/end_offset;
+				for (int i = 0; i < length; i++) {
+					AccessibleTextExtendedListener listener = (AccessibleTextExtendedListener) listeners.elementAt(i);
+					listener.getTextBounds(event);
+				}
+				int[] topWindowX = new int [1], topWindowY = new int [1];
+				if (coord_type == ATK.ATK_XY_WINDOW) {
+					windowPoint (object, topWindowX, topWindowY);
+					event.x -= topWindowX [0];
+					event.y -= topWindowY [0];
+				}
+				AtkTextRectangle atkRect = new AtkTextRectangle();
+				atkRect.x = event.x;
+				atkRect.y = event.y;
+				atkRect.width = event.width;
+				atkRect.height = event.height;
+				ATK.memmove (rect, atkRect, AtkTextRectangle.sizeof);
+				return 0;
+			}
+		}
+		AtkTextIface iface = getTextIface (atkObject);
+		if (iface != null && iface.get_range_extents != 0) {
+			ATK.call (iface.get_range_extents, atkObject, start_offset, end_offset, coord_type, rect);
+		}
+		return 0;
+	}
+	
+	static int /*long*/ atkText_get_run_attributes (int /*long*/ atkObject, int /*long*/ offset, int /*long*/ start_offset, int /*long*/ end_offset) {
+		if (DEBUG) print ("-->atkText_get_run_attributes");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleAttributeListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTextAttributeEvent event = new AccessibleTextAttributeEvent(accessible);
+				event.offset = (int)/*64*/offset;
+				for (int i = 0; i < length; i++) {
+					AccessibleAttributeListener listener = (AccessibleAttributeListener) listeners.elementAt(i);
+					listener.getTextAttributes(event);
+				}
+				OS.memmove (start_offset, new int []{event.start}, 4);
+				OS.memmove (end_offset, new int []{event.end}, 4);
+				TextStyle style = event.textStyle;
+				int /*long*/ result = 0;
+				AtkAttribute attr = new AtkAttribute();
+				if (style != null) {
+					if (style.rise != 0) {
+						int /*long*/ attrPtr = OS.g_malloc(AtkAttribute.sizeof);
+						attr.name = ATK.g_strdup (ATK.atk_text_attribute_get_name(ATK.ATK_TEXT_ATTR_RISE));
+						attr.value = getStringPtr (String.valueOf(style.rise));
+						ATK.memmove(attrPtr, attr, AtkAttribute.sizeof);
+						result = OS.g_list_append(result, attrPtr);
+					}
+					if (style.underline) {
+						int /*long*/ attrPtr = OS.g_malloc(AtkAttribute.sizeof);
+						attr.name = ATK.g_strdup (ATK.atk_text_attribute_get_name(ATK.ATK_TEXT_ATTR_UNDERLINE));
+						String str = "none"; //$NON-NLS-1$
+						switch (style.underlineStyle) {
+							case SWT.UNDERLINE_DOUBLE: str = "double"; break; //$NON-NLS-1$
+							case SWT.UNDERLINE_SINGLE: str = "single"; break; //$NON-NLS-1$
+							case SWT.UNDERLINE_ERROR: str = "error"; break; //$NON-NLS-1$
+							case SWT.UNDERLINE_SQUIGGLE: str = "squiggle"; break; //$NON-NLS-1$
+						}
+						attr.value = getStringPtr (str);
+						ATK.memmove(attrPtr, attr, AtkAttribute.sizeof);
+						result = OS.g_list_append(result, attrPtr);
+					}
+					if (style.strikeout) {
+						int /*long*/ attrPtr = OS.g_malloc(AtkAttribute.sizeof);
+						attr.name = ATK.g_strdup (ATK.atk_text_attribute_get_name(ATK.ATK_TEXT_ATTR_STRIKETHROUGH));
+						attr.value = getStringPtr ("1");
+						ATK.memmove(attrPtr, attr, AtkAttribute.sizeof);
+						result = OS.g_list_append(result, attrPtr);
+					}
+					Font font = style.font;
+					if (font != null && !font.isDisposed()) {
+						//TODO language and direction
+						int /*long*/ attrPtr;
+						attrPtr = OS.g_malloc(AtkAttribute.sizeof);
+						attr.name = ATK.g_strdup (ATK.atk_text_attribute_get_name(ATK.ATK_TEXT_ATTR_FAMILY_NAME));
+						attr.value = ATK.g_strdup (OS.pango_font_description_get_family (font.handle));
+						ATK.memmove(attrPtr, attr, AtkAttribute.sizeof);
+						result = OS.g_list_append(result, attrPtr);
+						
+						attrPtr = OS.g_malloc(AtkAttribute.sizeof);
+						attr.name = ATK.g_strdup (ATK.atk_text_attribute_get_name(ATK.ATK_TEXT_ATTR_SIZE));
+						attr.value = getStringPtr (String.valueOf (OS.pango_font_description_get_size(font.handle) / OS.PANGO_SCALE));
+						ATK.memmove(attrPtr, attr, AtkAttribute.sizeof);
+						result = OS.g_list_append(result, attrPtr);
+						
+						attrPtr = OS.g_malloc(AtkAttribute.sizeof);
+						attr.name = ATK.g_strdup (ATK.atk_text_attribute_get_name(ATK.ATK_TEXT_ATTR_STYLE));
+						attr.value = ATK.g_strdup (ATK.atk_text_attribute_get_value(ATK.ATK_TEXT_ATTR_STYLE, OS.pango_font_description_get_style(font.handle)));
+						ATK.memmove(attrPtr, attr, AtkAttribute.sizeof);
+						result = OS.g_list_append(result, attrPtr);
+						
+						attrPtr = OS.g_malloc(AtkAttribute.sizeof);
+						attr.name = ATK.g_strdup (ATK.atk_text_attribute_get_name(ATK.ATK_TEXT_ATTR_VARIANT));
+						attr.value = ATK.g_strdup (ATK.atk_text_attribute_get_value(ATK.ATK_TEXT_ATTR_VARIANT, OS.pango_font_description_get_variant(font.handle)));
+						ATK.memmove(attrPtr, attr, AtkAttribute.sizeof);
+						result = OS.g_list_append(result, attrPtr);
+						
+						attrPtr = OS.g_malloc(AtkAttribute.sizeof);
+						attr.name = ATK.g_strdup (ATK.atk_text_attribute_get_name(ATK.ATK_TEXT_ATTR_STRETCH));
+						attr.value = ATK.g_strdup (ATK.atk_text_attribute_get_value(ATK.ATK_TEXT_ATTR_STRETCH, OS.pango_font_description_get_stretch(font.handle)));
+						ATK.memmove(attrPtr, attr, AtkAttribute.sizeof);
+						result = OS.g_list_append(result, attrPtr);
+						
+						attrPtr = OS.g_malloc(AtkAttribute.sizeof);
+						attr.name = ATK.g_strdup (ATK.atk_text_attribute_get_name(ATK.ATK_TEXT_ATTR_WEIGHT));
+						attr.value = getStringPtr (String.valueOf (OS.pango_font_description_get_weight(font.handle)));
+						ATK.memmove(attrPtr, attr, AtkAttribute.sizeof);
+						result = OS.g_list_append(result, attrPtr);
+					}
+					Color color = style.foreground;
+					if (color != null && !color.isDisposed()) {
+						int /*long*/ attrPtr = OS.g_malloc(AtkAttribute.sizeof);
+						attr.name = ATK.g_strdup (ATK.atk_text_attribute_get_name(ATK.ATK_TEXT_ATTR_FG_COLOR));
+						attr.value = getStringPtr ((color.handle.red & 0xFFFF) + "," + (color.handle.blue & 0xFFFF) + "," + (color.handle.blue & 0xFFFF)); //$NON-NLS-1$ //$NON-NLS-2$
+						ATK.memmove(attrPtr, attr, AtkAttribute.sizeof);
+						result = OS.g_list_append(result, attrPtr);
+					}
+					color = style.background;
+					if (color != null && !color.isDisposed()) {
+						int /*long*/ attrPtr = OS.g_malloc(AtkAttribute.sizeof);
+						attr.name = ATK.g_strdup (ATK.atk_text_attribute_get_name(ATK.ATK_TEXT_ATTR_BG_COLOR));
+						attr.value = getStringPtr ((color.handle.red & 0xFFFF) + "," + (color.handle.blue & 0xFFFF) + "," + (color.handle.blue & 0xFFFF)); //$NON-NLS-1$ //$NON-NLS-2$
+						ATK.memmove(attrPtr, attr, AtkAttribute.sizeof);
+						result = OS.g_list_append(result, attrPtr);
+					}
+				}
+				if (event.attributes != null) {
+					int end = event.attributes.length / 2 * 2;
+					for (int i = 0; i < end; i+= 2) {
+						int /*long*/ attrPtr = OS.g_malloc(AtkAttribute.sizeof);
+						attr.name = getStringPtr (event.attributes[i]);
+						attr.value = getStringPtr (event.attributes[i + 1]);
+						ATK.memmove(attrPtr, attr, AtkAttribute.sizeof);
+						result = OS.g_list_append(result, attrPtr);
+					}
+				}
+				return result;
+			}
+		}
+		int /*long*/ parentResult = 0;
+		AtkTextIface iface = getTextIface (atkObject);
+		if (iface != null && iface.get_run_attributes != 0) {
+			parentResult = ATK.call (iface.get_run_attributes, atkObject, offset, start_offset, end_offset);
+		}
+		return parentResult;
+	}
+
+	static int /*long*/ atkText_get_offset_at_point (int /*long*/ atkObject, int /*long*/ x, int /*long*/ y, int /*long*/ coords) {
+		if (DEBUG) print ("-->atkText_get_offset_at_point");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTextExtendedListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTextEvent event = new AccessibleTextEvent(accessible);
+				event.x = (int)/*64*/x;
+				event.y = (int)/*64*/y;
+				int[] topWindowX = new int [1], topWindowY = new int [1];
+				if (coords == ATK.ATK_XY_WINDOW) {
+					windowPoint (object, topWindowX, topWindowY);
+					event.x += topWindowX [0];
+					event.y += topWindowY [0]; 
+				}
+				for (int i = 0; i < length; i++) {
+					AccessibleTextExtendedListener listener = (AccessibleTextExtendedListener) listeners.elementAt(i);
+					listener.getOffsetAtPoint(event);
+				}
+				return event.offset;
+			}
+		}
+		int /*long*/ parentResult = 0;
+		AtkTextIface iface = getTextIface (atkObject);
+		if (iface != null && iface.get_offset_at_point != 0) {
+			parentResult = ATK.call (iface.get_offset_at_point, atkObject, x, y, coords);
+		}
+		return parentResult;
+	}
+
+	static int /*long*/ atkText_add_selection (int /*long*/ atkObject, int /*long*/ start_offset, int /*long*/ end_offset) {
+		if (DEBUG) print ("-->atkText_add_selection");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTextExtendedListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTextEvent event = new AccessibleTextEvent(accessible);
+				event.start = (int)/*64*/start_offset;
+				event.end = (int)/*64*/end_offset;
+				for (int i = 0; i < length; i++) {
+					AccessibleTextExtendedListener listener = (AccessibleTextExtendedListener) listeners.elementAt(i);
+					listener.addSelection(event);
+				}
+				return ACC.OK.equals(event.result) ? 1 : 0;
+			}
+		}
+		int /*long*/ parentResult = 0;
+		AtkTextIface iface = getTextIface (atkObject);
+		if (iface != null && iface.add_selection != 0) {
+			parentResult = ATK.call (iface.add_selection, atkObject, start_offset, end_offset);
+		}
+		return parentResult;
+	}
+
+	static int /*long*/ atkText_remove_selection (int /*long*/ atkObject, int /*long*/ selection_num) {
+		if (DEBUG) print ("-->atkText_remove_selection");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTextExtendedListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTextEvent event = new AccessibleTextEvent(accessible);
+				event.index = (int)/*64*/selection_num;
+				for (int i = 0; i < length; i++) {
+					AccessibleTextExtendedListener listener = (AccessibleTextExtendedListener) listeners.elementAt(i);
+					listener.removeSelection(event);
+				}
+				return ACC.OK.equals(event.result) ? 1 : 0;
+			}
+		}
+		int /*long*/ parentResult = 0;
+		AtkTextIface iface = getTextIface (atkObject);
+		if (iface != null && iface.remove_selection != 0) {
+			parentResult = ATK.call (iface.remove_selection, atkObject, selection_num);
+		}
+		return parentResult;
+	}
+	
+	static int /*long*/ atkText_set_caret_offset (int /*long*/ atkObject, int /*long*/ offset) {
+		if (DEBUG) print ("-->atkText_set_caret_offset");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTextExtendedListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTextEvent event = new AccessibleTextEvent(accessible);
+				event.offset = (int)/*64*/offset;
+				for (int i = 0; i < length; i++) {
+					AccessibleTextExtendedListener listener = (AccessibleTextExtendedListener) listeners.elementAt(i);
+					listener.setCaretOffset(event);
+				}
+				return ACC.OK.equals(event.result) ? 1 : 0;
+			}
+		}
+		AtkTextIface iface = getTextIface (atkObject);
+		if (iface != null && iface.set_caret_offset != 0) {
+			return ATK.call (iface.set_caret_offset, atkObject, offset);
+		}
+		return 0;
+	}
+
+	static int /*long*/ atkText_set_selection (int /*long*/ atkObject, int /*long*/ selection_num, int /*long*/ start_offset, int /*long*/ end_offset) {
+		if (DEBUG) print ("-->atkText_set_selection");
 		AccessibleObject object = getAccessibleObject (atkObject);
-		if (object == null) return 0;
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTextExtendedListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTextEvent event = new AccessibleTextEvent(accessible);
+				event.index = (int)/*64*/selection_num;
+				event.start = (int)/*64*/start_offset;
+				event.end = (int)/*64*/end_offset;
+				for (int i = 0; i < length; i++) {
+					AccessibleTextExtendedListener listener = (AccessibleTextExtendedListener) listeners.elementAt(i);
+					listener.setSelection(event);
+				}
+				return ACC.OK.equals(event.result) ? 1 : 0;
+			}
+		}
 		int /*long*/ parentResult = 0;
-		if (ATK.g_type_is_a (object.parentType, ATK_SELECTION_TYPE)) {
-			int /*long*/ superType = ATK.g_type_interface_peek_parent (ATK.ATK_SELECTION_GET_IFACE (object.handle));
-			AtkSelectionIface selectionIface = new AtkSelectionIface ();
-			ATK.memmove (selectionIface, superType);
-			if (selectionIface.ref_selection != 0) {
-				parentResult = ATK.call (selectionIface.ref_selection, object.handle, index);
-			}
-		}
-		AccessibleControlListener[] listeners = object.getControlListeners ();
-		if (listeners.length == 0) return parentResult;
-			
-		AccessibleControlEvent event = new AccessibleControlEvent (object.accessible);
-		event.childID = object.id;
-		for (int i = 0; i < listeners.length; i++) {
-			listeners [i].getSelection (event);
-		} 
-		AccessibleObject accObj = object.getChildByID (event.childID);
-		if (accObj != null) {
-			if (parentResult > 0) OS.g_object_unref (parentResult);
-			OS.g_object_ref (accObj.handle);	
-			return accObj.handle;
+		AtkTextIface iface = getTextIface (atkObject);
+		if (iface != null && iface.set_selection != 0) {
+			parentResult = ATK.call (iface.set_selection, atkObject, selection_num, start_offset, end_offset);
 		}
 		return parentResult;
 	}
 
 	static int /*long*/ atkText_get_caret_offset (int /*long*/ atkObject) {
-		if (DEBUG) System.out.println ("-->atkText_get_caret_offset");
+		if (DEBUG) print ("-->atkText_get_caret_offset");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		int /*long*/ parentResult = 0;
+		AtkTextIface iface = getTextIface (atkObject);
+		if (iface != null && iface.get_caret_offset != 0) {
+			parentResult = ATK.call (iface.get_caret_offset, atkObject);
+		}
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTextExtendedListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTextEvent event = new AccessibleTextEvent(accessible);
+				for (int i = 0; i < length; i++) {
+					AccessibleTextExtendedListener listener = (AccessibleTextExtendedListener) listeners.elementAt(i);
+					listener.getCaretOffset (event);
+				}
+				return event.offset;
+			}
+			listeners = accessible.accessibleTextListeners;
+			length = listeners.size();
+			if (length > 0) {
+				AccessibleTextEvent event = new AccessibleTextEvent (object.accessible);
+				event.childID = object.id;
+				event.offset = (int)/*64*/parentResult;
+				for (int i = 0; i < length; i++) {
+					AccessibleTextListener listener = (AccessibleTextListener) listeners.elementAt(i);
+					listener.getCaretOffset (event);	
+				}
+				return event.offset;
+			}
+		}
+		return parentResult; 	
+	}
+	
+	static int /*long*/ atkText_get_bounded_ranges (int /*long*/ atkObject, int /*long*/ rect, int /*long*/ coord_type, int /*long*/ x_clip_type, int /*long*/ y_clip_type) {
+		if (DEBUG) print ("-->atkText_get_bounded_ranges");
 		AccessibleObject object = getAccessibleObject (atkObject);
-		if (object == null) return 0;
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTextExtendedListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTextEvent event = new AccessibleTextEvent(accessible);
+				AtkTextRectangle atkRect = new AtkTextRectangle();
+				ATK.memmove (atkRect, rect, AtkTextRectangle.sizeof);
+				event.x = atkRect.x;
+				event.y = atkRect.y;
+				event.width = atkRect.width;
+				event.height = atkRect.height;
+				for (int i = 0; i < length; i++) {
+					AccessibleTextExtendedListener listener = (AccessibleTextExtendedListener) listeners.elementAt(i);
+					listener.getRanges (event);
+				}
+				int [] ranges = event.ranges;
+				int size = ranges == null ? 1 : ranges.length / 2;
+				int /*long*/ result = OS.malloc(size * AtkTextRange.sizeof);
+				AtkTextRange range = new AtkTextRange();
+				for (int j = 0, end = (ranges != null ? ranges.length / 2 : 1); j < end; j++) {
+					if (ranges != null) {
+						int index = j * 2;
+						event.start = ranges[index];
+						event.end = ranges[index+1];
+					}
+					event.count = 0;
+					event.type = ACC.TEXT_BOUNDARY_ALL;
+					for (int i = 0; i < length; i++) {
+						AccessibleTextExtendedListener listener = (AccessibleTextExtendedListener) listeners.elementAt(i);
+						listener.getText(event);
+					}
+					range.start_offset = event.start;
+					range.end_offset = event.end;
+					range.content = getStringPtr (event.result);
+					event.result = null;
+					event.count = event.type = event.x = event.y = event.width = event.height = 0;
+					for (int i = 0; i < length; i++) {
+						AccessibleTextExtendedListener listener = (AccessibleTextExtendedListener) listeners.elementAt(i);
+						listener.getTextBounds(event);
+					}
+					range.bounds.x = event.x;
+					range.bounds.y = event.y;
+					range.bounds.width = event.width;
+					range.bounds.height = event.height;
+					ATK.memmove(result + j * AtkTextRange.sizeof, range, AtkTextRange.sizeof);
+				}
+				return result;
+			}
+		}
 		int /*long*/ parentResult = 0;
-		if (ATK.g_type_is_a (object.parentType, ATK_TEXT_TYPE)) {
-			int /*long*/ superType = ATK.g_type_interface_peek_parent (ATK.ATK_TEXT_GET_IFACE (object.handle));
-			AtkTextIface textIface = new AtkTextIface ();
-			ATK.memmove (textIface, superType);
-			if (textIface.get_caret_offset != 0) {
-				parentResult = ATK.call (textIface.get_caret_offset, object.handle);
-			}
-		}
-		AccessibleTextListener[] listeners = object.getTextListeners ();
-		if (listeners.length == 0) return parentResult;
-		
-		AccessibleTextEvent event = new AccessibleTextEvent (object.accessible);
-		event.childID = object.id;
-		event.offset = (int)/*64*/parentResult;
-		for (int i = 0; i < listeners.length; i++) {
-			listeners [i].getCaretOffset (event);	
-		} 
-		return event.offset; 	
+		AtkTextIface iface = getTextIface (atkObject);
+		if (iface != null && iface.get_bounded_ranges != 0) {
+			parentResult = ATK.call (iface.get_bounded_ranges, atkObject);
+		}
+		return parentResult;
 	}
 	
 	static int /*long*/ atkText_get_character_at_offset (int /*long*/ atkObject, int /*long*/ offset) {
-		if (DEBUG) System.out.println ("-->atkText_get_character_at_offset");
+		if (DEBUG) print ("-->atkText_get_character_at_offset");
 		AccessibleObject object = getAccessibleObject (atkObject);
-		if (object == null) return 0;
-		String text = object.getText ();
-		if (text != null) return text.charAt ((int)/*64*/offset); // TODO
-		if (ATK.g_type_is_a (object.parentType, ATK_TEXT_TYPE)) {
-			int /*long*/ superType = ATK.g_type_class_peek (object.parentType);
-			AtkTextIface textIface = new AtkTextIface ();
-			ATK.memmove (textIface, superType);
-			if (textIface.get_character_at_offset != 0) {
-				return ATK.call (textIface.get_character_at_offset, object.handle, offset);
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTextExtendedListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTextEvent event = new AccessibleTextEvent(accessible);
+				event.start = (int)/*64*/offset;
+				event.end = (int)/*64*/(offset + 1);
+				event.type = ACC.TEXT_BOUNDARY_CHAR;
+				for (int i = 0; i < length; i++) {
+					AccessibleTextExtendedListener listener = (AccessibleTextExtendedListener) listeners.elementAt(i);
+					listener.getText(event);
+				}
+				String text = event.result;
+				return text != null && text.length() > 0 ? text.charAt(0) : 0;
 			}
+			String text = object.getText ();
+			if (text != null && text.length() > offset) return text.charAt ((int)/*64*/offset);
+		}
+		AtkTextIface iface = getTextIface (atkObject);
+		if (iface != null && iface.get_character_at_offset != 0) {
+			return ATK.call (iface.get_character_at_offset, atkObject, offset);
 		}
 		return 0;
 	}
 
 	static int /*long*/ atkText_get_character_count (int /*long*/ atkObject) {
-		if (DEBUG) System.out.println ("-->atkText_get_character_count");
+		if (DEBUG) print ("-->atkText_get_character_count");
 		AccessibleObject object = getAccessibleObject (atkObject);
-		if (object == null) return 0;
-		String text = object.getText ();
-		if (text != null) return text.length ();
-		if (ATK.g_type_is_a (object.parentType, ATK_TEXT_TYPE)) {
-			int /*long*/ superType = ATK.g_type_class_peek (object.parentType);
-			AtkTextIface textIface = new AtkTextIface ();
-			ATK.memmove (textIface, superType);
-			if (textIface.get_character_count != 0) {
-				return ATK.call (textIface.get_character_count, object.handle);
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTextExtendedListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTextEvent event = new AccessibleTextEvent(accessible);
+				for (int i = 0; i < length; i++) {
+					AccessibleTextExtendedListener listener = (AccessibleTextExtendedListener) listeners.elementAt(i);
+					listener.getCharacterCount(event);
+				}
+				return event.count;
 			}
+			String text = object.getText ();
+			if (text != null) return text.length ();
+		}
+		AtkTextIface iface = getTextIface (atkObject);
+		if (iface != null && iface.get_character_count != 0) {
+			return ATK.call (iface.get_character_count, atkObject);
 		}
 		return 0;
 	}
 
 	static int /*long*/ atkText_get_n_selections (int /*long*/ atkObject) {
-		if (DEBUG) System.out.println ("-->atkText_get_n_selections");
+		if (DEBUG) print ("-->atkText_get_n_selections");
 		AccessibleObject object = getAccessibleObject (atkObject);
-		if (object == null) return 0;
-		int /*long*/ parentResult = 0;
-		if (ATK.g_type_is_a (object.parentType, ATK_TEXT_TYPE)) {
-			int /*long*/ superType = ATK.g_type_interface_peek_parent (ATK.ATK_TEXT_GET_IFACE (object.handle));
-			AtkTextIface textIface = new AtkTextIface ();
-			ATK.memmove (textIface, superType);
-			if (textIface.get_n_selections != 0) {
-				parentResult = ATK.call (textIface.get_n_selections, object.handle);
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTextExtendedListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTextEvent event = new AccessibleTextEvent(accessible);
+				for (int i = 0; i < length; i++) {
+					AccessibleTextExtendedListener listener = (AccessibleTextExtendedListener) listeners.elementAt(i);
+					listener.getSelectionCount (event);
+				}
+				return event.count;
+			}
+			listeners = accessible.accessibleTextListeners;
+			length = listeners.size();
+			if (length > 0) {
+				AccessibleTextEvent event = new AccessibleTextEvent (object.accessible);
+				event.childID = object.id;
+				for (int i = 0; i < length; i++) {
+					AccessibleTextListener listener = (AccessibleTextListener) listeners.elementAt(i);
+					listener.getSelectionRange (event);
+				}
+				if (event.length > 0) return 1;
 			}
 		}
-		AccessibleTextListener[] listeners = object.getTextListeners ();
-		if (listeners.length == 0) return parentResult;
-
-		AccessibleTextEvent event = new AccessibleTextEvent (object.accessible);
-		event.childID = object.id;
-		for (int i = 0; i < listeners.length; i++) {
-			listeners [i].getSelectionRange (event);
+		int /*long*/ parentResult = 0;
+		AtkTextIface iface = getTextIface (atkObject);
+		if (iface != null && iface.get_n_selections != 0) {
+			parentResult = ATK.call (iface.get_n_selections, atkObject);
 		}
-		return event.length == 0 ? parentResult : 1;
+		return parentResult;
 	}
 
 	static int /*long*/ atkText_get_selection (int /*long*/ atkObject, int /*long*/ selection_num, int /*long*/ start_offset, int /*long*/ end_offset) {
-		if (DEBUG) System.out.println ("-->atkText_get_selection");
+		if (DEBUG) print ("-->atkText_get_selection");
 		AccessibleObject object = getAccessibleObject (atkObject);
-		if (object == null) return 0;
+		int /*long*/ parentResult = 0;
 		OS.memmove (start_offset, new int[] {0}, 4);
 		OS.memmove (end_offset, new int[] {0}, 4);
-		if (ATK.g_type_is_a (object.parentType, ATK_TEXT_TYPE)) {
-			int /*long*/ superType = ATK.g_type_interface_peek_parent (ATK.ATK_TEXT_GET_IFACE (object.handle));
-			AtkTextIface textIface = new AtkTextIface ();
-			ATK.memmove (textIface, superType);
-			if (textIface.get_selection != 0) {
-				ATK.call (textIface.get_selection, object.handle, selection_num, start_offset, end_offset);
-			}
-		}
-		AccessibleTextListener[] listeners = object.getTextListeners ();
-		if (listeners.length == 0) return 0;
-
-		AccessibleTextEvent event = new AccessibleTextEvent (object.accessible);
-		event.childID = object.id;
-		int[] parentStart = new int [1];
-		int[] parentEnd = new int [1];
-		OS.memmove (parentStart, start_offset, 4);
-		OS.memmove (parentEnd, end_offset, 4);
-		event.offset = parentStart [0];
-		event.length = parentEnd [0] - parentStart [0];
-		for (int i = 0; i < listeners.length; i++) {
-			listeners [i].getSelectionRange (event);
-		}
-		OS.memmove (start_offset, new int[] {event.offset}, 4);
-		OS.memmove (end_offset, new int[] {event.offset + event.length}, 4);
-		return 0;
+		AtkTextIface iface = getTextIface (atkObject);
+		if (iface != null && iface.get_selection != 0) {
+			parentResult = ATK.call (iface.get_selection, atkObject, selection_num, start_offset, end_offset);
+		}
+		if (object != null) {
+			int[] parentStart = new int [1];
+			int[] parentEnd = new int [1];
+			OS.memmove (parentStart, start_offset, 4);
+			OS.memmove (parentEnd, end_offset, 4);
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTextExtendedListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTextEvent event = new AccessibleTextEvent(accessible);
+				event.index = (int)/*64*/selection_num;
+				event.start = parentStart[0];
+				event.end = parentEnd[0];
+				for (int i = 0; i < length; i++) {
+					AccessibleTextExtendedListener listener = (AccessibleTextExtendedListener) listeners.elementAt(i);
+					listener.getSelection (event);
+				}
+				parentStart [0] = event.start;
+				parentEnd [0] = event.end;
+				OS.memmove (start_offset, parentStart, 4);
+				OS.memmove (end_offset, parentEnd, 4);
+				event.count = event.index = 0;
+				event.type = ACC.TEXT_BOUNDARY_ALL;
+				for (int i = 0; i < length; i++) {
+					AccessibleTextExtendedListener listener = (AccessibleTextExtendedListener) listeners.elementAt(i);
+					listener.getText(event);
+				}
+				if (parentResult != 0) OS.g_free(parentResult);
+				return getStringPtr (event.result);
+			}
+			if (selection_num == 0) {
+				listeners = accessible.accessibleTextListeners;
+				length = listeners.size();
+				if (length > 0) {
+					AccessibleTextEvent event = new AccessibleTextEvent (accessible);
+					event.childID = object.id;
+					event.offset = parentStart [0];
+					event.length = parentEnd [0] - parentStart [0];
+					for (int i = 0; i < length; i++) {
+						AccessibleTextListener listener = (AccessibleTextListener) listeners.elementAt(i);
+						listener.getSelectionRange (event);
+					}
+					OS.memmove (start_offset, new int[] {event.offset}, 4);
+					OS.memmove (end_offset, new int[] {event.offset + event.length}, 4);
+					if (parentResult != 0) OS.g_free(parentResult);
+					String text = object.getText();
+					if (text != null && text.length () > event.offset && text.length() >= event.offset + event.length) {
+						return getStringPtr (text.substring(event.offset, event.offset + event.length));
+					}
+					if (iface != null && iface.get_text != 0) {
+						return ATK.call (iface.get_text, atkObject, event.offset, event.offset + event.length);
+					}
+					return 0;
+				}
+			}
+		}
+		return parentResult;
 	}
 
 	static int /*long*/ atkText_get_text (int /*long*/ atkObject, int /*long*/ start_offset, int /*long*/ end_offset) {
-		if (DEBUG) System.out.println ("-->atkText_get_text: " + start_offset + "," + end_offset);
-		AccessibleObject object = getAccessibleObject (atkObject);
-		if (object == null) return 0;
-		String text = object.getText ();
-		if (text.length () > 0) {
-			if (end_offset == -1) {
-				end_offset = text.length ();
-			} else {
-				end_offset = Math.min (end_offset, text.length ());	
-			}
-			start_offset = Math.min (start_offset, end_offset);
-			text = text.substring ((int)/*64*/start_offset, (int)/*64*/end_offset);
-			byte[] bytes = Converter.wcsToMbcs (null, text, true);
-			int /*long*/ result = OS.g_malloc (bytes.length);
-			OS.memmove (result, bytes, bytes.length);
-			return result;
+		if (DEBUG) print ("-->atkText_get_text: " + atkObject + " " + start_offset + "," + end_offset);
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTextExtendedListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleTextEvent event = new AccessibleTextEvent(accessible);
+				event.start = (int)/*64*/start_offset;
+				event.end = (int)/*64*/end_offset;
+				event.type = ACC.TEXT_BOUNDARY_ALL;
+				for (int i = 0; i < length; i++) {
+					AccessibleTextExtendedListener listener = (AccessibleTextExtendedListener) listeners.elementAt(i);
+					listener.getText(event);
+				}
+				return getStringPtr (event.result);
+			}
+			String text = object.getText ();
+			if (text != null && text.length () > 0) {
+				if (end_offset == -1) {
+					end_offset = text.length ();
+				} else {
+					end_offset = Math.min (end_offset, text.length ());	
+				}
+				start_offset = Math.min (start_offset, end_offset);
+				text = text.substring ((int)/*64*/start_offset, (int)/*64*/end_offset);
+				return getStringPtr (text);
+			}
+		}
+		AtkTextIface iface = getTextIface (atkObject);
+		if (iface != null && iface.get_text != 0) {
+			return ATK.call (iface.get_text, atkObject, start_offset, end_offset);
 		}
 		return 0;
 	}
 
 	static int /*long*/ atkText_get_text_after_offset (int /*long*/ atkObject, int /*long*/ offset_value, int /*long*/ boundary_type, int /*long*/ start_offset, int /*long*/ end_offset) {
-		if (DEBUG) System.out.println ("-->atkText_get_text_after_offset");
-		AccessibleObject object = getAccessibleObject (atkObject);
-		if (object == null) return 0;
-		int offset = (int)/*64*/offset_value;
-		String text = object.getText ();
-		if (text.length () > 0) {
-			int length = text.length ();
-			offset = Math.min (offset, length - 1);
-			int startBounds = offset;
-			int endBounds = offset;
-			switch ((int)/*64*/boundary_type) {
-				case ATK.ATK_TEXT_BOUNDARY_CHAR: {
-					if (length > offset) endBounds++;
-					break;
-				}
-				case ATK.ATK_TEXT_BOUNDARY_WORD_START: {
-					int wordStart1 = nextIndexOfChar (text, " !?.\n", offset - 1);
-					if (wordStart1 == -1) {
-						startBounds = endBounds = length;
-						break;
-					}
-					wordStart1 = nextIndexOfNotChar (text, " !?.\n", wordStart1);
-					if (wordStart1 == length) {
-						startBounds = endBounds = length;
-						break;
-					}
-					startBounds = wordStart1;
-					int wordStart2 = nextIndexOfChar (text, " !?.\n", wordStart1);
-					if (wordStart2 == -1) {
-						endBounds = length;
-						break;
-					}
-					endBounds = nextIndexOfNotChar (text, " !?.\n", wordStart2);
-					break;
+		if (DEBUG) print ("-->atkText_get_text_after_offset");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTextExtendedListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				int /*long*/ charCount = atkText_get_character_count (atkObject);
+				AccessibleTextEvent event = new AccessibleTextEvent(accessible);
+				event.start = event.end = (int)/*64*/offset_value;
+				event.count = 1;
+				switch ((int)/*64*/boundary_type) {
+					case ATK.ATK_TEXT_BOUNDARY_CHAR: event.type = ACC.TEXT_BOUNDARY_CHAR; break; 
+					case ATK.ATK_TEXT_BOUNDARY_WORD_START: event.type = ACC.TEXT_BOUNDARY_WORD; break; 
+					case ATK.ATK_TEXT_BOUNDARY_WORD_END: event.type = ACC.TEXT_BOUNDARY_WORD; break; 
+					case ATK.ATK_TEXT_BOUNDARY_SENTENCE_START: event.type = ACC.TEXT_BOUNDARY_SENTENCE; break; 
+					case ATK.ATK_TEXT_BOUNDARY_SENTENCE_END: event.type = ACC.TEXT_BOUNDARY_SENTENCE; break; 
+					case ATK.ATK_TEXT_BOUNDARY_LINE_START: event.type = ACC.TEXT_BOUNDARY_LINE; break; 
+					case ATK.ATK_TEXT_BOUNDARY_LINE_END: event.type = ACC.TEXT_BOUNDARY_LINE; break; 
 				}
-				case ATK.ATK_TEXT_BOUNDARY_WORD_END: {
-					int previousWordEnd = previousIndexOfNotChar (text, " \n", offset); 
-					if (previousWordEnd == -1 || previousWordEnd != offset - 1) {
-						offset = nextIndexOfNotChar (text, " \n", offset);
-					}
-					if (offset == -1) {
-						startBounds = endBounds = length;
-						break;
-					}
-					int wordEnd1 = nextIndexOfChar (text, " !?.\n", (int)/*64*/offset);
-					if (wordEnd1 == -1) {
-						startBounds = endBounds = length;
-						break;
-					}
-					wordEnd1 = nextIndexOfNotChar (text, "!?.", wordEnd1);
-					if (wordEnd1 == length) {
-						startBounds = endBounds = length;
+				int eventStart = event.start;
+				int eventEnd = event.end;
+				for (int i = 0; i < length; i++) {
+					AccessibleTextExtendedListener listener = (AccessibleTextExtendedListener) listeners.elementAt(i);
+					listener.getText(event);
+				}
+				switch ((int)/*64*/boundary_type) {
+					case ATK.ATK_TEXT_BOUNDARY_WORD_START: 
+					case ATK.ATK_TEXT_BOUNDARY_SENTENCE_START: 
+					case ATK.ATK_TEXT_BOUNDARY_LINE_START:
+						if (event.end < charCount) {
+							int start = event.start;
+							event.start = eventStart;
+							event.end = eventEnd;
+							event.count = 2;
+							for (int i = 0; i < length; i++) {
+								AccessibleTextExtendedListener listener = (AccessibleTextExtendedListener) listeners.elementAt(i);
+								listener.getText(event);
+							}
+							event.end = event.start;
+							event.start = start;
+							event.type = ACC.TEXT_BOUNDARY_ALL;
+							event.count = 0;
+							for (int i = 0; i < length; i++) {
+								AccessibleTextExtendedListener listener = (AccessibleTextExtendedListener) listeners.elementAt(i);
+								listener.getText(event);
+							}
+						}
 						break;
-					}
-					startBounds = wordEnd1;
-					int wordEnd2 = nextIndexOfNotChar (text, " \n", wordEnd1);
-					if (wordEnd2 == length) {
-						startBounds = endBounds = length;
+					case ATK.ATK_TEXT_BOUNDARY_WORD_END: 
+					case ATK.ATK_TEXT_BOUNDARY_SENTENCE_END: 
+					case ATK.ATK_TEXT_BOUNDARY_LINE_END:
+						if (0 < event.start) {
+							int end = event.end;
+							event.start = eventStart;
+							event.end = eventEnd;
+							event.count = 0;
+							for (int i = 0; i < length; i++) {
+								AccessibleTextExtendedListener listener = (AccessibleTextExtendedListener) listeners.elementAt(i);
+								listener.getText(event);
+							}
+							event.start = event.end;
+							event.end = end;
+							event.type = ACC.TEXT_BOUNDARY_ALL;
+							event.count = 0;
+							for (int i = 0; i < length; i++) {
+								AccessibleTextExtendedListener listener = (AccessibleTextExtendedListener) listeners.elementAt(i);
+								listener.getText(event);
+							}
+						}
 						break;
-					}
-					wordEnd2 = nextIndexOfChar (text, " !?.\n", wordEnd2);
-					if (wordEnd2 == -1) {
-						endBounds = length;
+				}
+				OS.memmove (start_offset, new int[] {event.start}, 4);
+				OS.memmove (end_offset, new int[] {event.end}, 4);
+				return getStringPtr (event.result);
+			}
+			int offset = (int)/*64*/offset_value;
+			String text = object.getText ();
+			if (text != null && text.length () > 0) {
+				length = text.length ();
+				offset = Math.min (offset, length - 1);
+				int startBounds = offset;
+				int endBounds = offset;
+				switch ((int)/*64*/boundary_type) {
+					case ATK.ATK_TEXT_BOUNDARY_CHAR: {
+						if (length > offset) endBounds++;
 						break;
 					}
-					endBounds = nextIndexOfNotChar (text, "!?.", wordEnd2);
-					break;
-				}
-				case ATK.ATK_TEXT_BOUNDARY_SENTENCE_START: {
-					int previousSentenceEnd = previousIndexOfChar (text, "!?.", offset);
-					int previousText = previousIndexOfNotChar (text, " !?.\n", offset);
-					int sentenceStart1 = 0;
-					if (previousSentenceEnd >= previousText) {
-						sentenceStart1 = nextIndexOfNotChar (text, " !?.\n", offset);
-					} else {
-						sentenceStart1 = nextIndexOfChar (text, "!?.", offset);
-						if (sentenceStart1 == -1) {
+					case ATK.ATK_TEXT_BOUNDARY_WORD_START: {
+						int wordStart1 = nextIndexOfChar (text, " !?.\n", offset - 1);
+						if (wordStart1 == -1) {
 							startBounds = endBounds = length;
 							break;
 						}
-						sentenceStart1 = nextIndexOfNotChar (text, " !?.\n", sentenceStart1);
-					}
-					if (sentenceStart1 == length) {
-						startBounds = endBounds = length;
+						wordStart1 = nextIndexOfNotChar (text, " !?.\n", wordStart1);
+						if (wordStart1 == length) {
+							startBounds = endBounds = length;
+							break;
+						}
+						startBounds = wordStart1;
+						int wordStart2 = nextIndexOfChar (text, " !?.\n", wordStart1);
+						if (wordStart2 == -1) {
+							endBounds = length;
+							break;
+						}
+						endBounds = nextIndexOfNotChar (text, " !?.\n", wordStart2);
 						break;
 					}
-					startBounds = sentenceStart1;
-					int sentenceStart2 = nextIndexOfChar (text, "!?.", sentenceStart1);
-					if (sentenceStart2 == -1) {
-						endBounds = length;
+					case ATK.ATK_TEXT_BOUNDARY_WORD_END: {
+						int previousWordEnd = previousIndexOfNotChar (text, " \n", offset); 
+						if (previousWordEnd == -1 || previousWordEnd != offset - 1) {
+							offset = nextIndexOfNotChar (text, " \n", offset);
+						}
+						if (offset == -1) {
+							startBounds = endBounds = length;
+							break;
+						}
+						int wordEnd1 = nextIndexOfChar (text, " !?.\n", (int)/*64*/offset);
+						if (wordEnd1 == -1) {
+							startBounds = endBounds = length;
+							break;
+						}
+						wordEnd1 = nextIndexOfNotChar (text, "!?.", wordEnd1);
+						if (wordEnd1 == length) {
+							startBounds = endBounds = length;
+							break;
+						}
+						startBounds = wordEnd1;
+						int wordEnd2 = nextIndexOfNotChar (text, " \n", wordEnd1);
+						if (wordEnd2 == length) {
+							startBounds = endBounds = length;
+							break;
+						}
+						wordEnd2 = nextIndexOfChar (text, " !?.\n", wordEnd2);
+						if (wordEnd2 == -1) {
+							endBounds = length;
+							break;
+						}
+						endBounds = nextIndexOfNotChar (text, "!?.", wordEnd2);
 						break;
 					}
-					endBounds = nextIndexOfNotChar (text, " !?.\n", sentenceStart2);
-					break;
-				}
-				case ATK.ATK_TEXT_BOUNDARY_SENTENCE_END: {
-					int sentenceEnd1 = nextIndexOfChar (text, "!?.", offset);
-					if (sentenceEnd1 == -1) {
-						startBounds = endBounds = length;
+					case ATK.ATK_TEXT_BOUNDARY_SENTENCE_START: {
+						int previousSentenceEnd = previousIndexOfChar (text, "!?.", offset);
+						int previousText = previousIndexOfNotChar (text, " !?.\n", offset);
+						int sentenceStart1 = 0;
+						if (previousSentenceEnd >= previousText) {
+							sentenceStart1 = nextIndexOfNotChar (text, " !?.\n", offset);
+						} else {
+							sentenceStart1 = nextIndexOfChar (text, "!?.", offset);
+							if (sentenceStart1 == -1) {
+								startBounds = endBounds = length;
+								break;
+							}
+							sentenceStart1 = nextIndexOfNotChar (text, " !?.\n", sentenceStart1);
+						}
+						if (sentenceStart1 == length) {
+							startBounds = endBounds = length;
+							break;
+						}
+						startBounds = sentenceStart1;
+						int sentenceStart2 = nextIndexOfChar (text, "!?.", sentenceStart1);
+						if (sentenceStart2 == -1) {
+							endBounds = length;
+							break;
+						}
+						endBounds = nextIndexOfNotChar (text, " !?.\n", sentenceStart2);
 						break;
 					}
-					sentenceEnd1 = nextIndexOfNotChar (text, "!?.", sentenceEnd1);
-					if (sentenceEnd1 == length) {
-						startBounds = endBounds = length;
+					case ATK.ATK_TEXT_BOUNDARY_SENTENCE_END: {
+						int sentenceEnd1 = nextIndexOfChar (text, "!?.", offset);
+						if (sentenceEnd1 == -1) {
+							startBounds = endBounds = length;
+							break;
+						}
+						sentenceEnd1 = nextIndexOfNotChar (text, "!?.", sentenceEnd1);
+						if (sentenceEnd1 == length) {
+							startBounds = endBounds = length;
+							break;
+						}
+						startBounds = sentenceEnd1;
+						int sentenceEnd2 = nextIndexOfNotChar (text, " \n", sentenceEnd1);
+						if (sentenceEnd2 == length) {
+							startBounds = endBounds = length;
+							break;
+						}
+						sentenceEnd2 = nextIndexOfChar (text, "!?.", sentenceEnd2);
+						if (sentenceEnd2 == -1) {
+							endBounds = length;
+							break;
+						}
+						endBounds = nextIndexOfNotChar (text, "!?.", sentenceEnd2);
 						break;
 					}
-					startBounds = sentenceEnd1;
-					int sentenceEnd2 = nextIndexOfNotChar (text, " \n", sentenceEnd1);
-					if (sentenceEnd2 == length) {
-						startBounds = endBounds = length;
+					case ATK.ATK_TEXT_BOUNDARY_LINE_START: {
+						int lineStart1 = text.indexOf ('\n', offset - 1);
+						if (lineStart1 == -1) {
+							startBounds = endBounds = length;
+							break;
+						}
+						lineStart1 = nextIndexOfNotChar (text, "\n", lineStart1);
+						if (lineStart1 == length) {
+							startBounds = endBounds = length;
+							break;
+						}
+						startBounds = lineStart1;
+						int lineStart2 = text.indexOf ('\n', lineStart1);
+						if (lineStart2 == -1) {
+							endBounds = length;
+							break;
+						}
+						lineStart2 = nextIndexOfNotChar (text, "\n", lineStart2);
+						endBounds = lineStart2;
 						break;
 					}
-					sentenceEnd2 = nextIndexOfChar (text, "!?.", sentenceEnd2);
-					if (sentenceEnd2 == -1) {
-						endBounds = length;
+					case ATK.ATK_TEXT_BOUNDARY_LINE_END: {
+						int lineEnd1 = nextIndexOfChar (text, "\n", offset);
+						if (lineEnd1 == -1) {
+							startBounds = endBounds = length;
+							break;
+						}
+						startBounds = lineEnd1;
+						if (startBounds == length) {
+							endBounds = length;
+							break;
+						}
+						int lineEnd2 = nextIndexOfChar (text, "\n", lineEnd1 + 1);
+						if (lineEnd2 == -1) {
+							endBounds = length;
+							break;
+						}
+						endBounds = lineEnd2;
 						break;
 					}
-					endBounds = nextIndexOfNotChar (text, "!?.", sentenceEnd2);
-					break;
 				}
-				case ATK.ATK_TEXT_BOUNDARY_LINE_START: {
-					int lineStart1 = text.indexOf ('\n', offset - 1);
-					if (lineStart1 == -1) {
-						startBounds = endBounds = length;
-						break;
-					}
-					lineStart1 = nextIndexOfNotChar (text, "\n", lineStart1);
-					if (lineStart1 == length) {
-						startBounds = endBounds = length;
-						break;
-					}
-					startBounds = lineStart1;
-					int lineStart2 = text.indexOf ('\n', lineStart1);
-					if (lineStart2 == -1) {
-						endBounds = length;
-						break;
-					}
-					lineStart2 = nextIndexOfNotChar (text, "\n", lineStart2);
-					endBounds = lineStart2;
-					break;
-				}
-				case ATK.ATK_TEXT_BOUNDARY_LINE_END: {
-					int lineEnd1 = nextIndexOfChar (text, "\n", offset);
-					if (lineEnd1 == -1) {
-						startBounds = endBounds = length;
-						break;
-					}
-					startBounds = lineEnd1;
-					if (startBounds == length) {
-						endBounds = length;
-						break;
-					}
-					int lineEnd2 = nextIndexOfChar (text, "\n", lineEnd1 + 1);
-					if (lineEnd2 == -1) {
-						endBounds = length;
-						break;
-					}
-					endBounds = lineEnd2;
-					break;
-				}
-			}
-			OS.memmove (start_offset, new int[] {startBounds}, 4);
-			OS.memmove (end_offset, new int[] {endBounds}, 4);
-			text = text.substring (startBounds, endBounds);
-			byte[] bytes = Converter.wcsToMbcs (null, text, true);
-			int /*long*/ result = OS.g_malloc (bytes.length);
-			OS.memmove (result, bytes, bytes.length);
-			return result;
-		} 
+				OS.memmove (start_offset, new int[] {startBounds}, 4);
+				OS.memmove (end_offset, new int[] {endBounds}, 4);
+				text = text.substring (startBounds, endBounds);
+				return getStringPtr (text);
+			} 
+		}
+		AtkTextIface iface = getTextIface (atkObject);
+		if (iface != null && iface.get_text_after_offset != 0) {
+			return ATK.call (iface.get_text_after_offset, atkObject, offset_value, boundary_type, start_offset, end_offset);
+		}
 		return 0;
 	}
 
 	static int /*long*/ atkText_get_text_at_offset (int /*long*/ atkObject, int /*long*/ offset_value, int /*long*/ boundary_type, int /*long*/ start_offset, int /*long*/ end_offset) {
-		if (DEBUG) System.out.println ("-->atkText_get_text_at_offset: " + offset_value + " start: " + start_offset + " end: " + end_offset);
-		AccessibleObject object = getAccessibleObject (atkObject);
-		if (object == null) return 0;
-		int offset = (int)/*64*/offset_value;
-		String text = object.getText ();
-		if (text.length () > 0) {
-			int length = text.length ();
-			offset = Math.min (offset, length - 1);
-			int startBounds = offset;
-			int endBounds = offset;
-			switch ((int)/*64*/boundary_type) {
-				case ATK.ATK_TEXT_BOUNDARY_CHAR: {
-					if (length > offset) endBounds++;
-					break;
-				}
-				case ATK.ATK_TEXT_BOUNDARY_WORD_START: {
-					int wordStart1 = previousIndexOfNotChar (text, " !?.\n", offset);
-					if (wordStart1 == -1) {
-						startBounds = endBounds = 0;
-						break;
-					}
-					wordStart1 = previousIndexOfChar (text, " !?.\n", wordStart1) + 1;
-					if (wordStart1 == -1) {
-						startBounds = 0;
+		if (DEBUG) print ("-->atkText_get_text_at_offset: " + offset_value + " start: " + start_offset + " end: " + end_offset);
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTextExtendedListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				int /*long*/ charCount = atkText_get_character_count (atkObject);
+				AccessibleTextEvent event = new AccessibleTextEvent(accessible);
+				event.start = event.end = (int)/*64*/offset_value;
+				event.count = 0;
+				switch ((int)/*64*/boundary_type) {
+					case ATK.ATK_TEXT_BOUNDARY_CHAR: event.type = ACC.TEXT_BOUNDARY_CHAR; break; 
+					case ATK.ATK_TEXT_BOUNDARY_WORD_START: event.type = ACC.TEXT_BOUNDARY_WORD; break; 
+					case ATK.ATK_TEXT_BOUNDARY_WORD_END: event.type = ACC.TEXT_BOUNDARY_WORD; break; 
+					case ATK.ATK_TEXT_BOUNDARY_SENTENCE_START: event.type = ACC.TEXT_BOUNDARY_SENTENCE; break; 
+					case ATK.ATK_TEXT_BOUNDARY_SENTENCE_END: event.type = ACC.TEXT_BOUNDARY_SENTENCE; break; 
+					case ATK.ATK_TEXT_BOUNDARY_LINE_START: event.type = ACC.TEXT_BOUNDARY_LINE; break; 
+					case ATK.ATK_TEXT_BOUNDARY_LINE_END: event.type = ACC.TEXT_BOUNDARY_LINE; break; 
+				}
+				int eventStart = event.start;
+				int eventEnd = event.end;
+				for (int i = 0; i < length; i++) {
+					AccessibleTextExtendedListener listener = (AccessibleTextExtendedListener) listeners.elementAt(i);
+					listener.getText(event);
+				}
+				switch ((int)/*64*/boundary_type) {
+					case ATK.ATK_TEXT_BOUNDARY_WORD_START: 
+					case ATK.ATK_TEXT_BOUNDARY_SENTENCE_START: 
+					case ATK.ATK_TEXT_BOUNDARY_LINE_START:
+						if (event.end < charCount) {
+							int start = event.start;
+							event.start = eventStart;
+							event.end = eventEnd;
+							event.count = 1;
+							for (int i = 0; i < length; i++) {
+								AccessibleTextExtendedListener listener = (AccessibleTextExtendedListener) listeners.elementAt(i);
+								listener.getText(event);
+							}
+							event.end = event.start;
+							event.start = start;
+							event.type = ACC.TEXT_BOUNDARY_ALL;
+							event.count = 0;
+							for (int i = 0; i < length; i++) {
+								AccessibleTextExtendedListener listener = (AccessibleTextExtendedListener) listeners.elementAt(i);
+								listener.getText(event);
+							}
+						}
 						break;
-					}
-					startBounds = wordStart1;
-					int wordStart2 = nextIndexOfChar (text, " !?.\n", wordStart1);
-					endBounds = nextIndexOfNotChar (text, " !?.\n", wordStart2);
-					break;
-				}
-				case ATK.ATK_TEXT_BOUNDARY_WORD_END: {
-					int wordEnd1 = previousIndexOfNotChar (text, "!?.", offset + 1);
-					wordEnd1 = previousIndexOfChar (text, " !?.\n", wordEnd1);
-					wordEnd1 = previousIndexOfNotChar (text, " \n", wordEnd1 + 1);
-					if (wordEnd1 == -1) {
-						startBounds = endBounds = 0;
+					case ATK.ATK_TEXT_BOUNDARY_WORD_END: 
+					case ATK.ATK_TEXT_BOUNDARY_SENTENCE_END: 
+					case ATK.ATK_TEXT_BOUNDARY_LINE_END:
+						if (0 < event.start) {
+							int end = event.end;
+							event.start = eventStart;
+							event.end = eventEnd;
+							event.count = -1;
+							for (int i = 0; i < length; i++) {
+								AccessibleTextExtendedListener listener = (AccessibleTextExtendedListener) listeners.elementAt(i);
+								listener.getText(event);
+							}
+							event.start = event.end;
+							event.end = end;
+							event.type = ACC.TEXT_BOUNDARY_ALL;
+							event.count = 0;
+							for (int i = 0; i < length; i++) {
+								AccessibleTextExtendedListener listener = (AccessibleTextExtendedListener) listeners.elementAt(i);
+								listener.getText(event);
+							}
+						}
 						break;
-					}
-					startBounds = wordEnd1 + 1;
-					int wordEnd2 = nextIndexOfNotChar (text, " \n", startBounds);
-					if (wordEnd2 == length) {
-						endBounds = startBounds;
+				}
+				OS.memmove (start_offset, new int[] {event.start}, 4);
+				OS.memmove (end_offset, new int[] {event.end}, 4);
+				return getStringPtr (event.result);
+			}
+			int offset = (int)/*64*/offset_value;
+			String text = object.getText ();
+			if (text != null && text.length () > 0) {
+				length = text.length ();
+				offset = Math.min (offset, length - 1);
+				int startBounds = offset;
+				int endBounds = offset;
+				switch ((int)/*64*/boundary_type) {
+					case ATK.ATK_TEXT_BOUNDARY_CHAR: {
+						if (length > offset) endBounds++;
 						break;
 					}
-					wordEnd2 = nextIndexOfChar (text, " !?.\n", wordEnd2);
-					if (wordEnd2 == -1) {
-						endBounds = startBounds;
+					case ATK.ATK_TEXT_BOUNDARY_WORD_START: {
+						int wordStart1 = previousIndexOfNotChar (text, " !?.\n", offset);
+						if (wordStart1 == -1) {
+							startBounds = endBounds = 0;
+							break;
+						}
+						wordStart1 = previousIndexOfChar (text, " !?.\n", wordStart1) + 1;
+						if (wordStart1 == -1) {
+							startBounds = 0;
+							break;
+						}
+						startBounds = wordStart1;
+						int wordStart2 = nextIndexOfChar (text, " !?.\n", wordStart1);
+						endBounds = nextIndexOfNotChar (text, " !?.\n", wordStart2);
 						break;
 					}
-					endBounds = nextIndexOfNotChar (text, "!?.", wordEnd2);
-					break;
-				}
-				case ATK.ATK_TEXT_BOUNDARY_SENTENCE_START: {
-					int sentenceStart1 = previousIndexOfNotChar (text, " !?.\n", offset + 1);
-					if (sentenceStart1 == -1) {
-						startBounds = endBounds = 0;
+					case ATK.ATK_TEXT_BOUNDARY_WORD_END: {
+						int wordEnd1 = previousIndexOfNotChar (text, "!?.", offset + 1);
+						wordEnd1 = previousIndexOfChar (text, " !?.\n", wordEnd1);
+						wordEnd1 = previousIndexOfNotChar (text, " \n", wordEnd1 + 1);
+						if (wordEnd1 == -1) {
+							startBounds = endBounds = 0;
+							break;
+						}
+						startBounds = wordEnd1 + 1;
+						int wordEnd2 = nextIndexOfNotChar (text, " \n", startBounds);
+						if (wordEnd2 == length) {
+							endBounds = startBounds;
+							break;
+						}
+						wordEnd2 = nextIndexOfChar (text, " !?.\n", wordEnd2);
+						if (wordEnd2 == -1) {
+							endBounds = startBounds;
+							break;
+						}
+						endBounds = nextIndexOfNotChar (text, "!?.", wordEnd2);
 						break;
 					}
-					sentenceStart1 = previousIndexOfChar (text, "!?.", sentenceStart1) + 1;
-					startBounds = nextIndexOfNotChar (text, " \n", sentenceStart1);
-					int sentenceStart2 = nextIndexOfChar (text, "!?.", startBounds);
-					endBounds = nextIndexOfNotChar (text, " !?.\n", sentenceStart2);
-					break;
-				}
-				case ATK.ATK_TEXT_BOUNDARY_SENTENCE_END: {
-					int sentenceEnd1 = previousIndexOfNotChar (text, "!?.", offset + 1);
-					sentenceEnd1 = previousIndexOfChar (text, "!?.", sentenceEnd1);
-					sentenceEnd1 = previousIndexOfNotChar (text, " \n", sentenceEnd1 + 1);
-					if (sentenceEnd1 == -1) {
-						startBounds = endBounds = 0;
+					case ATK.ATK_TEXT_BOUNDARY_SENTENCE_START: {
+						int sentenceStart1 = previousIndexOfNotChar (text, " !?.\n", offset + 1);
+						if (sentenceStart1 == -1) {
+							startBounds = endBounds = 0;
+							break;
+						}
+						sentenceStart1 = previousIndexOfChar (text, "!?.", sentenceStart1) + 1;
+						startBounds = nextIndexOfNotChar (text, " \n", sentenceStart1);
+						int sentenceStart2 = nextIndexOfChar (text, "!?.", startBounds);
+						endBounds = nextIndexOfNotChar (text, " !?.\n", sentenceStart2);
 						break;
 					}
-					startBounds = sentenceEnd1 + 1;
-					int sentenceEnd2 = nextIndexOfNotChar (text, " \n", startBounds);
-					if (sentenceEnd2 == length) {
-						endBounds = startBounds;
+					case ATK.ATK_TEXT_BOUNDARY_SENTENCE_END: {
+						int sentenceEnd1 = previousIndexOfNotChar (text, "!?.", offset + 1);
+						sentenceEnd1 = previousIndexOfChar (text, "!?.", sentenceEnd1);
+						sentenceEnd1 = previousIndexOfNotChar (text, " \n", sentenceEnd1 + 1);
+						if (sentenceEnd1 == -1) {
+							startBounds = endBounds = 0;
+							break;
+						}
+						startBounds = sentenceEnd1 + 1;
+						int sentenceEnd2 = nextIndexOfNotChar (text, " \n", startBounds);
+						if (sentenceEnd2 == length) {
+							endBounds = startBounds;
+							break;
+						}
+						sentenceEnd2 = nextIndexOfChar (text, "!?.", sentenceEnd2);
+						if (sentenceEnd2 == -1) {
+							endBounds = startBounds;
+							break;
+						}
+						endBounds = nextIndexOfNotChar (text, "!?.", sentenceEnd2);
 						break;
 					}
-					sentenceEnd2 = nextIndexOfChar (text, "!?.", sentenceEnd2);
-					if (sentenceEnd2 == -1) {
-						endBounds = startBounds;
+					case ATK.ATK_TEXT_BOUNDARY_LINE_START: {
+						startBounds = previousIndexOfChar (text, "\n", offset) + 1;
+						int lineEnd2 = nextIndexOfChar (text, "\n", startBounds);
+						if (lineEnd2 < length) lineEnd2++;
+						endBounds = lineEnd2;
 						break;
 					}
-					endBounds = nextIndexOfNotChar (text, "!?.", sentenceEnd2);
-					break;
-				}
-				case ATK.ATK_TEXT_BOUNDARY_LINE_START: {
-					startBounds = previousIndexOfChar (text, "\n", offset) + 1;
-					int lineEnd2 = nextIndexOfChar (text, "\n", startBounds);
-					if (lineEnd2 < length) lineEnd2++;
-					endBounds = lineEnd2;
-					break;
-				}
-				case ATK.ATK_TEXT_BOUNDARY_LINE_END: {
-					int lineEnd1 = previousIndexOfChar (text, "\n", offset);
-					if (lineEnd1 == -1) {
-						startBounds = endBounds = 0;
-						break;
+					case ATK.ATK_TEXT_BOUNDARY_LINE_END: {
+						int lineEnd1 = previousIndexOfChar (text, "\n", offset);
+						if (lineEnd1 == -1) {
+							startBounds = endBounds = 0;
+							break;
+						}
+						startBounds = lineEnd1;
+						endBounds = nextIndexOfChar (text, "\n", lineEnd1 + 1);
 					}
-					startBounds = lineEnd1;
-					endBounds = nextIndexOfChar (text, "\n", lineEnd1 + 1);
-				}
-			}
-			OS.memmove (start_offset, new int[] {startBounds}, 4);
-			OS.memmove (end_offset, new int[] {endBounds}, 4);
-			text = text.substring (startBounds, endBounds);
-			byte[] bytes = Converter.wcsToMbcs (null, text, true);
-			int /*long*/ result = OS.g_malloc (bytes.length);
-			OS.memmove (result, bytes, bytes.length);
-			return result;
-		} 
+				}
+				OS.memmove (start_offset, new int[] {startBounds}, 4);
+				OS.memmove (end_offset, new int[] {endBounds}, 4);
+				text = text.substring (startBounds, endBounds);
+				return getStringPtr (text);
+			} 
+		}
+		AtkTextIface iface = getTextIface (atkObject);
+		if (iface != null && iface.get_text_at_offset != 0) {
+			return ATK.call (iface.get_text_at_offset, atkObject, offset_value, boundary_type, start_offset, end_offset);
+		}
 		return 0;
 	}
 
 	static int /*long*/ atkText_get_text_before_offset (int /*long*/ atkObject, int /*long*/ offset_value, int /*long*/ boundary_type, int /*long*/ start_offset, int /*long*/ end_offset) {
-		if (DEBUG) System.out.println ("-->atkText_get_text_before_offset");
-		AccessibleObject object = getAccessibleObject (atkObject);
-		if (object == null) return 0;
-		int offset = (int)/*64*/offset_value;
-		String text = object.getText ();
-		if (text.length () > 0) {
-			int length = text.length ();
-			offset = Math.min (offset, length - 1);
-			int startBounds = offset;
-			int endBounds = offset;
-			switch ((int)/*64*/boundary_type) {
-				case ATK.ATK_TEXT_BOUNDARY_CHAR: {
-					if (length >= offset && offset > 0) startBounds--;
-					break;
-				}
-				case ATK.ATK_TEXT_BOUNDARY_WORD_START: {
-					int wordStart1 = previousIndexOfChar (text, " !?.\n", offset - 1);
-					if (wordStart1 == -1) {
-						startBounds = endBounds = 0;
-						break;
-					}
-					int wordStart2 = previousIndexOfNotChar (text, " !?.\n", wordStart1);
-					if (wordStart2 == -1) {
-						startBounds = endBounds = 0;
-						break;
-					}
-					endBounds = wordStart1 + 1;
-					startBounds = previousIndexOfChar (text, " !?.\n", wordStart2) + 1;
-					break;
-				}
-				case ATK.ATK_TEXT_BOUNDARY_WORD_END: {
-					int wordEnd1 =previousIndexOfChar (text, " !?.\n", offset);
-					if (wordEnd1 == -1) {
-						startBounds = endBounds = 0;
-						break;
-					}
-					wordEnd1 = previousIndexOfNotChar (text, " \n", wordEnd1 + 1);
-					if (wordEnd1 == -1) {
-						startBounds = endBounds = 0;
+		if (DEBUG) print ("-->atkText_get_text_before_offset");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleTextExtendedListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				int /*long*/ charCount = atkText_get_character_count (atkObject);
+				AccessibleTextEvent event = new AccessibleTextEvent(accessible);
+				event.start = event.end = (int)/*64*/offset_value;
+				event.count = -1;
+				switch ((int)/*64*/boundary_type) {
+					case ATK.ATK_TEXT_BOUNDARY_CHAR: event.type = ACC.TEXT_BOUNDARY_CHAR; break; 
+					case ATK.ATK_TEXT_BOUNDARY_WORD_START: event.type = ACC.TEXT_BOUNDARY_WORD; break; 
+					case ATK.ATK_TEXT_BOUNDARY_WORD_END: event.type = ACC.TEXT_BOUNDARY_WORD; break; 
+					case ATK.ATK_TEXT_BOUNDARY_SENTENCE_START: event.type = ACC.TEXT_BOUNDARY_SENTENCE; break; 
+					case ATK.ATK_TEXT_BOUNDARY_SENTENCE_END: event.type = ACC.TEXT_BOUNDARY_SENTENCE; break; 
+					case ATK.ATK_TEXT_BOUNDARY_LINE_START: event.type = ACC.TEXT_BOUNDARY_LINE; break; 
+					case ATK.ATK_TEXT_BOUNDARY_LINE_END: event.type = ACC.TEXT_BOUNDARY_LINE; break; 
+				}
+				int eventStart = event.start;
+				int eventEnd = event.end;
+				for (int i = 0; i < length; i++) {
+					AccessibleTextExtendedListener listener = (AccessibleTextExtendedListener) listeners.elementAt(i);
+					listener.getText(event);
+				}
+				OS.memmove (start_offset, new int[] {event.start}, 4);
+				OS.memmove (end_offset, new int[] {event.end}, 4);
+				switch ((int)/*64*/boundary_type) {
+					case ATK.ATK_TEXT_BOUNDARY_WORD_START: 
+					case ATK.ATK_TEXT_BOUNDARY_SENTENCE_START: 
+					case ATK.ATK_TEXT_BOUNDARY_LINE_START:
+						if (event.end < charCount) {
+							int start = event.start;
+							event.start = eventStart;
+							event.end = eventEnd;
+							event.count = 0;
+							for (int i = 0; i < length; i++) {
+								AccessibleTextExtendedListener listener = (AccessibleTextExtendedListener) listeners.elementAt(i);
+								listener.getText(event);
+							}
+							event.end = event.start;
+							event.start = start;
+							event.type = ACC.TEXT_BOUNDARY_ALL;
+							event.count = 0;
+							for (int i = 0; i < length; i++) {
+								AccessibleTextExtendedListener listener = (AccessibleTextExtendedListener) listeners.elementAt(i);
+								listener.getText(event);
+							}
+						}
 						break;
-					}
-					endBounds = wordEnd1 + 1;
-					int wordEnd2 = previousIndexOfNotChar (text, " !?.\n", endBounds);
-					wordEnd2 = previousIndexOfChar (text, " !?.\n", wordEnd2);
-					if (wordEnd2 == -1) {
-						startBounds = 0;
+					case ATK.ATK_TEXT_BOUNDARY_WORD_END: 
+					case ATK.ATK_TEXT_BOUNDARY_SENTENCE_END: 
+					case ATK.ATK_TEXT_BOUNDARY_LINE_END:
+						if (0 < event.start) {
+							int end = event.end;
+							event.start = eventStart;
+							event.end = eventEnd;
+							event.count = -2;
+							for (int i = 0; i < length; i++) {
+								AccessibleTextExtendedListener listener = (AccessibleTextExtendedListener) listeners.elementAt(i);
+								listener.getText(event);
+							}
+							event.start = event.end;
+							event.end = end;
+							event.type = ACC.TEXT_BOUNDARY_ALL;
+							event.count = 0;
+							for (int i = 0; i < length; i++) {
+								AccessibleTextExtendedListener listener = (AccessibleTextExtendedListener) listeners.elementAt(i);
+								listener.getText(event);
+							}
+						}
 						break;
-					}
-					startBounds = previousIndexOfNotChar (text, " \n", wordEnd2 + 1) + 1;
-					break;
 				}
-				case ATK.ATK_TEXT_BOUNDARY_SENTENCE_START: {
-					int sentenceStart1 = previousIndexOfChar (text, "!?.", offset);
-					if (sentenceStart1 == -1) {
-						startBounds = endBounds = 0;
+				return getStringPtr (event.result);
+			}
+			int offset = (int)/*64*/offset_value;
+			String text = object.getText ();
+			if (text != null && text.length () > 0) {
+				length = text.length ();
+				offset = Math.min (offset, length - 1);
+				int startBounds = offset;
+				int endBounds = offset;
+				switch ((int)/*64*/boundary_type) {
+					case ATK.ATK_TEXT_BOUNDARY_CHAR: {
+						if (length >= offset && offset > 0) startBounds--;
 						break;
 					}
-					int sentenceStart2 = previousIndexOfNotChar (text, "!?.", sentenceStart1);
-					if (sentenceStart2 == -1) {
-						startBounds = endBounds = 0;
+					case ATK.ATK_TEXT_BOUNDARY_WORD_START: {
+						int wordStart1 = previousIndexOfChar (text, " !?.\n", offset - 1);
+						if (wordStart1 == -1) {
+							startBounds = endBounds = 0;
+							break;
+						}
+						int wordStart2 = previousIndexOfNotChar (text, " !?.\n", wordStart1);
+						if (wordStart2 == -1) {
+							startBounds = endBounds = 0;
+							break;
+						}
+						endBounds = wordStart1 + 1;
+						startBounds = previousIndexOfChar (text, " !?.\n", wordStart2) + 1;
 						break;
 					}
-					endBounds = sentenceStart1 + 1;
-					startBounds = previousIndexOfChar (text, "!?.", sentenceStart2) + 1;
-					break;
-				}
-				case ATK.ATK_TEXT_BOUNDARY_SENTENCE_END: {
-					int sentenceEnd1 = previousIndexOfChar (text, "!?.", offset);
-					if (sentenceEnd1 == -1) {
-						startBounds = endBounds = 0;
+					case ATK.ATK_TEXT_BOUNDARY_WORD_END: {
+						int wordEnd1 =previousIndexOfChar (text, " !?.\n", offset);
+						if (wordEnd1 == -1) {
+							startBounds = endBounds = 0;
+							break;
+						}
+						wordEnd1 = previousIndexOfNotChar (text, " \n", wordEnd1 + 1);
+						if (wordEnd1 == -1) {
+							startBounds = endBounds = 0;
+							break;
+						}
+						endBounds = wordEnd1 + 1;
+						int wordEnd2 = previousIndexOfNotChar (text, " !?.\n", endBounds);
+						wordEnd2 = previousIndexOfChar (text, " !?.\n", wordEnd2);
+						if (wordEnd2 == -1) {
+							startBounds = 0;
+							break;
+						}
+						startBounds = previousIndexOfNotChar (text, " \n", wordEnd2 + 1) + 1;
 						break;
 					}
-					sentenceEnd1 = previousIndexOfNotChar (text, " \n", sentenceEnd1 + 1);
-					if (sentenceEnd1 == -1) {
-						startBounds = endBounds = 0;
+					case ATK.ATK_TEXT_BOUNDARY_SENTENCE_START: {
+						int sentenceStart1 = previousIndexOfChar (text, "!?.", offset);
+						if (sentenceStart1 == -1) {
+							startBounds = endBounds = 0;
+							break;
+						}
+						int sentenceStart2 = previousIndexOfNotChar (text, "!?.", sentenceStart1);
+						if (sentenceStart2 == -1) {
+							startBounds = endBounds = 0;
+							break;
+						}
+						endBounds = sentenceStart1 + 1;
+						startBounds = previousIndexOfChar (text, "!?.", sentenceStart2) + 1;
 						break;
 					}
-					endBounds = sentenceEnd1 + 1;
-					int sentenceEnd2 = previousIndexOfNotChar (text, "!?.", endBounds);
-					sentenceEnd2 = previousIndexOfChar (text, "!?.", sentenceEnd2);
-					if (sentenceEnd2 == -1) {
-						startBounds = 0;
+					case ATK.ATK_TEXT_BOUNDARY_SENTENCE_END: {
+						int sentenceEnd1 = previousIndexOfChar (text, "!?.", offset);
+						if (sentenceEnd1 == -1) {
+							startBounds = endBounds = 0;
+							break;
+						}
+						sentenceEnd1 = previousIndexOfNotChar (text, " \n", sentenceEnd1 + 1);
+						if (sentenceEnd1 == -1) {
+							startBounds = endBounds = 0;
+							break;
+						}
+						endBounds = sentenceEnd1 + 1;
+						int sentenceEnd2 = previousIndexOfNotChar (text, "!?.", endBounds);
+						sentenceEnd2 = previousIndexOfChar (text, "!?.", sentenceEnd2);
+						if (sentenceEnd2 == -1) {
+							startBounds = 0;
+							break;
+						}
+						startBounds = previousIndexOfNotChar (text, " \n", sentenceEnd2 + 1) + 1;
 						break;
 					}
-					startBounds = previousIndexOfNotChar (text, " \n", sentenceEnd2 + 1) + 1;
-					break;
-				}
-				case ATK.ATK_TEXT_BOUNDARY_LINE_START: {
-					int lineStart1 = previousIndexOfChar (text, "\n", offset);
-					if (lineStart1 == -1) {
-						startBounds = endBounds = 0;
+					case ATK.ATK_TEXT_BOUNDARY_LINE_START: {
+						int lineStart1 = previousIndexOfChar (text, "\n", offset);
+						if (lineStart1 == -1) {
+							startBounds = endBounds = 0;
+							break;
+						}
+						endBounds = lineStart1 + 1;
+						startBounds = previousIndexOfChar (text, "\n", lineStart1) + 1;
 						break;
 					}
-					endBounds = lineStart1 + 1;
-					startBounds = previousIndexOfChar (text, "\n", lineStart1) + 1;
-					break;
-				}
-				case ATK.ATK_TEXT_BOUNDARY_LINE_END: {
-					int lineEnd1 = previousIndexOfChar (text, "\n", offset);
-					if (lineEnd1 == -1) {
-						startBounds = endBounds = 0;
+					case ATK.ATK_TEXT_BOUNDARY_LINE_END: {
+						int lineEnd1 = previousIndexOfChar (text, "\n", offset);
+						if (lineEnd1 == -1) {
+							startBounds = endBounds = 0;
+							break;
+						}
+						endBounds = lineEnd1;
+						startBounds = previousIndexOfChar (text, "\n", lineEnd1);
+						if (startBounds == -1) startBounds = 0;
 						break;
 					}
-					endBounds = lineEnd1;
-					startBounds = previousIndexOfChar (text, "\n", lineEnd1);
-					if (startBounds == -1) startBounds = 0;
-					break;
-				}
-			}
-			OS.memmove (start_offset, new int[] {startBounds}, 4);
-			OS.memmove (end_offset, new int[] {endBounds}, 4);
-			text = text.substring (startBounds, endBounds);
-			byte[] bytes = Converter.wcsToMbcs (null, text, true);
-			int /*long*/ result = OS.g_malloc (bytes.length);
-			OS.memmove (result, bytes, bytes.length);
-			return result;
-		} 
+				}
+				OS.memmove (start_offset, new int[] {startBounds}, 4);
+				OS.memmove (end_offset, new int[] {endBounds}, 4);
+				text = text.substring (startBounds, endBounds);
+				return getStringPtr (text);
+			}
+		}
+		AtkTextIface iface = getTextIface (atkObject);
+		if (iface != null && iface.get_text_before_offset != 0) {
+			return ATK.call (iface.get_text_before_offset, atkObject, offset_value, boundary_type, start_offset, end_offset);
+		}
+		return 0;
+	}
+	
+	static void setGValue (int /*long*/ value, Number number) {
+		if (number == null) return;
+		if (OS.G_VALUE_TYPE(value) != 0) OS.g_value_unset(value);
+		if (number instanceof Double) {
+			OS.g_value_init(value, OS.G_TYPE_DOUBLE());
+			OS.g_value_set_double(value, number.doubleValue());
+		} else if (number instanceof Float) {
+			OS.g_value_init(value, OS.G_TYPE_FLOAT());
+			OS.g_value_set_float(value, number.floatValue());
+		} else if (number instanceof Long) {
+			OS.g_value_init(value, OS.G_TYPE_INT64());
+			OS.g_value_set_int64(value, number.longValue());
+		} else {
+			OS.g_value_init(value, OS.G_TYPE_INT());
+			OS.g_value_set_int(value, number.intValue());
+		}
+	}
+
+	static Number getGValue (int /*long*/ value) {
+		int /*long*/ type = OS.G_VALUE_TYPE(value);
+		if (type == 0) return null;
+		if (type == OS.G_TYPE_DOUBLE()) return new Double(OS.g_value_get_double(value));
+		if (type == OS.G_TYPE_FLOAT()) return new Float(OS.g_value_get_float(value));
+		if (type == OS.G_TYPE_INT64()) return new Long(OS.g_value_get_int64(value));
+		return new Integer(OS.g_value_get_int(value));
+	}
+	
+	static AtkValueIface getValueIface (int /*long*/ atkObject) {
+		if (ATK.g_type_is_a (OS.g_type_parent (OS.G_OBJECT_TYPE (atkObject)), ATK.ATK_TYPE_VALUE())) {
+			AtkValueIface iface = new AtkValueIface ();
+			ATK.memmove (iface, ATK.g_type_interface_peek_parent (ATK.ATK_VALUE_GET_IFACE (atkObject)));
+			return iface;
+		}
+		return null;
+	}
+	static int /*long*/ atkValue_get_current_value (int /*long*/ atkObject, int /*long*/ value) {
+		if (DEBUG) print ("-->atkValue_get_current_value");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		AtkValueIface iface = getValueIface (atkObject);
+		if (iface != null && iface.get_current_value != 0) {
+			ATK.call (iface.get_current_value, atkObject, value);
+		}
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleValueListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleValueEvent event = new AccessibleValueEvent(accessible);
+				event.value = getGValue(value);
+				for (int i = 0; i < length; i++) {
+					AccessibleValueListener listener = (AccessibleValueListener) listeners.elementAt(i);
+					listener.getCurrentValue(event);
+				}
+				setGValue(value, event.value);
+			}
+		}
+		return 0;
+	}
+
+	static int /*long*/ atkValue_get_maximum_value (int /*long*/ atkObject, int /*long*/ value) {
+		if (DEBUG) print ("-->atkValue_get_maximum_value");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		AtkValueIface iface = getValueIface (atkObject);
+		if (iface != null && iface.get_maximum_value != 0) {
+			ATK.call (iface.get_maximum_value, atkObject, value);
+		}
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleValueListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleValueEvent event = new AccessibleValueEvent(accessible);
+				event.value = getGValue(value);
+				for (int i = 0; i < length; i++) {
+					AccessibleValueListener listener = (AccessibleValueListener) listeners.elementAt(i);
+					listener.getMaximumValue(event);
+				}
+				setGValue(value, event.value);
+			}
+		}
+		return 0;
+	}
+
+	static int /*long*/ atkValue_get_minimum_value (int /*long*/ atkObject, int /*long*/ value) {
+		if (DEBUG) print ("-->atkValue_get_minimum_value");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		AtkValueIface iface = getValueIface (atkObject);
+		if (iface != null && iface.get_minimum_value != 0) {
+			ATK.call (iface.get_minimum_value, atkObject, value);
+		}
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleValueListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleValueEvent event = new AccessibleValueEvent(accessible);
+				event.value = getGValue(value);
+				for (int i = 0; i < length; i++) {
+					AccessibleValueListener listener = (AccessibleValueListener) listeners.elementAt(i);
+					listener.getMinimumValue(event);
+				}
+				setGValue(value, event.value);
+			}
+		}
 		return 0;
 	}
 
-	AccessibleListener[] getAccessibleListeners () {
-		if (accessible == null) return new AccessibleListener [0];
-		AccessibleListener[] result = accessible.getAccessibleListeners ();
-		return result != null ? result : new AccessibleListener [0];
+	static int /*long*/ atkValue_set_current_value (int /*long*/ atkObject, int /*long*/ value) {
+		if (DEBUG) print ("-->atkValue_set_current_value");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object != null) {
+			Accessible accessible = object.accessible;
+			Vector listeners = accessible.accessibleValueListeners;
+			int length = listeners.size();
+			if (length > 0) {
+				AccessibleValueEvent event = new AccessibleValueEvent(accessible);
+				event.value = getGValue(value);
+				for (int i = 0; i < length; i++) {
+					AccessibleValueListener listener = (AccessibleValueListener) listeners.elementAt(i);
+					listener.setCurrentValue(event);
+				}
+				return event.value != null ? 1 : 0;
+			}
+		}
+		int /*long*/ parentResult = 0;
+		AtkValueIface iface = getValueIface (atkObject);
+		if (iface != null && iface.set_current_value != 0) {
+			parentResult = ATK.call (iface.set_current_value, atkObject, value);
+		}
+		return parentResult;
 	}
 
 	static AccessibleObject getAccessibleObject (int /*long*/ atkObject) {
-		return (AccessibleObject)AccessibleObjects.get (new LONG (atkObject));
+		AccessibleObject object = (AccessibleObject)AccessibleObjects.get (new LONG (atkObject));
+		if (object == null) return null;
+		if (object.accessible == null) return null;
+		Control control = object.accessible.control;
+		if (control == null || control.isDisposed()) return null;
+		return object;
 	}
 	
-	AccessibleObject getChildByHandle (int /*long*/ handle) {
-		return (AccessibleObject) children.get (new LONG (handle));	
-	}	
-
 	AccessibleObject getChildByID (int childId) {
 		if (childId == ACC.CHILDID_SELF) return this;
-		Enumeration elements = children.elements ();
-		while (elements.hasMoreElements ()) {
-			AccessibleObject object = (AccessibleObject) elements.nextElement ();
-			if (object.id == childId) return object;
+		if (childId == ACC.CHILDID_NONE || childId == ACC.CHILDID_MULTIPLE) return null;
+		if (children != null) {
+			for (int i = 0; i < children.length; i++) {
+				AccessibleObject child = children[i];
+				if (child != null && child.id == childId) return child;
+			}
 		}
 		return null;
 	}
 	
 	AccessibleObject getChildByIndex (int childIndex) {
-		Enumeration elements = children.elements ();
-		while (elements.hasMoreElements ()) {
-			AccessibleObject object = (AccessibleObject) elements.nextElement ();
-			if (object.index == childIndex) return object;
-		}
+		if (children != null && childIndex < children.length) return children [childIndex];
 		return null;
 	}
 	
-	AccessibleControlListener[] getControlListeners () {
-		if (accessible == null) return new AccessibleControlListener [0];
-		AccessibleControlListener[] result = accessible.getControlListeners (); 
-		return result != null ? result : new AccessibleControlListener [0];
-	}
-
 	String getText () {
-		int /*long*/ parentResult = 0;
-		String parentText = "";	//$NON-NLS-1$
-		if (ATK.g_type_is_a (parentType, ATK_TEXT_TYPE)) {
-			int /*long*/ superType = ATK.g_type_interface_peek_parent (ATK.ATK_TEXT_GET_IFACE (handle));
-			AtkTextIface textIface = new AtkTextIface ();
-			ATK.memmove (textIface, superType);
-			int /*long*/ characterCount = 0;
-			if (textIface.get_character_count != 0) {
-				characterCount = ATK.call (textIface.get_character_count, handle);
-			}
-			if (characterCount > 0 && textIface.get_text != 0) {
-				parentResult = ATK.call (textIface.get_text, handle, 0, characterCount);
-				if (parentResult != 0) {
-					int length = OS.strlen (parentResult);
-					byte [] buffer = new byte [length];
-					OS.memmove (buffer, parentResult, length);
-					parentText = new String (Converter.mbcsToWcs (null, buffer));
-				}
-			}
-		}
-		AccessibleControlListener[] controlListeners = getControlListeners ();
-		if (controlListeners.length == 0) return parentText;
-		AccessibleControlEvent event = new AccessibleControlEvent (accessible);
-		event.childID = id;
-		event.result = parentText;
-		for (int i = 0; i < controlListeners.length; i++) {
-			controlListeners [i].getValue (event);				
+		Vector listeners = accessible.accessibleControlListeners;
+		int length = listeners.size();
+		if (length > 0) {
+			String parentText = "";	//$NON-NLS-1$
+			AtkTextIface iface = getTextIface (handle);
+			if (iface != null && iface.get_character_count != 0) {
+				int /*long*/ characterCount = ATK.call (iface.get_character_count, handle);
+				if (characterCount > 0 && iface.get_text != 0) {
+					int /*long*/ parentResult = ATK.call (iface.get_text, handle, 0, characterCount);
+					if (parentResult != 0) {
+						parentText = getString (parentResult);
+						OS.g_free(parentResult);
+					}
+				}
+			}
+			AccessibleControlEvent event = new AccessibleControlEvent (accessible);
+			event.childID = id;
+			event.result = parentText;
+			for (int i = 0; i < length; i++) {
+				AccessibleControlListener listener = (AccessibleControlListener)listeners.elementAt (i);
+				listener.getValue (event);				
+			}
+			return event.result;
 		}
-		return event.result;
-	}
-	
-	AccessibleTextListener[] getTextListeners () {
-		if (accessible == null) return new AccessibleTextListener [0];
-		AccessibleTextListener[] result = accessible.getTextListeners (); 
-		return result != null ? result : new AccessibleTextListener [0];
+		return null;
 	}
 
 	static int /*long*/ gObjectClass_finalize (int /*long*/ atkObject) {
+		if (DEBUG) print ("-->gObjectClass_finalize: " + atkObject);
 		int /*long*/ superType = ATK.g_type_class_peek_parent (ATK.G_OBJECT_GET_CLASS (atkObject));
 		int /*long*/ gObjectClass = ATK.G_OBJECT_CLASS (superType);
 		GObjectClass objectClassStruct = new GObjectClass ();
 		ATK.memmove (objectClassStruct, gObjectClass);
 		ATK.call (objectClassStruct.finalize, atkObject);
-		AccessibleObject object = getAccessibleObject (atkObject);
+		AccessibleObject object = (AccessibleObject)AccessibleObjects.get (new LONG (atkObject));
 		if (object != null) {
 			AccessibleObjects.remove (new LONG (atkObject));
-			object.release ();
+		}
+		return 0;
+	}
+
+	static int toATKRelation (int relation) {
+		switch (relation) {
+			case ACC.RELATION_CONTROLLED_BY: return ATK.ATK_RELATION_CONTROLLED_BY;
+			case ACC.RELATION_CONTROLLER_FOR: return ATK.ATK_RELATION_CONTROLLER_FOR;
+			case ACC.RELATION_DESCRIBED_BY: return ATK.ATK_RELATION_DESCRIBED_BY;
+			case ACC.RELATION_DESCRIPTION_FOR: return ATK.ATK_RELATION_DESCRIPTION_FOR;
+			case ACC.RELATION_EMBEDDED_BY: return ATK.ATK_RELATION_EMBEDDED_BY;
+			case ACC.RELATION_EMBEDS: return ATK.ATK_RELATION_EMBEDS;
+			case ACC.RELATION_FLOWS_FROM: return ATK.ATK_RELATION_FLOWS_FROM;
+			case ACC.RELATION_FLOWS_TO: return ATK.ATK_RELATION_FLOWS_TO;
+			case ACC.RELATION_LABEL_FOR: return ATK.ATK_RELATION_LABEL_FOR;
+			case ACC.RELATION_LABELLED_BY: return ATK.ATK_RELATION_LABELLED_BY;
+			case ACC.RELATION_MEMBER_OF: return ATK.ATK_RELATION_MEMBER_OF;
+			case ACC.RELATION_NODE_CHILD_OF: return ATK.ATK_RELATION_NODE_CHILD_OF;
+			case ACC.RELATION_PARENT_WINDOW_OF: return ATK.ATK_RELATION_PARENT_WINDOW_OF;
+			case ACC.RELATION_POPUP_FOR: return ATK.ATK_RELATION_POPUP_FOR;
+			case ACC.RELATION_SUBWINDOW_OF: return ATK.ATK_RELATION_SUBWINDOW_OF;
 		}
 		return 0;
 	}
 	
+	static void windowPoint (AccessibleObject object, int [] x, int [] y) {
+		GtkAccessible gtkAccessible = new GtkAccessible ();
+		ATK.memmove (gtkAccessible, object.handle);
+		while (gtkAccessible.widget == 0 && object.parent != null) {
+			object = object.parent;
+			ATK.memmove (gtkAccessible, object.handle);
+		}
+		if (gtkAccessible.widget == 0) return;
+		int /*long*/ topLevel = ATK.gtk_widget_get_toplevel (gtkAccessible.widget);
+		int /*long*/ window = OS.GTK_WIDGET_WINDOW (topLevel);				
+		OS.gdk_window_get_origin (window, x, y);
+	}
+	
 	static int nextIndexOfChar (String string, String searchChars, int startIndex) {
 		int result = string.length ();
 		for (int i = 0; i < searchChars.length (); i++) {
@@ -1303,38 +3168,241 @@ class AccessibleObject {
 		}
 		return index;
 	}
+	
+	void addRelation (int type, Accessible target) {
+		OS.atk_object_add_relationship(handle, toATKRelation(type), target.getAccessibleObject().handle);
+	}
 
 	void release () {
-		if (DEBUG) System.out.println("AccessibleObject.release: " + handle);
+		if (DEBUG) print("AccessibleObject.release: " + handle);
 		accessible = null;
-		Enumeration elements = children.elements ();
-		while (elements.hasMoreElements ()) {
-			AccessibleObject child = (AccessibleObject) elements.nextElement ();
-			if (child.isLightweight) OS.g_object_unref (child.handle);
+		if (children != null) {
+			for (int i = 0; i < children.length; i++) {
+				AccessibleObject child = children [i];
+				if (child != null) OS.g_object_unref(child.handle);
+			}
+			children = null;
+		}
+		// TODO remove from children from parent?
+		if (isLightweight) {
+			OS.g_object_unref(handle);
 		}
-		if (parent != null) parent.removeChild (this, false);
 	}
 	
-	void removeChild (AccessibleObject child, boolean unref) {
-		children.remove (new LONG (child.handle));
-		if (unref && child.isLightweight) OS.g_object_unref (child.handle);
+	void removeRelation (int type, Accessible target) {
+		OS.atk_object_remove_relationship (handle, toATKRelation(type), target.getAccessibleObject().handle);
 	}
 	
 	void selectionChanged () {
 		OS.g_signal_emit_by_name (handle, ATK.selection_changed);
 	}
 	
+	void sendEvent(int event, Object eventData) {
+		switch (event) {
+			case ACC.EVENT_SELECTION_CHANGED:
+				OS.g_signal_emit_by_name (handle, ATK.selection_changed);
+				break;
+			case ACC.EVENT_TEXT_SELECTION_CHANGED:
+				OS.g_signal_emit_by_name (handle, ATK.text_selection_changed);
+				break;
+			case ACC.EVENT_STATE_CHANGED: {
+				if (!(eventData instanceof int[])) break;
+				int[] array = (int[])eventData;
+				int state =  array[0];
+				int value = array[1];
+				int atkState = -1;
+				switch (state) {
+					case ACC.STATE_SELECTED: atkState = ATK.ATK_STATE_SELECTED; break;
+					case ACC.STATE_SELECTABLE: atkState = ATK.ATK_STATE_SELECTABLE; break;
+					case ACC.STATE_MULTISELECTABLE: atkState = ATK.ATK_STATE_MULTISELECTABLE; break;
+					case ACC.STATE_FOCUSED: atkState = ATK.ATK_STATE_FOCUSED; break;
+					case ACC.STATE_FOCUSABLE: atkState = ATK.ATK_STATE_FOCUSABLE; break;
+					case ACC.STATE_PRESSED: atkState = ATK.ATK_STATE_PRESSED; break;
+					case ACC.STATE_CHECKED: atkState = ATK.ATK_STATE_CHECKED; break;
+					case ACC.STATE_EXPANDED: atkState = ATK.ATK_STATE_EXPANDED; break;
+					case ACC.STATE_COLLAPSED: atkState = ATK.ATK_STATE_EXPANDED; break;
+					case ACC.STATE_HOTTRACKED: atkState = ATK.ATK_STATE_ARMED; break;
+					case ACC.STATE_BUSY: atkState = ATK.ATK_STATE_BUSY; break;
+					case ACC.STATE_READONLY: atkState = ATK.ATK_STATE_EDITABLE; break;
+					case ACC.STATE_INVISIBLE: atkState = ATK.ATK_STATE_VISIBLE; break;
+					case ACC.STATE_OFFSCREEN: atkState = ATK.ATK_STATE_SHOWING; break;
+					case ACC.STATE_SIZEABLE: atkState = ATK.ATK_STATE_RESIZABLE; break;
+					case ACC.STATE_LINKED: break;
+					case ACC.STATE_DISABLED: atkState = ATK.ATK_STATE_ENABLED; break;
+					case ACC.STATE_ACTIVE: atkState = ATK.ATK_STATE_ACTIVE; break;
+					case ACC.STATE_SINGLELINE: atkState = ATK.ATK_STATE_SINGLE_LINE; break;
+					case ACC.STATE_MULTILINE: atkState = ATK.ATK_STATE_MULTI_LINE; break;
+					case ACC.STATE_REQUIRED: atkState = ATK.ATK_STATE_REQUIRED; break;
+					case ACC.STATE_INVALID_ENTRY: atkState = ATK.ATK_STATE_INVALID_ENTRY; break;
+					case ACC.STATE_SUPPORTS_AUTOCOMPLETION: atkState = ATK.ATK_STATE_SUPPORTS_AUTOCOMPLETION; break;
+				}
+				if (atkState == -1) break;
+				ATK.atk_object_notify_state_change(handle, atkState, value != 0);
+				break;
+			}
+			case ACC.EVENT_LOCATION_CHANGED: {
+				Vector listeners = accessible.accessibleControlListeners;
+				int length = listeners.size();
+				GdkRectangle rect = new GdkRectangle();
+				if (length > 0) {
+					AccessibleControlEvent e = new AccessibleControlEvent (accessible);
+					e.childID = id;
+					for (int i = 0; i < length; i++) {
+						AccessibleControlListener listener = (AccessibleControlListener)listeners.elementAt (i);
+						listener.getLocation (e);
+					}
+					rect.x = e.x;
+					rect.y = e.y;
+					rect.width = e.width;
+					rect.height = e.height;
+				}
+				OS.g_signal_emit_by_name (handle, ATK.bounds_changed, rect);
+				break;
+			}
+			case ACC.EVENT_NAME_CHANGED:
+				OS.g_object_notify(handle, ATK.accessible_name);
+				break;
+			case ACC.EVENT_DESCRIPTION_CHANGED:
+				OS.g_object_notify(handle, ATK.accessible_description);
+				break;
+			case ACC.EVENT_VALUE_CHANGED:
+				OS.g_object_notify(handle, ATK.accessible_value);
+				break;
+			case ACC.EVENT_DOCUMENT_LOAD_COMPLETE:
+				OS.g_signal_emit_by_name (handle, ATK.load_complete);
+				break;
+			case ACC.EVENT_DOCUMENT_LOAD_STOPPED:
+				OS.g_signal_emit_by_name (handle, ATK.load_stopped);
+				break;
+			case ACC.EVENT_DOCUMENT_RELOAD:
+				OS.g_signal_emit_by_name (handle, ATK.reload);
+				break;
+			case ACC.EVENT_PAGE_CHANGED:
+				break;
+			case ACC.EVENT_SECTION_CHANGED:
+				break;
+			case ACC.EVENT_ACTION_CHANGED:
+				break;
+			case ACC.EVENT_HYPERLINK_END_INDEX_CHANGED:
+				OS.g_object_notify(handle, ATK.end_index);
+				break;
+			case ACC.EVENT_HYPERLINK_ANCHOR_COUNT_CHANGED:
+				OS.g_object_notify(handle, ATK.number_of_anchors);
+				break;
+			case ACC.EVENT_HYPERLINK_SELECTED_LINK_CHANGED:
+				OS.g_object_notify(handle, ATK.selected_link);
+				break;
+			case ACC.EVENT_HYPERLINK_START_INDEX_CHANGED:
+				OS.g_object_notify(handle, ATK.start_index);
+				break;
+			case ACC.EVENT_HYPERLINK_ACTIVATED:
+				OS.g_signal_emit_by_name (handle, ATK.link_activated);
+				break;
+			case ACC.EVENT_HYPERTEXT_LINK_SELECTED:
+				if (!(eventData instanceof Integer)) break;
+				int index =  ((Integer)eventData).intValue();
+				OS.g_signal_emit_by_name (handle, ATK.link_selected, index);
+				break;
+			case ACC.EVENT_HYPERTEXT_LINK_COUNT_CHANGED:
+				OS.g_object_notify(handle, ATK.accessible_hypertext_nlinks);
+				break;
+			case ACC.EVENT_ATTRIBUTE_CHANGED:
+				OS.g_signal_emit_by_name (handle, ATK.attributes_changed);
+				break;
+			case ACC.EVENT_TABLE_CAPTION_CHANGED:
+				OS.g_object_notify(handle, ATK.accessible_table_caption_object);
+				break;
+			case ACC.EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED:
+				OS.g_object_notify(handle, ATK.accessible_table_column_description);
+				break;
+			case ACC.EVENT_TABLE_COLUMN_HEADER_CHANGED:
+				OS.g_object_notify(handle, ATK.accessible_table_column_header);
+				break;
+			case ACC.EVENT_TABLE_CHANGED: {
+				if (!(eventData instanceof int[])) break;
+				int[] array = (int[])eventData;
+				int type =  array[0];
+				int rowStart = array[1];
+				int rowCount = array[2];
+				int columnStart = array[3];
+				int columnCount = array[4];
+				switch (type) {
+					case ACC.DELETE:
+						if (rowCount > 0) OS.g_signal_emit_by_name (handle, ATK.row_deleted, rowStart, rowCount);
+						if (columnCount > 0) OS.g_signal_emit_by_name (handle, ATK.column_deleted, columnStart, columnCount);
+						break;
+					case ACC.INSERT:
+						if (rowCount > 0) OS.g_signal_emit_by_name (handle, ATK.row_inserted, rowStart, rowCount);
+						if (columnCount > 0) OS.g_signal_emit_by_name (handle, ATK.column_inserted, columnStart, columnCount);
+						break;
+				}
+				break;
+			}
+			case ACC.EVENT_TABLE_ROW_DESCRIPTION_CHANGED:
+				OS.g_object_notify(handle, ATK.accessible_table_row_description);
+				break;
+			case ACC.EVENT_TABLE_ROW_HEADER_CHANGED:
+				OS.g_object_notify(handle, ATK.accessible_table_row_header);
+				break;
+			case ACC.EVENT_TABLE_SUMMARY_CHANGED:
+				OS.g_object_notify(handle, ATK.accessible_table_summary);
+				break;
+			case ACC.EVENT_TEXT_ATTRIBUTE_CHANGED:
+				OS.g_signal_emit_by_name (handle, ATK.text_attributes_changed);
+				break;
+			case ACC.EVENT_TEXT_CARET_MOVED:
+			case ACC.EVENT_TEXT_COLUMN_CHANGED: {
+				int offset = 0;
+				Vector listeners = accessible.accessibleTextExtendedListeners;
+				int length = listeners.size();
+				AccessibleTextEvent e = new AccessibleTextEvent (accessible);
+				if (length > 0) {
+					for (int i = 0; i < length; i++) {
+						AccessibleTextListener listener = (AccessibleTextListener) listeners.elementAt(i);
+						listener.getCaretOffset (e);
+					}
+				} else {
+					listeners = accessible.accessibleTextListeners;
+					length = listeners.size();
+					if (length > 0) {
+						e.childID = id;
+						for (int i = 0; i < length; i++) {
+							AccessibleTextListener listener = (AccessibleTextListener) listeners.elementAt(i);
+							listener.getCaretOffset (e);	
+						}
+					}
+				}
+				offset = e.offset;
+				OS.g_signal_emit_by_name (handle, ATK.text_caret_moved, offset);
+				break;
+			}
+			case ACC.EVENT_TEXT_CHANGED: {
+				if (!(eventData instanceof Object[])) break;
+				Object[] data = (Object[])eventData;
+				int type = ((Integer)data[0]).intValue();
+				int start = ((Integer)data[1]).intValue();
+				int end = ((Integer)data[2]).intValue();
+				switch (type) {
+					case ACC.DELETE:
+						OS.g_signal_emit_by_name (handle, ATK.text_changed_delete, start, end -start);
+						break;
+					case ACC.INSERT:
+						OS.g_signal_emit_by_name (handle, ATK.text_changed_insert, start, end -start);
+						break;
+				}
+				break;
+			}
+		}
+	}
+	
 	void setFocus (int childID) {
 		updateChildren ();
 		AccessibleObject accObject = getChildByID (childID);
 		if (accObject != null) {
-			ATK.atk_focus_tracker_notify (accObject.handle);
+			OS.g_signal_emit_by_name (accObject.handle, ATK.focus_event, 1, 0);
+			ATK.atk_object_notify_state_change(accObject.handle, ATK.ATK_STATE_FOCUSED, true);
 		}
 	}
-
-	void setParent (AccessibleObject parent) {
-		this.parent = parent;
-	}
 	
 	void textCaretMoved(int index) {
 		OS.g_signal_emit_by_name (handle, ATK.text_caret_moved, index);
@@ -1351,62 +3419,60 @@ class AccessibleObject {
 	void textSelectionChanged() {
 		OS.g_signal_emit_by_name (handle, ATK.text_selection_changed);
 	}
-
+	
 	void updateChildren () {
-		if (isLightweight) return;
-		AccessibleControlListener[] listeners = getControlListeners ();
-		if (listeners.length == 0) return;
-
+		Vector listeners = accessible.accessibleControlListeners;
+		int length = listeners.size();
 		AccessibleControlEvent event = new AccessibleControlEvent (accessible);
-		for (int i = 0; i < listeners.length; i++) {
-			listeners [i].getChildren (event);
-		}
-		if (event.children != null && event.children.length > 0) {
-			Vector idsToKeep = new Vector (children.size ());
-			if (event.children [0] instanceof Integer) {
-				/*	an array of child id's (Integers) was answered */
-				int /*long*/ parentType = AccessibleFactory.getDefaultParentType ();
-				for (int i = 0; i < event.children.length; i++) {
-					AccessibleObject object = getChildByIndex (i);
-					if (object == null) {
-						int /*long*/ childType = AccessibleFactory.getChildType (accessible, i);
-						object = new AccessibleObject (childType, 0, accessible, parentType, true);
-						AccessibleObjects.put (new LONG (object.handle), object);
-						addChild (object);
-						object.index = i;
-					}
-					try {
-						object.id = ((Integer)event.children[i]).intValue ();
-					} catch (ClassCastException e) {
-						/* a non-ID value was given so don't set the ID */
-					}
-					idsToKeep.addElement (new LONG (object.handle));
-				}
-			} else {
-				/* an array of Accessible children was answered */
-				int childIndex = 0;
-				for (int i = 0; i < event.children.length; i++) {
-					AccessibleObject object = null;
-					try {
-						object = ((Accessible)event.children [i]).accessibleObject;
-					} catch (ClassCastException e) {
-						/* a non-Accessible value was given so nothing to do here */ 
+		event.childID = id;
+		for (int i = 0; i < length; i++) {
+			AccessibleControlListener listener = (AccessibleControlListener)listeners.elementAt (i);
+			listener.getChildren (event);
+		}
+		Object[] children = event.children;
+		AccessibleObject[] oldChildren = this.children;
+		int count = children != null ? children.length : 0;
+		AccessibleObject[] newChildren = new AccessibleObject[count];
+		for (int i = 0; i < count; i++) {
+			Object child = children [i];
+			AccessibleObject object = null;
+			if (child instanceof Integer) {
+				int id = ((Integer)child).intValue();
+				object = oldChildren != null && i < oldChildren.length ? oldChildren [i] : null;
+				if (object == null || object.id != id) {
+					event = new AccessibleControlEvent (accessible);
+					event.childID = id;
+					for (int j = 0; j < length; j++) {
+						AccessibleControlListener listener = (AccessibleControlListener)listeners.elementAt (j);
+						listener.getChild (event);
 					}
-					if (object != null) {
-						object.index = childIndex++;
-						idsToKeep.addElement (new LONG (object.handle));
+					if (event.accessible != null) {
+						object = event.accessible.getAccessibleObject();
+						if (object != null)	OS.g_object_ref(object.handle);
+					} else {
+						object = AccessibleFactory.createChildAccessible (accessible, id);
 					}
+					object.id = id;
+				} else {
+					OS.g_object_ref(object.handle);
 				}
+			} else if (child instanceof Accessible) {
+				object = ((Accessible)child).getAccessibleObject();
+				if (object != null)	OS.g_object_ref(object.handle);
 			}
-			/* remove old children that were not provided as children anymore */
-			Enumeration ids = children.keys ();
-			while (ids.hasMoreElements ()) {
-				LONG id = (LONG)ids.nextElement ();
-				if (!idsToKeep.contains (id)) {
-					AccessibleObject object = (AccessibleObject) children.get (id);
-					removeChild (object, true);
-				}
+			if (object != null) {
+				object.index = i;
+				object.parent = this;
+				newChildren[i] = object;
 			}
 		}
+		if (oldChildren != null) {
+			for (int i = 0; i < oldChildren.length; i++) {
+				AccessibleObject object = oldChildren [i];
+				if (object != null) OS.g_object_unref(object.handle);
+			}
+		}
+		this.children = newChildren;
 	}
+
 }
diff --git a/org/eclipse/swt/accessibility/AccessibleTableAdapter.java b/org/eclipse/swt/accessibility/AccessibleTableAdapter.java
new file mode 100644
index 0000000..759efaa
--- /dev/null
+++ b/org/eclipse/swt/accessibility/AccessibleTableAdapter.java
@@ -0,0 +1,341 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.accessibility;
+
+/**
+ * This adapter class provides default implementations for the
+ * methods in the <code>AccessibleTableListener</code> interface.
+ * <p>
+ * Classes that wish to deal with <code>AccessibleTable</code> events can
+ * extend this class and override only the methods that they are
+ * interested in.
+ * </p><p>
+ * Many methods in this adapter return cell accessible objects,
+ * which should implement <code>AccessibleTableCellListener</code>.
+ * </p>
+ *
+ * @see AccessibleTableAdapter
+ * @see AccessibleTableEvent
+ * @see AccessibleTableCellListener
+ * @see AccessibleTableCellEvent
+ *
+ * @since 3.6
+ */
+public class AccessibleTableAdapter implements AccessibleTableListener {
+	/**
+	 * Deselects one column, leaving other selected columns selected (if any).
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] column - 0 based index of the column to be unselected.</li>
+	 * <li>[out] result - set to {@link ACC#OK} if the column was deselected.</li>
+	 * </ul>
+	 */
+	public void deselectColumn(AccessibleTableEvent e) {}
+
+	/**
+	 * Deselects one row, leaving other selected rows selected (if any).
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] row - 0 based index of the row to be unselected</li>
+	 * <li>[out] result - set to {@link ACC#OK} if the row was deselected.</li>
+	 * </ul>
+	 */
+	public void deselectRow(AccessibleTableEvent e) {}
+
+	/**
+	 * Returns the caption for the table.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] accessible - the caption for the table, or null if the table does not have a caption</li>
+	 * </ul>
+	 */
+	public void getCaption(AccessibleTableEvent e) {}
+
+	/**
+	 * Returns the accessible object at the specified row and column in the table.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] row - the 0 based row index for which to retrieve the accessible cell</li>
+	 * <li>[in] column - the 0 based column index for which to retrieve the accessible cell</li>
+	 * <li>[out] accessible - the table cell at the specified row and column index,
+	 * 		or null if the row or column index are not valid</li>
+	 * </ul>
+	 */
+	public void getCell(AccessibleTableEvent e) {}
+
+	/**
+	 * Returns the accessible object for the specified column in the table.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] column - the 0 based column index for which to retrieve the accessible column</li>
+	 * <li>[out] accessible - the table column at the specified column index,
+	 * 		or null if the column index is not valid</li>
+	 * </ul>
+	 */
+	public void getColumn(AccessibleTableEvent e) {}
+
+	/**
+	 * Returns the total number of columns in the table.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] count - the number of columns in the table</li>
+	 * </ul>
+	 */
+	public void getColumnCount(AccessibleTableEvent e) {}
+
+	/**
+	 * Returns the description text of the specified column in the table.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] column - the 0 based index of the column for which to retrieve the description</li>
+	 * <li>[out] result - the description text of the specified column in the table,
+	 * 		or null if the column does not have a description</li>
+	 * </ul>
+	 */
+	public void getColumnDescription(AccessibleTableEvent e) {}
+
+	/**
+	 * Returns the accessible object for the column header.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] accessible - an accessible object representing the column header,
+	 * 		or null if there is no column header</li>
+	 * </ul>
+	 */
+	public void getColumnHeader(AccessibleTableEvent e) {}
+
+	/**
+	 * Returns the column header cells as an array of accessible objects.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] accessibles - an array of accessible objects representing column header cells,
+	 * 		or null if there are no column header cells</li>
+	 * </ul>
+	 */
+	public void getColumnHeaderCells(AccessibleTableEvent e) {}
+
+	/**
+	 * Returns the columns as an array of accessible objects.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] accessibles - an array of accessible objects representing columns,
+	 * 		or null if there are no columns</li>
+	 * </ul>
+	 */
+	public void getColumns(AccessibleTableEvent e) {}
+
+	/**
+	 * Returns the accessible object for the specified row in the table.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] row - the 0 based row index for which to retrieve the accessible row</li>
+	 * <li>[out] accessible - the table row at the specified row index,
+	 * 		or null if the row index is not valid</li>
+	 * </ul>
+	 */
+	public void getRow(AccessibleTableEvent e) {}
+
+	/**
+	 * Returns the total number of rows in the table.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] count - the number of rows in the table</li>
+	 * </ul>
+	 */
+	public void getRowCount(AccessibleTableEvent e) {}
+
+	/**
+	 * Returns the description text of the specified row in the table.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] row - the 0 based index of the row for which to retrieve the description</li>
+	 * <li>[out] result - the description text of the specified row in the table,
+	 * 		or null if the row does not have a description</li>
+	 * </ul>
+	 */
+	public void getRowDescription(AccessibleTableEvent e) {}
+
+	/**
+	 * Returns the accessible object for the row header.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] accessible - an accessible object representing the row header,
+	 * 		or null if there is no row header</li>
+	 * </ul>
+	 */
+	public void getRowHeader(AccessibleTableEvent e) {}
+
+	/**
+	 * Returns the row header cells as an array of accessible objects.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] accessibles - an array of accessible objects representing row header cells,
+	 * 		or null if there are no row header cells</li>
+	 * </ul>
+	 */
+	public void getRowHeaderCells(AccessibleTableEvent e) {}
+
+	/**
+	 * Returns the rows as an array of accessible objects.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] accessibles - an array of accessible objects representing rows,
+	 * 		or null if there are no rows</li>
+	 * </ul>
+	 */
+	public void getRows(AccessibleTableEvent e) {}
+
+	/**
+	 * Returns the number of selected cells.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] count -  the number of cells currently selected</li>
+	 * </ul>
+	 */
+	public void getSelectedCellCount(AccessibleTableEvent e) {}
+
+	/**
+	 * Returns the currently selected cells.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] accessibles - array containing the selected accessible cells</li>
+	 * </ul>
+	 */
+	public void getSelectedCells(AccessibleTableEvent e) {}
+
+	/**
+	 * Returns the number of selected columns.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] count - the number of columns currently selected</li>
+	 * </ul>
+	 */
+	public void getSelectedColumnCount(AccessibleTableEvent e) {}
+
+	/**
+	 * Returns the column indexes that are currently selected.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] selected - an array of 0 based column indexes of selected columns</li>
+	 * </ul>
+	 */
+	public void getSelectedColumns(AccessibleTableEvent e) {}
+
+	/**
+	 * Returns the number of selected rows.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] count - the number of rows currently selected</li>
+	 * </ul>
+	 */
+	public void getSelectedRowCount(AccessibleTableEvent e) {}
+
+	/**
+	 * Returns the row indexes that are currently selected.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] selected - an array of 0 based row indexes of selected rows</li>
+	 * </ul>
+	 */
+	public void getSelectedRows(AccessibleTableEvent e) {}
+
+	/**
+	 * Returns the summary description of the table.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] accessible - the summary for the table,
+	 * 		or null if the table does not have a summary</li>
+	 * </ul>
+	 */
+	public void getSummary(AccessibleTableEvent e) {}
+
+	/**
+	 * Returns the visible columns as an array of accessible objects.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] accessibles - an array of accessible objects representing visible columns,
+	 * 		or null if there are no visible columns</li>
+	 * </ul>
+	 */
+	public void getVisibleColumns(AccessibleTableEvent e) {}
+
+	/**
+	 * Returns the visible rows as an array of accessible objects.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] accessibles - an array of accessible objects representing visible rows,
+	 * 		or null if there are no visible rows</li>
+	 * </ul>
+	 */
+	public void getVisibleRows(AccessibleTableEvent e) {}
+
+	/**
+	 * Returns a boolean value indicating whether the specified column is
+	 * completely selected.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] column - 0 based index of the column for which to determine whether it is selected</li>
+	 * <li>[out] isSelected - true if the specified column is selected completely, and false otherwise</li>
+	 * </ul>
+	 */
+	public void isColumnSelected(AccessibleTableEvent e) {}
+
+	/**
+	 * Returns a boolean value indicating whether the specified row is
+	 * completely selected.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] row - 0 based index of the row for which to determine whether it is selected</li>
+	 * <li>[out] isSelected - true if the specified row is selected completely, and false otherwise</li>
+	 * </ul>
+	 */
+	public void isRowSelected(AccessibleTableEvent e) {}
+
+	/**
+	 * Selects a column.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] column - 0 based index of the column to be selected</li>
+	 * <li>[out] result - set to {@link ACC#OK} if the column was selected.</li>
+	 * </ul>
+	 */
+	public void selectColumn(AccessibleTableEvent e) {}
+
+	/**
+	 * Selects a row.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] row - 0 based index of the row to be selected</li>
+	 * <li>[out] result - set to {@link ACC#OK} if the row was selected.</li>
+	 * </ul>
+	 */
+	public void selectRow(AccessibleTableEvent e) {}
+
+	/**
+	 * Selects a column and deselects all previously selected columns.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] column - 0 based index of the column to be selected</li>
+	 * <li>[out] result - set to {@link ACC#OK} if the column was selected.</li>
+	 * </ul>
+	 */
+	public void setSelectedColumn(AccessibleTableEvent e) {}
+
+	/**
+	 * Selects a row and deselects all previously selected rows.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] row - 0 based index of the row to be selected</li>
+	 * <li>[out] result - set to {@link ACC#OK} if the row was selected.</li>
+	 * </ul>
+	 */
+	public void setSelectedRow(AccessibleTableEvent e) {}
+}
diff --git a/org/eclipse/swt/accessibility/AccessibleTableCellAdapter.java b/org/eclipse/swt/accessibility/AccessibleTableCellAdapter.java
new file mode 100644
index 0000000..cc0835f
--- /dev/null
+++ b/org/eclipse/swt/accessibility/AccessibleTableCellAdapter.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.accessibility;
+
+/**
+ * This adapter class provides default implementations for the
+ * methods in the <code>AccessibleTableCellListener</code> interface.
+ * <p>
+ * Classes that wish to deal with <code>AccessibleTableCell</code> events can
+ * extend this class and override only the methods that they are
+ * interested in.
+ * </p>
+ *
+ * @see AccessibleTableCellListener
+ * @see AccessibleTableCellEvent
+ *
+ * @since 3.6
+ */
+public class AccessibleTableCellAdapter implements AccessibleTableCellListener {
+	/**
+	 * Returns the number of columns occupied by this cell accessible.
+	 * <p>
+	 * This is 1 if the specified cell is only in one column, or
+	 * more than 1 if the specified cell spans multiple columns.
+	 * </p>
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] count - the 1 based number of columns spanned by the specified cell
+	 * </ul>
+	 */
+	public void getColumnSpan(AccessibleTableCellEvent e) {}
+
+	/**
+	 * Returns the column headers as an array of cell accessibles.
+	 * TODO: doc that this is a more efficient way to get headers of a cell than TableListener.getRow/ColHeaders
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] accessibles - an array of cell accessibles, or null if there are no column headers
+	 * </ul>
+	 */
+	public void getColumnHeaders(AccessibleTableCellEvent e) {}
+
+	/**
+	 * Translates this cell accessible into the corresponding column index.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] index - the 0 based column index of the specified cell,
+	 * 		or the index of the first column if the cell spans multiple columns
+	 * </ul>
+	 */
+	public void getColumnIndex(AccessibleTableCellEvent e) {}
+
+	/**
+	 * Returns the number of rows occupied by this cell accessible.
+	 * <p>
+	 * This is 1 if the specified cell is only in one row, or
+	 * more than 1 if the specified cell spans multiple rows.
+	 * </p>
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] count - the 1 based number of rows spanned by the specified cell
+	 * </ul>
+	 */
+	public void getRowSpan(AccessibleTableCellEvent e) {}
+
+	/**
+	 * Returns the row headers as an array of cell accessibles.
+	 * TODO: doc that this is a more efficient way to get headers of a cell than TableListener.getRow/ColHeaders
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] accessibles - an array of cell accessibles, or null if there are no row headers
+	 * </ul>
+	 */
+	public void getRowHeaders(AccessibleTableCellEvent e) {}
+
+	/**
+	 * Translates this cell accessible into the corresponding row index.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] index - the 0 based row index of the specified cell,
+	 * 		or the index of the first row if the cell spans multiple rows
+	 * </ul>
+	 */
+	public void getRowIndex(AccessibleTableCellEvent e) {}
+
+	/**
+	 * Returns the accessible for the table containing this cell.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] accessible - the accessible for the containing table
+	 * </ul>
+	 */
+	public void getTable(AccessibleTableCellEvent e) {}
+
+	/**
+	 * Returns a boolean value indicating whether this cell is selected.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] isSelected - true if the specified cell is selected and false otherwise
+	 * </ul>
+	 */
+	public void isSelected(AccessibleTableCellEvent e) {}
+}
diff --git a/org/eclipse/swt/accessibility/AccessibleTableCellEvent.java b/org/eclipse/swt/accessibility/AccessibleTableCellEvent.java
new file mode 100644
index 0000000..47ceff4
--- /dev/null
+++ b/org/eclipse/swt/accessibility/AccessibleTableCellEvent.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.accessibility;
+
+import org.eclipse.swt.internal.*;
+
+/**
+ * Instances of this class are sent as a result of accessibility clients
+ * sending AccessibleTableCell messages to an accessible object.
+ *
+ * @see AccessibleTableCellListener
+ * @see AccessibleTableCellAdapter
+ *
+ * @since 3.6
+ */
+public class AccessibleTableCellEvent extends SWTEventObject {
+
+	public Accessible accessible;
+	public Accessible[] accessibles;
+	public boolean isSelected;
+	public int count;
+	public int index;
+
+	static final long serialVersionUID = 7231059449172889781L;
+
+/**
+ * Constructs a new instance of this class.
+ *
+ * @param source the object that fired the event
+ */
+public AccessibleTableCellEvent(Object source) {
+	super(source);
+}
+
+/**
+ * Returns a string containing a concise, human-readable
+ * description of the receiver.
+ *
+ * @return a string representation of the event
+ */
+public String toString () {
+	return "AccessibleTableCellEvent {"
+		+ " accessibles=" + accessibles   //$NON-NLS-1$
+		+ " isSelected=" + isSelected   //$NON-NLS-1$
+		+ " count=" + count   //$NON-NLS-1$
+		+ " index=" + index   //$NON-NLS-1$
+		+ "}";  //$NON-NLS-1$
+}
+}
diff --git a/org/eclipse/swt/accessibility/AccessibleTableCellListener.java b/org/eclipse/swt/accessibility/AccessibleTableCellListener.java
new file mode 100644
index 0000000..93ed52e
--- /dev/null
+++ b/org/eclipse/swt/accessibility/AccessibleTableCellListener.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.accessibility;
+
+import org.eclipse.swt.internal.SWTEventListener;
+
+/**
+ * Classes which implement this interface provide methods
+ * that handle AccessibleTableCell events.
+ * <p>
+ * After creating an instance of a class that implements
+ * this interface it can be added to an accessible using the
+ * <code>addAccessibleTableCellListener</code> method and removed using
+ * the <code>removeAccessibleTableCellListener</code> method.
+ * </p>
+ *
+ * @see AccessibleTableCellAdapter
+ * @see AccessibleTableCellEvent
+ *
+ * @since 3.6
+ */
+public interface AccessibleTableCellListener extends SWTEventListener {
+	/**
+	 * Returns the number of columns occupied by this cell accessible.
+	 * <p>
+	 * This is 1 if the specified cell is only in one column, or
+	 * more than 1 if the specified cell spans multiple columns.
+	 * </p>
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] count - the 1 based number of columns spanned by the specified cell
+	 * </ul>
+	 */
+	public void getColumnSpan(AccessibleTableCellEvent e);
+
+	/**
+	 * Returns the column headers as an array of cell accessibles.
+	 * TODO: doc that this is a more efficient way to get headers of a cell than TableListener.getRow/ColHeaders
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] accessibles - an array of cell accessibles, or null if there are no column headers
+	 * </ul>
+	 */
+	public void getColumnHeaders(AccessibleTableCellEvent e);
+
+	/**
+	 * Translates this cell accessible into the corresponding column index.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] index - the 0 based column index of the specified cell,
+	 * 		or the index of the first column if the cell spans multiple columns
+	 * </ul>
+	 */
+	public void getColumnIndex(AccessibleTableCellEvent e);
+
+	/**
+	 * Returns the number of rows occupied by this cell accessible.
+	 * <p>
+	 * This is 1 if the specified cell is only in one row, or
+	 * more than 1 if the specified cell spans multiple rows.
+	 * </p>
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] count - the 1 based number of rows spanned by the specified cell
+	 * </ul>
+	 */
+	public void getRowSpan(AccessibleTableCellEvent e);
+
+	/**
+	 * Returns the row headers as an array of cell accessibles.
+	 * TODO: doc that this is a more efficient way to get headers of a cell than TableListener.getRow/ColHeaders
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] accessibles - an array of cell accessibles, or null if there are no row headers
+	 * </ul>
+	 */
+	public void getRowHeaders(AccessibleTableCellEvent e);
+
+	/**
+	 * Translates this cell accessible into the corresponding row index.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] index - the 0 based row index of the specified cell,
+	 * 		or the index of the first row if the cell spans multiple rows
+	 * </ul>
+	 */
+	public void getRowIndex(AccessibleTableCellEvent e);
+
+	/**
+	 * Returns the accessible for the table containing this cell.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] accessible - the accessible for the containing table
+	 * </ul>
+	 */
+	public void getTable(AccessibleTableCellEvent e);
+
+	/**
+	 * Returns a boolean value indicating whether this cell is selected.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] isSelected - true if the specified cell is selected and false otherwise
+	 * </ul>
+	 */
+	public void isSelected(AccessibleTableCellEvent e);
+}
diff --git a/org/eclipse/swt/accessibility/AccessibleTableEvent.java b/org/eclipse/swt/accessibility/AccessibleTableEvent.java
new file mode 100644
index 0000000..a4dcc9b
--- /dev/null
+++ b/org/eclipse/swt/accessibility/AccessibleTableEvent.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.accessibility;
+
+import org.eclipse.swt.internal.*;
+
+/**
+ * Instances of this class are sent as a result of accessibility clients
+ * sending AccessibleTable messages to an accessible object.
+ *
+ * @see AccessibleTableListener
+ * @see AccessibleTableAdapter
+ *
+ * @since 3.6
+ */
+public class AccessibleTableEvent extends SWTEventObject {
+
+	public Accessible accessible;
+	public Accessible[] accessibles;
+	
+	/**
+	 * The value of this field must be set in the accessible table listener method
+	 * before returning. What to set it to depends on the listener method called.
+	 */
+	public String result;
+	
+	public int column;
+	public int row;
+	public int count;
+	public boolean isSelected;
+	public int[] selected;
+
+	static final long serialVersionUID = 1624586163666270447L;
+
+/**
+ * Constructs a new instance of this class.
+ *
+ * @param source the object that fired the event
+ */
+public AccessibleTableEvent(Object source) {
+	super(source);
+}
+
+/**
+ * Returns a string containing a concise, human-readable
+ * description of the receiver.
+ *
+ * @return a string representation of the event
+ */
+public String toString () {
+	return "AccessibleTableEvent {"
+		+ "accessible=" + accessible   //$NON-NLS-1$
+		+ " accessibles=" + accessibles   //$NON-NLS-1$
+		+ " string=" + result   //$NON-NLS-1$
+		+ " isSelected=" + isSelected   //$NON-NLS-1$
+		+ " column=" + column   //$NON-NLS-1$
+		+ " count=" + count   //$NON-NLS-1$
+		+ " row=" + row   //$NON-NLS-1$
+		+ " selected=" + selected   //$NON-NLS-1$
+		+ "}";  //$NON-NLS-1$
+}
+}
diff --git a/org/eclipse/swt/accessibility/AccessibleTableListener.java b/org/eclipse/swt/accessibility/AccessibleTableListener.java
new file mode 100644
index 0000000..65deb59
--- /dev/null
+++ b/org/eclipse/swt/accessibility/AccessibleTableListener.java
@@ -0,0 +1,344 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.accessibility;
+
+import org.eclipse.swt.internal.SWTEventListener;
+
+/**
+ * Classes which implement this interface provide methods
+ * that handle AccessibleTable events.
+ * <p>
+ * After creating an instance of a class that implements
+ * this interface it can be added to an accessible using the
+ * <code>addAccessibleTableListener</code> method and removed using
+ * the <code>removeAccessibleTableListener</code> method.
+ * </p><p>
+ * Many methods in this listener return cell accessible objects,
+ * which should implement <code>AccessibleTableCellListener</code>.
+ * </p>
+ *
+ * @see AccessibleTableAdapter
+ * @see AccessibleTableEvent
+ * @see AccessibleTableCellListener
+ * @see AccessibleTableCellEvent
+ *
+ * @since 3.6
+ */
+public interface AccessibleTableListener extends SWTEventListener {
+	/**
+	 * Deselects one column, leaving other selected columns selected (if any).
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] column - 0 based index of the column to be unselected.</li>
+	 * <li>[out] result - set to {@link ACC#OK} if the column was deselected.</li>
+	 * </ul>
+	 */
+	public void deselectColumn(AccessibleTableEvent e);
+
+	/**
+	 * Deselects one row, leaving other selected rows selected (if any).
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] row - 0 based index of the row to be unselected</li>
+	 * <li>[out] result - set to {@link ACC#OK} if the row was deselected.</li>
+	 * </ul>
+	 */
+	public void deselectRow(AccessibleTableEvent e);
+
+	/**
+	 * Returns the caption for the table.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] accessible - the caption for the table, or null if the table does not have a caption</li>
+	 * </ul>
+	 */
+	public void getCaption(AccessibleTableEvent e);
+
+	/**
+	 * Returns the accessible object at the specified row and column in the table.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] row - the 0 based row index for which to retrieve the accessible cell</li>
+	 * <li>[in] column - the 0 based column index for which to retrieve the accessible cell</li>
+	 * <li>[out] accessible - the table cell at the specified row and column index,
+	 * 		or null if the row or column index are not valid</li>
+	 * </ul>
+	 */
+	public void getCell(AccessibleTableEvent e);
+
+	/**
+	 * Returns the accessible object for the specified column in the table.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] column - the 0 based column index for which to retrieve the accessible column</li>
+	 * <li>[out] accessible - the table column at the specified column index,
+	 * 		or null if the column index is not valid</li>
+	 * </ul>
+	 */
+	public void getColumn(AccessibleTableEvent e);
+
+	/**
+	 * Returns the total number of columns in the table.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] count - the number of columns in the table</li>
+	 * </ul>
+	 */
+	public void getColumnCount(AccessibleTableEvent e);
+
+	/**
+	 * Returns the description text of the specified column in the table.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] column - the 0 based index of the column for which to retrieve the description</li>
+	 * <li>[out] result - the description text of the specified column in the table,
+	 * 		or null if the column does not have a description</li>
+	 * </ul>
+	 */
+	public void getColumnDescription(AccessibleTableEvent e);
+
+	/**
+	 * Returns the accessible object for the column header.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] accessible - an accessible object representing the column header,
+	 * 		or null if there is no column header</li>
+	 * </ul>
+	 */
+	public void getColumnHeader(AccessibleTableEvent e);
+
+	/**
+	 * Returns the column header cells as an array of accessible objects.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] accessibles - an array of accessible objects representing column header cells,
+	 * 		or null if there are no column header cells</li>
+	 * </ul>
+	 */
+	public void getColumnHeaderCells(AccessibleTableEvent e);
+
+	/**
+	 * Returns the columns as an array of accessible objects.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] accessibles - an array of accessible objects representing columns,
+	 * 		or null if there are no columns</li>
+	 * </ul>
+	 */
+	public void getColumns(AccessibleTableEvent e);
+
+	/**
+	 * Returns the accessible object for the specified row in the table.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] row - the 0 based row index for which to retrieve the accessible row</li>
+	 * <li>[out] accessible - the table row at the specified row index,
+	 * 		or null if the row index is not valid</li>
+	 * </ul>
+	 */
+	public void getRow(AccessibleTableEvent e);
+
+	/**
+	 * Returns the total number of rows in the table.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] count - the number of rows in the table</li>
+	 * </ul>
+	 */
+	public void getRowCount(AccessibleTableEvent e);
+
+	/**
+	 * Returns the description text of the specified row in the table.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] row - the 0 based index of the row for which to retrieve the description</li>
+	 * <li>[out] result - the description text of the specified row in the table,
+	 * 		or null if the row does not have a description</li>
+	 * </ul>
+	 */
+	public void getRowDescription(AccessibleTableEvent e);
+
+	/**
+	 * Returns the accessible object for the row header.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] accessible - an accessible object representing the row header,
+	 * 		or null if there is no row header</li>
+	 * </ul>
+	 */
+	public void getRowHeader(AccessibleTableEvent e);
+
+	/**
+	 * Returns the row header cells as an array of accessible objects.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] accessibles - an array of accessible objects representing row header cells,
+	 * 		or null if there are no row header cells</li>
+	 * </ul>
+	 */
+	public void getRowHeaderCells(AccessibleTableEvent e);
+
+	/**
+	 * Returns the rows as an array of accessible objects.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] accessibles - an array of accessible objects representing rows,
+	 * 		or null if there are no rows</li>
+	 * </ul>
+	 */
+	public void getRows(AccessibleTableEvent e);
+
+	/**
+	 * Returns the number of selected cells.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] count -  the number of cells currently selected</li>
+	 * </ul>
+	 */
+	public void getSelectedCellCount(AccessibleTableEvent e);
+
+	/**
+	 * Returns the currently selected cells.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] accessibles - array containing the selected accessible cells</li>
+	 * </ul>
+	 */
+	public void getSelectedCells(AccessibleTableEvent e);
+
+	/**
+	 * Returns the number of selected columns.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] count - the number of columns currently selected</li>
+	 * </ul>
+	 */
+	public void getSelectedColumnCount(AccessibleTableEvent e);
+
+	/**
+	 * Returns the column indexes that are currently selected.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] selected - an array of 0 based column indexes of selected columns</li>
+	 * </ul>
+	 */
+	public void getSelectedColumns(AccessibleTableEvent e);
+
+	/**
+	 * Returns the number of selected rows.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] count - the number of rows currently selected</li>
+	 * </ul>
+	 */
+	public void getSelectedRowCount(AccessibleTableEvent e);
+
+	/**
+	 * Returns the row indexes that are currently selected.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] selected - an array of 0 based row indexes of selected rows</li>
+	 * </ul>
+	 */
+	public void getSelectedRows(AccessibleTableEvent e);
+
+	/**
+	 * Returns the summary description of the table.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] accessible - the summary for the table,
+	 * 		or null if the table does not have a summary</li>
+	 * </ul>
+	 */
+	public void getSummary(AccessibleTableEvent e);
+
+	/**
+	 * Returns the visible columns as an array of accessible objects.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] accessibles - an array of accessible objects representing visible columns,
+	 * 		or null if there are no visible columns</li>
+	 * </ul>
+	 */
+	public void getVisibleColumns(AccessibleTableEvent e);
+
+	/**
+	 * Returns the visible rows as an array of accessible objects.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] accessibles - an array of accessible objects representing visible rows,
+	 * 		or null if there are no visible rows</li>
+	 * </ul>
+	 */
+	public void getVisibleRows(AccessibleTableEvent e);
+
+	/**
+	 * Returns a boolean value indicating whether the specified column is
+	 * completely selected.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] column - 0 based index of the column for which to determine whether it is selected</li>
+	 * <li>[out] isSelected - true if the specified column is selected completely, and false otherwise</li>
+	 * </ul>
+	 */
+	public void isColumnSelected(AccessibleTableEvent e);
+
+	/**
+	 * Returns a boolean value indicating whether the specified row is
+	 * completely selected.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] row - 0 based index of the row for which to determine whether it is selected</li>
+	 * <li>[out] isSelected - true if the specified row is selected completely, and false otherwise</li>
+	 * </ul>
+	 */
+	public void isRowSelected(AccessibleTableEvent e);
+
+	/**
+	 * Selects a column.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] column - 0 based index of the column to be selected</li>
+	 * <li>[out] result - set to {@link ACC#OK} if the column was selected.</li>
+	 * </ul>
+	 */
+	public void selectColumn(AccessibleTableEvent e);
+
+	/**
+	 * Selects a row.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] row - 0 based index of the row to be selected</li>
+	 * <li>[out] result - set to {@link ACC#OK} if the row was selected.</li>
+	 * </ul>
+	 */
+	public void selectRow(AccessibleTableEvent e);
+
+	/**
+	 * Selects a column and deselects all previously selected columns.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] column - 0 based index of the column to be selected</li>
+	 * <li>[out] result - set to {@link ACC#OK} if the column was selected.</li>
+	 * </ul>
+	 */
+	public void setSelectedColumn(AccessibleTableEvent e);
+
+	/**
+	 * Selects a row and deselects all previously selected rows.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] row - 0 based index of the row to be selected</li>
+	 * <li>[out] result - set to {@link ACC#OK} if the row was selected.</li>
+	 * </ul>
+	 */
+	public void setSelectedRow(AccessibleTableEvent e);
+}
diff --git a/org/eclipse/swt/accessibility/AccessibleTextAttributeEvent.java b/org/eclipse/swt/accessibility/AccessibleTextAttributeEvent.java
new file mode 100644
index 0000000..96dc631
--- /dev/null
+++ b/org/eclipse/swt/accessibility/AccessibleTextAttributeEvent.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.accessibility;
+
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.internal.*;
+
+/**
+ * Instances of this class are sent as a result of accessibility clients
+ * sending AccessibleAttribute messages to an accessible object.
+ *
+ * @see AccessibleAttributeListener
+ * @see AccessibleAttributeAdapter
+ *
+ * @since 3.6
+ */
+public class AccessibleTextAttributeEvent extends SWTEventObject {
+
+	public int offset;
+	public int start, end;
+	public TextStyle textStyle;
+	public String [] attributes;
+
+	static final long serialVersionUID = 0L; // TODO: run serialver -show
+
+/**
+ * Constructs a new instance of this class.
+ *
+ * @param source the object that fired the event
+ */
+public AccessibleTextAttributeEvent(Object source) {
+	super(source);
+}
+
+/**
+ * Returns a string containing a concise, human-readable
+ * description of the receiver.
+ *
+ * @return a string representation of the event
+ */
+public String toString () {
+	return "AccessibleAttributeEvent {"
+		+ " offset=" + offset   //$NON-NLS-1$
+		+ " startOffset=" + start   //$NON-NLS-1$
+		+ " endOffset=" + end   //$NON-NLS-1$
+		+ " textStyle=" + textStyle   //$NON-NLS-1$
+		+ "}";  //$NON-NLS-1$
+}
+}
diff --git a/org/eclipse/swt/accessibility/AccessibleTextEvent.java b/org/eclipse/swt/accessibility/AccessibleTextEvent.java
index 30e99eb..ce56485 100644
--- a/org/eclipse/swt/accessibility/AccessibleTextEvent.java
+++ b/org/eclipse/swt/accessibility/AccessibleTextEvent.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -11,6 +11,7 @@
 package org.eclipse.swt.accessibility;
 
 
+import org.eclipse.swt.graphics.Rectangle;
 import org.eclipse.swt.internal.*;
 
 /**
@@ -33,6 +34,30 @@ import org.eclipse.swt.internal.*;
 public class AccessibleTextEvent extends SWTEventObject {
 	public int childID;				// IN
 	public int offset, length;		// OUT
+	/** @since 3.6 */
+	public Accessible accessible;
+
+	/**
+	 * The value of this field must be set in the accessible text extended listener method
+	 * before returning. What to set it to depends on the listener method called.
+	 * @since 3.6
+	 */
+	public String result;
+	
+	/** @since 3.6 */
+	public int count;
+	/** @since 3.6 */
+	public int index;
+	/** @since 3.6 */
+	public int start, end;
+	/** @since 3.6 */
+	public int type;
+	/** @since 3.6 */
+	public int x, y, width, height;
+	/** @since 3.6 */
+	public int [] ranges;
+	/** @since 3.6 */
+	public Rectangle [] rectangles;
 	
 	static final long serialVersionUID = 3977019530868308275L;
 	
diff --git a/org/eclipse/swt/accessibility/AccessibleTextExtendedAdapter.java b/org/eclipse/swt/accessibility/AccessibleTextExtendedAdapter.java
new file mode 100644
index 0000000..d9fa74f
--- /dev/null
+++ b/org/eclipse/swt/accessibility/AccessibleTextExtendedAdapter.java
@@ -0,0 +1,292 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.accessibility;
+
+/**
+ * This adapter class provides default implementations for the
+ * methods in the <code>AccessibleTextExtendedListener</code> interface.
+ * <p>
+ * Classes that wish to deal with <code>AccessibleTextExtended</code> events can
+ * extend this class and override only the methods that they are
+ * interested in.
+ * </p>
+ *
+ * @see AccessibleTextExtendedListener
+ * @see AccessibleTextEvent
+ *
+ * @since 3.6
+ */
+public class AccessibleTextExtendedAdapter extends AccessibleTextAdapter implements AccessibleTextExtendedListener {
+	/**
+	 * Adds a text selection.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] start - the 0 based offset of the first character of the new selection</li>
+	 * <li>[in] end - the 0 based offset after the last character of the new selection</li>
+	 * <li>[out] result - set to {@link ACC#OK} if the text selection was added</li>
+	 * </ul>
+	 */
+	public void addSelection(AccessibleTextEvent e) {}
+
+	/**
+	 * Returns the total number of characters in the text.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] count - the total number of characters</li>
+	 * </ul>
+	 */
+	public void getCharacterCount(AccessibleTextEvent e) {}
+
+	/**
+	 * Returns the number of links and link groups contained within this hypertext
+	 * paragraph.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] count - the number of links and link groups within this hypertext paragraph,
+	 * 		or 0 if there are none</li>
+	 * </ul>
+	 */
+	public void getHyperlinkCount(AccessibleTextEvent e) {}
+
+	/**
+	 * Returns the specified hyperlink.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] index - the 0 based index of the hyperlink to return</li>
+	 * <li>[out] accessible - the specified hyperlink object, or null if the index is invalid</li>
+	 * </ul>
+	 */
+	public void getHyperlink(AccessibleTextEvent e) {}
+
+	/**
+	 * Returns the index of the hyperlink that is associated with this character offset.
+	 * <p>
+	 * This is the case when a link spans the given character index.
+	 * </p>
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] offset - the 0 based offset of the character for which to return the link index</li>
+	 * <li>[out] index - the 0 based index of the hyperlink that is associated with this
+	 * 		character offset, or -1 if the offset is not in a link</li>
+	 * </ul>
+	 */
+	public void getHyperlinkIndex(AccessibleTextEvent e) {}
+
+	/**
+	 * Returns the offset of the character under the specified point.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] x - the X value in display coordinates for which to look up the offset of the character
+	 * 		that is rendered on the display at that point</li>
+	 * <li>[in] y - the position's Y value for which to look up the offset of the character
+	 * 		that is rendered on the display at that point</li>
+	 * <li>[out] offset - the 0 based offset of the character under the given point,
+	 * 		or -1 if the point is invalid or there is no character under the point</li>
+	 * </ul>
+	 */
+	public void getOffsetAtPoint(AccessibleTextEvent e) {}
+
+	/**
+	 * Returns the text range(s) contained within the given bounding box.
+	 * <p>
+	 * Partially visible characters are included in the returned ranges.
+	 * </p>
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] x - the X coordinate of the top left corner of the bounding box, in display relative coordinates</li>
+	 * <li>[in] y - the Y coordinate of the top left corner of the bounding box, in display relative coordinates</li>
+	 * <li>[in] width - the width of the bounding box</li>
+	 * <li>[in] height - the height of the bounding box</li>
+	 * <li>[typical out] start - the 0 based offset of the first character of the substring in the bounding box</li>
+	 * <li>[typical out] end - the 0 based offset after the last character of the substring in the bounding box</li>
+	 * <li>[optional out] ranges - an array of pairs specifying the start and end offsets of each range,
+	 * 		if the text range is clipped by the bounding box</li>
+	 * </ul>
+	 */
+	public void getRanges(AccessibleTextEvent e) {}
+
+	/**
+	 * Returns the character offsets of the specified text selection.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] index - the 0 based index of the selection</li>
+	 * <li>[out] start - the 0 based offset of first selected character</li>
+	 * <li>[out] end - the 0 based offset after the last selected character</li>
+	 * </ul>
+	 */
+	public void getSelection(AccessibleTextEvent e) {}
+
+	/**
+	 * Returns the number of active non-contiguous selections.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] count - the number of active non-contiguous selections</li>
+	 * </ul>
+	 */
+	public void getSelectionCount(AccessibleTextEvent e) {}
+
+	/**
+	 * Returns a substring and its range for the given range, count and boundary type.
+	 * <p>
+	 * Returns the substring of the specified boundary type that is located count
+	 * positions from the given character range. Also returns the start and end
+	 * offsets of the returned substring.
+	 * </p><p>
+	 * For example, if the boundary type is TEXT_BOUNDARY_WORD, then the complete
+	 * word that is located count words from the specified range is returned.
+	 * If count is negative, then return the word that is count words before start.
+	 * If count is positive, then return the word that is count words after end.
+	 * If count is zero, start and end are the same, so return the word at start.
+	 * </p><p>
+	 * The whole text can be requested by passing start == 0 and end == getCharacterCount,
+	 * TEXT_BOUNDARY_ALL, and 0 for count. Alternatively the whole text can be requested
+	 * by calling AccessibleControlListener.getValue().
+	 * </p><p>
+	 * If start and end are valid, but no suitable word (or other boundary type) is found,
+	 * the returned string is null and the returned range is degenerate (start == end).
+	 * </p>
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] type - the boundary type of the substring to return. One of:<ul>
+	 * 		<li> {@link ACC#TEXT_BOUNDARY_CHAR}</li>
+	 * 		<li> {@link ACC#TEXT_BOUNDARY_WORD}</li>
+	 * 		<li> {@link ACC#TEXT_BOUNDARY_SENTENCE}</li>
+	 * 		<li> {@link ACC#TEXT_BOUNDARY_PARAGRAPH}</li>
+	 * 		<li> {@link ACC#TEXT_BOUNDARY_LINE}</li>
+	 * 		<li> {@link ACC#TEXT_BOUNDARY_ALL}</li>
+	 * 		</ul></li>
+	 * <li>[in,out] start - the 0 based offset of first character of the substring</li>
+	 * <li>[in,out] end - the 0 based offset after the last character of the substring</li>
+	 * <li>[in,out] count - the number of boundary type units to move to find the substring:<ul>
+	 * 		<li>in - look count units before start if count < 0, or after end if count > 0. Look at start if count == 0</li>
+	 * 		<li>out - the actual number of boundary type units that were moved. This may be fewer than the input count</li>
+	 * 		</ul></li>
+	 * <li>[out] result - the requested substring.  This may be empty or null
+	 * 		when no appropriate substring is found, or if the type is invalid.</li>
+	 * </ul>
+	 */
+	public void getText(AccessibleTextEvent e) {}
+
+	/**
+	 * Returns the bounding box(es) of the specified text range in display coordinates.
+	 * <p>
+	 * Typically, the text range will represent a single character, i.e. end - start = 1,
+	 * therefore providers should optimize for this case.
+	 * </p><p>
+	 * Note: The virtual character after the last character of the represented text,
+	 * i.e. the one at offset getCharacterCount, is a special case. It represents the
+	 * current input position and will therefore typically be queried by AT more
+	 * often than other positions.  Because it does not represent an existing character
+	 * its bounding box is defined in relation to preceding characters.  It should be
+	 * roughly equivalent to the bounding box of some character when inserted at the
+	 * end of the text; its height typically being the maximal height of all the
+	 * characters in the text or the height of the preceding character, its width
+	 * being at least one pixel so that the bounding box is not degenerate.
+	 * </p>
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] start - the 0 based offset of the first character of the substring in the bounding box</li>
+	 * <li>[in] end - the 0 based offset after the last character of the substring in the bounding box</li>
+	 * <li>[typical out] x - the X coordinate of the top left corner of the bounding box of the specified substring</li>
+	 * <li>[typical out] y - the Y coordinate of the top left corner of the bounding box of the specified substring</li>
+	 * <li>[typical out] width - the width of the bounding box of the specified substring</li>
+	 * <li>[typical out] height - the height of the bounding box of the specified substring</li>
+	 * <li>[optional out] rectangles - a set of disjoint bounding rectangles, if the specified text range includes
+	 * 		partial lines</li>
+	 * </ul>
+	 */
+	public void getTextBounds(AccessibleTextEvent e) {}
+
+	/**
+	 * Returns the visible text range(s).
+	 * <p>
+	 * Partially visible characters are included in the returned ranges.
+	 * </p>
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[typical out] start - the 0 based offset of the first character of the visible substring</li>
+	 * <li>[typical out] end - the 0 based offset after the last character of the visible substring</li>
+	 * <li>[optional out] ranges - an array of pairs specifying the start and end offsets of each range,
+	 * 		if the visible text range is clipped</li>
+	 * </ul>
+	 */
+	public void getVisibleRanges(AccessibleTextEvent e) {}
+
+	/**
+	 * Deselects a range of text.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] index - the 0 based index of selection to remove</li>
+	 * <li>[out] result - set to {@link ACC#OK} if the range of text was deselected</li>
+	 * </ul>
+	 */
+	public void removeSelection(AccessibleTextEvent e) {}
+
+	/**
+	 * Scrolls a specific part of a substring according to the scroll type.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] start - the 0 based offset of the first character of the substring</li>
+	 * <li>[in] end - the 0 based offset after the last character of the substring</li>
+	 * <li>[in] type - a scroll type indicating where the substring should be placed
+	 * 		on the screen. One of:<ul>
+	 * 		<li> {@link ACC#SCROLL_TYPE_TOP_LEFT}</li>
+	 * 		<li> {@link ACC#SCROLL_TYPE_BOTTOM_RIGHT}</li>
+	 * 		<li> {@link ACC#SCROLL_TYPE_TOP_EDGE}</li>
+	 * 		<li> {@link ACC#SCROLL_TYPE_BOTTOM_EDGE}</li>
+	 * 		<li> {@link ACC#SCROLL_TYPE_LEFT_EDGE}</li>
+	 * 		<li> {@link ACC#SCROLL_TYPE_RIGHT_EDGE}</li>
+	 * 		<li> {@link ACC#SCROLL_TYPE_ANYWHERE}</li>
+	 * 		<li> {@link ACC#SCROLL_TYPE_POINT}</li>
+	 * 		</ul></li>
+	 * <li>[optional in] x - for SCROLL_TYPE_POINT, the X coordinate of the destination point in display coordinates</li>
+	 * <li>[optional in] y - for SCROLL_TYPE_POINT, the Y coordinate of the destination point in display coordinates</li>
+	 * <li>[out] result - set to {@link ACC#OK} if the text was scrolled</li>
+	 * </ul>
+	 */
+	public void scrollText(AccessibleTextEvent e) {}
+
+	/**
+	 * Sets the position of the caret.
+	 * <p>
+	 * The caret position is that of the character logically following it,
+	 * e.g. to the right of it in a left to right language.
+	 * The caret is actually placed to the leading side of the character with
+	 * that offset. An offset of 0 places the caret so that the next insertion
+	 * goes before the first character. An offset of getCharacterCount places
+	 * the caret so that the next insertion goes after the last character.
+	 * </p><p>
+	 * Setting the caret position may or may not alter the current selection.  A
+	 * change of the selection is notified to the accessibility event listeners with
+	 * an EVENT_TEXT_SELECTION_CHANGED event.
+	 * </p><p>
+	 * When the new caret position differs from the old one, this is notified to the
+	 * accessibility event listeners with an EVENT_TEXT_CARET_MOVED event.
+	 * </p>
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] offset - the new offset of the caret</li>
+	 * <li>[out] result - set to {@link ACC#OK} if the caret position was set</li>
+	 * </ul>
+	 */
+	public void setCaretOffset(AccessibleTextEvent e) {}
+
+	/**
+	 * Changes the bounds of an existing selection.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] index - the 0 based index of the selection to change</li>
+	 * <li>[in] start - the new 0 based offset of the first character of the selection</li>
+	 * <li>[in] end - the new 0 based offset after the last character of the selection</li>
+	 * <li>[out] result - set to {@link ACC#OK} if the selection was set</li>
+	 * </ul>
+	 */
+	public void setSelection(AccessibleTextEvent e) {}
+}
diff --git a/org/eclipse/swt/accessibility/AccessibleTextExtendedListener.java b/org/eclipse/swt/accessibility/AccessibleTextExtendedListener.java
new file mode 100644
index 0000000..c4374ef
--- /dev/null
+++ b/org/eclipse/swt/accessibility/AccessibleTextExtendedListener.java
@@ -0,0 +1,293 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.accessibility;
+
+/**
+ * Classes which implement this interface provide methods
+ * that handle AccessibleTextExtended events.
+ * <p>
+ * After creating an instance of a class that implements
+ * this interface it can be added to an accessible using the
+ * <code>addAccessibleTextExtendedListener</code> method and removed using
+ * the <code>removeAccessibleTextExtendedListener</code> method.
+ * </p>
+ *
+ * @see AccessibleTextExtendedAdapter
+ * @see AccessibleTextEvent
+ *
+ * @since 3.6
+ */
+public interface AccessibleTextExtendedListener extends AccessibleTextListener {
+	/**
+	 * Adds a text selection.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] start - the 0 based offset of the first character of the new selection</li>
+	 * <li>[in] end - the 0 based offset after the last character of the new selection</li>
+	 * <li>[out] result - set to {@link ACC#OK} if the text selection was added</li>
+	 * </ul>
+	 */
+	public void addSelection(AccessibleTextEvent e);
+
+	/**
+	 * Returns the total number of characters in the text.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] count - the total number of characters</li>
+	 * </ul>
+	 */
+	public void getCharacterCount(AccessibleTextEvent e);
+
+	/**
+	 * Returns the number of links and link groups contained within this hypertext
+	 * paragraph.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] count - the number of links and link groups within this hypertext paragraph,
+	 * 		or 0 if there are none</li>
+	 * </ul>
+	 */
+	public void getHyperlinkCount(AccessibleTextEvent e);
+
+	/**
+	 * Returns the specified hyperlink.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] index - the 0 based index of the hyperlink to return</li>
+	 * <li>[out] accessible - the specified hyperlink object, or null if the index is invalid</li>
+	 * </ul>
+	 */
+	public void getHyperlink(AccessibleTextEvent e);
+
+	/**
+	 * Returns the index of the hyperlink that is associated with this character offset.
+	 * <p>
+	 * This is the case when a link spans the given character index.
+	 * </p>
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] offset - the 0 based offset of the character for which to return the link index</li>
+	 * <li>[out] index - the 0 based index of the hyperlink that is associated with this
+	 * 		character offset, or -1 if the offset is not in a link</li>
+	 * </ul>
+	 */
+	public void getHyperlinkIndex(AccessibleTextEvent e);
+
+	/**
+	 * Returns the offset of the character under the specified point.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] x - the X value in display coordinates for which to look up the offset of the character
+	 * 		that is rendered on the display at that point</li>
+	 * <li>[in] y - the position's Y value for which to look up the offset of the character
+	 * 		that is rendered on the display at that point</li>
+	 * <li>[out] offset - the 0 based offset of the character under the given point,
+	 * 		or -1 if the point is invalid or there is no character under the point</li>
+	 * </ul>
+	 */
+	public void getOffsetAtPoint(AccessibleTextEvent e);
+
+	/**
+	 * Returns the text range(s) contained within the given bounding box.
+	 * <p>
+	 * Partially visible characters are included in the returned ranges.
+	 * </p>
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] x - the X coordinate of the top left corner of the bounding box, in display relative coordinates</li>
+	 * <li>[in] y - the Y coordinate of the top left corner of the bounding box, in display relative coordinates</li>
+	 * <li>[in] width - the width of the bounding box</li>
+	 * <li>[in] height - the height of the bounding box</li>
+	 * <li>[typical out] start - the 0 based offset of the first character of the substring in the bounding box</li>
+	 * <li>[typical out] end - the 0 based offset after the last character of the substring in the bounding box</li>
+	 * <li>[optional out] ranges - an array of pairs specifying the start and end offsets of each range,
+	 * 		if the text range is clipped by the bounding box</li>
+	 * </ul>
+	 */
+	public void getRanges(AccessibleTextEvent e);
+
+	/**
+	 * Returns the character offsets of the specified text selection.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] index - the 0 based index of the selection</li>
+	 * <li>[out] start - the 0 based offset of first selected character</li>
+	 * <li>[out] end - the 0 based offset after the last selected character</li>
+	 * </ul>
+	 */
+	public void getSelection(AccessibleTextEvent e);
+
+	/**
+	 * Returns the number of active non-contiguous selections.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] count - the number of active non-contiguous selections</li>
+	 * </ul>
+	 */
+	public void getSelectionCount(AccessibleTextEvent e);
+
+	/**
+	 * Returns a substring and its range for the given range, count and boundary type.
+	 * <p>
+	 * Returns the substring of the specified boundary type that is located count
+	 * positions from the given character range. Also returns the start and end
+	 * offsets of the returned substring.
+	 * </p><p>
+	 * For example, if the boundary type is TEXT_BOUNDARY_WORD, then the complete
+	 * word that is located count words from the specified range is returned.
+	 * If count is negative, then return the word that is count words before start.
+	 * If count is positive, then return the word that is count words after end.
+	 * If count is zero, start and end are the same, so return the word at start.
+	 * </p><p>
+	 * The whole text can be requested by passing start == 0 and end == getCharacterCount,
+	 * TEXT_BOUNDARY_ALL, and 0 for count. Alternatively the whole text can be requested
+	 * by calling AccessibleControlListener.getValue().
+	 * </p><p>
+	 * If start and end are valid, but no suitable word (or other boundary type) is found,
+	 * the returned string is null and the returned range is degenerate (start == end).
+	 * </p>
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] type - the boundary type of the substring to return. One of:<ul>
+	 * 		<li> {@link ACC#TEXT_BOUNDARY_CHAR}</li>
+	 * 		<li> {@link ACC#TEXT_BOUNDARY_WORD}</li>
+	 * 		<li> {@link ACC#TEXT_BOUNDARY_SENTENCE}</li>
+	 * 		<li> {@link ACC#TEXT_BOUNDARY_PARAGRAPH}</li>
+	 * 		<li> {@link ACC#TEXT_BOUNDARY_LINE}</li>
+	 * 		<li> {@link ACC#TEXT_BOUNDARY_ALL}</li>
+	 * 		</ul></li>
+	 * <li>[in,out] start - the 0 based offset of first character of the substring</li>
+	 * <li>[in,out] end - the 0 based offset after the last character of the substring</li>
+	 * <li>[in,out] count - the number of boundary type units to move to find the substring:<ul>
+	 * 		<li>in - look count units before start if count < 0, or after end if count > 0. Look at start if count == 0</li>
+	 * 		<li>out - the actual number of boundary type units that were moved. This may be fewer than the input count</li>
+	 * 		</ul></li>
+	 * <li>[out] result - the requested substring.  This may be empty or null
+	 * 		when no appropriate substring is found, or if the type is invalid.</li>
+	 * </ul>
+	 */
+	public void getText(AccessibleTextEvent e);
+
+	/**
+	 * Returns the bounding box(es) of the specified text range in display coordinates.
+	 * <p>
+	 * Typically, the text range will represent a single character, i.e. end - start = 1,
+	 * therefore providers should optimize for this case.
+	 * </p><p>
+	 * Note: The virtual character after the last character of the represented text,
+	 * i.e. the one at offset getCharacterCount, is a special case. It represents the
+	 * current input position and will therefore typically be queried by AT more
+	 * often than other positions.  Because it does not represent an existing character
+	 * its bounding box is defined in relation to preceding characters.  It should be
+	 * roughly equivalent to the bounding box of some character when inserted at the
+	 * end of the text; its height typically being the maximal height of all the
+	 * characters in the text or the height of the preceding character, its width
+	 * being at least one pixel so that the bounding box is not degenerate.
+	 * </p>
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] start - the 0 based offset of the first character of the substring in the bounding box</li>
+	 * <li>[in] end - the 0 based offset after the last character of the substring in the bounding box</li>
+	 * <li>[typical out] x - the X coordinate of the top left corner of the bounding box of the specified substring</li>
+	 * <li>[typical out] y - the Y coordinate of the top left corner of the bounding box of the specified substring</li>
+	 * <li>[typical out] width - the width of the bounding box of the specified substring</li>
+	 * <li>[typical out] height - the height of the bounding box of the specified substring</li>
+	 * <li>[optional out] rectangles - a set of disjoint bounding rectangles, if the specified text range includes
+	 * 		partial lines</li>
+	 * </ul>
+	 */
+	public void getTextBounds(AccessibleTextEvent e);
+
+	/**
+	 * Returns the visible text range(s).
+	 * <p>
+	 * Partially visible characters are included in the returned ranges.
+	 * </p>
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[typical out] start - the 0 based offset of the first character of the visible substring</li>
+	 * <li>[typical out] end - the 0 based offset after the last character of the visible substring</li>
+	 * <li>[optional out] ranges - an array of pairs specifying the start and end offsets of each range,
+	 * 		if the visible text range is clipped</li>
+	 * </ul>
+	 */
+	public void getVisibleRanges(AccessibleTextEvent e);
+
+	/**
+	 * Deselects a range of text.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] index - the 0 based index of selection to remove</li>
+	 * <li>[out] result - set to {@link ACC#OK} if the range of text was deselected</li>
+	 * </ul>
+	 */
+	public void removeSelection(AccessibleTextEvent e);
+
+	/**
+	 * Scrolls a specific part of a substring according to the scroll type.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] start - the 0 based offset of the first character of the substring</li>
+	 * <li>[in] end - the 0 based offset after the last character of the substring</li>
+	 * <li>[in] type - a scroll type indicating where the substring should be placed
+	 * 		on the screen. One of:<ul>
+	 * 		<li> {@link ACC#SCROLL_TYPE_TOP_LEFT}</li>
+	 * 		<li> {@link ACC#SCROLL_TYPE_BOTTOM_RIGHT}</li>
+	 * 		<li> {@link ACC#SCROLL_TYPE_TOP_EDGE}</li>
+	 * 		<li> {@link ACC#SCROLL_TYPE_BOTTOM_EDGE}</li>
+	 * 		<li> {@link ACC#SCROLL_TYPE_LEFT_EDGE}</li>
+	 * 		<li> {@link ACC#SCROLL_TYPE_RIGHT_EDGE}</li>
+	 * 		<li> {@link ACC#SCROLL_TYPE_ANYWHERE}</li>
+	 * 		<li> {@link ACC#SCROLL_TYPE_POINT}</li>
+	 * 		</ul></li>
+	 * <li>[optional in] x - for SCROLL_TYPE_POINT, the X coordinate of the destination point in display coordinates</li>
+	 * <li>[optional in] y - for SCROLL_TYPE_POINT, the Y coordinate of the destination point in display coordinates</li>
+	 * <li>[out] result - set to {@link ACC#OK} if the text was scrolled</li>
+	 * </ul>
+	 */
+	public void scrollText(AccessibleTextEvent e);
+
+	/**
+	 * Sets the position of the caret.
+	 * <p>
+	 * The caret position is that of the character logically following it,
+	 * e.g. to the right of it in a left to right language.
+	 * The caret is actually placed to the leading side of the character with
+	 * that offset. An offset of 0 places the caret so that the next insertion
+	 * goes before the first character. An offset of getCharacterCount places
+	 * the caret so that the next insertion goes after the last character.
+	 * </p><p>
+	 * Setting the caret position may or may not alter the current selection.  A
+	 * change of the selection is notified to the accessibility event listeners with
+	 * an EVENT_TEXT_SELECTION_CHANGED event.
+	 * </p><p>
+	 * When the new caret position differs from the old one, this is notified to the
+	 * accessibility event listeners with an EVENT_TEXT_CARET_MOVED event.
+	 * </p>
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] offset - the new offset of the caret</li>
+	 * <li>[out] result - set to {@link ACC#OK} if the caret position was set</li>
+	 * </ul>
+	 */
+	public void setCaretOffset(AccessibleTextEvent e);
+
+	/**
+	 * Changes the bounds of an existing selection.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in] index - the 0 based index of the selection to change</li>
+	 * <li>[in] start - the new 0 based offset of the first character of the selection</li>
+	 * <li>[in] end - the new 0 based offset after the last character of the selection</li>
+	 * <li>[out] result - set to {@link ACC#OK} if the selection was set</li>
+	 * </ul>
+	 */
+	public void setSelection(AccessibleTextEvent e);
+}
diff --git a/org/eclipse/swt/accessibility/AccessibleValueAdapter.java b/org/eclipse/swt/accessibility/AccessibleValueAdapter.java
new file mode 100644
index 0000000..bb9600a
--- /dev/null
+++ b/org/eclipse/swt/accessibility/AccessibleValueAdapter.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.accessibility;
+
+/**
+ * This adapter class provides default implementations for the
+ * methods in the <code>AccessibleValueListener</code> interface.
+ * <p>
+ * Classes that wish to deal with <code>AccessibleValue</code> events can
+ * extend this class and override only the methods that they are
+ * interested in.
+ * </p>
+ *
+ * @see AccessibleValueListener
+ * @see AccessibleValueEvent
+ *
+ * @since 3.6
+ */
+public class AccessibleValueAdapter implements AccessibleValueListener {
+	/**
+	 * Returns the value of this object as a number.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] value - the number that is the current value of this object</li>
+	 * </ul>
+	 */
+	public void getCurrentValue(AccessibleValueEvent e) {}
+
+	/**
+	 * Sets the value of this object to the given number.
+	 * 
+	 * The argument is clipped to the valid interval whose upper and lower
+	 * bounds are returned by getMaximumValue and getMinimumValue,
+	 * i.e. if it is lower than the minimum value the new value will be the minimum,
+	 * and if it is greater than the maximum then the new value will be the maximum.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in/out] value - on input, the number that will be the new value of this object
+	 * 		<br>- on output, set to null if the value cannot be set</li>
+	 * </ul>
+	 */
+	public void setCurrentValue(AccessibleValueEvent e) {}
+
+	/**
+	 * Returns the maximum value that can be represented by this object.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] value - the number that is the maximum value that this object can represent.
+	 * 		If this object has no upper bound then null is returned.</li>
+	 * </ul>
+	 */
+	public void getMaximumValue(AccessibleValueEvent e) {}
+
+	/**
+	 * Returns the minimum value that can be represented by this object.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] value - the number that is the minimum value that this object can represent.
+	 * 		If this object has no lower bound then null is returned.</li>
+	 * </ul>
+	 */
+	public void getMinimumValue(AccessibleValueEvent e) {}
+}
diff --git a/org/eclipse/swt/accessibility/AccessibleValueEvent.java b/org/eclipse/swt/accessibility/AccessibleValueEvent.java
new file mode 100644
index 0000000..de42982
--- /dev/null
+++ b/org/eclipse/swt/accessibility/AccessibleValueEvent.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.accessibility;
+
+import org.eclipse.swt.internal.*;
+
+/**
+ * Instances of this class are sent as a result of accessibility clients
+ * sending AccessibleValue messages to an accessible object.
+ *
+ * @see AccessibleValueListener
+ * @see AccessibleValueAdapter
+ *
+ * @since 3.6
+ */
+public class AccessibleValueEvent extends SWTEventObject {
+
+	public Number value;
+
+	static final long serialVersionUID = -465979079760740668L;
+
+/**
+ * Constructs a new instance of this class.
+ *
+ * @param source the object that fired the event
+ */
+public AccessibleValueEvent(Object source) {
+	super(source);
+}
+
+/**
+ * Returns a string containing a concise, human-readable
+ * description of the receiver.
+ *
+ * @return a string representation of the event
+ */
+public String toString () {
+	return "AccessibleValueEvent {"
+		+ "value=" + value   //$NON-NLS-1$
+		+ "}";  //$NON-NLS-1$
+}
+}
diff --git a/org/eclipse/swt/accessibility/AccessibleValueListener.java b/org/eclipse/swt/accessibility/AccessibleValueListener.java
new file mode 100644
index 0000000..bd557f2
--- /dev/null
+++ b/org/eclipse/swt/accessibility/AccessibleValueListener.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.accessibility;
+
+import org.eclipse.swt.internal.SWTEventListener;
+
+/**
+ * Classes which implement this interface provide methods
+ * that handle AccessibleValue events.
+ * <p>
+ * After creating an instance of a class that implements
+ * this interface it can be added to an accessible using the
+ * <code>addAccessibleValueListener</code> method and removed using
+ * the <code>removeAccessibleValueListener</code> method.
+ * </p>
+ *
+ * @see AccessibleValueAdapter
+ * @see AccessibleValueEvent
+ *
+ * @since 3.6
+ */
+public interface AccessibleValueListener extends SWTEventListener {
+	/**
+	 * Returns the value of this object as a number.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] value - the number that is the current value of this object</li>
+	 * </ul>
+	 */
+	public void getCurrentValue(AccessibleValueEvent e);
+
+	/**
+	 * Sets the value of this object to the given number.
+	 * 
+	 * The argument is clipped to the valid interval whose upper and lower
+	 * bounds are returned by getMaximumValue and getMinimumValue,
+	 * i.e. if it is lower than the minimum value the new value will be the minimum,
+	 * and if it is greater than the maximum then the new value will be the maximum.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[in/out] value - on input, the number that will be the new value of this object
+	 * 		<br>- on output, set to null if the value cannot be set</li>
+	 * </ul>
+	 */
+	public void setCurrentValue(AccessibleValueEvent e);
+
+	/**
+	 * Returns the maximum value that can be represented by this object.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] value - the number that is the maximum value that this object can represent.
+	 * 		If this object has no upper bound then null is returned.</li>
+	 * </ul>
+	 */
+	public void getMaximumValue(AccessibleValueEvent e);
+
+	/**
+	 * Returns the minimum value that can be represented by this object.
+	 * 
+	 * @param e an event object containing the following fields:<ul>
+	 * <li>[out] value - the number that is the minimum value that this object can represent.
+	 * 		If this object has no lower bound then null is returned.</li>
+	 * </ul>
+	 */
+	public void getMinimumValue(AccessibleValueEvent e);
+}
diff --git a/org/eclipse/swt/browser/AppFileLocProvider.java b/org/eclipse/swt/browser/AppFileLocProvider.java
index 8971565..ecb412a 100644
--- a/org/eclipse/swt/browser/AppFileLocProvider.java
+++ b/org/eclipse/swt/browser/AppFileLocProvider.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2003, 2008 IBM Corporation and others.
+ * 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
@@ -20,10 +20,10 @@ class AppFileLocProvider {
 	XPCOMObject directoryServiceProvider;
 	XPCOMObject directoryServiceProvider2;	
 	int refCount = 0;
-	String mozillaPath, profilePath, componentsPath;
+	String mozillaPath, profilePath;
 	String[] pluginDirs;
 	boolean isXULRunner;
-	
+
 	static final String SEPARATOR_OS = System.getProperty ("file.separator"); //$NON-NLS-1$
 	static final String CHROME_DIR = "chrome"; //$NON-NLS-1$
 	static final String COMPONENTS_DIR = "components"; //$NON-NLS-1$
@@ -41,8 +41,23 @@ class AppFileLocProvider {
 		IsSparc = (osName.startsWith ("sunos") || osName.startsWith ("solaris")) && osArch.startsWith("sparc"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
 	}
 	
-AppFileLocProvider (String path) {
-	mozillaPath = path + SEPARATOR_OS;
+AppFileLocProvider (String mozillaPath, String profilePath, boolean isXULRunner) {
+	this.mozillaPath = mozillaPath + SEPARATOR_OS;
+	this.profilePath = profilePath + SEPARATOR_OS;
+	this.isXULRunner = isXULRunner;
+	if (!Compatibility.fileExists (profilePath, "")) { //$NON-NLS-1$
+		int /*long*/[] result = new int /*long*/[1];
+		nsEmbedString pathString = new nsEmbedString (profilePath);
+		int 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 file = new nsILocalFile (result [0]);
+		rc = file.Create (nsILocalFile.DIRECTORY_TYPE, 0700);
+		if (rc != XPCOM.NS_OK) Mozilla.error (rc);
+		file.Release ();
+	}
 	createCOMInterfaces ();
 }
 
@@ -125,27 +140,6 @@ int Release () {
 	return refCount;
 }
 
-void setComponentsPath (String path) {
-	componentsPath = path;
-}
-
-void setProfilePath (String path) {
-	profilePath = path;
-	if (!Compatibility.fileExists (path, "")) { //$NON-NLS-1$
-		int /*long*/[] result = new int /*long*/[1];
-		nsEmbedString pathString = new nsEmbedString (path);
-		int 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 file = new nsILocalFile (result [0]);
-		rc = file.Create (nsILocalFile.DIRECTORY_TYPE, 0700);
-		if (rc != XPCOM.NS_OK) Mozilla.error (rc);
-		file.Release ();
-	}
-}
-
 /* nsIDirectoryServiceProvider2 */
 
 int getFiles (int /*long*/ prop, int /*long*/ _retval) {
@@ -285,7 +279,7 @@ int getFile(int /*long*/ prop, int /*long*/ persistent, int /*long*/ _retval) {
 	} else if (propertyName.equals (XPCOM.NS_GRE_DIR)) {
 		propertyValue = mozillaPath;
 	} else if (propertyName.equals (XPCOM.NS_GRE_COMPONENT_DIR)) {
-		propertyValue = componentsPath != null ? componentsPath : mozillaPath + COMPONENTS_DIR;
+		propertyValue = profilePath + COMPONENTS_DIR;
 	} else if (propertyName.equals (XPCOM.NS_XPCOM_INIT_CURRENT_PROCESS_DIR)) {
 		propertyValue = mozillaPath;
 	} else if (propertyName.equals (XPCOM.NS_OS_CURRENT_PROCESS_DIR)) {
diff --git a/org/eclipse/swt/browser/Browser.java b/org/eclipse/swt/browser/Browser.java
index 05fcc05..88c8297 100644
--- a/org/eclipse/swt/browser/Browser.java
+++ b/org/eclipse/swt/browser/Browser.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2003, 2009 IBM Corporation and others.
+ * Copyright (c) 2003, 2010 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
@@ -42,9 +42,11 @@ import org.eclipse.swt.widgets.*;
 public class Browser extends Composite {
 	WebBrowser webBrowser;
 	int userStyle;
+	boolean isClosing;
 
-	static final String PACKAGE_PREFIX = "org.eclipse.swt.browser."; //$NON-NLS-1$
 	static final String NO_INPUT_METHOD = "org.eclipse.swt.internal.gtk.noInputMethod"; //$NON-NLS-1$
+	static final String PACKAGE_PREFIX = "org.eclipse.swt.browser."; //$NON-NLS-1$
+	static final String PROPERTY_USEWEBKITGTK = "org.eclipse.swt.browser.UseWebKitGTK"; //$NON-NLS-1$
 
 /**
  * Constructs a new instance of this class given its parent
@@ -83,40 +85,46 @@ public Browser (Composite parent, int style) {
 	String platform = SWT.getPlatform ();
 	Display display = parent.getDisplay ();
 	if ("gtk".equals (platform)) display.setData (NO_INPUT_METHOD, null); //$NON-NLS-1$
-	String className = null;
+	String classNames[] = null;
 	if ((style & SWT.MOZILLA) != 0) {
-		className = "org.eclipse.swt.browser.Mozilla"; //$NON-NLS-1$
+		classNames = new String[] {"org.eclipse.swt.browser.Mozilla"}; //$NON-NLS-1$
 	} else {
 		if ("win32".equals (platform) || "wpf".equals (platform)) { //$NON-NLS-1$ $NON-NLS-2$
-			className = "org.eclipse.swt.browser.IE"; //$NON-NLS-1$
+			classNames = new String[] {"org.eclipse.swt.browser.IE"}; //$NON-NLS-1$
 		} else if ("motif".equals (platform)) { //$NON-NLS-1$
-			className = "org.eclipse.swt.browser.Mozilla"; //$NON-NLS-1$
+			classNames = new String[] {"org.eclipse.swt.browser.Mozilla"}; //$NON-NLS-1$
 		} else if ("gtk".equals (platform)) { //$NON-NLS-1$
-			className = "org.eclipse.swt.browser.Mozilla"; //$NON-NLS-1$
+			String property = System.getProperty (PROPERTY_USEWEBKITGTK);
+			if (property != null && property.equalsIgnoreCase ("true")) { //$NON-NLS-1$
+				classNames = new String[] {"org.eclipse.swt.browser.WebKit", "org.eclipse.swt.browser.Mozilla"}; //$NON-NLS-1$ //$NON-NLS-2$
+			} else {
+				classNames = new String[] {"org.eclipse.swt.browser.Mozilla"}; //$NON-NLS-1$
+			}
 		} else if ("carbon".equals (platform) || "cocoa".equals (platform)) { //$NON-NLS-1$
-			className = "org.eclipse.swt.browser.Safari"; //$NON-NLS-1$
+			classNames = new String[] {"org.eclipse.swt.browser.Safari"}; //$NON-NLS-1$
 		} else if ("photon".equals (platform)) { //$NON-NLS-1$
-			className = "org.eclipse.swt.browser.Voyager"; //$NON-NLS-1$
+			classNames = new String[] {"org.eclipse.swt.browser.Voyager"}; //$NON-NLS-1$
 		} else {
 			dispose ();
 			SWT.error (SWT.ERROR_NO_HANDLES);
 		}
 	}
 
-	try {
-		Class clazz = Class.forName (className);
-		webBrowser = (WebBrowser)clazz.newInstance ();
-	} catch (ClassNotFoundException e) {
-	} catch (IllegalAccessException e) {
-	} catch (InstantiationException e) {
-	}
-	if (webBrowser == null) {
-		dispose ();
-		SWT.error (SWT.ERROR_NO_HANDLES);
+	for (int i = 0; i < classNames.length; i++) {
+		try {
+			Class clazz = Class.forName (classNames[i]);
+			webBrowser = (WebBrowser)clazz.newInstance ();
+			if (webBrowser != null) {
+				webBrowser.setBrowser (this);
+				if (webBrowser.create (parent, style)) return;
+			}
+		} catch (ClassNotFoundException e) {
+		} catch (IllegalAccessException e) {
+		} catch (InstantiationException e) {
+		}
 	}
-
-	webBrowser.setBrowser (this);
-	webBrowser.create (parent, style);
+	dispose ();
+	SWT.error (SWT.ERROR_NO_HANDLES);
 }
 
 static Composite checkParent (Composite parent) {
@@ -198,7 +206,7 @@ public static String getCookie (String name, String url) {
  * Sets a cookie on a URL.  Note that cookies are shared amongst all Browser instances.
  * 
  * The <code>value</code> parameter must be a cookie header string that
- * complies with <a href="http://www.ietf.org/rfc/rfc2109.txt">RFC 2109</code>.
+ * complies with <a href="http://www.ietf.org/rfc/rfc2109.txt">RFC 2109</a>.
  * The value is passed through to the native browser unchanged.
  * <p>
  * Example value strings:
@@ -221,7 +229,7 @@ public static String getCookie (String name, String url) {
 public static boolean setCookie (String value, String url) {
 	if (value == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
 	if (url == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
-	return WebBrowser.SetCookie (value, url);
+	return WebBrowser.SetCookie (value, url, true);
 }
 
 /**	 
@@ -491,6 +499,33 @@ public boolean execute (String script) {
 }
 
 /**
+ * Attempts to dispose the receiver, but allows the dispose to be vetoed
+ * by the user in response to an <code>onbeforeunload</code> listener
+ * in the Browser's current page.
+ *
+ * @return <code>true</code> if the receiver was disposed, and <code>false</code> otherwise
+ * 
+ * @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 #dispose()
+ * 
+ * @since 3.6
+ */
+public boolean close () {
+	checkWidget();
+	if (webBrowser.close ()) {
+		isClosing = true;
+		dispose ();
+		isClosing = false;
+		return true;
+	}
+	return false;
+}
+
+/**
  * Returns the result, if any, of executing the specified script.
  * <p>
  * Evaluates a script containing javascript commands in the context of
@@ -560,7 +595,7 @@ public boolean forward () {
 
 /**
  * Returns the type of native browser being used by this instance.
- * Examples: "mozilla", "ie", "safari", "voyager"
+ * Examples: "ie", "mozilla", "voyager", "webkit"
  *
  * @return the type of the native browser
  * 
@@ -920,9 +955,10 @@ public void setJavascriptEnabled (boolean enabled) {
 
 /**
  * Renders a string containing HTML.  The rendering of the content occurs asynchronously.
- * 
+ * The rendered page will be given trusted permissions; to render the page with untrusted
+ * permissions use <code>setText(String html, boolean trusted)</code> instead.   
  * <p>
- * The html parameter is Unicode encoded since it is a java <code>String</code>.
+ * 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.
  * 
@@ -939,14 +975,56 @@ public void setJavascriptEnabled (boolean enabled) {
  *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
  * </ul>
  *  
+ * @see #setText(String,boolean)
  * @see #setUrl
  * 
  * @since 3.0
  */
 public boolean setText (String html) {
 	checkWidget();
+	return setText (html, true);
+}
+
+/**
+ * Renders a string containing HTML.  The rendering of the content occurs asynchronously.
+ * The rendered page can be given either trusted or untrusted permissions. 
+ * <p>
+ * The <code>html</code> 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.
+ * <p>
+ * The <code>trusted</code> parameter affects the permissions that will be granted to the rendered
+ * page.  Specifying <code>true</code> for trusted gives the page permissions equivalent
+ * to a page on the local file system, while specifying <code>false</code> for trusted
+ * gives the page permissions equivalent to a page from the internet.  Page content should
+ * be specified as trusted if the invoker created it or trusts its source, since this would
+ * allow (for instance) style sheets on the local file system to be referenced.  Page 
+ * content should be specified as untrusted if its source is not trusted or is not known.
+ * 
+ * @param html the HTML content to be rendered
+ * @param trusted <code>false</code> if the rendered page should be granted restricted
+ * permissions and <code>true</code> otherwise
+ *
+ * @return <code>true</code> if the operation was successful and <code>false</code> 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 #setText(String)
+ * @see #setUrl
+ * 
+ * @since 3.6
+ */
+public boolean setText (String html, boolean trusted) {
+	checkWidget();
 	if (html == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
-	return webBrowser.setText (html);
+	return webBrowser.setText (html, trusted);
 }
 
 /**
@@ -966,13 +1044,45 @@ public boolean setText (String html) {
  * </ul>
  *  
  * @see #getUrl
+ * @see #setUrl(String,String,String[])
  * 
  * @since 3.0
  */
 public boolean setUrl (String url) {
 	checkWidget();
+	return setUrl (url, null, null);
+}
+
+/**
+ * Begins loading a URL.  The loading of its content occurs asynchronously.
+ * <p>
+ * If the URL causes an HTTP request to be initiated then the provided
+ * <code>postData</code> and <code>header</code> arguments, if any, are
+ * sent with the request.  A value in the <code>headers</code> argument
+ * must be a name-value pair with a colon separator in order to be sent
+ * (for example: "<code>user-agent: custom</code>").
+ * 
+ * @param url the URL to be loaded
+ * @param postData post data to be sent with the request, or <code>null</code>
+ * @param headers header lines to be sent with the request, or <code>null</code> 
+ *
+ * @return <code>true</code> if the operation was successful and <code>false</code> 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>
+ * 
+ * @since 3.6
+ */
+public boolean setUrl (String url, String postData, String[] headers) {
+	checkWidget();
 	if (url == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
-	return webBrowser.setUrl (url);
+	return webBrowser.setUrl (url, postData, headers);
 }
 
 /**
diff --git a/org/eclipse/swt/browser/Download.java b/org/eclipse/swt/browser/Download.java
index b648b33..3114c9a 100644
--- a/org/eclipse/swt/browser/Download.java
+++ b/org/eclipse/swt/browser/Download.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2003, 2008 IBM Corporation and others.
+ * Copyright (c) 2003, 2010 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
@@ -238,8 +238,8 @@ int Init (int /*long*/ aSource, int /*long*/ aTarget, int /*long*/ aDisplayName,
 	gridLayout.verticalSpacing = 20;
 	shell.setLayout(gridLayout);
 	msg = Compatibility.getMessage ("SWT_Download_Location", new Object[] {filename, url}); //$NON-NLS-1$
-	new Label (shell, SWT.SIMPLE).setText (msg);
-	status = new Label (shell, SWT.SIMPLE);
+	new Label (shell, SWT.WRAP).setText (msg);
+	status = new Label (shell, SWT.WRAP);
 	msg = Compatibility.getMessage ("SWT_Download_Started"); //$NON-NLS-1$
 	status.setText (msg);
 	GridData data = new GridData ();
diff --git a/org/eclipse/swt/browser/Download_1_8.java b/org/eclipse/swt/browser/Download_1_8.java
index 82819f1..3ec20e7 100644
--- a/org/eclipse/swt/browser/Download_1_8.java
+++ b/org/eclipse/swt/browser/Download_1_8.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2003, 2008 IBM Corporation and others.
+ * Copyright (c) 2003, 2010 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
@@ -256,8 +256,8 @@ int Init (int /*long*/ aSource, int /*long*/ aTarget, int /*long*/ aDisplayName,
 	gridLayout.verticalSpacing = 20;
 	shell.setLayout (gridLayout);
 	msg = Compatibility.getMessage ("SWT_Download_Location", new Object[] {filename, url}); //$NON-NLS-1$
-	new Label (shell, SWT.SIMPLE).setText (msg);
-	status = new Label (shell, SWT.SIMPLE);
+	new Label (shell, SWT.WRAP).setText (msg);
+	status = new Label (shell, SWT.WRAP);
 	msg = Compatibility.getMessage ("SWT_Download_Started"); //$NON-NLS-1$
 	status.setText (msg);
 	GridData data = new GridData ();
diff --git a/org/eclipse/swt/browser/External.java b/org/eclipse/swt/browser/External.java
index 53ed58f..e888c32 100644
--- a/org/eclipse/swt/browser/External.java
+++ b/org/eclipse/swt/browser/External.java
@@ -503,7 +503,10 @@ nsIVariant convertToJS (Object value, nsIComponentManager componentManager) {
 	if (value instanceof Object[]) {
 		Object[] arrayValue = (Object[])value;
 		int length = arrayValue.length;
-		if (length > 0) {
+		if (length == 0) {
+			rc = variant.SetAsEmptyArray ();
+			if (rc != XPCOM.NS_OK) Mozilla.error (rc);
+		} else {
 			int /*long*/ arrayPtr = C.malloc (C.PTR_SIZEOF * length);
 			for (int i = 0; i < length; i++) {
 				Object currentObject = arrayValue[i];
@@ -529,8 +532,8 @@ nsIVariant convertToJS (Object value, nsIComponentManager componentManager) {
 			C.free (idPtr);
 			C.free (arrayPtr);
 			if (rc != XPCOM.NS_OK) Mozilla.error (rc);
-			return variant;
 		}
+		return variant;
 	}
 
 	variant.Release ();
diff --git a/org/eclipse/swt/browser/InputStream.java b/org/eclipse/swt/browser/InputStream.java
index 3440fbb..8a5d967 100644
--- a/org/eclipse/swt/browser/InputStream.java
+++ b/org/eclipse/swt/browser/InputStream.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2003, 2007 IBM Corporation and others.
+ * 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
@@ -108,7 +108,10 @@ int Read(int /*long*/ aBuf, int aCount, int /*long*/ _retval) {
 }
 
 int ReadSegments (int /*long*/ aWriter, int /*long*/ aClosure, int aCount, int /*long*/ _retval) {
-	int max = Math.min (aCount, buffer == null ? 0 : buffer.length - index);
+	int max = buffer == null ? 0 : buffer.length - index;
+	if (aCount != -1) {
+		max = Math.min (max, aCount);
+	}
 	int cnt = max;
 	while (cnt > 0) {
 		int[] aWriteCount = new int[1];
diff --git a/org/eclipse/swt/browser/Mozilla.java b/org/eclipse/swt/browser/Mozilla.java
index 9cbf020..30d6b71 100644
--- a/org/eclipse/swt/browser/Mozilla.java
+++ b/org/eclipse/swt/browser/Mozilla.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2003, 2009 IBM Corporation and others.
+ * Copyright (c) 2003, 2010 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
@@ -42,11 +42,14 @@ class Mozilla extends WebBrowser {
 	XPCOMObject tooltipListener;
 	XPCOMObject domEventListener;
 	XPCOMObject badCertListener;
+
 	int chromeFlags = nsIWebBrowserChrome.CHROME_DEFAULT;
+	int registerFunctionsOnState = 0;
 	int refCount, lastKeyCode, lastCharCode, authCount;
 	int /*long*/ request;
 	Point location, size;
-	boolean visible, isChild, ignoreDispose, isRetrievingBadCert, isViewingErrorPage;
+	boolean visible, isChild, ignoreDispose, isRetrievingBadCert, isViewingErrorPage, ignoreAllMessages, untrustedText;
+	boolean updateLastNavigateUrl;
 	Shell tip = null;
 	Listener listener;
 	Vector unhookedDOMWindows = new Vector ();
@@ -57,8 +60,13 @@ class Mozilla extends WebBrowser {
 	static AppFileLocProvider LocationProvider;
 	static WindowCreator2 WindowCreator;
 	static int BrowserCount, NextJSFunctionIndex = 1;
-	static Hashtable AllFunctions = new Hashtable (); 
+	static Hashtable AllFunctions = new Hashtable ();
+	static Listener DisplayListener;
 	static boolean Initialized, IsPre_1_8, IsPre_1_9, PerformedVersionCheck, XPCOMWasGlued, XPCOMInitWasGlued;
+	static String oldProxyHostFTP, oldProxyHostHTTP, oldProxyHostSSL;
+	static int oldProxyPortFTP = -1, oldProxyPortHTTP = -1, oldProxyPortSSL = -1, oldProxyType = -1;
+	static byte[] pathBytes_JSEvaluateUCScriptForPrincipals;
+	static byte[] pathBytes_NSFree;
 
 	/* XULRunner detect constants */
 	static final String GRERANGE_LOWER = "1.8.1.2"; //$NON-NLS-1$
@@ -68,13 +76,18 @@ class Mozilla extends WebBrowser {
 	static final boolean UpperRangeInclusive = true;
 
 	static final int MAX_PORT = 65535;
+	static final String DEFAULTVALUE_STRING = "default"; //$NON-NLS-1$
 	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 HEADER_CONTENTTYPE = "Content-Type"; //$NON-NLS-1
+	static final String MIMETYPE_FORMURLENCODED = "application/x-www-form-urlencoded"; //$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_DISABLEOPENWINDOWSTATUSHIDE = "dom.disable_window_open_feature.status"; //$NON-NLS-1$
 	static final String PREFERENCE_DISABLEWINDOWSTATUSCHANGE = "dom.disable_window_status_change"; //$NON-NLS-1$
+	static final String PREFERENCE_JAVASCRIPTENABLED = "javascript.enabled"; //$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$
@@ -93,13 +106,217 @@ class Mozilla extends WebBrowser {
 	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 URI_FILEROOT = "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 {
+		DisplayListener = 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;
+					revertProxySettings (prefService);
+					rc = prefService.SavePrefFile (prefFile.getAddress ());
+					prefService.Release ();
+
+					prefFile.Release ();
+				}
+				serviceManager.Release ();
+
+				if (XPCOMWasGlued) {
+					/*
+					* The following is intentionally commented because it causes subsequent
+					* browser instantiations within the process to fail.  Mozilla does not
+					* support being unloaded and then re-initialized in a process, see
+					* http://www.mail-archive.com/dev-embedding@lists.mozilla.org/msg01732.html . 
+					*/
+
+//					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);
+
+//					XPCOM.XPCOMGlueShutdown ();
+					XPCOMWasGlued = false;
+				}
+				if (XPCOMInitWasGlued) {
+					XPCOMInit.XPCOMGlueShutdown ();
+					XPCOMInitWasGlued = false;
+				}
+				Initialized = false;
+			}
+
+			void revertProxySettings (nsIPrefService prefService) {
+				/* the proxy settings are typically not set, so check for this first */
+				boolean hostSet = oldProxyHostFTP != null || oldProxyHostHTTP != null || oldProxyHostSSL != null;
+				if (!hostSet && oldProxyPortFTP == -1 && oldProxyPortHTTP == -1 && oldProxyPortSSL == -1 && oldProxyType == -1) return;
+
+				int /*long*/[] result = new int /*long*/[1];
+				byte[] buffer = new byte[1];
+				int rc = prefService.GetBranch (buffer, result);	/* empty buffer denotes root preference level */
+				if (rc != XPCOM.NS_OK) error (rc);
+				if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
+
+				nsIPrefBranch prefBranch = new nsIPrefBranch (result[0]);
+				result[0] = 0;
+
+				if (hostSet) {
+					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_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);
+
+					nsIPrefLocalizedString localizedString = new nsIPrefLocalizedString (result[0]);
+					result[0] = 0;
+
+					if (oldProxyHostFTP != null) {
+						buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_PROXYHOST_FTP, true);
+						if (oldProxyHostFTP.equals (DEFAULTVALUE_STRING)) {
+							rc = prefBranch.ClearUserPref (buffer);
+							if (rc != XPCOM.NS_OK) error (rc);
+						} else {
+							int length = oldProxyHostFTP.length ();
+							char[] charBuffer = new char[length];
+							oldProxyHostFTP.getChars (0, length, charBuffer, 0);
+							rc = localizedString.SetDataWithLength (length, charBuffer);
+							if (rc != XPCOM.NS_OK) error (rc);
+							rc = prefBranch.SetComplexValue (buffer, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, localizedString.getAddress ());
+							if (rc != XPCOM.NS_OK) error (rc);
+						}
+					}
+
+					if (oldProxyHostHTTP != null) {
+						buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_PROXYHOST_HTTP, true);
+						if (oldProxyHostHTTP.equals (DEFAULTVALUE_STRING)) {
+							rc = prefBranch.ClearUserPref (buffer);
+							if (rc != XPCOM.NS_OK) error (rc);
+						} else {
+							int length = oldProxyHostHTTP.length ();
+							char[] charBuffer = new char[length];
+							oldProxyHostHTTP.getChars (0, length, charBuffer, 0);
+							rc = localizedString.SetDataWithLength (length, charBuffer);
+							if (rc != XPCOM.NS_OK) error (rc);
+							rc = prefBranch.SetComplexValue (buffer, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, localizedString.getAddress ());
+							if (rc != XPCOM.NS_OK) error (rc);
+						}
+					}
+
+					if (oldProxyHostSSL != null) {
+						buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_PROXYHOST_SSL, true);
+						if (oldProxyHostSSL.equals (DEFAULTVALUE_STRING)) {
+							rc = prefBranch.ClearUserPref (buffer);
+							if (rc != XPCOM.NS_OK) error (rc);
+						} else {
+							int length = oldProxyHostSSL.length ();
+							char[] charBuffer = new char[length];
+							oldProxyHostSSL.getChars (0, length, charBuffer, 0);
+							rc = localizedString.SetDataWithLength (length, charBuffer);
+							if (rc != XPCOM.NS_OK) error (rc);
+							rc = prefBranch.SetComplexValue (buffer, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, localizedString.getAddress ());
+							if (rc != XPCOM.NS_OK) error (rc);
+						}
+					}
+
+					localizedString.Release ();
+					componentManager.Release ();
+				}
+
+				if (oldProxyPortFTP != -1) {
+					buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_PROXYPORT_FTP, true);
+					rc = prefBranch.SetIntPref (buffer, oldProxyPortFTP);
+					if (rc != XPCOM.NS_OK) error (rc);
+				}
+				if (oldProxyPortHTTP != -1) {
+					buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_PROXYPORT_HTTP, true);
+					rc = prefBranch.SetIntPref (buffer, oldProxyPortHTTP);
+					if (rc != XPCOM.NS_OK) error (rc);
+				}
+				if (oldProxyPortSSL != -1) {
+					buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_PROXYPORT_SSL, true);
+					rc = prefBranch.SetIntPref (buffer, oldProxyPortSSL);
+					if (rc != XPCOM.NS_OK) error (rc);
+				}
+				if (oldProxyType != -1) {
+					buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_PROXYTYPE, true);
+					rc = prefBranch.SetIntPref (buffer, oldProxyType);
+					if (rc != XPCOM.NS_OK) error (rc);
+				}
+
+				prefBranch.Release ();
+			}
+		};
+
 		MozillaClearSessions = new Runnable () {
 			public void run () {
 				if (!Initialized) return;
@@ -223,7 +440,24 @@ class Mozilla extends WebBrowser {
 				int length = C.strlen (cookieString);
 				bytes = new byte[length];
 				XPCOM.memmove (bytes, cookieString, length);
-				C.free (cookieString);
+
+				/*
+				 * NS_Free was introduced in mozilla 1.8, prior to this the standard free() call
+				 * was to be used.  Try to free the cookie string with NS_Free first, and if it fails
+				 * then assume that an older mozilla is being used, and use C's free() instead. 
+				 */
+				if (pathBytes_NSFree == null) {
+					String mozillaPath = getMozillaPath () + MozillaDelegate.getLibraryName () + '\0';
+					try {
+						pathBytes_NSFree = mozillaPath.getBytes ("UTF-8"); //$NON-NLS-1$
+					} catch (UnsupportedEncodingException e) {
+						pathBytes_NSFree = mozillaPath.getBytes ();
+					}
+				}
+				if (!XPCOM.NS_Free (pathBytes_NSFree, cookieString)) {
+					C.free (cookieString);
+				}
+
 				String allCookies = new String (MozillaDelegate.mbcsToWcs (null, bytes));
 				StringTokenizer tokenizer = new StringTokenizer (allCookies, ";"); //$NON-NLS-1$
 				while (tokenizer.hasMoreTokens ()) {
@@ -294,14 +528,14 @@ class Mozilla extends WebBrowser {
 		};
 	}
 
-public void create (Composite parent, int style) {
+public boolean 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;
+		boolean isXULRunner = false;
 
 		String greInitialized = System.getProperty (GRE_INITIALIZED); 
 		if ("true".equals (greInitialized)) { //$NON-NLS-1$
@@ -345,125 +579,71 @@ public void create (Composite parent, int style) {
 				*/
 			}
 		} else {
-			mozillaPath += SEPARATOR_OS + delegate.getLibraryName ();
-			IsXULRunner = true;
+			mozillaPath += SEPARATOR_OS + MozillaDelegate.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);
+			mozillaPath = initDiscoverXULRunner ();
+			isXULRunner = mozillaPath.length () > 0;
 
 			/*
-			 * 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.
+			 * 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 (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;
+			if (isXULRunner) {
+				byte[] path = MozillaDelegate.wcsToMbcs (null, mozillaPath, true);
+				int 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 {
+						int 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 {
-							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$
-								}
+							mozillaPath += SEPARATOR_OS + MozillaDelegate.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;
-					}
+						}
+					} 
+				}
+				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));
+		if (isXULRunner) {
+			/* load swt's xulrunner library and invoke XPCOMGlueStartup to load xulrunner's dependencies */
+			mozillaPath = initXULRunner (mozillaPath);
 		} else {
+			/*
+			* If style SWT.MOZILLA was specified then this initialization has already
+			* failed, because SWT.MOZILLA-style Browsers must utilize XULRunner.
+			*/
 			if ((style & SWT.MOZILLA) != 0) {
 				browser.dispose ();
 				String errorString = (mozillaPath != null && mozillaPath.length () > 0) ?
@@ -472,161 +652,27 @@ public void create (Composite parent, int style) {
 				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$
-				}
-			}
+			/* load swt's mozilla library */
+			mozillaPath = initMozilla (mozillaPath);
 		}
 
 		if (!Initialized) {
-			LocationProvider = new AppFileLocProvider (mozillaPath);
+			/* create LocationProvider, which tells mozilla where to find things on the file system */
+			String profilePath = delegate.getProfilePath ();
+			LocationProvider = new AppFileLocProvider (mozillaPath, profilePath, isXULRunner);
 			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 ());
-			}
+			/* write external.xpt to the file system if needed */
+			initExternal (profilePath);
 
-			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);
-				if (functionPtr == 0) {
-            		browser.dispose ();
-            		error (XPCOM.NS_ERROR_NULL_POINTER);
-				}
-				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$
+			/* load swt's mozilla/xulrunner library and invoke appropriate Init function */
+			initXPCOM (mozillaPath, isXULRunner);
 		}
 
-		/* 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) {
-			}
-		}
+		/* attempt to initialize JavaXPCOM in the detected XULRunner */
+		if (isXULRunner) initJavaXPCOM (mozillaPath);
 
+		/* get the nsIComponentManager and nsIServiceManager, used throughout initialization */
 		int rc = XPCOM.NS_GetComponentManager (result);
 		if (rc != XPCOM.NS_OK) {
 			browser.dispose ();
@@ -636,40 +682,9 @@ public void create (Composite parent, int style) {
 			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 ();
@@ -679,615 +694,44 @@ public void create (Composite parent, int style) {
 			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 ();
-
-	        if (IsXULRunner) {
-				int size = XPCOM.nsDynamicFunctionLoad_sizeof ();
-				/* alloc memory for two structs, the second is empty to signify the end of the list */
-				ptr = C.malloc (size * 2);
-				C.memset (ptr, 0, size * 2);
-				nsDynamicFunctionLoad functionLoad = new nsDynamicFunctionLoad ();
-				byte[] bytes = MozillaDelegate.wcsToMbcs (null, "XRE_NotifyProfile", 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);
-				/* functionPtr == 0 for xulrunner < 1.9 */
-				if (functionPtr != 0) {
-					rc = XPCOM.Call (functionPtr);
-	            	if (rc != XPCOM.NS_OK) {
-	            		browser.dispose ();
-	            		error (rc);
-	            	}
-				}
-	        }
-		}
-
-		/*
-		 * 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);
-		}
+		result[0] = 0;	
 
-		prefBranch.Release ();
+		/* init the event handler if needed */
+		initSpinup (componentManager);
 
-		PromptService2Factory factory = new PromptService2Factory ();
-		factory.AddRef ();
+		/* init our WindowCreator, which mozilla uses for the creation of child browsers in external Shells */
+		initWindowCreator (serviceManager);
 
-		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 */ 
+		/* notify mozilla that the profile directory has been changed from its default value */
+		initProfile (serviceManager, isXULRunner);
 
-		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 ();
+		/* init preference values that give desired mozilla behaviours */ 
+		initPreferences (serviceManager, componentManager);
 
-		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 ();
+		/* init our various factories that mozilla can invoke as needed */ 
+		initFactories (serviceManager, componentManager, isXULRunner);
 
-		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 ();
+		componentManager.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);
+		/* add cookies that were set by a client before the first Mozilla instance was created */
+		if (MozillaPendingCookies != null) {
+			SetPendingCookies (MozillaPendingCookies);
 		}
-		pickerFactory.Release ();
-
-		componentRegistrar.Release ();
-		componentManager.Release ();
+		MozillaPendingCookies = null;
 
 		Initialized = true;
 	}
 
+	BrowserCount++;
+
 	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;
-			}
-		});
+		display.addListener (SWT.Dispose, DisplayListener);
 	}
 
-	BrowserCount++;
+	/* get the nsIComponentManager, used throughout initialization */
 	int rc = XPCOM.NS_GetComponentManager (result);
 	if (rc != XPCOM.NS_OK) {
 		browser.dispose ();
@@ -1297,9 +741,10 @@ public void create (Composite parent, int style) {
 		browser.dispose ();
 		error (XPCOM.NS_NOINTERFACE);
 	}
-	
 	nsIComponentManager componentManager = new nsIComponentManager (result[0]);
 	result[0] = 0;
+
+	/* create the nsIWebBrowser instance */
 	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) {
@@ -1310,55 +755,15 @@ public void create (Composite parent, int style) {
 		browser.dispose ();
 		error (XPCOM.NS_NOINTERFACE);	
 	}
-	
 	webBrowser = new nsIWebBrowser (result[0]);
 	result[0] = 0;
 
+	/* create the instance-based callback interfaces */
 	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 ();
+	/* init the nsIWebBrowser's container and base windows */
+	initWebBrowserWindows ();
 
 	if (!PerformedVersionCheck) {
 		PerformedVersionCheck = true;
@@ -1378,7 +783,7 @@ public void create (Composite parent, int style) {
 		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$
+		byte[] aClassName = MozillaDelegate.wcsToMbcs (null, "swtHelperAppLauncherDialog", true); //$NON-NLS-1$
 		rc = componentRegistrar.RegisterFactory (XPCOM.NS_HELPERAPPLAUNCHERDIALOG_CID, aClassName, aContractID, dialogFactory.getAddress ());
 		if (rc != XPCOM.NS_OK) {
 			browser.dispose ();
@@ -1428,7 +833,7 @@ public void create (Composite parent, int style) {
 				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$
+				aClassName = MozillaDelegate.wcsToMbcs (null, "swtTransfer", true); //$NON-NLS-1$
 				rc = componentRegistrar.RegisterFactory (XPCOM.NS_DOWNLOAD_CID, aClassName, aContractID, downloadFactory_1_8.getAddress ());
 				if (rc != XPCOM.NS_OK) {
 					browser.dispose ();
@@ -1457,12 +862,12 @@ public void create (Composite parent, int style) {
 		delegate.addWindowSubclass ();
 	}
 
+	/* add listeners for progress and content */
 	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 ();
@@ -1520,11 +925,13 @@ public void create (Composite parent, int style) {
 		SWT.Activate,
 		SWT.Deactivate,
 		SWT.Show,
-		SWT.KeyDown		// needed to make browser traversable
+		SWT.KeyDown,		/* needed to make browser traversable */
 	};
 	for (int i = 0; i < folderEvents.length; i++) {
 		browser.addListener (folderEvents[i], listener);
 	}
+
+	return true;
 }
 
 public boolean back () {
@@ -1541,6 +948,22 @@ public boolean back () {
 	return rc == XPCOM.NS_OK;
 }
 
+public boolean close () {
+	final boolean[] result = new boolean[] {false};
+	LocationListener[] oldListeners = locationListeners;
+	locationListeners = new LocationListener[] {
+		new LocationAdapter () {
+			public void changing (LocationEvent event) {
+				/* implies that the user did not veto the page unload */
+				result[0] = true;
+			}
+		} 
+	};
+	execute ("window.location.replace('about:blank');"); //$NON-NLS-1$
+	locationListeners = oldListeners;
+	return result[0];
+}
+
 void createCOMInterfaces () {
 	// Create each of the interfaces that this object implements
 	supports = new XPCOMObject (new int[] {2, 0, 0}) {
@@ -1771,7 +1194,6 @@ public boolean execute (String script) {
 				securityManager.Release ();
 			}
 		}
-		serviceManager.Release ();
 
 		if (principal != null) {
 			rc = webBrowser.QueryInterface (nsIInterfaceRequestor.NS_IINTERFACEREQUESTOR_IID, result);
@@ -1780,8 +1202,13 @@ public boolean execute (String script) {
 
 			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);
+			nsID scriptGlobalObjectNSID_1_9 = new nsID ("6afecd40-0b9a-4cfd-8c42-0f645cd91829"); /* nsIScriptGlobalObject */ //$NON-NLS-1$
+			rc = interfaceRequestor.GetInterface (scriptGlobalObjectNSID_1_9, result);
+			if (!(rc == XPCOM.NS_OK && result[0] != 0)) {
+				result[0] = 0;
+				nsID scriptGlobalObjectNSID_1_9_2 = new nsID ("e9f3f2c1-2d94-4722-bbd4-2bf6fdf42f48"); /* nsIScriptGlobalObject */ //$NON-NLS-1$
+				rc = interfaceRequestor.GetInterface (scriptGlobalObjectNSID_1_9_2, result);
+			}
 			interfaceRequestor.Release ();
 
 			if (rc == XPCOM.NS_OK && result[0] != 0) {
@@ -1795,8 +1222,14 @@ public boolean execute (String script) {
 
 				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);
+					nsID scriptContextNSID_1_9 = new nsID ("e7b9871d-3adc-4bf7-850d-7fb9554886bf"); /* nsIScriptContext */ //$NON-NLS-1$					
+					rc = new nsISupports (scriptContext).QueryInterface (scriptContextNSID_1_9, result);
+					if (!(rc == XPCOM.NS_OK && result[0] != 0)) {
+						result[0] = 0;
+						nsID scriptContextNSID_1_9_2 = new nsID ("87482b5e-e019-4df5-9bc2-b2a51b1f2d28"); /* nsIScriptContext */ //$NON-NLS-1$					
+						rc = new nsISupports (scriptContext).QueryInterface (scriptContextNSID_1_9_2, result);
+					}
+
 					if (rc == XPCOM.NS_OK && result[0] != 0) {
 						new nsISupports (result[0]).Release ();
 						result[0] = 0;
@@ -1812,15 +1245,32 @@ public boolean execute (String script) {
 								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 ();
+								if (pathBytes_JSEvaluateUCScriptForPrincipals == null) {
+									String mozillaPath = getMozillaPath () + delegate.getJSLibraryName () + '\0';
+									try {
+										pathBytes_JSEvaluateUCScriptForPrincipals = mozillaPath.getBytes ("UTF-8"); //$NON-NLS-1$
+									} catch (UnsupportedEncodingException e) {
+										pathBytes_JSEvaluateUCScriptForPrincipals = mozillaPath.getBytes ();
+									}
 								}
-								rc = XPCOM.JS_EvaluateUCScriptForPrincipals (pathBytes, nativeContext, globalJSObject, principals, scriptChars, length, urlbytes, 0, result);
-								return rc != 0;
+
+								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 (nativeContext);
+								if (rc != XPCOM.NS_OK) error (rc);
+								boolean success = XPCOM.JS_EvaluateUCScriptForPrincipals (pathBytes_JSEvaluateUCScriptForPrincipals, nativeContext, globalJSObject, principals, scriptChars, length, urlbytes, 0, result) != 0;
+								result[0] = 0;
+								rc = stack.Pop (result);
+								if (rc != XPCOM.NS_OK) error (rc);
+								stack.Release ();
+
+								return success;
 							}
 						}
 					}
@@ -1828,6 +1278,7 @@ public boolean execute (String script) {
 			}
 			principal.Release ();
 		}
+		serviceManager.Release ();
 	}
 
 	/* fall back to the pre-1.9 approach */
@@ -1838,9 +1289,9 @@ public boolean execute (String script) {
 	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);
+	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;
@@ -1914,6 +1365,53 @@ public String getBrowserType () {
 	return "mozilla"; //$NON-NLS-1$
 }
 
+static String getMozillaPath () {
+	if (LocationProvider != null) return LocationProvider.mozillaPath;
+	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[] buffer = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_DIRECTORYSERVICE_CONTRACTID, true);
+	rc = serviceManager.GetServiceByContractID (buffer, nsIDirectoryService.NS_IDIRECTORYSERVICE_IID, result);
+	if (rc != XPCOM.NS_OK) error (rc);
+	if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
+	serviceManager.Release();
+
+	nsIDirectoryService directoryService = new nsIDirectoryService (result[0]);
+	result[0] = 0;
+	rc = directoryService.QueryInterface (nsIProperties.NS_IPROPERTIES_IID, result);
+	if (rc != XPCOM.NS_OK) error (rc);
+	if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
+	directoryService.Release ();
+
+	nsIProperties properties = new nsIProperties (result[0]);
+	result[0] = 0;
+	buffer = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_GRE_DIR, true);
+	rc = properties.Get (buffer, nsIFile.NS_IFILE_IID, result);
+	if (rc != XPCOM.NS_OK) error (rc);
+	if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
+	properties.Release ();
+
+	nsIFile mozillaDir = new nsIFile (result[0]);
+	result[0] = 0;
+	int /*long*/ path = XPCOM.nsEmbedCString_new ();
+	rc = mozillaDir.GetNativePath (path);
+	if (rc != XPCOM.NS_OK) error (rc);
+	int length = XPCOM.nsEmbedCString_Length (path);
+	int /*long*/ ptr = XPCOM.nsEmbedCString_get (path);
+	buffer = new byte[length];
+	XPCOM.memmove (buffer, ptr, length);
+	XPCOM.nsEmbedCString_delete (path);
+	mozillaDir.Release ();
+
+	return new String (MozillaDelegate.mbcsToWcs (null, buffer)) + SEPARATOR_OS;
+}
+
 int getNextFunctionIndex () {
 	return NextJSFunctionIndex++;
 }
@@ -2009,7 +1507,14 @@ public String getUrl () {
 	 * 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;
+	if (location.equals (URI_FILEROOT)) {
+		location = ABOUT_BLANK;
+	} else {
+		int length = URI_FILEROOT.length ();
+		if (location.startsWith (URI_FILEROOT) && location.charAt (length) == '#') {
+			location = ABOUT_BLANK + location.substring (length);
+		}
+	}
 	return location;
 }
 
@@ -2038,6 +1543,847 @@ public Object getWebBrowser () {
 	return null;
 }
 
+String initDiscoverXULRunner () {
+	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);
+
+	String result = null;
+	if (rc == XPCOM.NS_OK) {
+		/* indicates that a XULRunner was found */
+		length = C.strlen (greBuffer);
+		bytes = new byte[length];
+		C.memmove (bytes, greBuffer, length);
+		result = new String (MozillaDelegate.mbcsToWcs (null, bytes));
+	} else {
+		result = ""; //$NON-NLS-1$
+	}
+	C.free (greBuffer);
+	return result;
+}
+
+void initExternal (String profilePath) {
+	File componentsDir = new File (profilePath, AppFileLocProvider.COMPONENTS_DIR);
+	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) {
+		}
+	}
+}
+
+void initFactories (nsIServiceManager serviceManager, nsIComponentManager componentManager, boolean isXULRunner) {
+	int /*long*/[] result = new int /*long*/[1];
+
+	PromptService2Factory factory = new PromptService2Factory ();
+	factory.AddRef ();
+
+	int 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 */ 
+
+	byte[] aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_PROMPTSERVICE_CONTRACTID, true); 
+	byte[] aClassName = MozillaDelegate.wcsToMbcs (null, "swtPromptService", 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);
+
+	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, "swtDownload", 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, "swtFilePicker", 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 ();
+}
+
+void initJavaXPCOM (String mozillaPath) {
+	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) {
+	}
+}
+
+String initMozilla (String mozillaPath) {
+	/* 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$
+		}
+	}
+
+	return mozillaPath;
+}
+
+void initXPCOM (String mozillaPath, boolean isXULRunner) {
+	int /*long*/[] result = new int /*long*/[1];
+
+	nsEmbedString pathString = new nsEmbedString (mozillaPath);
+	int rc = XPCOM.NS_NewLocalFile (pathString.getAddress (), 1, result);
+	pathString.dispose ();
+	if (rc != XPCOM.NS_OK) {
+		browser.dispose ();
+		error (rc);
+	}
+	if (result[0] == 0) {
+		browser.dispose ();
+		error (XPCOM.NS_ERROR_NULL_POINTER);
+	}
+
+	nsILocalFile localFile = new nsILocalFile (result[0]);
+	result[0] = 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);
+		if (functionPtr == 0) {
+			browser.dispose ();
+			error (XPCOM.NS_ERROR_NULL_POINTER);
+		}
+		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$
+}
+
+void initPreferences (nsIServiceManager serviceManager, nsIComponentManager componentManager) {
+	int /*long*/[] result = new int /*long*/[1];
+
+	/*
+	 * 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.
+	 */
+	byte[] aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_PREFSERVICE_CONTRACTID, true);
+	int 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];
+		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.GetComplexValue (buffer, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, result);
+		if (rc == XPCOM.NS_OK && result[0] != 0) {
+			nsIPrefLocalizedString value = new nsIPrefLocalizedString (result[0]);
+			result[0] = 0;
+			rc = value.ToString (result);
+			if (rc != XPCOM.NS_OK) error (rc);
+			if (result[0] == 0) error (XPCOM.NS_ERROR_NULL_POINTER);
+			length = XPCOM.strlen_PRUnichar (result[0]);
+			char[] dest = new char[length];
+			XPCOM.memmove (dest, result[0], length * 2);
+			oldProxyHostFTP = new String (dest);
+		} else {
+			/* value is default */
+			oldProxyHostFTP = DEFAULTVALUE_STRING;
+		}
+		result[0] = 0;
+		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.GetComplexValue (buffer, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, result);
+		if (rc == XPCOM.NS_OK && result[0] != 0) {
+			nsIPrefLocalizedString value = new nsIPrefLocalizedString (result[0]);
+			result[0] = 0;
+			rc = value.ToString (result);
+			if (rc != XPCOM.NS_OK) error (rc);
+			if (result[0] == 0) error (XPCOM.NS_ERROR_NULL_POINTER);
+			length = XPCOM.strlen_PRUnichar (result[0]);
+			char[] dest = new char[length];
+			XPCOM.memmove (dest, result[0], length * 2);
+			oldProxyHostHTTP = new String (dest);
+		} else {
+			/* value is default */
+			oldProxyHostHTTP = DEFAULTVALUE_STRING;
+		}
+		result[0] = 0;
+		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.GetComplexValue (buffer, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, result);
+		if (rc == XPCOM.NS_OK && result[0] != 0) {
+			nsIPrefLocalizedString value = new nsIPrefLocalizedString (result[0]);
+			result[0] = 0;
+			rc = value.ToString (result);
+			if (rc != XPCOM.NS_OK) error (rc);
+			if (result[0] == 0) error (XPCOM.NS_ERROR_NULL_POINTER);
+			length = XPCOM.strlen_PRUnichar (result[0]);
+			char[] dest = new char[length];
+			XPCOM.memmove (dest, result[0], length * 2);
+			oldProxyHostSSL = new String (dest);
+		} else {
+			/* value is default */
+			oldProxyHostSSL = DEFAULTVALUE_STRING;
+		}
+		result[0] = 0;
+		rc = prefBranch.SetComplexValue (buffer, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, localizedString.getAddress ());
+		if (rc != XPCOM.NS_OK) error (rc);
+
+		localizedString.Release ();
+	}
+
+	int[] intResult = new int[1]; /* C long*/
+	if (port != -1) {
+		buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_PROXYPORT_FTP, true);
+		rc = prefBranch.GetIntPref (buffer, intResult);
+		if (rc != XPCOM.NS_OK) error (rc);
+		oldProxyPortFTP = intResult[0];
+		intResult[0] = 0;
+		rc = prefBranch.SetIntPref (buffer, port);
+		if (rc != XPCOM.NS_OK) error (rc);
+
+		buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_PROXYPORT_HTTP, true);
+		rc = prefBranch.GetIntPref (buffer, intResult);
+		if (rc != XPCOM.NS_OK) error (rc);
+		oldProxyPortHTTP = intResult[0];
+		intResult[0] = 0;
+		rc = prefBranch.SetIntPref (buffer, port);
+		if (rc != XPCOM.NS_OK) error (rc);
+
+		buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_PROXYPORT_SSL, true);
+		rc = prefBranch.GetIntPref (buffer, intResult);
+		if (rc != XPCOM.NS_OK) error (rc);
+		oldProxyPortSSL = intResult[0];
+		intResult[0] = 0;
+		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.GetIntPref (buffer, intResult);
+		if (rc != XPCOM.NS_OK) error (rc);
+		oldProxyType = intResult[0];
+		intResult[0] = 0;
+		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);
+	}
+
+	/* Ensure that the status line can be hidden when opening a window from javascript */ 
+	buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_DISABLEOPENWINDOWSTATUSHIDE, true);
+	rc = prefBranch.SetBoolPref (buffer, 0);
+	if (rc != XPCOM.NS_OK) {
+		browser.dispose ();
+		error (rc);
+	}
+
+	/* Ensure that javascript execution is enabled since this is the Browser's default behaviour */ 
+	buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_JAVASCRIPTENABLED, true);
+	rc = prefBranch.SetBoolPref (buffer, 1);
+	if (rc != XPCOM.NS_OK) {
+		browser.dispose ();
+		error (rc);
+	}
+
+	prefBranch.Release ();
+}
+
+void initProfile (nsIServiceManager serviceManager, boolean isXULRunner) {
+	int /*long*/[] result = new int /*long*/[1];
+
+	byte[] buffer = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_OBSERVER_CONTRACTID, true);
+	int 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);
+	int 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 ();
+
+	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_NotifyProfile", 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);
+		/* functionPtr == 0 for xulrunner < 1.9 */
+		if (functionPtr != 0) {
+			rc = XPCOM.Call (functionPtr);
+			if (rc != XPCOM.NS_OK) {
+				browser.dispose ();
+				error (rc);
+			}
+		}
+	}
+}
+
+void initSpinup (nsIComponentManager componentManager) {
+	if (delegate.needsSpinup ()) {
+		int /*long*/[] result = new int /*long*/[1];
+
+		/* nsIAppShell is discontinued as of xulrunner 1.9, so do not fail if it is not found */
+		int 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]);
+			result[0] = 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);
+			}
+		}
+	}
+}
+
+void initWebBrowserWindows () {
+	int rc = webBrowser.SetContainerWindow (webBrowserChrome.getAddress());
+	if (rc != XPCOM.NS_OK) {
+		browser.dispose ();
+		error (rc);
+	}
+
+	int /*long*/[] result = new int /*long*/[1];
+	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 ();
+}
+
+void initWindowCreator (nsIServiceManager serviceManager) {
+	WindowCreator = new WindowCreator2 ();
+	WindowCreator.AddRef ();
+	
+	int /*long*/[] result = new int /*long*/[1];
+	byte[] aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_WINDOWWATCHER_CONTRACTID, true);
+	int 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 ();
+}
+
+String initXULRunner (String mozillaPath) {
+	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.
+	 */ 
+	return mozillaPath.substring (0, mozillaPath.lastIndexOf (SEPARATOR_OS));
+}
 public boolean isBackEnabled () {
 	int /*long*/[] result = new int /*long*/[1];
 	int rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result);
@@ -2069,6 +2415,16 @@ static String error (int code) {
 }
 
 void onDispose (Display display) {
+	/* invoke onbeforeunload handlers */
+	if (!browser.isClosing && !browser.isDisposed()) {
+		LocationListener[] oldLocationListeners = locationListeners;
+		locationListeners = new LocationListener[0];
+		ignoreAllMessages = true;
+		execute ("window.location.replace('about:blank');"); //$NON-NLS-1$
+		ignoreAllMessages = false;
+		locationListeners = oldLocationListeners;	
+	}
+
 	int rc = webBrowser.RemoveWebBrowserListener (weakReference.getAddress (), nsIWebProgressListener.NS_IWEBPROGRESSLISTENER_IID);
 	if (rc != XPCOM.NS_OK) error (rc);
 
@@ -2079,21 +2435,6 @@ void onDispose (Display display) {
 	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);
@@ -2111,6 +2452,7 @@ void onDispose (Display display) {
 	webBrowserObject = null;
 	lastNavigateURL = null;
 	htmlBytes = null;
+	listener = null;
 
 	if (tip != null && !tip.isDisposed ()) tip.dispose ();
 	tip = null;
@@ -2190,18 +2532,26 @@ public void refresh () {
 	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. 
+	* The following error conditions do not indicate unrecoverable problems:
+	* 
+	* - NS_ERROR_INVALID_POINTER: happens when Reload is called immediately
+	* after calling LoadURI.
+	* - NS_ERROR_FILE_NOT_FOUND: happens when attempting to reload a file that
+	* no longer exists.
+	* - NS_BINDING_ABORTED: happens when the user aborts the load (eg.- chooses
+	* to not resubmit a page with form data).
 	*/
-	if (rc != XPCOM.NS_ERROR_INVALID_POINTER && rc != XPCOM.NS_ERROR_FILE_NOT_FOUND) error (rc);
+	switch (rc) {
+		case XPCOM.NS_OK:
+		case XPCOM.NS_ERROR_INVALID_POINTER:
+		case XPCOM.NS_ERROR_FILE_NOT_FOUND:
+		case XPCOM.NS_BINDING_ABORTED: {
+			return;
+		}
+	}
+	error (rc);
 }
 
 void registerFunction (BrowserFunction function) {
@@ -2209,7 +2559,7 @@ void registerFunction (BrowserFunction function) {
 	AllFunctions.put (new Integer (function.index), function);
 }
 
-public boolean setText (String html) {
+public boolean setText (String html, boolean trusted) {
 	/*
 	*  Feature in Mozilla.  The focus memory of Mozilla must be 
 	*  properly managed through the nsIWebBrowserFocus interface.
@@ -2262,6 +2612,7 @@ public boolean setText (String html) {
 		*/
 		boolean blankLoading = htmlBytes != null;
 		htmlBytes = data;
+		untrustedText = !trusted;
 		if (blankLoading) return true;
 
 		/* navigate to about:blank */
@@ -2270,15 +2621,15 @@ public boolean setText (String html) {
 		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);
+		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$
+		byte[] contentCharsetBuffer = MozillaDelegate.wcsToMbcs (null, "UTF-8", false);	//$NON-NLS-1$
 		int /*long*/ aContentCharset = XPCOM.nsEmbedCString_new (contentCharsetBuffer, contentCharsetBuffer.length);
-		byte[] contentTypeBuffer = MozillaDelegate.wcsToMbcs (null, "text/html", true); // $NON-NLS-1$
+		byte[] contentTypeBuffer = MozillaDelegate.wcsToMbcs (null, "text/html", false); // $NON-NLS-1$
 		int /*long*/ aContentType = XPCOM.nsEmbedCString_new (contentTypeBuffer, contentTypeBuffer.length);
 
 		rc = XPCOM.NS_GetServiceManager (result);
@@ -2290,16 +2641,15 @@ public boolean setText (String html) {
 		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);
+		byte[] aString;
+		if (trusted) {
+			aString = MozillaDelegate.wcsToMbcs (null, URI_FILEROOT, false);
+		} else {
+			aString = MozillaDelegate.wcsToMbcs (null, ABOUT_BLANK, false);
+		}
 		int /*long*/ aSpec = XPCOM.nsEmbedCString_new (aString, aString.length);
 		rc = ioService.NewURI (aSpec, null, 0, result);
 		if (rc != XPCOM.NS_OK) error (rc);
@@ -2342,7 +2692,7 @@ public boolean setText (String html) {
 	return true;
 }
 
-public boolean setUrl (String url) {
+public boolean setUrl (String url, String postData, String[] headers) {
 	htmlBytes = null;
 
 	int /*long*/[] result = new int /*long*/[1];
@@ -2358,9 +2708,71 @@ public boolean setUrl (String url) {
 	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);
+	result[0] = 0;
+	char[] uri = new char[url.length () + 1];
+	url.getChars (0, url.length (), uri, 0);
+
+	nsIMIMEInputStream postDataStream = null;
+	InputStream dataStream = null;
+	if (postData != null) {
+		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_MIMEINPUTSTREAM_CONTRACTID, true);
+		rc = componentManager.CreateInstanceByContractID (contractID, 0, nsIMIMEInputStream.NS_IMIMEINPUTSTREAM_IID, result);
+		componentManager.Release();
+
+		if (rc == XPCOM.NS_OK && result[0] != 0) { /* nsIMIMEInputStream is not in mozilla 1.4 */
+			byte[] bytes = MozillaDelegate.wcsToMbcs (null, postData, false);
+			dataStream = new InputStream (bytes);
+			dataStream.AddRef ();
+			postDataStream = new nsIMIMEInputStream (result[0]);
+			rc = postDataStream.SetData (dataStream.getAddress ());
+			if (rc != XPCOM.NS_OK) error (rc);
+			rc = postDataStream.SetAddContentLength (1);
+			if (rc != XPCOM.NS_OK) error (rc);
+			byte[] name = MozillaDelegate.wcsToMbcs (null, HEADER_CONTENTTYPE, true);
+			byte[] value = MozillaDelegate.wcsToMbcs (null, MIMETYPE_FORMURLENCODED, true);
+			rc = postDataStream.AddHeader (name, value);
+			if (rc != XPCOM.NS_OK) error (rc);
+		}
+		result[0] = 0;
+	}
+
+	InputStream headersStream = null;
+    if (headers != null) {
+		StringBuffer buffer = new StringBuffer ();
+		for (int i = 0; i < headers.length; i++) {
+			String current = headers[i];
+			if (current != null) {
+				int sep = current.indexOf (':');
+				if (sep != -1) {
+					String key = current.substring (0, sep).trim ();
+					String value = current.substring (sep + 1).trim ();
+					if (key.length () > 0 && value.length () > 0) {
+						buffer.append (key);
+						buffer.append (':');
+						buffer.append (value);
+						buffer.append ("\r\n");
+					}
+				}
+			}
+		}
+		byte[] bytes = MozillaDelegate.wcsToMbcs (null, buffer.toString (), true);
+		headersStream = new InputStream (bytes);
+		headersStream.AddRef ();
+    }
+
+	rc = webNavigation.LoadURI (
+		uri,
+		nsIWebNavigation.LOAD_FLAGS_NONE,
+		0,
+		postDataStream == null ? 0 : postDataStream.getAddress (),
+		headersStream == null ? 0 : headersStream.getAddress ());
+	if (dataStream != null) dataStream.Release ();
+	if (headersStream != null) headersStream.Release ();
 	webNavigation.Release ();
 	return rc == XPCOM.NS_OK;
 }
@@ -2631,6 +3043,47 @@ int GetWeakReference (int /*long*/ ppvObject) {
 /* nsIWebProgressListener */
 
 int OnStateChange (int /*long*/ aWebProgress, int /*long*/ aRequest, int aStateFlags, int aStatus) {
+	if (registerFunctionsOnState != 0 && ((aStateFlags & registerFunctionsOnState) == registerFunctionsOnState)) {
+		registerFunctionsOnState = 0;
+		Enumeration elements = functions.elements ();
+		while (elements.hasMoreElements ()) {
+			BrowserFunction function = (BrowserFunction)elements.nextElement ();
+			execute (function.functionString);
+		}
+	}
+
+	/*
+	* Feature of Mozilla.  When a redirect occurs to a site with an invalid
+	* certificate, no STATE_IS_DOCUMENT state transitions are received for the
+	* new location, and an immediate attempt is made to show the invalid
+	* certificate error.  However our invalid certificate handler must know
+	* the site with the invalid certificate, not the site that redirected to
+	* it.  The only opportunity to get this site before our invalid certificate
+	* handler is invoked is in the subsequent STATE_START | STATE_IS_REQUEST
+	* transition.  When this comes, if the request's name appears to be a
+	* url then take this to be the new site, in case our invalid certificate
+	* handler is about to be invoked.
+	* 
+	* Note that updateLastNavigateUrl is not reset to false here so that in
+	* typical contexts where a redirect occurs without an accompanying invalid
+	* certificate, the updated site will be retrieved from the channel (this
+	* is more proper) on the next STATE_TRANSFERRING | STATE_IS_DOCUMENT transition.
+	*/
+	if (updateLastNavigateUrl && aStateFlags == (nsIWebProgressListener.STATE_IS_REQUEST | nsIWebProgressListener.STATE_START)) {
+		nsIRequest request = new nsIRequest (aRequest);
+		int /*long*/ name = XPCOM.nsEmbedCString_new ();
+		int rc = request.GetName (name);
+		if (rc == XPCOM.NS_OK) {
+			int length = XPCOM.nsEmbedCString_Length (name);
+			int /*long*/ buffer = XPCOM.nsEmbedCString_get (name);
+			byte[] bytes = new byte[length];
+			XPCOM.memmove (bytes, buffer, length);
+			String value = new String (bytes);
+			if (value.indexOf (":/") != -1) lastNavigateURL = value;	//$NON-NLS-1$
+		}
+		XPCOM.nsEmbedCString_delete (name);
+	}
+
 	if ((aStateFlags & nsIWebProgressListener.STATE_IS_DOCUMENT) == 0) return XPCOM.NS_OK;
 	if ((aStateFlags & nsIWebProgressListener.STATE_START) != 0) {
 		int /*long*/[] result = new int /*long*/[1];
@@ -2655,6 +3108,7 @@ int OnStateChange (int /*long*/ aWebProgress, int /*long*/ aRequest, int aStateF
 		}
 
 		if (request == 0) request = aRequest;
+		registerFunctionsOnState = nsIWebProgressListener.STATE_IS_REQUEST | nsIWebProgressListener.STATE_START;
 		/*
 		 * Add the page's nsIDOMWindow to the collection of windows that will
 		 * have DOM listeners added to them later on in the page loading
@@ -2668,6 +3122,8 @@ int OnStateChange (int /*long*/ aWebProgress, int /*long*/ aRequest, int aStateF
 		unhookedDOMWindows.addElement (new LONG (result[0]));
 	} else if ((aStateFlags & nsIWebProgressListener.STATE_REDIRECTING) != 0) {
 		if (request == aRequest) request = 0;
+		registerFunctionsOnState = nsIWebProgressListener.STATE_TRANSFERRING;
+		updateLastNavigateUrl = true;
 	} else if ((aStateFlags & nsIWebProgressListener.STATE_STOP) != 0) {
 		/*
 		* If this page's nsIDOMWindow handle is still in unhookedDOMWindows then
@@ -2749,12 +3205,12 @@ int OnStateChange (int /*long*/ aWebProgress, int /*long*/ aRequest, int aStateF
 
 				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);
+				byte[] aString;
+				if (untrustedText) {
+					aString = MozillaDelegate.wcsToMbcs (null, ABOUT_BLANK, false);
+				} else {
+					aString = MozillaDelegate.wcsToMbcs (null, URI_FILEROOT, false);
+				}
 				int /*long*/ aSpec = XPCOM.nsEmbedCString_new (aString, aString.length);
 				rc = ioService.NewURI (aSpec, null, 0, result);
 				if (rc != XPCOM.NS_OK) error (rc);
@@ -2772,11 +3228,29 @@ int OnStateChange (int /*long*/ aWebProgress, int /*long*/ aRequest, int aStateF
 				nsIWebBrowserStream stream = new nsIWebBrowserStream (result[0]);
 				result[0] = 0;
 
-				byte[] contentTypeBuffer = MozillaDelegate.wcsToMbcs (null, "text/html", true); // $NON-NLS-1$
+				byte[] contentTypeBuffer = MozillaDelegate.wcsToMbcs (null, "text/html", false); // $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);
+
+				/*
+				* For Mozilla < 1.9.2, when content is being set via nsIWebBrowserStream, this
+				* is the only place where registered functions can be re-installed such that
+				* they will be invokable at load time by JS contained in the text.
+				*/
+				Enumeration elements = functions.elements ();
+				while (elements.hasMoreElements ()) {
+					BrowserFunction function = (BrowserFunction)elements.nextElement ();
+					execute (function.functionString);
+				}
+				/* 
+				* For Mozilla >= 1.9.2, when content is being set via nsIWebBrowserStream,
+				* registered functions must be re-installed in the subsequent Start Request
+				* in order to be invokable at load time by JS contained in the text.
+				*/
+				registerFunctionsOnState = nsIWebProgressListener.STATE_IS_REQUEST | nsIWebProgressListener.STATE_START;
+
 				int /*long*/ ptr = C.malloc (htmlBytes.length);
 				XPCOM.memmove (ptr, htmlBytes, htmlBytes.length);
 				int pageSize = 8192;
@@ -2819,6 +3293,8 @@ int OnStateChange (int /*long*/ aWebProgress, int /*long*/ aRequest, int aStateF
 				result[0] = 0;
 				hookDOMListeners (target, isTop);
 				target.Release ();
+			} else {
+				registerFunctionsOnState = 0;
 			}
 		}
 		domWindow.Release ();
@@ -2842,13 +3318,6 @@ int OnStateChange (int /*long*/ aWebProgress, int /*long*/ aRequest, int aStateF
 				statusTextListeners[i].changed (event);
 			}
 
-			/* re-install registered functions */
-			Enumeration elements = functions.elements ();
-			while (elements.hasMoreElements ()) {
-				BrowserFunction function = (BrowserFunction)elements.nextElement ();
-				execute (function.functionString);
-			}
-
 			final Display display = browser.getDisplay ();
 			final ProgressEvent event2 = new ProgressEvent (browser);
 			event2.display = display;
@@ -2868,6 +3337,35 @@ int OnStateChange (int /*long*/ aWebProgress, int /*long*/ aRequest, int aStateF
 			}
 		}
 	} else if ((aStateFlags & nsIWebProgressListener.STATE_TRANSFERRING) != 0) {
+		if (updateLastNavigateUrl) {
+			updateLastNavigateUrl = false;
+			int /*long*/[] result = new int /*long*/[1];
+			nsIRequest request = new nsIRequest (aRequest);
+
+			int rc = request.QueryInterface (nsIChannel.NS_ICHANNEL_IID, result);
+			if (rc != XPCOM.NS_OK) error (rc);
+			if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
+			nsIChannel channel = new nsIChannel (result[0]);
+			result[0] = 0;
+			rc = channel.GetURI (result);
+			if (rc != XPCOM.NS_OK) error (rc);
+			if (result[0] == 0) error (XPCOM.NS_ERROR_NULL_POINTER);
+			channel.Release ();
+
+			nsIURI uri = new nsIURI (result[0]);
+			result[0] = 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);
+			byte[] bytes = new byte[length];
+			XPCOM.memmove (bytes, buffer, length);
+			lastNavigateURL = new String (bytes);
+			XPCOM.nsEmbedCString_delete (aSpec);
+			uri.Release ();
+		}
+
 		/*
 		* Hook DOM listeners to the page's nsIDOMWindow here because this is
 		* the earliest opportunity to do so.    
@@ -2980,7 +3478,14 @@ int OnLocationChange (int /*long*/ aWebProgress, int /*long*/ aRequest, int /*lo
 	 * 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;
+	if (event.location.equals (URI_FILEROOT)) {
+		event.location = ABOUT_BLANK;
+	} else {
+		length = URI_FILEROOT.length ();
+		if (event.location.startsWith (URI_FILEROOT) && event.location.charAt (length) == '#') {
+			event.location = ABOUT_BLANK + event.location.substring (length);
+		}
+	}
 	event.top = aTop[0] == aDOMWindow[0];
 	for (int i = 0; i < locationListeners.length; i++) {
 		locationListeners[i].changed (event);
@@ -3197,7 +3702,9 @@ int SetVisibility (int aVisibility) {
 				event.location = location;
 				event.size = size;
 				event.addressBar = (chromeFlags & nsIWebBrowserChrome.CHROME_LOCATIONBAR) != 0;
-				event.menuBar = (chromeFlags & nsIWebBrowserChrome.CHROME_MENUBAR) != 0;
+				/* Feature of OSX.  The menu bar is always displayed. */
+				boolean isOSX = Platform.PLATFORM.equals ("cocoa") || Platform.PLATFORM.equals ("carbon");
+				event.menuBar = isOSX || (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++) {
@@ -3350,7 +3857,7 @@ int OnStartURIOpen (int /*long*/ aURI, int /*long*/ retval) {
 	if (value.indexOf ("aboutCertError.xhtml") != -1 || (isViewingErrorPage && value.indexOf ("javascript:showSecuritySection") != -1)) { //$NON-NLS-1$ //$NON-NLS-2$
 		XPCOM.memmove (retval, new int[] {1}, 4); /* PRBool */
 		isRetrievingBadCert = true;
-		setUrl (lastNavigateURL);
+		setUrl (lastNavigateURL, null, null);
 		return XPCOM.NS_OK;
 	}
 	isViewingErrorPage = value.indexOf ("netError.xhtml") != -1; //$NON-NLS-1$
@@ -3371,7 +3878,14 @@ int OnStartURIOpen (int /*long*/ aURI, int /*long*/ retval) {
 				 * 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;
+				if (event.location.equals (URI_FILEROOT)) {
+					event.location = ABOUT_BLANK;
+				} else {
+					length = URI_FILEROOT.length ();
+					if (event.location.startsWith (URI_FILEROOT) && event.location.charAt (length) == '#') {
+						event.location = ABOUT_BLANK + event.location.substring (length);
+					}
+				}
 				event.doit = doit;
 				for (int i = 0; i < locationListeners.length; i++) {
 					locationListeners[i].changing (event);
@@ -3428,7 +3942,7 @@ int IsPreferred (int /*long*/ aContentType, int /*long*/ aDesiredContentType, in
 			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);
+				byte[] bytes = MozillaDelegate.wcsToMbcs (null, contentType, false);
 				int /*long*/ typePtr = XPCOM.nsEmbedCString_new (bytes, bytes.length);
 				nsIWebNavigationInfo info = new nsIWebNavigationInfo (result[0]);
 				result[0] = 0;
@@ -3705,8 +4219,14 @@ int HandleEvent (int /*long*/ event) {
 		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 ()) {
+		boolean doit = true;
+		if (delegate.sendTraverse ()) {
+			doit = sendKeyEvent (keyEvent);
+		} else {
+			browser.notifyListeners (keyEvent.type, keyEvent);
+			doit = keyEvent.doit; 
+		}
+		if (!doit || browser.isDisposed ()) {
 			domEvent.PreventDefault ();
 		}
 		return XPCOM.NS_OK;
@@ -3793,11 +4313,22 @@ int HandleEvent (int /*long*/ event) {
 		}
 	}
 
-	int[] aClientX = new int[1], aClientY = new int[1], aDetail = new int[1]; /* PRInt32 */
-	rc = domMouseEvent.GetClientX (aClientX);
+	int[] aScreenX = new int[1], aScreenY = new int[1]; /* PRInt32 */
+
+	/*
+	 * The position of mouse events is received in screen-relative coordinates
+	 * in order to handle pages with frames, since frames express their event
+	 * coordinates relative to themselves rather than relative to their top-
+	 * level page.  Convert screen-relative coordinates to be browser-relative.
+	 */
+	rc = domMouseEvent.GetScreenX (aScreenX);
 	if (rc != XPCOM.NS_OK) error (rc);
-	rc = domMouseEvent.GetClientY (aClientY);
+	rc = domMouseEvent.GetScreenY (aScreenY);
 	if (rc != XPCOM.NS_OK) error (rc);
+	Point position = new Point (aScreenX[0], aScreenY[0]);
+	position = browser.getDisplay ().map (null, browser, position);
+
+	int[] aDetail = new int[1]; /* PRInt32 */
 	rc = domMouseEvent.GetDetail (aDetail);
 	if (rc != XPCOM.NS_OK) error (rc);
 	short[] aButton = new short[1]; /* PRUint16 */
@@ -3816,7 +4347,7 @@ int HandleEvent (int /*long*/ event) {
 
 	Event mouseEvent = new Event ();
 	mouseEvent.widget = browser;
-	mouseEvent.x = aClientX[0]; mouseEvent.y = aClientY[0];
+	mouseEvent.x = position.x; mouseEvent.y = position.y;
 	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)) {
@@ -3864,7 +4395,7 @@ int HandleEvent (int /*long*/ event) {
 	if (aDetail[0] == 2 && XPCOM.DOMEVENT_MOUSEDOWN.equals (typeString)) {
 		mouseEvent = new Event ();
 		mouseEvent.widget = browser;
-		mouseEvent.x = aClientX[0]; mouseEvent.y = aClientY[0];
+		mouseEvent.x = position.x; mouseEvent.y = position.y;
 		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;
diff --git a/org/eclipse/swt/browser/MozillaDelegate.java b/org/eclipse/swt/browser/MozillaDelegate.java
index 76a5d83..e2dda62 100644
--- a/org/eclipse/swt/browser/MozillaDelegate.java
+++ b/org/eclipse/swt/browser/MozillaDelegate.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2003, 2009 IBM Corporation and others.
+ * Copyright (c) 2003, 2010 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
@@ -68,6 +68,10 @@ static Browser findBrowser (int /*long*/ handle) {
 	return (Browser)display.findWidget (parent); 
 }
 
+static String getLibraryName () {
+	return "libxpcom.so"; //$NON-NLS-1$
+}
+
 static char[] mbcsToWcs (String codePage, byte [] buffer) {
 	return Converter.mbcsToWcs (codePage, buffer);
 }
@@ -104,8 +108,9 @@ String getJSLibraryName () {
 	return "libmozjs.so"; //$NON-NLS-1$
 }
 
-String getLibraryName () {
-	return "libxpcom.so"; //$NON-NLS-1$
+String getProfilePath () {
+	String baseDir = System.getProperty ("user.home"); //$NON-NLS-1$
+	return baseDir + Mozilla.SEPARATOR_OS + ".mozilla" + Mozilla.SEPARATOR_OS + "eclipse"; //$NON-NLS-1$ //$NON-NLS-2$
 }
 
 String getSWTInitLibraryName () {
@@ -216,6 +221,10 @@ void onDispose (int /*long*/ embedHandle) {
 void removeWindowSubclass () {
 }
 
+boolean sendTraverse () {
+	return true;
+}
+
 void setSize (int /*long*/ embedHandle, int width, int height) {
 	OS.gtk_widget_set_size_request (embedHandle, width, height);
 }
diff --git a/org/eclipse/swt/browser/PromptDialog.java b/org/eclipse/swt/browser/PromptDialog.java
index df42674..02e0946 100644
--- a/org/eclipse/swt/browser/PromptDialog.java
+++ b/org/eclipse/swt/browser/PromptDialog.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2003, 2007 IBM Corporation and others.
+ * 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
@@ -138,7 +138,7 @@ class PromptDialog extends Dialog {
 
 		Button viewCertButton = new Button(buttonsComposite, SWT.PUSH);
 		viewCertButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
-		viewCertButton.setText(Compatibility.getMessage("View Certificate")); //$NON-NLS-1$
+		viewCertButton.setText(Compatibility.getMessage("SWT_ViewCertificate")); //$NON-NLS-1$
 		viewCertButton.addListener(SWT.Selection, new Listener() {
 			public void handleEvent(Event event) {
 				int /*long*/[] result = new int /*long*/[1];
diff --git a/org/eclipse/swt/browser/PromptService2.java b/org/eclipse/swt/browser/PromptService2.java
index e41b97a..7f1d718 100644
--- a/org/eclipse/swt/browser/PromptService2.java
+++ b/org/eclipse/swt/browser/PromptService2.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2003, 2009 IBM Corporation and others.
+ * Copyright (c) 2003, 2010 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
@@ -20,6 +20,17 @@ class PromptService2 {
 	XPCOMObject promptService;
 	XPCOMObject promptService2;
 	int refCount = 0;
+	
+	static final String[] certErrorCodes = new String[] {
+		"ssl_error_bad_cert_domain",
+		"sec_error_ca_cert_invalid",
+		"sec_error_expired_certificate",
+		"sec_error_expired_issuer_certificate",
+		"sec_error_inadequate_key_usage",
+		"sec_error_unknown_issuer",
+		"sec_error_untrusted_cert",
+		"sec_error_untrusted_issuer",
+	};	//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$
 
 PromptService2 () {
 	createCOMInterfaces ();
@@ -169,15 +180,15 @@ int Alert (int /*long*/ aParent, int /*long*/ aDialogTitle, int /*long*/ aText)
 	* detected then instead of showing it, re-navigate to the page with the invalid
 	* certificate so that the browser's nsIBadCertListener2 will be invoked.
 	*/
-	if (textLabel.indexOf ("ssl_error_bad_cert_domain") != -1 ||
-		textLabel.indexOf ("sec_error_unknown_issuer") != -1 ||
-		textLabel.indexOf ("sec_error_expired_certificate") != -1) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-			if (browser != null) {
+	if (browser != null) {
+		for (int i = 0; i < certErrorCodes.length; i++) {
+			if (textLabel.indexOf (certErrorCodes[i]) != -1) {
 				Mozilla mozilla = (Mozilla)browser.webBrowser;
 				mozilla.isRetrievingBadCert = true;
 				browser.setUrl (mozilla.lastNavigateURL);
 				return XPCOM.NS_OK;
 			}
+		}
 	}
 
 	Shell shell = browser == null ? new Shell () : browser.getShell (); 
@@ -221,7 +232,12 @@ int AsyncPromptAuth(int /*long*/ aParent, int /*long*/ aChannel, int /*long*/ aC
 
 int Confirm (int /*long*/ aParent, int /*long*/ aDialogTitle, int /*long*/ aText, int /*long*/ _retval) {
 	Browser browser = getBrowser (aParent);
-	
+
+	if (browser != null && ((Mozilla)browser.webBrowser).ignoreAllMessages) {
+		XPCOM.memmove (_retval, new int[] {1}, 4); /* PRBool */
+		return XPCOM.NS_OK;
+	}
+
 	int length = XPCOM.strlen_PRUnichar (aDialogTitle);
 	char[] dest = new char[length];
 	XPCOM.memmove (dest, aDialogTitle, length * 2);
@@ -238,7 +254,7 @@ int Confirm (int /*long*/ aParent, int /*long*/ aDialogTitle, int /*long*/ aText
 	messageBox.setMessage (textLabel);
 	int id = messageBox.open ();
 	int[] result = {id == SWT.OK ? 1 : 0};
-	XPCOM.memmove (_retval, result, 4);
+	XPCOM.memmove (_retval, result, 4); /* PRBool */
 	return XPCOM.NS_OK;
 }
 
diff --git a/org/eclipse/swt/browser/WebBrowser.java b/org/eclipse/swt/browser/WebBrowser.java
index ea8ef4b..8b93b11 100644
--- a/org/eclipse/swt/browser/WebBrowser.java
+++ b/org/eclipse/swt/browser/WebBrowser.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2003, 2009 IBM Corporation and others.
+ * Copyright (c) 2003, 2010 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
@@ -26,13 +26,15 @@ abstract class WebBrowser {
 	StatusTextListener[] statusTextListeners = new StatusTextListener[0];
 	TitleListener[] titleListeners = new TitleListener[0];
 	VisibilityWindowListener[] visibilityWindowListeners = new VisibilityWindowListener[0];
-	boolean jsEnabled = true;
-	boolean jsEnabledChanged;
+	boolean jsEnabledChanged, jsEnabled = true;
 	int nextFunctionIndex = 1;
 	Object evaluateResult;
 
 	static final String ERROR_ID = "org.eclipse.swt.browser.error"; // $NON-NLS-1$
 	static final String EXECUTE_ID = "SWTExecuteTemporaryFunction"; // $NON-NLS-1$
+
+	static Vector NativePendingCookies = new Vector ();
+	static Vector MozillaPendingCookies = new Vector ();
 	static String CookieName, CookieValue, CookieUrl;
 	static boolean CookieResult;
 	static Runnable MozillaClearSessions, NativeClearSessions;
@@ -169,7 +171,7 @@ abstract class WebBrowser {
 		{19,	SWT.PAUSE},
 		{3,		SWT.BREAK},
 
-		/* Safari-specific */
+		/* WebKit/Safari-specific */
 		{186,	';'},
 		{187,	'='},
 		{189,	'-'},
@@ -261,24 +263,44 @@ public static void clearSessions () {
 }
 
 public static String GetCookie (String name, String url) {
-	CookieName = name; CookieUrl = url;
+	CookieName = name; CookieUrl = url; CookieValue = null;
 	if (NativeGetCookie != null) NativeGetCookie.run ();
-	if (MozillaGetCookie != null) MozillaGetCookie.run ();
+	if (CookieValue == null && MozillaGetCookie != null) MozillaGetCookie.run ();
 	String result = CookieValue;
 	CookieName = CookieValue = CookieUrl = null;
 	return result;
 }
 
-public static boolean SetCookie (String value, String url) {
+public static boolean SetCookie (String value, String url, boolean addToPending) {
 	CookieValue = value; CookieUrl = url;
 	CookieResult = false;
-	if (NativeSetCookie != null) NativeSetCookie.run ();
-	if (MozillaSetCookie != null) MozillaSetCookie.run ();
+	if (NativeSetCookie != null) {
+		NativeSetCookie.run ();
+	} else {
+		if (addToPending && NativePendingCookies != null) {
+			NativePendingCookies.add (new String[] {value, url});
+		}
+	}
+	if (MozillaSetCookie != null) {
+		MozillaSetCookie.run ();
+	} else {
+		if (addToPending && MozillaPendingCookies != null) {
+			MozillaPendingCookies.add (new String[] {value, url});
+		}
+	}
 	CookieValue = CookieUrl = null;
 	return CookieResult;
 }
 
-public abstract void create (Composite parent, int style);
+static void SetPendingCookies (Vector pendingCookies) {
+	Enumeration elements = pendingCookies.elements ();
+	while (elements.hasMoreElements ()) {
+		String[] current = (String[])elements.nextElement ();
+		SetCookie (current[0], current[1], false);
+	}
+}
+
+public abstract boolean create (Composite parent, int style);
 
 static String CreateErrorString (String error) {
 	return ERROR_ID + error;
@@ -288,6 +310,10 @@ static String ExtractError (String error) {
 	return error.substring (ERROR_ID.length ());
 }
 
+public boolean close () {
+	return true;
+}
+
 public void createFunction (BrowserFunction function) {
 	/* 
 	 * If an existing function with the same name is found then
@@ -579,13 +605,83 @@ public void removeVisibilityWindowListener (VisibilityWindowListener listener) {
 	visibilityWindowListeners = newVisibilityWindowListeners;
 }
 
+boolean sendKeyEvent (Event event) {
+	int traversal = SWT.TRAVERSE_NONE;
+	boolean traverseDoit = true;
+	switch (event.keyCode) {
+		case SWT.ESC: {
+			traversal = SWT.TRAVERSE_ESCAPE;
+			traverseDoit = true;
+			break;
+		}
+		case SWT.CR: {
+			traversal = SWT.TRAVERSE_RETURN;
+			traverseDoit = false;
+			break;
+		}
+		case SWT.ARROW_DOWN:
+		case SWT.ARROW_RIGHT: {
+			traversal = SWT.TRAVERSE_ARROW_NEXT;
+			traverseDoit = false;
+			break;
+		}
+		case SWT.ARROW_UP:
+		case SWT.ARROW_LEFT: {
+			traversal = SWT.TRAVERSE_ARROW_PREVIOUS;
+			traverseDoit = false;
+			break;
+		}
+		case SWT.TAB: {
+			traversal = (event.stateMask & SWT.SHIFT) != 0 ? SWT.TRAVERSE_TAB_PREVIOUS : SWT.TRAVERSE_TAB_NEXT;
+			traverseDoit = (event.stateMask & SWT.CTRL) != 0;
+			break;
+		}
+		case SWT.PAGE_DOWN: {
+			if ((event.stateMask & SWT.CTRL) != 0) {
+				traversal = SWT.TRAVERSE_PAGE_NEXT;
+				traverseDoit = true;
+			}
+			break;
+		}
+		case SWT.PAGE_UP: {
+			if ((event.stateMask & SWT.CTRL) != 0) {
+				traversal = SWT.TRAVERSE_PAGE_PREVIOUS;
+				traverseDoit = true;
+			}
+			break;
+		}
+		default: {
+			if (translateMnemonics ()) {
+				if (event.character != 0 && (event.stateMask & (SWT.ALT | SWT.CTRL)) == SWT.ALT) {
+					traversal = SWT.TRAVERSE_MNEMONIC;
+					traverseDoit = true;
+				}
+			}
+			break;
+		}
+	}
+
+	boolean doit = true;
+	if (traversal != SWT.TRAVERSE_NONE) {
+		boolean oldEventDoit = event.doit;
+		event.doit = traverseDoit;	
+		doit = !browser.traverse (traversal, event);
+		event.doit = oldEventDoit;
+	}
+	if (doit) {
+		browser.notifyListeners (event.type, event);
+		doit = event.doit; 
+	}
+	return doit;
+}
+
 public void setBrowser (Browser browser) {
 	this.browser = browser;
 }
 
-public abstract boolean setText (String html);
+public abstract boolean setText (String html, boolean trusted);
 
-public abstract boolean setUrl (String url);
+public abstract boolean setUrl (String url, String postData, String[] headers);
 
 public abstract void stop ();
 
@@ -595,4 +691,9 @@ int translateKey (int key) {
 	}
 	return 0;
 }
+
+boolean translateMnemonics () {
+	return true;
+}
+
 }
diff --git a/org/eclipse/swt/browser/WebKit.java b/org/eclipse/swt/browser/WebKit.java
new file mode 100644
index 0000000..1244c84
--- /dev/null
+++ b/org/eclipse/swt/browser/WebKit.java
@@ -0,0 +1,1861 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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.UnsupportedEncodingException;
+import java.net.*;
+import java.util.*;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.internal.*;
+import org.eclipse.swt.internal.gtk.OS;
+import org.eclipse.swt.internal.webkit.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+
+public class WebKit extends WebBrowser {
+	int /*long*/ webView, webViewData, scrolledWindow;
+	int failureCount, lastKeyCode, lastCharCode;
+	String postData;
+	String[] headers;
+	boolean ignoreDispose, loadingText, untrustedText;
+	byte[] htmlBytes;
+	BrowserFunction eventFunction;
+
+	static int /*long*/ ExternalClass, PostString;
+	static boolean LibraryLoaded;
+
+	static final String ABOUT_BLANK = "about:blank"; //$NON-NLS-1$
+	static final String CHARSET_UTF8 = "UTF-8"; //$NON-NLS-1$
+	static final String CLASSNAME_EXTERNAL = "External"; //$NON-NLS-1$
+	static final String ENCODING_FORM = "Content-Type: application/x-www-form-urlencoded"; //$NON-NLS-1$
+	static final String FUNCTIONNAME_CALLJAVA = "callJava"; //$NON-NLS-1$
+	static final String OBJECTNAME_EXTERNAL = "external"; //$NON-NLS-1$
+	static final String PROPERTY_LENGTH = "length"; //$NON-NLS-1$
+	static final String PROPERTY_PROXYHOST = "network.proxy_host"; //$NON-NLS-1$
+	static final String PROPERTY_PROXYPORT = "network.proxy_port"; //$NON-NLS-1$
+	static final String PROTOCOL_FILE = "file://"; //$NON-NLS-1$
+	static final String PROTOCOL_HTTP = "http://"; //$NON-NLS-1$
+	static final String URI_FILEROOT = "file:///"; //$NON-NLS-1$
+	static final String USER_AGENT = "user-agent"; //$NON-NLS-1$
+	static final int MAX_PORT = 65535;
+	static final int MAX_PROGRESS = 100;
+	static final int[] MIN_VERSION = {1, 2, 0};
+	static final char SEPARATOR_FILE = System.getProperty ("file.separator").charAt (0); //$NON-NLS-1$
+	static final int STOP_PROPOGATE = 1;
+
+	static final String DOMEVENT_DRAGSTART = "dragstart"; //$NON-NLS-1$
+	static final String DOMEVENT_KEYDOWN = "keydown"; //$NON-NLS-1$
+	static final String DOMEVENT_KEYPRESS = "keypress"; //$NON-NLS-1$
+	static final String DOMEVENT_KEYUP = "keyup"; //$NON-NLS-1$
+	static final String DOMEVENT_MOUSEDOWN = "mousedown"; //$NON-NLS-1$
+	static final String DOMEVENT_MOUSEUP = "mouseup"; //$NON-NLS-1$
+	static final String DOMEVENT_MOUSEMOVE = "mousemove"; //$NON-NLS-1$
+	static final String DOMEVENT_MOUSEOUT = "mouseout"; //$NON-NLS-1$
+	static final String DOMEVENT_MOUSEOVER = "mouseover"; //$NON-NLS-1$
+	static final String DOMEVENT_MOUSEWHEEL = "mousewheel"; //$NON-NLS-1$
+
+	/* WebKit signal data */
+	static final int HOVERING_OVER_LINK = 1;
+	static final int NOTIFY_PROGRESS = 2;
+	static final int NAVIGATION_POLICY_DECISION_REQUESTED = 3;
+	static final int NOTIFY_TITLE = 4;
+	static final int POPULATE_POPUP = 5;
+	static final int STATUS_BAR_TEXT_CHANGED = 6;
+	static final int CREATE_WEB_VIEW = 7;
+	static final int WEB_VIEW_READY = 8;
+	static final int NOTIFY_LOAD_STATUS = 9;
+	static final int RESOURCE_REQUEST_STARTING = 10;
+	static final int DOWNLOAD_REQUESTED = 11;
+	static final int MIME_TYPE_POLICY_DECISION_REQUESTED = 12;
+	static final int CLOSE_WEB_VIEW = 13;
+	static final int WINDOW_OBJECT_CLEARED = 14;
+	static final int CONSOLE_MESSAGE = 15;
+
+	static final String KEY_CHECK_SUBWINDOW = "org.eclipse.swt.internal.control.checksubwindow"; //$NON-NLS-1$
+
+	// the following Callbacks are never freed
+	static Callback Proc2, Proc3, Proc4, Proc5, Proc6;
+	static Callback JSObjectHasPropertyProc, JSObjectGetPropertyProc, JSObjectCallAsFunctionProc;
+
+	static {
+		try {
+			Library.loadLibrary ("swt-webkit"); // $NON-NLS-1$
+			LibraryLoaded = true;
+		} catch (Throwable e) {
+		}
+
+		Proc2 = new Callback (WebKit.class, "Proc", 2); //$NON-NLS-1$
+		if (Proc2.getAddress () == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS);
+		Proc3 = new Callback (WebKit.class, "Proc", 3); //$NON-NLS-1$
+		if (Proc3.getAddress () == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS);
+		Proc4 = new Callback (WebKit.class, "Proc", 4); //$NON-NLS-1$
+		if (Proc4.getAddress () == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS);
+		Proc5 = new Callback (WebKit.class, "Proc", 5); //$NON-NLS-1$
+		if (Proc5.getAddress () == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS);
+		Proc6 = new Callback (WebKit.class, "Proc", 6); //$NON-NLS-1$
+		if (Proc6.getAddress () == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS);
+		JSObjectHasPropertyProc = new Callback (WebKit.class, "JSObjectHasPropertyProc", 3); //$NON-NLS-1$
+		if (JSObjectHasPropertyProc.getAddress () == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS);
+		JSObjectGetPropertyProc = new Callback (WebKit.class, "JSObjectGetPropertyProc", 4); //$NON-NLS-1$
+		if (JSObjectGetPropertyProc.getAddress () == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS);
+		JSObjectCallAsFunctionProc = new Callback (WebKit.class, "JSObjectCallAsFunctionProc", 6); //$NON-NLS-1$
+		if (JSObjectCallAsFunctionProc.getAddress () == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS);
+
+		NativeClearSessions = new Runnable () {
+			public void run () {
+				if (!LibraryLoaded) return;
+				int /*long*/ session = WebKitGTK.webkit_get_default_session ();
+				int type = WebKitGTK.soup_cookie_jar_get_type ();
+				int /*long*/ jar = WebKitGTK.soup_session_get_feature (session, type);
+				if (jar == 0) return;
+				int /*long*/ cookies = WebKitGTK.soup_cookie_jar_all_cookies (jar);
+				int length = OS.g_slist_length (cookies);
+				int /*long*/ current = cookies;
+				for (int i = 0; i < length; i++) {
+					int /*long*/ cookie = OS.g_slist_data (current);
+					int /*long*/ expires = WebKitGTK.SoupCookie_expires (cookie);
+					if (expires == 0) {
+						/* indicates a session cookie */
+						WebKitGTK.soup_cookie_jar_delete_cookie (jar, cookie);
+					}
+					OS.g_free (cookie);
+					current = OS.g_slist_next (current);
+				}
+			}
+		};
+
+		NativeGetCookie = new Runnable () {
+			public void run () {
+				if (!LibraryLoaded) return;
+				int /*long*/ session = WebKitGTK.webkit_get_default_session ();
+				int type = WebKitGTK.soup_cookie_jar_get_type ();
+				int /*long*/ jar = WebKitGTK.soup_session_get_feature (session, type);
+				if (jar == 0) return;
+				byte[] bytes = Converter.wcsToMbcs (null, CookieUrl, true);
+				int /*long*/ uri = WebKitGTK.soup_uri_new (bytes);
+				if (uri == 0) return;
+				int /*long*/ cookies = WebKitGTK.soup_cookie_jar_get_cookies (jar, uri, 0);
+				WebKitGTK.soup_uri_free (uri);
+				if (cookies == 0) return;
+				int length = OS.strlen (cookies);
+				bytes = new byte[length];
+				C.memmove (bytes, cookies, length);
+				OS.g_free (cookies);
+				String allCookies = new String (Converter.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;
+						}
+					}
+				}
+
+			}
+		};
+
+		NativeSetCookie = new Runnable () {
+			public void run () {
+				if (!LibraryLoaded) return;
+				int /*long*/ session = WebKitGTK.webkit_get_default_session ();
+				int type = WebKitGTK.soup_cookie_jar_get_type ();
+				int /*long*/ jar = WebKitGTK.soup_session_get_feature (session, type);
+				if (jar == 0) {
+					/* this happens if a navigation has not occurred yet */
+					WebKitGTK.soup_session_add_feature_by_type (session, type);
+					jar = WebKitGTK.soup_session_get_feature (session, type);
+				}
+				if (jar == 0) return;
+				byte[] bytes = Converter.wcsToMbcs (null, CookieUrl, true);
+				int /*long*/ uri = WebKitGTK.soup_uri_new (bytes);
+				if (uri == 0) return;
+				bytes = Converter.wcsToMbcs (null, CookieValue, true);
+				int /*long*/ cookie = WebKitGTK.soup_cookie_parse (bytes, uri);
+				if (cookie != 0) {
+					WebKitGTK.soup_cookie_jar_add_cookie (jar, cookie);
+					// the following line is intentionally commented
+					// WebKitGTK.soup_cookie_free (cookie);
+					CookieResult = true;
+				}
+				WebKitGTK.soup_uri_free (uri);
+			}
+		};
+
+		if (NativePendingCookies != null) {
+			SetPendingCookies (NativePendingCookies);
+			NativePendingCookies = null;
+		}
+	}
+
+static Browser findBrowser (int /*long*/ webView) {
+	if (webView == 0) return null;
+	int /*long*/ parent = OS.gtk_widget_get_parent (webView);
+	parent = OS.gtk_widget_get_parent (parent);
+	return (Browser)Display.getCurrent ().findWidget (parent);
+}
+
+static int /*long*/ JSObjectCallAsFunctionProc (int /*long*/ ctx, int /*long*/ function, int /*long*/ thisObject, int /*long*/ argumentCount, int /*long*/ arguments, int /*long*/ exception) {
+	if (WebKitGTK.JSValueIsObjectOfClass (ctx, thisObject, ExternalClass) == 0) {
+		return WebKitGTK.JSValueMakeUndefined (ctx);
+	}
+	int /*long*/ ptr = WebKitGTK.JSObjectGetPrivate (thisObject);
+	int /*long*/[] handle = new int /*long*/[1];
+	C.memmove (handle, ptr, C.PTR_SIZEOF);
+	Browser browser = findBrowser (handle[0]);
+	if (browser == null) return 0;
+	WebKit webkit = (WebKit)browser.webBrowser;
+	return webkit.callJava (ctx, function, thisObject, argumentCount, arguments, exception);
+}
+
+static int /*long*/ JSObjectGetPropertyProc (int /*long*/ ctx, int /*long*/ object, int /*long*/ propertyName, int /*long*/ exception) {
+	byte[] bytes = null;
+	try {
+		bytes = (FUNCTIONNAME_CALLJAVA + '\0').getBytes (CHARSET_UTF8); //$NON-NLS-1$
+	} catch (UnsupportedEncodingException e) {
+		bytes = Converter.wcsToMbcs (null, FUNCTIONNAME_CALLJAVA, true);
+	} 
+	int /*long*/ name = WebKitGTK.JSStringCreateWithUTF8CString (bytes);
+	int /*long*/ function = WebKitGTK.JSObjectMakeFunctionWithCallback (ctx, name, JSObjectCallAsFunctionProc.getAddress ());
+	WebKitGTK.JSStringRelease (name);
+	return function;
+}
+
+static int /*long*/ JSObjectHasPropertyProc (int /*long*/ ctx, int /*long*/ object, int /*long*/ propertyName) {
+	byte[] bytes = null;
+	try {
+		bytes = (FUNCTIONNAME_CALLJAVA + '\0').getBytes (CHARSET_UTF8); //$NON-NLS-1$
+	} catch (UnsupportedEncodingException e) {
+		bytes = Converter.wcsToMbcs (null, FUNCTIONNAME_CALLJAVA, true);
+	}
+	return WebKitGTK.JSStringIsEqualToUTF8CString (propertyName, bytes);
+}
+
+static int /*long*/ Proc (int /*long*/ handle, int /*long*/ user_data) {
+	Browser browser = findBrowser (handle);
+	if (browser == null) return 0;
+	WebKit webkit = (WebKit)browser.webBrowser;
+	return webkit.webViewProc (handle, user_data);
+}
+
+static int /*long*/ Proc (int /*long*/ handle, int /*long*/ arg0, int /*long*/ user_data) {
+	if (OS.GTK_IS_SCROLLED_WINDOW (handle)) {
+		/*
+		 * Stop the propagation of events that are not consumed by WebKit, before
+		 * they reach the parent embedder.  These events have already been received.
+		 */
+		return user_data;
+	}
+
+	int /*long*/ webView;
+	if (WebKitGTK.WEBKIT_IS_WEB_FRAME (handle)) {
+		webView = WebKitGTK.webkit_web_frame_get_web_view (handle);
+	} else {
+		webView = handle;
+	}
+	Browser browser = findBrowser (webView); 
+	if (browser == null) return 0;
+	WebKit webkit = (WebKit)browser.webBrowser;
+	if (webView == handle) {
+		return webkit.webViewProc (handle, arg0, user_data);
+	} else {
+		return webkit.webFrameProc (handle, arg0, user_data);
+	}
+}
+
+static int /*long*/ Proc (int /*long*/ handle, int /*long*/ arg0, int /*long*/ arg1, int /*long*/ user_data) {
+	Browser browser = findBrowser (handle);
+	if (browser == null) return 0;
+	WebKit webkit = (WebKit)browser.webBrowser;
+	return webkit.webViewProc (handle, arg0, arg1, user_data);
+}
+
+static int /*long*/ Proc (int /*long*/ handle, int /*long*/ arg0, int /*long*/ arg1, int /*long*/ arg2, int /*long*/ user_data) {
+	int /*long*/ webView;
+	if (WebKitGTK.SOUP_IS_SESSION (handle)) {
+		webView = user_data;
+	} else {
+		webView = handle;
+	}
+	Browser browser = findBrowser (webView);
+	if (browser == null) return 0;
+	WebKit webkit = (WebKit)browser.webBrowser;
+	if (webView == handle) {
+		return webkit.webViewProc (handle, arg0, arg1, arg2, user_data);
+	} else {
+		return webkit.sessionProc (handle, arg0, arg1, arg2, user_data);
+	}
+}
+
+static int /*long*/ Proc (int /*long*/ handle, int /*long*/ arg0, int /*long*/ arg1, int /*long*/ arg2, int /*long*/ arg3, int /*long*/ user_data) {
+	Browser browser = findBrowser (handle);
+	if (browser == null) return 0;
+	WebKit webkit = (WebKit)browser.webBrowser;
+	return webkit.webViewProc (handle, arg0, arg1, arg2, arg3, user_data);
+}
+
+int /*long*/ sessionProc (int /*long*/ session, int /*long*/ msg, int /*long*/ auth, int /*long*/ retrying, int /*long*/ user_data) {
+	/* authentication challenges are currently the only notification received from the session */
+	if (retrying == 0) {
+		failureCount = 0;
+	} else {
+		if (++failureCount >= 3) return 0;
+	}
+
+	int /*long*/ uri = WebKitGTK.soup_message_get_uri (msg);
+	int /*long*/ uriString = WebKitGTK.soup_uri_to_string (uri, 0);
+	int length = C.strlen (uriString);
+	byte[] bytes = new byte[length];
+	OS.memmove (bytes, uriString, length);
+	OS.g_free (uriString);
+	String location = new String (MozillaDelegate.mbcsToWcs (null, bytes));
+
+	for (int i = 0; i < authenticationListeners.length; i++) {
+		AuthenticationEvent event = new AuthenticationEvent (browser);
+		event.location = location;
+		authenticationListeners[i].authenticate (event);
+		if (!event.doit) {
+			OS.g_signal_stop_emission_by_name (session, WebKitGTK.authenticate);
+			return 0;
+		}
+		if (event.user != null && event.password != null) {
+			byte[] userBytes = Converter.wcsToMbcs (null, event.user, true);
+			byte[] passwordBytes = Converter.wcsToMbcs (null, event.password, true);
+			WebKitGTK.soup_auth_authenticate (auth, userBytes, passwordBytes);
+			OS.g_signal_stop_emission_by_name (session, WebKitGTK.authenticate);
+			return 0;
+		}
+	}
+	return 0;
+}
+
+int /*long*/ webFrameProc (int /*long*/ handle, int /*long*/ arg0, int /*long*/ user_data) {
+	switch ((int)/*64*/user_data) {
+		case NOTIFY_LOAD_STATUS: return webframe_notify_load_status (handle, arg0);
+		default: return 0;
+	}
+}
+
+int /*long*/ webViewProc (int /*long*/ handle, int /*long*/ user_data) {
+	switch ((int)/*64*/user_data) {
+		case CLOSE_WEB_VIEW: return webkit_close_web_view (handle);
+		case WEB_VIEW_READY: return webkit_web_view_ready (handle);
+		default: return 0;
+	}
+}
+
+int /*long*/ webViewProc (int /*long*/ handle, int /*long*/ arg0, int /*long*/ user_data) {
+	switch ((int)/*64*/user_data) {
+		case CREATE_WEB_VIEW: return webkit_create_web_view (handle, arg0);
+		case DOWNLOAD_REQUESTED: return webkit_download_requested (handle, arg0);
+		case NOTIFY_LOAD_STATUS: return webkit_notify_load_status (handle, arg0);
+		case NOTIFY_PROGRESS: return webkit_notify_progress (handle, arg0);
+		case NOTIFY_TITLE: return webkit_notify_title (handle, arg0);
+		case POPULATE_POPUP: return webkit_populate_popup (handle, arg0);
+		case STATUS_BAR_TEXT_CHANGED: return webkit_status_bar_text_changed (handle, arg0);
+		default: return 0;
+	}
+}
+
+int /*long*/ webViewProc (int /*long*/ handle, int /*long*/ arg0, int /*long*/ arg1, int /*long*/ user_data) {
+	switch ((int)/*64*/user_data) {
+		case HOVERING_OVER_LINK: return webkit_hovering_over_link (handle, arg0, arg1);
+		default: return 0;
+	}
+}
+
+int /*long*/ webViewProc (int /*long*/ handle, int /*long*/ arg0, int /*long*/ arg1, int /*long*/ arg2, int /*long*/ user_data) {
+	switch ((int)/*64*/user_data) {
+		case CONSOLE_MESSAGE: return webkit_console_message (handle, arg0, arg1, arg2);
+		case WINDOW_OBJECT_CLEARED: return webkit_window_object_cleared (handle, arg0, arg1, arg2);
+		default: return 0;
+	}
+}
+
+int /*long*/ webViewProc (int /*long*/ handle, int /*long*/ arg0, int /*long*/ arg1, int /*long*/ arg2, int /*long*/ arg3, int /*long*/ user_data) {
+	switch ((int)/*64*/user_data) {
+		case MIME_TYPE_POLICY_DECISION_REQUESTED: return webkit_mime_type_policy_decision_requested (handle, arg0, arg1, arg2, arg3);
+		case NAVIGATION_POLICY_DECISION_REQUESTED: return webkit_navigation_policy_decision_requested (handle, arg0, arg1, arg2, arg3);
+		case RESOURCE_REQUEST_STARTING: return webkit_resource_request_starting (handle, arg0, arg1, arg2, arg3);
+		default: return 0;
+	}
+}
+
+public boolean create (Composite parent, int style) {
+	if (!LibraryLoaded) return false;
+
+	if (ExternalClass == 0) {
+		// TODO webkit_check_version() should do the following, but for some reason
+		// this symbol is missing from the latest build.  If it is present in Linux
+		// distro-provided builds then replace the following with this call.
+		int major = WebKitGTK.webkit_major_version ();
+		int minor = WebKitGTK.webkit_minor_version ();
+		int micro = WebKitGTK.webkit_micro_version ();
+		boolean success = major > MIN_VERSION[0] ||
+			(major == MIN_VERSION[0] && minor > MIN_VERSION[1]) ||
+			(major == MIN_VERSION[0] && minor == MIN_VERSION[1] && micro >= MIN_VERSION[2]);
+		if (!success) return false;
+
+		if (Device.DEBUG) {
+			System.out.println("WebKit version " + major + "." + minor + "." + micro); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		}
+		JSClassDefinition jsClassDefinition = new JSClassDefinition ();
+		byte[] bytes = Converter.wcsToMbcs (null, CLASSNAME_EXTERNAL, true);
+		jsClassDefinition.className = C.malloc (bytes.length);
+		OS.memmove (jsClassDefinition.className, bytes, bytes.length);
+		jsClassDefinition.hasProperty = JSObjectHasPropertyProc.getAddress ();
+		jsClassDefinition.getProperty = JSObjectGetPropertyProc.getAddress ();
+		int /*long*/ classDefinitionPtr = C.malloc (JSClassDefinition.sizeof);
+		WebKitGTK.memmove (classDefinitionPtr, jsClassDefinition, JSClassDefinition.sizeof);
+		ExternalClass = WebKitGTK.JSClassCreate (classDefinitionPtr);
+
+		bytes = Converter.wcsToMbcs (null, "POST", true); //$NON-NLS-1$
+		PostString = C.malloc (bytes.length);
+		C.memmove (PostString, bytes, bytes.length);
+	}
+
+    scrolledWindow = OS.gtk_scrolled_window_new (0, 0);
+    OS.gtk_scrolled_window_set_policy (scrolledWindow, OS.GTK_POLICY_AUTOMATIC, OS.GTK_POLICY_AUTOMATIC);
+    webView = WebKitGTK.webkit_web_view_new ();
+    webViewData = C.malloc (C.PTR_SIZEOF);
+    C.memmove (webViewData, new int /*long*/[] {webView}, C.PTR_SIZEOF);
+    OS.gtk_container_add (scrolledWindow, webView);
+    OS.gtk_container_add (browser.handle, scrolledWindow);
+    OS.gtk_widget_show (scrolledWindow);
+	OS.gtk_widget_show (webView);
+	OS.g_signal_connect (webView, WebKitGTK.close_web_view, Proc2.getAddress (), CLOSE_WEB_VIEW);
+	OS.g_signal_connect (webView, WebKitGTK.console_message, Proc5.getAddress (), CONSOLE_MESSAGE);
+	OS.g_signal_connect (webView, WebKitGTK.create_web_view, Proc3.getAddress (), CREATE_WEB_VIEW);
+	OS.g_signal_connect (webView, WebKitGTK.download_requested, Proc3.getAddress (), DOWNLOAD_REQUESTED);
+	OS.g_signal_connect (webView, WebKitGTK.hovering_over_link, Proc4.getAddress (), HOVERING_OVER_LINK);
+	OS.g_signal_connect (webView, WebKitGTK.mime_type_policy_decision_requested, Proc6.getAddress (), MIME_TYPE_POLICY_DECISION_REQUESTED);
+	OS.g_signal_connect (webView, WebKitGTK.navigation_policy_decision_requested, Proc6.getAddress (), NAVIGATION_POLICY_DECISION_REQUESTED);
+    OS.g_signal_connect (webView, WebKitGTK.notify_load_status, Proc3.getAddress (), NOTIFY_LOAD_STATUS);
+    OS.g_signal_connect (webView, WebKitGTK.notify_progress, Proc3.getAddress (), NOTIFY_PROGRESS);
+    OS.g_signal_connect (webView, WebKitGTK.notify_title, Proc3.getAddress (), NOTIFY_TITLE);
+    OS.g_signal_connect (webView, WebKitGTK.populate_popup, Proc3.getAddress (), POPULATE_POPUP);
+    OS.g_signal_connect (webView, WebKitGTK.resource_request_starting, Proc6.getAddress (), RESOURCE_REQUEST_STARTING);
+    OS.g_signal_connect (webView, WebKitGTK.status_bar_text_changed, Proc3.getAddress (), STATUS_BAR_TEXT_CHANGED);
+    OS.g_signal_connect (webView, WebKitGTK.web_view_ready, Proc2.getAddress (), WEB_VIEW_READY);
+    OS.g_signal_connect (webView, WebKitGTK.window_object_cleared, Proc5.getAddress (), WINDOW_OBJECT_CLEARED);
+
+	/* Callback to get events before WebKit receives and consumes them */
+	OS.g_signal_connect (scrolledWindow, OS.event, Proc3.getAddress (), 0);
+	/*
+	* Callbacks to get the events not consumed by WebKit, and to block 
+	* them so that they don't get propagated to the parent handle twice.  
+	* This hook is set after WebKit and is therefore called after WebKit's 
+	* handler because GTK dispatches events in their order of registration.
+	*/
+	OS.g_signal_connect (scrolledWindow, OS.button_press_event, Proc3.getAddress (), STOP_PROPOGATE);
+	OS.g_signal_connect (scrolledWindow, OS.button_release_event, Proc3.getAddress (), STOP_PROPOGATE);
+	OS.g_signal_connect (scrolledWindow, OS.key_press_event, Proc3.getAddress (), STOP_PROPOGATE);
+	OS.g_signal_connect (scrolledWindow, OS.key_release_event, Proc3.getAddress (), STOP_PROPOGATE);
+	OS.g_signal_connect (scrolledWindow, OS.scroll_event, Proc3.getAddress (), STOP_PROPOGATE);
+	OS.g_signal_connect (scrolledWindow, OS.motion_notify_event, Proc3.getAddress (), STOP_PROPOGATE);
+
+    int /*long*/ settings = WebKitGTK.webkit_web_view_get_settings (webView);
+    OS.g_object_set (settings, WebKitGTK.javascript_can_open_windows_automatically, 1, 0);
+    OS.g_object_set (settings, WebKitGTK.enable_universal_access_from_file_uris, 1, 0);
+
+    Listener 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);
+					break;
+				}
+				case SWT.FocusIn: {
+					OS.gtk_widget_grab_focus (webView);
+					break;
+				}
+				case SWT.Resize: {
+					onResize (event);
+					break;
+				}
+			}
+		}
+	};
+	browser.addListener (SWT.Dispose, listener);
+	browser.addListener (SWT.FocusIn, listener);
+	browser.addListener (SWT.KeyDown, listener);
+	browser.addListener (SWT.Resize, listener);
+
+	/*
+	* Ensure that our Authenticate listener is at the front of the signal
+	* queue by removing the default Authenticate listener, adding ours,
+	* and then re-adding the default listener.
+	*/
+	int /*long*/ session = WebKitGTK.webkit_get_default_session ();
+	int /*long*/ originalAuth = WebKitGTK.soup_session_get_feature (session, WebKitGTK.webkit_soup_auth_dialog_get_type ());
+	WebKitGTK.soup_session_feature_detach (originalAuth, session);
+	OS.g_signal_connect (session, WebKitGTK.authenticate, Proc5.getAddress (), webView);
+	WebKitGTK.soup_session_feature_attach (originalAuth, session);
+
+	/*
+	* Check for proxy values set as documented java properties and update the
+	* session to use 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 || port != -1) {
+		if (!proxyHost.startsWith (PROTOCOL_HTTP)) {
+			proxyHost = PROTOCOL_HTTP + proxyHost;
+		}
+		proxyHost += ":" + port; //$NON-NLS-1$
+		byte[] bytes = Converter.wcsToMbcs (null, proxyHost, true);
+		int /*long*/ uri = WebKitGTK.soup_uri_new (bytes);
+		if (uri != 0) {
+			OS.g_object_set (session, WebKitGTK.SOUP_SESSION_PROXY_URI, uri, 0);
+			WebKitGTK.soup_uri_free (uri);
+		}
+	}
+
+	eventFunction = new BrowserFunction (browser, "HandleWebKitEvent") { //$NON-NLS-1$
+		public Object function(Object[] arguments) {
+			return handleEvent (arguments) ? Boolean.TRUE : Boolean.FALSE;
+		};	
+	};
+
+	/*
+	* Bug in WebKitGTK.  MouseOver/MouseLeave events are not consistently sent from
+	* the DOM when the mouse enters and exits the browser control, see
+	* https://bugs.webkit.org/show_bug.cgi?id=35246.  As a workaround for sending
+	* MouseEnter/MouseExit events, swt's default mouse enter/exit mechanism is used,
+	* but in order to do this the Browser's default sub-window check behavior must
+	* be changed.
+	*/
+	browser.setData (KEY_CHECK_SUBWINDOW, Boolean.FALSE);
+
+	return true;
+}
+
+void addEventHandlers (boolean top) {
+	if (top) {
+		StringBuffer buffer = new StringBuffer ("window.SWTkeyhandler = function SWTkeyhandler(e) {"); //$NON-NLS-1$
+		buffer.append ("try {e.returnValue = HandleWebKitEvent(e.type, e.keyCode, e.charCode, e.altKey, e.ctrlKey, e.shiftKey, e.metaKey);} catch (e) {}};"); //$NON-NLS-1$
+		buffer.append ("document.addEventListener('keydown', SWTkeyhandler, true);"); //$NON-NLS-1$
+		buffer.append ("document.addEventListener('keypress', SWTkeyhandler, true);"); //$NON-NLS-1$
+		buffer.append ("document.addEventListener('keyup', SWTkeyhandler, true);"); //$NON-NLS-1$
+		execute (buffer.toString ());
+
+		buffer = new StringBuffer ("window.SWTmousehandler = function SWTmousehandler(e) {"); //$NON-NLS-1$
+		buffer.append ("try {e.returnValue = HandleWebKitEvent(e.type, e.screenX, e.screenY, e.detail, e.button + 1, e.altKey, e.ctrlKey, e.shiftKey, e.metaKey, e.relatedTarget != null);} catch (e) {}};"); //$NON-NLS-1$
+		buffer.append ("document.addEventListener('mousedown', SWTmousehandler, true);"); //$NON-NLS-1$
+		buffer.append ("document.addEventListener('mouseup', SWTmousehandler, true);"); //$NON-NLS-1$
+		buffer.append ("document.addEventListener('mousemove', SWTmousehandler, true);"); //$NON-NLS-1$
+		buffer.append ("document.addEventListener('mousewheel', SWTmousehandler, true);"); //$NON-NLS-1$
+		buffer.append ("document.addEventListener('dragstart', SWTmousehandler, true);"); //$NON-NLS-1$
+
+		/*
+		* The following two lines are intentionally commented because they cannot be used to
+		* consistently send MouseEnter/MouseExit events until https://bugs.webkit.org/show_bug.cgi?id=35246
+		* is fixed.
+		*/ 
+		//buffer.append ("document.addEventListener('mouseover', SWTmousehandler, true);"); //$NON-NLS-1$
+		//buffer.append ("document.addEventListener('mouseout', SWTmousehandler, true);"); //$NON-NLS-1$
+
+		execute (buffer.toString ());
+	} else {
+		StringBuffer buffer = new StringBuffer ("for (var i = 0; i < frames.length; i++) {"); //$NON-NLS-1$
+		buffer.append ("frames[i].document.addEventListener('keydown', window.SWTkeyhandler, true);"); //$NON-NLS-1$
+		buffer.append ("frames[i].document.addEventListener('keypress', window.SWTkeyhandler, true);"); //$NON-NLS-1$
+		buffer.append ("frames[i].document.addEventListener('keyup', window.SWTkeyhandler, true);"); //$NON-NLS-1$
+		buffer.append ("frames[i].document.addEventListener('mousedown', window.SWTmousehandler, true);"); //$NON-NLS-1$
+		buffer.append ("frames[i].document.addEventListener('mouseup', window.SWTmousehandler, true);"); //$NON-NLS-1$
+		buffer.append ("frames[i].document.addEventListener('mousemove', window.SWTmousehandler, true);"); //$NON-NLS-1$
+		buffer.append ("frames[i].document.addEventListener('mouseover', window.SWTmousehandler, true);"); //$NON-NLS-1$
+		buffer.append ("frames[i].document.addEventListener('mouseout', window.SWTmousehandler, true);"); //$NON-NLS-1$
+		buffer.append ("frames[i].document.addEventListener('mousewheel', window.SWTmousehandler, true);"); //$NON-NLS-1$
+		buffer.append ("frames[i].document.addEventListener('dragstart', window.SWTmousehandler, true);"); //$NON-NLS-1$
+		buffer.append ('}');
+		execute (buffer.toString ());
+	}
+}
+
+public boolean back () {
+	if (WebKitGTK.webkit_web_view_can_go_back (webView) == 0) return false;
+	WebKitGTK.webkit_web_view_go_back (webView);
+	return true;
+}
+
+public boolean close () {
+	return close (true);
+}
+
+boolean close (boolean showPrompters) {
+	if (!jsEnabled) return true;
+
+	String message1 = Compatibility.getMessage("SWT_OnBeforeUnload_Message1"); // $NON-NLS-1$
+	String message2 = Compatibility.getMessage("SWT_OnBeforeUnload_Message2"); // $NON-NLS-1$
+	String functionName = EXECUTE_ID + "CLOSE"; // $NON-NLS-1$
+	StringBuffer buffer = new StringBuffer ("function "); // $NON-NLS-1$
+	buffer.append (functionName);
+	buffer.append ("(win) {\n"); // $NON-NLS-1$
+	buffer.append ("var fn = win.onbeforeunload; if (fn != null) {try {var str = fn(); "); // $NON-NLS-1$
+	if (showPrompters) {
+		buffer.append ("if (str != null) { "); // $NON-NLS-1$
+		buffer.append ("var result = confirm('"); // $NON-NLS-1$
+		buffer.append (message1);
+		buffer.append ("\\n\\n'+str+'\\n\\n"); // $NON-NLS-1$
+		buffer.append (message2);
+		buffer.append ("');"); // $NON-NLS-1$
+		buffer.append ("if (!result) return false;}"); // $NON-NLS-1$
+	}	
+	buffer.append ("} catch (e) {}}"); // $NON-NLS-1$
+	buffer.append ("try {for (var i = 0; i < win.frames.length; i++) {var result = "); // $NON-NLS-1$
+	buffer.append (functionName);
+	buffer.append ("(win.frames[i]); if (!result) return false;}} catch (e) {} return true;"); // $NON-NLS-1$
+	buffer.append ("\n};"); // $NON-NLS-1$
+	execute (buffer.toString ());
+
+	Boolean result = (Boolean)evaluate ("return " + functionName +"(window);"); // $NON-NLS-1$ // $NON-NLS-2$
+	if (result == null) return false;
+	return result.booleanValue ();
+}
+
+public boolean execute (String script) {
+	int /*long*/ frame = WebKitGTK.webkit_web_view_get_main_frame (webView);
+	int /*long*/ context = WebKitGTK.webkit_web_frame_get_global_context (frame);
+
+	byte[] bytes = null;
+	try {
+		bytes = (script + '\0').getBytes (CHARSET_UTF8); //$NON-NLS-1$
+	} catch (UnsupportedEncodingException e) {
+		bytes = Converter.wcsToMbcs (null, script, true);
+	}
+	int /*long*/ scriptString = WebKitGTK.JSStringCreateWithUTF8CString (bytes);
+
+	try {
+		bytes = (getUrl () + '\0').getBytes (CHARSET_UTF8); //$NON-NLS-1$
+	} catch (UnsupportedEncodingException e) {
+		bytes = Converter.wcsToMbcs (null, getUrl (), true);
+	}
+	int /*long*/ urlString = WebKitGTK.JSStringCreateWithUTF8CString (bytes);
+
+	int /*long*/ result = WebKitGTK.JSEvaluateScript (context, scriptString, 0, urlString, 0, null);
+	WebKitGTK.JSStringRelease (urlString);
+	WebKitGTK.JSStringRelease (scriptString);
+	return result != 0;
+}
+
+public boolean forward () {
+	if (WebKitGTK.webkit_web_view_can_go_forward (webView) == 0) return false;
+	WebKitGTK.webkit_web_view_go_forward (webView);
+	return true;
+}
+
+public String getBrowserType () {
+	return "webkit"; //$NON-NLS-1$
+}
+
+public String getText () {
+	int /*long*/ frame = WebKitGTK.webkit_web_view_get_main_frame (webView);
+	int /*long*/ source = WebKitGTK.webkit_web_frame_get_data_source (frame);
+	if (source == 0) return "";	//$NON-NLS-1$
+	int /*long*/ data = WebKitGTK.webkit_web_data_source_get_data (source);
+	if (data == 0) return "";	//$NON-NLS-1$
+
+	int /*long*/ encoding = WebKitGTK.webkit_web_data_source_get_encoding (source);
+	int length = OS.strlen (encoding);
+	byte[] bytes = new byte [length];
+	OS.memmove (bytes, encoding, length);
+	String encodingString = new String (Converter.mbcsToWcs (null, bytes));
+
+	int /*long*/ string = OS.GString_str (data);
+	length = OS.GString_len (string);
+	bytes = new byte[length];
+	C.memmove (bytes, string, length);
+
+	try {
+		return new String (bytes, encodingString);
+	} catch (UnsupportedEncodingException e) {
+	}
+	return new String (Converter.mbcsToWcs (null, bytes));
+}
+
+public String getUrl () {
+	int /*long*/ uri = WebKitGTK.webkit_web_view_get_uri (webView);
+
+	/* WebKit auto-navigates to about:blank at startup */
+	if (uri == 0) return ABOUT_BLANK;
+
+	int length = OS.strlen (uri);
+	byte[] bytes = new byte[length];
+	OS.memmove (bytes, uri, length);
+
+	String url = new String (Converter.mbcsToWcs (null, bytes));
+	/*
+	 * 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 (url.equals (URI_FILEROOT)) {
+		url = ABOUT_BLANK;
+	} else {
+		length = URI_FILEROOT.length ();
+		if (url.startsWith (URI_FILEROOT) && url.charAt (length) == '#') {
+			url = ABOUT_BLANK + url.substring (length);
+		}
+	}
+	return url;
+}
+
+boolean handleEvent (Object[] arguments) {
+
+	/*
+	* DOM events are currently received by hooking DOM listeners
+	* in javascript that invoke this method via a BrowserFunction.
+	* It should be possible to replace this mechanism with more
+	* typical callbacks from C once WebKitGTK enhancement request
+	* https://bugs.webkit.org/show_bug.cgi?id=33590 is completed.
+	* In the meantime, the argument lists received here are:
+	* 
+	* For key events:
+	* 	argument 0: type (String)
+	* 	argument 1: keyCode (Double)
+	* 	argument 2: charCode (Double)
+	* 	argument 3: altKey (Boolean)
+	* 	argument 4: ctrlKey (Boolean)
+	* 	argument 5: shiftKey (Boolean)
+	* 	argument 6: metaKey (Boolean)
+	* 	returns doit
+	* 
+	* For mouse events
+	* 	argument 0: type (String)
+	* 	argument 1: screenX (Double)
+	* 	argument 2: screenY (Double)
+	* 	argument 3: detail (Double)
+	* 	argument 4: button (Double)
+	* 	argument 5: altKey (Boolean)
+	* 	argument 6: ctrlKey (Boolean)
+	* 	argument 7: shiftKey (Boolean)
+	* 	argument 8: metaKey (Boolean)
+	* 	argument 9: hasRelatedTarget (Boolean)
+	* 	returns doit
+	*/
+
+	String type = (String)arguments[0];
+	if (type.equals (DOMEVENT_KEYDOWN)) {
+		int keyCode = translateKey (((Double)arguments[1]).intValue ());
+		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:
+			case SWT.ESC:
+			case SWT.TAB:
+			case SWT.PAUSE:
+			case SWT.BS:
+			case SWT.INSERT:
+			case SWT.DEL:
+			case SWT.HOME:
+			case SWT.END:
+			case SWT.PAGE_UP:
+			case SWT.PAGE_DOWN:
+			case SWT.ARROW_DOWN:
+			case SWT.ARROW_UP:
+			case SWT.ARROW_LEFT:
+			case SWT.ARROW_RIGHT:
+			case SWT.F1:
+			case SWT.F2:
+			case SWT.F3:
+			case SWT.F4:
+			case SWT.F5:
+			case SWT.F6:
+			case SWT.F7:
+			case SWT.F8:
+			case SWT.F9:
+			case SWT.F10:
+			case SWT.F11:
+			case SWT.F12: {
+				/* keypress events will not be received for these keys, so send KeyDowns for them now */
+
+				Event keyEvent = new Event ();
+				keyEvent.widget = browser;
+				keyEvent.type = type.equals (DOMEVENT_KEYDOWN) ? SWT.KeyDown : SWT.KeyUp;
+				keyEvent.keyCode = keyCode;
+				switch (keyCode) {
+					case SWT.BS: keyEvent.character = SWT.BS; break;
+					case SWT.DEL: keyEvent.character = SWT.DEL; break;
+					case SWT.ESC: keyEvent.character = SWT.ESC; break;
+					case SWT.TAB: keyEvent.character = SWT.TAB; break;
+				}
+				lastCharCode = keyEvent.character;
+				keyEvent.stateMask =
+					(((Boolean)arguments[3]).booleanValue () ? SWT.ALT : 0) |
+					(((Boolean)arguments[4]).booleanValue () ? SWT.CTRL : 0) |
+					(((Boolean)arguments[5]).booleanValue () ? SWT.SHIFT : 0) |
+					(((Boolean)arguments[6]).booleanValue () ? SWT.COMMAND : 0);
+				keyEvent.stateMask &= ~keyCode;		/* remove current keydown if it's a state key */
+				final int stateMask = keyEvent.stateMask;
+				if (!sendKeyEvent (keyEvent) || browser.isDisposed ()) return false;
+
+				if (browser.isFocusControl ()) {
+					if (keyCode == SWT.TAB && (stateMask & (SWT.CTRL | SWT.ALT)) == 0) {
+						browser.getDisplay ().asyncExec (new Runnable () {
+							public void run () {
+								if (browser.isDisposed ()) return;
+								if (browser.getDisplay ().getFocusControl () == null) {
+									int traversal = (stateMask & SWT.SHIFT) != 0 ? SWT.TRAVERSE_TAB_PREVIOUS : SWT.TRAVERSE_TAB_NEXT;
+									browser.traverse (traversal);
+								}
+							}
+						});
+					}
+				}
+				break;
+			}
+		}
+		return true;
+	}
+
+	if (type.equals (DOMEVENT_KEYPRESS)) {
+		/*
+		* 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 true;
+
+		lastCharCode = ((Double)arguments[2]).intValue ();
+		if (((Boolean)arguments[4]).booleanValue () && (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 =
+			(((Boolean)arguments[3]).booleanValue () ? SWT.ALT : 0) |
+			(((Boolean)arguments[4]).booleanValue () ? SWT.CTRL : 0) |
+			(((Boolean)arguments[5]).booleanValue () ? SWT.SHIFT : 0) |
+			(((Boolean)arguments[6]).booleanValue () ? SWT.COMMAND : 0);
+		return sendKeyEvent (keyEvent) && !browser.isDisposed ();
+	}
+
+	if (type.equals(DOMEVENT_KEYUP)) {
+		int keyCode = translateKey (((Double)arguments[1]).intValue ());
+		if (keyCode == 0) {
+			/* indicates a key for which key events are not sent */
+			return true;
+		}
+		if (keyCode != lastKeyCode) {
+			/* keyup does not correspond to the last keydown */
+			lastKeyCode = keyCode;
+			lastCharCode = 0;
+		}
+
+		Event keyEvent = new Event ();
+		keyEvent.widget = browser;
+		keyEvent.type = SWT.KeyUp;
+		keyEvent.keyCode = lastKeyCode;
+		keyEvent.character = (char)lastCharCode;
+		keyEvent.stateMask =
+			(((Boolean)arguments[3]).booleanValue () ? SWT.ALT : 0) |
+			(((Boolean)arguments[4]).booleanValue () ? SWT.CTRL : 0) |
+			(((Boolean)arguments[5]).booleanValue () ? SWT.SHIFT : 0) |
+			(((Boolean)arguments[6]).booleanValue () ? 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);
+		lastKeyCode = lastCharCode = 0;
+		return keyEvent.doit && !browser.isDisposed ();
+	}
+
+	/* mouse events */
+
+	/*
+	 * 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 there is a related target element.
+	 */
+
+	/*
+	* The following is intentionally commented because MouseOver and MouseOut events
+	* are not being hooked until https://bugs.webkit.org/show_bug.cgi?id=35246 is fixed.
+	*/ 
+	//if (type.equals (DOMEVENT_MOUSEOVER) || type.equals (DOMEVENT_MOUSEOUT)) {
+	//	if (((Boolean)arguments[9]).booleanValue ()) return true;
+	//}
+
+	/*
+	 * The position of mouse events is received in screen-relative coordinates
+	 * in order to handle pages with frames, since frames express their event
+	 * coordinates relative to themselves rather than relative to their top-
+	 * level page.  Convert screen-relative coordinates to be browser-relative.
+	 */
+	Point position = new Point (((Double)arguments[1]).intValue (), ((Double)arguments[2]).intValue ());
+	position = browser.getDisplay ().map (null, browser, position); 
+
+	Event mouseEvent = new Event ();
+	mouseEvent.widget = browser;
+	mouseEvent.x = position.x;
+	mouseEvent.y = position.y;
+	int mask =
+		(((Boolean)arguments[5]).booleanValue () ? SWT.ALT : 0) |
+		(((Boolean)arguments[6]).booleanValue () ? SWT.CTRL : 0) |
+		(((Boolean)arguments[7]).booleanValue () ? SWT.SHIFT : 0) |
+		(((Boolean)arguments[8]).booleanValue () ? SWT.COMMAND : 0);
+	mouseEvent.stateMask = mask;
+
+	if (type.equals (DOMEVENT_MOUSEDOWN)) {
+		mouseEvent.type = SWT.MouseDown;
+		mouseEvent.count = ((Double)arguments[3]).intValue ();
+		mouseEvent.button = ((Double)arguments[4]).intValue ();
+		browser.notifyListeners (mouseEvent.type, mouseEvent);
+		if (browser.isDisposed ()) return true;
+		if (((Double)arguments[3]).intValue () == 2) {
+			mouseEvent = new Event ();
+			mouseEvent.type = SWT.MouseDoubleClick;
+			mouseEvent.widget = browser;
+			mouseEvent.x = position.x;
+			mouseEvent.y = position.y;
+			mouseEvent.stateMask = mask;
+			mouseEvent.count = ((Double)arguments[3]).intValue ();
+			mouseEvent.button = ((Double)arguments[4]).intValue ();
+			browser.notifyListeners (mouseEvent.type, mouseEvent);
+		}
+		return true;
+	}
+
+	if (type.equals (DOMEVENT_MOUSEUP)) {
+		mouseEvent.type = SWT.MouseUp;
+		mouseEvent.count = ((Double)arguments[3]).intValue ();
+		mouseEvent.button = ((Double)arguments[4]).intValue ();
+	} else if (type.equals (DOMEVENT_MOUSEMOVE)) {
+		mouseEvent.type = SWT.MouseMove;
+	} else if (type.equals (DOMEVENT_MOUSEWHEEL)) {
+		mouseEvent.type = SWT.MouseWheel;
+		mouseEvent.count = ((Double)arguments[3]).intValue ();
+
+	/*
+	* The following is intentionally commented because MouseOver and MouseOut events
+	* are not being hooked until https://bugs.webkit.org/show_bug.cgi?id=35246 is fixed.
+	*/ 
+	//} else if (type.equals (DOMEVENT_MOUSEOVER)) {
+	//	mouseEvent.type = SWT.MouseEnter;
+	//} else if (type.equals (DOMEVENT_MOUSEOUT)) {
+	//	mouseEvent.type = SWT.MouseExit;
+
+	} else if (type.equals (DOMEVENT_DRAGSTART)) {
+		mouseEvent.type = SWT.DragDetect;
+		mouseEvent.button = ((Double)arguments[4]).intValue () + 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);
+		/*
+		* Bug in WebKitGTK.  Dragging an image quickly and repeatedly can cause
+		* WebKitGTK to take the mouse grab indefinitely and lock up the display,
+		* see https://bugs.webkit.org/show_bug.cgi?id=32840.  The workaround is
+		* to veto all drag attempts.
+		*/
+		return false;
+	}
+
+	browser.notifyListeners (mouseEvent.type, mouseEvent);
+	return true;
+}
+
+int /*long*/ handleLoadCommitted (int /*long*/ uri, boolean top) {
+	int length = OS.strlen (uri);
+	byte[] bytes = new byte[length];
+	OS.memmove (bytes, uri, length);
+	String url = new String (Converter.mbcsToWcs (null, bytes));
+	/*
+	 * 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 (url.equals (URI_FILEROOT)) {
+		url = ABOUT_BLANK;
+	} else {
+		length = URI_FILEROOT.length ();
+		if (url.startsWith (URI_FILEROOT) && url.charAt (length) == '#') {
+			url = ABOUT_BLANK + url.substring (length);
+		}
+	}
+
+	/*
+	* Each invocation of setText() causes webkit_notify_load_status to be invoked
+	* twice, once for the initial navigate to about:blank, and once for the auto-navigate
+	* to about:blank that WebKit does when webkit_web_view_load_string is invoked.  If
+	* this is the first webkit_notify_load_status callback received for a setText()
+	* invocation then do not send any events or re-install registered BrowserFunctions. 
+	*/
+	if (top && url.startsWith(ABOUT_BLANK) && htmlBytes != null) return 0;
+
+	LocationEvent event = new LocationEvent (browser);
+	event.display = browser.getDisplay ();
+	event.widget = browser;
+	event.location = url;
+	event.top = top;
+	for (int i = 0; i < locationListeners.length; i++) {
+		locationListeners[i].changed (event);
+	}
+	return 0;
+}
+
+int /*long*/ handleLoadFinished (int /*long*/ uri, boolean top) {
+	int length = OS.strlen (uri);
+	byte[] bytes = new byte[length];
+	OS.memmove (bytes, uri, length);
+	String url = new String (Converter.mbcsToWcs (null, bytes));
+	/*
+	 * 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 (url.equals (URI_FILEROOT)) {
+		url = ABOUT_BLANK;
+	} else {
+		length = URI_FILEROOT.length ();
+		if (url.startsWith (URI_FILEROOT) && url.charAt (length) == '#') {
+			url = ABOUT_BLANK + url.substring (length);
+		}
+	}
+
+	/*
+	 * 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 (top && htmlBytes != null) {
+		if (url.startsWith(ABOUT_BLANK)) {
+			loadingText = true;
+			byte[] mimeType = Converter.wcsToMbcs (null, "text/html", true);  //$NON-NLS-1$
+			byte[] encoding = Converter.wcsToMbcs (null, CHARSET_UTF8, true);  //$NON-NLS-1$
+			byte[] uriBytes;
+			if (untrustedText) {
+				uriBytes = Converter.wcsToMbcs (null, ABOUT_BLANK, true);
+			} else {
+				uriBytes = Converter.wcsToMbcs (null, URI_FILEROOT, true);
+			}
+			WebKitGTK.webkit_web_view_load_string (webView, htmlBytes, mimeType, encoding, uriBytes);
+			htmlBytes = null;
+		}
+	}
+
+	/*
+	* The webkit_web_view_load_string() invocation above will trigger a second
+	* webkit_web_view_load_string callback when it is completed.  Wait for this
+	* second callback to come before sending the title or completed events.
+	*/
+	if (!loadingText) {
+		/*
+		* To be consistent with other platforms a title event should be fired
+		* when a top-level page has completed loading.  A page with a <title>
+		* tag will do this automatically when the notify::title signal is received.
+		* However a page without a <title> tag will not do this by default, so fire
+		* the event here with the page's url as the title.
+		*/
+		if (top) {
+			int /*long*/ frame = WebKitGTK.webkit_web_view_get_main_frame (webView);
+			int /*long*/ title = WebKitGTK.webkit_web_frame_get_title (frame);
+			if (title == 0) {
+				TitleEvent newEvent = new TitleEvent (browser);
+				newEvent.display = browser.getDisplay ();
+				newEvent.widget = browser;
+				newEvent.title = url;
+				for (int i = 0; i < titleListeners.length; i++) {
+					titleListeners[i].changed (newEvent);
+				}
+				if (browser.isDisposed ()) return 0;
+			}
+		}
+
+		ProgressEvent progress = new ProgressEvent (browser);
+		progress.display = browser.getDisplay ();
+		progress.widget = browser;
+		progress.current = MAX_PROGRESS;
+		progress.total = MAX_PROGRESS;
+		for (int i = 0; i < progressListeners.length; i++) {
+			progressListeners[i].completed (progress);
+		}
+	}
+	loadingText = false;
+
+	return 0;
+}
+
+public boolean isBackEnabled () {
+	return WebKitGTK.webkit_web_view_can_go_back (webView) != 0;
+}
+
+public boolean isForwardEnabled () {
+	return WebKitGTK.webkit_web_view_can_go_forward (webView) != 0;
+}
+
+void onDispose (Event e) {
+	/* Browser could have been disposed by one of the Dispose listeners */
+	if (!browser.isDisposed()) {
+		/* invoke onbeforeunload handlers */
+		if (!browser.isClosing) {
+			close (false);
+		}
+	}
+
+	Enumeration elements = functions.elements ();
+	while (elements.hasMoreElements ()) {
+		((BrowserFunction)elements.nextElement ()).dispose (false);
+	}
+	functions = null;
+
+	C.free (webViewData);
+	postData = null;
+	headers = null;
+	htmlBytes = null;
+}
+
+void onResize (Event e) {
+	Rectangle rect = browser.getClientArea ();
+	OS.gtk_widget_set_size_request (scrolledWindow, rect.width, rect.height);
+}
+
+void openDownloadWindow (final int /*long*/ webkitDownload) {
+	final Shell shell = new Shell ();
+	String msg = Compatibility.getMessage ("SWT_FileDownload"); //$NON-NLS-1$
+	shell.setText (msg);
+	GridLayout gridLayout = new GridLayout ();
+	gridLayout.marginHeight = 15;
+	gridLayout.marginWidth = 15;
+	gridLayout.verticalSpacing = 20;
+	shell.setLayout (gridLayout);
+
+	int /*long*/ name = WebKitGTK.webkit_download_get_suggested_filename (webkitDownload);
+	int length = OS.strlen (name);
+	byte[] bytes = new byte[length];
+	OS.memmove (bytes, name, length);
+	String nameString = new String (Converter.mbcsToWcs (null, bytes));
+	int /*long*/ url = WebKitGTK.webkit_download_get_uri (webkitDownload);
+	length = OS.strlen (url);
+	bytes = new byte[length];
+	OS.memmove (bytes, url, length);
+	String urlString = new String (Converter.mbcsToWcs (null, bytes));
+	msg = Compatibility.getMessage ("SWT_Download_Location", new Object[] {nameString, urlString}); //$NON-NLS-1$
+	Label nameLabel = new Label (shell, SWT.WRAP);
+	nameLabel.setText (msg);
+	GridData data = new GridData ();
+	Monitor monitor = browser.getMonitor ();
+	int maxWidth = monitor.getBounds ().width / 2;
+	int width = nameLabel.computeSize (SWT.DEFAULT, SWT.DEFAULT).x;
+	data.widthHint = Math.min (width, maxWidth);
+	data.horizontalAlignment = GridData.FILL;
+	data.grabExcessHorizontalSpace = true;
+	nameLabel.setLayoutData (data);
+
+	final Label statusLabel = new Label (shell, SWT.NONE);
+	statusLabel.setText (Compatibility.getMessage ("SWT_Download_Started")); //$NON-NLS-1$
+	data = new GridData (GridData.FILL_BOTH);
+	statusLabel.setLayoutData (data);
+
+	final Button cancel = new Button (shell, SWT.PUSH);
+	cancel.setText (Compatibility.getMessage ("SWT_Cancel")); //$NON-NLS-1$
+	data = new GridData ();
+	data.horizontalAlignment = GridData.CENTER;
+	cancel.setLayoutData (data);
+	final Listener cancelListener = new Listener () {
+		public void handleEvent (Event event) {
+			WebKitGTK.webkit_download_cancel (webkitDownload);
+		}
+	};
+	cancel.addListener (SWT.Selection, cancelListener);
+
+	OS.g_object_ref (webkitDownload);
+	final Display display = browser.getDisplay ();
+	final int INTERVAL = 500;
+	display.timerExec (INTERVAL, new Runnable () {
+		public void run () {
+			int status = WebKitGTK.webkit_download_get_status (webkitDownload);
+			if (shell.isDisposed () || status == WebKitGTK.WEBKIT_DOWNLOAD_STATUS_FINISHED || status == WebKitGTK.WEBKIT_DOWNLOAD_STATUS_CANCELLED) {
+				shell.dispose ();
+				display.timerExec (-1, this);
+				OS.g_object_unref (webkitDownload);
+				return;
+			}
+			if (status == WebKitGTK.WEBKIT_DOWNLOAD_STATUS_ERROR) {
+				statusLabel.setText (Compatibility.getMessage ("SWT_Download_Error")); //$NON-NLS-1$
+				display.timerExec (-1, this);
+				OS.g_object_unref (webkitDownload);
+				cancel.removeListener (SWT.Selection, cancelListener);
+				cancel.addListener (SWT.Selection, new Listener () {
+					public void handleEvent (Event event) {
+						shell.dispose ();
+					}
+				});
+				return;
+			}
+
+			long current = WebKitGTK.webkit_download_get_current_size (webkitDownload) / 1024L;
+			long total = WebKitGTK.webkit_download_get_total_size (webkitDownload) / 1024L;
+			String message = Compatibility.getMessage ("SWT_Download_Status", new Object[] {new Long(current), new Long(total)}); //$NON-NLS-1$
+			statusLabel.setText (message);
+			display.timerExec (INTERVAL, this);
+		}
+	});
+
+	shell.pack ();
+	shell.open ();
+}
+
+public void refresh () {
+	WebKitGTK.webkit_web_view_reload (webView);
+}
+
+public boolean setText (String html, boolean trusted) {
+	/* convert the String containing HTML to an array of bytes with UTF-8 data */
+	byte[] bytes = null;
+	try {
+		bytes = (html + '\0').getBytes (CHARSET_UTF8); //$NON-NLS-1$
+	} catch (UnsupportedEncodingException e) {
+		bytes = Converter.wcsToMbcs (null, html, true);
+	}
+
+	/*
+	* If this.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 = bytes;
+	untrustedText = !trusted;
+	if (blankLoading) return true;
+
+	byte[] uriBytes = Converter.wcsToMbcs (null, ABOUT_BLANK, true);
+	WebKitGTK.webkit_web_view_load_uri (webView, uriBytes);
+	return true;
+}
+
+public boolean setUrl (String url, String postData, String[] headers) {
+	this.postData = postData;
+	this.headers = headers;
+
+	/*
+	* WebKitGTK attempts to open the exact url string that is passed to it and
+	* will not infer a protocol if it's not specified.  Detect the case of an
+	* invalid URL string and try to fix it by prepending an appropriate protocol.
+	*/
+	try {
+		new URL(url);
+	} catch (MalformedURLException e) {
+		String testUrl = null;
+		if (url.charAt (0) == SEPARATOR_FILE) {
+			/* appears to be a local file */
+			testUrl = PROTOCOL_FILE + url; 
+		} else {
+			testUrl = PROTOCOL_HTTP + url;
+		}
+		try {
+			new URL (testUrl);
+			url = testUrl;		/* adding the protocol made the url valid */
+		} catch (MalformedURLException e2) {
+			/* adding the protocol did not make the url valid, so do nothing */
+		}
+	}
+
+	/*
+	* Feature of WebKit.  The user-agent header value cannot be overridden
+	* by changing it in the resource request.  The workaround is to detect
+	* here whether the user-agent is being overridden, and if so, temporarily
+	* set the value on the WebView when initiating the load request and then
+	* remove it afterwards.
+	*/
+	int /*long*/ settings = WebKitGTK.webkit_web_view_get_settings (webView);
+	if (headers != null) {
+		for (int i = 0; i < headers.length; i++) {
+			String current = headers[i];
+			if (current != null) {
+				int index = current.indexOf (':');
+				if (index != -1) {
+					String key = current.substring (0, index).trim ();
+					String value = current.substring (index + 1).trim ();
+					if (key.length () > 0 && value.length () > 0) {
+						if (key.equalsIgnoreCase (USER_AGENT)) {
+							byte[] bytes = Converter.wcsToMbcs (null, value, true);
+							OS.g_object_set (settings, WebKitGTK.user_agent, bytes, 0);
+						}
+					}
+				}
+			}
+		}
+	}
+	byte[] uriBytes = Converter.wcsToMbcs (null, url, true);
+	WebKitGTK.webkit_web_view_load_uri (webView, uriBytes);
+	OS.g_object_set (settings, WebKitGTK.user_agent, 0, 0);
+	return true;
+}
+
+public void stop () {
+	WebKitGTK.webkit_web_view_stop_loading (webView);
+}
+
+int /*long*/ webframe_notify_load_status (int /*long*/ web_frame, int /*long*/ pspec) {
+	int status = WebKitGTK.webkit_web_frame_get_load_status (web_frame);
+	switch (status) {
+		case WebKitGTK.WEBKIT_LOAD_COMMITTED: {
+			int /*long*/ uri = WebKitGTK.webkit_web_frame_get_uri (web_frame);
+			return handleLoadCommitted (uri, false);
+		}
+		case WebKitGTK.WEBKIT_LOAD_FINISHED: {
+			/*
+			* If this frame navigation was isolated to this frame (eg.- a link was
+			* clicked in the frame, as opposed to this frame being created in
+			* response to navigating to a main document containing frames) then
+			* treat this as a completed load.
+			*/
+			int /*long*/ parentFrame = WebKitGTK.webkit_web_frame_get_parent (web_frame);
+			if (WebKitGTK.webkit_web_frame_get_load_status (parentFrame) == WebKitGTK.WEBKIT_LOAD_FINISHED) {
+				int /*long*/ uri = WebKitGTK.webkit_web_frame_get_uri (web_frame);
+				return handleLoadFinished (uri, false);
+			}
+		}
+	}
+	return 0;
+}
+
+int /*long*/ webkit_close_web_view (int /*long*/ web_view) {
+	WindowEvent newEvent = new WindowEvent (browser);
+	newEvent.display = browser.getDisplay ();
+	newEvent.widget = browser;
+	for (int i = 0; i < closeWindowListeners.length; i++) {
+		closeWindowListeners[i].close (newEvent);
+	}
+	browser.dispose ();
+	return 0;
+}
+
+int /*long*/ webkit_console_message (int /*long*/ web_view, int /*long*/ message, int /*long*/ line, int /*long*/ source_id) {
+	return 1;	/* stop the message from being written to stderr */
+}
+
+int /*long*/ webkit_create_web_view (int /*long*/ web_view, int /*long*/ frame) {
+	WindowEvent newEvent = new WindowEvent (browser);
+	newEvent.display = browser.getDisplay ();
+	newEvent.widget = browser;
+	newEvent.required = true;
+	if (openWindowListeners != null) {
+		for (int i = 0; i < openWindowListeners.length; i++) {
+			openWindowListeners[i].open (newEvent);
+		}
+	}
+	Browser browser = null;
+	if (newEvent.browser != null && newEvent.browser.webBrowser instanceof WebKit) {
+		browser = newEvent.browser;
+	}
+	if (browser != null && !browser.isDisposed ()) {
+		return ((WebKit)browser.webBrowser).webView;
+	}
+	return 0;
+}
+
+int /*long*/ webkit_download_requested (int /*long*/ web_view, int /*long*/ download) {
+	int /*long*/ name = WebKitGTK.webkit_download_get_suggested_filename (download);
+	int length = OS.strlen (name);
+	byte[] bytes = new byte[length];
+	OS.memmove (bytes, name, length);
+	String nameString = new String (Converter.mbcsToWcs (null, bytes));
+	FileDialog dialog = new FileDialog (browser.getShell (), SWT.OPEN);
+	dialog.setFileName (nameString);
+	String title = Compatibility.getMessage ("SWT_FileDownload"); //$NON-NLS-1$
+	dialog.setText (title);
+	String path = dialog.open ();
+
+	if (path != null) {
+		path = URI_FILEROOT + path;
+		byte[] uriBytes = Converter.wcsToMbcs (null, path, true);
+		WebKitGTK.webkit_download_set_destination_uri (download, uriBytes);
+		openDownloadWindow (download);
+	} else {
+		WebKitGTK.webkit_download_cancel (download);
+	}
+	return 1;
+}
+
+int /*long*/ webkit_hovering_over_link (int /*long*/ web_view, int /*long*/ title, int /*long*/ uri) {
+	if (uri != 0) {
+		int length = OS.strlen (uri);
+		byte[] bytes = new byte[length];
+		OS.memmove (bytes, uri, length);
+		String text = new String (Converter.mbcsToWcs (null, bytes));
+		StatusTextEvent event = new StatusTextEvent (browser);
+		event.display = browser.getDisplay ();
+		event.widget = browser;
+		event.text = text;
+		for (int i = 0; i < statusTextListeners.length; i++) {
+			statusTextListeners[i].changed (event);
+		}
+	}
+	return 0;
+}
+
+int /*long*/ webkit_mime_type_policy_decision_requested (int /*long*/ web_view, int /*long*/ frame, int /*long*/ request, int /*long*/ mimetype, int /*long*/ policy_decision) {
+	boolean canShow = WebKitGTK.webkit_web_view_can_show_mime_type (webView, mimetype) != 0;
+	if (!canShow) {
+		WebKitGTK.webkit_web_policy_decision_download (policy_decision);
+		return 1;
+	}
+	return 0;
+}
+
+int /*long*/ webkit_navigation_policy_decision_requested (int /*long*/ web_view, int /*long*/ frame, int /*long*/ request, int /*long*/ navigation_action, int /*long*/ policy_decision) {
+	if (loadingText) {
+		/* 
+		 * WebKit is auto-navigating to about:blank in response to a
+		 * webkit_web_view_load_string() invocation.  This navigate
+		 * should always proceed without sending an event since it is
+		 * preceded by an explicit navigate to about:blank in setText().
+		 */
+		return 0;
+	}
+
+	int /*long*/ uri = WebKitGTK.webkit_network_request_get_uri (request);
+	int length = OS.strlen (uri);
+	byte[] bytes = new byte[length];
+	OS.memmove (bytes, uri, length);
+
+	String url = new String (Converter.mbcsToWcs (null, bytes));
+	/*
+	 * 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 (url.equals (URI_FILEROOT)) {
+		url = ABOUT_BLANK;
+	} else {
+		length = URI_FILEROOT.length ();
+		if (url.startsWith (URI_FILEROOT) && url.charAt (length) == '#') {
+			url = ABOUT_BLANK + url.substring (length);
+		}
+	}
+
+	LocationEvent newEvent = new LocationEvent (browser);
+	newEvent.display = browser.getDisplay ();
+	newEvent.widget = browser;
+	newEvent.location = url;
+	newEvent.doit = true;
+	if (locationListeners != null) {
+		for (int i = 0; i < locationListeners.length; i++) {
+			locationListeners[i].changing (newEvent);
+		}
+	}
+	if (newEvent.doit && !browser.isDisposed ()) {
+		if (jsEnabledChanged) {
+			jsEnabledChanged = false;
+			int /*long*/ settings = WebKitGTK.webkit_web_view_get_settings (webView);
+			OS.g_object_set (settings, WebKitGTK.enable_scripts, jsEnabled ? 1 : 0, 0);
+		}
+
+		/* hook status change signal if frame is a newly-created sub-frame */
+		int /*long*/ mainFrame = WebKitGTK.webkit_web_view_get_main_frame (webView);
+		if (frame != mainFrame) {
+			int id = OS.g_signal_handler_find (frame, OS.G_SIGNAL_MATCH_FUNC | OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, Proc3.getAddress (), NOTIFY_LOAD_STATUS);
+			if (id == 0) {
+				OS.g_signal_connect (frame, WebKitGTK.notify_load_status, Proc3.getAddress (), NOTIFY_LOAD_STATUS);
+			}
+		}
+
+		/*
+		* The following line is intentionally commented.  For some reason, invoking 
+		* webkit_web_policy_decision_use(policy_decision) causes the Flash plug-in
+		* to crash when navigating to a page with Flash.  Since returning from this
+		* callback without invoking webkit_web_policy_decision_ignore(policy_decision)
+		* implies that the page should be loaded, it's fine to not invoke
+		* webkit_web_policy_decision_use(policy_decision) here. 
+		*/
+		//WebKitGTK.webkit_web_policy_decision_use (policy_decision);
+	} else {
+		WebKitGTK.webkit_web_policy_decision_ignore (policy_decision);
+	}
+	return 0;
+}
+
+int /*long*/ webkit_notify_load_status (int /*long*/ web_view, int /*long*/ pspec) {
+	int status = WebKitGTK.webkit_web_view_get_load_status (webView);
+	switch (status) {
+		case WebKitGTK.WEBKIT_LOAD_COMMITTED: {
+			int /*long*/ uri = WebKitGTK.webkit_web_view_get_uri (webView);
+			return handleLoadCommitted (uri, true);
+		}
+		case WebKitGTK.WEBKIT_LOAD_FINISHED: {
+			int /*long*/ uri = WebKitGTK.webkit_web_view_get_uri (webView);
+			return handleLoadFinished (uri, true);
+		}
+	}
+	return 0;
+}
+
+int /*long*/ webkit_notify_progress (int /*long*/ web_view, int /*long*/ pspec) {
+	ProgressEvent event = new ProgressEvent (browser);
+	event.display = browser.getDisplay ();
+	event.widget = browser;
+	event.current = (int)(WebKitGTK.webkit_web_view_get_progress (webView) * MAX_PROGRESS);
+	event.total = MAX_PROGRESS;
+	for (int i = 0; i < progressListeners.length; i++) {
+		progressListeners[i].changed (event);				
+	}
+	return 0;
+}
+
+int /*long*/ webkit_notify_title (int /*long*/ web_view, int /*long*/ pspec) {
+	int /*long*/ title = WebKitGTK.webkit_web_view_get_title (webView);
+	String titleString;
+	if (title == 0) {
+		titleString = ""; //$NON-NLS-1$
+	} else {
+		int length = OS.strlen (title);
+		byte[] bytes = new byte[length];
+		OS.memmove (bytes, title, length);
+		titleString = new String (Converter.mbcsToWcs (null, bytes));
+	}
+	TitleEvent event = new TitleEvent (browser);
+	event.display = browser.getDisplay ();
+	event.widget = browser;
+	event.title = titleString;
+	for (int i = 0; i < titleListeners.length; i++) {
+		titleListeners[i].changed (event);
+	}
+	return 0;
+}
+
+int /*long*/ webkit_populate_popup (int /*long*/ web_view, int /*long*/ webkit_menu) {
+	Point pt = browser.getDisplay ().getCursorLocation ();
+	Event event = new Event ();
+	event.x = pt.x;
+	event.y = pt.y;
+	browser.notifyListeners (SWT.MenuDetect, event);
+	if (!event.doit) {
+		/* clear the menu */
+		int /*long*/ children = OS.gtk_container_get_children (webkit_menu);
+		int /*long*/ current = children;
+		while (current != 0) {
+			int /*long*/ item = OS.g_list_data (current);
+			OS.gtk_container_remove (webkit_menu, item);
+			current = OS.g_list_next (current);
+		}
+		OS.g_list_free (children);
+		return 0;
+	}
+	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);
+		/* clear the menu */
+		int /*long*/ children = OS.gtk_container_get_children (webkit_menu);
+		int /*long*/ current = children;
+		while (current != 0) {
+			int /*long*/ item = OS.g_list_data (current);
+			OS.gtk_container_remove (webkit_menu, item);
+			current = OS.g_list_next (current);
+		}
+		OS.g_list_free (children);
+	}
+	return 0;
+}
+
+int /*long*/ webkit_resource_request_starting (int /*long*/ web_view, int /*long*/ web_frame, int /*long*/ web_resource, int /*long*/ request, int /*long*/ response) {
+	if (postData != null || headers != null) {
+		int /*long*/ message = WebKitGTK.webkit_network_request_get_message (request);
+		if (message == 0) {
+			headers = null;
+			postData = null;
+		} else {
+			if (postData != null) {
+				WebKitGTK.SoupMessage_method (message, PostString);
+				int /*long*/ body = WebKitGTK.SoupMessage_request_body (message);
+				byte[] bytes = Converter.wcsToMbcs (null, postData, false);
+				int /*long*/ data = C.malloc (bytes.length);
+				C.memmove (data, bytes, bytes.length);
+				WebKitGTK.soup_message_body_append (body, WebKitGTK.SOUP_MEMORY_TAKE, data, bytes.length);
+				WebKitGTK.soup_message_body_flatten (body);
+
+				if (headers == null) headers = new String[0];
+				String[] temp = new String[headers.length + 1];
+				System.arraycopy (headers, 0, temp, 0, headers.length);
+				temp[headers.length] = ENCODING_FORM;
+				headers = temp;
+				postData = null;
+			}
+
+			/* headers */
+			int /*long*/ requestHeaders = WebKitGTK.SoupMessage_request_headers (message);
+			for (int i = 0; i < headers.length; i++) {
+				String current = headers[i];
+				if (current != null) {
+					int index = current.indexOf (':');
+					if (index != -1) {
+						String key = current.substring (0, index).trim ();
+						String value = current.substring (index + 1).trim ();
+						if (key.length () > 0 && value.length () > 0) {
+							byte[] nameBytes = Converter.wcsToMbcs (null, key, true);
+							byte[] valueBytes = Converter.wcsToMbcs (null, value, true);
+							WebKitGTK.soup_message_headers_append (requestHeaders, nameBytes, valueBytes);
+						}
+					}
+				}
+			}
+			headers = null;
+		}
+	}
+
+	return 0;
+}
+
+int /*long*/ webkit_status_bar_text_changed (int /*long*/ web_view, int /*long*/ text) {
+	int length = OS.strlen (text);
+	byte[] bytes = new byte[length];
+	OS.memmove (bytes, text, length);
+	StatusTextEvent statusText = new StatusTextEvent (browser);
+	statusText.display = browser.getDisplay ();
+	statusText.widget = browser;
+	statusText.text = new String (Converter.mbcsToWcs (null, bytes));
+	for (int i = 0; i < statusTextListeners.length; i++) {
+		statusTextListeners[i].changed (statusText);
+	}
+	return 0;
+}
+
+int /*long*/ webkit_web_view_ready (int /*long*/ web_view) {
+	WindowEvent newEvent = new WindowEvent (browser);
+	newEvent.display = browser.getDisplay ();
+	newEvent.widget = browser;
+
+	int /*long*/ settings = WebKitGTK.webkit_web_view_get_window_features (webView);
+	int[] result = new int[1];
+	OS.g_object_get (settings, WebKitGTK.locationbar_visible, result, 0);
+	newEvent.addressBar = result[0] != 0;
+	result[0] = 0;
+	OS.g_object_get (settings, WebKitGTK.menubar_visible, result, 0);
+	newEvent.menuBar = result[0] != 0;
+	result[0] = 0;
+	OS.g_object_get (settings, WebKitGTK.statusbar_visible, result, 0);
+	newEvent.statusBar = result[0] != 0;
+	result[0] = 0;
+	OS.g_object_get (settings, WebKitGTK.toolbar_visible, result, 0);
+	newEvent.toolBar = result[0] != 0;
+	result[0] = 0;
+	OS.g_object_get (settings, WebKitGTK.x, result, 0);
+	int x = result[0];
+	result[0] = 0;
+	OS.g_object_get (settings, WebKitGTK.y, result, 0);
+	int y = result[0];
+	result[0] = 0;
+	OS.g_object_get (settings, WebKitGTK.width, result, 0);
+	int width = result[0];
+	result[0] = 0;
+	OS.g_object_get (settings, WebKitGTK.height, result, 0);
+	int height = result[0];
+	result[0] = 0;
+	if (x != -1 && y != -1) {
+		newEvent.location = new Point (x,y);
+	}
+	if (width != -1 && height != -1) {
+		newEvent.size = new Point (width,height);
+	}
+	for (int i = 0; i < visibilityWindowListeners.length; i++) {
+		visibilityWindowListeners[i].show (newEvent);
+	}
+	return 0;
+}
+
+int /*long*/ webkit_window_object_cleared (int /*long*/ web_view, int /*long*/ frame, int /*long*/ context, int /*long*/ window_object) {
+	int /*long*/ globalObject = WebKitGTK.JSContextGetGlobalObject (context);
+	int /*long*/ externalObject = WebKitGTK.JSObjectMake (context, ExternalClass, webViewData);
+	byte[] bytes = null;
+	try {
+		bytes = (OBJECTNAME_EXTERNAL + '\0').getBytes (CHARSET_UTF8);
+	} catch (UnsupportedEncodingException e) {
+		bytes = Converter.wcsToMbcs (null, OBJECTNAME_EXTERNAL, true);
+	} 
+	int /*long*/ name = WebKitGTK.JSStringCreateWithUTF8CString (bytes);
+	WebKitGTK.JSObjectSetProperty (context, globalObject, name, externalObject, 0, null);
+	WebKitGTK.JSStringRelease (name);
+	Enumeration elements = functions.elements ();
+	while (elements.hasMoreElements ()) {
+		BrowserFunction current = (BrowserFunction)elements.nextElement ();
+		execute (current.functionString);
+	}
+	int /*long*/ mainFrame = WebKitGTK.webkit_web_view_get_main_frame (webView);
+	boolean top = mainFrame == frame;
+	addEventHandlers (top);
+	return 0;
+}
+
+int /*long*/ callJava (int /*long*/ ctx, int /*long*/ func, int /*long*/ thisObject, int /*long*/ argumentCount, int /*long*/ arguments, int /*long*/ exception) {
+	Object returnValue = null;
+	if (argumentCount == 2) {
+		int /*long*/[] result = new int /*long*/[1];
+		C.memmove (result, arguments, C.PTR_SIZEOF);
+		int type = WebKitGTK.JSValueGetType (ctx, result[0]);
+		if (type == WebKitGTK.kJSTypeNumber) {
+			int index = ((Double)convertToJava (ctx, result[0])).intValue ();
+			result[0] = 0;
+			if (index > 0) {
+				Object key = new Integer (index);
+				BrowserFunction function = (BrowserFunction)functions.get (key);
+				if (function != null) {
+					try {
+						C.memmove (result, arguments + C.PTR_SIZEOF, C.PTR_SIZEOF);
+						Object temp = convertToJava (ctx, result[0]);
+						if (temp instanceof Object[]) {
+							Object[] args = (Object[])temp;
+							try {
+								returnValue = function.function (args);
+							} catch (Exception e) {
+								/* exception during function invocation */
+								returnValue = WebBrowser.CreateErrorString (e.getLocalizedMessage ());
+							}
+						}
+					} catch (IllegalArgumentException e) {
+						/* invalid argument value type */
+						if (function.isEvaluate) {
+							/* notify the function so that a java exception can be thrown */
+							function.function (new String[] {WebBrowser.CreateErrorString (new SWTException (SWT.ERROR_INVALID_RETURN_VALUE).getLocalizedMessage ())});
+						}
+						returnValue = WebBrowser.CreateErrorString (e.getLocalizedMessage ());
+					}
+				}
+			}
+		}
+	}
+	return convertToJS (ctx, returnValue);
+}
+
+int /*long*/ convertToJS (int /*long*/ ctx, Object value) {
+	if (value == null) {
+		return WebKitGTK.JSValueMakeUndefined (ctx);
+	}
+	if (value instanceof String) {
+		byte[] bytes = null;
+		try {
+			bytes = ((String)value + '\0').getBytes (CHARSET_UTF8); //$NON-NLS-1$
+		} catch (UnsupportedEncodingException e) {
+			bytes = Converter.wcsToMbcs (null, (String)value, true);
+		}
+		int /*long*/ stringRef = WebKitGTK.JSStringCreateWithUTF8CString (bytes);
+		int /*long*/ result = WebKitGTK.JSValueMakeString (ctx, stringRef);
+		WebKitGTK.JSStringRelease (stringRef);
+		return result;
+	}
+	if (value instanceof Boolean) {
+		return WebKitGTK.JSValueMakeBoolean (ctx, ((Boolean)value).booleanValue () ? 1 : 0);
+	}
+	if (value instanceof Number) {
+		return WebKitGTK.JSValueMakeNumber (ctx, ((Number)value).doubleValue ());
+	}
+	if (value instanceof Object[]) {
+		Object[] arrayValue = (Object[]) value;
+		int length = arrayValue.length;
+		int /*long*/[] arguments = new int /*long*/[length];
+		for (int i = 0; i < length; i++) {
+			Object javaObject = arrayValue[i];
+			int /*long*/ jsObject = convertToJS (ctx, javaObject);
+			arguments[i] = jsObject;
+		}
+		return WebKitGTK.JSObjectMakeArray (ctx, length, arguments, null);
+	}
+	SWT.error (SWT.ERROR_INVALID_RETURN_VALUE);
+	return 0;
+}
+
+Object convertToJava (int /*long*/ ctx, int /*long*/ value) {
+	int type = WebKitGTK.JSValueGetType (ctx, value);
+	switch (type) {
+		case WebKitGTK.kJSTypeBoolean: {
+			int result = WebKitGTK.JSValueToBoolean (ctx, value);
+			return new Boolean (result != 0);
+		}
+		case WebKitGTK.kJSTypeNumber: {
+			double result = WebKitGTK.JSValueToNumber (ctx, value, null);
+			return new Double(result);
+		}
+		case WebKitGTK.kJSTypeString: {
+			int /*long*/ string = WebKitGTK.JSValueToStringCopy (ctx, value, null);
+			if (string == 0) return ""; //$NON-NLS-1$
+			int /*long*/ length = WebKitGTK.JSStringGetMaximumUTF8CStringSize (string);
+			byte[] bytes = new byte[(int)/*64*/length];
+			length = WebKitGTK.JSStringGetUTF8CString (string, bytes, length);
+			WebKitGTK.JSStringRelease (string);
+			try {
+				/* length-1 is needed below to exclude the terminator character */
+				return new String (bytes, 0, (int)/*64*/length - 1, CHARSET_UTF8);
+			} catch (UnsupportedEncodingException e) {
+				return new String (Converter.mbcsToWcs (null, bytes));
+			}
+		}
+		case WebKitGTK.kJSTypeNull:
+			// FALL THROUGH
+		case WebKitGTK.kJSTypeUndefined: return null;
+		case WebKitGTK.kJSTypeObject: {
+			byte[] bytes = null;
+			try {
+				bytes = (PROPERTY_LENGTH + '\0').getBytes (CHARSET_UTF8); //$NON-NLS-1$
+			} catch (UnsupportedEncodingException e) {
+				bytes = Converter.wcsToMbcs (null, PROPERTY_LENGTH, true);
+			}
+			int /*long*/ propertyName = WebKitGTK.JSStringCreateWithUTF8CString (bytes);
+			int /*long*/ valuePtr = WebKitGTK.JSObjectGetProperty (ctx, value, propertyName, null);
+			WebKitGTK.JSStringRelease (propertyName);
+			type = WebKitGTK.JSValueGetType (ctx, valuePtr);
+			if (type == WebKitGTK.kJSTypeNumber) {
+				int length = (int)WebKitGTK.JSValueToNumber (ctx, valuePtr, null);
+				Object[] result = new Object[length];
+				for (int i = 0; i < length; i++) {
+					int /*long*/ current = WebKitGTK.JSObjectGetPropertyAtIndex (ctx, value, i, null);
+					if (current != 0) {
+						result[i] = convertToJava (ctx, current);
+					}
+				}
+				return result;
+			}
+		}
+	}
+	SWT.error (SWT.ERROR_INVALID_ARGUMENT);
+	return null;
+}
+
+}
diff --git a/org/eclipse/swt/browser/WindowCreator2.java b/org/eclipse/swt/browser/WindowCreator2.java
index 17ca051..4a176e0 100644
--- a/org/eclipse/swt/browser/WindowCreator2.java
+++ b/org/eclipse/swt/browser/WindowCreator2.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2003, 2007 IBM Corporation and others.
+ * Copyright (c) 2003, 2010 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
@@ -152,7 +152,11 @@ int CreateChromeWindow2 (int /*long*/ parent, int chromeFlags, int contextFlags,
 		* dialog that is not available to it (eg.- a print dialog on Linux).  For this
 		* reason modal requests are handled here so that the user is not exposed to them.
 		*/
-		int style = SWT.DIALOG_TRIM;
+		int style = SWT.NONE;
+		if ((chromeFlags & nsIWebBrowserChrome.CHROME_WINDOW_POPUP) == 0) {
+			/* add dialog trim for all windows except pop-ups */
+			style |= SWT.DIALOG_TRIM;
+		}
 		if ((chromeFlags & nsIWebBrowserChrome.CHROME_MODAL) != 0) style |= SWT.APPLICATION_MODAL; 
 		final Shell shell = src == null ?
 			new Shell (style) :
diff --git a/org/eclipse/swt/browser/WindowEvent.java b/org/eclipse/swt/browser/WindowEvent.java
index a0c67ba..ae75515 100644
--- a/org/eclipse/swt/browser/WindowEvent.java
+++ b/org/eclipse/swt/browser/WindowEvent.java
@@ -161,7 +161,7 @@ public class WindowEvent extends TypedEvent {
 
 	/**
 	 * Specifies whether the <code>Shell</code> hosting the <code>Browser</code> should
-	 * display a menu bar.
+	 * display a menu bar.  Note that this is always <code>true</code> on OS X.
 	 * 
 	 * @since 3.1
 	 */
diff --git a/org/eclipse/swt/custom/BidiSegmentEvent.java b/org/eclipse/swt/custom/BidiSegmentEvent.java
index cafd31f..d632d41 100644
--- a/org/eclipse/swt/custom/BidiSegmentEvent.java
+++ b/org/eclipse/swt/custom/BidiSegmentEvent.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -15,10 +15,12 @@ import org.eclipse.swt.events.*;
 
 /**
  * This event is sent to BidiSegmentListeners when a line is to
- * be measured or rendered in a bidi locale.  The segments field is 
- * used to specify text ranges in the line that should be treated as 
- * separate segments for bidi reordering.  Each segment will be reordered 
- * and rendered separately.
+ * be measured or rendered in a bidi locale.  
+ * The segments field can be used in conjunction with the segmentsChars
+ * field or by itself. Setting only the segmentsChars field has no effect.
+ * When used by itself, the segments field specify text ranges in the line
+ * that should be treated as separate segments for bidi reordering.  Each 
+ * segment will be reordered and rendered separately.
  * <p>
  * The elements in the segments field specify the start offset of 
  * a segment relative to the start of the line. They must follow
@@ -56,6 +58,18 @@ import org.eclipse.swt.events.*;
  * 		"R4R5R6". 
  *		visual line = "R3R2R1" + "R6R5R4"
  * </pre>
+ * 
+ * <p>
+ * The segments and segementsChars fields can be used together to obtain different
+ * types of bidi reordering and text display. The application can use these two fields
+ * to insert Unicode Control Characters in specific offsets in the line, the character
+ * at segmentsChars[i] is inserted at the offset specified by segments[i]. When both fields 
+ * are set, the rules for the segments field are less restrictive:
+ * <ul>
+ * <li>elements must be in ascending order, duplicates are allowed
+ * <li>elements must not exceed the line length
+ * </ul>
+ * </p>
  *
  * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
  */
@@ -75,6 +89,13 @@ public class BidiSegmentEvent extends TypedEvent {
 	 * bidi segments, see above 
 	 */
 	public int[] segments;
+
+	/** 
+	 * characters to be used in the segment boundaries (optional)
+	 * 
+	 * @since 3.6
+	 */
+	public char[] segmentsChars;
 		
 	static final long serialVersionUID = 3257846571587547957L;
 
diff --git a/org/eclipse/swt/custom/CCombo.java b/org/eclipse/swt/custom/CCombo.java
index f07a52a..aceaced 100644
--- a/org/eclipse/swt/custom/CCombo.java
+++ b/org/eclipse/swt/custom/CCombo.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -136,6 +136,12 @@ public CCombo (Composite parent, int style) {
 	filter = new Listener() {
 		public void handleEvent(Event event) {
 			if (isDisposed ()) return;
+			if (event.type == SWT.Selection) {
+				if (event.widget instanceof ScrollBar) {
+					handleScroll(event);
+				}
+				return;
+			}
 			Shell shell = ((Control)event.widget).getShell ();
 			if (shell == CCombo.this.getShell ()) {
 				handleFocus (SWT.FocusOut);
@@ -146,10 +152,13 @@ public CCombo (Composite parent, int style) {
 	int [] comboEvents = {SWT.Dispose, SWT.FocusIn, SWT.Move, SWT.Resize};
 	for (int i=0; i<comboEvents.length; i++) this.addListener (comboEvents [i], listener);
 	
-	int [] textEvents = {SWT.DefaultSelection, SWT.KeyDown, SWT.KeyUp, SWT.MenuDetect, SWT.Modify, SWT.MouseDown, SWT.MouseUp, SWT.MouseDoubleClick, SWT.MouseWheel, SWT.Traverse, SWT.FocusIn, SWT.Verify};
+	int [] textEvents = {SWT.DefaultSelection, SWT.DragDetect, SWT.KeyDown, SWT.KeyUp, SWT.MenuDetect, SWT.Modify,
+		SWT.MouseDown, SWT.MouseUp, SWT.MouseDoubleClick, SWT.MouseEnter, SWT.MouseExit, SWT.MouseHover,
+		SWT.MouseMove, SWT.MouseWheel, SWT.Traverse, SWT.FocusIn, SWT.Verify};
 	for (int i=0; i<textEvents.length; i++) text.addListener (textEvents [i], listener);
 	
-	int [] arrowEvents = {SWT.MouseDown, SWT.MouseUp, SWT.Selection, SWT.FocusIn};
+	int [] arrowEvents = {SWT.DragDetect, SWT.MouseDown, SWT.MouseEnter, SWT.MouseExit, SWT.MouseHover,
+		SWT.MouseMove, SWT.MouseUp, SWT.MouseWheel, SWT.Selection, SWT.FocusIn};
 	for (int i=0; i<arrowEvents.length; i++) arrow.addListener (arrowEvents [i], listener);
 	
 	createPopup(null, -1);
@@ -296,26 +305,42 @@ void arrowEvent (Event event) {
 			handleFocus (SWT.FocusIn);
 			break;
 		}
-		case SWT.MouseDown: {
-			Event mouseEvent = new Event ();
-			mouseEvent.button = event.button;
-			mouseEvent.count = event.count;
-			mouseEvent.stateMask = event.stateMask;
-			mouseEvent.time = event.time;
-			mouseEvent.x = event.x; mouseEvent.y = event.y;
-			notifyListeners (SWT.MouseDown, mouseEvent);
-			event.doit = mouseEvent.doit;
+		case SWT.DragDetect:
+		case SWT.MouseDown:
+		case SWT.MouseUp:
+		case SWT.MouseMove:
+		case SWT.MouseEnter:
+		case SWT.MouseExit:
+		case SWT.MouseHover: {
+			Point pt = getDisplay ().map (arrow, this, event.x, event.y);
+			event.x = pt.x; event.y = pt.y;
+			notifyListeners (event.type, event);
+			event.type = SWT.None;
 			break;
 		}
-		case SWT.MouseUp: {
-			Event mouseEvent = new Event ();
-			mouseEvent.button = event.button;
-			mouseEvent.count = event.count;
-			mouseEvent.stateMask = event.stateMask;
-			mouseEvent.time = event.time;
-			mouseEvent.x = event.x; mouseEvent.y = event.y;
-			notifyListeners (SWT.MouseUp, mouseEvent);
-			event.doit = mouseEvent.doit;
+		case SWT.MouseWheel: {
+			Point pt = getDisplay ().map (arrow, this, event.x, event.y);
+			event.x = pt.x; event.y = pt.y;
+			notifyListeners (SWT.MouseWheel, event);
+			event.type = SWT.None;
+			if (isDisposed ()) break;
+			if (!event.doit) break;
+			if (event.count != 0) {
+				event.doit = false;
+				int oldIndex = getSelectionIndex ();
+				if (event.count > 0) {
+					select (Math.max (oldIndex - 1, 0));
+				} else {
+					select (Math.min (oldIndex + 1, getItemCount () - 1));
+				}
+				if (oldIndex != getSelectionIndex ()) {
+					Event e = new Event();
+					e.time = event.time;
+					e.stateMask = event.stateMask;
+					notifyListeners (SWT.Selection, e);
+				}
+				if (isDisposed ()) break;
+			}
 			break;
 		}
 		case SWT.Selection: {
@@ -513,7 +538,9 @@ public void deselectAll () {
 }
 void dropDown (boolean drop) {
 	if (drop == isDropped ()) return;
+	Display display = getDisplay ();
 	if (!drop) {
+		display.removeFilter (SWT.Selection, filter);
 		popup.setVisible (false);
 		if (!isDisposed () && isFocusControl()) {
 			text.setFocus();
@@ -540,7 +567,6 @@ void dropDown (boolean drop) {
 	
 	int index = list.getSelectionIndex ();
 	if (index != -1) list.setTopIndex (index);
-	Display display = getDisplay ();
 	Rectangle listRect = list.getBounds ();
 	Rectangle parentRect = display.map (getParent (), null, getBounds ());
 	Point comboSize = getSize ();
@@ -554,6 +580,14 @@ void dropDown (boolean drop) {
 	popup.setBounds (x, y, width, height);
 	popup.setVisible (true);
 	if (isFocusControl()) list.setFocus ();
+	
+	/*
+	 * Add a filter to listen to scrolling of the parent composite, when the
+	 * drop-down is visible. Remove the filter when drop-down is not
+	 * visible.
+	 */
+	display.removeFilter (SWT.Selection, filter);
+	display.addFilter (SWT.Selection, filter);
 }
 /*
  * Return the lowercase of the first non-'&' character following
@@ -576,13 +610,16 @@ char _findMnemonic (String string) {
  * Return the Label immediately preceding the receiver in the z-order, 
  * or null if none. 
  */
-Label getAssociatedLabel () {
+String getAssociatedLabel () {
 	Control[] siblings = getParent ().getChildren ();
 	for (int i = 0; i < siblings.length; i++) {
 		if (siblings [i] == this) {
-			if (i > 0 && siblings [i-1] instanceof Label) {
-				return (Label) siblings [i-1];
+			if (i > 0) {
+				Control sibling = siblings [i-1];
+				if (sibling instanceof Label) return ((Label) sibling).getText();
+				if (sibling instanceof CLabel) return ((CLabel) sibling).getText();
 			}
+			break;
 		}
 	}
 	return null;
@@ -846,6 +883,12 @@ void handleFocus (int type) {
 		}
 	}
 }
+void handleScroll(Event event) {
+	ScrollBar scrollBar = (ScrollBar)event.widget;
+	Control scrollableParent = scrollBar.getParent();
+	if (scrollableParent.equals(list)) return;
+	if (isParentScrolling(scrollableParent)) dropDown(false);
+}
 /**
  * Searches the receiver's list starting at the first item
  * (index 0) until an item is found that is equal to the 
@@ -897,22 +940,19 @@ void initAccessible() {
 	AccessibleAdapter accessibleAdapter = new AccessibleAdapter () {
 		public void getName (AccessibleEvent e) {
 			String name = null;
-			Label label = getAssociatedLabel ();
-			if (label != null) {
-				name = stripMnemonic (label.getText());
+			String text = getAssociatedLabel ();
+			if (text != null) {
+				name = stripMnemonic (text);
 			}
 			e.result = name;
 		}
 		public void getKeyboardShortcut(AccessibleEvent e) {
 			String shortcut = null;
-			Label label = getAssociatedLabel ();
-			if (label != null) {
-				String text = label.getText ();
-				if (text != null) {
-					char mnemonic = _findMnemonic (text);
-					if (mnemonic != '\0') {
-						shortcut = "Alt+"+mnemonic; //$NON-NLS-1$
-					}
+			String text = getAssociatedLabel ();
+			if (text != null) {
+				char mnemonic = _findMnemonic (text);
+				if (mnemonic != '\0') {
+					shortcut = "Alt+"+mnemonic; //$NON-NLS-1$
 				}
 			}
 			e.result = shortcut;
@@ -1004,6 +1044,15 @@ public boolean isFocusControl () {
 	} 
 	return super.isFocusControl ();
 }
+boolean isParentScrolling(Control scrollableParent) {
+	Control parent = this.getParent();
+	while (parent != null) {
+		if (parent.equals(scrollableParent))
+			return true;
+		parent = parent.getParent();
+	}
+	return false;
+}
 void internalLayout (boolean changed) {
 	if (isDropped ()) dropDown (false);
 	Rectangle rect = getClientArea ();
@@ -1068,6 +1117,7 @@ void listEvent (Event event) {
 			e.doit = event.doit;
 			e.character = event.character;
 			e.keyCode = event.keyCode;
+			e.keyLocation = event.keyLocation;
 			notifyListeners (SWT.Traverse, e);
 			event.doit = e.doit;
 			event.detail = e.detail;
@@ -1078,8 +1128,10 @@ void listEvent (Event event) {
 			e.time = event.time;
 			e.character = event.character;
 			e.keyCode = event.keyCode;
+			e.keyLocation = event.keyLocation;
 			e.stateMask = event.stateMask;
 			notifyListeners (SWT.KeyUp, e);
+			event.doit = e.doit;
 			break;
 		}
 		case SWT.KeyDown: {
@@ -1105,8 +1157,10 @@ void listEvent (Event event) {
 			e.time = event.time;
 			e.character = event.character;
 			e.keyCode = event.keyCode;
+			e.keyLocation = event.keyLocation;
 			e.stateMask = event.stateMask;
 			notifyListeners(SWT.KeyDown, e);
+			event.doit = e.doit;
 			break;
 			
 		}
@@ -1617,11 +1671,24 @@ void textEvent (Event event) {
 			notifyListeners (SWT.DefaultSelection, e);
 			break;
 		}
+		case SWT.DragDetect:
+		case SWT.MouseDoubleClick:
+		case SWT.MouseMove:
+		case SWT.MouseEnter:
+		case SWT.MouseExit:
+		case SWT.MouseHover: {
+			Point pt = getDisplay ().map (text, this, event.x, event.y);
+			event.x = pt.x; event.y = pt.y;
+			notifyListeners (event.type, event);
+			event.type = SWT.None;
+			break;
+		}
 		case SWT.KeyDown: {
 			Event keyEvent = new Event ();
 			keyEvent.time = event.time;
 			keyEvent.character = event.character;
 			keyEvent.keyCode = event.keyCode;
+			keyEvent.keyLocation = event.keyLocation;
 			keyEvent.stateMask = event.stateMask;
 			notifyListeners (SWT.KeyDown, keyEvent);
 			if (isDisposed ()) break;
@@ -1661,6 +1728,7 @@ void textEvent (Event event) {
 			e.time = event.time;
 			e.character = event.character;
 			e.keyCode = event.keyCode;
+			e.keyLocation = event.keyLocation;
 			e.stateMask = event.stateMask;
 			notifyListeners (SWT.KeyUp, e);
 			event.doit = e.doit;
@@ -1680,12 +1748,13 @@ void textEvent (Event event) {
 			break;
 		}
 		case SWT.MouseDown: {
+			Point pt = getDisplay ().map (text, this, event.x, event.y);
 			Event mouseEvent = new Event ();
 			mouseEvent.button = event.button;
 			mouseEvent.count = event.count;
 			mouseEvent.stateMask = event.stateMask;
 			mouseEvent.time = event.time;
-			mouseEvent.x = event.x; mouseEvent.y = event.y;
+			mouseEvent.x = pt.x; mouseEvent.y = pt.y;
 			notifyListeners (SWT.MouseDown, mouseEvent);
 			if (isDisposed ()) break;
 			event.doit = mouseEvent.doit;
@@ -1699,12 +1768,13 @@ void textEvent (Event event) {
 			break;
 		}
 		case SWT.MouseUp: {
+			Point pt = getDisplay ().map (text, this, event.x, event.y);
 			Event mouseEvent = new Event ();
 			mouseEvent.button = event.button;
 			mouseEvent.count = event.count;
 			mouseEvent.stateMask = event.stateMask;
 			mouseEvent.time = event.time;
-			mouseEvent.x = event.x; mouseEvent.y = event.y;
+			mouseEvent.x = pt.x; mouseEvent.y = pt.y;
 			notifyListeners (SWT.MouseUp, mouseEvent);
 			if (isDisposed ()) break;
 			event.doit = mouseEvent.doit;
@@ -1714,24 +1784,10 @@ void textEvent (Event event) {
 			text.selectAll ();
 			break;
 		}
-		case SWT.MouseDoubleClick: {
-			Event mouseEvent = new Event ();
-			mouseEvent.button = event.button;
-			mouseEvent.count = event.count;
-			mouseEvent.stateMask = event.stateMask;
-			mouseEvent.time = event.time;
-			mouseEvent.x = event.x; mouseEvent.y = event.y;
-			notifyListeners (SWT.MouseDoubleClick, mouseEvent);
-			break;
-		}
 		case SWT.MouseWheel: {
-			Event keyEvent = new Event ();
-			keyEvent.time = event.time;
-			keyEvent.keyCode = event.count > 0 ? SWT.ARROW_UP : SWT.ARROW_DOWN;
-			keyEvent.stateMask = event.stateMask;
-			notifyListeners (SWT.KeyDown, keyEvent);
+			notifyListeners (SWT.MouseWheel, event);
+			event.type = SWT.None;
 			if (isDisposed ()) break;
-			event.doit = keyEvent.doit;
 			if (!event.doit) break;
 			if (event.count != 0) {
 				event.doit = false;
@@ -1771,6 +1827,7 @@ void textEvent (Event event) {
 			e.doit = event.doit;
 			e.character = event.character;
 			e.keyCode = event.keyCode;
+			e.keyLocation = event.keyLocation;
 			notifyListeners (SWT.Traverse, e);
 			event.doit = e.doit;
 			event.detail = e.detail;
@@ -1783,11 +1840,25 @@ void textEvent (Event event) {
 			e.end = event.end;
 			e.character = event.character;
 			e.keyCode = event.keyCode;
+			e.keyLocation = event.keyLocation;
 			e.stateMask = event.stateMask;
 			notifyListeners (SWT.Verify, e);
+			event.text = e.text;
 			event.doit = e.doit;
 			break;
 		}
 	}
 }
+public boolean traverse(int event){
+    /*
+     * When the traverse event is sent to the CCombo, it will create a list of
+     * controls to tab to next. Since the CCombo is a composite, the next control is
+     * the Text field which is a child of the CCombo. It will set focus to the text
+     * field which really is itself. So, call the traverse next events directly on the text.
+     */
+    if (event == SWT.TRAVERSE_ARROW_NEXT || event == SWT.TRAVERSE_TAB_NEXT) {
+    	return text.traverse(event);
+    }
+    return super.traverse(event);
+}
 }
diff --git a/org/eclipse/swt/custom/CLabel.java b/org/eclipse/swt/custom/CLabel.java
index ddd3c6a..b45797e 100644
--- a/org/eclipse/swt/custom/CLabel.java
+++ b/org/eclipse/swt/custom/CLabel.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -48,13 +48,15 @@ public class CLabel extends Canvas {
 	/** Gap between icon and text */
 	private static final int GAP = 5;
 	/** Left and right margins */
-	private static final int INDENT = 3;
+	private static final int DEFAULT_MARGIN = 3;
 	/** a string inserted in the middle of text that has been shortened */
 	private static final String ELLIPSIS = "..."; //$NON-NLS-1$ // could use the ellipsis glyph on some platforms "\u2026"
 	/** the alignment. Either CENTER, RIGHT, LEFT. Default is LEFT*/
 	private int align = SWT.LEFT;
-	private int hIndent = INDENT;
-	private int vIndent = INDENT;
+	private int leftMargin = DEFAULT_MARGIN;
+	private int topMargin = DEFAULT_MARGIN;
+	private int rightMargin = DEFAULT_MARGIN;
+	private int bottomMargin = DEFAULT_MARGIN;
 	/** the current text */
 	private String text;
 	/** the current icon */
@@ -65,13 +67,13 @@ public class CLabel extends Canvas {
 	// The appToolTip stores the tooltip set by the application.  Control.tooltiptext 
 	// contains whatever tooltip is currently being displayed.
 	private String appToolTipText;
+	private boolean ignoreDispose;
 	
 	private Image backgroundImage;
 	private Color[] gradientColors;
 	private int[] gradientPercents;
 	private boolean gradientVertical;
 	private Color background;
-	private Listener disposeListener;
 	
 	private static int DRAW_FLAGS = SWT.DRAW_MNEMONIC | SWT.DRAW_TAB | SWT.DRAW_TRANSPARENT | SWT.DRAW_DELIMITER;
 
@@ -113,7 +115,7 @@ public CLabel(Composite parent, int style) {
 	if ((style & SWT.RIGHT) != 0)  align = SWT.RIGHT;
 	if ((style & SWT.LEFT) != 0)   align = SWT.LEFT;
 	
-	addPaintListener(new PaintListener(){
+	addPaintListener(new PaintListener() {
 		public void paintControl(PaintEvent event) {
 			onPaint(event);
 		}
@@ -127,11 +129,11 @@ public CLabel(Composite parent, int style) {
 		}
 	});
 	
-	disposeListener = new Listener() {
+	addListener(SWT.Dispose, new Listener() {
 		public void handleEvent(Event event) {
 			onDispose(event);
 		}
-	};
+	});
 	
 	initAccessible();
 
@@ -158,12 +160,12 @@ public Point computeSize(int wHint, int hHint, boolean changed) {
 	checkWidget();
 	Point e = getTotalSize(image, text);
 	if (wHint == SWT.DEFAULT){
-		e.x += 2*hIndent;
+		e.x += leftMargin + rightMargin;
 	} else {
 		e.x = wHint;
 	}
 	if (hHint == SWT.DEFAULT) {
-		e.y += 2*vIndent;
+		e.y += topMargin + bottomMargin;
 	} else {
 		e.y = hHint;
 	}
@@ -199,7 +201,7 @@ char _findMnemonic (String string) {
  	return '\0';
 }
 /**
- * Returns the alignment.
+ * Returns the horizontal alignment.
  * The alignment style (LEFT, CENTER or RIGHT) is returned.
  * 
  * @return SWT.LEFT, SWT.RIGHT or SWT.CENTER
@@ -209,6 +211,17 @@ public int getAlignment() {
 	return align;
 }
 /**
+ * Return the CLabel's bottom margin.
+ * 
+ * @return the bottom margin of the label
+ * 
+ * @since 3.6
+ */
+public int getBottomMargin() {
+	//checkWidget();
+	return bottomMargin;
+}
+/**
  * Return the CLabel's image or <code>null</code>.
  * 
  * @return the image of the label or null
@@ -218,6 +231,28 @@ public Image getImage() {
 	return image;
 }
 /**
+ * Return the CLabel's left margin.
+ * 
+ * @return the left margin of the label
+ * 
+ * @since 3.6
+ */
+public int getLeftMargin() {
+	//checkWidget();
+	return leftMargin;
+}
+/**
+ * Return the CLabel's right margin.
+ * 
+ * @return the right margin of the label
+ * 
+ * @since 3.6
+ */
+public int getRightMargin() {
+	//checkWidget();
+	return rightMargin;
+}
+/**
  * Compute the minimum size.
  */
 private Point getTotalSize(Image image, String text) {
@@ -265,6 +300,17 @@ public String getToolTipText () {
 	checkWidget();
 	return appToolTipText;
 }
+/**
+ * Return the CLabel's top margin.
+ *  
+ * @return the top margin of the label
+ * 
+ * @since 3.6
+ */
+public int getTopMargin() {
+	//checkWidget();
+	return topMargin;
+}
 private void initAccessible() {
 	Accessible accessible = getAccessible();
 	accessible.addAccessibleListener(new AccessibleAdapter() {
@@ -311,9 +357,14 @@ private void initAccessible() {
 	});
 }
 void onDispose(Event event) {
-	removeListener(SWT.Dispose, disposeListener);
-	notifyListeners(SWT.Dispose, event);
-	event.type = SWT.None;
+	/* make this handler run after other dispose listeners */
+	if (ignoreDispose) {
+		ignoreDispose = false;
+		return;
+	}
+	ignoreDispose = true;
+	notifyListeners (event.type, event);
+	event.type = SWT.NONE;
 
 	gradientColors = null;
 	gradientPercents = null;
@@ -352,7 +403,7 @@ void onPaint(PaintEvent event) {
 	boolean shortenText = false;
 	String t = text;
 	Image img = image;
-	int availableWidth = Math.max(0, rect.width - 2*hIndent);
+	int availableWidth = Math.max(0, rect.width - (leftMargin + rightMargin));
 	Point extent = getTotalSize(img, t);
 	if (extent.x > availableWidth) {
 		img = null;
@@ -385,12 +436,12 @@ void onPaint(PaintEvent event) {
 	}
 		
 	// determine horizontal position
-	int x = rect.x + hIndent;
+	int x = rect.x + leftMargin;
 	if (align == SWT.CENTER) {
 		x = (rect.width - extent.x)/2;
 	}
 	if (align == SWT.RIGHT) {
-		x = rect.width - hIndent - extent.x;
+		x = rect.width - rightMargin - extent.x;
 	}
 	
 	// draw a background image behind the text
@@ -466,19 +517,47 @@ void onPaint(PaintEvent event) {
 		paintBorder(gc, rect);
 	}
 
+	/*
+	 * Compute text height and image height. If image height is more than
+	 * the text height, draw image starting from top margin. Else draw text
+	 * starting from top margin.
+	 */
+	Rectangle imageRect = null;
+	int lineHeight = 0, textHeight = 0, imageHeight = 0;
+	
+	if (img != null) {
+	    imageRect = img.getBounds();
+	    imageHeight = imageRect.height;
+	}
+	if (lines != null) {
+	    lineHeight = gc.getFontMetrics().getHeight();
+	    textHeight = lines.length * lineHeight;
+	}
+	
+	int imageY = 0, midPoint = 0, lineY = 0;
+	if (imageHeight > textHeight ) {
+	    if (topMargin == DEFAULT_MARGIN && bottomMargin == DEFAULT_MARGIN) imageY = rect.y + (rect.height - imageHeight) / 2;
+	    else imageY = topMargin;
+	    midPoint = imageY + imageHeight/2;
+	    lineY = midPoint - textHeight / 2;
+	}
+	else {
+	    if (topMargin == DEFAULT_MARGIN && bottomMargin == DEFAULT_MARGIN) lineY = rect.y + (rect.height - textHeight) / 2;
+	    else lineY = topMargin;
+	    midPoint = lineY + textHeight/2;
+	    imageY = midPoint - imageHeight / 2;
+	}
+	
 	// draw the image
 	if (img != null) {
-		Rectangle imageRect = img.getBounds();
-		gc.drawImage(img, 0, 0, imageRect.width, imageRect.height, 
-		                x, (rect.height-imageRect.height)/2, imageRect.width, imageRect.height);
+		gc.drawImage(img, 0, 0, imageRect.width, imageHeight, 
+		                x, imageY, imageRect.width, imageHeight);
 		x +=  imageRect.width + GAP;
 		extent.x -= imageRect.width + GAP;
 	}
+	
 	// draw the text
 	if (lines != null) {
-		int lineHeight = gc.getFontMetrics().getHeight();
-		int textHeight = lines.length * lineHeight;
-		int lineY = Math.max(vIndent, rect.y + (rect.height - textHeight) / 2);
 		gc.setForeground(getForeground());
 		for (int i = 0; i < lines.length; i++) {
 			int lineX = x;
@@ -489,7 +568,7 @@ void onPaint(PaintEvent event) {
 				}
 				if (align == SWT.RIGHT) {
 					int lineWidth = gc.textExtent(lines[i], DRAW_FLAGS).x;
-					lineX = Math.max(x, rect.x + rect.width - hIndent - lineWidth);
+					lineX = Math.max(x, rect.x + rect.width - rightMargin - lineWidth);
 				}
 			}
 			gc.drawText(lines[i], lineX, lineY, DRAW_FLAGS);
@@ -522,7 +601,7 @@ private void paintBorder(GC gc, Rectangle r) {
 	}
 }
 /**
- * Set the alignment of the CLabel.
+ * Set the horizontal alignment of the CLabel.
  * Use the values LEFT, CENTER and RIGHT to align image and text within the available space.
  * 
  * @param align the alignment style of LEFT, RIGHT or CENTER
@@ -703,6 +782,24 @@ public void setBackground(Image image) {
 	redraw();
 	
 }
+/**
+ * Set the label's bottom margin, in pixels.
+ * 
+ * @param bottomMargin the bottom margin of the label, which must be equal to or greater than zero
+ * 
+ * @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>
+ * 
+ * @since 3.6
+ */
+public void setBottomMargin(int bottomMargin) {
+    checkWidget();
+    if (this.bottomMargin == bottomMargin || bottomMargin < 0) return;
+    this.bottomMargin = bottomMargin;
+    redraw();
+}
 public void setFont(Font font) {
 	super.setFont(font);
 	redraw();
@@ -726,6 +823,64 @@ public void setImage(Image image) {
 	}
 }
 /**
+ * Set the label's horizontal left margin, in pixels.
+ * 
+ * @param leftMargin the left margin of the label, which must be equal to or greater than zero
+ * 
+ * @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>
+ * 
+ * @since 3.6
+ */
+public void setLeftMargin(int leftMargin) {
+    checkWidget();
+    if (this.leftMargin == leftMargin || leftMargin < 0) return;
+    this.leftMargin = leftMargin;
+    redraw();
+}
+/** 
+ * Set the label's margins, in pixels.
+ * 
+ * @param leftMargin the left margin.
+ * @param topMargin the top margin.
+ * @param rightMargin the right margin.
+ * @param bottomMargin the bottom margin.
+ * @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>
+ * 
+ * @since 3.6
+ */
+public void setMargins (int leftMargin, int topMargin, int rightMargin, int bottomMargin) {
+	checkWidget();
+	this.leftMargin = Math.max(0, leftMargin);
+	this.topMargin = Math.max(0, topMargin);
+	this.rightMargin = Math.max(0, rightMargin);
+	this.bottomMargin = Math.max(0, bottomMargin);
+	redraw();
+}
+/**
+ * Set the label's right margin, in pixels.
+ * 
+ * @param rightMargin the right margin of the label, which must be equal to or greater than zero
+ * 
+ * @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>
+ * 
+ * @since 3.6
+ */
+public void setRightMargin(int rightMargin) {
+    checkWidget();
+    if (this.rightMargin == rightMargin || rightMargin < 0) return;
+    this.rightMargin = rightMargin;
+    redraw();
+}
+/**
  * Set the label's text.
  * The value <code>null</code> clears it.
  * <p>
@@ -759,6 +914,24 @@ public void setToolTipText (String string) {
 	appToolTipText = super.getToolTipText();
 }
 /**
+ * Set the label's top margin, in pixels.
+ * 
+ * @param topMargin the top margin of the label, which must be equal to or greater than zero
+ * 
+ * @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>
+ * 
+ * @since 3.6
+ */
+public void setTopMargin(int topMargin) {
+    checkWidget();
+    if (this.topMargin == topMargin || topMargin < 0) return;
+    this.topMargin = topMargin;
+    redraw();
+}
+/**
  * Shorten the given text <code>t</code> so that its length doesn't exceed
  * the given width. The default implementation replaces characters in the
  * center of the original string with an ellipsis ("...").
diff --git a/org/eclipse/swt/custom/CTabFolder.java b/org/eclipse/swt/custom/CTabFolder.java
index 9d26184..6549c46 100644
--- a/org/eclipse/swt/custom/CTabFolder.java
+++ b/org/eclipse/swt/custom/CTabFolder.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -107,15 +107,16 @@ public class CTabFolder extends Composite {
 	public static RGB borderOutsideRGB = new RGB (171, 168, 165); 
 
 	/* sizing, positioning */
-	int xClient, yClient;
 	boolean onBottom = false;
 	boolean single = false;
 	boolean simple = true;
 	int fixedTabHeight = SWT.DEFAULT;
 	int tabHeight;
 	int minChars = 20;
+	boolean borderVisible = false;
 	
 	/* item management */
+	CTabFolderRenderer renderer;
 	CTabItem items[] = new CTabItem[0];
 	int firstIndex = -1; // index of the left most visible tab.
 	int selectedIndex = -1;
@@ -127,7 +128,7 @@ public class CTabFolder extends Composite {
 	/* External Listener management */
 	CTabFolder2Listener[] folderListeners = new CTabFolder2Listener[0];
 	// support for deprecated listener mechanism
-	CTabFolderListener[] tabListeners = new CTabFolderListener[0]; 
+	CTabFolderListener[] tabListeners = new CTabFolderListener[0];
 	
 	/* Selected item appearance */
 	Image selectionBgImage;
@@ -135,63 +136,37 @@ public class CTabFolder extends Composite {
 	int[] selectionGradientPercents;
 	boolean selectionGradientVertical;
 	Color selectionForeground;
-	Color selectionBackground;  //selection fade end
-	Color selectionFadeStart;
-	
-	Color selectionHighlightGradientBegin = null;  //null == no highlight
-	//Although we are given new colours all the time to show different states (active, etc),
-	//some of which may have a highlight and some not, we'd like to retain the highlight colours
-	//as a cache so that we can reuse them if we're again told to show the highlight.
-	//We are relying on the fact that only one tab state usually gets a highlight, so only
-	//a single cache is required. If that happens to not be true, cache simply becomes less effective,
-	//but we don't leak colours.
-	Color[] selectionHighlightGradientColorsCache = null;  //null is a legal value, check on access
+	Color selectionBackground;
 	
 	/* Unselected item appearance */
-	Color[] gradientColors;
+	Color[] gradientColors; 
 	int[] gradientPercents;
 	boolean gradientVertical;
 	boolean showUnselectedImage = true;
 	
 	// close, min/max and chevron buttons
-	Color fillColor;
 	boolean showClose = false;
 	boolean showUnselectedClose = true;
 	
 	Rectangle chevronRect = new Rectangle(0, 0, 0, 0);
-	int chevronImageState = NORMAL;
+	int chevronImageState = SWT.NONE;
 	boolean showChevron = false;
 	Menu showMenu;
 	
 	boolean showMin = false;
 	Rectangle minRect = new Rectangle(0, 0, 0, 0);
 	boolean minimized = false;
-	int minImageState = NORMAL;
+	int minImageState = SWT.NONE;
 	
 	boolean showMax = false;
 	Rectangle maxRect = new Rectangle(0, 0, 0, 0);
 	boolean maximized = false;
-	int maxImageState = NORMAL;
+	int maxImageState = SWT.NONE;
 	
 	Control topRight;
 	Rectangle topRightRect = new Rectangle(0, 0, 0, 0);
 	int topRightAlignment = SWT.RIGHT;
 	
-	// borders and shapes
-	int borderLeft = 0;
-	int borderRight = 0;
-	int borderTop = 0;
-	int borderBottom = 0;
-	
-	int highlight_margin = 0;
-	int highlight_header = 0;
-	
-	int[] curve;
-	int[] topCurveHighlightStart;
-	int[] topCurveHighlightEnd;
-	int curveWidth = 0;
-	int curveIndent = 0;
-	
 	// when disposing CTabFolder, don't try to layout the items or 
 	// change the selection as each child is destroyed.
 	boolean inDispose = false;
@@ -204,54 +179,18 @@ public class CTabFolder extends Composite {
 	// internal constants
 	static final int DEFAULT_WIDTH = 64;
 	static final int DEFAULT_HEIGHT = 64;
-	static final int BUTTON_SIZE = 18;
-
-	static final int[] TOP_LEFT_CORNER = new int[] {0,6, 1,5, 1,4, 4,1, 5,1, 6,0};
-
-	//TOP_LEFT_CORNER_HILITE is laid out in reverse (ie. top to bottom)
-	//so can fade in same direction as right swoop curve
-	static final int[] TOP_LEFT_CORNER_HILITE = new int[] {5,2, 4,2, 3,3, 2,4, 2,5, 1,6};
-
-	static final int[] TOP_RIGHT_CORNER = new int[] {-6,0, -5,1, -4,1, -1,4, -1,5, 0,6};
-	static final int[] BOTTOM_LEFT_CORNER = new int[] {0,-6, 1,-5, 1,-4, 4,-1, 5,-1, 6,0};
-	static final int[] BOTTOM_RIGHT_CORNER = new int[] {-6,0, -5,-1, -4,-1, -1,-4, -1,-5, 0,-6};
-
-	static final int[] SIMPLE_TOP_LEFT_CORNER = new int[] {0,2, 1,1, 2,0};
-	static final int[] SIMPLE_TOP_RIGHT_CORNER = new int[] {-2,0, -1,1, 0,2};
-	static final int[] SIMPLE_BOTTOM_LEFT_CORNER = new int[] {0,-2, 1,-1, 2,0};
-	static final int[] SIMPLE_BOTTOM_RIGHT_CORNER = new int[] {-2,0, -1,-1, 0,-2};
-	static final int[] SIMPLE_UNSELECTED_INNER_CORNER = new int[] {0,0};
-
-	static final int[] TOP_LEFT_CORNER_BORDERLESS = new int[] {0,6, 1,5, 1,4, 4,1, 5,1, 6,0};
-	static final int[] TOP_RIGHT_CORNER_BORDERLESS = new int[] {-7,0, -6,1, -5,1, -2,4, -2,5, -1,6};
-	static final int[] BOTTOM_LEFT_CORNER_BORDERLESS = new int[] {0,-6, 1,-6, 1,-5, 2,-4, 4,-2, 5,-1, 6,-1, 6,0};
-	static final int[] BOTTOM_RIGHT_CORNER_BORDERLESS = new int[] {-7,0, -7,-1, -6,-1, -5,-2, -3,-4, -2,-5, -2,-6, -1,-6};
-
-	static final int[] SIMPLE_TOP_LEFT_CORNER_BORDERLESS = new int[] {0,2, 1,1, 2,0};
-	static final int[] SIMPLE_TOP_RIGHT_CORNER_BORDERLESS= new int[] {-3,0, -2,1, -1,2};
-	static final int[] SIMPLE_BOTTOM_LEFT_CORNER_BORDERLESS = new int[] {0,-3, 1,-2, 2,-1, 3,0};
-	static final int[] SIMPLE_BOTTOM_RIGHT_CORNER_BORDERLESS = new int[] {-4,0, -3,-1, -2,-2, -1,-3};
-
+	
 	static final int SELECTION_FOREGROUND = SWT.COLOR_LIST_FOREGROUND;
 	static final int SELECTION_BACKGROUND = SWT.COLOR_LIST_BACKGROUND;
-	static final int BORDER1_COLOR = SWT.COLOR_WIDGET_NORMAL_SHADOW;
+	
 	static final int FOREGROUND = SWT.COLOR_WIDGET_FOREGROUND;
 	static final int BACKGROUND = SWT.COLOR_WIDGET_BACKGROUND;
-	static final int BUTTON_BORDER = SWT.COLOR_WIDGET_DARK_SHADOW;
-	static final int BUTTON_FILL = SWT.COLOR_LIST_BACKGROUND;
-	
-	static final int NONE = 0;
-	static final int NORMAL = 1;
-	static final int HOT = 2;
-	static final int SELECTED = 3;
-	static final RGB CLOSE_FILL = new RGB(252, 160, 160);
 	
 	static final int CHEVRON_CHILD_ID = 0;
 	static final int MINIMIZE_CHILD_ID = 1;
 	static final int MAXIMIZE_CHILD_ID = 2;
 	static final int EXTRA_CHILD_ID_COUNT = 3;
 	
-
 /**
  * Constructs a new instance of this class given its parent
  * and a style value describing its behavior and appearance.
@@ -297,19 +236,14 @@ void init(int style) {
 //	showMin = (style2 & SWT.MIN) != 0; - conflicts with SWT.TOP
 //	showMax = (style2 & SWT.MAX) != 0; - conflicts with SWT.BOTTOM
 	single = (style2 & SWT.SINGLE) != 0;
-	borderLeft = borderRight = (style & SWT.BORDER) != 0 ? 1 : 0;
-	borderTop = onBottom ? borderLeft : 0;
-	borderBottom = onBottom ? 0 : borderLeft;
-	highlight_header = (style & SWT.FLAT) != 0 ? 1 : 3;
-	highlight_margin = (style & SWT.FLAT) != 0 ? 0 : 2;
+	borderVisible = (style & SWT.BORDER) != 0;
 	//set up default colors
 	Display display = getDisplay();
 	selectionForeground = display.getSystemColor(SELECTION_FOREGROUND);
 	selectionBackground = display.getSystemColor(SELECTION_BACKGROUND);
+	renderer = new CTabFolderRenderer(this);
 	updateTabHeight(false);
 	
-	initAccessible();
-	
 	// Add all listeners
 	listener = new Listener() {
 		public void handleEvent(Event event) {
@@ -351,6 +285,8 @@ void init(int style) {
 	for (int i = 0; i < folderEvents.length; i++) {
 		addListener(folderEvents[i], listener);
 	}
+	
+	initAccessible();
 }
 static int checkStyle (Composite parent, int style) {
 	int mask = SWT.CLOSE | SWT.TOP | SWT.BOTTOM | SWT.FLAT | SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT | SWT.SINGLE | SWT.MULTI;
@@ -363,16 +299,6 @@ static int checkStyle (Composite parent, int style) {
 	if ((style & SWT.MULTI) != 0) style = style & ~SWT.SINGLE;
 	// reduce the flash by not redrawing the entire area on a Resize event
 	style |= SWT.NO_REDRAW_RESIZE;
-	//TEMPORARY CODE
-	/*
-	 * The default background on carbon and some GTK themes is not a solid color 
-	 * but a texture.  To show the correct default background, we must allow
-	 * the operating system to draw it and therefore, we can not use the 
-	 * NO_BACKGROUND style.  The NO_BACKGROUND style is not required on platforms
-	 * that use double buffering which is true in both of these cases.
-	 */
-	String platform = SWT.getPlatform();
-	if ("cocoa".equals(platform) || "carbon".equals(platform) || "gtk".equals(platform)) return style; //$NON-NLS-1$ //$NON-NLS-2$
 	
 	//TEMPORARY CODE
 	/*
@@ -384,18 +310,9 @@ static int checkStyle (Composite parent, int style) {
 	if ((style & SWT.RIGHT_TO_LEFT) != 0) return style;
 	if ((parent.getStyle() & SWT.MIRRORED) != 0 && (style & SWT.LEFT_TO_RIGHT) == 0) return style;
 	
-	return style | SWT.NO_BACKGROUND;
-}
-static void fillRegion(GC gc, Region region) {
-	// NOTE: region passed in to this function will be modified
-	Region clipping = new Region();
-	gc.getClipping(clipping);
-	region.intersect(clipping);
-	gc.setClipping(region);
-	gc.fillRectangle(region.getBounds());
-	gc.setClipping(clipping);
-	clipping.dispose();
+	return style | SWT.DOUBLE_BUFFERED;
 }
+
 /**
  * 
  * Adds the listener to the collection of listeners who will
@@ -495,63 +412,7 @@ public void addSelectionListener(SelectionListener listener) {
 	addListener(SWT.Selection, typedListener);
 	addListener(SWT.DefaultSelection, typedListener);
 }
-void antialias (int[] shape, RGB lineRGB, RGB innerRGB, RGB outerRGB, GC gc){
-	// Don't perform anti-aliasing on Mac and WPF because the platform
-	// already does it.  The simple style also does not require anti-aliasing.
-	if (simple) return;
-	String platform = SWT.getPlatform();
-	if ("cocoa".equals(platform)) return; //$NON-NLS-1$
-	if ("carbon".equals(platform)) return; //$NON-NLS-1$
-	if ("wpf".equals(platform)) return; //$NON-NLS-1$
-	// Don't perform anti-aliasing on low resolution displays
-	if (getDisplay().getDepth() < 15) return;
-	if (outerRGB != null) {
-		int index = 0;
-		boolean left = true;
-		int oldY = onBottom ? 0 : getSize().y;
-		int[] outer = new int[shape.length];
-		for (int i = 0; i < shape.length/2; i++) {
-			if (left && (index + 3 < shape.length)) {
-				left = onBottom ? oldY <= shape[index+3] : oldY >= shape[index+3];
-				oldY = shape[index+1];
-			}
-			outer[index] = shape[index++] + (left ? -1 : +1);
-			outer[index] = shape[index++];
-		}
-		RGB from = lineRGB;
-		RGB to = outerRGB;
-		int red = from.red + 2*(to.red - from.red)/3;
-		int green = from.green + 2*(to.green - from.green)/3;
-		int blue = from.blue + 2*(to.blue - from.blue)/3;
-		Color color = new Color(getDisplay(), red, green, blue);
-		gc.setForeground(color);
-		gc.drawPolyline(outer);
-		color.dispose();
-	}
-	if (innerRGB != null) {
-		int[] inner = new int[shape.length];
-		int index = 0;
-		boolean left = true;
-		int oldY = onBottom ? 0 : getSize().y;
-		for (int i = 0; i < shape.length/2; i++) {
-			if (left && (index + 3 < shape.length)) {
-				left = onBottom ? oldY <= shape[index+3] : oldY >= shape[index+3];
-				oldY = shape[index+1];
-			}
-			inner[index] = shape[index++] + (left ? +1 : -1);
-			inner[index] = shape[index++];
-		}
-		RGB from = lineRGB;
-		RGB to = innerRGB;
-		int red = from.red + 2*(to.red - from.red)/3;
-		int green = from.green + 2*(to.green - from.green)/3;
-		int blue = from.blue + 2*(to.blue - from.blue)/3;
-		Color color = new Color(getDisplay(), red, green, blue);
-		gc.setForeground(color);
-		gc.drawPolyline(inner);
-		color.dispose();
-	}
-}
+
 /*
 * This class was not intended to be subclassed but this restriction
 * cannot be enforced without breaking backward compatibility.
@@ -565,17 +426,7 @@ void antialias (int[] shape, RGB lineRGB, RGB innerRGB, RGB outerRGB, GC gc){
 //}
 public Rectangle computeTrim (int x, int y, int width, int height) {
 	checkWidget();
-	int trimX = x - marginWidth - highlight_margin - borderLeft;
-	int trimWidth = width + borderLeft + borderRight + 2*marginWidth + 2*highlight_margin;
-	if (minimized) {
-		int trimY = onBottom ? y - borderTop : y - highlight_header - tabHeight - borderTop;
-		int trimHeight = borderTop + borderBottom + tabHeight + highlight_header;
-		return new Rectangle (trimX, trimY, trimWidth, trimHeight);
-	} else {
-		int trimY = onBottom ? y - marginHeight - highlight_margin - borderTop: y - marginHeight - highlight_header - tabHeight - borderTop;
-		int trimHeight = height + borderTop + borderBottom + 2*marginHeight + tabHeight + highlight_header + highlight_margin;
-		return new Rectangle (trimX, trimY, trimWidth, trimHeight);
-	}
+	return renderer.computeTrim(CTabFolderRenderer.PART_BODY, SWT.NONE, x, y, width, height);
 }
 void createItem (CTabItem item, int index) {
 	if (0 > index || index > getItemCount ())SWT.error (SWT.ERROR_INVALID_RANGE);
@@ -621,7 +472,9 @@ void destroyItem (CTabItem item) {
 			control.setVisible(false);
 		}
 		setToolTipText(null);
-		setButtonBounds();
+		GC gc = new GC(this);
+		setButtonBounds(gc);
+		gc.dispose();
 		redraw();
 		return;
 	} 
@@ -655,518 +508,7 @@ void destroyItem (CTabItem item) {
 	updateItems();
 	redrawTabs();
 }
-void drawBackground(GC gc, int[] shape, boolean selected) {
-	Color defaultBackground = selected ? selectionBackground : getBackground();
-	Image image = selected ? selectionBgImage : null;
-	Color[] colors = selected ? selectionGradientColors : gradientColors;
-	int[] percents = selected ? selectionGradientPercents : gradientPercents;
-	boolean vertical = selected ? selectionGradientVertical : gradientVertical; 
-	Point size = getSize();
-	int width = size.x;
-	int height = tabHeight + highlight_header;
-	int x = 0;
-	if (borderLeft > 0) {
-		x += 1; width -= 2;
-	}
-	int y = onBottom ? size.y - borderBottom - height : borderTop;
-	drawBackground(gc, shape, x, y, width, height, defaultBackground, image, colors, percents, vertical);
-}
-void drawBackground(GC gc, int[] shape, int x, int y, int width, int height, Color defaultBackground, Image image, Color[] colors, int[] percents, boolean vertical) {
-	Region clipping = new Region();
-	gc.getClipping(clipping);
-	Region region = new Region();
-	region.add(shape);
-	region.intersect(clipping);
-	gc.setClipping(region);
-	
-	if (image != null) {
-		// draw the background image in shape
-		gc.setBackground(defaultBackground);
-		gc.fillRectangle(x, y, width, height);
-		Rectangle imageRect = image.getBounds();
-		gc.drawImage(image, imageRect.x, imageRect.y, imageRect.width, imageRect.height, x, y, width, height);
-	} else if (colors != null) {
-		// draw gradient
-		if (colors.length == 1) {
-			Color background = colors[0] != null ? colors[0] : defaultBackground;
-			gc.setBackground(background);
-			gc.fillRectangle(x, y, width, height);
-		} else {
-			if (vertical) {
-				if (onBottom) {
-					int pos = 0;
-					if (percents[percents.length - 1] < 100) {
-						pos = (100 - percents[percents.length - 1]) * height / 100;
-						gc.setBackground(defaultBackground);
-						gc.fillRectangle(x, y, width, pos);
-					}
-					Color lastColor = colors[colors.length-1];
-					if (lastColor == null) lastColor = defaultBackground;
-					for (int i = percents.length-1; i >= 0; i--) {
-						gc.setForeground(lastColor);
-						lastColor = colors[i];
-						if (lastColor == null) lastColor = defaultBackground;
-						gc.setBackground(lastColor);
-						int percentage = i > 0 ? percents[i] - percents[i-1] : percents[i];
-						int gradientHeight = percentage * height / 100;
-						gc.fillGradientRectangle(x, y+pos, width, gradientHeight, true);
-						pos += gradientHeight;
-					}
-				} else {
-					Color lastColor = colors[0];
-					if (lastColor == null) lastColor = defaultBackground;
-					int pos = 0;
-					for (int i = 0; i < percents.length; i++) {
-						gc.setForeground(lastColor);
-						lastColor = colors[i + 1];
-						if (lastColor == null) lastColor = defaultBackground;
-						gc.setBackground(lastColor);
-						int percentage = i > 0 ? percents[i] - percents[i-1] : percents[i];
-						int gradientHeight = percentage * height / 100;
-						gc.fillGradientRectangle(x, y+pos, width, gradientHeight, true);
-						pos += gradientHeight;
-					}
-					if (pos < height) {
-						gc.setBackground(defaultBackground);
-						gc.fillRectangle(x, pos, width, height-pos+1);
-					}
-				}
-			} else { //horizontal gradient
-				y = 0;
-				height = getSize().y;
-				Color lastColor = colors[0];
-				if (lastColor == null) lastColor = defaultBackground;
-				int pos = 0;
-				for (int i = 0; i < percents.length; ++i) {
-					gc.setForeground(lastColor);
-					lastColor = colors[i + 1];
-					if (lastColor == null) lastColor = defaultBackground;
-					gc.setBackground(lastColor);
-					int gradientWidth = (percents[i] * width / 100) - pos;
-					gc.fillGradientRectangle(x+pos, y, gradientWidth, height, false);
-					pos += gradientWidth;
-				}
-				if (pos < width) {
-					gc.setBackground(defaultBackground);
-					gc.fillRectangle(x+pos, y, width-pos, height);
-				}
-			}
-		}
-	} else {
-		// draw a solid background using default background in shape
-		if ((getStyle() & SWT.NO_BACKGROUND) != 0 || !defaultBackground.equals(getBackground())) {
-			gc.setBackground(defaultBackground);
-			gc.fillRectangle(x, y, width, height);
-		}
-	}
-	gc.setClipping(clipping);
-	clipping.dispose();
-	region.dispose();
-}
-void drawBody(Event event) {
-	GC gc = event.gc;
-	Point size = getSize();
-	
-	// fill in body
-	if (!minimized){
-		int width = size.x  - borderLeft - borderRight - 2*highlight_margin;
-		int height = size.y - borderTop - borderBottom - tabHeight - highlight_header - highlight_margin;
-		// Draw highlight margin
-		if (highlight_margin > 0) {
-			int[] shape = null;
-			if (onBottom) {
-				int x1 = borderLeft;
-				int y1 = borderTop;
-				int x2 = size.x - borderRight;
-				int y2 = size.y - borderBottom - tabHeight - highlight_header;
-				shape = new int[] {x1,y1, x2,y1, x2,y2, x2-highlight_margin,y2,
-						           x2-highlight_margin, y1+highlight_margin, x1+highlight_margin,y1+highlight_margin,
-								   x1+highlight_margin,y2, x1,y2};
-			} else {	
-				int x1 = borderLeft;
-				int y1 = borderTop + tabHeight + highlight_header;
-				int x2 = size.x - borderRight;
-				int y2 = size.y - borderBottom;
-				shape = new int[] {x1,y1, x1+highlight_margin,y1, x1+highlight_margin,y2-highlight_margin, 
-						           x2-highlight_margin,y2-highlight_margin, x2-highlight_margin,y1,
-								   x2,y1, x2,y2, x1,y2};
-			}
-			// If horizontal gradient, show gradient across the whole area
-			if (selectedIndex != -1 && selectionGradientColors != null && selectionGradientColors.length > 1 && !selectionGradientVertical) {
-				drawBackground(gc, shape, true);
-			} else if (selectedIndex == -1 && gradientColors != null && gradientColors.length > 1 && !gradientVertical) {
-				drawBackground(gc, shape, false);
-			} else {
-				gc.setBackground(selectedIndex == -1 ? getBackground() : selectionBackground);
-				gc.fillPolygon(shape);
-			}
-		}
-		//Draw client area
-		if ((getStyle() & SWT.NO_BACKGROUND) != 0) {
-			gc.setBackground(getBackground());
-			gc.fillRectangle(xClient - marginWidth, yClient - marginHeight, width, height);
-		}
-	} else {
-		if ((getStyle() & SWT.NO_BACKGROUND) != 0) {
-			int height = borderTop + tabHeight + highlight_header + borderBottom;
-			if (size.y > height) {
-				gc.setBackground(getParent().getBackground());
-				gc.fillRectangle(0, height, size.x, size.y - height);
-			}
-		}
-	}
-	
-	//draw 1 pixel border around outside
-	if (borderLeft > 0) {
-		gc.setForeground(getDisplay().getSystemColor(BORDER1_COLOR));
-		int x1 = borderLeft - 1;
-		int x2 = size.x - borderRight;
-		int y1 = onBottom ? borderTop - 1 : borderTop + tabHeight;
-		int y2 = onBottom ? size.y - tabHeight - borderBottom - 1 : size.y - borderBottom;
-		gc.drawLine(x1, y1, x1, y2); // left
-		gc.drawLine(x2, y1, x2, y2); // right
-		if (onBottom) {
-			gc.drawLine(x1, y1, x2, y1); // top
-		} else {
-			gc.drawLine(x1, y2, x2, y2); // bottom
-		}
-	}
-}
-
-void drawChevron(GC gc) {
-	if (chevronRect.width == 0 || chevronRect.height == 0) return;
-	// draw chevron (10x7)
-	Display display = getDisplay();
-	Point dpi = display.getDPI();
-	int fontHeight = 72 * 10 / dpi.y;
-	FontData fd = getFont().getFontData()[0];
-	fd.setHeight(fontHeight);
-	Font f = new Font(display, fd);
-	int fHeight = f.getFontData()[0].getHeight() * dpi.y / 72;
-	int indent = Math.max(2, (chevronRect.height - fHeight - 4) /2);
-	int x = chevronRect.x + 2;
-	int y = chevronRect.y + indent;
-	int count;
-	if (single) {
-		count = selectedIndex == -1 ? items.length : items.length - 1;
-	} else {
-		int showCount = 0;
-		while (showCount < priority.length && items[priority[showCount]].showing) {
-			showCount++;
-		}
-		count = items.length - showCount;
-	}
-	String chevronString = count > 99 ? "99+" : String.valueOf(count); //$NON-NLS-1$
-	switch (chevronImageState) {
-		case NORMAL: {
-			Color chevronBorder = single ? getSelectionForeground() : getForeground();
-			gc.setForeground(chevronBorder);
-			gc.setFont(f);
-			gc.drawLine(x,y,     x+2,y+2);
-			gc.drawLine(x+2,y+2, x,y+4);
-			gc.drawLine(x+1,y,   x+3,y+2);
-			gc.drawLine(x+3,y+2, x+1,y+4);
-			gc.drawLine(x+4,y,   x+6,y+2);
-			gc.drawLine(x+6,y+2, x+5,y+4);
-			gc.drawLine(x+5,y,   x+7,y+2);
-			gc.drawLine(x+7,y+2, x+4,y+4);
-			gc.drawString(chevronString, x+7, y+3, true);
-			break;
-		}
-		case HOT: {
-			gc.setForeground(display.getSystemColor(BUTTON_BORDER));
-			gc.setBackground(display.getSystemColor(BUTTON_FILL));
-			gc.setFont(f);
-			gc.fillRoundRectangle(chevronRect.x, chevronRect.y, chevronRect.width, chevronRect.height, 6, 6);
-			gc.drawRoundRectangle(chevronRect.x, chevronRect.y, chevronRect.width - 1, chevronRect.height - 1, 6, 6);
-			gc.drawLine(x,y,     x+2,y+2);
-			gc.drawLine(x+2,y+2, x,y+4);
-			gc.drawLine(x+1,y,   x+3,y+2);
-			gc.drawLine(x+3,y+2, x+1,y+4);
-			gc.drawLine(x+4,y,   x+6,y+2);
-			gc.drawLine(x+6,y+2, x+5,y+4);
-			gc.drawLine(x+5,y,   x+7,y+2);
-			gc.drawLine(x+7,y+2, x+4,y+4);
-			gc.drawString(chevronString, x+7, y+3, true);
-			break;
-		}
-		case SELECTED: {
-			gc.setForeground(display.getSystemColor(BUTTON_BORDER));
-			gc.setBackground(display.getSystemColor(BUTTON_FILL));
-			gc.setFont(f);
-			gc.fillRoundRectangle(chevronRect.x, chevronRect.y, chevronRect.width, chevronRect.height, 6, 6);
-			gc.drawRoundRectangle(chevronRect.x, chevronRect.y, chevronRect.width - 1, chevronRect.height - 1, 6, 6);
-			gc.drawLine(x+1,y+1, x+3,y+3);
-			gc.drawLine(x+3,y+3, x+1,y+5);
-			gc.drawLine(x+2,y+1, x+4,y+3);
-			gc.drawLine(x+4,y+3, x+2,y+5);
-			gc.drawLine(x+5,y+1, x+7,y+3);
-			gc.drawLine(x+7,y+3, x+6,y+5);
-			gc.drawLine(x+6,y+1, x+8,y+3);
-			gc.drawLine(x+8,y+3, x+5,y+5);
-			gc.drawString(chevronString, x+8, y+4, true);
-			break;
-		}
-	}
-	f.dispose();
-}
-void drawMaximize(GC gc) {
-	if (maxRect.width == 0 || maxRect.height == 0) return;
-	Display display = getDisplay();
-	// 5x4 or 7x9
-	int x = maxRect.x + (CTabFolder.BUTTON_SIZE - 10)/2;
-	int y = maxRect.y + 3;
-	
-	gc.setForeground(display.getSystemColor(BUTTON_BORDER));
-	gc.setBackground(display.getSystemColor(BUTTON_FILL));
-	
-	switch (maxImageState) {
-		case NORMAL: {
-			if (!maximized) {
-				gc.fillRectangle(x, y, 9, 9);
-				gc.drawRectangle(x, y, 9, 9);
-				gc.drawLine(x+1, y+2, x+8, y+2);				
-			} else {
-				gc.fillRectangle(x, y+3, 5, 4);
-				gc.fillRectangle(x+2, y, 5, 4);
-				gc.drawRectangle(x, y+3, 5, 4);
-				gc.drawRectangle(x+2, y, 5, 4);
-				gc.drawLine(x+3, y+1, x+6, y+1);
-				gc.drawLine(x+1, y+4, x+4, y+4);
-			}
-			break;
-		}
-		case HOT: {
-			gc.fillRoundRectangle(maxRect.x, maxRect.y, maxRect.width, maxRect.height, 6, 6);
-			gc.drawRoundRectangle(maxRect.x, maxRect.y, maxRect.width - 1, maxRect.height - 1, 6, 6);
-			if (!maximized) {
-				gc.fillRectangle(x, y, 9, 9);
-				gc.drawRectangle(x, y, 9, 9);
-				gc.drawLine(x+1, y+2, x+8, y+2);
-			} else {
-				gc.fillRectangle(x, y+3, 5, 4);
-				gc.fillRectangle(x+2, y, 5, 4);
-				gc.drawRectangle(x, y+3, 5, 4);
-				gc.drawRectangle(x+2, y, 5, 4);
-				gc.drawLine(x+3, y+1, x+6, y+1);
-				gc.drawLine(x+1, y+4, x+4, y+4);
-			}
-			break;
-		}
-		case SELECTED: {
-			gc.fillRoundRectangle(maxRect.x, maxRect.y, maxRect.width, maxRect.height, 6, 6);
-			gc.drawRoundRectangle(maxRect.x, maxRect.y, maxRect.width - 1, maxRect.height - 1, 6, 6);
-			if (!maximized) {
-				gc.fillRectangle(x+1, y+1, 9, 9);
-				gc.drawRectangle(x+1, y+1, 9, 9);
-				gc.drawLine(x+2, y+3, x+9, y+3);
-			} else {
-				gc.fillRectangle(x+1, y+4, 5, 4);
-				gc.fillRectangle(x+3, y+1, 5, 4);
-				gc.drawRectangle(x+1, y+4, 5, 4);
-				gc.drawRectangle(x+3, y+1, 5, 4);
-				gc.drawLine(x+4, y+2, x+7, y+2);
-				gc.drawLine(x+2, y+5, x+5, y+5);
-			}
-			break;
-		}
-	}
-}
-void drawMinimize(GC gc) {
-	if (minRect.width == 0 || minRect.height == 0) return;
-	Display display = getDisplay();
-	// 5x4 or 9x3
-	int x = minRect.x + (BUTTON_SIZE - 10)/2;
-	int y = minRect.y + 3;
-	
-	gc.setForeground(display.getSystemColor(BUTTON_BORDER));
-	gc.setBackground(display.getSystemColor(BUTTON_FILL));
-	
-	switch (minImageState) {
-		case NORMAL: {
-			if (!minimized) {
-				gc.fillRectangle(x, y, 9, 3);
-				gc.drawRectangle(x, y, 9, 3);
-			} else {
-				gc.fillRectangle(x, y+3, 5, 4);
-				gc.fillRectangle(x+2, y, 5, 4);
-				gc.drawRectangle(x, y+3, 5, 4);
-				gc.drawRectangle(x+2, y, 5, 4);
-				gc.drawLine(x+3, y+1, x+6, y+1);
-				gc.drawLine(x+1, y+4, x+4, y+4);
-			}
-			break;
-		}
-		case HOT: {
-			gc.fillRoundRectangle(minRect.x, minRect.y, minRect.width, minRect.height, 6, 6);
-			gc.drawRoundRectangle(minRect.x, minRect.y, minRect.width - 1, minRect.height - 1, 6, 6);
-			if (!minimized) {
-				gc.fillRectangle(x, y, 9, 3);
-				gc.drawRectangle(x, y, 9, 3);
-			} else {
-				gc.fillRectangle(x, y+3, 5, 4);
-				gc.fillRectangle(x+2, y, 5, 4);
-				gc.drawRectangle(x, y+3, 5, 4);
-				gc.drawRectangle(x+2, y, 5, 4);
-				gc.drawLine(x+3, y+1, x+6, y+1);
-				gc.drawLine(x+1, y+4, x+4, y+4);
-			}
-			break;
-		}
-		case SELECTED: {
-			gc.fillRoundRectangle(minRect.x, minRect.y, minRect.width, minRect.height, 6, 6);
-			gc.drawRoundRectangle(minRect.x, minRect.y, minRect.width - 1, minRect.height - 1, 6, 6);
-			if (!minimized) {
-				gc.fillRectangle(x+1, y+1, 9, 3);
-				gc.drawRectangle(x+1, y+1, 9, 3);
-			} else {
-				gc.fillRectangle(x+1, y+4, 5, 4);
-				gc.fillRectangle(x+3, y+1, 5, 4);
-				gc.drawRectangle(x+1, y+4, 5, 4);
-				gc.drawRectangle(x+3, y+1, 5, 4);
-				gc.drawLine(x+4, y+2, x+7, y+2);
-				gc.drawLine(x+2, y+5, x+5, y+5);
-			}
-			break;
-		}
-	}
-}
-void drawTabArea(Event event) {
-	GC gc = event.gc;
-	Point size = getSize();
-	int[] shape = null;
-	Color borderColor = getDisplay().getSystemColor(BORDER1_COLOR);
-	
-	if (tabHeight == 0) {
-		int style = getStyle();
-		if ((style & SWT.FLAT) != 0 && (style & SWT.BORDER) == 0) return;
-		int x1 = borderLeft - 1;
-		int x2 = size.x - borderRight;
-		int y1 = onBottom ? size.y - borderBottom - highlight_header - 1 : borderTop + highlight_header;
-		int y2 = onBottom ? size.y - borderBottom : borderTop;
-		if (borderLeft > 0 && onBottom) y2 -= 1;
-		
-		shape = new int[] {x1, y1, x1,y2, x2,y2, x2,y1};
 
-		// If horizontal gradient, show gradient across the whole area
-		if (selectedIndex != -1 && selectionGradientColors != null && selectionGradientColors.length > 1 && !selectionGradientVertical) {
-			drawBackground(gc, shape, true);
-		} else if (selectedIndex == -1 && gradientColors != null && gradientColors.length > 1 && !gradientVertical) {
-			drawBackground(gc, shape, false);
-		} else {
-			gc.setBackground(selectedIndex == -1 ? getBackground() : selectionBackground);
-			gc.fillPolygon(shape);
-		}
-		
-		//draw 1 pixel border
-		if (borderLeft > 0) {
-			gc.setForeground(borderColor);
-			gc.drawPolyline(shape); 
-		}
-		return;
-	}
-	
-	int x = Math.max(0, borderLeft - 1);
-	int y = onBottom ? size.y - borderBottom - tabHeight : borderTop;
-	int width = size.x - borderLeft - borderRight + 1;
-	int height = tabHeight - 1;
-	
-	// Draw Tab Header
-	if (onBottom) {
-		int[] left, right;
-		if ((getStyle() & SWT.BORDER) != 0) {
-			left = simple ? SIMPLE_BOTTOM_LEFT_CORNER : BOTTOM_LEFT_CORNER;
-			right = simple ? SIMPLE_BOTTOM_RIGHT_CORNER : BOTTOM_RIGHT_CORNER;
-		} else {
-			left = simple ? SIMPLE_BOTTOM_LEFT_CORNER_BORDERLESS : BOTTOM_LEFT_CORNER_BORDERLESS;
-			right = simple ? SIMPLE_BOTTOM_RIGHT_CORNER_BORDERLESS : BOTTOM_RIGHT_CORNER_BORDERLESS;
-		}
-		shape = new int[left.length + right.length + 4];
-		int index = 0;
-		shape[index++] = x;
-		shape[index++] = y-highlight_header;
-		for (int i = 0; i < left.length/2; i++) {
-			shape[index++] = x+left[2*i];
-			shape[index++] = y+height+left[2*i+1];
-			if (borderLeft == 0) shape[index-1] += 1;
-		}
-		for (int i = 0; i < right.length/2; i++) {
-			shape[index++] = x+width+right[2*i];
-			shape[index++] = y+height+right[2*i+1];
-			if (borderLeft == 0) shape[index-1] += 1;
-		}
-		shape[index++] = x+width;
-		shape[index++] = y-highlight_header;
-	} else {
-		int[] left, right;
-		if ((getStyle() & SWT.BORDER) != 0) {
-			left = simple ? SIMPLE_TOP_LEFT_CORNER : TOP_LEFT_CORNER;
-			right = simple ? SIMPLE_TOP_RIGHT_CORNER : TOP_RIGHT_CORNER;
-		} else {
-			left = simple ? SIMPLE_TOP_LEFT_CORNER_BORDERLESS : TOP_LEFT_CORNER_BORDERLESS;
-			right = simple ? SIMPLE_TOP_RIGHT_CORNER_BORDERLESS : TOP_RIGHT_CORNER_BORDERLESS;
-		}
-		shape = new int[left.length + right.length + 4];
-		int index = 0;
-		shape[index++] = x;
-		shape[index++] = y+height+highlight_header + 1;
-		for (int i = 0; i < left.length/2; i++) {
-			shape[index++] = x+left[2*i];
-			shape[index++] = y+left[2*i+1];
-		}
-		for (int i = 0; i < right.length/2; i++) {
-			shape[index++] = x+width+right[2*i];
-			shape[index++] = y+right[2*i+1];
-		}
-		shape[index++] = x+width;
-		shape[index++] = y+height+highlight_header + 1;
-	}
-	// Fill in background
-	boolean bkSelected = single && selectedIndex != -1;
-	drawBackground(gc, shape, bkSelected);
-	// Fill in parent background for non-rectangular shape
-	Region r = new Region();
-	r.add(new Rectangle(x, y, width + 1, height + 1));
-	r.subtract(shape);
-	gc.setBackground(getParent().getBackground());
-	fillRegion(gc, r);
-	r.dispose();
-	
-	// Draw the unselected tabs.
-	if (!single) {
-		for (int i=0; i < items.length; i++) {
-			if (i != selectedIndex && event.getBounds().intersects(items[i].getBounds())) {
-				items[i].onPaint(gc, false);
-			}
-		}
-	}
-	
-	// Draw selected tab
-	if (selectedIndex != -1) {
-		CTabItem item = items[selectedIndex];
-		item.onPaint(gc, true);
-	} else {
-		// if no selected tab - draw line across bottom of all tabs
-		int x1 = borderLeft;
-		int y1 = (onBottom) ? size.y - borderBottom - tabHeight - 1 : borderTop + tabHeight;
-		int x2 = size.x - borderRight;
-		gc.setForeground(borderColor);
-		gc.drawLine(x1, y1, x2, y1);
-	}
-	
-	// Draw Buttons
-	drawChevron(gc);
-	drawMinimize(gc);
-	drawMaximize(gc);
-	
-	// Draw border line
-	if (borderLeft > 0) {
-		RGB outside = getParent().getBackground().getRGB();
-		antialias(shape, borderColor.getRGB(), null, outside, gc);
-		gc.setForeground(borderColor);
-		gc.drawPolyline(shape);
-	}	
-}
 /**
  * Returns <code>true</code> if the receiver's border is visible.
  *
@@ -1181,23 +523,18 @@ void drawTabArea(Event event) {
  */
 public boolean getBorderVisible() {
 	checkWidget();
-	return borderLeft == 1;
+	return borderVisible;
 }
 public Rectangle getClientArea() {
 	checkWidget();
-	if (minimized) return new Rectangle(xClient, yClient, 0, 0);
+	Rectangle trim = renderer.computeTrim(CTabFolderRenderer.PART_BODY, SWT.NONE, 0, 0, 0, 0);
+	if (minimized) return new Rectangle(-trim.x, -trim.y, 0, 0);
 	Point size = getSize();
-	int width = size.x  - borderLeft - borderRight - 2*marginWidth - 2*highlight_margin;
-	int height = size.y - borderTop - borderBottom - 2*marginHeight - highlight_margin - highlight_header;
-	height -= tabHeight;
-	return new Rectangle(xClient, yClient, width, height);
-}
-Color getFillColor() {
-	if (fillColor == null) {
-		fillColor = new Color(getDisplay(), CTabFolder.CLOSE_FILL);
-	}
-	return fillColor;
+	int width = size.x - trim.width;
+	int height = size.y - trim.height;
+	return new Rectangle(-trim.x, -trim.y, width, height);
 }
+
 /**
  * Return the tab that is located at the specified index.
  * 
@@ -1233,7 +570,8 @@ public CTabItem getItem (Point pt) {
 	//checkWidget();
 	if (items.length == 0) return null;
 	Point size = getSize();
-	if (size.x <= borderLeft + borderRight) return null;
+	Rectangle trim = renderer.computeTrim(CTabFolderRenderer.PART_BORDER, SWT.NONE, 0, 0, 0, 0);
+	if (size.x <= trim.width) return null;
 	if (showChevron && chevronRect.contains(pt)) return null;
 	for (int i = 0; i < priority.length; i++) {
 		CTabItem item = items[priority[i]];
@@ -1272,6 +610,7 @@ public CTabItem [] getItems() {
 	System.arraycopy(items, 0, tabItems, 0, items.length);
 	return tabItems;
 }
+
 /*
  * Return the lowercase of the first non-'&' character following
  * an '&' character in the given string. If there are no '&'
@@ -1347,6 +686,7 @@ public int getMinimumCharacters() {
 	checkWidget();
 	return minChars;
 }
+
 /**
  * Returns <code>true</code> if the receiver is maximized.
  * <p>
@@ -1414,11 +754,31 @@ public boolean getMRUVisible() {
 	checkWidget();
 	return mru;
 }
-int getRightItemEdge (){
-	int x = getSize().x - borderRight - 3;
-	if (showMin) x -= BUTTON_SIZE;
-	if (showMax) x -= BUTTON_SIZE;
-	if (showChevron) x -= 3*BUTTON_SIZE/2;
+/**
+ * Returns the receiver's renderer.
+ * 
+ * @return the receiver's renderer
+ *
+ * @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 #setRenderer(CTabFolderRenderer)
+ * @see CTabFolderRenderer
+ * 
+ * @since 3.6
+ */
+public CTabFolderRenderer getRenderer() {
+	checkWidget();
+	return renderer;
+}
+int getRightItemEdge (GC gc){
+	Rectangle trim = renderer.computeTrim(CTabFolderRenderer.PART_BORDER, SWT.NONE, 0, 0, 0, 0);
+	int x = getSize().x - (trim.width + trim.x) - 3; //TODO: add setter for spacing?
+	if (showMin) x -= renderer.computeSize(CTabFolderRenderer.PART_MIN_BUTTON, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT).x;
+	if (showMax) x -= renderer.computeSize(CTabFolderRenderer.PART_MAX_BUTTON, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT).x;
+	if (showChevron) x -= renderer.computeSize(CTabFolderRenderer.PART_CHEVRON_BUTTON, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT).x;
 	if (topRight != null && topRightAlignment != SWT.FILL) {
 		Point rightSize = topRight.computeSize(SWT.DEFAULT, SWT.DEFAULT);
 		x -= rightSize.x + 3;
@@ -1518,7 +878,7 @@ public int getStyle() {
 	style |= onBottom ? SWT.BOTTOM : SWT.TOP;
 	style &= ~(SWT.SINGLE | SWT.MULTI);
 	style |= single ? SWT.SINGLE : SWT.MULTI;
-	if (borderLeft != 0) style |= SWT.BORDER;
+	if (borderVisible) style |= SWT.BORDER;
 	style &= ~SWT.CLOSE;
 	if (showClose) style |= SWT.CLOSE;
 	return style;
@@ -1536,7 +896,7 @@ public int getStyle() {
 public int getTabHeight(){
 	checkWidget();
 	if (fixedTabHeight != SWT.DEFAULT) return fixedTabHeight;
-	return tabHeight - 1; // -1 for line drawn across top of tab
+	return tabHeight - 1; // -1 for line drawn across top of tab //TODO: replace w/ computeTrim of tab area?
 }
 /**
  * Returns the position of the tab.  Possible values are SWT.TOP or SWT.BOTTOM.
@@ -1570,6 +930,23 @@ public Control getTopRight() {
 	return topRight;
 }
 /**
+ * Returns the alignment of the top right control. 
+ *
+ * @return the alignment of the top right control which is either
+ * <code>SWT.RIGHT</code> or <code>SWT.FILL</code> 
+ * 
+ * @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.6
+ */
+public int getTopRightAlignment() {
+	checkWidget();
+	return topRightAlignment;
+}
+/**
  * Returns <code>true</code> if the close button appears 
  * when the user hovers over an unselected tabs.
  * 
@@ -1896,10 +1273,7 @@ void onDispose(Event event) {
 			items[i].dispose();
 		}
 	}
-	if (fillColor != null) {
-	    fillColor.dispose();
-	    fillColor = null;
-	}
+
 	
 	selectionGradientColors = null;
 	selectionGradientPercents = null;
@@ -1907,7 +1281,9 @@ void onDispose(Event event) {
 
 	selectionBackground = null;
 	selectionForeground = null;
-	disposeSelectionHighlightGradientColors();	
+	
+	if (renderer != null) renderer.dispose();
+	renderer = null;
 }
 void onDragDetect(Event event) {
 	boolean consume = false;
@@ -1942,7 +1318,10 @@ boolean onMnemonic (Event event, boolean doit) {
 			char mnemonic = _findMnemonic (items[i].getText ());
 			if (mnemonic != '\0') {
 				if (Character.toLowerCase (key) == mnemonic) {
-					if (doit) setSelection(i, true);
+					if (doit) {
+					    setSelection(i, true);
+					    forceFocus();
+					}
 					return true;
 				}
 			}
@@ -1968,26 +1347,30 @@ void onMouse(Event event) {
 			break;
 		}
 		case SWT.MouseExit: {
-			if (minImageState != NORMAL) {
-				minImageState = NORMAL;
+			if (minImageState != SWT.NONE) {
+				minImageState = SWT.NONE;
 				redraw(minRect.x, minRect.y, minRect.width, minRect.height, false);
 			}
-			if (maxImageState != NORMAL) {
-				maxImageState = NORMAL;
+			if (maxImageState != SWT.NONE) {
+				maxImageState = SWT.NONE;
 				redraw(maxRect.x, maxRect.y, maxRect.width, maxRect.height, false);
 			}
-			if (chevronImageState != NORMAL) {
-				chevronImageState = NORMAL;
+			if (chevronImageState != SWT.NONE) {
+				chevronImageState = SWT.NONE;
 				redraw(chevronRect.x, chevronRect.y, chevronRect.width, chevronRect.height, false);
 			}
 			for (int i=0; i<items.length; i++) {
 				CTabItem item = items[i];
-				if (i != selectedIndex && item.closeImageState != NONE) {
-					item.closeImageState = NONE;
+				if (i != selectedIndex && item.closeImageState != SWT.BACKGROUND) {
+					item.closeImageState = SWT.BACKGROUND;
 					redraw(item.closeRect.x, item.closeRect.y, item.closeRect.width, item.closeRect.height, false);
 				}
-				if (i == selectedIndex && item.closeImageState != NORMAL) {
-					item.closeImageState = NORMAL;
+				if ((item.state & SWT.HOT) != 0) {
+					item.state &= ~SWT.HOT;
+					redraw(item.x, item.y, item.width, item.height, false);
+				}
+				if (i == selectedIndex && item.closeImageState != SWT.NONE) {
+					item.closeImageState = SWT.NONE;
 					redraw(item.closeRect.x, item.closeRect.y, item.closeRect.width, item.closeRect.height, false);
 				}
 			}
@@ -1996,22 +1379,22 @@ void onMouse(Event event) {
 		case SWT.MouseDown: {
 			if (event.button != 1) return;
 			if (minRect.contains(x, y)) {
-				minImageState = SELECTED;
+				minImageState = SWT.SELECTED;
 				redraw(minRect.x, minRect.y, minRect.width, minRect.height, false);
 				update();
 				return;
 			}
 			if (maxRect.contains(x, y)) {
-				maxImageState = SELECTED;
+				maxImageState = SWT.SELECTED;
 				redraw(maxRect.x, maxRect.y, maxRect.width, maxRect.height, false);
 				update();
 				return;
 			}
 			if (chevronRect.contains(x, y)) {
-				if (chevronImageState != HOT) {
-					chevronImageState = HOT;
+				if (chevronImageState != SWT.HOT) {
+					chevronImageState = SWT.HOT;
 				} else {
-					chevronImageState = SELECTED;
+					chevronImageState = SWT.SELECTED;
 				}
 				redraw(chevronRect.x, chevronRect.y, chevronRect.width, chevronRect.height, false);
 				update();
@@ -2035,14 +1418,19 @@ void onMouse(Event event) {
 			}
 			if (item != null) {
 				if (item.closeRect.contains(x,y)){
-					item.closeImageState = SELECTED;
+					item.closeImageState = SWT.SELECTED;
 					redraw(item.closeRect.x, item.closeRect.y, item.closeRect.width, item.closeRect.height, false);
 					update();
 					return;
 				}
 				int index = indexOf(item);
 				if (item.showing){
-					setSelection(index, true);
+				    	int oldSelectedIndex = selectedIndex;
+				    	setSelection(index, true);
+				    	if (oldSelectedIndex == selectedIndex) {
+				    	    /* If the click is on the selected tabitem, then set focus to the tabfolder */
+				    	    forceFocus();
+				    	}
 				}
 				return;
 			}
@@ -2053,35 +1441,35 @@ void onMouse(Event event) {
 			boolean close = false, minimize = false, maximize = false, chevron = false;
 			if (minRect.contains(x, y)) {
 				minimize = true;
-				if (minImageState != SELECTED && minImageState != HOT) {
-					minImageState = HOT;
+				if (minImageState != SWT.SELECTED && minImageState != SWT.HOT) {
+					minImageState = SWT.HOT;
 					redraw(minRect.x, minRect.y, minRect.width, minRect.height, false);
 				}
 			}
 			if (maxRect.contains(x, y)) {
 				maximize = true;
-				if (maxImageState != SELECTED && maxImageState != HOT) {
-					maxImageState = HOT;
+				if (maxImageState != SWT.SELECTED && maxImageState != SWT.HOT) {
+					maxImageState = SWT.HOT;
 					redraw(maxRect.x, maxRect.y, maxRect.width, maxRect.height, false);
 				}
 			}
 			if (chevronRect.contains(x, y)) {
 				chevron = true;
-				if (chevronImageState != SELECTED && chevronImageState != HOT) {
-					chevronImageState = HOT;
+				if (chevronImageState != SWT.SELECTED && chevronImageState != SWT.HOT) {
+					chevronImageState = SWT.HOT;
 					redraw(chevronRect.x, chevronRect.y, chevronRect.width, chevronRect.height, false);
 				}
 			}
-			if (minImageState != NORMAL && !minimize) {
-				minImageState = NORMAL;
+			if (minImageState != SWT.NONE && !minimize) {
+				minImageState = SWT.NONE;
 				redraw(minRect.x, minRect.y, minRect.width, minRect.height, false);
 			}
-			if (maxImageState != NORMAL && !maximize) {
-				maxImageState = NORMAL;
+			if (maxImageState != SWT.NONE && !maximize) {
+				maxImageState = SWT.NONE;
 				redraw(maxRect.x, maxRect.y, maxRect.width, maxRect.height, false);
 			}
-			if (chevronImageState != NORMAL && !chevron) {
-				chevronImageState = NORMAL;
+			if (chevronImageState != SWT.NONE && !chevron) {
+				chevronImageState = SWT.NONE;
 				redraw(chevronRect.x, chevronRect.y, chevronRect.width, chevronRect.height, false);
 			}
 			for (int i=0; i<items.length; i++) {
@@ -2090,23 +1478,31 @@ void onMouse(Event event) {
 				if (item.getBounds().contains(x, y)) {
 					close = true;
 					if (item.closeRect.contains(x, y)) {
-						if (item.closeImageState != SELECTED && item.closeImageState != HOT) {
-							item.closeImageState = HOT;
+						if (item.closeImageState != SWT.SELECTED && item.closeImageState != SWT.HOT) {
+							item.closeImageState = SWT.HOT;
 							redraw(item.closeRect.x, item.closeRect.y, item.closeRect.width, item.closeRect.height, false);
 						}
 					} else {
-						if (item.closeImageState != NORMAL) {
-							item.closeImageState = NORMAL;
+						if (item.closeImageState != SWT.NONE) {
+							item.closeImageState = SWT.NONE;
 							redraw(item.closeRect.x, item.closeRect.y, item.closeRect.width, item.closeRect.height, false);
 						}
 					}
-				} 
-				if (i != selectedIndex && item.closeImageState != NONE && !close) {
-					item.closeImageState = NONE;
+					if ((item.state & SWT.HOT) == 0) {
+						item.state |= SWT.HOT;
+						redraw(item.x, item.y, item.width, item.height, false);
+					}
+				}
+				if (i != selectedIndex && item.closeImageState != SWT.BACKGROUND && !close) {
+					item.closeImageState = SWT.BACKGROUND;
 					redraw(item.closeRect.x, item.closeRect.y, item.closeRect.width, item.closeRect.height, false);
 				}
-				if (i == selectedIndex && item.closeImageState != NORMAL && !close) {
-					item.closeImageState = NORMAL;
+				if ((item.state & SWT.HOT) != 0 && !close) {
+					item.state &= ~SWT.HOT;
+					redraw(item.x, item.y, item.width, item.height, false);
+				}
+				if (i == selectedIndex && item.closeImageState != SWT.NONE && !close) {
+					item.closeImageState = SWT.NONE;
 					redraw(item.closeRect.x, item.closeRect.y, item.closeRect.width, item.closeRect.height, false);
 				}
 			}
@@ -2115,7 +1511,7 @@ void onMouse(Event event) {
 		case SWT.MouseUp: {
 			if (event.button != 1) return;
 			if (chevronRect.contains(x, y)) {
-				boolean selected = chevronImageState == SELECTED;
+				boolean selected = chevronImageState == SWT.SELECTED;
 				if (!selected) return;
 				CTabFolderEvent e = new CTabFolderEvent(this);
 				e.widget = this;
@@ -2134,8 +1530,8 @@ void onMouse(Event event) {
 				return;
 			}
 			if (minRect.contains(x, y)) {
-				boolean selected = minImageState == SELECTED;
-				minImageState = HOT;
+				boolean selected = minImageState == SWT.SELECTED;
+				minImageState = SWT.HOT;
 				redraw(minRect.x, minRect.y, minRect.width, minRect.height, false);
 				if (!selected) return;
 				CTabFolderEvent e = new CTabFolderEvent(this);
@@ -2151,8 +1547,8 @@ void onMouse(Event event) {
 				return;
 			}
 			if (maxRect.contains(x, y)) {
-				boolean selected = maxImageState == SELECTED;
-				maxImageState = HOT;
+				boolean selected = maxImageState == SWT.SELECTED;
+				maxImageState = SWT.HOT;
 				redraw(maxRect.x, maxRect.y, maxRect.width, maxRect.height, false);
 				if (!selected) return;
 				CTabFolderEvent e = new CTabFolderEvent(this);
@@ -2185,8 +1581,8 @@ void onMouse(Event event) {
 			}
 			if (item != null) {
 				if (item.closeRect.contains(x,y)) {
-					boolean selected = item.closeImageState == SELECTED;
-					item.closeImageState = HOT;
+					boolean selected = item.closeImageState == SWT.SELECTED;
+					item.closeImageState = SWT.HOT;
 					redraw(item.closeRect.x, item.closeRect.y, item.closeRect.width, item.closeRect.height, false);
 					if (!selected) return;
 					CTabFolderEvent e = new CTabFolderEvent(this);
@@ -2210,13 +1606,13 @@ void onMouse(Event event) {
 						CTabItem nextItem = getItem(pt);
 						if (nextItem != null) {
 							if (nextItem.closeRect.contains(pt)) {
-								if (nextItem.closeImageState != SELECTED && nextItem.closeImageState != HOT) {
-									nextItem.closeImageState = HOT;
+								if (nextItem.closeImageState != SWT.SELECTED && nextItem.closeImageState != SWT.HOT) {
+									nextItem.closeImageState = SWT.HOT;
 									redraw(nextItem.closeRect.x, nextItem.closeRect.y, nextItem.closeRect.width, nextItem.closeRect.height, false);
 								}
 							} else {
-								if (nextItem.closeImageState != NORMAL) {
-									nextItem.closeImageState = NORMAL;
+								if (nextItem.closeImageState != SWT.NONE) {
+									nextItem.closeImageState = SWT.NONE;
 									redraw(nextItem.closeRect.x, nextItem.closeRect.y, nextItem.closeRect.width, nextItem.closeRect.height, false);
 								}
 							} 
@@ -2297,14 +1693,45 @@ void onPaint(Event event) {
 //gc.fillRectangle(-10, -10, size.x + 20, size.y+20);
 //}
 
-	drawBody(event);
-	
+	Point size = getSize();
+	Rectangle bodyRect = new Rectangle(0, 0, size.x, size.y); 
+	renderer.draw(CTabFolderRenderer.PART_BODY, SWT.BACKGROUND | SWT.FOREGROUND, bodyRect, gc); 
+
 	gc.setFont(gcFont);
 	gc.setForeground(gcForeground);
 	gc.setBackground(gcBackground);
 	
-	drawTabArea(event);
+	renderer.draw(CTabFolderRenderer.PART_HEADER, SWT.BACKGROUND | SWT.FOREGROUND, bodyRect, gc);
+	
+	gc.setFont(gcFont);
+	gc.setForeground(gcForeground);
+	gc.setBackground(gcBackground);	
+	
+	if (!single) {
+		for (int i=0; i < items.length; i++) {
+			Rectangle itemBounds = items[i].getBounds();
+			if (i != selectedIndex && event.getBounds().intersects(itemBounds)) {
+				renderer.draw(i, SWT.BACKGROUND | SWT.FOREGROUND | items[i].state , itemBounds, gc);
+			}
+		}
+	}
+	
+	gc.setFont(gcFont);
+	gc.setForeground(gcForeground);
+	gc.setBackground(gcBackground);	
+	
+	if (selectedIndex != -1) { 
+		renderer.draw(selectedIndex, items[selectedIndex].state | SWT.BACKGROUND | SWT.FOREGROUND, items[selectedIndex].getBounds(), gc);
+	}
+	
+	gc.setFont(gcFont);
+	gc.setForeground(gcForeground);
+	gc.setBackground(gcBackground);	
 	
+	renderer.draw(CTabFolderRenderer.PART_MAX_BUTTON, maxImageState, maxRect, gc);
+	renderer.draw(CTabFolderRenderer.PART_MIN_BUTTON, minImageState, minRect, gc);
+	renderer.draw(CTabFolderRenderer.PART_CHEVRON_BUTTON, chevronImageState, chevronRect, gc);
+
 	gc.setFont(gcFont);
 	gc.setForeground(gcForeground);
 	gc.setBackground(gcBackground);	
@@ -2321,10 +1748,11 @@ void onResize() {
 			redraw();
 		} else {
 			int x1 = Math.min(size.x, oldSize.x);
-			if (size.x != oldSize.x) x1 -= borderRight + highlight_margin + 2;
+			Rectangle trim = renderer.computeTrim(CTabFolderRenderer.PART_BODY, SWT.NONE, 0, 0, 0, 0);
+			if (size.x != oldSize.x) x1 -= trim.width + trim.x - marginWidth + 2;
 			if (!simple) x1 -= 5; // rounded top right corner
 			int y1 = Math.min(size.y, oldSize.y);
-			if (size.y != oldSize.y) y1 -= borderBottom + highlight_margin;
+			if (size.y != oldSize.y) y1 -= trim.height + trim.y - marginHeight;
 			int x2 = Math.max(size.x, oldSize.x);
 			int y2 = Math.max(size.y, oldSize.y);		
 			redraw(0, y1, x2, y2 - y1, false);
@@ -2371,10 +1799,12 @@ void onTraverse (Event event) {
 }
 void redrawTabs() {
 	Point size = getSize();
+	Rectangle trim = renderer.computeTrim(CTabFolderRenderer.PART_BODY, SWT.NONE, 0, 0, 0, 0);
 	if (onBottom) {
-		redraw(0, size.y - borderBottom - tabHeight - highlight_header - 1, size.x, borderBottom + tabHeight + highlight_header + 1, false);
+		int h = trim.height + trim.y - marginHeight;
+		redraw(0, size.y - h - 1, size.x, h + 1, false);
 	} else {
-		redraw(0, 0, size.x, borderTop + tabHeight + highlight_header + 1, false);
+		redraw(0, 0, size.x, -trim.y - marginHeight + 1, false);
 	}
 }
 /**	 
@@ -2478,12 +1908,21 @@ public void removeSelectionListener(SelectionListener listener) {
 	removeListener(SWT.Selection, listener);
 	removeListener(SWT.DefaultSelection, listener);	
 }
+
+public void reskin(int flags) {
+	super.reskin(flags);
+	for (int i = 0; i < items.length; i++) {
+		items[i].reskin(flags);
+	}
+}
+
 public void setBackground (Color color) {
 	super.setBackground(color);
+	renderer.createAntialiasColors(); //TODO: need better caching strategy
 	redraw();
 }
 /**
- * Specify a gradient of colours to be drawn in the background of the unselected tabs.
+ * Specify a gradient of colors to be drawn in the background of the unselected tabs.
  * For example to draw a gradient that varies from dark blue to blue and then to
  * white, use the following call to setBackground:
  * <pre>
@@ -2499,21 +1938,21 @@ public void setBackground (Color color) {
  *               background gradient. The value <code>null</code> can be used inside the array of 
  *               Color to specify the background color.
  * @param percents an array of integers between 0 and 100 specifying the percent of the width 
- *                 of the widget at which the color should change.  The size of the percents array must be one 
- *                 less than the size of the colors array.
+ *                 of the widget at which the color should change.  The size of the <code>percents</code>
+ *                 array must be one less than the size of the <code>colors</code> array.
  * 
  * @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
+ * @since 3.6
  */
-void setBackground(Color[] colors, int[] percents) {
+public void setBackground(Color[] colors, int[] percents) {
 	setBackground(colors, percents, false);
 }
 /**
- * Specify a gradient of colours to be drawn in the background of the unselected tab.
+ * Specify a gradient of colors to be drawn in the background of the unselected tab.
  * For example to draw a vertical gradient that varies from dark blue to blue and then to
  * white, use the following call to setBackground:
  * <pre>
@@ -2529,19 +1968,19 @@ void setBackground(Color[] colors, int[] percents) {
  *               background gradient. The value <code>null</code> can be used inside the array of 
  *               Color to specify the background color.
  * @param percents an array of integers between 0 and 100 specifying the percent of the width 
- *                 of the widget at which the color should change.  The size of the percents array must be one 
- *                 less than the size of the colors array.
+ *                 of the widget at which the color should change.  The size of the <code>percents</code>
+ *                 array must be one less than the size of the <code>colors</code> array.
  * 
- * @param vertical indicate the direction of the gradient.  True is vertical and false is horizontal. 
+ * @param vertical indicate the direction of the gradient. <code>True</code> is vertical and <code>false</code> is horizontal. 
  * 
  * @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
+ * @since 3.6
  */
-void setBackground(Color[] colors, int[] percents, boolean vertical) {
+public void setBackground(Color[] colors, int[] percents, boolean vertical) {
 	checkWidget();
 	if (colors != null) {
 		if (percents == null || percents.length != colors.length - 1) {
@@ -2604,6 +2043,11 @@ void setBackground(Color[] colors, int[] percents, boolean vertical) {
 	// Refresh with the new settings
 	redraw();
 }
+public void setBackgroundImage(Image image) {
+    	super.setBackgroundImage(image);
+    	renderer.createAntialiasColors(); //TODO: need better caching strategy
+    	redraw();
+}
 /**
  * Toggle the visibility of the border
  * 
@@ -2616,10 +2060,8 @@ void setBackground(Color[] colors, int[] percents, boolean vertical) {
  */
 public void setBorderVisible(boolean show) {
 	checkWidget();
-	if ((borderLeft == 1) == show) return;
-	borderLeft = borderRight = show ? 1 : 0;
-	borderTop = onBottom ? borderLeft : 0;
-	borderBottom = onBottom ? 0 : borderLeft;
+	if (borderVisible == show) return;
+	this.borderVisible = show;
 	Rectangle rectBefore = getClientArea();
 	updateItems();
 	Rectangle rectAfter = getClientArea();
@@ -2628,9 +2070,15 @@ public void setBorderVisible(boolean show) {
 	}
 	redraw();
 }
-void setButtonBounds() {
+void setButtonBounds(GC gc) {
 	Point size = getSize();
 	int oldX, oldY, oldWidth, oldHeight;
+	Rectangle trim = renderer.computeTrim(CTabFolderRenderer.PART_BORDER, SWT.NONE, 0, 0, 0, 0);
+	int borderRight = trim.width + trim.x;
+	int borderLeft = -trim.x;
+	int borderBottom = trim.height + trim.y;
+	int borderTop = -trim.y;
+	
 	// max button
 	oldX = maxRect.x;
 	oldY = maxRect.y;
@@ -2638,11 +2086,12 @@ void setButtonBounds() {
 	oldHeight = maxRect.height;
 	maxRect.x = maxRect.y = maxRect.width = maxRect.height = 0;
 	if (showMax) {
-		maxRect.x = size.x - borderRight - BUTTON_SIZE - 3;
+		Point maxSize = renderer.computeSize(CTabFolderRenderer.PART_MAX_BUTTON, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT);
+		maxRect.x = size.x - borderRight - maxSize.x - 3;
 		if (borderRight > 0) maxRect.x += 1;
-		maxRect.y = onBottom ? size.y - borderBottom - tabHeight + (tabHeight - BUTTON_SIZE)/2: borderTop + (tabHeight - BUTTON_SIZE)/2;
-		maxRect.width = BUTTON_SIZE;
-		maxRect.height = BUTTON_SIZE;
+		maxRect.y = onBottom ? size.y - borderBottom - tabHeight + (tabHeight - maxSize.y)/2: borderTop + (tabHeight - maxSize.y)/2;
+		maxRect.width = maxSize.x;
+		maxRect.height = maxSize.y;
 	}
 	if (oldX != maxRect.x || oldWidth != maxRect.width ||
 	    oldY != maxRect.y || oldHeight != maxRect.height) {
@@ -2651,7 +2100,7 @@ void setButtonBounds() {
 		int top = onBottom ? size.y - borderBottom - tabHeight: borderTop + 1;
 		redraw(left, top, right - left, tabHeight, false); 
 	}
-	
+
 	// min button
 	oldX = minRect.x;
 	oldY = minRect.y;
@@ -2659,11 +2108,12 @@ void setButtonBounds() {
 	oldHeight = minRect.height;
 	minRect.x = minRect.y = minRect.width = minRect.height = 0;
 	if (showMin) {
-		minRect.x = size.x - borderRight - maxRect.width - BUTTON_SIZE - 3;
+		Point minSize = renderer.computeSize(CTabFolderRenderer.PART_MIN_BUTTON, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT);
+		minRect.x = size.x - borderRight - maxRect.width - minSize.x - 3;
 		if (borderRight > 0) minRect.x += 1;
-		minRect.y = onBottom ? size.y - borderBottom - tabHeight + (tabHeight - BUTTON_SIZE)/2: borderTop + (tabHeight - BUTTON_SIZE)/2;
-		minRect.width = BUTTON_SIZE;
-		minRect.height = BUTTON_SIZE;
+		minRect.y = onBottom ? size.y - borderBottom - tabHeight + (tabHeight - minSize.y)/2: borderTop + (tabHeight - minSize.y)/2;
+		minRect.width = minSize.x;
+		minRect.height = minSize.y;
 	}
 	if (oldX != minRect.x || oldWidth != minRect.width ||
 	    oldY != minRect.y || oldHeight != minRect.height) {
@@ -2691,8 +2141,9 @@ void setButtonBounds() {
 					} else {
 						// fill size is 0 if item compressed
 						CTabItem item = items[selectedIndex];
-						if (item.x + item.width + 7 + 3*BUTTON_SIZE/2 >= rightEdge) break;
-						topRightRect.x = item.x + item.width + 7 + 3*BUTTON_SIZE/2;
+						int chevronWidth = renderer.computeSize(CTabFolderRenderer.PART_CHEVRON_BUTTON, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT).x;
+						if (item.x + item.width + 7 + chevronWidth >= rightEdge) break;
+						topRightRect.x = item.x + item.width + 7 + chevronWidth;
 						topRightRect.width = rightEdge - topRightRect.x;
 					}
 				} else {
@@ -2701,9 +2152,9 @@ void setButtonBounds() {
 					if (items.length == 0) {
 						topRightRect.x = borderLeft + 3;
 					} else {
-						CTabItem item = items[items.length - 1];
-						topRightRect.x = item.x + item.width;
-						if (!simple && items.length - 1 == selectedIndex) topRightRect.x += curveWidth - curveIndent;
+						int lastIndex = items.length - 1;
+						CTabItem lastItem = items[lastIndex];
+						topRightRect.x = lastItem.x + lastItem.width;
 					}
 					topRightRect.width = Math.max(0, rightEdge - topRightRect.x);
 				}
@@ -2737,10 +2188,11 @@ void setButtonBounds() {
 	oldWidth = chevronRect.width;
 	oldHeight = chevronRect.height;
 	chevronRect.x = chevronRect.y = chevronRect.height = chevronRect.width = 0;
+	Point chevronSize = renderer.computeSize(CTabFolderRenderer.PART_CHEVRON_BUTTON, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT);
 	if (single) {
 		if (selectedIndex == -1 || items.length > 1) {
-			chevronRect.width = 3*BUTTON_SIZE/2;
-			chevronRect.height = BUTTON_SIZE;
+			chevronRect.width = chevronSize.x;
+			chevronRect.height = chevronSize.y;
 			chevronRect.y = onBottom ? size.y - borderBottom - tabHeight + (tabHeight - chevronRect.height)/2 : borderTop + (tabHeight - chevronRect.height)/2;
 			if (selectedIndex == -1) {
 				chevronRect.x = size.x - borderRight - 3 - minRect.width - maxRect.width - topRightRect.width - chevronRect.width;
@@ -2754,8 +2206,8 @@ void setButtonBounds() {
 		}
 	} else {
 		if (showChevron) {
-			chevronRect.width = 3*BUTTON_SIZE/2;
-			chevronRect.height = BUTTON_SIZE;
+			chevronRect.width = chevronSize.x;
+			chevronRect.height = chevronSize.y;
 			int i = 0, lastIndex = -1;
 			while (i < priority.length && items[priority[i]].showing) {
 				lastIndex = Math.max(lastIndex, priority[i++]);
@@ -2763,8 +2215,8 @@ void setButtonBounds() {
 			if (lastIndex == -1) lastIndex = firstIndex;
 			CTabItem lastItem = items[lastIndex];
 			int w = lastItem.x + lastItem.width + 3;
-			if (!simple && lastIndex == selectedIndex) w += curveWidth - 2*curveIndent;
-			chevronRect.x = Math.min(w, getRightItemEdge());
+			if (!simple && lastIndex == selectedIndex) w -= renderer.curveIndent;  //TODO: fix chevron position
+			chevronRect.x = Math.min(w, getRightItemEdge(gc));
 			chevronRect.y = onBottom ? size.y - borderBottom - tabHeight + (tabHeight - chevronRect.height)/2 : borderTop + (tabHeight - chevronRect.height)/2;
 		}
 	}
@@ -2830,11 +2282,16 @@ public void setInsertMark(int index, boolean after) {
 		SWT.error(SWT.ERROR_INVALID_ARGUMENT);
 	}
 }
-boolean setItemLocation() {
+boolean setItemLocation(GC gc) {
 	boolean changed = false;
 	if (items.length == 0) return false;
+	Rectangle trim = renderer.computeTrim(CTabFolderRenderer.PART_BORDER, SWT.NONE, 0, 0, 0, 0);
+	int borderLeft = -trim.x;
+	int borderBottom = trim.height + trim.y;
+	int borderTop = -trim.y;
 	Point size = getSize();
 	int y = onBottom ? Math.max(borderBottom, size.y - borderBottom - tabHeight) : borderTop;
+	Point closeButtonSize = renderer.computeSize(CTabFolderRenderer.PART_CLOSE_BUTTON, 0, gc, SWT.DEFAULT, SWT.DEFAULT);
 	if (single) {
 		int defaultX = getDisplay().getBounds().width + 10; // off screen
 		for (int i = 0; i < items.length; i++) {
@@ -2846,8 +2303,8 @@ boolean setItemLocation() {
 				item.y = y;
 				item.showing = true;
 				if (showClose || item.showClose) {
-					item.closeRect.x = borderLeft + CTabItem.LEFT_MARGIN;
-					item.closeRect.y = onBottom ? size.y - borderBottom - tabHeight + (tabHeight - BUTTON_SIZE)/2: borderTop + (tabHeight - BUTTON_SIZE)/2;
+					item.closeRect.x = borderLeft - renderer.computeTrim(i, SWT.NONE, 0, 0, 0, 0).x;
+					item.closeRect.y = onBottom ? size.y - borderBottom - tabHeight + (tabHeight - closeButtonSize.y)/2: borderTop + (tabHeight - closeButtonSize.y)/2;
 				}
 				if (item.x != oldX || item.y != oldY) changed = true;
 			} else {
@@ -2856,16 +2313,15 @@ boolean setItemLocation() {
 			}
 		}
 	} else {
-		int rightItemEdge = getRightItemEdge();
+		int rightItemEdge = getRightItemEdge(gc);
 		int maxWidth = rightItemEdge - borderLeft;
 		int width = 0;
 		for (int i = 0; i < priority.length; i++) {
 			CTabItem item = items[priority[i]];
 			width += item.width;
 			item.showing = i == 0 ? true : item.width > 0 && width <= maxWidth;
-			if (!simple && priority[i] == selectedIndex) width += curveWidth - 2*curveIndent;
 		}
-		int x = 0;
+		int x = -renderer.computeTrim(CTabFolderRenderer.PART_HEADER, SWT.NONE, 0, 0, 0, 0).x;
 		int defaultX = getDisplay().getBounds().width + 10; // off screen
 		firstIndex = items.length - 1;
 		for (int i = 0; i < items.length; i++) {
@@ -2878,40 +2334,35 @@ boolean setItemLocation() {
 				if (item.x != x || item.y != y) changed = true;
 				item.x = x;
 				item.y = y;
-				if (i == selectedIndex) {
-					int edge = Math.min(item.x + item.width, rightItemEdge);
-					item.closeRect.x = edge - CTabItem.RIGHT_MARGIN - BUTTON_SIZE;
-				} else {
-					item.closeRect.x = item.x + item.width - CTabItem.RIGHT_MARGIN - BUTTON_SIZE;
-				}
-				item.closeRect.y = onBottom ? size.y - borderBottom - tabHeight + (tabHeight - BUTTON_SIZE)/2: borderTop + (tabHeight - BUTTON_SIZE)/2;
+				int state = SWT.NONE;
+				if (i == selectedIndex) state |= SWT.SELECTED;
+				Rectangle edgeTrim = renderer.computeTrim(i, state, 0, 0, 0, 0);
+				item.closeRect.x = item.x + item.width  - (edgeTrim.width + edgeTrim.x) - closeButtonSize.x;
+				item.closeRect.y = onBottom ? size.y - borderBottom - tabHeight + (tabHeight - closeButtonSize.y)/2: borderTop + (tabHeight - closeButtonSize.y)/2;
 				x = x + item.width;
-				if (!simple && i == selectedIndex) x += curveWidth - 2*curveIndent;
+				if (!simple && i == selectedIndex) x -= renderer.curveIndent; //TODO: fix next item position 
 			}
 		}
 	}
 	return changed;
 }
-boolean setItemSize() {
+boolean setItemSize(GC gc) {
 	boolean changed = false;
 	if (isDisposed()) return changed;
 	Point size = getSize();
 	if (size.x <= 0 || size.y <= 0) return changed;
-	xClient = borderLeft + marginWidth + highlight_margin;
-	if (onBottom) {
-		yClient = borderTop + highlight_margin + marginHeight;
-	} else {
-		yClient = borderTop + tabHeight + highlight_header + marginHeight; 
-	}
+
+	Rectangle trim = renderer.computeTrim(CTabFolderRenderer.PART_BORDER, SWT.NONE, 0, 0, 0, 0);
+	int borderRight = trim.width + trim.x;
+	int borderLeft = -trim.x;
+	
 	showChevron = false;
 	if (single) {
 		showChevron = true;
 		if (selectedIndex != -1) {
 			CTabItem tab = items[selectedIndex];
-			GC gc = new GC(this);
-			int width = tab.preferredWidth(gc, true, false);
-			gc.dispose();
-			width = Math.min(width, getRightItemEdge() - borderLeft);
+			int width = renderer.computeSize(selectedIndex, SWT.SELECTED, gc, SWT.DEFAULT, SWT.DEFAULT).x;
+			width = Math.min(width, getRightItemEdge(gc) - borderLeft);
 			if (tab.height != tabHeight || tab.width != width) {
 				changed = true;
 				tab.shortenedText = null;
@@ -2920,8 +2371,9 @@ boolean setItemSize() {
 				tab.width = width;
 				tab.closeRect.width = tab.closeRect.height = 0;
 				if (showClose || tab.showClose) {
-					tab.closeRect.width = BUTTON_SIZE;
-					tab.closeRect.height = BUTTON_SIZE;
+					Point closeSize = renderer.computeSize(CTabFolderRenderer.PART_CLOSE_BUTTON, SWT.SELECTED, gc, SWT.DEFAULT, SWT.DEFAULT);
+					tab.closeRect.width = closeSize.x;
+					tab.closeRect.height = closeSize.y;
 				}
 			}
 		}
@@ -2931,30 +2383,30 @@ boolean setItemSize() {
 	if (items.length == 0) return changed;
 
 	int[] widths;
-	GC gc = new GC(this);
 	int tabAreaWidth = size.x - borderLeft - borderRight - 3;
-	if (showMin) tabAreaWidth -= BUTTON_SIZE;
-	if (showMax) tabAreaWidth -= BUTTON_SIZE;
+	if (showMin) tabAreaWidth -= renderer.computeSize(CTabFolderRenderer.PART_MIN_BUTTON, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT).x;
+	if (showMax) tabAreaWidth -= renderer.computeSize(CTabFolderRenderer.PART_MAX_BUTTON, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT).x;
 	if (topRightAlignment == SWT.RIGHT && topRight != null) {
 		Point rightSize = topRight.computeSize(SWT.DEFAULT, SWT.DEFAULT, false);
 		tabAreaWidth -= rightSize.x + 3;
 	}
-	if (!simple) tabAreaWidth -= curveWidth - 2*curveIndent;
 	tabAreaWidth = Math.max(0, tabAreaWidth);
-	
+
 	// First, try the minimum tab size at full compression.
 	int minWidth = 0;
 	int[] minWidths = new int[items.length];	
 	for (int i = 0; i < priority.length; i++) {
 		int index = priority[i];
-		minWidths[index] = items[index].preferredWidth(gc, index == selectedIndex, true);
+		int state = CTabFolderRenderer.MINIMUM_SIZE;
+		if (index == selectedIndex) state |= SWT.SELECTED;
+		minWidths[index] = renderer.computeSize(index, state, gc, SWT.DEFAULT, SWT.DEFAULT).x;
 		minWidth += minWidths[index];
 		if (minWidth > tabAreaWidth) break;
 	}
 	if (minWidth > tabAreaWidth) {
 		// full compression required and a chevron
 		showChevron = items.length > 1;
-		if (showChevron) tabAreaWidth -= 3*BUTTON_SIZE/2;
+		if (showChevron) tabAreaWidth -= renderer.computeSize(CTabFolderRenderer.PART_CHEVRON_BUTTON, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT).x;
 		widths = minWidths;
 		int index = selectedIndex != -1 ? selectedIndex : 0;
 		if (tabAreaWidth < widths[index]) {
@@ -2964,7 +2416,9 @@ boolean setItemSize() {
 		int maxWidth = 0;
 		int[] maxWidths = new int[items.length];
 		for (int i = 0; i < items.length; i++) {
-			maxWidths[i] = items[i].preferredWidth(gc, i == selectedIndex, false);
+			int state = 0;
+			if (i == selectedIndex) state |= SWT.SELECTED;
+			maxWidths[i] = renderer.computeSize(i, state, gc, SWT.DEFAULT, SWT.DEFAULT).x;
 			maxWidth += maxWidths[i];
 		}
 		if (maxWidth <= tabAreaWidth) {
@@ -2996,7 +2450,6 @@ boolean setItemSize() {
 			}
 		}
 	}
-	gc.dispose();
 
 	for (int i = 0; i < items.length; i++) {
 		CTabItem tab = items[i];
@@ -3010,8 +2463,9 @@ boolean setItemSize() {
 			tab.closeRect.width = tab.closeRect.height = 0;
 			if (showClose || tab.showClose) {
 				if (i == selectedIndex || showUnselectedClose) {
-					tab.closeRect.width = BUTTON_SIZE;
-					tab.closeRect.height = BUTTON_SIZE;
+					Point closeSize = renderer.computeSize(CTabFolderRenderer.PART_CLOSE_BUTTON, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT);
+					tab.closeRect.width = closeSize.x;
+					tab.closeRect.height = closeSize.y;
 				}
 			}
 		}
@@ -3183,6 +2637,37 @@ public void setMRUVisible(boolean show) {
 	}
 }
 /**
+ * Sets the renderer which is associated with the receiver to be
+ * the argument which may be null. In the case of null, the default
+ * renderer is used.
+ *
+ * @param renderer a new renderer
+ * 
+ * @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 CTabFolderRenderer
+ * 
+ * @since 3.6
+ */
+public void setRenderer(CTabFolderRenderer renderer) {
+	checkWidget();
+	if (this.renderer == renderer) return;
+	if (this.renderer != null) this.renderer.dispose();
+	if (renderer == null) renderer = new CTabFolderRenderer(this);
+	this.renderer = renderer;
+	updateTabHeight(false);
+	Rectangle rectBefore = getClientArea();
+	updateItems();
+	Rectangle rectAfter = getClientArea();
+	if (!rectBefore.equals(rectAfter)) {
+		notifyListeners(SWT.Resize, new Event());
+	}
+	redraw();
+}
+/**
  * Set the selection to the tab at the specified item.
  * 
  * @param item the tab item to be selected
@@ -3224,10 +2709,12 @@ public void setSelection(int index) {
 	int oldIndex = selectedIndex;
 	selectedIndex = index;
 	if (oldIndex != -1) {
-		items[oldIndex].closeImageState = NONE;
+		items[oldIndex].closeImageState = SWT.BACKGROUND;
+		items[oldIndex].state &= ~SWT.SELECTED;
 	}
-	selection.closeImageState = NORMAL;
+	selection.closeImageState = SWT.NONE;
 	selection.showing = false;
+	selection.state |= SWT.SELECTED;
 
 	Control newControl = selection.control;
 	Control oldControl = null;
@@ -3279,6 +2766,7 @@ public void setSelectionBackground (Color color) {
 	if (selectionBackground == color) return;
 	if (color == null) color = getDisplay().getSystemColor(SELECTION_BACKGROUND);
 	selectionBackground = color;
+	renderer.createAntialiasColors(); //TODO:  need better caching strategy
 	if (selectedIndex > -1) redraw();
 }
 /**
@@ -3429,58 +2917,8 @@ public void setSelectionBackground(Color[] colors, int[] percents, boolean verti
  * Set the color for the highlight start for selected tabs.
  * Update the cache of highlight gradient colors if required.
  */
-
 void setSelectionHighlightGradientColor(Color start) {
-	//Set to null to match all the early return cases.
-	//For early returns, don't realloc the cache, we may get a cache hit next time we're given the highlight
-	selectionHighlightGradientBegin = null;
-
-	if(start == null)
-		return;
-
-	//don't bother on low colour
-	if (getDisplay().getDepth() < 15)
-		return;
-	
-	//don't bother if we don't have a background gradient
-	if(selectionGradientColors.length < 2) 
-		return;
-
-	//OK we know its a valid gradient now
-	selectionHighlightGradientBegin = start;
-
-	if(! isSelectionHighlightColorsCacheHit(start))
-		createSelectionHighlightGradientColors(start);  //if no cache hit then compute new ones
-}
-
-/*
- * Return true if given start color, the cache of highlight colors we have
- * would match the highlight colors we'd compute.
- */
-boolean isSelectionHighlightColorsCacheHit(Color start) {
-
-	if(selectionHighlightGradientColorsCache == null)
-		return false;
-	
-	//this case should never happen but check to be safe before accessing array indexes
-	if(selectionHighlightGradientColorsCache.length < 2)
-		return false;
-
-	Color highlightBegin = selectionHighlightGradientColorsCache[0];
-	Color highlightEnd = selectionHighlightGradientColorsCache[selectionHighlightGradientColorsCache.length - 1];
-
-	if(! highlightBegin.equals(start))
-		return false;	
-	
-	//Compare number of colours we have vs. we'd compute
-	if(selectionHighlightGradientColorsCache.length != tabHeight)
-		return false;
-	
-	//Compare existing highlight end to what it would be (selectionBackground)
-	if(! highlightEnd.equals(selectionBackground))
-		return false;
-	
-	return true;
+	renderer.setSelectionHighlightGradientColor(start);  //TODO: need better caching strategy
 }
 
 /**
@@ -3501,9 +2939,10 @@ public void setSelectionBackground(Image image) {
 	if (image != null) {
 		selectionGradientColors = null;
 		selectionGradientPercents = null;
-		disposeSelectionHighlightGradientColors();
+		renderer.disposeSelectionHighlightGradientColors(); //TODO: need better caching strategy
 	}
 	selectionBgImage = image;
+	renderer.createAntialiasColors(); //TODO:  need better caching strategy
 	if (selectedIndex > -1) redraw();
 }
 /**
@@ -3524,59 +2963,6 @@ public void setSelectionForeground (Color color) {
 	if (selectedIndex > -1) redraw();
 }
 
-/*
- * Allocate colors for the highlight line.
- * Colours will be a gradual blend ranging from to.
- * Blend length will be tab height.
- * Recompute this if tab height changes.
- * Could remain null if there'd be no gradient (start=end or low colour display)
- */
-void createSelectionHighlightGradientColors(Color start) {
-	disposeSelectionHighlightGradientColors(); //dispose if existing
-
-	if(start == null)  //shouldn't happen but just to be safe
-		return;
-
-	//alloc colours for entire height to ensure it matches wherever we stop drawing
-	int fadeGradientSize = tabHeight;
-
-	RGB from = start.getRGB();
-	RGB to = selectionBackground.getRGB();
-
-	selectionHighlightGradientColorsCache = new Color[fadeGradientSize];
-	int denom = fadeGradientSize - 1;
-
-	for (int i = 0; i < fadeGradientSize; i++) {
-		int propFrom = denom - i;
-		int propTo = i;
-		int red = (to.red * propTo + from.red * propFrom) / denom;
-		int green = (to.green * propTo  + from.green * propFrom) / denom;
-		int blue = (to.blue * propTo  + from.blue * propFrom) / denom;
-		selectionHighlightGradientColorsCache[i] = new Color(getDisplay(), red, green, blue);
-	}
-}
-
-void disposeSelectionHighlightGradientColors() {
-	if(selectionHighlightGradientColorsCache == null)
-		return;
-	for (int i = 0; i < selectionHighlightGradientColorsCache.length; i++) {
-		selectionHighlightGradientColorsCache[i].dispose();
-	}
-	selectionHighlightGradientColorsCache = null;
-}
-
-/*
- * Return the gradient start color for selected tabs, which is the start of the tab fade
- * (end is selectionBackground).
- */
-Color getSelectionBackgroundGradientBegin() {
-	if (selectionGradientColors == null)
-		return getSelectionBackground();
-	if (selectionGradientColors.length == 0)
-		return getSelectionBackground();
-	return selectionGradientColors[0];
-}
-
 /**
  * Sets the shape that the CTabFolder will use to render itself.  
  * 
@@ -3620,8 +3006,8 @@ public void setSingle(boolean single) {
 		this.single = single;
 		if (!single) {
 			for (int i = 0; i < items.length; i++) {
-				if (i != selectedIndex && items[i].closeImageState == NORMAL) {
-					items[i].closeImageState = NONE;
+				if (i != selectedIndex && items[i].closeImageState == SWT.NONE) {
+					items[i].closeImageState = SWT.BACKGROUND;
 				}
 			}
 		}
@@ -3676,8 +3062,6 @@ public void setTabPosition(int position) {
 	}
 	if (onBottom != (position == SWT.BOTTOM)) {
 		onBottom = position == SWT.BOTTOM;
-		borderTop = onBottom ? borderLeft : 0;
-		borderBottom = onBottom ? 0 : borderRight;
 		updateTabHeight(true);
 		Rectangle rectBefore = getClientArea();
 		updateItems();
@@ -3832,7 +3216,7 @@ public void showItem (CTabItem item) {
 void showList (Rectangle rect) {
 	if (items.length == 0 || !showChevron) return;
 	if (showMenu == null || showMenu.isDisposed()) {
-		showMenu = new Menu(this);
+		showMenu = new Menu(getShell(), getStyle() & (SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT));
 	} else {
 		MenuItem[] items = showMenu.getItems();
 		for (int i = 0; i < items.length; i++) {
@@ -3895,24 +3279,29 @@ boolean updateItems() {
 }
 
 boolean updateItems(int showIndex) {
+	GC gc = new GC(this);
 	if (!single && !mru && showIndex != -1) {
 		// make sure selected item will be showing
 		int firstIndex = showIndex;
 		if (priority[0] < showIndex) {
-			int maxWidth = getRightItemEdge() - borderLeft;
-			if (!simple) maxWidth -= curveWidth - 2*curveIndent;
+			Rectangle trim = renderer.computeTrim(CTabFolderRenderer.PART_BORDER, SWT.NONE, 0, 0, 0, 0);
+			int borderLeft = -trim.x;
+			int maxWidth = getRightItemEdge(gc) - borderLeft;
 			int width = 0;
 			int[] widths = new int[items.length];
-			GC gc = new GC(this);
 			for (int i = priority[0]; i <= showIndex; i++) {
-				widths[i] = items[i].preferredWidth(gc, i == selectedIndex, true);
+				int state = CTabFolderRenderer.MINIMUM_SIZE;
+				if (i == selectedIndex) state |= SWT.SELECTED;
+				widths[i] = renderer.computeSize(i, state, gc, SWT.DEFAULT, SWT.DEFAULT).x;
 				width += widths[i];
 				if (width > maxWidth) break;
 			}
 			if (width > maxWidth) {
 				width = 0;
 				for (int i = showIndex; i >= 0; i--) {
-					if (widths[i] == 0) widths[i] = items[i].preferredWidth(gc, i == selectedIndex, true);
+					int state = CTabFolderRenderer.MINIMUM_SIZE;
+					if (i == selectedIndex) state |= SWT.SELECTED;
+					if (widths[i] == 0) widths[i] = renderer.computeSize(i, state, gc, SWT.DEFAULT, SWT.DEFAULT).x;
 					width += widths[i];
 					if (width > maxWidth) break;
 					firstIndex = i;
@@ -3920,20 +3309,24 @@ boolean updateItems(int showIndex) {
 			} else {
 				firstIndex = priority[0];
 				for (int i = showIndex + 1; i < items.length; i++) {
-					widths[i] = items[i].preferredWidth(gc, i == selectedIndex, true);
+					int state = CTabFolderRenderer.MINIMUM_SIZE;
+					if (i == selectedIndex) state |= SWT.SELECTED;
+					widths[i] = renderer.computeSize(i, state, gc, SWT.DEFAULT, SWT.DEFAULT).x;
 					width += widths[i];
 					if (width >= maxWidth) break;
 				}
 				if (width < maxWidth) {
 					for (int i = priority[0] - 1; i >= 0; i--) {
-						if (widths[i] == 0) widths[i] = items[i].preferredWidth(gc, i == selectedIndex, true);
+						int state = CTabFolderRenderer.MINIMUM_SIZE;
+						if (i == selectedIndex) state |= SWT.SELECTED;
+						if (widths[i] == 0) widths[i] = renderer.computeSize(i, state, gc, SWT.DEFAULT, SWT.DEFAULT).x;
 						width += widths[i];
 						if (width > maxWidth) break;
 						firstIndex = i;
 					}
 				}
 			}
-			gc.dispose();
+		
 		}
 		if (firstIndex != priority[0]) {
 			int index = 0;
@@ -3947,72 +3340,25 @@ boolean updateItems(int showIndex) {
 	}
 	
 	boolean oldShowChevron = showChevron;
-	boolean changed = setItemSize();
-	changed |= setItemLocation();
-	setButtonBounds();
+	boolean changed = setItemSize(gc);
+	changed |= setItemLocation(gc);
+	setButtonBounds(gc);
 	changed |= showChevron != oldShowChevron;
 	if (changed && getToolTipText() != null) {
 		Point pt = getDisplay().getCursorLocation();
 		pt = toControl(pt);
 		_setToolTipText(pt.x, pt.y);
 	}
+	gc.dispose();
 	return changed;
 }
 boolean updateTabHeight(boolean force){
-	int style = getStyle();
-	if (fixedTabHeight == 0 && (style & SWT.FLAT) != 0 && (style & SWT.BORDER) == 0) highlight_header = 0;		
 	int oldHeight = tabHeight;
-	if (fixedTabHeight != SWT.DEFAULT) {
-		tabHeight = fixedTabHeight == 0 ? 0 : fixedTabHeight + 1; // +1 for line drawn across top of tab
-	} else {
-		int tempHeight = 0;
-		GC gc = new GC(this);
-		if (items.length == 0) {
-			tempHeight = gc.textExtent("Default", CTabItem.FLAGS).y + CTabItem.TOP_MARGIN + CTabItem.BOTTOM_MARGIN; //$NON-NLS-1$
-		} else {
-			for (int i=0; i < items.length; i++) {
-				tempHeight = Math.max(tempHeight, items[i].preferredHeight(gc));
-			}
-		}
-		gc.dispose();
-		tabHeight =  tempHeight;
-	}
+	GC gc = new GC(this);
+	tabHeight = renderer.computeSize(CTabFolderRenderer.PART_HEADER, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT).y;
+	gc.dispose();
 	if (!force && tabHeight == oldHeight) return false;
-	
 	oldSize = null;
-	if (onBottom) {
-		int d = tabHeight - 12;
-		curve = new int[]{0,13+d, 0,12+d, 2,12+d, 3,11+d, 5,11+d, 6,10+d, 7,10+d, 9,8+d, 10,8+d,
-				          11,7+d, 11+d,7,
-						  12+d,6, 13+d,6, 15+d,4, 16+d,4, 17+d,3, 19+d,3, 20+d,2, 22+d,2, 23+d,1}; 
-		curveWidth = 26+d;
-		curveIndent = curveWidth/3;	
-	} else {
-		int d = tabHeight - 12;
-		curve = new int[]{0,0, 0,1, 2,1, 3,2, 5,2, 6,3, 7,3, 9,5, 10,5,
-				          11,6, 11+d,6+d,
-				          12+d,7+d, 13+d,7+d, 15+d,9+d, 16+d,9+d, 17+d,10+d, 19+d,10+d, 20+d,11+d, 22+d,11+d, 23+d,12+d};
-		curveWidth = 26+d;
-		curveIndent = curveWidth/3;
-		
-		//this could be static but since values depend on curve, better to keep in one place
-		topCurveHighlightStart = new int[] { 
-				0, 2,  1, 2,  2, 2,    
-				3, 3,  4, 3,  5, 3, 
-				6, 4,  7, 4,
-				8, 5, 
-				9, 6, 10, 6};
-		
-		//also, by adding in 'd' here we save some math cost when drawing the curve
-		topCurveHighlightEnd = new int[] { 
-				10+d, 6+d,
-				11+d, 7+d,
-				12+d, 8+d,  13+d, 8+d,
-				14+d, 9+d,
-				15+d, 10+d,  16+d, 10+d,
-				17+d, 11+d,  18+d, 11+d,  19+d, 11+d,
-				20+d, 12+d,  21+d, 12+d,  22+d,  12+d }; 
-	}
 	notifyListeners(SWT.Resize, new Event());
 	return true;
 }
diff --git a/org/eclipse/swt/custom/CTabFolderLayout.java b/org/eclipse/swt/custom/CTabFolderLayout.java
index e01fac6..a9fbf02 100644
--- a/org/eclipse/swt/custom/CTabFolderLayout.java
+++ b/org/eclipse/swt/custom/CTabFolderLayout.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -23,26 +23,32 @@ class CTabFolderLayout extends Layout {
 protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) {
 	CTabFolder folder = (CTabFolder)composite;
 	CTabItem[] items = folder.items;
+	CTabFolderRenderer renderer = folder.renderer;
 	// preferred width of tab area to show all tabs
 	int tabW = 0;
+	int selectedIndex = folder.selectedIndex;
+	if (selectedIndex == -1) selectedIndex = 0;
 	GC gc = new GC(folder);
 	for (int i = 0; i < items.length; i++) {
 		if (folder.single) {
-			tabW = Math.max(tabW, items[i].preferredWidth(gc, true, false));
+			tabW = Math.max(tabW, renderer.computeSize(i, SWT.SELECTED, gc, SWT.DEFAULT, SWT.DEFAULT).x);
 		} else {
-			tabW += items[i].preferredWidth(gc, i == folder.selectedIndex, false);
+			int state = 0;
+			if (i == selectedIndex) state |= SWT.SELECTED;
+			tabW += renderer.computeSize(i, state, gc, SWT.DEFAULT, SWT.DEFAULT).x;
 		}
 	}
-	gc.dispose();
 	tabW += 3;
-	if (folder.showMax) tabW += CTabFolder.BUTTON_SIZE;
-	if (folder.showMin) tabW += CTabFolder.BUTTON_SIZE;
-	if (folder.single) tabW += 3*CTabFolder.BUTTON_SIZE/2; //chevron
+	
+	if (folder.showMax) tabW += renderer.computeSize(CTabFolderRenderer.PART_MAX_BUTTON, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT).x;
+	if (folder.showMin) tabW += renderer.computeSize(CTabFolderRenderer.PART_MIN_BUTTON, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT).x;
+	if (folder.single) tabW += renderer.computeSize(CTabFolderRenderer.PART_CHEVRON_BUTTON, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT).x;
 	if (folder.topRight != null) {
 		Point pt = folder.topRight.computeSize(SWT.DEFAULT, folder.tabHeight, flushCache);
 		tabW += 3 + pt.x;
 	}
-	if (!folder.single && !folder.simple) tabW += folder.curveWidth - 2*folder.curveIndent;
+
+	gc.dispose();
 	
 	int controlW = 0;
 	int controlH = 0;
diff --git a/org/eclipse/swt/custom/CTabFolderRenderer.java b/org/eclipse/swt/custom/CTabFolderRenderer.java
new file mode 100644
index 0000000..1a05182
--- /dev/null
+++ b/org/eclipse/swt/custom/CTabFolderRenderer.java
@@ -0,0 +1,1755 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2010 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.custom;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.*;
+
+/**
+ * Instances of this class provide all of the measuring and drawing functionality 
+ * required by <code>CTabFolder</code>. This class can be subclassed in order to
+ * customize the look of a CTabFolder.
+ *
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
+ * @since 3.6
+ */
+public class CTabFolderRenderer {
+	
+	protected CTabFolder parent;
+	
+	int[] curve;
+	int[] topCurveHighlightStart;
+	int[] topCurveHighlightEnd;
+	int curveWidth = 0;
+	int curveIndent = 0;
+	int lastTabHeight = -1;
+	
+	Color fillColor;
+	/* Selected item appearance */
+	Color selectionHighlightGradientBegin = null;  //null == no highlight
+	//Although we are given new colours all the time to show different states (active, etc),
+	//some of which may have a highlight and some not, we'd like to retain the highlight colours
+	//as a cache so that we can reuse them if we're again told to show the highlight.
+	//We are relying on the fact that only one tab state usually gets a highlight, so only
+	//a single cache is required. If that happens to not be true, cache simply becomes less effective,
+	//but we don't leak colours.
+	Color[] selectionHighlightGradientColorsCache = null;  //null is a legal value, check on access
+	/* Colors for anti-aliasing */
+	Color selectedOuterColor = null;
+	Color selectedInnerColor = null;
+	Color tabAreaColor = null;
+	/* 
+	 * Border color that was used in computing the cached anti-alias Colors.
+	 * We have to recompute the colors if the border color changes
+	 */
+	Color lastBorderColor = null;
+	
+	//TOP_LEFT_CORNER_HILITE is laid out in reverse (ie. top to bottom)
+	//so can fade in same direction as right swoop curve
+	static final int[] TOP_LEFT_CORNER_HILITE = new int[] {5,2, 4,2, 3,3, 2,4, 2,5, 1,6};
+
+	static final int[] TOP_LEFT_CORNER = new int[] {0,6, 1,5, 1,4, 4,1, 5,1, 6,0};
+	static final int[] TOP_RIGHT_CORNER = new int[] {-6,0, -5,1, -4,1, -1,4, -1,5, 0,6};
+	static final int[] BOTTOM_LEFT_CORNER = new int[] {0,-6, 1,-5, 1,-4, 4,-1, 5,-1, 6,0};
+	static final int[] BOTTOM_RIGHT_CORNER = new int[] {-6,0, -5,-1, -4,-1, -1,-4, -1,-5, 0,-6};
+
+	static final int[] SIMPLE_TOP_LEFT_CORNER = new int[] {0,2, 1,1, 2,0};
+	static final int[] SIMPLE_TOP_RIGHT_CORNER = new int[] {-2,0, -1,1, 0,2};
+	static final int[] SIMPLE_BOTTOM_LEFT_CORNER = new int[] {0,-2, 1,-1, 2,0};
+	static final int[] SIMPLE_BOTTOM_RIGHT_CORNER = new int[] {-2,0, -1,-1, 0,-2};
+	static final int[] SIMPLE_UNSELECTED_INNER_CORNER = new int[] {0,0};
+
+	static final int[] TOP_LEFT_CORNER_BORDERLESS = new int[] {0,6, 1,5, 1,4, 4,1, 5,1, 6,0};
+	static final int[] TOP_RIGHT_CORNER_BORDERLESS = new int[] {-7,0, -6,1, -5,1, -2,4, -2,5, -1,6};
+	static final int[] BOTTOM_LEFT_CORNER_BORDERLESS = new int[] {0,-6, 1,-6, 1,-5, 2,-4, 4,-2, 5,-1, 6,-1, 6,0};
+	static final int[] BOTTOM_RIGHT_CORNER_BORDERLESS = new int[] {-7,0, -7,-1, -6,-1, -5,-2, -3,-4, -2,-5, -2,-6, -1,-6};
+
+	static final int[] SIMPLE_TOP_LEFT_CORNER_BORDERLESS = new int[] {0,2, 1,1, 2,0};
+	static final int[] SIMPLE_TOP_RIGHT_CORNER_BORDERLESS= new int[] {-3,0, -2,1, -1,2};
+	static final int[] SIMPLE_BOTTOM_LEFT_CORNER_BORDERLESS = new int[] {0,-3, 1,-2, 2,-1, 3,0};
+	static final int[] SIMPLE_BOTTOM_RIGHT_CORNER_BORDERLESS = new int[] {-4,0, -3,-1, -2,-2, -1,-3};
+	
+	static final RGB CLOSE_FILL = new RGB(252, 160, 160);
+	
+	static final int BUTTON_SIZE = 18;
+	
+	static final int BUTTON_BORDER = SWT.COLOR_WIDGET_DARK_SHADOW;
+	static final int BUTTON_FILL = SWT.COLOR_LIST_BACKGROUND;
+	static final int BORDER1_COLOR = SWT.COLOR_WIDGET_NORMAL_SHADOW;
+	
+	static final int ITEM_TOP_MARGIN = 2;
+	static final int ITEM_BOTTOM_MARGIN = 2;
+	static final int ITEM_LEFT_MARGIN = 4;
+	static final int ITEM_RIGHT_MARGIN = 4;
+	static final int INTERNAL_SPACING = 4;
+	static final int FLAGS = SWT.DRAW_TRANSPARENT | SWT.DRAW_MNEMONIC;
+	static final String ELLIPSIS = "..."; //$NON-NLS-1$ 
+	
+	//Part constants
+	public static final int PART_BODY = -1;
+	public static final int PART_HEADER = -2;
+	public static final int PART_BORDER = -3;
+	public static final int PART_BACKGROUND = -4;
+	public static final int PART_MAX_BUTTON = -5;
+	public static final int PART_MIN_BUTTON = -6;
+	public static final int PART_CHEVRON_BUTTON = -7;
+	public static final int PART_CLOSE_BUTTON = -8;
+
+	public static final int MINIMUM_SIZE = 1 << 24; //TODO: Should this be a state?
+
+
+	/**
+	 * Constructs a new instance of this class given its parent.
+	 * 
+	 * @param parent CTabFolder
+	 *
+	 * @exception IllegalArgumentException <ul>
+	 *    <li>ERROR_INVALID_ARGUMENT - if the parent is disposed</li>
+	 * </ul>
+	 * 
+	 * @see Widget#getStyle
+	 */
+	protected CTabFolderRenderer(CTabFolder parent) {
+		if (parent == null) return;
+		if (parent.isDisposed ()) SWT.error (SWT.ERROR_INVALID_ARGUMENT);
+		this.parent = parent;
+	}
+	
+	void antialias (int[] shape, Color innerColor, Color outerColor, GC gc){
+		// Don't perform anti-aliasing on Mac and WPF because the platform
+		// already does it.  The simple style also does not require anti-aliasing.
+		if (parent.simple) return;
+		String platform = SWT.getPlatform();
+		if ("cocoa".equals(platform)) return; //$NON-NLS-1$
+		if ("carbon".equals(platform)) return; //$NON-NLS-1$
+		if ("wpf".equals(platform)) return; //$NON-NLS-1$
+		// Don't perform anti-aliasing on low resolution displays
+		if (parent.getDisplay().getDepth() < 15) return;
+		if (outerColor != null) {
+			int index = 0;
+			boolean left = true;
+			int oldY = parent.onBottom ? 0 : parent.getSize().y;
+			int[] outer = new int[shape.length];
+			for (int i = 0; i < shape.length/2; i++) {
+				if (left && (index + 3 < shape.length)) {
+					left = parent.onBottom ? oldY <= shape[index+3] : oldY >= shape[index+3];
+					oldY = shape[index+1];
+				}
+				outer[index] = shape[index++] + (left ? -1 : +1);
+				outer[index] = shape[index++];
+			}
+			gc.setForeground(outerColor);
+			gc.drawPolyline(outer);
+		}
+		if (innerColor != null) {
+			int[] inner = new int[shape.length];
+			int index = 0;
+			boolean left = true;
+			int oldY = parent.onBottom ? 0 : parent.getSize().y;
+			for (int i = 0; i < shape.length/2; i++) {
+				if (left && (index + 3 < shape.length)) {
+					left = parent.onBottom ? oldY <= shape[index+3] : oldY >= shape[index+3];
+					oldY = shape[index+1];
+				}
+				inner[index] = shape[index++] + (left ? +1 : -1);
+				inner[index] = shape[index++];
+			}
+			gc.setForeground(innerColor);
+			gc.drawPolyline(inner);
+		}
+	}
+
+	/**
+	 * Returns the preferred size of a part.
+	 * <p>
+	 * The <em>preferred size</em> of a part is the size that it would
+	 * best be displayed at. The width hint and height hint arguments
+	 * allow the caller to ask a control questions such as "Given a particular
+	 * width, how high does the part need to be to show all of the contents?"
+	 * To indicate that the caller does not wish to constrain a particular 
+	 * dimension, the constant <code>SWT.DEFAULT</code> is passed for the hint. 
+	 * </p><p>
+	 * The <code>part</code> value indicated what component the preferred size is 
+	 * to be calculated for. Valid values are any of the part constants:
+	 * <ul> 
+	 * <li>PART_BODY</li>
+	 * <li>PART_HEADER</li> 
+	 * <li>PART_BORDER</li>
+	 * <li>PART_BACKGROUND</li> 
+	 * <li>PART_MAX_BUTTON</li> 
+	 * <li>PART_MIN_BUTTON</li> 
+	 * <li>PART_CHEVRON_BUTTON</li>
+	 * <li>PART_CLOSE_BUTTON</li> 
+	 * <li>A positive integer which is the index of an item in the CTabFolder.</li>
+	 * </ul>
+	 * </p>
+	 * <p>
+	 * The <code>state</code> parameter may be one of the following: 
+	 * <ul>
+	 * <li>SWT.NONE</li>
+	 * <li>SWT.SELECTED - whether the part is selected</li>
+	 * </ul>
+	 * </p>
+	 * @param part a part constant 
+	 * @param state current state 
+	 * @param gc the gc to use for measuring
+	 * @param wHint the width hint (can be <code>SWT.DEFAULT</code>)
+	 * @param hHint the height hint (can be <code>SWT.DEFAULT</code>)
+	 * @return the preferred size of the part
+	 * 
+	 * @since 3.6
+	 */
+	protected Point computeSize (int part, int state, GC gc, int wHint, int hHint) {
+		int width = 0, height = 0; 
+		switch (part) {
+			case PART_HEADER:
+				if (parent.fixedTabHeight != SWT.DEFAULT) {
+					height = parent.fixedTabHeight == 0 ? 0 : parent.fixedTabHeight + 1; // +1 for line drawn across top of tab
+				} else {
+					CTabItem[] items = parent.items;
+					if (items.length == 0) {
+						height = gc.textExtent("Default", FLAGS).y + ITEM_TOP_MARGIN + ITEM_BOTTOM_MARGIN; //$NON-NLS-1$
+					} else {
+						for (int i=0; i < items.length; i++) {
+							height = Math.max(height, computeSize(i, SWT.NONE, gc, wHint, hHint).y);
+						}
+					}
+					gc.dispose();
+				}
+				break;
+			case PART_MAX_BUTTON:
+			case PART_MIN_BUTTON:
+			case PART_CLOSE_BUTTON:
+				width = height = BUTTON_SIZE;
+				break;
+			case PART_CHEVRON_BUTTON:
+				width = 3*BUTTON_SIZE/2;
+				height = BUTTON_SIZE;
+				break;
+			default:
+				if (0 <= part && part < parent.getItemCount()) {
+					updateCurves();
+					CTabItem item = parent.items[part]; 
+					if (item.isDisposed()) return new Point(0,0);
+					Image image = item.getImage();
+					if (image != null) { 
+						Rectangle bounds = image.getBounds();
+						if ((state & SWT.SELECTED) != 0 || parent.showUnselectedImage) {
+							width += bounds.width;
+						}
+						height =  bounds.height;
+					}
+					String text = null;
+					if ((state & MINIMUM_SIZE) != 0) {
+						int minChars = parent.minChars;
+						text = minChars == 0 ? null : item.getText();
+						if (text != null && text.length() > minChars) {
+							if (useEllipses()) {
+								int end = minChars < ELLIPSIS.length() + 1 ? minChars : minChars - ELLIPSIS.length();
+								text = text.substring(0, end);
+								if (minChars > ELLIPSIS.length() + 1) text += ELLIPSIS;
+							} else {
+								int end = minChars;
+								text = text.substring(0, end);
+							}
+						}
+					} else {
+						text = item.getText();
+					}
+					if (text != null) {
+						if (width > 0) width += INTERNAL_SPACING;
+						if (item.font == null) {
+							Point size = gc.textExtent(text, FLAGS);
+							width += size.x;
+							height = Math.max(height, size.y);
+						} else {
+							Font gcFont = gc.getFont();
+							gc.setFont(item.font);
+							Point size = gc.textExtent(text, FLAGS);
+							width += size.x;
+							height = Math.max(height, size.y);
+							gc.setFont(gcFont);
+						}
+					}
+					if (parent.showClose || item.showClose) {
+						if ((state & SWT.SELECTED) != 0 || parent.showUnselectedClose) {
+							if (width > 0) width += INTERNAL_SPACING;
+							width += computeSize(PART_CLOSE_BUTTON, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT).x;
+						}
+					}	
+				}
+				break;
+		}
+		Rectangle trim = computeTrim(part, state, 0, 0, width, height);
+		width = trim.width;
+		height = trim.height;
+		return new Point(width, height);
+	}
+
+	/**
+	 * Given a desired <em>client area</em> for the part
+	 * (as described by the arguments), returns the bounding
+	 * rectangle which would be required to produce that client
+	 * area.
+	 * <p>
+	 * In other words, it returns a rectangle such that, if the
+	 * part's bounds were set to that rectangle, the area
+	 * of the part which is capable of displaying data
+	 * (that is, not covered by the "trimmings") would be the
+	 * rectangle described by the arguments (relative to the
+	 * receiver's parent).
+	 * </p>
+	 * 
+	 * @param part one of the part constants 
+	 * @param state the state of the part
+	 * @param x the desired x coordinate of the client area
+	 * @param y the desired y coordinate of the client area
+	 * @param width the desired width of the client area
+	 * @param height the desired height of the client area
+	 * @return the required bounds to produce the given client area
+	 *
+	 * @see CTabFolderRenderer#computeSize(int, int, GC, int, int) valid part and state values
+	 *  
+	 * @since 3.6
+	 */
+	protected Rectangle computeTrim (int part, int state, int x, int y, int width, int height) {
+		int borderLeft = parent.borderVisible ? 1 : 0;
+		int borderRight = borderLeft;
+		int borderTop = parent.onBottom ? borderLeft : 0;
+		int borderBottom = parent.onBottom ? 0 : borderLeft;
+		int tabHeight = parent.tabHeight;
+		switch (part) {
+			case PART_BODY:
+				int style = parent.getStyle();
+				int highlight_header = (style & SWT.FLAT) != 0 ? 1 : 3;
+				int highlight_margin = (style & SWT.FLAT) != 0 ? 0 : 2;
+				if (parent.fixedTabHeight == 0 && (style & SWT.FLAT) != 0 && (style & SWT.BORDER) == 0) {
+					highlight_header = 0;	
+				}
+				int marginWidth = parent.marginWidth;
+				int marginHeight = parent.marginHeight;
+				x = x - marginWidth - highlight_margin - borderLeft;
+				width = width + borderLeft + borderRight + 2*marginWidth + 2*highlight_margin;
+				if (parent.minimized) {
+					y = parent.onBottom ? y - borderTop : y - highlight_header - tabHeight - borderTop;
+					height = borderTop + borderBottom + tabHeight + highlight_header;
+				} else {
+					y = parent.onBottom ? y - marginHeight - highlight_margin - borderTop: y - marginHeight - highlight_header - tabHeight - borderTop;
+					height = height + borderTop + borderBottom + 2*marginHeight + tabHeight + highlight_header + highlight_margin;
+				}
+				break;
+			case PART_HEADER:
+				//no trim 
+				break;
+			case PART_BORDER:
+				x = x - borderLeft;
+				width = width + borderLeft + borderRight; 
+				y = y - borderTop;
+				height = height + borderTop + borderBottom;
+				break;
+			default:
+				if (0 <= part && part < parent.getItemCount()) {
+					updateCurves();
+					x = x - ITEM_LEFT_MARGIN;
+					width = width + ITEM_LEFT_MARGIN + ITEM_RIGHT_MARGIN;
+					if (!parent.simple && !parent.single && (state & SWT.SELECTED) != 0) {
+						width += curveWidth - curveIndent;
+					}
+					y = y - ITEM_TOP_MARGIN;
+					height = height + ITEM_TOP_MARGIN + ITEM_BOTTOM_MARGIN;
+				}
+				break;
+		}
+		return new Rectangle(x, y, width, height);
+	}
+	
+	void createAntialiasColors() {
+	    disposeAntialiasColors();
+	    lastBorderColor = parent.getDisplay().getSystemColor(BORDER1_COLOR);
+	    RGB lineRGB = lastBorderColor.getRGB();
+	    /* compute the selected color */
+	    RGB innerRGB = parent.selectionBackground.getRGB();
+	    if (parent.selectionBgImage != null || 
+		    (parent.selectionGradientColors != null && parent.selectionGradientColors.length > 1)) {
+		    innerRGB = null;
+	    }
+	    RGB outerRGB = parent.getBackground().getRGB();		
+	    if (parent.gradientColors != null && parent.gradientColors.length > 1) {
+		    outerRGB = null;
+	    }
+	    if (outerRGB != null) {
+			RGB from = lineRGB;
+			RGB to = outerRGB;
+			int red = from.red + 2*(to.red - from.red)/3;
+			int green = from.green + 2*(to.green - from.green)/3;
+			int blue = from.blue + 2*(to.blue - from.blue)/3;
+			selectedOuterColor = new Color(parent.getDisplay(), red, green, blue);
+	    }
+	    if (innerRGB != null) {
+			RGB from = lineRGB;
+			RGB to = innerRGB;
+			int red = from.red + 2*(to.red - from.red)/3;
+			int green = from.green + 2*(to.green - from.green)/3;
+			int blue = from.blue + 2*(to.blue - from.blue)/3;
+			selectedInnerColor = new Color(parent.getDisplay(), red, green, blue);
+	    }
+	    /* compute the tabArea color */
+	    outerRGB = parent.getParent().getBackground().getRGB();
+	    if (outerRGB != null) {
+			RGB from = lineRGB;
+			RGB to = outerRGB;
+			int red = from.red + 2*(to.red - from.red)/3;
+			int green = from.green + 2*(to.green - from.green)/3;
+			int blue = from.blue + 2*(to.blue - from.blue)/3;
+			tabAreaColor = new Color(parent.getDisplay(), red, green, blue);
+	    }
+	}
+
+	/*
+	 * Allocate colors for the highlight line.
+	 * Colours will be a gradual blend ranging from to.
+	 * Blend length will be tab height.
+	 * Recompute this if tab height changes.
+	 * Could remain null if there'd be no gradient (start=end or low colour display)
+	 */
+	void createSelectionHighlightGradientColors(Color start) {
+		disposeSelectionHighlightGradientColors(); //dispose if existing
+
+		if(start == null)  //shouldn't happen but just to be safe
+			return;
+
+		//alloc colours for entire height to ensure it matches wherever we stop drawing
+		int fadeGradientSize = parent.tabHeight;
+
+		RGB from = start.getRGB();
+		RGB to = parent.selectionBackground.getRGB();
+
+		selectionHighlightGradientColorsCache = new Color[fadeGradientSize];
+		int denom = fadeGradientSize - 1;
+
+		for (int i = 0; i < fadeGradientSize; i++) {
+			int propFrom = denom - i;
+			int propTo = i;
+			int red = (to.red * propTo + from.red * propFrom) / denom;
+			int green = (to.green * propTo  + from.green * propFrom) / denom;
+			int blue = (to.blue * propTo  + from.blue * propFrom) / denom;
+			selectionHighlightGradientColorsCache[i] = new Color(parent.getDisplay(), red, green, blue);
+		}
+	}
+	
+	/**
+	 * Dispose of any operating system resources associated with
+	 * the renderer. Called by the CTabFolder parent upon receiving
+	 * the dispose event or when changing the renderer.
+	 * 
+	 * @since 3.6
+	 */
+	protected void dispose() {
+		disposeAntialiasColors();
+		disposeSelectionHighlightGradientColors();
+		if (fillColor != null) {
+		    fillColor.dispose();
+		    fillColor = null;
+		}
+	}
+	
+	void disposeAntialiasColors() {
+	    if (tabAreaColor != null) tabAreaColor.dispose();
+	    if (selectedInnerColor != null) selectedInnerColor.dispose();
+	    if (selectedOuterColor != null) selectedOuterColor.dispose();
+	    tabAreaColor = selectedInnerColor = selectedOuterColor = null;
+	}
+
+	void disposeSelectionHighlightGradientColors() {
+		if(selectionHighlightGradientColorsCache == null)
+			return;
+		for (int i = 0; i < selectionHighlightGradientColorsCache.length; i++) {
+			selectionHighlightGradientColorsCache[i].dispose();
+		}
+		selectionHighlightGradientColorsCache = null;
+	}
+	
+	/**
+	 * Draw a specified <code>part</code> of the CTabFolder using the provided <code>bounds</code> and <code>GC</code>. 
+	 * <p>The valid CTabFolder <code>part</code> constants are:
+	 * <ul>
+	 * <li>PART_BODY - the entire body of the CTabFolder</li>
+	 * <li>PART_HEADER - the upper tab area of the CTabFolder</li>
+	 * <li>PART_BORDER - the border of the CTabFolder</li>
+	 * <li>PART_BACKGROUND - the background of the CTabFolder</li>
+	 * <li>PART_MAX_BUTTON</li> 
+	 * <li>PART_MIN_BUTTON</li>
+	 * <li>PART_CHEVRON_BUTTON</li>
+	 * <li>PART_CLOSE_BUTTON</li>
+	 * <li>A positive integer which is the index of an item in the CTabFolder.</li>
+	 * </ul>
+	 * </p>
+	 * <p>
+	 * The <code>state</code> parameter may be a combination of: 
+	 * <ul>
+	 * <li>SWT.BACKGROUND - whether the background should be drawn</li>
+	 * <li>SWT.FOREGROUND - whether the foreground should be drawn</li>
+	 * <li>SWT.SELECTED - whether the part is selected</li>
+	 * <li>SWT.HOT - whether the part is hot (i.e. mouse is over the part)</li>
+	 * </ul>
+	 * </p>
+	 * 
+	 * @param part part to draw 
+	 * @param state state of the part 
+	 * @param bounds the bounds of the part
+	 * @param gc the gc to draw the part on
+	 * 
+	 * @since 3.6
+	 */
+	protected void draw (int part, int state, Rectangle bounds, GC gc) {
+		switch (part) {
+			case PART_BACKGROUND:
+				this.drawBackground(gc, bounds, state);
+				break;
+			case PART_BODY:
+				drawBody(gc, bounds, state);
+				break;
+			case PART_HEADER:
+				drawTabArea(gc, bounds, state);
+				break;
+			case PART_MAX_BUTTON:
+				drawMaximize(gc, bounds, state);
+				break;
+			case PART_MIN_BUTTON:
+				drawMinimize(gc, bounds, state);
+				break;
+			case PART_CHEVRON_BUTTON:
+				drawChevron(gc, bounds, state);
+				break;
+			default:
+				if (0 <= part && part < parent.getItemCount()) {
+					if (bounds.width == 0 || bounds.height == 0) return;
+					if ((state & SWT.SELECTED) != 0 ) {
+						drawSelected(part, gc, bounds, state);
+					} else {
+						drawUnselected(part, gc, bounds, state);
+					}
+				}
+				break;
+		}
+	}
+	
+	void drawBackground(GC gc, Rectangle bounds, int state) {
+		boolean selected = (state & SWT.SELECTED) != 0;
+		Color defaultBackground = selected ? parent.selectionBackground : parent.getBackground();
+		Image image = selected ? parent.selectionBgImage : null;
+		Color[] colors = selected ? parent.selectionGradientColors : parent.gradientColors;
+		int[] percents = selected ? parent.selectionGradientPercents : parent.gradientPercents;
+		boolean vertical = selected ? parent.selectionGradientVertical : parent.gradientVertical; 
+		
+		drawBackground(gc, null, bounds.x, bounds.y, bounds.width, bounds.height, defaultBackground, image, colors, percents, vertical);
+	}
+	
+	void drawBackground(GC gc, int[] shape, boolean selected) {
+		Color defaultBackground = selected ? parent.selectionBackground : parent.getBackground();
+		Image image = selected ? parent.selectionBgImage : null;
+		Color[] colors = selected ? parent.selectionGradientColors : parent.gradientColors;
+		int[] percents = selected ? parent.selectionGradientPercents : parent.gradientPercents;
+		boolean vertical = selected ? parent.selectionGradientVertical : parent.gradientVertical; 
+		Point size = parent.getSize();
+		int width = size.x;
+		int height = parent.tabHeight + ((parent.getStyle() & SWT.FLAT) != 0 ? 1 : 3);
+		int x = 0;
+
+		int borderLeft = parent.borderVisible ? 1 : 0;
+		int borderTop = parent.onBottom ? borderLeft : 0;
+		int borderBottom = parent.onBottom ? 0 : borderLeft;
+		
+		if (borderLeft > 0) {
+			x += 1; width -= 2;
+		}
+		int y = parent.onBottom ? size.y - borderBottom - height : borderTop;
+		drawBackground(gc, shape, x, y, width, height, defaultBackground, image, colors, percents, vertical);
+	}
+	
+	void drawBackground(GC gc, int[] shape, int x, int y, int width, int height, Color defaultBackground, Image image, Color[] colors, int[] percents, boolean vertical) {
+		Region clipping = null, region = null;
+		if (shape != null) { 
+			clipping = new Region();
+			gc.getClipping(clipping);
+			region = new Region();
+			region.add(shape);
+			region.intersect(clipping);
+			gc.setClipping(region);
+		}
+		if (image != null) {
+			// draw the background image in shape
+			gc.setBackground(defaultBackground);
+			gc.fillRectangle(x, y, width, height);
+			Rectangle imageRect = image.getBounds();
+			gc.drawImage(image, imageRect.x, imageRect.y, imageRect.width, imageRect.height, x, y, width, height);
+		} else if (colors != null) {
+			// draw gradient
+			if (colors.length == 1) {
+				Color background = colors[0] != null ? colors[0] : defaultBackground;
+				gc.setBackground(background);
+				gc.fillRectangle(x, y, width, height);
+			} else {
+				if (vertical) {
+					if (parent.onBottom) {
+						int pos = 0;
+						if (percents[percents.length - 1] < 100) {
+							pos = (100 - percents[percents.length - 1]) * height / 100;
+							gc.setBackground(defaultBackground);
+							gc.fillRectangle(x, y, width, pos);
+						}
+						Color lastColor = colors[colors.length-1];
+						if (lastColor == null) lastColor = defaultBackground;
+						for (int i = percents.length-1; i >= 0; i--) {
+							gc.setForeground(lastColor);
+							lastColor = colors[i];
+							if (lastColor == null) lastColor = defaultBackground;
+							gc.setBackground(lastColor);
+							int percentage = i > 0 ? percents[i] - percents[i-1] : percents[i];
+							int gradientHeight = percentage * height / 100;
+							gc.fillGradientRectangle(x, y+pos, width, gradientHeight, true);
+							pos += gradientHeight;
+						}
+					} else {
+						Color lastColor = colors[0];
+						if (lastColor == null) lastColor = defaultBackground;
+						int pos = 0;
+						for (int i = 0; i < percents.length; i++) {
+							gc.setForeground(lastColor);
+							lastColor = colors[i + 1];
+							if (lastColor == null) lastColor = defaultBackground;
+							gc.setBackground(lastColor);
+							int percentage = i > 0 ? percents[i] - percents[i-1] : percents[i];
+							int gradientHeight = percentage * height / 100;
+							gc.fillGradientRectangle(x, y+pos, width, gradientHeight, true);
+							pos += gradientHeight;
+						}
+						if (pos < height) {
+							gc.setBackground(defaultBackground);
+							gc.fillRectangle(x, pos, width, height-pos+1);
+						}
+					}
+				} else { //horizontal gradient
+					y = 0;
+					height = parent.getSize().y;
+					Color lastColor = colors[0];
+					if (lastColor == null) lastColor = defaultBackground;
+					int pos = 0;
+					for (int i = 0; i < percents.length; ++i) {
+						gc.setForeground(lastColor);
+						lastColor = colors[i + 1];
+						if (lastColor == null) lastColor = defaultBackground;
+						gc.setBackground(lastColor);
+						int gradientWidth = (percents[i] * width / 100) - pos;
+						gc.fillGradientRectangle(x+pos, y, gradientWidth, height, false);
+						pos += gradientWidth;
+					}
+					if (pos < width) {
+						gc.setBackground(defaultBackground);
+						gc.fillRectangle(x+pos, y, width-pos, height);
+					}
+				}
+			}
+		} else {
+			// draw a solid background using default background in shape
+			if ((parent.getStyle() & SWT.NO_BACKGROUND) != 0 || !defaultBackground.equals(parent.getBackground())) {
+				gc.setBackground(defaultBackground);
+				gc.fillRectangle(x, y, width, height);
+			}
+		}
+		if (shape != null) {
+			gc.setClipping(clipping);
+			clipping.dispose();
+			region.dispose();
+		}
+	}
+	
+	/*
+	 * Draw the border of the tab
+	 * 
+	 * @param gc
+	 * @param shape
+	 */
+	void drawBorder(GC gc, int[] shape) {
+	
+		gc.setForeground(parent.getDisplay().getSystemColor(BORDER1_COLOR));
+		gc.drawPolyline(shape);
+	}
+
+	void drawBody(GC gc, Rectangle bounds, int state) {
+		Point size = new Point(bounds.width, bounds.height);
+		int selectedIndex = parent.selectedIndex;
+		int tabHeight = parent.tabHeight;
+		
+		int borderLeft = parent.borderVisible ? 1 : 0;
+		int borderRight = borderLeft;
+		int borderTop = parent.onBottom ? borderLeft : 0;
+		int borderBottom = parent.onBottom ? 0 : borderLeft;
+		
+		int style = parent.getStyle();
+		int highlight_header = (style & SWT.FLAT) != 0 ? 1 : 3;
+		int highlight_margin = (style & SWT.FLAT) != 0 ? 0 : 2;
+		
+		// fill in body
+		if (!parent.minimized){
+			int width = size.x  - borderLeft - borderRight - 2*highlight_margin;
+			int height = size.y - borderTop - borderBottom - tabHeight - highlight_header - highlight_margin;
+			// Draw highlight margin
+			if (highlight_margin > 0) {
+				int[] shape = null;
+				if (parent.onBottom) {
+					int x1 = borderLeft;
+					int y1 = borderTop;
+					int x2 = size.x - borderRight;
+					int y2 = size.y - borderBottom - tabHeight - highlight_header;
+					shape = new int[] {x1,y1, x2,y1, x2,y2, x2-highlight_margin,y2,
+							           x2-highlight_margin, y1+highlight_margin, x1+highlight_margin,y1+highlight_margin,
+									   x1+highlight_margin,y2, x1,y2};
+				} else {	
+					int x1 = borderLeft;
+					int y1 = borderTop + tabHeight + highlight_header;
+					int x2 = size.x - borderRight;
+					int y2 = size.y - borderBottom;
+					shape = new int[] {x1,y1, x1+highlight_margin,y1, x1+highlight_margin,y2-highlight_margin, 
+							           x2-highlight_margin,y2-highlight_margin, x2-highlight_margin,y1,
+									   x2,y1, x2,y2, x1,y2};
+				}
+				// If horizontal gradient, show gradient across the whole area
+				if (selectedIndex != -1 && parent.selectionGradientColors != null && parent.selectionGradientColors.length > 1 && !parent.selectionGradientVertical) {
+					drawBackground(gc, shape, true);
+				} else if (selectedIndex == -1 && parent.gradientColors != null && parent.gradientColors.length > 1 && !parent.gradientVertical) {
+					drawBackground(gc, shape, false);
+				} else {
+					gc.setBackground(selectedIndex == -1 ? parent.getBackground() : parent.selectionBackground);
+					gc.fillPolygon(shape);
+				}
+			}
+			//Draw client area
+			if ((parent.getStyle() & SWT.NO_BACKGROUND) != 0) {
+				gc.setBackground(parent.getBackground());
+				int marginWidth = parent.marginWidth;
+				int marginHeight = parent.marginHeight;
+				int xClient = borderLeft + marginWidth + highlight_margin, yClient;
+				if (parent.onBottom) {
+					yClient = borderTop + highlight_margin + marginHeight;
+				} else {
+					yClient = borderTop + tabHeight + highlight_header + marginHeight; 
+				}
+				gc.fillRectangle(xClient - marginWidth, yClient - marginHeight, width, height);
+			}
+		} else {
+			if ((parent.getStyle() & SWT.NO_BACKGROUND) != 0) {
+				int height = borderTop + tabHeight + highlight_header + borderBottom;
+				if (size.y > height) {
+					gc.setBackground(parent.getParent().getBackground());
+					gc.fillRectangle(0, height, size.x, size.y - height);
+				}
+			}
+		}
+		
+		//draw 1 pixel border around outside
+		if (borderLeft > 0) {
+			gc.setForeground(parent.getDisplay().getSystemColor(BORDER1_COLOR));
+			int x1 = borderLeft - 1;
+			int x2 = size.x - borderRight;
+			int y1 = parent.onBottom ? borderTop - 1 : borderTop + tabHeight;
+			int y2 = parent.onBottom ? size.y - tabHeight - borderBottom - 1 : size.y - borderBottom;
+			gc.drawLine(x1, y1, x1, y2); // left
+			gc.drawLine(x2, y1, x2, y2); // right
+			if (parent.onBottom) {
+				gc.drawLine(x1, y1, x2, y1); // top
+			} else {
+				gc.drawLine(x1, y2, x2, y2); // bottom
+			}
+		}
+	}
+	
+	void drawClose(GC gc, Rectangle closeRect, int closeImageState) {
+		if (closeRect.width == 0 || closeRect.height == 0) return;
+		Display display = parent.getDisplay();
+	
+		// draw X 9x9
+		int x = closeRect.x + Math.max(1, (closeRect.width-9)/2);
+		int y = closeRect.y + Math.max(1, (closeRect.height-9)/2);
+		y += parent.onBottom ? -1 : 1;
+		
+		Color closeBorder = display.getSystemColor(BUTTON_BORDER);
+		switch (closeImageState & (SWT.HOT | SWT.SELECTED | SWT.BACKGROUND)) {
+			case SWT.NONE: {
+				int[] shape = new int[] {x,y, x+2,y, x+4,y+2, x+5,y+2, x+7,y, x+9,y, 
+						                 x+9,y+2, x+7,y+4, x+7,y+5, x+9,y+7, x+9,y+9,
+				                         x+7,y+9, x+5,y+7, x+4,y+7, x+2,y+9, x,y+9,
+				                         x,y+7, x+2,y+5, x+2,y+4, x,y+2};
+				gc.setBackground(display.getSystemColor(BUTTON_FILL));
+				gc.fillPolygon(shape);
+				gc.setForeground(closeBorder);
+				gc.drawPolygon(shape);
+				break;
+			}
+			case SWT.HOT: {
+				int[] shape = new int[] {x,y, x+2,y, x+4,y+2, x+5,y+2, x+7,y, x+9,y, 
+						                 x+9,y+2, x+7,y+4, x+7,y+5, x+9,y+7, x+9,y+9,
+				                         x+7,y+9, x+5,y+7, x+4,y+7, x+2,y+9, x,y+9,
+				                         x,y+7, x+2,y+5, x+2,y+4, x,y+2};
+				gc.setBackground(getFillColor());
+				gc.fillPolygon(shape);
+				gc.setForeground(closeBorder);
+				gc.drawPolygon(shape);
+				break;
+			}
+			case SWT.SELECTED: {
+				int[] shape = new int[] {x+1,y+1, x+3,y+1, x+5,y+3, x+6,y+3, x+8,y+1, x+10,y+1, 
+						                 x+10,y+3, x+8,y+5, x+8,y+6, x+10,y+8, x+10,y+10,
+				                         x+8,y+10, x+6,y+8, x+5,y+8, x+3,y+10, x+1,y+10,
+				                         x+1,y+8, x+3,y+6, x+3,y+5, x+1,y+3};
+				gc.setBackground(getFillColor());
+				gc.fillPolygon(shape);
+				gc.setForeground(closeBorder);
+				gc.drawPolygon(shape);
+				break;
+			}
+			case SWT.BACKGROUND: {
+				int[] shape = new int[] {x,y, x+10,y, x+10,y+10, x,y+10};
+				drawBackground(gc, shape, false);
+				break;
+			}
+		}
+	}
+
+	void drawChevron(GC gc, Rectangle chevronRect, int chevronImageState) {
+		if (chevronRect.width == 0 || chevronRect.height == 0) return;
+		int selectedIndex = parent.selectedIndex;
+		// draw chevron (10x7)
+		Display display = parent.getDisplay();
+		Point dpi = display.getDPI();
+		int fontHeight = 72 * 10 / dpi.y;
+		FontData fd = parent.getFont().getFontData()[0];
+		fd.setHeight(fontHeight);
+		Font f = new Font(display, fd);
+		int fHeight = f.getFontData()[0].getHeight() * dpi.y / 72;
+		int indent = Math.max(2, (chevronRect.height - fHeight - 4) /2);
+		int x = chevronRect.x + 2;
+		int y = chevronRect.y + indent;
+		int count;
+		int itemCount = parent.getItemCount();
+		if (parent.single) {
+			count = selectedIndex == -1 ? itemCount : itemCount - 1;
+		} else {
+			int showCount = 0;
+			while (showCount < parent.priority.length && parent.items[parent.priority[showCount]].showing) {
+				showCount++;
+			}
+			count = itemCount - showCount;
+		}
+		String chevronString = count > 99 ? "99+" : String.valueOf(count); //$NON-NLS-1$
+		switch (chevronImageState & (SWT.HOT | SWT.SELECTED)) {
+			case SWT.NONE: {
+				Color chevronBorder = parent.single ? parent.getSelectionForeground() : parent.getForeground();
+				gc.setForeground(chevronBorder);
+				gc.setFont(f);
+				gc.drawLine(x,y,     x+2,y+2);
+				gc.drawLine(x+2,y+2, x,y+4);
+				gc.drawLine(x+1,y,   x+3,y+2);
+				gc.drawLine(x+3,y+2, x+1,y+4);
+				gc.drawLine(x+4,y,   x+6,y+2);
+				gc.drawLine(x+6,y+2, x+5,y+4);
+				gc.drawLine(x+5,y,   x+7,y+2);
+				gc.drawLine(x+7,y+2, x+4,y+4);
+				gc.drawString(chevronString, x+7, y+3, true);
+				break;
+			}
+			case SWT.HOT: {
+				gc.setForeground(display.getSystemColor(BUTTON_BORDER));
+				gc.setBackground(display.getSystemColor(BUTTON_FILL));
+				gc.setFont(f);
+				gc.fillRoundRectangle(chevronRect.x, chevronRect.y, chevronRect.width, chevronRect.height, 6, 6);
+				gc.drawRoundRectangle(chevronRect.x, chevronRect.y, chevronRect.width - 1, chevronRect.height - 1, 6, 6);
+				gc.drawLine(x,y,     x+2,y+2);
+				gc.drawLine(x+2,y+2, x,y+4);
+				gc.drawLine(x+1,y,   x+3,y+2);
+				gc.drawLine(x+3,y+2, x+1,y+4);
+				gc.drawLine(x+4,y,   x+6,y+2);
+				gc.drawLine(x+6,y+2, x+5,y+4);
+				gc.drawLine(x+5,y,   x+7,y+2);
+				gc.drawLine(x+7,y+2, x+4,y+4);
+				gc.drawString(chevronString, x+7, y+3, true);
+				break;
+			}
+			case SWT.SELECTED: {
+				gc.setForeground(display.getSystemColor(BUTTON_BORDER));
+				gc.setBackground(display.getSystemColor(BUTTON_FILL));
+				gc.setFont(f);
+				gc.fillRoundRectangle(chevronRect.x, chevronRect.y, chevronRect.width, chevronRect.height, 6, 6);
+				gc.drawRoundRectangle(chevronRect.x, chevronRect.y, chevronRect.width - 1, chevronRect.height - 1, 6, 6);
+				gc.drawLine(x+1,y+1, x+3,y+3);
+				gc.drawLine(x+3,y+3, x+1,y+5);
+				gc.drawLine(x+2,y+1, x+4,y+3);
+				gc.drawLine(x+4,y+3, x+2,y+5);
+				gc.drawLine(x+5,y+1, x+7,y+3);
+				gc.drawLine(x+7,y+3, x+6,y+5);
+				gc.drawLine(x+6,y+1, x+8,y+3);
+				gc.drawLine(x+8,y+3, x+5,y+5);
+				gc.drawString(chevronString, x+8, y+4, true);
+				break;
+			}
+		}
+		f.dispose();
+	}
+
+	/*
+	 * Draw a highlight effect along the left, top, and right edges of the tab.
+	 * Only for curved tabs, on top.
+	 * Do not draw if insufficient colors.
+	 */
+	void drawHighlight(GC gc, Rectangle bounds, int state, int rightEdge) {
+		//only draw for curvy tabs and only draw for top tabs
+		if(parent.simple || parent.onBottom)
+			return;
+		
+		if(selectionHighlightGradientBegin == null)
+			return;
+
+		Color[] gradients = selectionHighlightGradientColorsCache;
+		if(gradients == null)
+			return;
+		int gradientsSize = gradients.length;
+		if(gradientsSize == 0)
+			return;		//shouldn't happen but just to be tidy
+
+		int x = bounds.x;
+		int y = bounds.y;
+		
+		gc.setForeground(gradients[0]);
+		
+		//draw top horizontal line
+		gc.drawLine(
+				TOP_LEFT_CORNER_HILITE[0] + x + 1, //rely on fact that first pair is top/right of curve
+				1 + y,
+				rightEdge - curveIndent,
+				1 + y);
+		
+		int[] leftHighlightCurve = TOP_LEFT_CORNER_HILITE;
+
+		int d = parent.tabHeight - topCurveHighlightEnd.length /2;
+
+		int lastX = 0;
+		int lastY = 0;
+		int lastColorIndex = 0;
+		
+		//draw upper left curve highlight
+		for (int i = 0; i < leftHighlightCurve.length /2; i++) {
+			int rawX = leftHighlightCurve[i * 2];
+			int rawY = leftHighlightCurve[i * 2 + 1];
+			lastX = rawX + x;
+			lastY = rawY + y;
+			lastColorIndex = rawY - 1;
+			gc.setForeground(gradients[lastColorIndex]);
+			gc.drawPoint(lastX, lastY);
+		}
+		//draw left vertical line highlight
+		for(int i = lastColorIndex; i < gradientsSize; i++) {
+			gc.setForeground(gradients[i]);
+			gc.drawPoint(lastX, 1 + lastY++);
+		}
+		
+		int rightEdgeOffset = rightEdge - curveIndent;
+		
+		//draw right swoop highlight up to diagonal portion
+		for (int i = 0; i < topCurveHighlightStart.length /2; i++) {
+			int rawX = topCurveHighlightStart[i * 2];
+			int rawY = topCurveHighlightStart[i * 2 + 1];
+			lastX = rawX + rightEdgeOffset;
+			lastY = rawY + y;
+			lastColorIndex = rawY - 1;
+			if(lastColorIndex >= gradientsSize)
+				break;	//can happen if tabs are unusually short and cut off the curve
+			gc.setForeground(gradients[lastColorIndex]);
+			gc.drawPoint(lastX, lastY);
+		}
+		//draw right diagonal line highlight
+		for(int i = lastColorIndex; i < lastColorIndex + d; i++) {
+			if(i >= gradientsSize)
+				break;	//can happen if tabs are unusually short and cut off the curve
+			gc.setForeground(gradients[i]);
+			gc.drawPoint(1 + lastX++, 1 + lastY++);
+		}
+
+		//draw right swoop highlight from diagonal portion to end
+		for (int i = 0; i < topCurveHighlightEnd.length /2; i++) {
+			int rawX = topCurveHighlightEnd[i * 2]; //d is already encoded in this value
+			int rawY = topCurveHighlightEnd[i * 2 + 1]; //d already encoded
+			lastX = rawX + rightEdgeOffset;
+			lastY = rawY + y;
+			lastColorIndex = rawY - 1;
+			if(lastColorIndex >= gradientsSize)
+				break;	//can happen if tabs are unusually short and cut off the curve
+			gc.setForeground(gradients[lastColorIndex]);
+			gc.drawPoint(lastX, lastY);
+		}	
+	}
+
+	/*
+	 * Draw the unselected border for the receiver on the left.
+	 * 
+	 * @param gc
+	 */
+	void drawLeftUnselectedBorder(GC gc, Rectangle bounds, int state) {
+		int x = bounds.x;
+		int y = bounds.y;
+		int height = bounds.height;
+		
+		int[] shape = null;
+		if (parent.onBottom) {
+			int[] left = parent.simple
+				? SIMPLE_UNSELECTED_INNER_CORNER
+				: BOTTOM_LEFT_CORNER;
+			
+			shape = new int[left.length + 2];
+			int index = 0;
+			shape[index++] = x;
+			shape[index++] = y - 1;
+			for (int i = 0; i < left.length / 2; i++) {
+				shape[index++] = x + left[2 * i];
+				shape[index++] = y + height + left[2 * i + 1] - 1;
+			}
+		} else {
+			int[] left = parent.simple
+				? SIMPLE_UNSELECTED_INNER_CORNER
+				: TOP_LEFT_CORNER;
+
+			shape = new int[left.length + 2];
+			int index = 0;
+			shape[index++] = x;
+			shape[index++] = y + height;
+			for (int i = 0; i < left.length / 2; i++) {
+				shape[index++] = x + left[2 * i];
+				shape[index++] = y + left[2 * i + 1];
+			}
+
+		}
+
+		drawBorder(gc, shape);
+	}
+
+	void drawMaximize(GC gc, Rectangle maxRect, int maxImageState) {
+		if (maxRect.width == 0 || maxRect.height == 0) return;
+		Display display = parent.getDisplay();
+		// 5x4 or 7x9
+		int x = maxRect.x + (maxRect.width - 10)/2;
+		int y = maxRect.y + 3;
+		
+		gc.setForeground(display.getSystemColor(BUTTON_BORDER));
+		gc.setBackground(display.getSystemColor(BUTTON_FILL));
+		
+		switch (maxImageState & (SWT.HOT | SWT.SELECTED)) {
+			case SWT.NONE: {
+				if (!parent.getMaximized()) {
+					gc.fillRectangle(x, y, 9, 9);
+					gc.drawRectangle(x, y, 9, 9);
+					gc.drawLine(x+1, y+2, x+8, y+2);				
+				} else {
+					gc.fillRectangle(x, y+3, 5, 4);
+					gc.fillRectangle(x+2, y, 5, 4);
+					gc.drawRectangle(x, y+3, 5, 4);
+					gc.drawRectangle(x+2, y, 5, 4);
+					gc.drawLine(x+3, y+1, x+6, y+1);
+					gc.drawLine(x+1, y+4, x+4, y+4);
+				}
+				break;
+			}
+			case SWT.HOT: {
+				gc.fillRoundRectangle(maxRect.x, maxRect.y, maxRect.width, maxRect.height, 6, 6);
+				gc.drawRoundRectangle(maxRect.x, maxRect.y, maxRect.width - 1, maxRect.height - 1, 6, 6);
+				if (!parent.getMaximized()) {
+					gc.fillRectangle(x, y, 9, 9);
+					gc.drawRectangle(x, y, 9, 9);
+					gc.drawLine(x+1, y+2, x+8, y+2);
+				} else {
+					gc.fillRectangle(x, y+3, 5, 4);
+					gc.fillRectangle(x+2, y, 5, 4);
+					gc.drawRectangle(x, y+3, 5, 4);
+					gc.drawRectangle(x+2, y, 5, 4);
+					gc.drawLine(x+3, y+1, x+6, y+1);
+					gc.drawLine(x+1, y+4, x+4, y+4);
+				}
+				break;
+			}
+			case SWT.SELECTED: {
+				gc.fillRoundRectangle(maxRect.x, maxRect.y, maxRect.width, maxRect.height, 6, 6);
+				gc.drawRoundRectangle(maxRect.x, maxRect.y, maxRect.width - 1, maxRect.height - 1, 6, 6);
+				if (!parent.getMaximized()) {
+					gc.fillRectangle(x+1, y+1, 9, 9);
+					gc.drawRectangle(x+1, y+1, 9, 9);
+					gc.drawLine(x+2, y+3, x+9, y+3);
+				} else {
+					gc.fillRectangle(x+1, y+4, 5, 4);
+					gc.fillRectangle(x+3, y+1, 5, 4);
+					gc.drawRectangle(x+1, y+4, 5, 4);
+					gc.drawRectangle(x+3, y+1, 5, 4);
+					gc.drawLine(x+4, y+2, x+7, y+2);
+					gc.drawLine(x+2, y+5, x+5, y+5);
+				}
+				break;
+			}
+		}
+	}
+	void drawMinimize(GC gc, Rectangle minRect, int minImageState) {
+		if (minRect.width == 0 || minRect.height == 0) return;
+		Display display = parent.getDisplay();
+		// 5x4 or 9x3
+		int x = minRect.x + (minRect.width - 10)/2;
+		int y = minRect.y + 3;
+		
+		gc.setForeground(display.getSystemColor(BUTTON_BORDER));
+		gc.setBackground(display.getSystemColor(BUTTON_FILL));
+		
+		switch (minImageState & (SWT.HOT | SWT.SELECTED)) {
+			case SWT.NONE: {
+				if (!parent.getMinimized()) {
+					gc.fillRectangle(x, y, 9, 3);
+					gc.drawRectangle(x, y, 9, 3);
+				} else {
+					gc.fillRectangle(x, y+3, 5, 4);
+					gc.fillRectangle(x+2, y, 5, 4);
+					gc.drawRectangle(x, y+3, 5, 4);
+					gc.drawRectangle(x+2, y, 5, 4);
+					gc.drawLine(x+3, y+1, x+6, y+1);
+					gc.drawLine(x+1, y+4, x+4, y+4);
+				}
+				break;
+			}
+			case SWT.HOT: {
+				gc.fillRoundRectangle(minRect.x, minRect.y, minRect.width, minRect.height, 6, 6);
+				gc.drawRoundRectangle(minRect.x, minRect.y, minRect.width - 1, minRect.height - 1, 6, 6);
+				if (!parent.getMinimized()) {
+					gc.fillRectangle(x, y, 9, 3);
+					gc.drawRectangle(x, y, 9, 3);
+				} else {
+					gc.fillRectangle(x, y+3, 5, 4);
+					gc.fillRectangle(x+2, y, 5, 4);
+					gc.drawRectangle(x, y+3, 5, 4);
+					gc.drawRectangle(x+2, y, 5, 4);
+					gc.drawLine(x+3, y+1, x+6, y+1);
+					gc.drawLine(x+1, y+4, x+4, y+4);
+				}
+				break;
+			}
+			case SWT.SELECTED: {
+				gc.fillRoundRectangle(minRect.x, minRect.y, minRect.width, minRect.height, 6, 6);
+				gc.drawRoundRectangle(minRect.x, minRect.y, minRect.width - 1, minRect.height - 1, 6, 6);
+				if (!parent.getMinimized()) {
+					gc.fillRectangle(x+1, y+1, 9, 3);
+					gc.drawRectangle(x+1, y+1, 9, 3);
+				} else {
+					gc.fillRectangle(x+1, y+4, 5, 4);
+					gc.fillRectangle(x+3, y+1, 5, 4);
+					gc.drawRectangle(x+1, y+4, 5, 4);
+					gc.drawRectangle(x+3, y+1, 5, 4);
+					gc.drawLine(x+4, y+2, x+7, y+2);
+					gc.drawLine(x+2, y+5, x+5, y+5);
+				}
+				break;
+			}
+		}
+	}
+
+	/*
+	 * Draw the unselected border for the receiver on the right.
+	 * 
+	 * @param gc
+	 */
+	void drawRightUnselectedBorder(GC gc, Rectangle bounds, int state) {
+		int x = bounds.x;
+		int y = bounds.y;
+		int width = bounds.width;
+		int height = bounds.height;
+		
+		int[] shape = null;
+		int startX = x + width - 1;
+	
+		if (parent.onBottom) {
+			int[] right = parent.simple
+				? SIMPLE_UNSELECTED_INNER_CORNER
+				: BOTTOM_RIGHT_CORNER;
+			
+			shape = new int[right.length + 2];
+			int index = 0;
+			
+			for (int i = 0; i < right.length / 2; i++) {
+				shape[index++] = startX + right[2 * i];
+				shape[index++] = y + height + right[2 * i + 1] - 1;
+			}
+			shape[index++] = startX;
+			shape[index++] = y - 1;
+		} else {
+			int[] right = parent.simple
+				? SIMPLE_UNSELECTED_INNER_CORNER
+				: TOP_RIGHT_CORNER;
+			
+			shape = new int[right.length + 2];
+			int index = 0;
+	
+			for (int i = 0; i < right.length / 2; i++) {
+				shape[index++] = startX + right[2 * i];
+				shape[index++] = y + right[2 * i + 1];
+			}
+	
+			shape[index++] = startX;
+			shape[index++] = y + height;
+	
+		}
+	
+		drawBorder(gc, shape);
+	
+	}
+
+	void drawSelected(int itemIndex, GC gc, Rectangle bounds, int state ) {
+		CTabItem item = parent.items[itemIndex];
+		int x = bounds.x;
+		int y = bounds.y;
+		int height = bounds.height;
+		int width = bounds.width;
+		if (!parent.simple && !parent.single) width -= (curveWidth - curveIndent);
+		int borderLeft = parent.borderVisible ? 1 : 0;
+		int borderRight = borderLeft;
+		int borderTop = parent.onBottom ? borderLeft : 0;
+		int borderBottom = parent.onBottom ? 0 : borderLeft;
+		
+		Point size = parent.getSize();
+	
+		int rightEdge = Math.min (x + width, parent.getRightItemEdge(gc));
+		//	 Draw selection border across all tabs
+		
+		if ((state & SWT.BACKGROUND) != 0) {
+			int highlight_header = (parent.getStyle() & SWT.FLAT) != 0 ? 1 : 3;
+			int xx = borderLeft;
+			int yy = parent.onBottom ? size.y - borderBottom - parent.tabHeight - highlight_header : borderTop + parent.tabHeight + 1;
+			int ww = size.x - borderLeft - borderRight;
+			int hh = highlight_header - 1;
+			int[] shape = new int[] {xx,yy, xx+ww,yy, xx+ww,yy+hh, xx,yy+hh};
+			if (parent.selectionGradientColors != null && !parent.selectionGradientVertical) {
+				drawBackground(gc, shape, true);
+			} else {
+				gc.setBackground(parent.selectionBackground);
+				gc.fillRectangle(xx, yy, ww, hh);
+			}
+			
+			if (parent.single) {
+				if (!item.showing) return;
+			} else {
+				// if selected tab scrolled out of view or partially out of view
+				// just draw bottom line
+				if (!item.showing){
+					int x1 = Math.max(0, borderLeft - 1);
+					int y1 = (parent.onBottom) ? y - 1 : y + height;
+					int x2 = size.x - borderRight;
+					gc.setForeground(parent.getDisplay().getSystemColor(BORDER1_COLOR));
+					gc.drawLine(x1, y1, x2, y1);
+					return;
+				}
+					
+				// draw selected tab background and outline
+				shape = null;
+				if (parent.onBottom) {
+					int[] left = parent.simple ? SIMPLE_BOTTOM_LEFT_CORNER : BOTTOM_LEFT_CORNER;
+					int[] right = parent.simple ? SIMPLE_BOTTOM_RIGHT_CORNER : curve;
+					if (borderLeft == 0 && itemIndex == parent.firstIndex) {
+						left = new int[]{x, y+height};
+					}
+					shape = new int[left.length+right.length+8];
+					int index = 0;
+					shape[index++] = x; // first point repeated here because below we reuse shape to draw outline
+					shape[index++] = y - 1;
+					shape[index++] = x;
+					shape[index++] = y - 1;
+					for (int i = 0; i < left.length/2; i++) {
+						shape[index++] = x + left[2*i];
+						shape[index++] = y + height + left[2*i+1] - 1;
+					}
+					for (int i = 0; i < right.length/2; i++) {
+						shape[index++] = parent.simple ? rightEdge - 1 + right[2*i] : rightEdge - curveIndent + right[2*i];
+						shape[index++] = parent.simple ? y + height + right[2*i+1] - 1 : y + right[2*i+1] - 2;
+					}
+					shape[index++] = parent.simple ? rightEdge - 1 : rightEdge + curveWidth - curveIndent;
+					shape[index++] = y - 1;
+					shape[index++] = parent.simple ? rightEdge - 1 : rightEdge + curveWidth - curveIndent;
+					shape[index++] = y - 1;
+				} else {
+					int[] left = parent.simple ? SIMPLE_TOP_LEFT_CORNER : TOP_LEFT_CORNER;
+					int[] right = parent.simple ? SIMPLE_TOP_RIGHT_CORNER : curve;
+					if (borderLeft == 0 && itemIndex == parent.firstIndex) {
+						left = new int[]{x, y};
+					}
+					shape = new int[left.length+right.length+8];
+					int index = 0;
+					shape[index++] = x; // first point repeated here because below we reuse shape to draw outline
+					shape[index++] = y + height + 1;
+					shape[index++] = x;
+					shape[index++] = y + height + 1;
+					for (int i = 0; i < left.length/2; i++) {
+						shape[index++] = x + left[2*i];
+						shape[index++] = y + left[2*i+1];
+					}
+					for (int i = 0; i < right.length/2; i++) {
+						shape[index++] = parent.simple ? rightEdge - 1 + right[2*i] : rightEdge - curveIndent + right[2*i];
+						shape[index++] = y + right[2*i+1];
+					}
+					shape[index++] = parent.simple ? rightEdge - 1 : rightEdge + curveWidth - curveIndent;
+					shape[index++] = y + height + 1;
+					shape[index++] = parent.simple ? rightEdge - 1 : rightEdge + curveWidth - curveIndent;
+					shape[index++] = y + height + 1;
+				}
+				
+				Rectangle clipping = gc.getClipping();
+				Rectangle clipBounds = item.getBounds();
+				clipBounds.height += 1;
+				if (parent.onBottom) clipBounds.y -= 1;
+				boolean tabInPaint = clipping.intersects(clipBounds);
+				
+				if (tabInPaint) {
+					// fill in tab background
+					if (parent.selectionGradientColors != null && !parent.selectionGradientVertical) {
+						drawBackground(gc, shape, true);
+					} else {
+						Color defaultBackground = parent.selectionBackground;
+						Image image = parent.selectionBgImage;
+						Color[] colors = parent.selectionGradientColors;
+						int[] percents = parent.selectionGradientPercents;
+						boolean vertical = parent.selectionGradientVertical;
+						xx = x;
+						yy = parent.onBottom ? y -1 : y + 1;
+						ww = width;
+						hh = height;
+						if (!parent.single && !parent.simple) ww += curveWidth - curveIndent;
+						drawBackground(gc, shape, xx, yy, ww, hh, defaultBackground, image, colors, percents, vertical);
+					}
+				}
+				
+				//Highlight MUST be drawn before the outline so that outline can cover it in the right spots (start of swoop)
+				//otherwise the curve looks jagged
+				drawHighlight(gc, bounds, state, rightEdge);
+	
+				// draw outline
+				shape[0] = Math.max(0, borderLeft - 1);
+				if (borderLeft == 0 && itemIndex == parent.firstIndex) {
+					shape[1] = parent.onBottom ? y + height - 1 : y; 
+					shape[5] = shape[3] = shape[1];
+				}
+				shape[shape.length - 2] = size.x - borderRight + 1;
+				for (int i = 0; i < shape.length/2; i++) {
+					if (shape[2*i + 1] == y + height + 1) shape[2*i + 1] -= 1;
+				}
+				Color borderColor = parent.getDisplay().getSystemColor(BORDER1_COLOR);
+				if (! borderColor.equals(lastBorderColor)) createAntialiasColors();
+				antialias(shape, selectedInnerColor, selectedOuterColor, gc);
+				gc.setForeground(borderColor);
+				gc.drawPolyline(shape);
+				
+				if (!tabInPaint) return;
+			}
+		}
+		
+		if ((state & SWT.FOREGROUND) != 0) {
+			// draw Image
+			Rectangle trim = computeTrim(itemIndex, SWT.NONE, 0, 0, 0, 0);
+			int xDraw = x - trim.x;
+			if (parent.single && (parent.showClose || item.showClose)) xDraw += item.closeRect.width; 
+			Image image = item.getImage();
+			if (image != null) {
+				Rectangle imageBounds = image.getBounds();
+				// only draw image if it won't overlap with close button
+				int maxImageWidth = rightEdge - xDraw - (trim.width + trim.x);
+				if (!parent.single && item.closeRect.width > 0) maxImageWidth -= item.closeRect.width + INTERNAL_SPACING;
+				if (imageBounds.width < maxImageWidth) {
+					int imageX = xDraw;
+					int imageY = y + (height - imageBounds.height) / 2;
+					imageY += parent.onBottom ? -1 : 1;
+					gc.drawImage(image, imageX, imageY);
+					xDraw += imageBounds.width + INTERNAL_SPACING;
+				}
+			}
+			
+			// draw Text
+			int textWidth = rightEdge - xDraw - (trim.width + trim.x);
+			if (!parent.single && item.closeRect.width > 0) textWidth -= item.closeRect.width + INTERNAL_SPACING;
+			if (textWidth > 0) {
+				Font gcFont = gc.getFont();
+				gc.setFont(item.font == null ? parent.getFont() : item.font);
+				
+				if (item.shortenedText == null || item.shortenedTextWidth != textWidth) {
+					item.shortenedText = shortenText(gc, item.getText(), textWidth);
+					item.shortenedTextWidth = textWidth;
+				}
+				Point extent = gc.textExtent(item.shortenedText, FLAGS);	
+				int textY = y + (height - extent.y) / 2;
+				textY += parent.onBottom ? -1 : 1;
+				
+				gc.setForeground(parent.selectionForeground);
+				gc.drawText(item.shortenedText, xDraw, textY, FLAGS);
+				gc.setFont(gcFont);
+				
+				// draw a Focus rectangle
+				if (parent.isFocusControl()) {
+					Display display = parent.getDisplay();
+					if (parent.simple || parent.single) {
+						gc.setBackground(display.getSystemColor(SWT.COLOR_BLACK));
+						gc.setForeground(display.getSystemColor(SWT.COLOR_WHITE));
+						gc.drawFocus(xDraw-1, textY-1, extent.x+2, extent.y+2);
+					} else {
+						gc.setForeground(display.getSystemColor(BUTTON_BORDER));
+						gc.drawLine(xDraw, textY+extent.y+1, xDraw+extent.x+1, textY+extent.y+1);
+					}
+				}
+			}
+			if (parent.showClose || item.showClose) drawClose(gc, item.closeRect, item.closeImageState);
+		}
+	}
+
+	void drawTabArea(GC gc, Rectangle bounds, int state) {
+		Point size = parent.getSize();
+		int[] shape = null;
+		Color borderColor = parent.getDisplay().getSystemColor(BORDER1_COLOR);
+		int tabHeight = parent.tabHeight;
+		int style = parent.getStyle();
+		
+		int borderLeft = parent.borderVisible ? 1 : 0;
+		int borderRight = borderLeft;
+		int borderTop = parent.onBottom ? borderLeft : 0;
+		int borderBottom = parent.onBottom ? 0 : borderLeft;
+		
+		int selectedIndex = parent.selectedIndex;
+		int highlight_header = (style & SWT.FLAT) != 0 ? 1 : 3;
+		if (tabHeight == 0) {
+			if ((style & SWT.FLAT) != 0 && (style & SWT.BORDER) == 0) return;
+			int x1 = borderLeft - 1;
+			int x2 = size.x - borderRight;
+			int y1 = parent.onBottom ? size.y - borderBottom - highlight_header - 1 : borderTop + highlight_header;
+			int y2 = parent.onBottom ? size.y - borderBottom : borderTop;
+			if (borderLeft > 0 && parent.onBottom) y2 -= 1;
+			
+			shape = new int[] {x1, y1, x1,y2, x2,y2, x2,y1};
+	
+			// If horizontal gradient, show gradient across the whole area
+			if (selectedIndex != -1 && parent.selectionGradientColors != null && parent.selectionGradientColors.length > 1 && !parent.selectionGradientVertical) {
+				drawBackground(gc, shape, true);
+			} else if (selectedIndex == -1 && parent.gradientColors != null && parent.gradientColors.length > 1 && !parent.gradientVertical) {
+				drawBackground(gc, shape, false);
+			} else {
+				gc.setBackground(selectedIndex == -1 ? parent.getBackground() : parent.selectionBackground);
+				gc.fillPolygon(shape);
+			}
+			
+			//draw 1 pixel border
+			if (borderLeft > 0) {
+				gc.setForeground(borderColor);
+				gc.drawPolyline(shape); 
+			}
+			return;
+		}
+		
+		int x = Math.max(0, borderLeft - 1);
+		int y = parent.onBottom ? size.y - borderBottom - tabHeight : borderTop;
+		int width = size.x - borderLeft - borderRight + 1;
+		int height = tabHeight - 1;
+		boolean simple = parent.simple;
+		// Draw Tab Header
+		if (parent.onBottom) {
+			int[] left, right;
+			if ((style & SWT.BORDER) != 0) {
+				left = simple ? SIMPLE_BOTTOM_LEFT_CORNER : BOTTOM_LEFT_CORNER;
+				right = simple ? SIMPLE_BOTTOM_RIGHT_CORNER : BOTTOM_RIGHT_CORNER;
+			} else {
+				left = simple ? SIMPLE_BOTTOM_LEFT_CORNER_BORDERLESS : BOTTOM_LEFT_CORNER_BORDERLESS;
+				right = simple ? SIMPLE_BOTTOM_RIGHT_CORNER_BORDERLESS : BOTTOM_RIGHT_CORNER_BORDERLESS;
+			}
+			shape = new int[left.length + right.length + 4];
+			int index = 0;
+			shape[index++] = x;
+			shape[index++] = y-highlight_header;
+			for (int i = 0; i < left.length/2; i++) {
+				shape[index++] = x+left[2*i];
+				shape[index++] = y+height+left[2*i+1];
+				if (borderLeft == 0) shape[index-1] += 1;
+			}
+			for (int i = 0; i < right.length/2; i++) {
+				shape[index++] = x+width+right[2*i];
+				shape[index++] = y+height+right[2*i+1];
+				if (borderLeft == 0) shape[index-1] += 1;
+			}
+			shape[index++] = x+width;
+			shape[index++] = y-highlight_header;
+		} else {
+			int[] left, right;
+			if ((style & SWT.BORDER) != 0) {
+				left = simple ? SIMPLE_TOP_LEFT_CORNER : TOP_LEFT_CORNER;
+				right = simple ? SIMPLE_TOP_RIGHT_CORNER : TOP_RIGHT_CORNER;
+			} else {
+				left = simple ? SIMPLE_TOP_LEFT_CORNER_BORDERLESS : TOP_LEFT_CORNER_BORDERLESS;
+				right = simple ? SIMPLE_TOP_RIGHT_CORNER_BORDERLESS : TOP_RIGHT_CORNER_BORDERLESS;
+			}
+			shape = new int[left.length + right.length + 4];
+			int index = 0;
+			shape[index++] = x;
+			shape[index++] = y+height+highlight_header + 1;
+			for (int i = 0; i < left.length/2; i++) {
+				shape[index++] = x+left[2*i];
+				shape[index++] = y+left[2*i+1];
+			}
+			for (int i = 0; i < right.length/2; i++) {
+				shape[index++] = x+width+right[2*i];
+				shape[index++] = y+right[2*i+1];
+			}
+			shape[index++] = x+width;
+			shape[index++] = y+height+highlight_header + 1;
+		}
+		// Fill in background
+		boolean single = parent.single;
+		boolean bkSelected = single && selectedIndex != -1;
+		drawBackground(gc, shape, bkSelected);
+		// Fill in parent background for non-rectangular shape
+		Region r = new Region();
+		r.add(new Rectangle(x, y, width + 1, height + 1));
+		r.subtract(shape);
+		gc.setBackground(parent.getParent().getBackground());
+		fillRegion(gc, r);
+		r.dispose();
+		
+		// Draw selected tab
+		if (selectedIndex == -1) {
+			// if no selected tab - draw line across bottom of all tabs
+			int x1 = borderLeft;
+			int y1 = (parent.onBottom) ? size.y - borderBottom - tabHeight - 1 : borderTop + tabHeight;
+			int x2 = size.x - borderRight;
+			gc.setForeground(borderColor);
+			gc.drawLine(x1, y1, x2, y1);
+		}
+	
+		// Draw border line
+		if (borderLeft > 0) {
+	    	if (! borderColor.equals(lastBorderColor)) createAntialiasColors();
+	    	antialias(shape, null, tabAreaColor, gc);
+			gc.setForeground(borderColor);
+			gc.drawPolyline(shape);
+		}		
+	}
+
+	void drawUnselected(int index, GC gc, Rectangle bounds, int state) {
+		CTabItem item = parent.items[index];
+		int x = bounds.x;
+		int y = bounds.y;
+		int height = bounds.height;
+		int width = bounds.width;
+		
+		// Do not draw partial items
+		if (!item.showing) return;
+		
+		Rectangle clipping = gc.getClipping();
+		if (!clipping.intersects(bounds)) return;
+		
+		if ((state & SWT.BACKGROUND) != 0) {
+			if (index > 0 && index < parent.selectedIndex)
+				drawLeftUnselectedBorder(gc, bounds, state);
+			// If it is the last one then draw a line
+			if (index > parent.selectedIndex)
+				drawRightUnselectedBorder(gc, bounds, state);
+		}
+		
+		if ((state & SWT.FOREGROUND) != 0) {
+			// draw Image
+			Rectangle trim = computeTrim(index, SWT.NONE, 0, 0, 0, 0);
+			int xDraw = x - trim.x;
+			Image image = item.getImage();
+			if (image != null && parent.showUnselectedImage) {
+				Rectangle imageBounds = image.getBounds();
+				// only draw image if it won't overlap with close button
+				int maxImageWidth = x + width - xDraw - (trim.width + trim.x);
+				if (parent.showUnselectedClose && (parent.showClose || item.showClose)) {
+					maxImageWidth -= item.closeRect.width + INTERNAL_SPACING;
+				}
+				if (imageBounds.width < maxImageWidth) {		
+					int imageX = xDraw;
+					int imageHeight = imageBounds.height;
+					int imageY = y + (height - imageHeight) / 2;
+					imageY += parent.onBottom ? -1 : 1;
+					int imageWidth = imageBounds.width * imageHeight / imageBounds.height;
+					gc.drawImage(image, 
+						         imageBounds.x, imageBounds.y, imageBounds.width, imageBounds.height,
+						         imageX, imageY, imageWidth, imageHeight);
+					xDraw += imageWidth + INTERNAL_SPACING;
+				}
+			}
+			// draw Text
+			int textWidth = x + width - xDraw - (trim.width + trim.x);
+			if (parent.showUnselectedClose && (parent.showClose || item.showClose)) {
+				textWidth -= item.closeRect.width + INTERNAL_SPACING;
+			}
+			if (textWidth > 0) {
+				Font gcFont = gc.getFont();
+				gc.setFont(item.font == null ? parent.getFont() : item.font);
+				if (item.shortenedText == null || item.shortenedTextWidth != textWidth) {
+					item.shortenedText = shortenText(gc, item.getText(), textWidth);
+					item.shortenedTextWidth = textWidth;
+				}	
+				Point extent = gc.textExtent(item.shortenedText, FLAGS);
+				int textY = y + (height - extent.y) / 2;
+				textY += parent.onBottom ? -1 : 1;
+				gc.setForeground(parent.getForeground());
+				gc.drawText(item.shortenedText, xDraw, textY, FLAGS);
+				gc.setFont(gcFont);
+			}
+			// draw close
+			if (parent.showUnselectedClose && (parent.showClose || item.showClose)) drawClose(gc, item.closeRect, item.closeImageState);
+		}
+	}
+
+	void fillRegion(GC gc, Region region) {
+		// NOTE: region passed in to this function will be modified
+		Region clipping = new Region();
+		gc.getClipping(clipping);
+		region.intersect(clipping);
+		gc.setClipping(region);
+		gc.fillRectangle(region.getBounds());
+		gc.setClipping(clipping);
+		clipping.dispose();
+	}
+		
+	Color getFillColor() {
+		if (fillColor == null) {
+			fillColor = new Color(parent.getDisplay(), CLOSE_FILL);
+		}
+		return fillColor;
+	}
+		
+	/*
+	 * Return true if given start color, the cache of highlight colors we have
+	 * would match the highlight colors we'd compute.
+	 */
+	boolean isSelectionHighlightColorsCacheHit(Color start) {
+
+		if(selectionHighlightGradientColorsCache == null)
+			return false;
+		
+		//this case should never happen but check to be safe before accessing array indexes
+		if(selectionHighlightGradientColorsCache.length < 2)
+			return false;
+
+		Color highlightBegin = selectionHighlightGradientColorsCache[0];
+		Color highlightEnd = selectionHighlightGradientColorsCache[selectionHighlightGradientColorsCache.length - 1];
+
+		if(! highlightBegin.equals(start))
+			return false;	
+		
+		//Compare number of colours we have vs. we'd compute
+		if(selectionHighlightGradientColorsCache.length != parent.tabHeight)
+			return false;
+		
+		//Compare existing highlight end to what it would be (selectionBackground)
+		if(! highlightEnd.equals(parent.selectionBackground))
+			return false;
+		
+		return true;
+	}
+
+	void setSelectionHighlightGradientColor(Color start) {
+		//
+		//Set to null to match all the early return cases.
+		//For early returns, don't realloc the cache, we may get a cache hit next time we're given the highlight
+		selectionHighlightGradientBegin = null;
+	
+		if(start == null)
+			return;
+	
+		//don't bother on low colour
+		if (parent.getDisplay().getDepth() < 15)
+			return;
+		
+		//don't bother if we don't have a background gradient
+		if(parent.selectionGradientColors.length < 2) 
+			return;
+	
+		//OK we know its a valid gradient now
+		selectionHighlightGradientBegin = start;
+	
+		if(! isSelectionHighlightColorsCacheHit(start))
+			createSelectionHighlightGradientColors(start);  //if no cache hit then compute new ones
+	}
+	
+	String shortenText(GC gc, String text, int width) {
+		return useEllipses()
+			? shortenText(gc, text, width, ELLIPSIS)
+			: shortenText(gc, text, width, ""); //$NON-NLS-1$
+	}
+
+	String shortenText(GC gc, String text, int width, String ellipses) {
+		if (gc.textExtent(text, FLAGS).x <= width) return text;
+		int ellipseWidth = gc.textExtent(ellipses, FLAGS).x;
+		int length = text.length();
+		TextLayout layout = new TextLayout(parent.getDisplay());
+		layout.setText(text);
+		int end = layout.getPreviousOffset(length, SWT.MOVEMENT_CLUSTER);
+		while (end > 0) {
+			text = text.substring(0, end);
+			int l = gc.textExtent(text, FLAGS).x;
+			if (l + ellipseWidth <= width) {
+				break;
+			}
+			end = layout.getPreviousOffset(end, SWT.MOVEMENT_CLUSTER);
+		}
+		layout.dispose();
+		return end == 0 ? text.substring(0, 1) : text + ellipses;
+	}
+	
+	void updateCurves () {
+		int tabHeight = parent.tabHeight;
+		if (tabHeight == lastTabHeight) return;
+		if (parent.onBottom) {
+			int d = tabHeight - 12;
+			curve = new int[]{0,13+d, 0,12+d, 2,12+d, 3,11+d, 5,11+d, 6,10+d, 7,10+d, 9,8+d, 10,8+d,
+					          11,7+d, 11+d,7,
+							  12+d,6, 13+d,6, 15+d,4, 16+d,4, 17+d,3, 19+d,3, 20+d,2, 22+d,2, 23+d,1}; 
+			curveWidth = 26+d;
+			curveIndent = curveWidth/3;	
+		} else {
+			int d = tabHeight - 12;
+			curve = new int[]{0,0, 0,1, 2,1, 3,2, 5,2, 6,3, 7,3, 9,5, 10,5,
+					          11,6, 11+d,6+d,
+					          12+d,7+d, 13+d,7+d, 15+d,9+d, 16+d,9+d, 17+d,10+d, 19+d,10+d, 20+d,11+d, 22+d,11+d, 23+d,12+d};
+			curveWidth = 26+d;
+			curveIndent = curveWidth/3;
+			
+			//this could be static but since values depend on curve, better to keep in one place
+			topCurveHighlightStart = new int[] { 
+					0, 2,  1, 2,  2, 2,    
+					3, 3,  4, 3,  5, 3, 
+					6, 4,  7, 4,
+					8, 5, 
+					9, 6, 10, 6};
+			
+			//also, by adding in 'd' here we save some math cost when drawing the curve
+			topCurveHighlightEnd = new int[] { 
+					10+d, 6+d,
+					11+d, 7+d,
+					12+d, 8+d,  13+d, 8+d,
+					14+d, 9+d,
+					15+d, 10+d,  16+d, 10+d,
+					17+d, 11+d,  18+d, 11+d,  19+d, 11+d,
+					20+d, 12+d,  21+d, 12+d,  22+d,  12+d }; 
+		}
+	}
+
+	/*
+	 * Return whether to use ellipses or just truncate labels
+	 */
+	boolean useEllipses() {
+		return parent.simple;
+	}
+}
diff --git a/org/eclipse/swt/custom/CTabItem.java b/org/eclipse/swt/custom/CTabItem.java
index ffe19d2..1d1185d 100644
--- a/org/eclipse/swt/custom/CTabItem.java
+++ b/org/eclipse/swt/custom/CTabItem.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -47,19 +47,11 @@ public class CTabItem extends Item {
 	Image disabledImage; 
 	
 	Rectangle closeRect = new Rectangle(0, 0, 0, 0);
-	int closeImageState = CTabFolder.NONE;
+	int closeImageState = SWT.BACKGROUND;
+	int state = SWT.NONE;
 	boolean showClose = false;
 	boolean showing = false;
 
-	// internal constants
-	static final int TOP_MARGIN = 2;
-	static final int BOTTOM_MARGIN = 2;
-	static final int LEFT_MARGIN = 4;
-	static final int RIGHT_MARGIN = 4;
-	static final int INTERNAL_SPACING = 4;
-	static final int FLAGS = SWT.DRAW_TRANSPARENT | SWT.DRAW_MNEMONIC;
-	static final String ELLIPSIS = "..."; //$NON-NLS-1$ // could use the ellipsis glyph on some platforms "\u2026"
-	
 /**
  * Constructs a new instance of this class given its parent
  * (which must be a <code>CTabFolder</code>) and a style value
@@ -127,37 +119,6 @@ public CTabItem (CTabFolder parent, int style, int index) {
 	parent.createItem (this, index);
 }
 
-/*
- * Return whether to use ellipses or just truncate labels
- */
-boolean useEllipses() {
-	return parent.simple;
-}
-
-String shortenText(GC gc, String text, int width) {
-	return useEllipses()
-		? shortenText(gc, text, width, ELLIPSIS)
-		: shortenText(gc, text, width, ""); //$NON-NLS-1$
-}
-
-String shortenText(GC gc, String text, int width, String ellipses) {
-	if (gc.textExtent(text, FLAGS).x <= width) return text;
-	int ellipseWidth = gc.textExtent(ellipses, FLAGS).x;
-	int length = text.length();
-	TextLayout layout = new TextLayout(getDisplay());
-	layout.setText(text);
-	int end = layout.getPreviousOffset(length, SWT.MOVEMENT_CLUSTER);
-	while (end > 0) {
-		text = text.substring(0, end);
-		int l = gc.textExtent(text, FLAGS).x;
-		if (l + ellipseWidth <= width) {
-			break;
-		}
-		end = layout.getPreviousOffset(end, SWT.MOVEMENT_CLUSTER);
-	}
-	layout.dispose();
-	return end == 0 ? text.substring(0, 1) : text + ellipses;
-}
 
 public void dispose() {
 	if (isDisposed ()) return;
@@ -170,506 +131,7 @@ public void dispose() {
 	shortenedText = null;
 	font = null;
 }
-void drawClose(GC gc) {
-	if (closeRect.width == 0 || closeRect.height == 0) return;
-	Display display = getDisplay();
-
-	// draw X 9x9
-	int indent = Math.max(1, (CTabFolder.BUTTON_SIZE-9)/2);
-	int x = closeRect.x + indent;
-	int y = closeRect.y + indent;
-	y += parent.onBottom ? -1 : 1;
-	
-	Color closeBorder = display.getSystemColor(CTabFolder.BUTTON_BORDER);
-	switch (closeImageState) {
-		case CTabFolder.NORMAL: {
-			int[] shape = new int[] {x,y, x+2,y, x+4,y+2, x+5,y+2, x+7,y, x+9,y, 
-					                 x+9,y+2, x+7,y+4, x+7,y+5, x+9,y+7, x+9,y+9,
-			                         x+7,y+9, x+5,y+7, x+4,y+7, x+2,y+9, x,y+9,
-			                         x,y+7, x+2,y+5, x+2,y+4, x,y+2};
-			gc.setBackground(display.getSystemColor(CTabFolder.BUTTON_FILL));
-			gc.fillPolygon(shape);
-			gc.setForeground(closeBorder);
-			gc.drawPolygon(shape);
-			break;
-		}
-		case CTabFolder.HOT: {
-			int[] shape = new int[] {x,y, x+2,y, x+4,y+2, x+5,y+2, x+7,y, x+9,y, 
-					                 x+9,y+2, x+7,y+4, x+7,y+5, x+9,y+7, x+9,y+9,
-			                         x+7,y+9, x+5,y+7, x+4,y+7, x+2,y+9, x,y+9,
-			                         x,y+7, x+2,y+5, x+2,y+4, x,y+2};
-			gc.setBackground(parent.getFillColor());
-			gc.fillPolygon(shape);
-			gc.setForeground(closeBorder);
-			gc.drawPolygon(shape);
-			break;
-		}
-		case CTabFolder.SELECTED: {
-			int[] shape = new int[] {x+1,y+1, x+3,y+1, x+5,y+3, x+6,y+3, x+8,y+1, x+10,y+1, 
-					                 x+10,y+3, x+8,y+5, x+8,y+6, x+10,y+8, x+10,y+10,
-			                         x+8,y+10, x+6,y+8, x+5,y+8, x+3,y+10, x+1,y+10,
-			                         x+1,y+8, x+3,y+6, x+3,y+5, x+1,y+3};
-			gc.setBackground(parent.getFillColor());
-			gc.fillPolygon(shape);
-			gc.setForeground(closeBorder);
-			gc.drawPolygon(shape);
-			break;
-		}
-		case CTabFolder.NONE: {
-			int[] shape = new int[] {x,y, x+10,y, x+10,y+10, x,y+10};
-			if (parent.gradientColors != null && !parent.gradientVertical) {
-				parent.drawBackground(gc, shape, false);
-			} else {
-				Color defaultBackground = parent.getBackground();
-				Color[] colors = parent.gradientColors;
-				int[] percents = parent.gradientPercents;
-				boolean vertical = parent.gradientVertical; 
-				parent.drawBackground(gc, shape, x, y, 10, 10, defaultBackground, null, colors, percents, vertical);
-			}
-			break;
-		}
-	}
-}
-void drawSelected(GC gc ) {
-	Point size = parent.getSize();
-	int rightEdge = Math.min (x + width, parent.getRightItemEdge());
-	
-	//	 Draw selection border across all tabs
-	int xx = parent.borderLeft;
-	int yy = parent.onBottom ? size.y - parent.borderBottom - parent.tabHeight - parent.highlight_header : parent.borderTop + parent.tabHeight + 1;
-	int ww = size.x - parent.borderLeft - parent.borderRight;
-	int hh = parent.highlight_header - 1;
-	int[] shape = new int[] {xx,yy, xx+ww,yy, xx+ww,yy+hh, xx,yy+hh};
-	if (parent.selectionGradientColors != null && !parent.selectionGradientVertical) {
-		parent.drawBackground(gc, shape, true);
-	} else {
-		gc.setBackground(parent.selectionBackground);
-		gc.fillRectangle(xx, yy, ww, hh);
-	}
-	
-	if (parent.single) {
-		if (!showing) return;
-	} else {
-		// if selected tab scrolled out of view or partially out of view
-		// just draw bottom line
-		if (!showing){
-			int x1 = Math.max(0, parent.borderLeft - 1);
-			int y1 = (parent.onBottom) ? y - 1 : y + height;
-			int x2 = size.x - parent.borderRight;
-			gc.setForeground(getDisplay().getSystemColor(CTabFolder.BORDER1_COLOR));
-			gc.drawLine(x1, y1, x2, y1);
-			return;
-		}
-			
-		// draw selected tab background and outline
-		shape = null;
-		if (this.parent.onBottom) {
-			int[] left = parent.simple ? CTabFolder.SIMPLE_BOTTOM_LEFT_CORNER : CTabFolder.BOTTOM_LEFT_CORNER;
-			int[] right = parent.simple ? CTabFolder.SIMPLE_BOTTOM_RIGHT_CORNER : parent.curve;
-			if (parent.borderLeft == 0 && parent.indexOf(this) == parent.firstIndex) {
-				left = new int[]{x, y+height};
-			}
-			shape = new int[left.length+right.length+8];
-			int index = 0;
-			shape[index++] = x; // first point repeated here because below we reuse shape to draw outline
-			shape[index++] = y - 1;
-			shape[index++] = x;
-			shape[index++] = y - 1;
-			for (int i = 0; i < left.length/2; i++) {
-				shape[index++] = x + left[2*i];
-				shape[index++] = y + height + left[2*i+1] - 1;
-			}
-			for (int i = 0; i < right.length/2; i++) {
-				shape[index++] = parent.simple ? rightEdge - 1 + right[2*i] : rightEdge - parent.curveIndent + right[2*i];
-				shape[index++] = parent.simple ? y + height + right[2*i+1] - 1 : y + right[2*i+1] - 2;
-			}
-			shape[index++] = parent.simple ? rightEdge - 1 : rightEdge + parent.curveWidth - parent.curveIndent;
-			shape[index++] = y - 1;
-			shape[index++] = parent.simple ? rightEdge - 1 : rightEdge + parent.curveWidth - parent.curveIndent;
-			shape[index++] = y - 1;
-		} else {
-			int[] left = parent.simple ? CTabFolder.SIMPLE_TOP_LEFT_CORNER : CTabFolder.TOP_LEFT_CORNER;
-			int[] right = parent.simple ? CTabFolder.SIMPLE_TOP_RIGHT_CORNER : parent.curve;
-			if (parent.borderLeft == 0 && parent.indexOf(this) == parent.firstIndex) {
-				left = new int[]{x, y};
-			}
-			shape = new int[left.length+right.length+8];
-			int index = 0;
-			shape[index++] = x; // first point repeated here because below we reuse shape to draw outline
-			shape[index++] = y + height + 1;
-			shape[index++] = x;
-			shape[index++] = y + height + 1;
-			for (int i = 0; i < left.length/2; i++) {
-				shape[index++] = x + left[2*i];
-				shape[index++] = y + left[2*i+1];
-			}
-			for (int i = 0; i < right.length/2; i++) {
-				shape[index++] = parent.simple ? rightEdge - 1 + right[2*i] : rightEdge - parent.curveIndent + right[2*i];
-				shape[index++] = y + right[2*i+1];
-			}
-			shape[index++] = parent.simple ? rightEdge - 1 : rightEdge + parent.curveWidth - parent.curveIndent;
-			shape[index++] = y + height + 1;
-			shape[index++] = parent.simple ? rightEdge - 1 : rightEdge + parent.curveWidth - parent.curveIndent;
-			shape[index++] = y + height + 1;
-		}
-		
-		Rectangle clipping = gc.getClipping();
-		Rectangle bounds = getBounds();
-		bounds.height += 1;
-		if (parent.onBottom) bounds.y -= 1;
-		boolean tabInPaint = clipping.intersects(bounds);
-		
-		if (tabInPaint) {
-			// fill in tab background
-			if (parent.selectionGradientColors != null && !parent.selectionGradientVertical) {
-				parent.drawBackground(gc, shape, true);
-			} else {
-				Color defaultBackground = parent.selectionBackground;
-				Image image = parent.selectionBgImage;
-				Color[] colors = parent.selectionGradientColors;
-				int[] percents = parent.selectionGradientPercents;
-				boolean vertical = parent.selectionGradientVertical;
-				xx = x;
-				yy = parent.onBottom ? y -1 : y + 1;
-				ww = width;
-				hh = height;
-				if (!parent.single && !parent.simple) ww += parent.curveWidth - parent.curveIndent;
-				parent.drawBackground(gc, shape, xx, yy, ww, hh, defaultBackground, image, colors, percents, vertical);
-			}
-		}
-		
-		//Highlight MUST be drawn before the outline so that outline can cover it in the right spots (start of swoop)
-		//otherwise the curve looks jagged
-		drawHighlight(gc, rightEdge);
-
-		// draw outline
-		shape[0] = Math.max(0, parent.borderLeft - 1);
-		if (parent.borderLeft == 0 && parent.indexOf(this) == parent.firstIndex) {
-			shape[1] = parent.onBottom ? y + height - 1 : y; 
-			shape[5] = shape[3] = shape[1];
-		}
-		shape[shape.length - 2] = size.x - parent.borderRight + 1;
-		for (int i = 0; i < shape.length/2; i++) {
-			if (shape[2*i + 1] == y + height + 1) shape[2*i + 1] -= 1;
-		}
-		RGB inside = parent.selectionBackground.getRGB();
-		if (parent.selectionBgImage != null || 
-		    (parent.selectionGradientColors != null && parent.selectionGradientColors.length > 1)) {
-		    inside = null;
-		}
-		RGB outside = parent.getBackground().getRGB();		
-		if (parent.gradientColors != null && parent.gradientColors.length > 1) {
-		    outside = null;
-		}
-		Color borderColor = getDisplay().getSystemColor(CTabFolder.BORDER1_COLOR);
-		parent.antialias(shape, borderColor.getRGB(), inside, outside, gc);
-		gc.setForeground(borderColor);
-		gc.drawPolyline(shape);
-		
-		if (!tabInPaint) return;
-	}
-	
-	// draw Image
-	int xDraw = x + LEFT_MARGIN;
-	if (parent.single && (parent.showClose || showClose)) xDraw += CTabFolder.BUTTON_SIZE; 
-	Image image = getImage();
-	if (image != null) {
-		Rectangle imageBounds = image.getBounds();
-		// only draw image if it won't overlap with close button
-		int maxImageWidth = rightEdge - xDraw - RIGHT_MARGIN;
-		if (!parent.single && closeRect.width > 0) maxImageWidth -= closeRect.width + INTERNAL_SPACING;
-		if (imageBounds.width < maxImageWidth) {
-			int imageX = xDraw;
-			int imageY = y + (height - imageBounds.height) / 2;
-			imageY += parent.onBottom ? -1 : 1;
-			gc.drawImage(image, imageX, imageY);
-			xDraw += imageBounds.width + INTERNAL_SPACING;
-		}
-	}
-	
-	// draw Text
-	int textWidth = rightEdge - xDraw - RIGHT_MARGIN;
-	if (!parent.single && closeRect.width > 0) textWidth -= closeRect.width + INTERNAL_SPACING;
-	if (textWidth > 0) {
-		Font gcFont = gc.getFont();
-		gc.setFont(font == null ? parent.getFont() : font);
-		
-		if (shortenedText == null || shortenedTextWidth != textWidth) {
-			shortenedText = shortenText(gc, getText(), textWidth);
-			shortenedTextWidth = textWidth;
-		}
-		Point extent = gc.textExtent(shortenedText, FLAGS);	
-		int textY = y + (height - extent.y) / 2;
-		textY += parent.onBottom ? -1 : 1;
-		
-		gc.setForeground(parent.selectionForeground);
-		gc.drawText(shortenedText, xDraw, textY, FLAGS);
-		gc.setFont(gcFont);
-		
-		// draw a Focus rectangle
-		if (parent.isFocusControl()) {
-			Display display = getDisplay();
-			if (parent.simple || parent.single) {
-				gc.setBackground(display.getSystemColor(SWT.COLOR_BLACK));
-				gc.setForeground(display.getSystemColor(SWT.COLOR_WHITE));
-				gc.drawFocus(xDraw-1, textY-1, extent.x+2, extent.y+2);
-			} else {
-				gc.setForeground(display.getSystemColor(CTabFolder.BUTTON_BORDER));
-				gc.drawLine(xDraw, textY+extent.y+1, xDraw+extent.x+1, textY+extent.y+1);
-			}
-		}
-	}
-	if (parent.showClose || showClose) drawClose(gc);
-}
 
-/*
- * Draw a highlight effect along the left, top, and right edges of the tab.
- * Only for curved tabs, on top.
- * Do not draw if insufficient colors.
- */
-void drawHighlight(GC gc, int rightEdge) {
-	//only draw for curvy tabs and only draw for top tabs
-	if(parent.simple || this.parent.onBottom)
-		return;
-	
-	if(parent.selectionHighlightGradientBegin == null)
-		return;
-	
-	Color[] gradients = parent.selectionHighlightGradientColorsCache;
-	if(gradients == null)
-		return;
-	int gradientsSize = gradients.length;
-	if(gradientsSize == 0)
-		return;		//shouldn't happen but just to be tidy
-
-	gc.setForeground(gradients[0]);
-	
-	//draw top horizontal line
-	gc.drawLine(
-			CTabFolder.TOP_LEFT_CORNER_HILITE[0] + x + 1, //rely on fact that first pair is top/right of curve
-			1 + y,
-			rightEdge - parent.curveIndent,
-			1 + y);
-	
-	int[] leftHighlightCurve = CTabFolder.TOP_LEFT_CORNER_HILITE;
-
-	int d = parent.tabHeight - parent.topCurveHighlightEnd.length /2;
-
-	int lastX = 0;
-	int lastY = 0;
-	int lastColorIndex = 0;
-	
-	//draw upper left curve highlight
-	for (int i = 0; i < leftHighlightCurve.length /2; i++) {
-		int rawX = leftHighlightCurve[i * 2];
-		int rawY = leftHighlightCurve[i * 2 + 1];
-		lastX = rawX + x;
-		lastY = rawY + y;
-		lastColorIndex = rawY - 1;
-		gc.setForeground(gradients[lastColorIndex]);
-		gc.drawPoint(lastX, lastY);
-	}
-	//draw left vertical line highlight
-	for(int i = lastColorIndex; i < gradientsSize; i++) {
-		gc.setForeground(gradients[i]);
-		gc.drawPoint(lastX, 1 + lastY++);
-	}
-	
-	int rightEdgeOffset = rightEdge - parent.curveIndent;
-	
-	//draw right swoop highlight up to diagonal portion
-	for (int i = 0; i < parent.topCurveHighlightStart.length /2; i++) {
-		int rawX = parent.topCurveHighlightStart[i * 2];
-		int rawY = parent.topCurveHighlightStart[i * 2 + 1];
-		lastX = rawX + rightEdgeOffset;
-		lastY = rawY + y;
-		lastColorIndex = rawY - 1;
-		if(lastColorIndex >= gradientsSize)
-			break;	//can happen if tabs are unusually short and cut off the curve
-		gc.setForeground(gradients[lastColorIndex]);
-		gc.drawPoint(lastX, lastY);
-	}
-	//draw right diagonal line highlight
-	for(int i = lastColorIndex; i < lastColorIndex + d; i++) {
-		if(i >= gradientsSize)
-			break;	//can happen if tabs are unusually short and cut off the curve
-		gc.setForeground(gradients[i]);
-		gc.drawPoint(1 + lastX++, 1 + lastY++);
-	}
-
-	//draw right swoop highlight from diagonal portion to end
-	for (int i = 0; i < parent.topCurveHighlightEnd.length /2; i++) {
-		int rawX = parent.topCurveHighlightEnd[i * 2]; //d is already encoded in this value
-		int rawY = parent.topCurveHighlightEnd[i * 2 + 1]; //d already encoded
-		lastX = rawX + rightEdgeOffset;
-		lastY = rawY + y;
-		lastColorIndex = rawY - 1;
-		if(lastColorIndex >= gradientsSize)
-			break;	//can happen if tabs are unusually short and cut off the curve
-		gc.setForeground(gradients[lastColorIndex]);
-		gc.drawPoint(lastX, lastY);
-	}	
-}
-
-/*
- * Draw the unselected border for the receiver on the right.
- * 
- * @param gc
- */
-void drawRightUnselectedBorder(GC gc) {
-
-	int[] shape = null;
-	int startX = x + width - 1;
-
-	if (this.parent.onBottom) {
-		int[] right = parent.simple
-			? CTabFolder.SIMPLE_UNSELECTED_INNER_CORNER
-			: CTabFolder.BOTTOM_RIGHT_CORNER;
-		
-		shape = new int[right.length + 2];
-		int index = 0;
-		
-		for (int i = 0; i < right.length / 2; i++) {
-			shape[index++] = startX + right[2 * i];
-			shape[index++] = y + height + right[2 * i + 1] - 1;
-		}
-		shape[index++] = startX;
-		shape[index++] = y - 1;
-	} else {
-		int[] right = parent.simple
-			? CTabFolder.SIMPLE_UNSELECTED_INNER_CORNER
-			: CTabFolder.TOP_RIGHT_CORNER;
-		
-		shape = new int[right.length + 2];
-		int index = 0;
-
-		for (int i = 0; i < right.length / 2; i++) {
-			shape[index++] = startX + right[2 * i];
-			shape[index++] = y + right[2 * i + 1];
-		}
-
-		shape[index++] = startX;
-		shape[index++] = y + height;
-
-	}
-
-	drawBorder(gc, shape);
-
-}
-
-/*
- * Draw the border of the tab
- * 
- * @param gc
- * @param shape
- */
-void drawBorder(GC gc, int[] shape) {
-
-	gc.setForeground(getDisplay().getSystemColor(CTabFolder.BORDER1_COLOR));
-	gc.drawPolyline(shape);
-}
-
-/*
- * Draw the unselected border for the receiver on the left.
- * 
- * @param gc
- */
-void drawLeftUnselectedBorder(GC gc) {
-
-	int[] shape = null;
-	if (this.parent.onBottom) {
-		int[] left = parent.simple
-			? CTabFolder.SIMPLE_UNSELECTED_INNER_CORNER
-			: CTabFolder.BOTTOM_LEFT_CORNER;
-		
-		shape = new int[left.length + 2];
-		int index = 0;
-		shape[index++] = x;
-		shape[index++] = y - 1;
-		for (int i = 0; i < left.length / 2; i++) {
-			shape[index++] = x + left[2 * i];
-			shape[index++] = y + height + left[2 * i + 1] - 1;
-		}
-	} else {
-		int[] left = parent.simple
-			? CTabFolder.SIMPLE_UNSELECTED_INNER_CORNER
-			: CTabFolder.TOP_LEFT_CORNER;
-
-		shape = new int[left.length + 2];
-		int index = 0;
-		shape[index++] = x;
-		shape[index++] = y + height;
-		for (int i = 0; i < left.length / 2; i++) {
-			shape[index++] = x + left[2 * i];
-			shape[index++] = y + left[2 * i + 1];
-		}
-
-	}
-
-	drawBorder(gc, shape);
-}
-
-void drawUnselected(GC gc) {
-	// Do not draw partial items
-	if (!showing) return;
-	
-	Rectangle clipping = gc.getClipping();
-	Rectangle bounds = getBounds();
-	if (!clipping.intersects(bounds)) return;
-	
-	// draw border
-	int index = parent.indexOf(this);
-
-	if (index > 0 && index < parent.selectedIndex)
-		drawLeftUnselectedBorder(gc);
-	// If it is the last one then draw a line
-	if (index > parent.selectedIndex)
-		drawRightUnselectedBorder(gc);
-
-	// draw Image
-	int xDraw = x + LEFT_MARGIN;
-	Image image = getImage();
-	if (image != null && parent.showUnselectedImage) {
-		Rectangle imageBounds = image.getBounds();
-		// only draw image if it won't overlap with close button
-		int maxImageWidth = x + width - xDraw - RIGHT_MARGIN;
-		if (parent.showUnselectedClose && (parent.showClose || showClose)) {
-			maxImageWidth -= closeRect.width + INTERNAL_SPACING;
-		}
-		if (imageBounds.width < maxImageWidth) {		
-			int imageX = xDraw;
-			int imageHeight = imageBounds.height;
-			int imageY = y + (height - imageHeight) / 2;
-			imageY += parent.onBottom ? -1 : 1;
-			int imageWidth = imageBounds.width * imageHeight / imageBounds.height;
-			gc.drawImage(image, 
-				         imageBounds.x, imageBounds.y, imageBounds.width, imageBounds.height,
-				         imageX, imageY, imageWidth, imageHeight);
-			xDraw += imageWidth + INTERNAL_SPACING;
-		}
-	}
-	// draw Text
-	int textWidth = x + width - xDraw - RIGHT_MARGIN;
-	if (parent.showUnselectedClose && (parent.showClose || showClose)) {
-		textWidth -= closeRect.width + INTERNAL_SPACING;
-	}
-	if (textWidth > 0) {
-		Font gcFont = gc.getFont();
-		gc.setFont(font == null ? parent.getFont() : font);
-		if (shortenedText == null || shortenedTextWidth != textWidth) {
-			shortenedText = shortenText(gc, getText(), textWidth);
-			shortenedTextWidth = textWidth;
-		}	
-		Point extent = gc.textExtent(shortenedText, FLAGS);
-		int textY = y + (height - extent.y) / 2;
-		textY += parent.onBottom ? -1 : 1;
-		gc.setForeground(parent.getForeground());
-		gc.drawText(shortenedText, xDraw, textY, FLAGS);
-		gc.setFont(gcFont);
-	}
-	// draw close
-	if (parent.showUnselectedClose && (parent.showClose || showClose)) drawClose(gc);
-}
 /**
  * Returns a rectangle describing the receiver's size and location
  * relative to its parent.
@@ -683,9 +145,7 @@ void drawUnselected(GC gc) {
  */
 public Rectangle getBounds () {
 	//checkWidget();
-	int w = width;
-	if (!parent.simple && !parent.single && parent.indexOf(this) == parent.selectedIndex) w += parent.curveWidth - parent.curveIndent;
-	return new Rectangle(x, y, w, height);
+	return new Rectangle(x, y, width, height);
 }
 /**
 * Gets the control that is displayed in the content area of the tab item.
@@ -801,73 +261,7 @@ public boolean isShowing () {
 	checkWidget();
 	return showing;
 }
-void onPaint(GC gc, boolean isSelected) {
-	if (width == 0 || height == 0) return;
-	if (isSelected) {
-		drawSelected(gc);
-	} else {
-		drawUnselected(gc);
-	}
-}
-int preferredHeight(GC gc) {
-	Image image = getImage();
-	int h = (image == null) ? 0 : image.getBounds().height;
-	String text = getText();
-	if (font == null) {
-		h = Math.max(h, gc.textExtent(text, FLAGS).y);
-	} else {
-		Font gcFont = gc.getFont();
-		gc.setFont(font);
-		h = Math.max(h, gc.textExtent(text, FLAGS).y);
-		gc.setFont(gcFont);
-	}
-	return h + TOP_MARGIN + BOTTOM_MARGIN;
-}
-int preferredWidth(GC gc, boolean isSelected, boolean minimum) {
-	// NOTE: preferred width does not include the "dead space" caused
-	// by the curve.
-	if (isDisposed()) return 0;
-	int w = 0;
-	Image image = getImage();
-	if (image != null && (isSelected || parent.showUnselectedImage)) {
-		w += image.getBounds().width;
-	}
-	String text = null;
-	if (minimum) {
-		int minChars = parent.minChars;
-		text = minChars == 0 ? null : getText();
-		if (text != null && text.length() > minChars) {
-			if (useEllipses()) {
-				int end = minChars < ELLIPSIS.length() + 1 ? minChars : minChars - ELLIPSIS.length();
-				text = text.substring(0, end);
-				if (minChars > ELLIPSIS.length() + 1) text += ELLIPSIS;
-			} else {
-				int end = minChars;
-				text = text.substring(0, end);
-			}
-		}
-	} else {
-		text = getText();
-	}
-	if (text != null) {
-		if (w > 0) w += INTERNAL_SPACING;
-		if (font == null) {
-			w += gc.textExtent(text, FLAGS).x;
-		} else {
-			Font gcFont = gc.getFont();
-			gc.setFont(font);
-			w += gc.textExtent(text, FLAGS).x;
-			gc.setFont(gcFont);
-		}
-	}
-	if (parent.showClose || showClose) {
-		if (isSelected || parent.showUnselectedClose) {
-			if (w > 0) w += INTERNAL_SPACING;
-			w += CTabFolder.BUTTON_SIZE;
-		}
-	}
-	return w + LEFT_MARGIN + RIGHT_MARGIN;
-}
+
 /**
  * Sets the control that is used to fill the client area of
  * the tab folder when the user selects the tab item.
@@ -899,7 +293,14 @@ public void setControl (Control control) {
 			this.control.setBounds(parent.getClientArea ());
 			this.control.setVisible(true);
 		} else {
-			this.control.setVisible(false);
+		    int selectedIndex = parent.getSelectionIndex();
+		    Control selectedControl = null;
+		    if (selectedIndex != -1) {
+		    	selectedControl = parent.getItem(selectedIndex).getControl();
+		    }
+		    if (this.control != selectedControl) {
+		    	this.control.setVisible(false);
+		    }
 		}
 	}
 }
@@ -970,18 +371,25 @@ public void setImage (Image image) {
 			Rectangle bounds = image.getBounds();
 			if (bounds.width == oldBounds.width && bounds.height == oldBounds.height) {
 				if (showing) {
-					boolean selected = parent.indexOf(this) == parent.selectedIndex;
+					int index = parent.indexOf(this);
+					boolean selected = index == parent.selectedIndex;
 					if (selected || parent.showUnselectedImage) {
-						int imageX = x + LEFT_MARGIN, maxImageWidth;
+						CTabFolderRenderer renderer = parent.renderer;
+						Rectangle trim = renderer.computeTrim(index, SWT.NONE, 0, 0, 0, 0);
+						int imageX = x - trim.x, maxImageWidth;
 						if (selected) {
-							if (parent.single && (parent.showClose || showClose)) imageX += CTabFolder.BUTTON_SIZE; 
-							int rightEdge = Math.min (x + width, parent.getRightItemEdge());
-							maxImageWidth = rightEdge - imageX - RIGHT_MARGIN;
-							if (!parent.single && closeRect.width > 0) maxImageWidth -= closeRect.width + INTERNAL_SPACING;
+							GC gc = new GC(parent);
+							if (parent.single && (parent.showClose || showClose)) {
+								imageX += renderer.computeSize(CTabFolderRenderer.PART_CLOSE_BUTTON, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT).x; 
+							}
+							int rightEdge = Math.min (x + width, parent.getRightItemEdge(gc));
+							gc.dispose();
+							maxImageWidth = rightEdge - imageX - (trim.width + trim.x);
+							if (!parent.single && closeRect.width > 0) maxImageWidth -= closeRect.width + CTabFolderRenderer.INTERNAL_SPACING;
 						} else {
-							maxImageWidth = x + width - imageX - RIGHT_MARGIN;
+							maxImageWidth = x + width - imageX  - (trim.width + trim.x);
 							if (parent.showUnselectedClose && (parent.showClose || showClose)) {
-								maxImageWidth -= closeRect.width + INTERNAL_SPACING;
+								maxImageWidth -= closeRect.width + CTabFolderRenderer.INTERNAL_SPACING;
 							}
 						}
 						if (bounds.width < maxImageWidth) {
@@ -1037,6 +445,11 @@ public void setText (String string) {
  * tool tip, such as the Tree control on Windows, setting
  * the tool tip text to an empty string replaces the default,
  * causing no tool tip text to be shown.
+ * <p>
+ * The mnemonic indicator (character '&amp;') is not displayed in a tool tip.
+ * To display a single '&amp;' in the tool tip, the character '&amp;' can be 
+ * escaped by doubling it in the string.
+ * </p>
  *
  * @param string the new tool tip text (or null)
  *
diff --git a/org/eclipse/swt/custom/LineStyleEvent.java b/org/eclipse/swt/custom/LineStyleEvent.java
index 7b5e2b3..bfa853e 100644
--- a/org/eclipse/swt/custom/LineStyleEvent.java
+++ b/org/eclipse/swt/custom/LineStyleEvent.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 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
@@ -61,6 +61,13 @@ public class LineStyleEvent extends TypedEvent {
 	 */
 	public int indent;
 
+	/**
+	 * line wrap indent (input, output)
+	 * 
+	 * @since 3.6
+	 */
+	public int wrapIndent;
+
 	/** 
 	 * line justification (input, output)
 	 * 
@@ -79,6 +86,13 @@ public class LineStyleEvent extends TypedEvent {
 	 * @since 3.2
 	 */
 	public int bulletIndex;
+
+	/**
+	 * line tab stops (output)
+	 * @since 3.6
+	 */
+	public int[] tabStops;
+
 	
 	static final long serialVersionUID = 3906081274027192884L;
 
@@ -97,7 +111,9 @@ public LineStyleEvent(StyledTextEvent e) {
 	alignment = e.alignment;
 	justify = e.justify;
 	indent = e.indent;
+	wrapIndent = e.wrapIndent;
 	bullet = e.bullet;
 	bulletIndex = e.bulletIndex;
+	tabStops = e.tabStops;
 }
 }
diff --git a/org/eclipse/swt/custom/StackLayout.java b/org/eclipse/swt/custom/StackLayout.java
index cc76e97..afa0ad5 100644
--- a/org/eclipse/swt/custom/StackLayout.java
+++ b/org/eclipse/swt/custom/StackLayout.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -119,7 +119,6 @@ protected void layout(Composite composite, boolean flushCache) {
 	for (int i = 0; i < children.length; i++) {
 		children[i].setBounds(rect);
 		children[i].setVisible(children[i] == topControl);
-			
 	}
 }
 
diff --git a/org/eclipse/swt/custom/StyledText.java b/org/eclipse/swt/custom/StyledText.java
index 50e1587..c6915a2 100644
--- a/org/eclipse/swt/custom/StyledText.java
+++ b/org/eclipse/swt/custom/StyledText.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -68,7 +68,7 @@ import org.eclipse.swt.widgets.*;
  * </p><p>
  * <dl>
  * <dt><b>Styles:</b><dd>FULL_SELECTION, MULTI, READ_ONLY, SINGLE, WRAP
- * <dt><b>Events:</b><dd>ExtendedModify, LineGetBackground, LineGetSegments, LineGetStyle, Modify, Selection, Verify, VerifyKey
+ * <dt><b>Events:</b><dd>ExtendedModify, LineGetBackground, LineGetSegments, LineGetStyle, Modify, Selection, Verify, VerifyKey, OrientationChange
  * </dl>
  * </p><p>
  * IMPORTANT: This class is <em>not</em> intended to be subclassed.
@@ -117,6 +117,7 @@ public class StyledText extends Canvas {
 	int clientAreaHeight = 0;			// the client area height. Needed to calculate content width for new visible lines during Resize callback
 	int clientAreaWidth = 0;			// the client area width. Needed during Resize callback to determine if line wrap needs to be recalculated
 	int tabLength = 4;					// number of characters in a tab
+	int [] tabs;
 	int leftMargin;
 	int topMargin;
 	int rightMargin;
@@ -162,9 +163,11 @@ public class StyledText extends Canvas {
 	Cursor cursor;
 	int alignment;
 	boolean justify;
-	int indent;
+	int indent, wrapIndent;
 	int lineSpacing;
 	int alignmentMargin;
+	int newOrientation = SWT.NONE;
+	int accCaretOffset;
 	
 	//block selection
 	boolean blockSelection;
@@ -203,6 +206,7 @@ public class StyledText extends Canvas {
 		int pageWidth;									// width of a printer page in pixels
 		int startPage;									// first page to print
 		int endPage;									// last page to print
+		int scope;										// scope of print job
 		int startLine;									// first (wrapped) line to print
 		int endLine;									// last (wrapped) line to print
 		boolean singleLine;								// widget single line mode
@@ -228,7 +232,8 @@ public class StyledText extends Canvas {
 		startPage = 1;
 		endPage = Integer.MAX_VALUE;
 		PrinterData data = printer.getPrinterData();
-		if (data.scope == PrinterData.PAGE_RANGE) {
+		scope = data.scope;
+		if (scope == PrinterData.PAGE_RANGE) {
 			startPage = data.startPage;
 			endPage = data.endPage;
 			if (endPage < startPage) {
@@ -236,7 +241,7 @@ public class StyledText extends Canvas {
 				endPage = startPage;
 				startPage = temp;
 			}
-		} else if (data.scope == PrinterData.SELECTION) {
+		} else if (scope == PrinterData.SELECTION) {
 			selection = styledText.getSelectionRange();
 		}
 		printerRenderer = new StyledTextRenderer(printer, null);
@@ -265,9 +270,12 @@ public class StyledText extends Canvas {
 					printerRenderer.setLineBackground(i, 1, event.lineBackground);
 				}
 				if (styledText.isBidi()) {
-					int[] segments = styledText.getBidiSegments(lineOffset, line);
-					printerRenderer.setLineSegments(i, 1, segments);
-				}			
+					event = styledText.getBidiSegments(lineOffset, line);
+					if (event != null) {
+						printerRenderer.setLineSegments(i, 1, event.segments);
+						printerRenderer.setLineSegmentChars(i, 1, event.segmentsChars);
+					}
+				}
 				event = styledText.getLineStyleData(lineOffset, line);
 				if (event != null) {
 					printerRenderer.setLineIndent(i, 1, event.indent);
@@ -432,11 +440,10 @@ public class StyledText extends Canvas {
 		StyledTextContent content = printerRenderer.content;
 		startLine = 0;
 		endLine = singleLine ? 0 : content.getLineCount() - 1;
-		PrinterData data = printer.getPrinterData();
-		if (data.scope == PrinterData.PAGE_RANGE) {
+		if (scope == PrinterData.PAGE_RANGE) {
 			int pageSize = clientArea.height / lineHeight;//WRONG
 			startLine = (startPage - 1) * pageSize;
-		} else if (data.scope == PrinterData.SELECTION) {
+		} else if (scope == PrinterData.SELECTION) {
 			startLine = content.getLineAtOffset(selection.x);
 			if (selection.y > 0) {
 				endLine = content.getLineAtOffset(selection.x + selection.y - 1);
@@ -787,7 +794,7 @@ public class StyledText extends Canvas {
 	void write(String string, int start, int end) {
 		for (int index = start; index < end; index++) {
 			char ch = string.charAt(index);
-			if (ch > 0xFF && WriteUnicode) {
+			if (ch > 0x7F && WriteUnicode) {
 				// write the sub string from the last escaped character 
 				// to the current one. Fixes bug 21698.
 				if (index > start) {
@@ -1648,6 +1655,7 @@ static int checkStyle(int style) {
  * deleted lines.
  */
 void claimBottomFreeSpace() {
+	if (ime.getCompositionOffset() != -1) return;
 	if (isFixedLineHeight()) {
 		int newVerticalOffset = Math.max(0, renderer.getHeight() - clientAreaHeight);
 		if (newVerticalOffset < getVerticalScrollOffset()) {
@@ -2243,9 +2251,18 @@ void doBackspace() {
 			event.start = lineOffset + content.getLine(lineIndex - 1).length();
 			event.end = caretOffset;
 		} else {
+			boolean isSurrogate = false;
+			String lineText = content.getLine(lineIndex);
+			char ch = lineText.charAt(caretOffset - lineOffset - 1);
+			if (0xDC00 <= ch && ch <= 0xDFFF) {
+				if (caretOffset - lineOffset - 2 >= 0) {
+					ch = lineText.charAt(caretOffset - lineOffset - 2);
+					isSurrogate = 0xD800 <= ch && ch <= 0xDBFF;
+				}
+			}
 			TextLayout layout = renderer.getTextLayout(lineIndex);
-			int start = layout.getPreviousOffset(caretOffset - lineOffset, SWT.MOVEMENT_CHAR);
-			renderer.disposeTextLayout(layout); 
+			int start = layout.getPreviousOffset(caretOffset - lineOffset, isSurrogate ? SWT.MOVEMENT_CLUSTER : SWT.MOVEMENT_CHAR);
+			renderer.disposeTextLayout(layout);
 			event.start = start + lineOffset;
 			event.end = caretOffset;
 		}
@@ -2392,6 +2409,7 @@ void doBlockSelection(boolean sendEvent) {
 	if (sendEvent) {
 		sendSelectionEvent();
 	}
+	sendAccessibleTextCaretMoved();
 }
 /**
  * Replaces the selection with the character or insert the character at the 
@@ -3200,6 +3218,7 @@ void doSelection(int direction) {
 		internalRedrawRange(redrawStart, redrawEnd - redrawStart);
 		sendSelectionEvent();
 	}
+	sendAccessibleTextCaretMoved();
 }
 /**
  * Moves the caret to the next character or to the beginning of the 
@@ -3483,7 +3502,7 @@ public boolean getBlockSelection() {
 	checkWidget();
 	return blockSelection;
 }
-Rectangle getBlockSelectonPosition() {
+Rectangle getBlockSelectionPosition() {
 	int firstLine = getLineIndex(blockYAnchor - getVerticalScrollOffset());
 	int lastLine = getLineIndex(blockYLocation - getVerticalScrollOffset()); 
 	if (firstLine > lastLine) {
@@ -3530,14 +3549,14 @@ public Rectangle getBlockSelectionBounds() {
 	return rect;
 }
 Rectangle getBlockSelectionRectangle() {
-	Rectangle rect = getBlockSelectonPosition();
+	Rectangle rect = getBlockSelectionPosition();
 	rect.y = getLinePixel(rect.y);
 	rect.width = rect.width - rect.x;
 	rect.height =  getLinePixel(rect.height + 1) - rect.y;
 	return rect;
 }
 String getBlockSelectionText(String delimiter) {
-	Rectangle rect = getBlockSelectonPosition();
+	Rectangle rect = getBlockSelectionPosition();
 	int firstLine = rect.y;
 	int lastLine = rect.height;
 	int left = rect.x;
@@ -3616,7 +3635,7 @@ Rectangle getBoundsAtOffset(int offset) {
 	} else {
 		bounds = new Rectangle (0, 0, 0, renderer.getLineHeight());
 	}
-	if (offset == caretOffset) {
+	if (offset == caretOffset && !wordWrap) {
 		int lineEnd = lineOffset + line.length();
 		if (offset == lineEnd) {
 			bounds.width += getCaretWidth();
@@ -4214,6 +4233,64 @@ public int getLineIndex(int y) {
 	}
 	return line;
 }
+/**
+ * Returns the tab stops of the line at the given <code>index</code>.
+ * 
+ * @param index the index of the line
+ * 
+ * @return the tab stops for the line 
+ * 
+ * @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>
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_INVALID_ARGUMENT when the index is invalid</li>
+ * </ul>
+ * 
+ * @see #getTabStops()
+ * 
+ * @since 3.6
+ */
+public int[] getLineTabStops(int index) {
+	checkWidget();
+	if (index < 0 || index > content.getLineCount()) {
+		SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+	}
+	if (isListening(LineGetStyle)) return null;
+	int[] tabs = renderer.getLineTabStops(index, null);
+	if (tabs == null) tabs = this.tabs;
+	if (tabs == null) return new int [] {renderer.tabWidth};
+	int[] result = new int[tabs.length];
+	System.arraycopy(tabs, 0, result, 0, tabs.length);
+	return result;
+}
+/**
+ * Returns the wrap indentation of the line at the given <code>index</code>.
+ * 
+ * @param index the index of the line
+ * 
+ * @return the wrap indentation
+ * 
+ * @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>
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_INVALID_ARGUMENT when the index is invalid</li>
+ * </ul>
+ * 
+ * @see #getWrapIndent()
+ * 
+ * @since 3.6
+ */
+public int getLineWrapIndent(int index) {
+	checkWidget();
+	if (index < 0 || index > content.getLineCount()) {
+		SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+	}
+	return isListening(LineGetStyle) ? 0 : renderer.getLineWrapIndent(index, wrapIndent);
+}
 /** 
  * Returns the left margin.
  *
@@ -4395,6 +4472,10 @@ int getOffsetAtPoint(int x, int y, int[] trailing, boolean inTextOnly) {
  */
 public int getOrientation () {
 	checkWidget();
+	if (IS_MAC) {
+		int style = super.getStyle();
+		return style & (SWT.RIGHT_TO_LEFT | SWT.LEFT_TO_RIGHT);
+	}
 	return isMirrored() ? SWT.RIGHT_TO_LEFT : SWT.LEFT_TO_RIGHT;
 }
 /** 
@@ -4599,7 +4680,7 @@ public Point getSelectionRange() {
 public int[] getSelectionRanges() {
 	checkWidget();
 	if (blockSelection && blockXLocation != -1) {
-		Rectangle rect = getBlockSelectonPosition();
+		Rectangle rect = getBlockSelectionPosition();
 		int firstLine = rect.y;
 		int lastLine = rect.height;
 		int left = rect.x;
@@ -4692,63 +4773,48 @@ public String getSelectionText() {
 public int getStyle() {
 	int style = super.getStyle();
 	style &= ~(SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT | SWT.MIRRORED);
-	if (isMirrored()) {
-		style |= SWT.RIGHT_TO_LEFT | SWT.MIRRORED;
-	} else {
-		style |= SWT.LEFT_TO_RIGHT;
-	}
+	style |= getOrientation();
+	if (isMirrored()) style |= SWT.MIRRORED;
 	return style;
 }
 
-/**
- * Returns the text segments that should be treated as if they 
- * had a different direction than the surrounding text.
- *
- * @param lineOffset offset of the first character in the line. 
- * 	0 based from the beginning of the document.
- * @param line text of the line to specify bidi segments for
- * @return text segments that should be treated as if they had a
- * 	different direction than the surrounding text. Only the start 
- * 	index of a segment is specified, relative to the start of the 
- * 	line. Always starts with 0 and ends with the line length. 
- * @exception IllegalArgumentException <ul>
- *    <li>ERROR_INVALID_ARGUMENT - if the segment indices returned 
- * 		by the listener do not start with 0, are not in ascending order,
- * 		exceed the line length or have duplicates</li>
- * </ul>
- */
-int [] getBidiSegments(int lineOffset, String line) {
+StyledTextEvent getBidiSegments(int lineOffset, String line) {
 	if (!isBidi()) return null;
 	if (!isListening(LineGetSegments)) {
-		return getBidiSegmentsCompatibility(line, lineOffset);
+		StyledTextEvent event = new StyledTextEvent(content);
+		event.segments = getBidiSegmentsCompatibility(line, lineOffset);
+		return event;
 	}
 	StyledTextEvent event = sendLineEvent(LineGetSegments, lineOffset, line);
+	if (event == null || event.segments == null || event.segments.length == 0) return null;
 	int lineLength = line.length();
-	int[] segments;
-	if (event == null || event.segments == null || event.segments.length == 0) {
-		segments = new int[] {0, lineLength};
-	} else {
-		int segmentCount = event.segments.length;
-		
+	int[] segments = event.segments;
+	int segmentCount = segments.length;
+	if (event.segmentsChars == null) {
 		// test segment index consistency
-		if (event.segments[0] != 0) {
+		if (segments[0] != 0) {
 			SWT.error(SWT.ERROR_INVALID_ARGUMENT);
-		} 	
+		}
 		for (int i = 1; i < segmentCount; i++) {
-			if (event.segments[i] <= event.segments[i - 1] || event.segments[i] > lineLength) {
+			if (segments[i] <= segments[i - 1] || segments[i] > lineLength) {
 				SWT.error(SWT.ERROR_INVALID_ARGUMENT);
-			} 	
+			}
 		}
 		// ensure that last segment index is line end offset
-		if (event.segments[segmentCount - 1] != lineLength) {
+		if (segments[segmentCount - 1] != lineLength) {
 			segments = new int[segmentCount + 1];
 			System.arraycopy(event.segments, 0, segments, 0, segmentCount);
 			segments[segmentCount] = lineLength;
-		} else {
-			segments = event.segments;
+		}
+		event.segments = segments;
+	} else {
+		for (int i = 1; i < segmentCount; i++) {
+			if (event.segments[i] < event.segments[i - 1] || event.segments[i] > lineLength) {
+				SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+			}
 		}
 	}
-	return segments;
+	return event;
 }
 /**
  * @see #getBidiSegments
@@ -4994,11 +5060,33 @@ public StyleRange[] getStyleRanges(int start, int length, boolean includeRanges)
  *    <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 #getTabStops()
  */
 public int getTabs() {
 	checkWidget();
 	return tabLength;
 }
+
+/**
+ * Returns the tab list of the receiver.
+ *
+ * @return the tab list
+ * @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>
+ * 
+ * @since 3.6
+ */
+public int[] getTabStops() {
+	checkWidget();
+	if (tabs == null) return new int [] {renderer.tabWidth};
+	int[] result = new int[tabs.length];
+	System.arraycopy(tabs, 0, result, 0, tabs.length);
+	return result;
+}
+
 /**
  * Returns a copy of the widget content.
  *
@@ -5241,12 +5329,15 @@ int getCaretLine() {
 }
 int getWrapWidth () {
 	if (wordWrap && !isSingleLine()) {
-		int width = clientAreaWidth - leftMargin - rightMargin - getCaretWidth();
+		int width = clientAreaWidth - leftMargin - rightMargin;
 		return width > 0 ? width : 1;
 	}
 	return -1;
 }
 int getWordNext (int offset, int movement) {
+	return getWordNext(offset, movement, false);
+}
+int getWordNext (int offset, int movement, boolean ignoreListener) {
 	int newOffset, lineOffset;
 	String lineText;
 	if (offset >= getCharCount()) {
@@ -5259,7 +5350,7 @@ int getWordNext (int offset, int movement) {
 		lineOffset = content.getOffsetAtLine(lineIndex);
 		lineText = content.getLine(lineIndex);
 		int lineLength = lineText.length();
-		if (offset == lineOffset + lineLength) {
+		if (offset >= lineOffset + lineLength) {
 			newOffset = content.getOffsetAtLine(lineIndex + 1);
 		} else {
 			TextLayout layout = renderer.getTextLayout(lineIndex);
@@ -5267,9 +5358,13 @@ int getWordNext (int offset, int movement) {
 			renderer.disposeTextLayout(layout);
 		}
 	}
+	if (ignoreListener) return newOffset; 
 	return sendWordBoundaryEvent(WordNext, movement, offset, newOffset, lineText, lineOffset);
 }
 int getWordPrevious(int offset, int movement) {
+	return getWordPrevious(offset, movement, false); 
+}
+int getWordPrevious(int offset, int movement, boolean ignoreListener) {
 	int newOffset, lineOffset;
 	String lineText;
 	if (offset <= 0) {
@@ -5286,11 +5381,13 @@ int getWordPrevious(int offset, int movement) {
 			int nextLineOffset = content.getOffsetAtLine(lineIndex - 1); 
 			newOffset = nextLineOffset + nextLineText.length();
 		} else {
+			int layoutOffset = Math.min(offset - lineOffset, lineText.length());
 			TextLayout layout = renderer.getTextLayout(lineIndex);
-			newOffset = lineOffset + layout.getPreviousOffset(offset - lineOffset, movement);
+			newOffset = lineOffset + layout.getPreviousOffset(layoutOffset, movement);
 			renderer.disposeTextLayout(layout); 
 		}
 	}
+	if (ignoreListener) return newOffset;
 	return sendWordBoundaryEvent(WordPrevious, movement, offset, newOffset, lineText, lineOffset);
 }
 /**
@@ -5303,6 +5400,24 @@ public boolean getWordWrap() {
 	checkWidget();
 	return wordWrap;
 }
+/**
+ * Returns the wrap indentation of the widget.
+ * 
+ * @return the wrap indentation
+ * 
+ * @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 #getLineWrapIndent(int)
+ * 
+ * @since 3.6
+ */
+public int getWrapIndent() {
+	checkWidget();
+	return wrapIndent;
+}
 /** 
  * Returns the location of the given offset.
  * <p>
@@ -5411,7 +5526,7 @@ int insertBlockSelectionText(String text, boolean fillWithSpaces) {
 			String line = lines[i];
 			int length = line.length();
 			if (length < maxLength) {
-				int numSpaces = maxLength - length;;
+				int numSpaces = maxLength - length;
 				StringBuffer buffer = new StringBuffer(length + numSpaces);
 				buffer.append(line);
 				for (int j = 0; j < numSpaces; j++) buffer.append(' ');
@@ -5421,7 +5536,7 @@ int insertBlockSelectionText(String text, boolean fillWithSpaces) {
 	}
 	int firstLine, lastLine, left, right;
 	if (blockXLocation != -1) {
-		Rectangle rect = getBlockSelectonPosition();
+		Rectangle rect = getBlockSelectionPosition();
 		firstLine = rect.y;
 		lastLine = rect.height;
 		left = rect.x;
@@ -5448,7 +5563,7 @@ int insertBlockSelectionText(String text, boolean fillWithSpaces) {
 }
 void insertBlockSelectionText(char key, int action) {
 	if (key == SWT.CR || key == SWT.LF) return;
-	Rectangle rect = getBlockSelectonPosition();
+	Rectangle rect = getBlockSelectionPosition();
 	int firstLine = rect.y;
 	int lastLine = rect.height;
 	int left = rect.x;
@@ -5692,7 +5807,7 @@ void handleCompositionChanged(Event event) {
 		caretDirection = SWT.NULL;
 	} else {
 		content.replaceTextRange(start, end - start, text);
-		setCaretOffset(ime.getCaretOffset(), SWT.DEFAULT);
+		int alignment = SWT.DEFAULT;
 		if (ime.getWideCaret()) {
 			start = ime.getCompositionOffset();
 			int lineIndex = getCaretLine();
@@ -5700,7 +5815,9 @@ void handleCompositionChanged(Event event) {
 			TextLayout layout = renderer.getTextLayout(lineIndex);	
 			caretWidth = layout.getBounds(start - lineOffset, start + length - 1 - lineOffset).width;
 			renderer.disposeTextLayout(layout);
+			alignment = OFFSET_LEADING;
 		}
+		setCaretOffset(ime.getCaretOffset(), alignment);
 	}
 	showCaret();
 }
@@ -5746,6 +5863,7 @@ void handleDispose(Event event) {
 	background = null;
 	foreground = null;
 	clipboard = null;
+	tabs = null;
 }
 /** 
  * Scrolls the widget horizontally.
@@ -5828,14 +5946,19 @@ void handleKeyDown(Event event) {
 	if (clipboardSelection == null) {
 		clipboardSelection = new Point(selection.x, selection.y);
 	}
+	newOrientation = SWT.NONE;
 	
 	Event verifyEvent = new Event();
 	verifyEvent.character = event.character;
 	verifyEvent.keyCode = event.keyCode;
+	verifyEvent.keyLocation = event.keyLocation;
 	verifyEvent.stateMask = event.stateMask;
 	verifyEvent.doit = true;
 	notifyListeners(VerifyKey, verifyEvent);
 	if (verifyEvent.doit) {
+		if ((event.stateMask & SWT.MODIFIER_MASK) == SWT.CTRL && event.keyCode == SWT.SHIFT && isBidiCaret()) {
+			newOrientation = event.keyLocation == SWT.LEFT ? SWT.LEFT_TO_RIGHT : SWT.RIGHT_TO_LEFT; 
+		}
 		handleKey(event);
 	}
 }
@@ -5851,6 +5974,18 @@ void handleKeyUp(Event event) {
 		}
 	}
 	clipboardSelection = null;
+	
+	if (newOrientation != SWT.NONE) {
+		if (newOrientation != getOrientation()) {
+			Event e = new Event();
+			e.doit = true;
+			notifyListeners(SWT.OrientationChange, e);
+			if (e.doit) {
+				setOrientation(newOrientation);
+			}
+		}
+		newOrientation = SWT.NONE;
+	}
 }
 /** 
  * Updates the caret location and selection if mouse button 1 has been 
@@ -6098,7 +6233,7 @@ void handleTextChanged(TextChangedEvent event) {
 		claimRightFreeSpace();
 	}
 	
-	sendAccessibleTextChanged(lastTextChangeStart, lastTextChangeNewCharCount, lastTextChangeReplaceCharCount);
+	sendAccessibleTextChanged(lastTextChangeStart, lastTextChangeNewCharCount, 0);
 	lastCharCount += lastTextChangeNewCharCount;
 	lastCharCount -= lastTextChangeReplaceCharCount;
 	setAlignment();
@@ -6136,7 +6271,7 @@ void handleTextChanging(TextChangingEvent event) {
 	} else {
 		scrollText(srcY, destY);
 	}
-
+	sendAccessibleTextChanged(lastTextChangeStart, 0, lastTextChangeReplaceCharCount);
 	renderer.textChanging(event);
 	
 	// Update the caret offset if it is greater than the length of the content.
@@ -6204,9 +6339,9 @@ void initializeAccessible() {
 	accessible.addAccessibleListener(new AccessibleAdapter() {
 		public void getName (AccessibleEvent e) {
 			String name = null;
-			Label label = getAssociatedLabel ();
-			if (label != null) {
-				name = stripMnemonic (label.getText());
+			String text = getAssociatedLabel ();
+			if (text != null) {
+				name = stripMnemonic (text);
 			}
 			e.result = name;
 		}
@@ -6215,28 +6350,426 @@ void initializeAccessible() {
 		}
 		public void getKeyboardShortcut(AccessibleEvent e) {
 			String shortcut = null;
-			Label label = getAssociatedLabel ();
-			if (label != null) {
-				String text = label.getText ();
-				if (text != null) {
-					char mnemonic = _findMnemonic (text);
-					if (mnemonic != '\0') {
-						shortcut = "Alt+"+mnemonic; //$NON-NLS-1$
-					}
+			String text = getAssociatedLabel ();
+			if (text != null) {
+				char mnemonic = _findMnemonic (text);
+				if (mnemonic != '\0') {
+					shortcut = "Alt+"+mnemonic; //$NON-NLS-1$
 				}
 			}
 			e.result = shortcut;
 		}
 	});
-	accessible.addAccessibleTextListener(new AccessibleTextAdapter() {
+	accessible.addAccessibleTextListener(new AccessibleTextExtendedAdapter() {
 		public void getCaretOffset(AccessibleTextEvent e) {
 			e.offset = StyledText.this.getCaretOffset();
 		}
+		public void setCaretOffset(AccessibleTextEvent e) {
+			StyledText.this.setCaretOffset(e.offset);
+			e.result = ACC.OK;
+		}
 		public void getSelectionRange(AccessibleTextEvent e) {
 			Point selection = StyledText.this.getSelectionRange();
 			e.offset = selection.x;
 			e.length = selection.y;
 		}
+		public void addSelection(AccessibleTextEvent e) {
+			StyledText st = StyledText.this;
+			Point point = st.getSelection();
+			if (point.x == point.y) {
+				int end = e.end;
+				if (end == -1) end = st.getCharCount();
+				st.setSelection(e.start, end);
+				e.result = ACC.OK;
+			}
+		}
+		public void getSelection(AccessibleTextEvent e) {
+			StyledText st = StyledText.this;
+			if (st.blockSelection && st.blockXLocation != -1) {
+				Rectangle rect = st.getBlockSelectionPosition();
+				int lineIndex = rect.y + e.index;
+				int linePixel = st.getLinePixel(lineIndex);
+				e.ranges = getRanges(rect.x, linePixel, rect.width, linePixel);
+				if (e.ranges.length > 0) {
+					e.start = e.ranges[0];
+					e.end = e.ranges[e.ranges.length - 1];
+				}
+			} else {
+				if (e.index == 0) {
+					Point point = st.getSelection();
+					e.start = point.x;
+					e.end = point.y;
+					if (e.start > e.end) {
+						int temp = e.start;
+						e.start = e.end;
+						e.end = temp;
+					}
+				}
+			}
+		}
+		public void getSelectionCount(AccessibleTextEvent e) {
+			StyledText st = StyledText.this;
+			if (st.blockSelection && st.blockXLocation != -1) {
+				Rectangle rect = st.getBlockSelectionPosition();
+				e.count = rect.height - rect.y + 1;
+			} else {
+				Point point = st.getSelection();
+				e.count = point.x == point.y ? 0 : 1; 
+			}
+		}
+		public void removeSelection(AccessibleTextEvent e) {
+			StyledText st = StyledText.this;
+			if (e.index == 0) {
+				if (st.blockSelection) {
+					st.clearBlockSelection(true, false);
+				} else {
+					st.clearSelection(false);
+				}
+				e.result = ACC.OK;
+			}
+		}
+		public void setSelection(AccessibleTextEvent e) {
+			if (e.index != 0) return;
+			StyledText st = StyledText.this;
+			Point point = st.getSelection();
+			if (point.x == point.y) return;
+			int end = e.end;
+			if (end == -1) end = st.getCharCount();
+			st.setSelection(e.start, end);
+			e.result = ACC.OK;
+		}
+		public void getCharacterCount(AccessibleTextEvent e) {
+			e.count = StyledText.this.getCharCount();
+		}
+		public void getOffsetAtPoint(AccessibleTextEvent e) {
+			StyledText st = StyledText.this;
+			Point point = new Point (e.x, e.y);
+			Display display = st.getDisplay();
+			point = display.map(null, st, point);
+			e.offset = st.getOffsetAtPoint(point.x, point.y, null, true);
+		}
+		public void getTextBounds(AccessibleTextEvent e) {
+			StyledText st = StyledText.this;
+			int start = e.start;
+			int end = e.end;
+			int contentLength = st.getCharCount();
+			start = Math.max(0, Math.min(start, contentLength));
+			end = Math.max(0, Math.min(end, contentLength));
+			if (start > end) {
+				int temp = start;
+				start = end;
+				end = temp;
+			}
+			int startLine = st.getLineAtOffset(start);
+			int endLine = st.getLineAtOffset(end);
+			Rectangle[] rects = new Rectangle[endLine - startLine + 1];
+			Rectangle bounds = null;
+			int index = 0;
+			Display display = st.getDisplay();
+			for (int lineIndex = startLine; lineIndex <= endLine; lineIndex++) {
+				Rectangle rect = new Rectangle(0, 0, 0, 0);
+				rect.y = st.getLinePixel(lineIndex);
+				rect.height = st.renderer.getLineHeight(lineIndex);
+				if (lineIndex == startLine) {
+					rect.x = st.getPointAtOffset(start).x;
+				} else {
+					rect.x = st.leftMargin - st.horizontalScrollOffset;
+				}
+				if (lineIndex == endLine) {
+					rect.width = st.getPointAtOffset(end).x - rect.x;
+				} else {
+					TextLayout layout = st.renderer.getTextLayout(lineIndex);
+					rect.width = layout.getBounds().width - rect.x;
+					st.renderer.disposeTextLayout(layout);
+				}
+				rects [index++] = rect = display.map(st, null, rect);
+				if (bounds == null) {
+					bounds = new Rectangle(rect.x, rect.y, rect.width, rect.height);
+				} else {
+					bounds.add(rect);
+				}
+			}
+			e.rectangles = rects;
+			if (bounds != null) {
+				e.x = bounds.x;
+				e.y = bounds.y;
+				e.width = bounds.width;
+				e.height = bounds.height;
+			}
+		}
+		int[] getRanges(int left, int top, int right, int bottom) {
+			StyledText st = StyledText.this;
+			int lineStart = st.getLineIndex(top);
+			int lineEnd = st.getLineIndex(bottom);
+			int count = lineEnd - lineStart + 1;
+			int[] ranges = new int [count * 2];
+			int index = 0;
+			for (int lineIndex = lineStart; lineIndex <= lineEnd; lineIndex++) {
+				String line = st.content.getLine(lineIndex);
+				int lineOffset = st.content.getOffsetAtLine(lineIndex);
+				int lineEndOffset = lineOffset + line.length();
+				int linePixel = st.getLinePixel(lineIndex);
+				int start = st.getOffsetAtPoint(left, linePixel, null, true);
+				if (start == -1) {
+					start = left < st.leftMargin ? lineOffset : lineEndOffset;
+				}
+				int[] trailing = new int[1];
+				int end = st.getOffsetAtPoint(right, linePixel, trailing, true);
+				if (end == -1) {
+					end = right < st.leftMargin ? lineOffset : lineEndOffset; 
+				} else {
+					end += trailing[0];
+				}
+				if (start > end) {
+					int temp = start;
+					start = end;
+					end = temp;
+				}
+				ranges[index++] = start;
+				ranges[index++] = end;
+			}
+			return ranges;
+		}
+		public void getRanges(AccessibleTextEvent e) {
+			StyledText st = StyledText.this;
+			Point point = new Point (e.x, e.y);
+			Display display = st.getDisplay();
+			point = display.map(null, st, point);
+			e.ranges = getRanges(point.x, point.y, point.x + e.width, point.y + e.height);
+			if (e.ranges.length > 0) {
+				e.start = e.ranges[0];
+				e.end = e.ranges[e.ranges.length - 1];
+			}
+		}
+		public void getText(AccessibleTextEvent e) {
+			StyledText st = StyledText.this;
+			int start = e.start;
+			int end = e.end;
+			int contentLength = st.getCharCount();
+			if (end == -1) end = contentLength;
+			start = Math.max(0, Math.min(start, contentLength));
+			end = Math.max(0, Math.min(end, contentLength));
+			if (start > end) {
+				int temp = start;
+				start = end;
+				end = temp;
+			}
+			int count = e.count;
+			switch (e.type) {
+				case ACC.TEXT_BOUNDARY_ALL:
+					//nothing to do
+					break;
+				case ACC.TEXT_BOUNDARY_CHAR: {
+					int newCount = 0;
+					if (count > 0) {
+						while (count-- > 0) {
+							int newEnd = st.getWordNext(end, SWT.MOVEMENT_CLUSTER);
+							if (newEnd == contentLength) break;
+							if (newEnd == end) break;
+							end = newEnd;
+							newCount++;
+						}
+						start = end;
+						end = st.getWordNext(end, SWT.MOVEMENT_CLUSTER);
+					} else {
+						while (count++ < 0) {
+							int newStart = st.getWordPrevious(start, SWT.MOVEMENT_CLUSTER);
+							if (newStart == start) break;
+							start = newStart;
+							newCount--;
+						}
+						end = st.getWordNext(start, SWT.MOVEMENT_CLUSTER);
+					}
+					count = newCount;
+					break;
+				}
+				case ACC.TEXT_BOUNDARY_WORD: {
+					int newCount = 0;
+					if (count > 0) {
+						while (count-- > 0) { 
+							int newEnd = st.getWordNext(end, SWT.MOVEMENT_WORD_START, true);
+							if (newEnd == end) break;
+							newCount++;
+							end = newEnd;
+						}
+						start = end;
+						end = st.getWordNext(start, SWT.MOVEMENT_WORD_END, true);
+					} else {
+						if (st.getWordPrevious(Math.min(start + 1, contentLength), SWT.MOVEMENT_WORD_START, true) == start) {
+							//start is a word start already
+							count++;
+						}
+						while (count <= 0) {
+							int newStart = st.getWordPrevious(start, SWT.MOVEMENT_WORD_START, true);
+							if (newStart == start) break;
+							count++;
+							start = newStart;
+							if (count != 0) newCount--;
+						}
+						if (count <= 0 && start == 0) {
+							end = start;
+						} else {
+							end = st.getWordNext(start, SWT.MOVEMENT_WORD_END, true);
+						}
+					}
+					count = newCount;
+					break;
+				}
+				case ACC.TEXT_BOUNDARY_LINE:
+					//TODO implement line
+				case ACC.TEXT_BOUNDARY_PARAGRAPH:
+				case ACC.TEXT_BOUNDARY_SENTENCE: {
+					int offset = count > 0 ? end : start;
+					int lineIndex = st.getLineAtOffset(offset) + count;
+					lineIndex = Math.max(0, Math.min(lineIndex, st.getLineCount() - 1));
+					start = st.getOffsetAtLine(lineIndex);
+					String line = st.getLine(lineIndex);
+					end = start + line.length();
+					count = lineIndex - st.getLineAtOffset(offset);
+					break;
+				}
+			}
+			e.start = start;
+			e.end = end;
+			e.count = count;
+			e.result = st.content.getTextRange(start, end - start);
+		}
+		public void getVisibleRanges(AccessibleTextEvent e) {
+			e.ranges = getRanges(leftMargin, topMargin, clientAreaWidth - rightMargin, clientAreaHeight - bottomMargin);
+			if (e.ranges.length > 0) {
+				e.start = e.ranges[0];
+				e.end = e.ranges[e.ranges.length - 1];
+			}
+		}
+		public void scrollText(AccessibleTextEvent e) {
+			StyledText st = StyledText.this;
+			int topPixel = getTopPixel(), horizontalPixel = st.getHorizontalPixel();
+			switch (e.type) {
+				case ACC.SCROLL_TYPE_ANYWHERE:
+				case ACC.SCROLL_TYPE_TOP_LEFT:
+				case ACC.SCROLL_TYPE_LEFT_EDGE:
+				case ACC.SCROLL_TYPE_TOP_EDGE: {
+					Rectangle rect = st.getBoundsAtOffset(e.start);
+					if (e.type != ACC.SCROLL_TYPE_TOP_EDGE) {
+						horizontalPixel = horizontalPixel + rect.x - st.leftMargin;
+					}
+					if (e.type != ACC.SCROLL_TYPE_LEFT_EDGE) {
+						topPixel = topPixel + rect.y - st.topMargin;
+					}
+					break;
+				}
+				case ACC.SCROLL_TYPE_BOTTOM_RIGHT:
+				case ACC.SCROLL_TYPE_BOTTOM_EDGE:
+				case ACC.SCROLL_TYPE_RIGHT_EDGE: {
+					Rectangle rect = st.getBoundsAtOffset(e.end - 1);
+					if (e.type != ACC.SCROLL_TYPE_BOTTOM_EDGE) {
+						horizontalPixel = horizontalPixel - st.clientAreaWidth + rect.x + rect.width + st.rightMargin;
+					}
+					if (e.type != ACC.SCROLL_TYPE_RIGHT_EDGE) {
+						topPixel = topPixel - st.clientAreaHeight + rect.y +rect.height + st.bottomMargin;
+					}
+					break;
+				}
+				case ACC.SCROLL_TYPE_POINT: {
+					Point point = new Point(e.x, e.y);
+					Display display = st.getDisplay();
+					point = display.map(null, st, point);
+					Rectangle rect = st.getBoundsAtOffset(e.start);
+					topPixel = topPixel - point.y + rect.y;
+					horizontalPixel = horizontalPixel - point.x + rect.x;
+					break;
+				}
+			}
+			st.setTopPixel(topPixel);
+			st.setHorizontalPixel(horizontalPixel);
+			e.result = ACC.OK;
+		}
+	});
+	accessible.addAccessibleAttributeListener(new AccessibleAttributeAdapter() {
+		public void getAttributes(AccessibleAttributeEvent e) {
+			StyledText st = StyledText.this;
+			e.leftMargin = st.getLeftMargin();
+			e.topMargin = st.getTopMargin();
+			e.rightMargin = st.getRightMargin();
+			e.bottomMargin = st.getBottomMargin();
+			e.tabStops = st.getTabStops();
+			e.justify = st.getJustify();
+			e.alignment = st.getAlignment();
+			e.indent = st.getIndent(); 
+		}
+		public void getTextAttributes(AccessibleTextAttributeEvent e) {
+			StyledText st = StyledText.this;
+			int contentLength = st.getCharCount();
+			if (!isListening(LineGetStyle) && st.renderer.styleCount == 0) {
+				e.start = 0;
+				e.end = contentLength;
+				e.textStyle = new TextStyle(st.getFont(), st.foreground, st.background);
+				return;
+			}
+			int offset = Math.max(0, Math.min(e.offset, contentLength - 1));
+			int lineIndex = st.getLineAtOffset(offset);
+			int lineOffset = st.getOffsetAtLine(lineIndex);
+			int lineCount = st.getLineCount();
+			offset = offset - lineOffset;
+			
+			TextLayout layout = st.renderer.getTextLayout(lineIndex);
+			int lineLength = layout.getText().length();
+			if (lineLength > 0) {
+				e.textStyle = layout.getStyle(Math.max(0, Math.min(offset, lineLength - 1)));
+			}
+			
+			// If no override info available, use defaults. Don't supply default colors, though.
+			if (e.textStyle == null) {
+				e.textStyle = new TextStyle(st.getFont(), st.foreground, st.background);
+			} else {
+				if (e.textStyle.foreground == null || e.textStyle.background == null || e.textStyle.font == null) {
+					TextStyle textStyle = new TextStyle(e.textStyle);
+					if (textStyle.foreground == null) textStyle.foreground = st.foreground;
+					if (textStyle.background == null) textStyle.background = st.background;
+					if (textStyle.font == null) textStyle.font = st.getFont();
+					e.textStyle = textStyle;
+				}
+			}
+			
+			//offset at line delimiter case
+			if (offset >= lineLength) {
+				e.start = lineOffset + lineLength;
+				if (lineIndex + 1 < lineCount) {
+					e.end = st.getOffsetAtLine(lineIndex + 1);
+				} else  {
+					e.end = contentLength;
+				}
+				return;
+			}
+			
+			int[] ranges = layout.getRanges();
+			st.renderer.disposeTextLayout(layout);
+			int index = 0;
+			int end = 0;
+			while (index < ranges.length) {
+				int styleStart = ranges[index++];
+				int styleEnd = ranges[index++];
+				if (styleStart <= offset && offset <= styleEnd) {
+					e.start = lineOffset + styleStart;
+					e.end = lineOffset + styleEnd + 1;
+					return;
+				}
+				if (styleStart > offset) {
+					e.start = lineOffset + end;
+					e.end = lineOffset + styleStart;
+					return;
+				}
+				end = styleEnd + 1;
+			}
+			if (index == ranges.length) {
+				e.start = lineOffset + end;
+				if (lineIndex + 1 < lineCount) {
+					e.end = st.getOffsetAtLine(lineIndex + 1);
+				} else  {
+					e.end = contentLength;
+				}
+			}
+		}
 	});
 	accessible.addAccessibleControlListener(new AccessibleControlAdapter() {
 		public void getRole(AccessibleControlEvent e) {
@@ -6248,6 +6781,8 @@ void initializeAccessible() {
 			if (isFocusControl()) state |= ACC.STATE_FOCUSED;
 			if (!isVisible()) state |= ACC.STATE_INVISIBLE;
 			if (!getEditable()) state |= ACC.STATE_READONLY;
+			if (isSingleLine()) state |= ACC.STATE_SINGLELINE;
+			else state |= ACC.STATE_MULTILINE;
 			e.detail = state;
 		}
 		public void getValue(AccessibleControlEvent e) {
@@ -6264,13 +6799,16 @@ void initializeAccessible() {
  * Return the Label immediately preceding the receiver in the z-order, 
  * or null if none. 
  */
-Label getAssociatedLabel () {
+String getAssociatedLabel () {
 	Control[] siblings = getParent ().getChildren ();
 	for (int i = 0; i < siblings.length; i++) {
 		if (siblings [i] == StyledText.this) {
-			if (i > 0 && siblings [i-1] instanceof Label) {
-				return (Label) siblings [i-1];
+			if (i > 0) {
+				Control sibling = siblings [i-1];
+				if (sibling instanceof Label) return ((Label) sibling).getText();
+				if (sibling instanceof CLabel) return ((CLabel) sibling).getText();
 			}
+			break;
 		}
 	}
 	return null;
@@ -6846,7 +7384,7 @@ void redrawLines(int startLine, int lineCount, boolean bottomChanged) {
 		startLine = partialTopIndex;
 	}
 	if (endLine > partialBottomIndex) {
-		endLine = partialBottomIndex;;
+		endLine = partialBottomIndex;
 	}
 	int redrawTop = getLinePixel(startLine);
 	int redrawBottom = getLinePixel(endLine + 1);
@@ -7260,6 +7798,7 @@ void resetCache(int firstLine, int count) {
 void resetSelection() {
 	selection.x = selection.y = caretOffset;
 	selectionAnchor = -1;
+	sendAccessibleTextCaretMoved();
 }
 
 public void scroll(int destX, int destY, int x, int y, int width, int height, boolean all) {
@@ -7288,9 +7827,8 @@ public void scroll(int destX, int destY, int x, int y, int width, int height, bo
  *	false=the widget was not scrolled, the given offset is not valid.
  */
 boolean scrollHorizontal(int pixels, boolean adjustScrollBar) {
-	if (pixels == 0) {
-		return false;
-	}
+	if (pixels == 0) return false;
+	if (wordWrap) return false;
 	ScrollBar horizontalBar = getHorizontalBar();
 	if (horizontalBar != null && adjustScrollBar) {
 		horizontalBar.setSelection(horizontalScrollOffset + pixels);
@@ -7395,6 +7933,12 @@ void scrollText(int srcY, int destY) {
 		super.redraw(leftMargin, clientAreaHeight - bottomMargin, scrollWidth, bottomMargin, false);
 	}
 }
+void sendAccessibleTextCaretMoved() {
+	if (caretOffset != accCaretOffset) {
+		accCaretOffset = caretOffset;
+		getAccessible().textCaretMoved(caretOffset);
+	}
+}
 void sendAccessibleTextChanged(int start, int newCharCount, int replaceCharCount) {
 	Accessible accessible = getAccessible();
 	if (replaceCharCount != 0) {
@@ -7466,6 +8010,7 @@ StyledTextEvent sendLineEvent(int eventType, int lineOffset, String line) {
 		event.text = line;
 		event.alignment = alignment;
 		event.indent = indent;
+		event.wrapIndent = wrapIndent;
 		event.justify = justify;
 		notifyListeners(eventType, event);
 	}
@@ -7832,7 +8377,6 @@ void setCaretLocation(Point location, int direction) {
 		} else {
 			caret.setLocation(location);
 		}
-		getAccessible().textCaretMoved(getCaretOffset());
 		if (direction != caretDirection) {
 			caretDirection = direction;
 			if (isDefaultCaret) {
@@ -7863,8 +8407,8 @@ void setCaretLocation(Point location, int direction) {
  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
  * </ul>
  * @exception IllegalArgumentException <ul>
- *   <li>ERROR_INVALID_ARGUMENT when either the start or the end of the selection range is inside a 
- * multi byte line delimiter (and thus neither clearly in front of or after the line delimiter)
+ *   <li>ERROR_INVALID_ARGUMENT when the offset is inside a multi byte line 
+ *   delimiter (and thus neither clearly in front of or after the line delimiter)
  * </ul>
  */
 public void setCaretOffset(int offset) {
@@ -8513,6 +9057,113 @@ public void setLineSpacing(int lineSpacing) {
 	setCaretLocation();
 	super.redraw();
 }
+/**
+ * Sets the tab stops of the specified lines.
+ * <p>
+ * Should not be called if a <code>LineStyleListener</code> has been set since the listener 
+ * maintains the line attributes.
+ * </p><p>
+ * All line attributes are maintained relative to the line text, not the 
+ * line index that is specified in this method call.
+ * During text changes, when entire lines are inserted or removed, the line 
+ * attributes that are associated with the lines after the change 
+ * will "move" with their respective text. An entire line is defined as 
+ * extending from the first character on a line to the last and including the 
+ * line delimiter. 
+ * </p><p>
+ * When two lines are joined by deleting a line delimiter, the top line 
+ * attributes take precedence and the attributes of the bottom line are deleted. 
+ * For all other text changes line attributes will remain unchanged.
+ * </p>
+ *  
+ * @param startLine first line the justify is applied to, 0 based
+ * @param lineCount number of lines the justify applies to.
+ * @param tabStops tab stops
+ * 
+ * @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>
+ * @exception IllegalArgumentException <ul>
+ *   <li>ERROR_INVALID_ARGUMENT when the specified line range is invalid</li>
+ * </ul>
+ * @see #setTabStops(int[])
+ * @since 3.6
+ */
+public void setLineTabStops(int startLine, int lineCount, int[] tabStops) {
+	checkWidget();
+	if (isListening(LineGetStyle)) return;
+	if (startLine < 0 || startLine + lineCount > content.getLineCount()) {
+		SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+	}
+	if (tabStops != null) {
+		int pos = 0;
+		int[] newTabs = new int[tabStops.length];
+		for (int i = 0; i < tabStops.length; i++) {
+			if (tabStops[i] < pos) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+			newTabs[i] = pos = tabStops[i];
+		}
+		renderer.setLineTabStops(startLine, lineCount, newTabs);
+	} else {
+		renderer.setLineTabStops(startLine, lineCount, null);
+	}
+	resetCache(startLine, lineCount);
+	redrawLines(startLine, lineCount, false);
+	int caretLine = getCaretLine();
+	if (startLine <= caretLine && caretLine < startLine + lineCount) {
+		setCaretLocation();
+	}
+}
+/**
+ * Sets the wrap indent of the specified lines.
+ * <p>
+ * Should not be called if a <code>LineStyleListener</code> has been set since the listener 
+ * maintains the line attributes.
+ * </p><p>
+ * All line attributes are maintained relative to the line text, not the 
+ * line index that is specified in this method call.
+ * During text changes, when entire lines are inserted or removed, the line 
+ * attributes that are associated with the lines after the change 
+ * will "move" with their respective text. An entire line is defined as 
+ * extending from the first character on a line to the last and including the 
+ * line delimiter. 
+ * </p><p>
+ * When two lines are joined by deleting a line delimiter, the top line 
+ * attributes take precedence and the attributes of the bottom line are deleted. 
+ * For all other text changes line attributes will remain unchanged.
+ * </p>
+ *
+ * @param startLine first line the wrap indent is applied to, 0 based
+ * @param lineCount number of lines the wrap indent applies to.
+ * @param wrapIndent line wrap indent
+ * 
+ * @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>
+ * @exception IllegalArgumentException <ul>
+ *   <li>ERROR_INVALID_ARGUMENT when the specified line range is invalid</li>
+ * </ul>
+ * @see #setWrapIndent(int)
+ * @since 3.6
+ */
+public void setLineWrapIndent(int startLine, int lineCount, int wrapIndent) {
+	checkWidget();
+	if (isListening(LineGetStyle)) return;
+	if (startLine < 0 || startLine + lineCount > content.getLineCount()) {
+		SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+	}
+	int oldBottom = getLinePixel(startLine + lineCount);
+	renderer.setLineWrapIndent(startLine, lineCount, wrapIndent);
+	resetCache(startLine, lineCount);
+	int newBottom = getLinePixel(startLine + lineCount);
+	redrawLines(startLine, lineCount, oldBottom != newBottom);
+	int caretLine = getCaretLine();
+	if (startLine <= caretLine && caretLine < startLine + lineCount) {
+		setCaretLocation();
+	}
+}
+
 /** 
  * Sets the color of the margins.
  * 
@@ -8838,6 +9489,7 @@ void setSelection(int start, int length, boolean sendEvent, boolean doBlock) {
 				setCaretOffset(end, PREVIOUS_OFFSET_TRAILING);
 			}
 			internalRedrawRange(selection.x, selection.y - selection.x);
+			sendAccessibleTextCaretMoved();
 		}
 	}
 }
@@ -9085,7 +9737,9 @@ void setStyleRanges(int start, int length, int[] ranges, StyleRange[] styles, bo
 			super.redraw(0, top, clientAreaWidth, bottom - top, false);		
 		}
 	}
+	int oldColumnX = columnX;
 	setCaretLocation();
+	columnX = oldColumnX;
 	doMouseLinkCursor();
 }
 /** 
@@ -9130,6 +9784,8 @@ public void setStyleRanges(StyleRange[] ranges) {
  *    <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 #setTabStops(int[])
  */
 public void setTabs(int tabs) {
 	checkWidget();	
@@ -9139,6 +9795,44 @@ public void setTabs(int tabs) {
 	setCaretLocation();
 	super.redraw();
 }
+
+/**
+ * Sets the receiver's tab list. Each value in the tab list specifies
+ * the space in pixels from the origin of the document to the respective
+ * tab stop.  The last tab stop width is repeated continuously.
+ * 
+ * @param tabs the new tab list (or null)
+ * 
+ * @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>
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_INVALID_ARGUMENT - if a tab stop is negavite or less than the previous stop in the list</li>
+ * </ul>
+ * 
+ * @see StyledText#getTabStops()
+ * 
+ * @since 3.6
+ */
+public void setTabStops(int [] tabs) {
+	checkWidget();
+	if (tabs != null) {
+		int pos = 0;
+		int[] newTabs = new int[tabs.length];
+		for (int i = 0; i < tabs.length; i++) {
+			if (tabs[i] < pos) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+			newTabs[i] = pos = tabs[i];
+		}
+		this.tabs = newTabs;
+	} else {
+		this.tabs = null;
+	}
+	resetCache(0, content.getLineCount());
+	setCaretLocation();
+	super.redraw();
+}
+
 /** 
  * Sets the widget content. 
  * If the widget has the SWT.SINGLE style and "text" contains more than 
@@ -9333,6 +10027,33 @@ public void setWordWrap(boolean wrap) {
 	setCaretLocation();
 	super.redraw();
 }
+/**
+ * Sets the wrap line indentation of the widget.
+ * <p>
+ * It is the amount of blank space, in pixels, at the beginning of each wrapped line.
+ * When a line wraps in several lines all the lines but the first one is indented
+ * by this amount. 
+ * </p>
+ * 
+ * @param wrapIndent the new wrap indent
+ *  
+ * @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 #setLineWrapIndent(int, int, int)
+ *  
+ * @since 3.6
+ */
+public void setWrapIndent(int wrapIndent) {
+	checkWidget();
+	if (this.wrapIndent == wrapIndent || wrapIndent < 0) return;
+	this.wrapIndent = wrapIndent;
+	resetCache(0, content.getLineCount());
+	setCaretLocation();
+	super.redraw();	
+}
 boolean showLocation(Rectangle rect, boolean scrollPage) {
 	boolean scrolled = false;
 	if (rect.y < topMargin) {
diff --git a/org/eclipse/swt/custom/StyledTextEvent.java b/org/eclipse/swt/custom/StyledTextEvent.java
index 84e3331..98ee4ef 100644
--- a/org/eclipse/swt/custom/StyledTextEvent.java
+++ b/org/eclipse/swt/custom/StyledTextEvent.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * Copyright (c) 2000, 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
@@ -22,13 +22,16 @@ class StyledTextEvent extends Event {
 	StyleRange[] styles;
 	int alignment;
 	int indent;
+	int wrapIndent;
 	boolean justify;
 	Bullet bullet;
 	int bulletIndex;
+	int[] tabStops;
 	// used by LineBackgroundEvent
 	Color lineBackground;
 	// used by BidiSegmentEvent
 	int[] segments;	
+	char[] segmentsChars;
 	// used by TextChangedEvent
 	int replaceCharCount; 	
 	int newCharCount; 
diff --git a/org/eclipse/swt/custom/StyledTextListener.java b/org/eclipse/swt/custom/StyledTextListener.java
index 166e911..d9f026b 100644
--- a/org/eclipse/swt/custom/StyledTextListener.java
+++ b/org/eclipse/swt/custom/StyledTextListener.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 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
@@ -41,6 +41,7 @@ public void handleEvent(Event e) {
 			BidiSegmentEvent segmentEvent = new BidiSegmentEvent((StyledTextEvent) e);
 			((BidiSegmentListener) eventListener).lineGetSegments(segmentEvent);
 			((StyledTextEvent) e).segments = segmentEvent.segments;
+			((StyledTextEvent) e).segmentsChars = segmentEvent.segmentsChars;
 			break;		
 		case StyledText.LineGetStyle:
 			LineStyleEvent lineStyleEvent = new LineStyleEvent((StyledTextEvent) e);
@@ -49,9 +50,11 @@ public void handleEvent(Event e) {
 			((StyledTextEvent) e).styles = lineStyleEvent.styles;
 			((StyledTextEvent) e).alignment = lineStyleEvent.alignment;
 			((StyledTextEvent) e).indent = lineStyleEvent.indent;
+			((StyledTextEvent) e).wrapIndent = lineStyleEvent.wrapIndent;
 			((StyledTextEvent) e).justify = lineStyleEvent.justify;
 			((StyledTextEvent) e).bullet = lineStyleEvent.bullet;
 			((StyledTextEvent) e).bulletIndex = lineStyleEvent.bulletIndex;
+			((StyledTextEvent) e).tabStops = lineStyleEvent.tabStops;
 			break;
 		case StyledText.PaintObject:
 			PaintObjectEvent paintObjectEvent = new PaintObjectEvent((StyledTextEvent) e);
diff --git a/org/eclipse/swt/custom/StyledTextRenderer.java b/org/eclipse/swt/custom/StyledTextRenderer.java
index 86dcf4d..f1e2fba 100644
--- a/org/eclipse/swt/custom/StyledTextRenderer.java
+++ b/org/eclipse/swt/custom/StyledTextRenderer.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -67,14 +67,20 @@ class StyledTextRenderer {
 	final static int INDENT = 1 << 2;
 	final static int JUSTIFY = 1 << 3;
 	final static int SEGMENTS = 1 << 5;
+	final static int TABSTOPS = 1 << 6;
+	final static int WRAP_INDENT = 1 << 7;
+	final static int SEGMENT_CHARS = 1 << 8;
 	
 	static class LineInfo {
 		int flags;
 		Color background;
 		int alignment;
 		int indent;
+		int wrapIndent;
 		boolean justify;
 		int[] segments;
+		char[] segmentsChars;
+		int[] tabStops;
 
 		public LineInfo() {
 		}
@@ -84,8 +90,11 @@ class StyledTextRenderer {
 				background = info.background;
 				alignment = info.alignment;
 				indent = info.indent;
+				wrapIndent = info.wrapIndent;
 				justify = info.justify;
 				segments = info.segments;
+				segmentsChars = info.segmentsChars;
+				tabStops = info.tabStops;
 			}
 		}
 	}
@@ -267,7 +276,7 @@ void clearLineStyle(int startLine, int count) {
 	for (int i = startLine; i < startLine + count; i++) {
 		LineInfo info = lines[i];
 		if (info != null) {
-			info.flags &= ~(ALIGNMENT | INDENT | JUSTIFY);
+			info.flags &= ~(ALIGNMENT | INDENT | WRAP_INDENT | JUSTIFY | TABSTOPS);
 			if (info.flags == 0) lines[i] = null;
 		}
 	}
@@ -333,7 +342,7 @@ void drawBullet(Bullet bullet, GC gc, int paintX, int paintY, int index, int lin
 	int type = bullet.type & (ST.BULLET_DOT|ST.BULLET_NUMBER|ST.BULLET_LETTER_LOWER|ST.BULLET_LETTER_UPPER);
 	switch (type) {
 		case ST.BULLET_DOT: string = "\u2022"; break;
-		case ST.BULLET_NUMBER: string = String.valueOf(index); break;
+		case ST.BULLET_NUMBER: string = String.valueOf(index + 1); break;
 		case ST.BULLET_LETTER_LOWER: string = String.valueOf((char) (index % 26 + 97)); break;
 		case ST.BULLET_LETTER_UPPER: string = String.valueOf((char) (index % 26 + 65)); break;
 	}
@@ -428,7 +437,7 @@ int drawLine(int lineIndex, int paintX, int paintY, GC gc, Color widgetBackgroun
 		if (styles[i].metrics != null) {
 			if (ranges == null) ranges = layout.getRanges();
 			int start = ranges[i << 1];
-			int length = ranges[(i << 1) + 1] - start;
+			int length = ranges[(i << 1) + 1] - start + 1;
 			Point point = layout.getLocation(start, false);
 			FontMetrics metrics = layout.getLineMetrics(layout.getLineIndex(start));
 			StyleRange style = (StyleRange)((StyleRange)styles[i]).clone();
@@ -568,6 +577,14 @@ int getLineIndent(int index, int defaultIndent) {
 	}
 	return defaultIndent;
 }
+int getLineWrapIndent(int index, int defaultWrapIndent) {
+	if (lines == null) return defaultWrapIndent;
+	LineInfo info = lines[index];
+	if (info != null && (info.flags & WRAP_INDENT) != 0) {
+		return info.wrapIndent;
+	}
+	return defaultWrapIndent;
+}
 boolean getLineJustify(int index, boolean defaultJustify) {
 	if (lines == null) return defaultJustify;
 	LineInfo info = lines[index];
@@ -576,13 +593,13 @@ boolean getLineJustify(int index, boolean defaultJustify) {
 	}
 	return defaultJustify;
 }
-int[] getLineSegments(int index, int[] defaultSegments) {
-	if (lines == null) return defaultSegments;
+int[] getLineTabStops(int index, int[] defaultTabStops) {
+	if (lines == null) return defaultTabStops;
 	LineInfo info = lines[index];
-	if (info != null && (info.flags & SEGMENTS) != 0) {
-		return info.segments;
+	if (info != null && (info.flags & TABSTOPS) != 0) {
+		return info.tabStops;
 	}
-	return defaultSegments;
+	return defaultTabStops;
 }
 int getRangeIndex(int offset, int low, int high) {
 	if (styleCount == 0) return 0;
@@ -756,28 +773,39 @@ TextLayout getTextLayout(int lineIndex, int orientation, int width, int lineSpac
 	String line = content.getLine(lineIndex);
 	int lineOffset = content.getOffsetAtLine(lineIndex);
 	int[] segments = null;
+	char[] segmentChars = null;
 	int indent = 0;
+	int wrapIndent = 0;
 	int alignment = SWT.LEFT;
 	boolean justify = false;
+	int[] tabs = {tabWidth};
 	Bullet bullet = null;
 	int[] ranges = null;
 	StyleRange[] styles = null;
 	int rangeStart = 0, styleCount = 0;
 	StyledTextEvent event = null;
 	if (styledText != null) {
+		event = styledText.getBidiSegments(lineOffset, line);
+		if (event != null) {
+			segments = event.segments;
+			segmentChars = event.segmentsChars;
+		}
 		event = styledText.getLineStyleData(lineOffset, line);
-		segments = styledText.getBidiSegments(lineOffset, line);
 		indent = styledText.indent;
+		wrapIndent = styledText.wrapIndent;
 		alignment = styledText.alignment;
 		justify = styledText.justify;
+		if (styledText.tabs != null) tabs = styledText.tabs;
 	}
 	if (event != null) {
 		indent = event.indent;
+		wrapIndent = event.wrapIndent;
 		alignment = event.alignment;
 		justify = event.justify;
 		bullet = event.bullet;
 		ranges = event.ranges;
 		styles = event.styles;
+		if (event.tabStops != null) tabs = event.tabStops;
 		if (styles != null) {
 			styleCount = styles.length;
 			if (styledText.isFixedLineHeight()) {
@@ -805,9 +833,12 @@ TextLayout getTextLayout(int lineIndex, int orientation, int width, int lineSpac
 			LineInfo info = lines[lineIndex];
 			if (info != null) {
 				if ((info.flags & INDENT) != 0) indent = info.indent;
+				if ((info.flags & WRAP_INDENT) != 0) wrapIndent = info.wrapIndent;
 				if ((info.flags & ALIGNMENT) != 0) alignment = info.alignment;
 				if ((info.flags & JUSTIFY) != 0) justify = info.justify;
 				if ((info.flags & SEGMENTS) != 0) segments = info.segments;
+				if ((info.flags & SEGMENT_CHARS) != 0) segmentChars = info.segmentsChars;
+				if ((info.flags & TABSTOPS) != 0) tabs = info.tabStops;
 			}
 		}
 		if (bulletsIndices != null) {
@@ -842,10 +873,12 @@ TextLayout getTextLayout(int lineIndex, int orientation, int width, int lineSpac
 	layout.setText(line);
 	layout.setOrientation(orientation);
 	layout.setSegments(segments);
+	layout.setSegmentsChars(segmentChars);
 	layout.setWidth(width);
 	layout.setSpacing(lineSpacing);
-	layout.setTabs(new int[]{tabWidth});
+	layout.setTabs(tabs);
 	layout.setIndent(indent);
+	layout.setWrapIndent(wrapIndent);
 	layout.setAlignment(alignment);
 	layout.setJustify(justify);
 	
@@ -1135,6 +1168,16 @@ void setLineIndent(int startLine, int count, int indent) {
 		lines[i].indent = indent;
 	}
 }
+void setLineWrapIndent(int startLine, int count, int wrapIndent) {
+	if (lines == null) lines = new LineInfo[lineCount];
+	for (int i = startLine; i < startLine + count; i++) {
+		if (lines[i] == null) {
+			lines[i] = new LineInfo();
+		}
+		lines[i].flags |= WRAP_INDENT;
+		lines[i].wrapIndent = wrapIndent;
+	}
+}
 void setLineJustify(int startLine, int count, boolean justify) {
 	if (lines == null) lines = new LineInfo[lineCount];
 	for (int i = startLine; i < startLine + count; i++) {
@@ -1155,6 +1198,26 @@ void setLineSegments(int startLine, int count, int[] segments) {
 		lines[i].segments = segments;
 	}
 }
+void setLineSegmentChars(int startLine, int count, char[] segmentChars) {
+	if (lines == null) lines = new LineInfo[lineCount];
+	for (int i = startLine; i < startLine + count; i++) {
+		if (lines[i] == null) {
+			lines[i] = new LineInfo();
+		}
+		lines[i].flags |= SEGMENT_CHARS;
+		lines[i].segmentsChars = segmentChars;
+	}
+}
+void setLineTabStops(int startLine, int count, int[] tabStops) {
+	if (lines == null) lines = new LineInfo[lineCount];
+	for (int i = startLine; i < startLine + count; i++) {
+		if (lines[i] == null) {
+			lines[i] = new LineInfo();
+		}
+		lines[i].flags |= TABSTOPS;
+		lines[i].tabStops = tabStops;
+	}
+}
 void setStyleRanges (int[] newRanges, StyleRange[] newStyles) {
 	if (newStyles == null) {
 		stylesSetCount = styleCount = 0;
diff --git a/org/eclipse/swt/custom/ViewFormLayout.java b/org/eclipse/swt/custom/ViewFormLayout.java
index 18d4b6d..20522f5 100644
--- a/org/eclipse/swt/custom/ViewFormLayout.java
+++ b/org/eclipse/swt/custom/ViewFormLayout.java
@@ -156,7 +156,10 @@ protected void layout(Composite composite, boolean flushCache) {
 			top = true;
 			int trim = computeTrim(center);
 			int w = rect.width - 2*form.marginWidth - 2*form.highlight - trim;
-			centerSize = computeChildSize(center, w, SWT.DEFAULT, false);
+			Point size = computeChildSize(center, w, SWT.DEFAULT, false);
+			if (size.x < centerSize.x) {
+				centerSize = size;
+			}
 			center.setBounds(rect.x + rect.width - form.marginWidth - form.highlight - centerSize.x, y, centerSize.x, centerSize.y);
 			y += centerSize.y + form.verticalSpacing;
 		}		
diff --git a/org/eclipse/swt/dnd/ClipboardProxy.java b/org/eclipse/swt/dnd/ClipboardProxy.java
index 6e122cc..1c53f72 100644
--- a/org/eclipse/swt/dnd/ClipboardProxy.java
+++ b/org/eclipse/swt/dnd/ClipboardProxy.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -30,6 +30,7 @@ class ClipboardProxy {
 	Object[] primaryClipboardData;
 	Transfer[] primaryClipboardDataTypes;
 
+	int /*long*/ clipboardOwner = OS.gtk_window_new(0);
 	Display display;
 	Clipboard activeClipboard = null;
 	Clipboard activePrimaryClipboard = null;
@@ -98,6 +99,8 @@ void dispose () {
 	clipboardDataTypes = null;
 	primaryClipboardData = null;
 	primaryClipboardDataTypes = null;
+	if (clipboardOwner != 0) OS.gtk_widget_destroy (clipboardOwner);
+	clipboardOwner = 0;
 }
 
 /**
@@ -158,23 +161,31 @@ boolean setData(Clipboard owner, Object[] data, Transfer[] dataTypes, int clipbo
 			offset += GtkTargetEntry.sizeof;
 		}
 		if ((clipboards & DND.CLIPBOARD) != 0) {
-			if (activeClipboard != null) OS.gtk_clipboard_clear(Clipboard.GTKCLIPBOARD);
 			clipboardData = data;
 			clipboardDataTypes = dataTypes;
 			int /*long*/ getFuncProc = getFunc.getAddress();
 			int /*long*/ clearFuncProc = clearFunc.getAddress();
-			if (!OS.gtk_clipboard_set_with_data(Clipboard.GTKCLIPBOARD, pTargetsList, entries.length, getFuncProc, clearFuncProc, 0)) {
+			/*
+			* Feature in GTK. When the contents are set again, clipboard_set_with_data() 
+			* invokes clearFunc and then, getFunc is not sequentially called. 
+			* If we clear the content before calling set_with_data(), then there is a fair 
+			* chance for other apps like Klipper to claim the ownership of the clipboard.
+			* The fix is to make sure that the content is not cleared before the data is
+			* set again. GTK does not invoke clearFunc for clipboard_set_with_owner()
+			* though we set the data again. So, this API has to be used whenever we
+			* are setting the contents.
+			*/
+			if (!OS.gtk_clipboard_set_with_owner (Clipboard.GTKCLIPBOARD, pTargetsList, entries.length, getFuncProc, clearFuncProc, clipboardOwner)) {
 				return false;
 			}
 			activeClipboard = owner;
 		}
 		if ((clipboards & DND.SELECTION_CLIPBOARD) != 0) {
-			if (activePrimaryClipboard != null) OS.gtk_clipboard_clear(Clipboard.GTKPRIMARYCLIPBOARD);
 			primaryClipboardData = data;
 			primaryClipboardDataTypes = dataTypes;
 			int /*long*/ getFuncProc = getFunc.getAddress();
 			int /*long*/ clearFuncProc = clearFunc.getAddress();
-			if (!OS.gtk_clipboard_set_with_data(Clipboard.GTKPRIMARYCLIPBOARD, pTargetsList, entries.length, getFuncProc, clearFuncProc, 0)) {
+			if (!OS.gtk_clipboard_set_with_owner (Clipboard.GTKPRIMARYCLIPBOARD, pTargetsList, entries.length, getFuncProc, clearFuncProc, clipboardOwner)) {
 				return false;
 			}
 			activePrimaryClipboard = owner;
diff --git a/org/eclipse/swt/dnd/DND.java b/org/eclipse/swt/dnd/DND.java
index 6879423..0cfec0a 100644
--- a/org/eclipse/swt/dnd/DND.java
+++ b/org/eclipse/swt/dnd/DND.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 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
@@ -14,7 +14,6 @@ package org.eclipse.swt.dnd;
 import org.eclipse.swt.*;
 
 /**
- *
  * Class DND contains all the constants used in defining a 
  * DragSource or a DropTarget.
  *
@@ -151,19 +150,19 @@ public class DND {
 	
 	/**
 	 * DropTarget drag under effect: An insertion mark is shown before the item under the cursor; applies to 
-	 * trees (value is 2).
+	 * tables and trees (value is 2).
 	 */
 	public static final int FEEDBACK_INSERT_BEFORE = 2;
 	
 	/**
-	 * DropTarget drag under effect:An insertion mark is shown after the item under the cursor; applies to
-	 * trees (value is 4).
+	 * DropTarget drag under effect: An insertion mark is shown after the item under the cursor; applies to
+	 * tables and trees (value is 4).
 	 */	
 	public static final int FEEDBACK_INSERT_AFTER = 4;
 	
 	/**
 	 * DropTarget drag under effect: The widget is scrolled up or down to allow the user to drop on items that 
-	 * are not currently visible;  applies to tables and trees (value is 8).
+	 * are not currently visible; applies to tables and trees (value is 8).
 	 */	
 	public static final int FEEDBACK_SCROLL = 8;
 	
diff --git a/org/eclipse/swt/dnd/DropTargetListener.java b/org/eclipse/swt/dnd/DropTargetListener.java
index 531a0de..9f30c84 100644
--- a/org/eclipse/swt/dnd/DropTargetListener.java
+++ b/org/eclipse/swt/dnd/DropTargetListener.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -51,7 +51,7 @@ public interface DropTargetListener extends SWTEventListener {
  * <li>(in,out)feedback
  * </ul></p>
  *
- * <p>The <code>operation</code> value is determined by the modifier keys pressed by the user.  
+ * <p>The <code>operations</code> value is determined by the modifier keys pressed by the user.  
  * If no keys are pressed the <code>event.detail</code> field is set to DND.DROP_DEFAULT.  
  * If the application does not set the <code>event.detail</code> to something other 
  * than <code>DND.DROP_DEFAULT</code> the operation will be set to the platform defined standard 
@@ -116,7 +116,7 @@ public void dragLeave(DropTargetEvent event);
  * <li>(in,out)feedback
  * </ul></p>
  *
- * <p>The <code>operation</code> value is determined by the modifier keys pressed by the user.  
+ * <p>The <code>operations</code> value is determined by the modifier keys pressed by the user.  
  * If no keys are pressed the <code>event.detail</code> field is set to DND.DROP_DEFAULT.  
  * If the application does not set the <code>event.detail</code> to something other than 
  * <code>DND.DROP_DEFAULT</code> the operation will be set to the platform defined standard default.</p>
@@ -154,7 +154,7 @@ public void dragOperationChanged(DropTargetEvent event);
  * <li>(in,out)feedback
  * </ul></p>
  *
- * <p>The <code>operation</code> value is determined by the value assigned to 
+ * <p>The <code>operations</code> value is determined by the value assigned to 
  * <code>currentDataType</code> in previous dragEnter and dragOver calls.</p>
  * 
  * <p>The <code>currentDataType</code> value is determined by the value assigned to 
diff --git a/org/eclipse/swt/dnd/ImageTransfer.java b/org/eclipse/swt/dnd/ImageTransfer.java
index cf28027..c4875c1 100644
--- a/org/eclipse/swt/dnd/ImageTransfer.java
+++ b/org/eclipse/swt/dnd/ImageTransfer.java
@@ -141,7 +141,6 @@ public Object nativeToJava(TransferData transferData) {
 		OS.gdk_pixbuf_loader_close(loader, null);
 		int /*long*/ pixbuf = OS.gdk_pixbuf_loader_get_pixbuf(loader);
 		if (pixbuf != 0) {
-			OS.g_object_ref(pixbuf);
 			int /*long*/ [] pixmap_return = new int /*long*/ [1];
 			OS.gdk_pixbuf_render_pixmap_and_mask(pixbuf, pixmap_return, null, 0);
 			int /*long*/ handle = pixmap_return[0];
@@ -156,11 +155,11 @@ public Object nativeToJava(TransferData transferData) {
 }
 
 protected int[] getTypeIds(){
-	return new int[]{JPEG_ID, PNG_ID, BMP_ID, EPS_ID, PCX_ID, PPM_ID, RGB_ID, TGA_ID, XBM_ID, XPM_ID, XV_ID};	
+	return new int[]{PNG_ID, BMP_ID, EPS_ID, JPEG_ID, PCX_ID, PPM_ID, RGB_ID, TGA_ID, XBM_ID, XPM_ID, XV_ID};	
 }
 
 protected String[] getTypeNames(){
-	return new String[]{JPEG, PNG, BMP, EPS, PCX, PPM, RGB, TGA, XBM, XPM, XV};
+	return new String[]{PNG, BMP, EPS, JPEG, PCX, PPM, RGB, TGA, XBM, XPM, XV};
 }
 
 boolean checkImage(Object object) {
diff --git a/org/eclipse/swt/dnd/TableDropTargetEffect.java b/org/eclipse/swt/dnd/TableDropTargetEffect.java
index f4ab889..dc81136 100644
--- a/org/eclipse/swt/dnd/TableDropTargetEffect.java
+++ b/org/eclipse/swt/dnd/TableDropTargetEffect.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 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
@@ -169,12 +169,12 @@ public class TableDropTargetEffect extends DropTargetEffect {
 			}
 		}
 		if (path[0] != 0) {
-			int position = 0;
+			int position = -1;
 			if ((effect & DND.FEEDBACK_SELECT) != 0) position = OS.GTK_TREE_VIEW_DROP_INTO_OR_BEFORE;
-			//if ((effect & DND.FEEDBACK_INSERT_BEFORE) != 0) position = OS.GTK_TREE_VIEW_DROP_BEFORE;
-			//if ((effect & DND.FEEDBACK_INSERT_AFTER) != 0) position = OS.GTK_TREE_VIEW_DROP_AFTER;
-			if (position != 0) {
-				OS.gtk_tree_view_set_drag_dest_row(handle, path[0], OS.GTK_TREE_VIEW_DROP_INTO_OR_BEFORE);
+			if ((effect & DND.FEEDBACK_INSERT_BEFORE) != 0) position = OS.GTK_TREE_VIEW_DROP_BEFORE;
+			if ((effect & DND.FEEDBACK_INSERT_AFTER) != 0) position = OS.GTK_TREE_VIEW_DROP_AFTER;
+			if (position != -1) {
+				OS.gtk_tree_view_set_drag_dest_row(handle, path[0], position);
 			} else {
 				OS.gtk_tree_view_set_drag_dest_row(handle, 0, OS.GTK_TREE_VIEW_DROP_BEFORE);
 			}
diff --git a/org/eclipse/swt/dnd/TextTransfer.java b/org/eclipse/swt/dnd/TextTransfer.java
index 6a6dabc..63ce761 100644
--- a/org/eclipse/swt/dnd/TextTransfer.java
+++ b/org/eclipse/swt/dnd/TextTransfer.java
@@ -25,6 +25,12 @@ import org.eclipse.swt.internal.gtk.*;
  *     String textData = "Hello World";
  * </code></pre>
  * 
+ * <p>Note the <code>TextTransfer</code> does not change the content of the text
+ * data. For a better integration with the platform, the application should convert
+ * the line delimiters used in the text data to the standard line delimiter used by the
+ * platform.
+ * </p>
+ * 
  * @see Transfer
  */
 public class TextTransfer extends ByteArrayTransfer {
diff --git a/org/eclipse/swt/dnd/TransferData.java b/org/eclipse/swt/dnd/TransferData.java
index 275a9da..dc8fcfb 100644
--- a/org/eclipse/swt/dnd/TransferData.java
+++ b/org/eclipse/swt/dnd/TransferData.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -37,6 +37,8 @@ public class TransferData {
 	 * within the packages provided by SWT. It is not available on all
 	 * platforms and should never be accessed from application code.
 	 * </p>
+	 * 
+	 * @noreference This field is not intended to be referenced by clients.
 	 */
 	public int /*long*/ type;
 	
@@ -51,6 +53,8 @@ public class TransferData {
 	 * </p>
 	 * 
 	 * @see TransferData#format for the size of one unit
+	 * 
+	 * @noreference This field is not intended to be referenced by clients.
 	 */
 	public int length;
 	
@@ -65,6 +69,8 @@ public class TransferData {
 	 * </p>
  	 * 
  	 * This is most commonly 8 bits.
+ 	 * 
+ 	 * @noreference This field is not intended to be referenced by clients.
 	 */
 	public int format;
 	
@@ -77,6 +83,8 @@ public class TransferData {
 	 * within the packages provided by SWT. It is not available on all
 	 * platforms and should never be accessed from application code.
 	 * </p>
+	 * 
+	 * @noreference This field is not intended to be referenced by clients.
 	 */
 	public int /*long*/ pValue;
 
@@ -92,6 +100,8 @@ public class TransferData {
 	 * </p>
  	 * <p>The value of result is 1 if the conversion was successful.
 	 * The value of result is 0 if the conversion failed.</p>
+	 * 
+	 * @noreference This field is not intended to be referenced by clients.
 	 */
 	public int result;
 	
diff --git a/org/eclipse/swt/events/KeyEvent.java b/org/eclipse/swt/events/KeyEvent.java
index 7a3a1d7..03ecb92 100644
--- a/org/eclipse/swt/events/KeyEvent.java
+++ b/org/eclipse/swt/events/KeyEvent.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 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
@@ -59,11 +59,36 @@ public class KeyEvent extends TypedEvent {
 	public int keyCode;
 	
 	/**
-	 * the state of the keyboard modifier keys at the time
-	 * the event was generated, as defined by the key code
-	 * constants in class <code>SWT</code>.
+	 * depending on the event, the location of key specified by the
+	 * keyCode or character. The possible values for this field are
+	 * <code>SWT.LEFT</code>, <code>SWT.RIGHT</code>, <code>SWT.KEYPAD</code>,
+	 * or <code>SWT.NONE</code> representing the main keyboard area.
+	 * <p>
+	 * The location field can be used to differentiate key events that have
+	 * the same key code and character but are generated by different keys
+	 * on the keyboard. For example, a key down event with the key code equal
+	 * to SWT.SHIFT can be generated by the left and the right shift keys on
+	 * the keyboard.
+	 * </p><p>
+	 * The location field can only be used to determine the location of
+	 * the key code or character in the current event. It does not include
+	 * information about the location of modifiers in the state mask.
+	 * </p>
 	 * 
-	 * @see org.eclipse.swt.SWT
+	 * @see org.eclipse.swt.SWT#LEFT
+	 * @see org.eclipse.swt.SWT#RIGHT
+	 * @see org.eclipse.swt.SWT#KEYPAD
+	 * 
+	 * @since 3.6
+	 */
+	public int keyLocation;
+	
+	/**
+	 * the state of the keyboard modifier keys and mouse masks
+	 * at the time the event was generated.
+	 * 
+	 * @see org.eclipse.swt.SWT#MODIFIER_MASK
+	 * @see org.eclipse.swt.SWT#BUTTON_MASK
 	 */
 	public int stateMask;
 	
@@ -85,6 +110,7 @@ public KeyEvent(Event e) {
 	super(e);
 	this.character = e.character;
 	this.keyCode = e.keyCode;
+	this.keyLocation = e.keyLocation;
 	this.stateMask = e.stateMask;
 	this.doit = e.doit;
 }
@@ -100,6 +126,7 @@ public String toString() {
 	return string.substring (0, string.length() - 1) // remove trailing '}'
 		+ " character='" + ((character == 0) ? "\\0" : "" + character) + "'"
 		+ " keyCode=" + keyCode
+		+ " keyLocation=" + keyLocation
 		+ " stateMask=" + stateMask
 		+ " doit=" + doit
 		+ "}";
diff --git a/org/eclipse/swt/events/MouseEvent.java b/org/eclipse/swt/events/MouseEvent.java
index 19da769..2730002 100644
--- a/org/eclipse/swt/events/MouseEvent.java
+++ b/org/eclipse/swt/events/MouseEvent.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 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
@@ -42,6 +42,9 @@ public class MouseEvent extends TypedEvent {
 	/**
 	 * the state of the keyboard modifier keys and mouse masks
 	 * at the time the event was generated.
+	 * 
+	 * @see org.eclipse.swt.SWT#MODIFIER_MASK
+	 * @see org.eclipse.swt.SWT#BUTTON_MASK
 	 */
 	public int stateMask;
 	
diff --git a/org/eclipse/swt/graphics/Color.java b/org/eclipse/swt/graphics/Color.java
index e3fae9e..7a57f02 100644
--- a/org/eclipse/swt/graphics/Color.java
+++ b/org/eclipse/swt/graphics/Color.java
@@ -41,6 +41,8 @@ public final class Color extends Resource {
 	 * within the packages provided by SWT. It is not available on all
 	 * platforms and should never be accessed from application code.
 	 * </p>
+	 * 
+	 * @noreference This field is not intended to be referenced by clients.
 	 */
 	public GdkColor handle;
 
@@ -224,7 +226,7 @@ public RGB getRGB () {
  * @param device the device on which to allocate the color
  * @param handle the handle for the color
  * 
- * @private
+ * @noreference This method is not intended to be referenced by clients.
  */
 public static Color gtk_new(Device device, GdkColor gdkColor) {
 	Color color = new Color(device);
@@ -267,7 +269,7 @@ void init(int red, int green, int blue) {
  * <p>
  * This method gets the dispose state for the color.
  * When a color has been disposed, it is an error to
- * invoke any other method using the color.
+ * invoke any other method (except {@link #dispose()}) using the color.
  *
  * @return <code>true</code> when the color is disposed and <code>false</code> otherwise
  */
diff --git a/org/eclipse/swt/graphics/Cursor.java b/org/eclipse/swt/graphics/Cursor.java
index ce5768c..96dfe32 100644
--- a/org/eclipse/swt/graphics/Cursor.java
+++ b/org/eclipse/swt/graphics/Cursor.java
@@ -51,6 +51,8 @@ public final class Cursor extends Resource {
 	 * within the packages provided by SWT. It is not available on all
 	 * platforms and should never be accessed from application code.
 	 * </p>
+	 * 
+	 * @noreference This field is not intended to be referenced by clients.
 	 */
 	public int /*long*/ handle;
 
@@ -90,6 +92,10 @@ Cursor (Device device) {
  * <p>
  * You must dispose the cursor when it is no longer required. 
  * </p>
+ * NOTE:
+ * It is recommended to use {@link org.eclipse.swt.widgets.Display#getSystemCursor(int)}
+ * instead of using this constructor. This way you can avoid the 
+ * overhead of disposing the Cursor resource.
  *
  * @param device the device on which to allocate the cursor
  * @param style the style of cursor to allocate
@@ -477,7 +483,7 @@ public boolean equals(Object object) {
  * @param device the device on which to allocate the color
  * @param handle the handle for the cursor
  * 
- * @private
+ * @noreference This method is not intended to be referenced by clients.
  */
 public static Cursor gtk_new(Device device, int /*long*/ handle) {
 	Cursor cursor = new Cursor(device);
@@ -505,7 +511,7 @@ public int hashCode() {
  * <p>
  * This method gets the dispose state for the cursor.
  * When a cursor has been disposed, it is an error to
- * invoke any other method using the cursor.
+ * invoke any other method (except {@link #dispose()}) using the cursor.
  *
  * @return <code>true</code> when the cursor is disposed and <code>false</code> otherwise
  */
diff --git a/org/eclipse/swt/graphics/Device.java b/org/eclipse/swt/graphics/Device.java
index fbacfcf..7393351 100644
--- a/org/eclipse/swt/graphics/Device.java
+++ b/org/eclipse/swt/graphics/Device.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -33,6 +33,8 @@ public abstract class Device implements Drawable {
 	 * within the packages provided by SWT. It is not available on all
 	 * platforms and should never be accessed from application code.
 	 * </p>
+	 * 
+	 * @noreference This field is not intended to be referenced by clients.
 	 */
 	protected int /*long*/ xDisplay;
 	int /*long*/ shellHandle;
@@ -56,7 +58,7 @@ public abstract class Device implements Drawable {
 	int /*long*/ logProc;
 	Callback logCallback;
 	//NOT DONE - get list of valid names
-	String [] log_domains = {"GLib-GObject", "GLib", "GObject", "Pango", "ATK", "GdkPixbuf", "Gdk", "Gtk", "GnomeVFS"};
+	String [] log_domains = {"GLib-GObject", "GLib", "GObject", "Pango", "ATK", "GdkPixbuf", "Gdk", "Gtk", "GnomeVFS", "GIO"};
 	int [] handler_ids = new int [log_domains.length];
 	int warningLevel;
 	
@@ -649,6 +651,8 @@ protected void init () {
  *
  * @param data the platform specific GC data 
  * @return the platform specific GC handle
+ * 
+ * @noreference This method is not intended to be referenced by clients.
  */
 public abstract int /*long*/ internal_new_GC (GCData data);
 
@@ -664,6 +668,8 @@ public abstract int /*long*/ internal_new_GC (GCData data);
  *
  * @param hDC the platform specific GC handle
  * @param data the platform specific GC data 
+ * 
+ * @noreference This method is not intended to be referenced by clients.
  */
 public abstract void internal_dispose_GC (int /*long*/ handle, GCData data);
 
diff --git a/org/eclipse/swt/graphics/DeviceData.java b/org/eclipse/swt/graphics/DeviceData.java
index 6fc287f..f212af0 100644
--- a/org/eclipse/swt/graphics/DeviceData.java
+++ b/org/eclipse/swt/graphics/DeviceData.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -12,17 +12,43 @@ package org.eclipse.swt.graphics;
 
 
 public class DeviceData {
-	/*
-	* The following fields are platform dependent.
-	* <p>
-	* <b>IMPORTANT:</b> These fields are <em>not</em> part of the SWT
-	* public API. They are marked public only so that they can be shared
-	* within the packages provided by SWT. They are not available on all
-	* platforms and should never be accessed from application code.
-	* </p>
-	*/
+	/**
+	 * This field is platform dependent.
+	 * <p>
+	 * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT
+	 * public API. It is marked protected only so that it can be shared
+	 * within the packages provided by SWT. It is not available on all
+	 * platforms and should never be accessed from application code.
+	 * </p>
+	 * 
+	 * @noreference This field is not intended to be referenced by clients.
+	 */
 	public String display_name;
+
+	/**
+	 * This field is platform dependent.
+	 * <p>
+	 * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT
+	 * public API. It is marked protected only so that it can be shared
+	 * within the packages provided by SWT. It is not available on all
+	 * platforms and should never be accessed from application code.
+	 * </p>
+	 * 
+	 * @noreference This field is not intended to be referenced by clients.
+	 */
 	public String application_name;
+
+	/**
+	 * This field is platform dependent.
+	 * <p>
+	 * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT
+	 * public API. It is marked protected only so that it can be shared
+	 * within the packages provided by SWT. It is not available on all
+	 * platforms and should never be accessed from application code.
+	 * </p>
+	 * 
+	 * @noreference This field is not intended to be referenced by clients.
+	 */
 	public String application_class;
 
 	/*
diff --git a/org/eclipse/swt/graphics/Drawable.java b/org/eclipse/swt/graphics/Drawable.java
index 2d909d1..141268b 100644
--- a/org/eclipse/swt/graphics/Drawable.java
+++ b/org/eclipse/swt/graphics/Drawable.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -41,6 +41,8 @@ public interface Drawable {
  *
  * @param data the platform specific GC data 
  * @return the platform specific GC handle
+ * 
+ * @noreference This method is not intended to be referenced by clients.
  */
  
 public int /*long*/ internal_new_GC (GCData data);
@@ -57,6 +59,8 @@ public int /*long*/ internal_new_GC (GCData data);
  *
  * @param handle the platform specific GC handle
  * @param data the platform specific GC data 
+ * 
+ * @noreference This method is not intended to be referenced by clients.
  */
 public void internal_dispose_GC (int /*long*/ handle, GCData data);
 
diff --git a/org/eclipse/swt/graphics/Font.java b/org/eclipse/swt/graphics/Font.java
index 3607e38..2619dbb 100644
--- a/org/eclipse/swt/graphics/Font.java
+++ b/org/eclipse/swt/graphics/Font.java
@@ -41,6 +41,8 @@ public final class Font extends Resource {
 	 * within the packages provided by SWT. It is not available on all
 	 * platforms and should never be accessed from application code.
 	 * </p>
+	 * 
+	 * @noreference This field is not intended to be referenced by clients.
 	 */
 	public int /*long*/ handle;
 	
@@ -213,7 +215,7 @@ public FontData[] getFontData() {
  * @param device the device on which to allocate the color
  * @param handle the handle for the font
  * 
- * @private
+ * @noreference This method is not intended to be referenced by clients.
  */
 public static Font gtk_new(Device device, int /*long*/ handle) {
 	Font font = new Font(device);
@@ -266,7 +268,7 @@ void init(String name, float height, int style, byte[] fontString) {
  * <p>
  * This method gets the dispose state for the font.
  * When a font has been disposed, it is an error to
- * invoke any other method using the font.
+ * invoke any other method (except {@link #dispose()}) using the font.
  *
  * @return <code>true</code> when the font is disposed and <code>false</code> otherwise
  */
diff --git a/org/eclipse/swt/graphics/FontData.java b/org/eclipse/swt/graphics/FontData.java
index 6d15004..39a350c 100644
--- a/org/eclipse/swt/graphics/FontData.java
+++ b/org/eclipse/swt/graphics/FontData.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -48,6 +48,8 @@ public final class FontData {
 	 * within the packages provided by SWT. It is not available on all
 	 * platforms and should never be accessed from application code.
 	 * </p>
+	 * 
+	 * @noreference This field is not intended to be referenced by clients.
 	 */
 	public String name;
 
@@ -60,6 +62,8 @@ public final class FontData {
 	 * within the packages provided by SWT. It is not available on all
 	 * platforms and should never be accessed from application code.
 	 * </p>
+	 * 
+	 * @noreference This field is not intended to be referenced by clients.
 	 */
 	public float height;
 
@@ -72,6 +76,8 @@ public final class FontData {
 	 * within the packages provided by SWT. It is not available on all
 	 * platforms and should never be accessed from application code.
 	 * </p>
+	 * 
+	 * @noreference This field is not intended to be referenced by clients.
 	 */
 	public int style;
 	
@@ -84,6 +90,8 @@ public final class FontData {
 	 * within the packages provided by SWT. It is not available on all
 	 * platforms and should never be accessed from application code.
 	 * </p>
+	 * 
+	 * @noreference This field is not intended to be referenced by clients.
 	 */
 	public byte[] string;
 
diff --git a/org/eclipse/swt/graphics/GC.java b/org/eclipse/swt/graphics/GC.java
index 78c020d..ac76e2c 100644
--- a/org/eclipse/swt/graphics/GC.java
+++ b/org/eclipse/swt/graphics/GC.java
@@ -66,6 +66,8 @@ public final class GC extends Resource {
 	 * within the packages provided by SWT. It is not available on all
 	 * platforms and should never be accessed from application code.
 	 * </p>
+	 * 
+	 * @noreference This field is not intended to be referenced by clients.
 	 */
 	public int /*long*/ handle;
 	
@@ -1089,12 +1091,12 @@ void drawImageXRender(Image srcImage, int srcX, int srcY, int srcWidth, int srcH
 		short[] xRects = new short[nRects[0] * 4];
 		for (int i=0, j=0; i<nRects[0]; i++, j+=4) {
 			OS.memmove(rect, rects[0] + (i * GdkRectangle.sizeof), GdkRectangle.sizeof);
-			xRects[j] = (short)rect.x;
-			xRects[j+1] = (short)rect.y;
+			xRects[j] = (short)(translateX + rect.x);
+			xRects[j+1] = (short)(translateY + rect.y);
 			xRects[j+2] = (short)rect.width;
 			xRects[j+3] = (short)rect.height;
 		}
-		OS.XRenderSetPictureClipRectangles(xDisplay, destPict, translateX, translateY, xRects, nRects[0]);
+		OS.XRenderSetPictureClipRectangles(xDisplay, destPict, 0, 0, xRects, nRects[0]);
 		if (clipping != data.clipRgn && clipping != data.damageRgn) {
 			OS.gdk_region_destroy(clipping);
 		}
@@ -2508,8 +2510,9 @@ public Pattern getForegroundPattern() {
  * 
  * @see GCData
  * 
- * @since 3.2
  * @noreference This method is not intended to be referenced by clients.
+ * 
+ * @since 3.2
  */
 public GCData getGCData() {
 	if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
@@ -2821,31 +2824,35 @@ void initCairo() {
 	data.device.checkCairo();
 	int /*long*/ cairo = data.cairo;
 	if (cairo != 0) return;
-	int /*long*/ xDisplay = OS.GDK_DISPLAY();
-	int /*long*/ xVisual = OS.gdk_x11_visual_get_xvisual(OS.gdk_visual_get_system());
-	int /*long*/ xDrawable = 0;
-	int translateX = 0, translateY = 0;
-	int /*long*/ drawable = data.drawable;
-	if (data.image != null) {
-		xDrawable = OS.GDK_PIXMAP_XID(drawable);
+	if (OS.GTK_VERSION < OS.VERSION(2, 17, 0)) {
+		int /*long*/ xDisplay = OS.GDK_DISPLAY();
+		int /*long*/ xVisual = OS.gdk_x11_visual_get_xvisual(OS.gdk_visual_get_system());
+		int /*long*/ xDrawable = 0;
+		int translateX = 0, translateY = 0;
+		int /*long*/ drawable = data.drawable;
+		if (data.image != null) {
+			xDrawable = OS.GDK_PIXMAP_XID(drawable);
+		} else {
+			if (!data.realDrawable) {
+				int[] x = new int[1], y = new int[1];
+				int /*long*/ [] real_drawable = new int /*long*/ [1];
+				OS.gdk_window_get_internal_paint_info(drawable, real_drawable, x, y);
+				xDrawable = OS.gdk_x11_drawable_get_xid(real_drawable[0]);
+				translateX = -x[0];
+				translateY = -y[0];
+			}
+		}
+		int[] w = new int[1], h = new int[1];
+		OS.gdk_drawable_get_size(drawable, w, h);
+		int width = w[0], height = h[0];
+		int /*long*/ surface = Cairo.cairo_xlib_surface_create(xDisplay, xDrawable, xVisual, width, height);
+		if (surface == 0) SWT.error(SWT.ERROR_NO_HANDLES);
+		Cairo.cairo_surface_set_device_offset(surface, translateX, translateY);
+		data.cairo = cairo = Cairo.cairo_create(surface);
+		Cairo.cairo_surface_destroy(surface);
 	} else {
-		if (!data.realDrawable) {
-			int[] x = new int[1], y = new int[1];
-			int /*long*/ [] real_drawable = new int /*long*/ [1];
-			OS.gdk_window_get_internal_paint_info(drawable, real_drawable, x, y);
-			xDrawable = OS.gdk_x11_drawable_get_xid(real_drawable[0]);
-			translateX = -x[0];
-			translateY = -y[0];
-		}
-	}
-	int[] w = new int[1], h = new int[1];
-	OS.gdk_drawable_get_size(drawable, w, h);
-	int width = w[0], height = h[0];
-	int /*long*/ surface = Cairo.cairo_xlib_surface_create(xDisplay, xDrawable, xVisual, width, height);
-	if (surface == 0) SWT.error(SWT.ERROR_NO_HANDLES);
-	Cairo.cairo_surface_set_device_offset(surface, translateX, translateY);
-	data.cairo = cairo = Cairo.cairo_create(surface);
-	Cairo.cairo_surface_destroy(surface);
+		data.cairo = cairo = OS.gdk_cairo_create(data.drawable);
+	}
 	if (cairo == 0) SWT.error(SWT.ERROR_NO_HANDLES);
 	data.disposeCairo = true;
 	Cairo.cairo_set_fill_rule(cairo, Cairo.CAIRO_FILL_RULE_EVEN_ODD);
@@ -2885,7 +2892,7 @@ public boolean isClipped() {
  * <p>
  * This method gets the dispose state for the GC.
  * When a GC has been disposed, it is an error to
- * invoke any other method using the GC.
+ * invoke any other method (except {@link #dispose()}) using the GC.
  *
  * @return <code>true</code> when the GC is disposed and <code>false</code> otherwise
  */
@@ -3533,9 +3540,9 @@ public void setLineAttributes(LineAttributes attributes) {
 	if (join != data.lineJoin) {
 		mask |= LINE_JOIN;
 		switch (join) {
-			case SWT.CAP_ROUND:
-			case SWT.CAP_FLAT:
-			case SWT.CAP_SQUARE:
+			case SWT.JOIN_MITER:
+			case SWT.JOIN_ROUND:
+			case SWT.JOIN_BEVEL:
 				break;
 			default:
 				SWT.error(SWT.ERROR_INVALID_ARGUMENT);
@@ -3545,9 +3552,9 @@ public void setLineAttributes(LineAttributes attributes) {
 	if (cap != data.lineCap) {
 		mask |= LINE_CAP;
 		switch (cap) {
-			case SWT.JOIN_MITER:
-			case SWT.JOIN_ROUND:
-			case SWT.JOIN_BEVEL:
+			case SWT.CAP_FLAT:
+			case SWT.CAP_ROUND:
+			case SWT.CAP_SQUARE:
 				break;
 			default:
 				SWT.error(SWT.ERROR_INVALID_ARGUMENT);
diff --git a/org/eclipse/swt/graphics/Image.java b/org/eclipse/swt/graphics/Image.java
index 1754574..08c0da6 100644
--- a/org/eclipse/swt/graphics/Image.java
+++ b/org/eclipse/swt/graphics/Image.java
@@ -79,6 +79,8 @@ public final class Image extends Resource implements Drawable {
 	 * within the packages provided by SWT. It is not available on all
 	 * platforms and should never be accessed from application code.
 	 * </p>
+	 * 
+	 * @noreference This field is not intended to be referenced by clients.
 	 */
 	public int type;
 	
@@ -91,6 +93,8 @@ public final class Image extends Resource implements Drawable {
 	 * within the packages provided by SWT. It is not available on all
 	 * platforms and should never be accessed from application code.
 	 * </p>
+	 * 
+	 * @noreference This field is not intended to be referenced by clients.
 	 */
 	public int /*long*/ pixmap;
 	
@@ -103,6 +107,8 @@ public final class Image extends Resource implements Drawable {
 	 * within the packages provided by SWT. It is not available on all
 	 * platforms and should never be accessed from application code.
 	 * </p>
+	 * 
+	 * @noreference This field is not intended to be referenced by clients.
 	 */
 	public int /*long*/ mask;
 
@@ -645,6 +651,17 @@ void createSurface() {
 		int stride = OS.gdk_pixbuf_get_rowstride(pixbuf);
 		int /*long*/ pixels = OS.gdk_pixbuf_get_pixels(pixbuf);		
 		byte[] line = new byte[stride];
+		int /*long*/ ptr = OS.malloc(4);
+		OS.memmove(ptr, new int[]{1}, 4);
+		OS.memmove(line, ptr, 1);
+		OS.free(ptr);
+		int oa, or, og, ob;
+		boolean bigendian = line[0] == 0;
+		if (bigendian) {
+			oa = 0; or = 1; og = 2; ob = 3;
+		} else {
+			oa = 3; or = 2; og = 1; ob = 0;
+		}
 		if (mask != 0 && OS.gdk_drawable_get_depth(mask) == 1) {
 			int /*long*/ maskPixbuf = OS.gdk_pixbuf_new(OS.GDK_COLORSPACE_RGB, false, 8, width, height);
 			if (maskPixbuf == 0) SWT.error(SWT.ERROR_NO_HANDLES);
@@ -659,10 +676,15 @@ void createSurface() {
 				for (int x=0, offset1=0; x<width; x++, offset1 += 4) {
 					if (maskLine[x * 3] == 0) {
 						line[offset1 + 0] = line[offset1 + 1] = line[offset1 + 2] = line[offset1 + 3] = 0;
+					} else {
+						byte r = line[offset1 + 0];
+						byte g = line[offset1 + 1];
+						byte b = line[offset1 + 2];
+						line[offset1 + oa] = (byte)0xFF;
+						line[offset1 + or] = r;
+						line[offset1 + og] = g;
+						line[offset1 + ob] = b;
 					}
-					byte temp = line[offset1];
-					line[offset1] = line[offset1 + 2];
-					line[offset1 + 2] = temp;
 				}
 				OS.memmove(offset, line, stride);
 				offset += stride;
@@ -674,7 +696,6 @@ void createSurface() {
 			for (int y=0; y<height; y++) {
 				OS.memmove(line, offset, stride);
 				for (int x=0, offset1=0; x<width; x++, offset1 += 4) {
-					line[offset1+3] = (byte)alpha;
 					/* pre-multiplied alpha */
 					int r = ((line[offset1 + 0] & 0xFF) * alpha) + 128;
 					r = (r + (r >> 8)) >> 8;
@@ -682,9 +703,10 @@ void createSurface() {
 					g = (g + (g >> 8)) >> 8;
 					int b = ((line[offset1 + 2] & 0xFF) * alpha) + 128;
 					b = (b + (b >> 8)) >> 8;
-					line[offset1 + 0] = (byte)b;
-					line[offset1 + 1] = (byte)g;
-					line[offset1 + 2] = (byte)r;
+					line[offset1 + oa] = (byte)alpha;
+					line[offset1 + or] = (byte)r;
+					line[offset1 + og] = (byte)g;
+					line[offset1 + ob] = (byte)b;
 				}
 				OS.memmove(offset, line, stride);
 				offset += stride;
@@ -695,7 +717,6 @@ void createSurface() {
 				OS.memmove (line, offset, stride);
 				for (int x=0, offset1=0; x<width; x++, offset1 += 4) {
 					int alpha = alphaData [y*w [0]+x] & 0xFF;
-					line[offset1+3] = (byte)alpha;
 					/* pre-multiplied alpha */
 					int r = ((line[offset1 + 0] & 0xFF) * alpha) + 128;
 					r = (r + (r >> 8)) >> 8;
@@ -703,9 +724,10 @@ void createSurface() {
 					g = (g + (g >> 8)) >> 8;
 					int b = ((line[offset1 + 2] & 0xFF) * alpha) + 128;
 					b = (b + (b >> 8)) >> 8;
-					line[offset1 + 0] = (byte)b;
-					line[offset1 + 1] = (byte)g;
-					line[offset1 + 2] = (byte)r;
+					line[offset1 + oa] = (byte)alpha;
+					line[offset1 + or] = (byte)r;
+					line[offset1 + og] = (byte)g;
+					line[offset1 + ob] = (byte)b;
 				}
 				OS.memmove (offset, line, stride);
 				offset += stride;
@@ -715,10 +737,13 @@ void createSurface() {
 			for (int y = 0; y < h [0]; y++) {
 				OS.memmove (line, offset, stride);
 				for (int x=0, offset1=0; x<width; x++, offset1 += 4) {
-					line[offset1+3] = (byte)0xFF;
-					byte temp = line[offset1];
-					line[offset1] = line[offset1 + 2];
-					line[offset1 + 2] = temp;
+					byte r = line[offset1 + 0];
+					byte g = line[offset1 + 1];
+					byte b = line[offset1 + 2];
+					line[offset1 + oa] = (byte)0xFF;
+					line[offset1 + or] = r;
+					line[offset1 + og] = g;
+					line[offset1 + ob] = b;
 				}
 				OS.memmove (offset, line, stride);
 				offset += stride;
@@ -907,7 +932,7 @@ public ImageData getImageData() {
  * @param pixmap the OS handle for the image
  * @param mask the OS handle for the image mask
  *
- * @private
+ * @noreference This method is not intended to be referenced by clients.
  */
 public static Image gtk_new(Device device, int type, int /*long*/ pixmap, int /*long*/ mask) {
 	Image image = new Image(device);
@@ -1052,6 +1077,8 @@ void init(ImageData image) {
  *
  * @param data the platform specific GC data 
  * @return the platform specific GC handle
+ * 
+ * @noreference This method is not intended to be referenced by clients.
  */
 public int /*long*/ internal_new_GC (GCData data) {
 	if (pixmap == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
@@ -1089,7 +1116,9 @@ public int /*long*/ internal_new_GC (GCData data) {
  * </p>
  *
  * @param hDC the platform specific GC handle
- * @param data the platform specific GC data 
+ * @param data the platform specific GC data
+ * 
+ * @noreference This method is not intended to be referenced by clients.
  */
 public void internal_dispose_GC (int /*long*/ gdkGC, GCData data) {
 	OS.g_object_unref(gdkGC);
@@ -1101,7 +1130,7 @@ public void internal_dispose_GC (int /*long*/ gdkGC, GCData data) {
  * <p>
  * This method gets the dispose state for the image.
  * When an image has been disposed, it is an error to
- * invoke any other method using the image.
+ * invoke any other method (except {@link #dispose()}) using the image.
  *
  * @return <code>true</code> when the image is disposed and <code>false</code> otherwise
  */
diff --git a/org/eclipse/swt/graphics/ImageData.java b/org/eclipse/swt/graphics/ImageData.java
index 24c7f64..ea9f1d4 100644
--- a/org/eclipse/swt/graphics/ImageData.java
+++ b/org/eclipse/swt/graphics/ImageData.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -505,6 +505,8 @@ void setAllFields(int width, int height, int depth, int scanlinePad,
  * <p>
  * This method is for internal use, and is not described further.
  * </p>
+ * 
+ * @noreference This method is not intended to be referenced by clients.
  */
 public static ImageData internal_new(
 	int width, int height, int depth, PaletteData palette,
@@ -1778,7 +1780,7 @@ static void blit(int op,
 	if ((destWidth <= 0) || (destHeight <= 0) || (alphaMode == ALPHA_TRANSPARENT)) return;
 
 	// these should be supplied as params later
-	final int srcAlphaMask = 0, destAlphaMask = 0;
+	int srcAlphaMask = 0, destAlphaMask = 0;
 
 	/*** Prepare scaling data ***/
 	final int dwm1 = destWidth - 1;
diff --git a/org/eclipse/swt/graphics/Path.java b/org/eclipse/swt/graphics/Path.java
index f7d2e8a..4a2cb56 100644
--- a/org/eclipse/swt/graphics/Path.java
+++ b/org/eclipse/swt/graphics/Path.java
@@ -46,6 +46,8 @@ public class Path extends Resource {
 	 * within the packages provided by SWT. It is not available on all
 	 * platforms and should never be accessed from application code.
 	 * </p>
+	 * 
+	 * @noreference This field is not intended to be referenced by clients.
 	 */
 	public int /*long*/ handle;
 	
@@ -678,7 +680,7 @@ void init(PathData data) {
  * <p>
  * This method gets the dispose state for the Path.
  * When a Path has been disposed, it is an error to
- * invoke any other method using the Path.
+ * invoke any other method (except {@link #dispose()}) using the Path.
  *
  * @return <code>true</code> when the Path is disposed, and <code>false</code> otherwise
  */
diff --git a/org/eclipse/swt/graphics/Pattern.java b/org/eclipse/swt/graphics/Pattern.java
index 0711132..9e94116 100644
--- a/org/eclipse/swt/graphics/Pattern.java
+++ b/org/eclipse/swt/graphics/Pattern.java
@@ -43,6 +43,8 @@ public class Pattern extends Resource {
 	 * within the packages provided by SWT. It is not available on all
 	 * platforms and should never be accessed from application code.
 	 * </p>
+	 * 
+	 * @noreference This field is not intended to be referenced by clients.
 	 */
 	public int /*long*/ handle;
 	
@@ -183,7 +185,7 @@ void destroy() {
  * <p>
  * This method gets the dispose state for the Pattern.
  * When a Pattern has been disposed, it is an error to
- * invoke any other method using the Pattern.
+ * invoke any other method (except {@link #dispose()}) using the Pattern.
  *
  * @return <code>true</code> when the Pattern is disposed, and <code>false</code> otherwise
  */
diff --git a/org/eclipse/swt/graphics/Region.java b/org/eclipse/swt/graphics/Region.java
index 3ddb8b5..a2b8995 100644
--- a/org/eclipse/swt/graphics/Region.java
+++ b/org/eclipse/swt/graphics/Region.java
@@ -37,6 +37,8 @@ public final class Region extends Resource {
 	 * within the packages provided by SWT. It is not available on all
 	 * platforms and should never be accessed from application code.
 	 * </p>
+	 * 
+	 * @noreference This field is not intended to be referenced by clients.
 	 */
 	public int /*long*/ handle;
 
@@ -412,7 +414,7 @@ public boolean intersects(Rectangle rect) {
  * <p>
  * This method gets the dispose state for the region.
  * When a region has been disposed, it is an error to
- * invoke any other method using the region.
+ * invoke any other method (except {@link #dispose()}) using the region.
  *
  * @return <code>true</code> when the region is disposed, and <code>false</code> otherwise
  */
diff --git a/org/eclipse/swt/graphics/Resource.java b/org/eclipse/swt/graphics/Resource.java
index 82c4504..c683130 100644
--- a/org/eclipse/swt/graphics/Resource.java
+++ b/org/eclipse/swt/graphics/Resource.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -58,6 +58,7 @@ void destroy() {
  * Disposes of the operating system resources associated with
  * this resource. Applications must dispose of all resources
  * which they allocate.
+ * This method does nothing if the resource is already disposed.
  */
 public void dispose() {
 	if (device == null) return;
@@ -91,7 +92,7 @@ void init() {
  * <p>
  * This method gets the dispose state for the resource.
  * When a resource has been disposed, it is an error to
- * invoke any other method using the resource.
+ * invoke any other method (except {@link #dispose()}) using the resource.
  *
  * @return <code>true</code> when the resource is disposed and <code>false</code> otherwise
  */
diff --git a/org/eclipse/swt/graphics/TextLayout.java b/org/eclipse/swt/graphics/TextLayout.java
index d72c2ba..372b628 100644
--- a/org/eclipse/swt/graphics/TextLayout.java
+++ b/org/eclipse/swt/graphics/TextLayout.java
@@ -48,9 +48,12 @@ public final class TextLayout extends Resource {
 	Font font;
 	String text;
 	int ascent, descent;
+	int indent, wrapIndent, wrapWidth;
 	int[] segments;
+	char[] segmentsChars;
 	int[] tabs;
 	StyleItem[] styles;
+	int stylesCount;
 	int /*long*/ layout, context, attrList;
 	int[] invalidOffsets;
 	static final char LTR_MARK = '\u200E', RTL_MARK = '\u200F', ZWS = '\u200B', ZWNBS = '\uFEFF';
@@ -86,10 +89,11 @@ public TextLayout (Device device) {
 		OS.pango_layout_set_auto_dir(layout, false);
 	}
 	text = "";
-	ascent = descent = -1;
+	wrapWidth = ascent = descent = -1;
 	styles = new StyleItem[2];
 	styles[0] = new StyleItem();
 	styles[1] = new StyleItem();
+	stylesCount = 2;
 	init();
 }
 
@@ -102,18 +106,22 @@ void computeRuns () {
 	String segmentsText = getSegmentsText();
 	byte[] buffer = Converter.wcsToMbcs(null, segmentsText, false);
 	OS.pango_layout_set_text (layout, buffer, buffer.length);
-	if (styles.length == 2 && styles[0].style == null && ascent == -1 && descent == -1 && segments == null) return;
+	if (stylesCount == 2 && styles[0].style == null && ascent == -1 && descent == -1 && segments == null) return;
 	int /*long*/ ptr = OS.pango_layout_get_text(layout);
 	attrList = OS.pango_attr_list_new();	
 	PangoAttribute attribute = new PangoAttribute();
 	char[] chars = null;
 	int segementsLength = segmentsText.length();
+	int nSegments = segementsLength - text.length();
+	int offsetCount = nSegments;
+	int[] lineOffsets = null; 
 	if ((ascent != -1  || descent != -1) && segementsLength > 0) {
 		PangoRectangle rect = new PangoRectangle();
 		if (ascent != -1) rect.y =  -(ascent  * OS.PANGO_SCALE);
 		rect.height = (Math.max(0, ascent) + Math.max(0, descent)) * OS.PANGO_SCALE;
 		int lineCount = OS.pango_layout_get_line_count(layout);
 		chars = new char[segementsLength + lineCount * 2];
+		lineOffsets = new int [lineCount];
 		int oldPos = 0, lineIndex = 0;
 		PangoLayoutLine line = new PangoLayoutLine();
 		while (lineIndex < lineCount) {
@@ -138,6 +146,7 @@ void computeRuns () {
 			chars[pos + lineIndex * 2] = ZWS;
 			chars[pos + lineIndex * 2 + 1] = ZWNBS;
 			segmentsText.getChars(oldPos, pos, chars,  oldPos + lineIndex * 2);
+			lineOffsets[lineIndex] = pos + lineIndex * 2; 
 			oldPos = pos;
 			lineIndex++;
 		}
@@ -145,28 +154,31 @@ void computeRuns () {
 		buffer = Converter.wcsToMbcs(null, chars, false);
 		OS.pango_layout_set_text (layout, buffer, buffer.length);
 		ptr = OS.pango_layout_get_text(layout);
+		offsetCount += 2 * lineCount;
 	} else {
 		chars = new char[segementsLength];
 		segmentsText.getChars(0, segementsLength, chars, 0);
 	}
-	int offsetCount = 0;
-	for (int i = 0; i < chars.length; i++) {
-		char c = chars[i];
-		if (c == LTR_MARK || c == RTL_MARK || c == ZWNBS || c == ZWS) {
-			offsetCount++;
-		}
-	}
 	invalidOffsets = new int[offsetCount];
-	offsetCount = 0;
-	for (int i = 0; i < chars.length; i++) {
-		char c = chars[i];
-		if (c == LTR_MARK || c == RTL_MARK || c == ZWNBS || c == ZWS) {
-			invalidOffsets[offsetCount++] = i;
+	if (offsetCount > 0) {
+		offsetCount = 0;
+		int lineIndex = 0;
+		int segmentCount = 0;
+		for (int i = 0; i < chars.length; i++) {
+			char c = chars[i];
+			if (c == ZWS && lineOffsets != null && i == lineOffsets[lineIndex]) {
+				invalidOffsets[offsetCount++] = i;		//ZWS
+				invalidOffsets[offsetCount++] = ++i;	//ZWNBS
+				lineIndex++;
+			} else if (segmentCount < nSegments && i - offsetCount == segments[segmentCount]) {
+				invalidOffsets[offsetCount++] = i;
+				segmentCount++;
+			}
 		}
 	}
 	int strlen = OS.strlen(ptr);
 	Font defaultFont = font != null ? font : device.systemFont;
-	for (int i = 0; i < styles.length - 1; i++) {
+	for (int i = 0; i < stylesCount - 1; i++) {
 		StyleItem styleItem = styles[i];
 		TextStyle style = styleItem.style; 
 		if (style == null) continue;
@@ -306,6 +318,8 @@ void destroy() {
 	text = null;
 	styles = null;
 	freeRuns();
+	segments = null;
+	segmentsChars = null;
 	if (layout != 0) OS.g_object_unref(layout);
 	layout = 0;
 	if (context != 0) OS.g_object_unref(context);
@@ -390,6 +404,7 @@ public void draw(GC gc, int x, int y, int selectionStart, int selectionEnd, Colo
 	if (selectionBackground != null && selectionBackground.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
 	gc.checkGC(GC.FOREGROUND);
 	int length = text.length();
+	x += Math.min (indent, wrapIndent);
 	boolean hasSelection = selectionStart <= selectionEnd && selectionStart != -1 && selectionEnd != -1;
 	GCData data = gc.data;
 	int /*long*/ cairo = data.cairo;
@@ -572,7 +587,7 @@ void drawBorder(GC gc, int x, int y, GdkColor selectionColor) {
 	if (cairo != 0 && OS.GTK_VERSION >= OS.VERSION(2, 8, 0)) {
 		Cairo.cairo_save(cairo);
 	}
-	for (int i = 0; i < styles.length - 1; i++) {
+	for (int i = 0; i < stylesCount - 1; i++) {
 		TextStyle style = styles[i].style;
 		if (style == null) continue;
 		
@@ -975,6 +990,7 @@ public Rectangle getBounds(int start, int end) {
 	if (OS.pango_context_get_base_dir(context) == OS.PANGO_DIRECTION_RTL) {
 		rect.x = width() - rect.x - rect.width;
 	}
+	rect.x += Math.min (indent, wrapIndent);
 	return new Rectangle(rect.x, rect.y, rect.width, rect.height);
 }
 
@@ -1025,7 +1041,7 @@ public Font getFont () {
 */
 public int getIndent () {
 	checkLayout();
-	return OS.PANGO_PIXELS(OS.pango_layout_get_indent(layout));
+	return indent;
 }
 
 /**
@@ -1122,6 +1138,7 @@ public Rectangle getLineBounds(int lineIndex) {
 	if (OS.pango_context_get_base_dir(context) == OS.PANGO_DIRECTION_RTL) {
 		x = width() - x - width;
 	}
+	x += Math.min (indent, wrapIndent);
 	return new Rectangle(x, y, width, height);
 }
 
@@ -1239,7 +1256,7 @@ public int[] getLineOffsets() {
 		int pos = (int)/*64*/OS.g_utf8_pointer_to_offset(ptr, ptr + line.start_index);
 		offsets[i] = untranslateOffset(pos);
 	}
-	offsets[lineCount] = text.length();						 
+	offsets[lineCount] = text.length();
 	return offsets;
 }
 
@@ -1277,6 +1294,7 @@ public Point getLocation(int offset, boolean trailing) {
 	if (OS.pango_context_get_base_dir(context) == OS.PANGO_DIRECTION_RTL) {
 		x = width() - x;
 	}
+	x += Math.min (indent, wrapIndent);
 	return new Point(x, OS.PANGO_PIXELS(y));
 }
 
@@ -1320,11 +1338,11 @@ int _getOffset (int offset, int movement, boolean forward) {
 	OS.pango_layout_get_log_attrs(layout, attrs, nAttrs);
 	if (attrs[0] == 0) return offset + step;
 	length = (int)/*64*/OS.g_utf8_strlen(OS.pango_layout_get_text(layout), -1);
-	offset = translateOffset(offset);
+	offset += step;
+	int internalOffset = translateOffset(offset);
 	PangoLogAttr logAttr = new PangoLogAttr();
-	offset = validateOffset(offset, step);
-	while (0 < offset && offset < length) {
-		OS.memmove(logAttr, attrs[0] + offset * PangoLogAttr.sizeof, PangoLogAttr.sizeof);
+	while (0 < internalOffset && internalOffset < length) {
+		OS.memmove(logAttr, attrs[0] + internalOffset * PangoLogAttr.sizeof, PangoLogAttr.sizeof);
 		if (((movement & SWT.MOVEMENT_CLUSTER) != 0) && logAttr.is_cursor_position) break; 
 		if ((movement & SWT.MOVEMENT_WORD) != 0) {
 			if (forward) {
@@ -1335,14 +1353,16 @@ int _getOffset (int offset, int movement, boolean forward) {
 		}
 		if ((movement & SWT.MOVEMENT_WORD_START) != 0) {
 			if (logAttr.is_word_start) break;
+			if (logAttr.is_sentence_end) break;
 		}
 		if ((movement & SWT.MOVEMENT_WORD_END) != 0) {
 			if (logAttr.is_word_end) break;
 		}
-		offset = validateOffset(offset, step);
+		offset += step;
+		internalOffset = translateOffset(offset);
 	}
 	OS.g_free(attrs[0]);
-	return Math.min(Math.max(0, untranslateOffset(offset)), text.length());
+	return Math.min(Math.max(0, offset), text.length());
 }
 
 /**
@@ -1401,6 +1421,7 @@ public int getOffset(int x, int y, int[] trailing) {
 	checkLayout();
 	computeRuns();
 	if (trailing != null && trailing.length < 1) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+	x -= Math.min (indent, wrapIndent);
 	if (OS.pango_context_get_base_dir(context) == OS.PANGO_DIRECTION_RTL) {
 		x = width() - x;
 	}
@@ -1492,9 +1513,9 @@ public int getPreviousOffset (int index, int movement) {
  */
 public int[] getRanges () {
 	checkLayout();
-	int[] result = new int[styles.length * 2];
+	int[] result = new int[stylesCount * 2];
 	int count = 0;
-	for (int i=0; i<styles.length - 1; i++) {
+	for (int i=0; i<stylesCount - 1; i++) {
 		if (styles[i].style != null) {
 			result[count++] = styles[i].start;
 			result[count++] = styles[i + 1].start - 1;
@@ -1522,32 +1543,53 @@ public int[] getSegments() {
 	return segments;
 }
 
+/**
+ * Returns the segments characters of the receiver.
+ *
+ * @return the segments characters
+ *
+ * @exception SWTException <ul>
+ *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ * 
+ * @since 3.6
+ */
+public char[] getSegmentsChars () {
+	checkLayout();
+	return segmentsChars;
+}
+
 String getSegmentsText() {
-	if (segments == null) return text;
-	int nSegments = segments.length;
-	if (nSegments <= 1) return text;
 	int length = text.length();
 	if (length == 0) return text;
-	if (nSegments == 2) {
-		if (segments[0] == 0 && segments[1] == length) return text;
+	if (segments == null) return text;
+	int nSegments = segments.length;
+	if (nSegments == 0) return text;
+	if (segmentsChars == null) {
+		if (nSegments == 1) return text;
+		if (nSegments == 2) {
+			if (segments[0] == 0 && segments[1] == length) return text;
+		}
 	}
 	char[] oldChars = new char[length];
 	text.getChars(0, length, oldChars, 0);
 	char[] newChars = new char[length + nSegments];
 	int charCount = 0, segmentCount = 0;
-	char separator = getOrientation() == SWT.RIGHT_TO_LEFT ? RTL_MARK : LTR_MARK;
+	char defaultSeparator = getOrientation() == SWT.RIGHT_TO_LEFT ? RTL_MARK : LTR_MARK;
 	while (charCount < length) {
 		if (segmentCount < nSegments && charCount == segments[segmentCount]) {
+			char separator = segmentsChars != null && segmentsChars.length > segmentCount ? segmentsChars[segmentCount] : defaultSeparator;
 			newChars[charCount + segmentCount++] = separator;
 		} else {
 			newChars[charCount + segmentCount] = oldChars[charCount++];
 		}
 	}
-	if (segmentCount < nSegments) {
+	while (segmentCount < nSegments) {
 		segments[segmentCount] = charCount;
+		char separator = segmentsChars != null && segmentsChars.length > segmentCount ? segmentsChars[segmentCount] : defaultSeparator;
 		newChars[charCount + segmentCount++] = separator;
 	}
-	return new String(newChars, 0, Math.min(charCount + segmentCount, newChars.length));
+	return new String(newChars, 0, newChars.length);
 }
 
 /**
@@ -1581,7 +1623,7 @@ public TextStyle getStyle (int offset) {
 	checkLayout();
 	int length = text.length();
 	if (!(0 <= offset && offset < length)) SWT.error(SWT.ERROR_INVALID_RANGE);
-	for (int i=1; i<styles.length; i++) {
+	for (int i=1; i<stylesCount; i++) {
 		StyleItem item = styles[i];
 		if (item.start > offset) {
 			return styles[i - 1].style;
@@ -1605,9 +1647,9 @@ public TextStyle getStyle (int offset) {
  */
 public TextStyle[] getStyles () {
 	checkLayout();
-	TextStyle[] result = new TextStyle[styles.length];
+	TextStyle[] result = new TextStyle[stylesCount];
 	int count = 0;
-	for (int i=0; i<styles.length; i++) {
+	for (int i=0; i<stylesCount; i++) {
 		if (styles[i].style != null) {
 			result[count++] = styles[i].style;
 		}
@@ -1660,8 +1702,23 @@ public String getText () {
  */
 public int getWidth () {
 	checkLayout ();
-	int width = OS.pango_layout_get_width(layout);
-	return width != -1 ? OS.PANGO_PIXELS(width) : -1;
+	return wrapWidth;
+}
+
+/**
+* Returns the receiver's wrap indent.
+*
+* @return the receiver's wrap indent
+* 
+* @exception SWTException <ul>
+*    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
+* </ul>
+* 
+* @since 3.6
+*/
+public int getWrapIndent () {
+	checkLayout ();
+	return wrapIndent;
 }
 
 /**
@@ -1670,7 +1727,7 @@ public int getWidth () {
  * <p>
  * This method gets the dispose state for the text layout.
  * When a text layout has been disposed, it is an error to
- * invoke any other method using the text layout.
+ * invoke any other method (except {@link #dispose()}) using the text layout.
  * </p>
  *
  * @return <code>true</code> when the text layout is disposed and <code>false</code> otherwise
@@ -1797,7 +1854,7 @@ public void setFont (Font font) {
 }
 
 /**
- * Sets the indent of the receiver. This indent it applied of the first line of 
+ * Sets the indent of the receiver. This indent is applied to the first line of 
  * each paragraph.  
  *
  * @param indent new indent
@@ -1806,12 +1863,17 @@ public void setFont (Font font) {
  *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
  * </ul>
  * 
+ * @see #setWrapIndent(int)
+ * 
  * @since 3.2
  */
 public void setIndent (int indent) {
 	checkLayout();
 	if (indent < 0) return;
-	OS.pango_layout_set_indent(layout, indent * OS.PANGO_SCALE);
+	if (this.indent == indent) return;
+	this.indent = indent;
+	OS.pango_layout_set_indent(layout, (indent - wrapIndent) * OS.PANGO_SCALE);
+	if (wrapWidth != -1) setWidth();
 }
 
 /**
@@ -1879,7 +1941,7 @@ public void setSpacing (int spacing) {
 
 /**
  * Sets the offsets of the receiver's text segments. Text segments are used to
- * override the default behaviour of the bidirectional algorithm.
+ * override the default behavior of the bidirectional algorithm.
  * Bidirectional reordering can happen within a text segment but not 
  * between two adjacent segments.
  * <p>
@@ -1888,12 +1950,18 @@ public void setSpacing (int spacing) {
  * always be zero and the last one should always be equals to length of
  * the text.
  * </p>
+ * <p>
+ * When segments characters are set, the segments are the offsets where
+ * the characters are inserted in the text.
+ * <p> 
  * 
  * @param segments the text segments offset
  * 
  * @exception SWTException <ul>
  *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
  * </ul>
+ * 
+ * @see #setSegmentsChars(char[])
  */
 public void setSegments(int[] segments) {
 	checkLayout();
@@ -1912,6 +1980,39 @@ public void setSegments(int[] segments) {
 }
 
 /**
+ * Sets the characters to be used in the segments boundaries. The segments 
+ * are set by calling <code>setSegments(int[])</code>. The application can
+ * use this API to insert Unicode Control Characters in the text to control
+ * the display of the text and bidi reordering. The characters are not 
+ * accessible by any other API in <code>TextLayout</code>.
+ * 
+ * @param segmentsChars the segments characters 
+ *
+ * @exception SWTException <ul>
+ *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ * 
+ * @see #setSegments(int[])
+ * 
+ * @since 3.6
+ */
+public void setSegmentsChars(char[] segmentsChars) {
+	checkLayout();
+	if (this.segmentsChars == null && segmentsChars == null) return;
+	if (this.segmentsChars != null && segmentsChars != null) {
+		if (this.segmentsChars.length == segmentsChars.length) {
+			int i;
+			for (i = 0; i <segmentsChars.length; i++) {
+				if (this.segmentsChars[i] != segmentsChars[i]) break;
+			}
+			if (i == segmentsChars.length) return;
+		}
+	}
+	freeRuns();
+	this.segmentsChars = segmentsChars;
+}
+
+/**
  * Sets the style of the receiver for the specified range.  Styles previously
  * set for that range will be overwritten.  The start and end offsets are
  * inclusive and will be clamped if out of range.
@@ -1947,7 +2048,7 @@ public void setStyle (TextStyle style, int start, int end) {
 	}
 
 	int low = -1;
-	int high = styles.length;
+	int high = stylesCount;
 	while (high - low > 1) {
 		int index = (high + low) / 2;
 		if (styles[index + 1].start > start) {
@@ -1956,7 +2057,7 @@ public void setStyle (TextStyle style, int start, int end) {
 			low = index;
 		}
 	}
-	if (0 <= high && high < styles.length) {
+	if (0 <= high && high < stylesCount) {
 		StyleItem item = styles[high];
 		if (item.start == start && styles[high + 1].start - 1 == end) {
 			if (style == null) {
@@ -1969,7 +2070,7 @@ public void setStyle (TextStyle style, int start, int end) {
 	freeRuns();
 	int modifyStart = high;
 	int modifyEnd = modifyStart;
-	while (modifyEnd < styles.length) {
+	while (modifyEnd < stylesCount) {
 		if (styles[modifyEnd + 1].start > end) break;
 		modifyEnd++;
 	}
@@ -1981,33 +2082,42 @@ public void setStyle (TextStyle style, int start, int end) {
 			return;
 		}
 		if (styleStart != start && styleEnd != end) {
-			StyleItem[] newStyles = new StyleItem[styles.length + 2];
-			System.arraycopy(styles, 0, newStyles, 0, modifyStart + 1);
+			int newLength = stylesCount + 2; 
+			if (newLength > styles.length) {
+				int newSize = Math.min(newLength + 1024, Math.max(64, newLength * 2));
+				StyleItem[] newStyles = new StyleItem[newSize];
+				System.arraycopy(styles, 0, newStyles, 0, stylesCount);
+				styles = newStyles;
+			}
+			System.arraycopy(styles, modifyEnd + 1, styles, modifyEnd + 3, stylesCount - modifyEnd - 1);
 			StyleItem item = new StyleItem();
 			item.start = start;
 			item.style = style;
-			newStyles[modifyStart + 1] = item;	
+			styles[modifyStart + 1] = item;	
 			item = new StyleItem();
 			item.start = end + 1;
 			item.style = styles[modifyStart].style;
-			newStyles[modifyStart + 2] = item;
-			System.arraycopy(styles, modifyEnd + 1, newStyles, modifyEnd + 3, styles.length - modifyEnd - 1);
-			styles = newStyles;
+			styles[modifyStart + 2] = item;
+			stylesCount = newLength;
 			return;
 		}
 	}
 	if (start == styles[modifyStart].start) modifyStart--;
 	if (end == styles[modifyEnd + 1].start - 1) modifyEnd++;
-	int newLength = styles.length + 1 - (modifyEnd - modifyStart - 1);
-	StyleItem[] newStyles = new StyleItem[newLength];
-	System.arraycopy(styles, 0, newStyles, 0, modifyStart + 1);	
+	int newLength = stylesCount + 1 - (modifyEnd - modifyStart - 1);
+	if (newLength > styles.length) {
+		int newSize = Math.min(newLength + 1024, Math.max(64, newLength * 2));
+		StyleItem[] newStyles = new StyleItem[newSize];
+		System.arraycopy(styles, 0, newStyles, 0, stylesCount);
+		styles = newStyles;
+	}
+	System.arraycopy(styles, modifyEnd, styles, modifyStart + 2, stylesCount - modifyEnd);
 	StyleItem item = new StyleItem();
 	item.start = start;
 	item.style = style;
-	newStyles[modifyStart + 1] = item;
-	styles[modifyEnd].start = end + 1;
-	System.arraycopy(styles, modifyEnd, newStyles, modifyStart + 2, styles.length - modifyEnd);
-	styles = newStyles;
+	styles[modifyStart + 1] = item;
+	styles[modifyStart + 2].start = end + 1;
+	stylesCount = newLength;
 }
 
 /**
@@ -2080,7 +2190,8 @@ public void setText (String text) {
 	styles = new StyleItem[2];
 	styles[0] = new StyleItem();
 	styles[1] = new StyleItem();
-	styles[styles.length - 1].start = text.length();
+	styles[1].start = text.length();
+	stylesCount = 2;
 }
 
 /**
@@ -2102,16 +2213,46 @@ public void setText (String text) {
 public void setWidth (int width) {
 	checkLayout ();
 	if (width < -1 || width == 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+	if (wrapWidth == width) return;
 	freeRuns();
-	if (width == -1) {
+	wrapWidth = width;
+	setWidth();
+}
+
+void setWidth () {
+	if (wrapWidth == -1) {
 		OS.pango_layout_set_width(layout, -1);
 		boolean rtl = OS.pango_context_get_base_dir(context) == OS.PANGO_DIRECTION_RTL;
 		OS.pango_layout_set_alignment(layout, rtl ? OS.PANGO_ALIGN_RIGHT : OS.PANGO_ALIGN_LEFT);
 	} else {
-		OS.pango_layout_set_width(layout, width * OS.PANGO_SCALE);
+		int margin = Math.min (indent, wrapIndent);
+		OS.pango_layout_set_width(layout, (wrapWidth - margin) * OS.PANGO_SCALE);
 	}
 }
 
+/**
+ * Sets the wrap indent of the receiver. This indent is applied to all lines
+ * in the paragraph except the first line.  
+ *
+ * @param wrapIndent new wrap indent
+ * 
+ * @exception SWTException <ul>
+ *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ * 
+ * @see #setIndent(int)
+ * 
+ * @since 3.6
+ */
+public void setWrapIndent (int wrapIndent) {
+	checkLayout();
+	if (wrapIndent < 0) return;
+	if (this.wrapIndent == wrapIndent) return;
+	this.wrapIndent = wrapIndent;
+	OS.pango_layout_set_indent(layout, (indent - wrapIndent) * OS.PANGO_SCALE);
+	if (wrapWidth != -1) setWidth();
+}
+
 static final boolean isLam(int ch) {
 	return ch == 0x0644;
 }
@@ -2165,29 +2306,11 @@ int untranslateOffset(int offset) {
 	int length = text.length();
 	if (length == 0) return offset;
 	if (invalidOffsets == null) return offset;
-	for (int i = 0; i < invalidOffsets.length; i++) {
-		if (offset == invalidOffsets[i]) {
-			offset++;
-			continue;
-		}
-		if (offset < invalidOffsets[i]) {
-			return offset - i;
-		}
+	int i = 0;
+	while (i < invalidOffsets.length && offset > invalidOffsets[i]) {
+		i++;
 	}
-	return offset - invalidOffsets.length;
-}
-
-int validateOffset(int offset, int step) {
-	if (invalidOffsets == null) return offset + step;
-	int i = step > 0 ? 0 : invalidOffsets.length - 1;
-	do {
-		offset += step;
-		while (0 <= i && i < invalidOffsets.length) {
-			if (invalidOffsets[i] == offset) break;
-			i += step;
-		}
-	} while (0 <= i && i < invalidOffsets.length);
-	return offset;
+	return offset - i;
 }
 
 int width () {
@@ -2195,7 +2318,7 @@ int width () {
 	if (wrapWidth != -1) return OS.PANGO_PIXELS(wrapWidth); 
 	int[] w = new int[1], h = new int[1];
 	OS.pango_layout_get_size(layout, w, h);
-	return OS.PANGO_PIXELS(w[0] + OS.pango_layout_get_indent(layout));
+	return OS.PANGO_PIXELS(w[0]);
 }
 
 } 
diff --git a/org/eclipse/swt/graphics/Transform.java b/org/eclipse/swt/graphics/Transform.java
index b755f16..067008c 100644
--- a/org/eclipse/swt/graphics/Transform.java
+++ b/org/eclipse/swt/graphics/Transform.java
@@ -42,6 +42,8 @@ public class Transform extends Resource {
 	 * within the packages provided by SWT. It is not available on all
 	 * platforms and should never be accessed from application code.
 	 * </p>
+	 * 
+	 * @noreference This field is not intended to be referenced by clients.
 	 */
 	public double[] handle;
 	
@@ -211,7 +213,7 @@ public void invert() {
  * <p>
  * This method gets the dispose state for the Transform.
  * When a Transform has been disposed, it is an error to
- * invoke any other method using the Transform.
+ * invoke any other method (except {@link #dispose()}) using the Transform.
  *
  * @return <code>true</code> when the Transform is disposed, and <code>false</code> otherwise
  */
diff --git a/org/eclipse/swt/internal/Compatibility.java b/org/eclipse/swt/internal/Compatibility.java
index 13e2a65..70eee21 100644
--- a/org/eclipse/swt/internal/Compatibility.java
+++ b/org/eclipse/swt/internal/Compatibility.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -282,6 +282,32 @@ public static void exec(String[] progArray) throws java.io.IOException{
 	Runtime.getRuntime().exec(progArray);
 }
 
+/**
+ * Execute prog[0] in a separate platform process if the
+ * underlying platform supports this.
+ * <p>
+ * The new process inherits the environment of the caller.
+ * <p>
+ *
+ * @param prog array containing the program to execute and its arguments
+ * @param envp
+ *            array of strings, each element of which has environment
+ *            variable settings in the format name=value
+ * @param workingDir
+ *            the working directory of the new process, or null if the new
+ *            process should inherit the working directory of the caller
+ *
+ * @exception IOException
+ *  if the program cannot be executed
+ * @exception	SecurityException
+ *  if the current SecurityManager disallows program execution
+ *
+ * @since 3.6
+ */
+public static void exec(String[] prog, String[] envp, String workingDir) throws java.io.IOException{
+	Runtime.getRuntime().exec(prog, null, workingDir != null ? new File(workingDir) : null);
+}
+
 private static ResourceBundle msgs = null;
 
 /**
diff --git a/org/eclipse/swt/internal/Library.java b/org/eclipse/swt/internal/Library.java
index 1f9a8c5..b1586d6 100644
--- a/org/eclipse/swt/internal/Library.java
+++ b/org/eclipse/swt/internal/Library.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -24,7 +24,7 @@ public class Library {
 	/**
 	 * SWT Minor version number (must be in the range 0..999)
 	 */
-    static int MINOR_VERSION = 555;
+    static int MINOR_VERSION = 655;
 	
 	/**
 	 * SWT revision number (must be >= 0)
@@ -37,19 +37,33 @@ public class Library {
 	public static final int JAVA_VERSION, SWT_VERSION;
 
 	static final String SEPARATOR;
+	static final String DELIMITER;
 	
 	/* 64-bit support */
-	static /*final*/ boolean IS_64 = 0x1FFFFFFFFL == (int /*long*/)0x1FFFFFFFFL;
+	static final boolean IS_64 = longConst() == (int /*long*/)longConst();
 	static final String SUFFIX_64 = "-64";	//$NON-NLS-1$
 	static final String SWTDIR_32 = "swtlib-32";	//$NON-NLS-1$
 	static final String SWTDIR_64 = "swtlib-64";	//$NON-NLS-1$
 
 static {
-	SEPARATOR = System.getProperty("file.separator");
-	JAVA_VERSION = parseVersion(System.getProperty("java.version"));
+	DELIMITER = System.getProperty("line.separator"); //$NON-NLS-1$
+	SEPARATOR = System.getProperty("file.separator"); //$NON-NLS-1$
+	JAVA_VERSION = parseVersion(System.getProperty("java.version")); //$NON-NLS-1$
 	SWT_VERSION = SWT_VERSION(MAJOR_VERSION, MINOR_VERSION);
 }
 
+static void chmod(String permision, String path) {
+	if (Platform.PLATFORM.equals ("win32")) return; //$NON-NLS-1$
+	try {
+		Runtime.getRuntime ().exec (new String []{"chmod", permision, path}).waitFor(); //$NON-NLS-1$
+	} catch (Throwable e) {}
+}
+
+/* Use method instead of in-lined constants to avoid compiler warnings */
+static long longConst() {
+	return 0x1FFFFFFFFL;
+}
+
 static int parseVersion(String version) {
 	if (version == null) return 0;
 	int major = 0, minor = 0, micro = 0;
@@ -94,7 +108,7 @@ public static int SWT_VERSION (int major, int minor) {
 	return major * 1000 + minor;
 }
 
-static boolean extract (String fileName, String mappedName) {
+static boolean extract (String fileName, String mappedName, StringBuffer message) {
 	FileOutputStream os = null;
 	InputStream is = null;
 	File file = new File(fileName);
@@ -112,14 +126,10 @@ static boolean extract (String fileName, String mappedName) {
 				}
 				os.close ();
 				is.close ();
-				if (!Platform.PLATFORM.equals ("win32")) { //$NON-NLS-1$
-					try {
-						Runtime.getRuntime ().exec (new String []{"chmod", "755", fileName}).waitFor(); //$NON-NLS-1$ //$NON-NLS-2$
-					} catch (Throwable e) {}
-				}
+				chmod ("755", fileName);
+				if (load (fileName, message)) return true;
 			}
 		}
-		if (load (fileName)) return true;
 	} catch (Throwable e) {
 		try {
 			if (os != null) os.close ();
@@ -132,7 +142,7 @@ static boolean extract (String fileName, String mappedName) {
 	return false;
 }
 
-static boolean load (String libName) {
+static boolean load (String libName, StringBuffer message) {
 	try {
 		if (libName.indexOf (SEPARATOR) != -1) {
 			System.load (libName);
@@ -140,7 +150,12 @@ static boolean load (String libName) {
 			System.loadLibrary (libName);
 		}		
 		return true;
-	} catch (UnsatisfiedLinkError e) {}
+	} catch (UnsatisfiedLinkError e) {
+		if (message.length() == 0) message.append(DELIMITER);
+		message.append('\t');
+		message.append(e.getMessage());
+		message.append(DELIMITER);
+	}
 	return false;
 }
 
@@ -207,17 +222,19 @@ public static void loadLibrary (String name, boolean mapName) {
 		libName1 = libName2 = mappedName1 = mappedName2 = name;
 	}
 
+	StringBuffer message = new StringBuffer();
+	
 	/* Try loading library from swt library path */
 	String path = System.getProperty ("swt.library.path"); //$NON-NLS-1$
 	if (path != null) {
 		path = new File (path).getAbsolutePath ();
-		if (load (path + SEPARATOR + mappedName1)) return;
-		if (mapName && load (path + SEPARATOR + mappedName2)) return;
+		if (load (path + SEPARATOR + mappedName1, message)) return;
+		if (mapName && load (path + SEPARATOR + mappedName2, message)) return;
 	}
 
 	/* Try loading library from java library path */
-	if (load (libName1)) return;
-	if (mapName && load (libName2)) return;
+	if (load (libName1, message)) return;
+	if (mapName && load (libName2, message)) return;
 
 	/* Try loading library from the tmp directory if swt library path is not specified */
 	String fileName1 = mappedName1;
@@ -228,11 +245,7 @@ public static void loadLibrary (String name, boolean mapName) {
 		boolean make = false;
 		if ((dir.exists () && dir.isDirectory ()) || (make = dir.mkdir ())) {
 			path = dir.getAbsolutePath ();
-			if (make && !Platform.PLATFORM.equals ("win32")) { //$NON-NLS-1$
-				try {
-					Runtime.getRuntime ().exec (new String []{"chmod", "777", path}).waitFor(); //$NON-NLS-1$ //$NON-NLS-2$
-				} catch (Throwable e) {}
-			}
+			if (make) chmod ("777", path); //$NON-NLS-1$
 		} else {
 			/* fall back to using the tmp directory */
 			if (IS_64) {
@@ -240,18 +253,18 @@ public static void loadLibrary (String name, boolean mapName) {
 				fileName2 = mapLibraryName (libName2 + SUFFIX_64);
 			}
 		}
-		if (load (path + SEPARATOR + fileName1)) return;
-		if (mapName && load (path + SEPARATOR + fileName2)) return;
+		if (load (path + SEPARATOR + fileName1, message)) return;
+		if (mapName && load (path + SEPARATOR + fileName2, message)) return;
 	}
 		
 	/* Try extracting and loading library from jar */
 	if (path != null) {
-		if (extract (path + SEPARATOR + fileName1, mappedName1)) return;
-		if (mapName && extract (path + SEPARATOR + fileName2, mappedName2)) return;
+		if (extract (path + SEPARATOR + fileName1, mappedName1, message)) return;
+		if (mapName && extract (path + SEPARATOR + fileName2, mappedName2, message)) return;
 	}
 	
 	/* Failed to find the library */
-	throw new UnsatisfiedLinkError ("no " + libName1 + " or " + libName2 + " in swt.library.path, java.library.path or the jar file"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+	throw new UnsatisfiedLinkError ("Could not load SWT library. Reasons: " + message.toString()); //$NON-NLS-1$
 }
 
 static String mapLibraryName (String libName) {
diff --git a/org/eclipse/swt/internal/SWTMessages.properties b/org/eclipse/swt/internal/SWTMessages.properties
index 1aef256..3a5c957 100644
--- a/org/eclipse/swt/internal/SWTMessages.properties
+++ b/org/eclipse/swt/internal/SWTMessages.properties
@@ -1,5 +1,5 @@
 ###############################################################################
-# Copyright (c) 2000, 2009 IBM Corporation and others.
+# Copyright (c) 2000, 2010 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
@@ -66,6 +66,7 @@ SWT_Maximize=Maximize
 SWT_Restore=Restore
 SWT_ShowList=Show List
 SWT_FileDownload=File Download
+SWT_Download_Error=Error occurred, download not completed
 SWT_Download_File=Download: {0}
 SWT_Download_Location=Saving {0} from {1}
 SWT_Download_Started=Downloading...
@@ -74,8 +75,26 @@ SWT_Authentication_Required=Authentication Required
 SWT_Enter_Username_and_Password=Enter user name and password for {0} at {1}
 SWT_Page_Load_Failed=Page load failed with error: {0}
 SWT_InvalidCert_Title=Invalid Certificate
-SWT_InvalidCert_Message=The security certificate presented by "{0}" has the following problem(s):
+SWT_InvalidCert_Message=The security certificate presented by "{0}" has problem(s).
 SWT_InvalidCert_InvalidName=Certificate name is invalid or does not match site name.  Certificate issued to: "{0}". 
 SWT_InvalidCert_NotValid=Certificate is not currently valid.  Valid date range: "{0}".  
 SWT_InvalidCert_NotTrusted=Certificate is not from a trusted certifying authority.  Certificate issuer: "{0}".
 SWT_InvalidCert_Connect=Would you like to connect to this site anyways?
+SWT_OnBeforeUnload_Message1=Are you sure you want to leave this page?
+SWT_OnBeforeUnload_Message2=Click OK to continue, or Cancel to stay on this page.
+SWT_ViewCertificate=View Certificate
+SWT_Controlled_By=controlled by
+SWT_Controller_For=controller for
+SWT_Described_By=described by
+SWT_Description_For=description for
+SWT_Embedded_By=embedded by
+SWT_Embeds=embeds
+SWT_Flows_From=flows from
+SWT_Flows_To=flows to
+SWT_Label_For=label for
+SWT_Labelled_By=labelled by
+SWT_Member_Of=member of
+SWT_Node_Child_Of=node child of
+SWT_Parent_Window_Of=parent window of
+SWT_Popup_For=popup for
+SWT_Subwindow_Of=subwindow of
diff --git a/org/eclipse/swt/internal/SWTMessages_ar.properties b/org/eclipse/swt/internal/SWTMessages_ar.properties
new file mode 100644
index 0000000..c14fda9
--- /dev/null
+++ b/org/eclipse/swt/internal/SWTMessages_ar.properties
@@ -0,0 +1,25 @@
+# Copyright by many contributors; see http://babel.eclipse.org/
+SWT_Yes=\u0646\u0639\u0645
+SWT_No=\u0644\u0627
+SWT_OK=\u062d\u0633\u0646\u0627
+SWT_Cancel=\u0627\u0644\u063a\u0627\u0621
+SWT_Abort=\u0627\u0646\u0647\u0627\u0621
+SWT_Ignore=\u062a\u062c\u0627\u0647\u0644
+SWT_Sample=\u0646\u0645\u0648\u0630\u062c
+SWT_Selection=\u0627\u0644\u0627\u062e\u062a\u064a\u0627\u0631
+SWT_Font=\u0637\u0627\u0642\u0645 \u0627\u0644\u0637\u0628\u0627\u0639\u0629
+SWT_Color=\u0627\u0644\u0644\u0648\u0646
+SWT_Size=\u062a\u063a\u064a\u064a\u0631 \u062d\u062c\u0645
+SWT_Style=\u0627\u0644\u0646\u0645\u0637
+SWT_Save=\u062d\u0641\u0638
+SWT_FontDialog_Title=\u0623\u0637\u0642\u0645 \u0627\u0644\u0637\u0628\u0627\u0639\u0629
+SWT_Remove=\u0627\u0632\u0627\u0644\u0629
+SWT_Up=\u0644\u0623\u0639\u0644\u0649
+SWT_Down=\u0644\u0623\u0633\u0641\u0644
+SWT_Charset_ASCII=ASCII
+SWT_Password=\u0643\u0644\u0645\u0629 \u0627\u0644\u0633\u0631\u064a\u0629:
+SWT_Open=\u0641\u062a\u062d
+SWT_Close=\u0627\u063a\u0644\u0627\u0642
+SWT_Minimize=\u062a\u0635\u063a\u064a\u0631
+SWT_Maximize=\u062a\u0643\u0628\u064a\u0631
+SWT_Restore=\u0627\u0633\u062a\u0639\u0627\u062f\u0629
\ No newline at end of file
diff --git a/org/eclipse/swt/internal/SWTMessages_cs.properties b/org/eclipse/swt/internal/SWTMessages_cs.properties
new file mode 100644
index 0000000..f6c9664
--- /dev/null
+++ b/org/eclipse/swt/internal/SWTMessages_cs.properties
@@ -0,0 +1,29 @@
+# Copyright by many contributors; see http://babel.eclipse.org/
+SWT_Yes=Ano
+SWT_No=Ne
+SWT_OK=OK
+SWT_Cancel=Storno
+SWT_Abort=P\u0159ed\u010dasn\u011b ukon\u010dit
+SWT_Retry=Zkusit znovu
+SWT_Ignore=Ignorovat
+SWT_Sample=Uk\u00e1zka
+SWT_Selection=V\u00fdb\u011br
+SWT_Current_Selection=Aktu\u00e1ln\u00ed v\u00fdb\u011br
+SWT_Font=P\u00edsmo
+SWT_Color=Barva
+SWT_Size=Velikost
+SWT_Style=Styl
+SWT_Save=Ulo\u017eit
+SWT_ColorDialog_Title=Barvy
+SWT_FontDialog_Title=P\u00edsma
+SWT_Remove=Odstranit
+SWT_Up=Nahoru
+SWT_Down=Dol\u016f
+SWT_Charset_ASCII=ASCII
+SWT_Password=Heslo:
+SWT_Username=U\u017eivatelsk\u00e9 jm\u00e9no:
+SWT_Open=Otev\u0159\u00edt
+SWT_Close=Zav\u0159\u00edt
+SWT_Minimize=Minimalizovat
+SWT_Maximize=Maximalizovat
+SWT_Restore=Obnovit
\ No newline at end of file
diff --git a/org/eclipse/swt/internal/SWTMessages_da.properties b/org/eclipse/swt/internal/SWTMessages_da.properties
new file mode 100644
index 0000000..e6efe92
--- /dev/null
+++ b/org/eclipse/swt/internal/SWTMessages_da.properties
@@ -0,0 +1,25 @@
+# Copyright by many contributors; see http://babel.eclipse.org/
+SWT_Yes=Ja
+SWT_No=Nej
+SWT_OK=OK
+SWT_Cancel=Annull\u00e9r
+SWT_Abort=Afbryd
+SWT_Ignore=Ignor\u00e9r
+SWT_Sample=Eksempel
+SWT_Selection=Valg
+SWT_Font=Font
+SWT_Color=Farve
+SWT_Size=St\u00f8rrelse
+SWT_Style=Typografi
+SWT_Save=Gem
+SWT_FontDialog_Title=Fonte
+SWT_Remove=Fjern
+SWT_Up=Op
+SWT_Down=Ned
+SWT_Charset_ASCII=ASCII
+SWT_Password=Kodeord:
+SWT_Open=\u00c5bn
+SWT_Close=Luk
+SWT_Minimize=Minim\u00e9r
+SWT_Maximize=Maksim\u00e9r
+SWT_Restore=Gendan
\ No newline at end of file
diff --git a/org/eclipse/swt/internal/SWTMessages_de.properties b/org/eclipse/swt/internal/SWTMessages_de.properties
new file mode 100644
index 0000000..d2969d0
--- /dev/null
+++ b/org/eclipse/swt/internal/SWTMessages_de.properties
@@ -0,0 +1,65 @@
+# Copyright by many contributors; see http://babel.eclipse.org/
+SWT_Yes=Ja
+SWT_No=Nein
+SWT_OK=OK
+SWT_Cancel=Abbrechen
+SWT_Abort=Abbrechen
+SWT_Retry=Erneut versuchen
+SWT_Ignore=Ignorieren
+SWT_Sample=Beispiel
+SWT_A_Sample_Text=Beispieltext
+SWT_Selection=Auswahl
+SWT_Current_Selection=Aktuelle Auswahl
+SWT_Font=Schriftart
+SWT_Color=Farbe
+SWT_Extended_style=Erweiterter Stil
+SWT_Size=Gr\u00f6\u00dfe
+SWT_Style=Darstellung
+SWT_Save=Speichern
+SWT_Character_set=Zeichensatz
+SWT_ColorDialog_Title=Farben
+SWT_FontDialog_Title=Schriftarten
+SWT_FontSet=Schriftsatz
+SWT_NewFont=Neue Schriftart
+SWT_Remove=Entfernen
+SWT_Up=Nach oben
+SWT_Down=Nach unten
+SWT_Charset_Western=westlich
+SWT_Charset_EastEuropean=\u00f6stlich
+SWT_Charset_SouthEuropean=s\u00fcdlich
+SWT_Charset_NorthEuropean=n\u00f6rdlich
+SWT_Charset_Cyrillic=kyrillisch
+SWT_Charset_Arabic=arabisch
+SWT_Charset_Greek=Griechisch
+SWT_Charset_Hebrew=Hebr\u00e4isch
+SWT_Charset_Turkish=T\u00fcrkisch
+SWT_Charset_Nordic=Nordisch
+SWT_Charset_Thai=Thail\u00e4ndisch
+SWT_Charset_BalticRim=Baltisch
+SWT_Charset_Celtic=Keltisch
+SWT_Charset_Euro=Euro
+SWT_Charset_Romanian=Rum\u00e4nisch
+SWT_Charset_SimplifiedChinese=chinesisch, vereinfacht
+SWT_Charset_TraditionalChinese=chinesisch, traditionell
+SWT_Charset_Japanese=Japanisch
+SWT_Charset_Korean=Koreanisch
+SWT_Charset_Unicode=Unicode
+SWT_Charset_ASCII=ASCII
+SWT_InputMethods=Eingabemethoden
+SWT_Password=Kennwort\:
+SWT_Username=Benutzername:
+SWT_Switch=Schalter
+SWT_Press=Dr\u00fccken
+SWT_Open=\u00d6ffnen
+SWT_Close=Schlie\u00dfen
+SWT_Minimize=Minimieren
+SWT_Maximize=Maximieren
+SWT_Restore=Wiederherstellen
+SWT_ShowList=Liste anzeigen
+SWT_FileDownload=Datei-Download
+SWT_Download_File=Herunterladen: {0}
+SWT_Download_Location=Speichern von {0} von {1}
+SWT_Download_Started=Herunterladen...
+SWT_Download_Status=Download: {0,number,integer} KB von {1,number,integer} KB
+SWT_Authentication_Required=Authentifizierung erforderlich
+SWT_Enter_Username_and_Password=Benutzernamen und Kennwort f\u00fcr {0} unter {1} eingeben
\ No newline at end of file
diff --git a/org/eclipse/swt/internal/SWTMessages_el.properties b/org/eclipse/swt/internal/SWTMessages_el.properties
new file mode 100644
index 0000000..a14609e
--- /dev/null
+++ b/org/eclipse/swt/internal/SWTMessages_el.properties
@@ -0,0 +1,25 @@
+# Copyright by many contributors; see http://babel.eclipse.org/
+SWT_Yes=\u039d\u03b1\u03b9
+SWT_No=\u038c\u03c7\u03b9
+SWT_OK=OK
+SWT_Cancel=\u0391\u03ba\u03cd\u03c1\u03c9\u03c3\u03b7
+SWT_Abort=\u039c\u03b1\u03c4\u03b1\u03af\u03c9\u03c3\u03b7
+SWT_Ignore=\u03a0\u03b1\u03c1\u03ac\u03b2\u03bb\u03b5\u03c8\u03b7
+SWT_Sample=\u0394\u03b5\u03af\u03b3\u03bc\u03b1
+SWT_Selection=\u0395\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae
+SWT_Font=\u0393\u03c1\u03b1\u03bc\u03bc\u03b1\u03c4\u03bf\u03c3\u03b5\u03b9\u03c1\u03ac
+SWT_Color=\u03a7\u03c1\u03ce\u03bc\u03b1
+SWT_Size=\u039c\u03ad\u03b3\u03b5\u03b8\u03bf\u03c2
+SWT_Style=\u03a3\u03c4\u03c5\u03bb
+SWT_Save=\u0391\u03c0\u03bf\u03b8\u03ae\u03ba\u03b5\u03c5\u03c3\u03b7
+SWT_FontDialog_Title=\u0393\u03c1\u03b1\u03bc\u03bc\u03b1\u03c4\u03bf\u03c3\u03b5\u03b9\u03c1\u03ad\u03c2
+SWT_Remove=\u0391\u03c6\u03b1\u03af\u03c1\u03b5\u03c3\u03b7
+SWT_Up=\u03a0\u03ac\u03bd\u03c9
+SWT_Down=\u039a\u03ac\u03c4\u03c9
+SWT_Charset_ASCII=ASCII
+SWT_Password=\u039a\u03c9\u03b4\u03b9\u03ba\u03cc\u03c2 \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7\u03c2:
+SWT_Open=\u0386\u03bd\u03bf\u03b9\u03b3\u03bc\u03b1
+SWT_Close=\u039a\u03bb\u03b5\u03af\u03c3\u03b9\u03bc\u03bf
+SWT_Minimize=\u0395\u03bb\u03b1\u03c7\u03b9\u03c3\u03c4\u03bf\u03c0\u03bf\u03af\u03b7\u03c3\u03b7
+SWT_Maximize=\u039c\u03b5\u03b3\u03b9\u03c3\u03c4\u03bf\u03c0\u03bf\u03af\u03b7\u03c3\u03b7
+SWT_Restore=\u0395\u03c0\u03b1\u03bd\u03b1\u03c6\u03bf\u03c1\u03ac
\ No newline at end of file
diff --git a/org/eclipse/swt/internal/SWTMessages_es.properties b/org/eclipse/swt/internal/SWTMessages_es.properties
new file mode 100644
index 0000000..83c1aa0
--- /dev/null
+++ b/org/eclipse/swt/internal/SWTMessages_es.properties
@@ -0,0 +1,66 @@
+# Copyright by many contributors; see http://babel.eclipse.org/
+SWT_Yes=S\u00ed
+SWT_No=No
+SWT_OK=Aceptar
+SWT_Cancel=Cancelar
+SWT_Abort=Terminar anormalmente
+SWT_Retry=Reintentar
+SWT_Ignore=Omitir
+SWT_Sample=Muestra
+SWT_A_Sample_Text=Un Texto de Muestra
+SWT_Selection=Selecci\u00f3n
+SWT_Current_Selection=Seleccion Actual
+SWT_Font=Fuente
+SWT_Color=Color
+SWT_Extended_style=Estilo extendido
+SWT_Size=Tama\u00f1o
+SWT_Style=Estilo
+SWT_Save=Guardar
+SWT_Character_set=Conjunto de caracteres
+SWT_ColorDialog_Title=Colores
+SWT_FontDialog_Title=Fuentes
+SWT_FontSet=Conjunto de Fuentes
+SWT_NewFont=Nueva Fuente
+SWT_Remove=Eliminar
+SWT_Up=Subir
+SWT_Down=Bajar
+SWT_Charset_Western=oeste
+SWT_Charset_EastEuropean=este
+SWT_Charset_SouthEuropean=sur
+SWT_Charset_NorthEuropean=norte
+SWT_Charset_Cyrillic=cir\u00edlico
+SWT_Charset_Arabic=ar\u00e1bico
+SWT_Charset_Greek=griego
+SWT_Charset_Hebrew=hebreo
+SWT_Charset_Turkish=turco
+SWT_Charset_Nordic=noruego
+SWT_Charset_Thai=tailand\u00e9s
+SWT_Charset_BalticRim=lenguas escandinavas/b\u00e1lticas
+SWT_Charset_Celtic=celta
+SWT_Charset_Euro=euro
+SWT_Charset_Romanian=rumano
+SWT_Charset_SimplifiedChinese=chino simple
+SWT_Charset_TraditionalChinese=chino tradicional
+SWT_Charset_Japanese=japones
+SWT_Charset_Korean=coreano
+SWT_Charset_Unicode=unicode
+SWT_Charset_ASCII=ASCII
+SWT_InputMethods=M\u00e9todos de Entrada
+SWT_Password=Contrase\u00f1a:
+SWT_Username=Nombre de Usuario:
+SWT_Switch=Cambiar
+SWT_Press=Presionar
+SWT_Open=Abrir
+SWT_Close=Cerrar
+SWT_Minimize=Minimizar
+SWT_Maximize=Maximizar
+SWT_Restore=Restaurar
+SWT_ShowList=Mostrar Lista
+SWT_FileDownload=Descarga Fichero
+SWT_Download_File=Descarga: {0}
+SWT_Download_Location=Guardando {0} desde {1}
+SWT_Download_Started=Descargando...
+SWT_Download_Status=Descarga: {0,number,integer} KB de {1,number,integer} KB
+SWT_Authentication_Required=Autenticaci\u00f3n requerida
+SWT_Enter_Username_and_Password=Introduzca nombre de usuario y contrase\u00f1a para {0} en {1}
+SWT_Page_Load_Failed=Carga de p\u00e1gina fall\u00f3 con error: {0}
diff --git a/org/eclipse/swt/internal/SWTMessages_et.properties b/org/eclipse/swt/internal/SWTMessages_et.properties
new file mode 100644
index 0000000..6118bc8
--- /dev/null
+++ b/org/eclipse/swt/internal/SWTMessages_et.properties
@@ -0,0 +1,23 @@
+# Copyright by many contributors; see http://babel.eclipse.org/
+SWT_Yes=Jah
+SWT_No=Ei
+SWT_OK=OK
+SWT_Cancel=T\u00fchista
+SWT_Abort=Katkesta
+SWT_Retry=Proovi uuesti
+SWT_Ignore=Ignoreeri
+SWT_Sample=N\u00e4ide
+SWT_A_Sample_Text=N\u00e4idis tekst
+SWT_Selection=Valik
+SWT_Save=Salvesta
+SWT_Remove=Eemalda
+SWT_Up=\u00dcles
+SWT_Down=Alla
+SWT_InputMethods=Sisestamis meetodid
+SWT_Press=Vajuta
+SWT_Open=Ava
+SWT_Close=Sulge
+SWT_Minimize=V\u00e4henda
+SWT_Maximize=Suurenda
+SWT_Restore=Taasta
+SWT_Download_Started=Laen alla...
diff --git a/org/eclipse/swt/internal/SWTMessages_fi.properties b/org/eclipse/swt/internal/SWTMessages_fi.properties
new file mode 100644
index 0000000..796ae74
--- /dev/null
+++ b/org/eclipse/swt/internal/SWTMessages_fi.properties
@@ -0,0 +1,25 @@
+# Copyright by many contributors; see http://babel.eclipse.org/
+SWT_Yes=Kyll\u00e4
+SWT_No=Ei
+SWT_OK=OK
+SWT_Cancel=Peruuta
+SWT_Abort=Keskeyt\u00e4
+SWT_Ignore=Ohita
+SWT_Sample=Malli
+SWT_Selection=Valinta
+SWT_Font=Fontti
+SWT_Color=V\u00e4ri
+SWT_Size=Koko
+SWT_Style=Tyyli
+SWT_Save=Tallenna
+SWT_FontDialog_Title=Fontit
+SWT_Remove=Poista
+SWT_Up=Yl\u00f6s
+SWT_Down=Alas
+SWT_Charset_ASCII=ASCII
+SWT_Password=Salasana:
+SWT_Open=Avaa
+SWT_Close=Sulje
+SWT_Minimize=Pienenn\u00e4
+SWT_Maximize=Suurenna
+SWT_Restore=Palauta
\ No newline at end of file
diff --git a/org/eclipse/swt/internal/SWTMessages_fr.properties b/org/eclipse/swt/internal/SWTMessages_fr.properties
new file mode 100644
index 0000000..1b60f16
--- /dev/null
+++ b/org/eclipse/swt/internal/SWTMessages_fr.properties
@@ -0,0 +1,65 @@
+# Copyright by many contributors; see http://babel.eclipse.org/
+SWT_Yes=Oui
+SWT_No=Non
+SWT_OK=OK
+SWT_Cancel=Annuler
+SWT_Abort=Abandonner
+SWT_Retry=Recommencer
+SWT_Ignore=Ignorer
+SWT_Sample=Exemple
+SWT_A_Sample_Text=Exemple de texte
+SWT_Selection=S\u00e9lection
+SWT_Current_Selection=S\u00e9lection en cours
+SWT_Font=Police
+SWT_Color=Couleur
+SWT_Extended_style=Style \u00e9tendu
+SWT_Size=Taille
+SWT_Style=Style
+SWT_Save=Enregistrer
+SWT_Character_set=Jeu de caract\u00e8res
+SWT_ColorDialog_Title=Couleurs
+SWT_FontDialog_Title=Polices
+SWT_FontSet=Jeu de polices
+SWT_NewFont=Nouvelle police
+SWT_Remove=Supprimer
+SWT_Up=Haut
+SWT_Down=Bas
+SWT_Charset_Western=occidental
+SWT_Charset_EastEuropean=oriental
+SWT_Charset_SouthEuropean=austral
+SWT_Charset_NorthEuropean=septentrional
+SWT_Charset_Cyrillic=cyrillique
+SWT_Charset_Arabic=arabe
+SWT_Charset_Greek=grec
+SWT_Charset_Hebrew=h\u00e9breu
+SWT_Charset_Turkish=turc
+SWT_Charset_Nordic=nordique
+SWT_Charset_Thai=tha\u00ef
+SWT_Charset_BalticRim=baltique
+SWT_Charset_Celtic=celtique
+SWT_Charset_Euro=euro
+SWT_Charset_Romanian=roumain
+SWT_Charset_SimplifiedChinese=chinois simplifi\u00e9
+SWT_Charset_TraditionalChinese=chinois traditionnel
+SWT_Charset_Japanese=japonais
+SWT_Charset_Korean=cor\u00e9en
+SWT_Charset_Unicode=unicode
+SWT_Charset_ASCII=ASCII
+SWT_InputMethods=M\u00e9thodes d'entr\u00e9e
+SWT_Password=Mot de passe \:
+SWT_Username=Nom d'utilisateur\u00a0:
+SWT_Switch=Commuter
+SWT_Press=Appuyer
+SWT_Open=Ouvrir
+SWT_Close=Fermer
+SWT_Minimize=R\u00e9duire
+SWT_Maximize=Agrandir
+SWT_Restore=Restaurer
+SWT_ShowList=Afficher la liste
+SWT_FileDownload=T\u00e9l\u00e9chargement de fichiers
+SWT_Download_File=T\u00e9l\u00e9charger\u00a0: {0}
+SWT_Download_Location=Enregistrement de {0} depuis {1}
+SWT_Download_Started=T\u00e9l\u00e9chargement...
+SWT_Download_Status=T\u00e9l\u00e9charger\u00a0: {0,number,integer} ko de {1,number,integer} ko
+SWT_Authentication_Required=Authentification requise
+SWT_Enter_Username_and_Password=Entrer le nom d''utilisateur et le mot de passe pour {0} au niveau de {1}
\ No newline at end of file
diff --git a/org/eclipse/swt/internal/SWTMessages_hu.properties b/org/eclipse/swt/internal/SWTMessages_hu.properties
new file mode 100644
index 0000000..f2dd2c1
--- /dev/null
+++ b/org/eclipse/swt/internal/SWTMessages_hu.properties
@@ -0,0 +1,25 @@
+# Copyright by many contributors; see http://babel.eclipse.org/
+SWT_Yes=Igen
+SWT_No=Nem
+SWT_OK=OK
+SWT_Cancel=M\u00e9gse
+SWT_Abort=Megszak\u00edt\u00e1s
+SWT_Ignore=Mell\u0151z\u00e9s
+SWT_Sample=Minta
+SWT_Selection=Kiv\u00e1laszt\u00e1s
+SWT_Font=Bet\u0171t\u00edpus
+SWT_Color=Sz\u00edn
+SWT_Size=M\u00e9ret
+SWT_Style=St\u00edlus
+SWT_Save=Ment\u00e9s
+SWT_FontDialog_Title=Bet\u0171t\u00edpusok
+SWT_Remove=Elt\u00e1vol\u00edt\u00e1s
+SWT_Up=Fel
+SWT_Down=Le
+SWT_Charset_ASCII=ASCII
+SWT_Password=Jelsz\u00f3:
+SWT_Open=Megnyit\u00e1s
+SWT_Close=Bez\u00e1r\u00e1s
+SWT_Minimize=Kis m\u00e9ret
+SWT_Maximize=Teljes m\u00e9ret
+SWT_Restore=Vissza\u00e1ll\u00edt\u00e1s
\ No newline at end of file
diff --git a/org/eclipse/swt/internal/SWTMessages_it.properties b/org/eclipse/swt/internal/SWTMessages_it.properties
new file mode 100644
index 0000000..bb229e6
--- /dev/null
+++ b/org/eclipse/swt/internal/SWTMessages_it.properties
@@ -0,0 +1,63 @@
+# Copyright by many contributors; see http://babel.eclipse.org/
+SWT_Yes=S\u00ec
+SWT_No=No
+SWT_OK=OK
+SWT_Cancel=Annulla
+SWT_Abort=Interrompi
+SWT_Retry=Riprova
+SWT_Ignore=Ignora
+SWT_Sample=Esempio
+SWT_A_Sample_Text=Testo di esempio
+SWT_Selection=Selezione
+SWT_Current_Selection=Selezione corrente
+SWT_Font=Tipo di carattere
+SWT_Color=Colore
+SWT_Extended_style=Stile esteso
+SWT_Size=Dimensione
+SWT_Style=Stile
+SWT_Save=Salva
+SWT_Character_set=Insieme di caratteri
+SWT_ColorDialog_Title=Colori
+SWT_FontDialog_Title=Tipi di carattere
+SWT_FontSet=Insieme di tipi di carattere
+SWT_NewFont=Nuovo tipo di carattere
+SWT_Remove=Rimuovi
+SWT_Up=Su
+SWT_Down=Gi\u00f9
+SWT_Charset_Western=occidentali
+SWT_Charset_EastEuropean=orientali
+SWT_Charset_SouthEuropean=area del Mediterraneo
+SWT_Charset_NorthEuropean=area settentrionale
+SWT_Charset_Cyrillic=cirillici
+SWT_Charset_Arabic=arabi
+SWT_Charset_Greek=greci
+SWT_Charset_Hebrew=ebraici
+SWT_Charset_Turkish=turchi
+SWT_Charset_Nordic=nordici
+SWT_Charset_Thai=thai
+SWT_Charset_BalticRim=del Baltico
+SWT_Charset_Celtic=celtici
+SWT_Charset_Euro=europei
+SWT_Charset_Romanian=rumeni
+SWT_Charset_SimplifiedChinese=cinesi sempl.
+SWT_Charset_TraditionalChinese=cinesi trad.
+SWT_Charset_Japanese=giapponesi
+SWT_Charset_Korean=coreani
+SWT_Charset_Unicode=unicode
+SWT_Charset_ASCII=ASCII
+SWT_InputMethods=Metodi di input
+SWT_Password=Password:
+SWT_Username=Nome utente:
+SWT_Switch=Passa a
+SWT_Press=Premi
+SWT_Open=Apertura
+SWT_Close=Chiudi
+SWT_Minimize=Riduci a icona
+SWT_Maximize=Ingrandisci
+SWT_Restore=Ripristina
+SWT_ShowList=Mostra elenco
+SWT_FileDownload=Download file
+SWT_Download_File=Download: {0}
+SWT_Download_Location=Salvataggio di {0} da {1}
+SWT_Download_Started=Download in corso...
+SWT_Download_Status=Download: {0,number,integer} KB di {1,number,integer} KB
\ No newline at end of file
diff --git a/org/eclipse/swt/internal/SWTMessages_iw.properties b/org/eclipse/swt/internal/SWTMessages_iw.properties
new file mode 100644
index 0000000..0e9d119
--- /dev/null
+++ b/org/eclipse/swt/internal/SWTMessages_iw.properties
@@ -0,0 +1,21 @@
+# Copyright by many contributors; see http://babel.eclipse.org/
+SWT_Yes=\u05db\u05df
+SWT_No=\u05dc\u05d0
+SWT_OK=OK
+SWT_Cancel=\u05d1\u05d9\u05d8\u05d5\u05dc
+SWT_Abort=Abort
+SWT_Ignore=Ignore
+SWT_Selection=Selection
+SWT_Font=\u05d2\u05d5\u05e4\u05df
+SWT_Style=Style
+SWT_Save=\u05e9\u05de\u05d9\u05e8\u05d4
+SWT_Remove=Remove
+SWT_Up=Up
+SWT_Down=Down
+SWT_Charset_ASCII=ASCII
+SWT_Password=\u05e1\u05d9\u05e1\u05de\u05d4:
+SWT_Open=Open
+SWT_Close=\u05e1\u05d2\u05d9\u05e8\u05d4
+SWT_Minimize=\u05de\u05d6\u05e2\u05d5\u05e8
+SWT_Maximize=\u05d4\u05d2\u05d3\u05dc\u05d4
+SWT_Restore=\u05e9\u05d7\u05d6\u05d5\u05e8
\ No newline at end of file
diff --git a/org/eclipse/swt/internal/SWTMessages_ja.properties b/org/eclipse/swt/internal/SWTMessages_ja.properties
new file mode 100644
index 0000000..3f48738
--- /dev/null
+++ b/org/eclipse/swt/internal/SWTMessages_ja.properties
@@ -0,0 +1,65 @@
+# Copyright by many contributors; see http://babel.eclipse.org/
+SWT_Yes=\u306f\u3044
+SWT_No=\u3044\u3044\u3048
+SWT_OK=OK
+SWT_Cancel=\u30ad\u30e3\u30f3\u30bb\u30eb
+SWT_Abort=\u4e2d\u65ad
+SWT_Retry=\u518d\u8a66\u884c
+SWT_Ignore=\u7121\u8996
+SWT_Sample=\u30b5\u30f3\u30d7\u30eb
+SWT_A_Sample_Text=\u30b5\u30f3\u30d7\u30eb\u30c6\u30ad\u30b9\u30c8
+SWT_Selection=\u9078\u629e
+SWT_Current_Selection=\u73fe\u5728\u306e\u9078\u629e
+SWT_Font=\u30d5\u30a9\u30f3\u30c8
+SWT_Color=\u8272
+SWT_Extended_style=\u62e1\u5f35\u30b9\u30bf\u30a4\u30eb
+SWT_Size=\u30b5\u30a4\u30ba
+SWT_Style=\u30b9\u30bf\u30a4\u30eb
+SWT_Save=\u4fdd\u7ba1
+SWT_Character_set=\u6587\u5b57\u30bb\u30c3\u30c8
+SWT_ColorDialog_Title=\u8272
+SWT_FontDialog_Title=\u30d5\u30a9\u30f3\u30c8
+SWT_FontSet=\u30d5\u30a9\u30f3\u30c8\u30bb\u30c3\u30c8
+SWT_NewFont=\u65b0\u3057\u3044\u30d5\u30a9\u30f3\u30c8
+SWT_Remove=\u524a\u9664
+SWT_Up=\u4e0a\u3078
+SWT_Down=\u4e0b\u3078
+SWT_Charset_Western=\u897f\u90e8
+SWT_Charset_EastEuropean=\u6771\u90e8
+SWT_Charset_SouthEuropean=\u5357\u90e8
+SWT_Charset_NorthEuropean=\u5317\u90e8
+SWT_Charset_Cyrillic=\u30ad\u30ea\u30eb\u8a9e
+SWT_Charset_Arabic=\u30a2\u30e9\u30d3\u30a2\u8a9e
+SWT_Charset_Greek=\u30ae\u30ea\u30b7\u30e3\u8a9e
+SWT_Charset_Hebrew=\u30d8\u30d6\u30e9\u30a4\u8a9e
+SWT_Charset_Turkish=\u30c8\u30eb\u30b3\u8a9e
+SWT_Charset_Nordic=\u30ce\u30eb\u30a6\u30a7\u30fc\u8a9e
+SWT_Charset_Thai=\u30bf\u30a4\u8a9e
+SWT_Charset_BalticRim=\u30d0\u30eb\u30c8\u6d77\u5468\u8fba
+SWT_Charset_Celtic=\u30b1\u30eb\u30c8\u8a9e
+SWT_Charset_Euro=\u30e6\u30fc\u30ed
+SWT_Charset_Romanian=\u30eb\u30fc\u30de\u30cb\u30a2\u8a9e
+SWT_Charset_SimplifiedChinese=\u7c21\u4f53\u5b57\u4e2d\u56fd\u8a9e
+SWT_Charset_TraditionalChinese=\u7e41\u4f53\u5b57\u4e2d\u56fd\u8a9e
+SWT_Charset_Japanese=\u65e5\u672c\u8a9e
+SWT_Charset_Korean=\u97d3\u56fd\u8a9e
+SWT_Charset_Unicode=Unicode
+SWT_Charset_ASCII=ASCII
+SWT_InputMethods=\u5165\u529b\u30e1\u30bd\u30c3\u30c9
+SWT_Password=\u30d1\u30b9\u30ef\u30fc\u30c9\:
+SWT_Username=\u30e6\u30fc\u30b6\u540d :
+SWT_Switch=\u5207\u308a\u66ff\u3048
+SWT_Press=\u62bc\u3059
+SWT_Open=\u958b\u304f
+SWT_Close=\u9589\u3058\u308b
+SWT_Minimize=\u6700\u5c0f\u5316
+SWT_Maximize=\u6700\u5927\u5316
+SWT_Restore=\u5fa9\u5143
+SWT_ShowList=\u30ea\u30b9\u30c8\u3092\u8868\u793a
+SWT_FileDownload=\u30d5\u30a1\u30a4\u30eb\u306e\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9
+SWT_Download_File=\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9 : {0}
+SWT_Download_Location={1} \u304b\u3089 {0} \u3092\u4fdd\u5b58\u3057\u3066\u3044\u307e\u3059
+SWT_Download_Started=\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9...
+SWT_Download_Status=\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9 : {0,number,integer} KB / {1,number,integer} KB
+SWT_Authentication_Required=\u8a8d\u8a3c\u304c\u5fc5\u8981\u3067\u3059
+SWT_Enter_Username_and_Password={1} \u306b\u304a\u3051\u308b {0} \u306e\u30e6\u30fc\u30b6\u540d\u3068\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044
\ No newline at end of file
diff --git a/org/eclipse/swt/internal/SWTMessages_ko.properties b/org/eclipse/swt/internal/SWTMessages_ko.properties
new file mode 100644
index 0000000..2adca26
--- /dev/null
+++ b/org/eclipse/swt/internal/SWTMessages_ko.properties
@@ -0,0 +1,65 @@
+# Copyright by many contributors; see http://babel.eclipse.org/
+SWT_Yes=\uc608
+SWT_No=\uc544\ub2c8\uc624
+SWT_OK=\ud655\uc778
+SWT_Cancel=\ucde8\uc18c
+SWT_Abort=\uc911\ub2e8
+SWT_Retry=\uc7ac\uc2dc\ub3c4
+SWT_Ignore=\ubb34\uc2dc
+SWT_Sample=\uc0d8\ud50c
+SWT_A_Sample_Text=\uc0d8\ud50c \ud14d\uc2a4\ud2b8
+SWT_Selection=\uc120\ud0dd\uc0ac\ud56d
+SWT_Current_Selection=\ud604\uc7ac \uc120\ud0dd\uc0ac\ud56d
+SWT_Font=\uae00\uaf34
+SWT_Color=\uc0c9\uc0c1
+SWT_Extended_style=\ud655\uc7a5 \uc2a4\ud0c0\uc77c
+SWT_Size=\ud06c\uae30
+SWT_Style=\uc2a4\ud0c0\uc77c
+SWT_Save=\uc800\uc7a5
+SWT_Character_set=\ubb38\uc790 \uc138\ud2b8
+SWT_ColorDialog_Title=\uc0c9\uc0c1
+SWT_FontDialog_Title=\uae00\uaf34
+SWT_FontSet=\uae00\uaf34 \uc138\ud2b8
+SWT_NewFont=\uc0c8 \uae00\uaf34
+SWT_Remove=\uc81c\uac70
+SWT_Up=\uc704\ub85c
+SWT_Down=\uc544\ub798\ub85c
+SWT_Charset_Western=\uc11c\ubc29
+SWT_Charset_EastEuropean=\ub3d9\ubc29
+SWT_Charset_SouthEuropean=\ub0a8\ubc29
+SWT_Charset_NorthEuropean=\ubd81\ubc29
+SWT_Charset_Cyrillic=\ud0a4\ub9b4 \uc790\ubaa8
+SWT_Charset_Arabic=\uc544\ub78d\uc5b4
+SWT_Charset_Greek=\uadf8\ub9ac\uc2a4\uc5b4
+SWT_Charset_Hebrew=\ud5e4\ube0c\ub8e8\uc5b4
+SWT_Charset_Turkish=\ud130\ud0a4\uc5b4
+SWT_Charset_Nordic=\ubd81\uc720\ub7fd\uc5b4
+SWT_Charset_Thai=\ud0dc\uad6d\uc5b4
+SWT_Charset_BalticRim=\ubc1c\ud2b8\ud574 \uc5f0\uc548\uad6d\uac00
+SWT_Charset_Celtic=\ucf08\ud2b8\uc5b4
+SWT_Charset_Euro=\uc720\ub85c
+SWT_Charset_Romanian=\ub8e8\ub9c8\ub2c8\uc544\uc5b4
+SWT_Charset_SimplifiedChinese=\uc911\uad6d\uc5b4 \uac04\uccb4
+SWT_Charset_TraditionalChinese=\uc911\uad6d\uc5b4 \ubc88\uccb4
+SWT_Charset_Japanese=\uc77c\ubcf8\uc5b4
+SWT_Charset_Korean=\ud55c\uad6d\uc5b4
+SWT_Charset_Unicode=\uc720\ub2c8\ucf54\ub4dc
+SWT_Charset_ASCII=ASCII
+SWT_InputMethods=\uc785\ub825 \uba54\uc18c\ub4dc
+SWT_Password=\uc554\ud638:
+SWT_Username=\uc0ac\uc6a9\uc790 \uc774\ub984:
+SWT_Switch=\uc804\ud658
+SWT_Press=\ub204\ub974\uae30
+SWT_Open=\uc5f4\uae30
+SWT_Close=\ub2eb\uae30
+SWT_Minimize=\ucd5c\uc18c\ud654
+SWT_Maximize=\ucd5c\ub300\ud654
+SWT_Restore=\ubcf5\uc6d0
+SWT_ShowList=\ubaa9\ub85d \ud45c\uc2dc
+SWT_FileDownload=\ud30c\uc77c \ub2e4\uc6b4\ub85c\ub4dc
+SWT_Download_File=\ub2e4\uc6b4\ub85c\ub4dc: {0}
+SWT_Download_Location={1}\uc5d0\uc11c {0} \uc800\uc7a5
+SWT_Download_Started=\ub2e4\uc6b4\ub85c\ub4dc \uc911 ...
+SWT_Download_Status=\ub2e4\uc6b4\ub85c\ub4dc: {0,number,integer}KB/{1,number,integer}KB
+SWT_Authentication_Required=\uc778\uc99d \ud544\uc694
+SWT_Enter_Username_and_Password={1}\uc5d0 {0}\uc758 \uc0ac\uc6a9\uc790 \uc774\ub984\uacfc \uc554\ud638\ub97c \uc785\ub825\ud569\ub2c8\ub2e4.
\ No newline at end of file
diff --git a/org/eclipse/swt/internal/SWTMessages_mn.properties b/org/eclipse/swt/internal/SWTMessages_mn.properties
new file mode 100644
index 0000000..7ce97ec
--- /dev/null
+++ b/org/eclipse/swt/internal/SWTMessages_mn.properties
@@ -0,0 +1,2 @@
+# Copyright by many contributors; see http://babel.eclipse.org/
+SWT_Cancel=\u0411\u043e\u043b\u0438\u0445
\ No newline at end of file
diff --git a/org/eclipse/swt/internal/SWTMessages_nl.properties b/org/eclipse/swt/internal/SWTMessages_nl.properties
new file mode 100644
index 0000000..db94758
--- /dev/null
+++ b/org/eclipse/swt/internal/SWTMessages_nl.properties
@@ -0,0 +1,25 @@
+# Copyright by many contributors; see http://babel.eclipse.org/
+SWT_Yes=Ja
+SWT_No=Nee
+SWT_OK=OK
+SWT_Cancel=Annuleren
+SWT_Abort=Afbreken
+SWT_Ignore=Negeren
+SWT_Sample=Voorbeeld
+SWT_Selection=Selectie
+SWT_Font=Lettertype
+SWT_Color=Kleur
+SWT_Size=Grootte
+SWT_Style=Stijl
+SWT_Save=Opslaan
+SWT_FontDialog_Title=Lettertypen
+SWT_Remove=Verwijderen
+SWT_Up=Omhoog
+SWT_Down=Omlaag
+SWT_Charset_ASCII=ASCII
+SWT_Password=Wachtwoord:
+SWT_Open=Openen
+SWT_Close=Sluiten
+SWT_Minimize=Minimaliseren
+SWT_Maximize=Maximaliseren
+SWT_Restore=Herstellen
\ No newline at end of file
diff --git a/org/eclipse/swt/internal/SWTMessages_no.properties b/org/eclipse/swt/internal/SWTMessages_no.properties
new file mode 100644
index 0000000..2d1bc5d
--- /dev/null
+++ b/org/eclipse/swt/internal/SWTMessages_no.properties
@@ -0,0 +1,25 @@
+# Copyright by many contributors; see http://babel.eclipse.org/
+SWT_Yes=Ja
+SWT_No=Nei
+SWT_OK=Ok
+SWT_Cancel=Avbryt
+SWT_Abort=Avbryt
+SWT_Ignore=Ignorer
+SWT_Sample=Eksempel
+SWT_Selection=Valg
+SWT_Font=Font
+SWT_Color=Farge
+SWT_Size=St\u00f8rrelse
+SWT_Style=Stil
+SWT_Save=Lagre
+SWT_FontDialog_Title=Fonter
+SWT_Remove=Fjern
+SWT_Up=Opp
+SWT_Down=Ned
+SWT_Charset_ASCII=ASCII
+SWT_Password=Passord:
+SWT_Open=\u00c5pne
+SWT_Close=Lukk
+SWT_Minimize=Minimer
+SWT_Maximize=Maksimer
+SWT_Restore=Gjenopprett
\ No newline at end of file
diff --git a/org/eclipse/swt/internal/SWTMessages_pl.properties b/org/eclipse/swt/internal/SWTMessages_pl.properties
new file mode 100644
index 0000000..5f09c29
--- /dev/null
+++ b/org/eclipse/swt/internal/SWTMessages_pl.properties
@@ -0,0 +1,42 @@
+# Copyright by many contributors; see http://babel.eclipse.org/
+SWT_Yes=Tak
+SWT_No=Nie
+SWT_OK=OK
+SWT_Cancel=Anuluj
+SWT_Abort=Przerwij
+SWT_Retry=Powt\u00f3rz
+SWT_Ignore=Ignoruj
+SWT_Sample=Przyk\u0142ad
+SWT_A_Sample_Text=Przyk\u0142adowy text
+SWT_Selection=Wyb\u00f3r
+SWT_Current_Selection=Obecny wyb\u00f3r
+SWT_Font=Czcionka
+SWT_Color=Kolor
+SWT_Extended_style=Rozszerzony styl
+SWT_Size=Rozmiar
+SWT_Style=Styl
+SWT_Save=Zapisz
+SWT_Character_set=Tablica znak\u00f3w
+SWT_ColorDialog_Title=Kolory
+SWT_FontDialog_Title=Czcionki
+SWT_FontSet=Zestaw czcionek
+SWT_NewFont=Nowa czcionka
+SWT_Remove=Usu\u0144
+SWT_Up=W g\u00f3r\u0119
+SWT_Down=W d\u00f3\u0142
+SWT_Charset_ASCII=ASCII
+SWT_Password=Has\u0142o:
+SWT_Username=Nazwa u\u017cytkownika:
+SWT_Switch=Zmie\u0144
+SWT_Press=Wci\u015bnij
+SWT_Open=Otwieranie
+SWT_Close=Zamknij
+SWT_Minimize=Minimalizuj
+SWT_Maximize=Maksymalizuj
+SWT_Restore=Odtw\u00f3rz
+SWT_ShowList=Poka\u017c list\u0119
+SWT_FileDownload=Pobierz plik
+SWT_Download_File=Pobierz
+SWT_Download_Location=Zapisuj\u0119 {0} z {1}
+SWT_Download_Started=Pobieranie...
+SWT_Download_Status=Pobrano: {0,number,integer} KB z {1,number,integer} KB
\ No newline at end of file
diff --git a/org/eclipse/swt/internal/SWTMessages_pt.properties b/org/eclipse/swt/internal/SWTMessages_pt.properties
new file mode 100644
index 0000000..6b03c74
--- /dev/null
+++ b/org/eclipse/swt/internal/SWTMessages_pt.properties
@@ -0,0 +1,64 @@
+# Copyright by many contributors; see http://babel.eclipse.org/
+SWT_Yes=Sim
+SWT_No=N\u00e3o
+SWT_OK=OK
+SWT_Cancel=Cancelar
+SWT_Abort=Abortar
+SWT_Retry=Tentar Novamente
+SWT_Ignore=Ignorar
+SWT_Sample=Exemplo
+SWT_A_Sample_Text=Texto de Exemplo
+SWT_Selection=Selec\u00e7\u00e3o
+SWT_Current_Selection=Selec\u00e7\u00e3o Actual
+SWT_Font=Tipo de letra
+SWT_Color=Cor
+SWT_Extended_style=Estilo Adicional
+SWT_Size=Tamanho
+SWT_Style=Estilo
+SWT_Save=Guardar
+SWT_Character_set=Conjunto de caracteres
+SWT_ColorDialog_Title=Cores
+SWT_FontDialog_Title=Tipos de Letra
+SWT_FontSet=Conjunto de Fontes
+SWT_NewFont=Nova Fonte
+SWT_Remove=Remover
+SWT_Up=Para cima
+SWT_Down=Para baixo
+SWT_Charset_Western=ocidental
+SWT_Charset_EastEuropean=oriental
+SWT_Charset_SouthEuropean=sul
+SWT_Charset_NorthEuropean=norte
+SWT_Charset_Cyrillic=cir\u00edlico
+SWT_Charset_Arabic=\u00e1rabe 
+SWT_Charset_Greek=grego
+SWT_Charset_Hebrew=hebraico
+SWT_Charset_Turkish=turco
+SWT_Charset_Nordic=n\u00f3rdico
+SWT_Charset_Thai=tailand\u00eas 
+SWT_Charset_BalticRim=b\u00e1ltico
+SWT_Charset_Celtic=celta
+SWT_Charset_Euro=euro
+SWT_Charset_Romanian=romeno
+SWT_Charset_SimplifiedChinese=chin\u00eas simp.
+SWT_Charset_TraditionalChinese=chin\u00eas trad.
+SWT_Charset_Japanese=japon\u00eas 
+SWT_Charset_Korean=coreano
+SWT_Charset_ASCII=ASCII
+SWT_InputMethods=M\u00e9todos de Entrada
+SWT_Password=Palavra-passe:
+SWT_Username=Nome de Utilizador:
+SWT_Switch=Bot\u00e3o
+SWT_Press=Pressionar
+SWT_Open=Abrir
+SWT_Close=Fechar
+SWT_Minimize=Minimizar
+SWT_Maximize=Maximizar
+SWT_Restore=Restaurar
+SWT_ShowList=Mostrar Lista
+SWT_FileDownload=Descarregar Ficheiro
+SWT_Download_File=Descarga: {0}
+SWT_Download_Location=Gravando {0} de {1}
+SWT_Download_Started=Descarregando...
+SWT_Download_Status=Descarregar: {0,number,integer} KB de {1,number,integer} KB
+SWT_Authentication_Required=Autentica\u00e7\u00e3o Necess\u00e1ria
+SWT_Enter_Username_and_Password=Insira nome de utilizador e palavra-passe para {0} em {1}
\ No newline at end of file
diff --git a/org/eclipse/swt/internal/SWTMessages_pt_BR.properties b/org/eclipse/swt/internal/SWTMessages_pt_BR.properties
new file mode 100644
index 0000000..e80c352
--- /dev/null
+++ b/org/eclipse/swt/internal/SWTMessages_pt_BR.properties
@@ -0,0 +1,25 @@
+# Copyright by many contributors; see http://babel.eclipse.org/
+SWT_Yes=Sim
+SWT_No=N\u00e3o
+SWT_OK=OK
+SWT_Cancel=Cancelar
+SWT_Abort=Interromper
+SWT_Ignore=Ignorar
+SWT_Sample=Exemplo
+SWT_Selection=Sele\u00e7\u00e3o
+SWT_Font=Fonte
+SWT_Color=Cor
+SWT_Size=Tamanho
+SWT_Style=Estilo
+SWT_Save=Salvar
+SWT_FontDialog_Title=Fontes
+SWT_Remove=Remover
+SWT_Up=Para Cima
+SWT_Down=Para Baixo
+SWT_Charset_ASCII=ASCII
+SWT_Password=Senha:
+SWT_Open=Abrir
+SWT_Close=Fechar
+SWT_Minimize=Minimizar
+SWT_Maximize=Maximizar
+SWT_Restore=Restaurar
\ No newline at end of file
diff --git a/org/eclipse/swt/internal/SWTMessages_ro.properties b/org/eclipse/swt/internal/SWTMessages_ro.properties
new file mode 100644
index 0000000..820114f
--- /dev/null
+++ b/org/eclipse/swt/internal/SWTMessages_ro.properties
@@ -0,0 +1,5 @@
+# Copyright by many contributors; see http://babel.eclipse.org/
+SWT_Yes=Da
+SWT_No=Nu
+SWT_Password=Parol\u0103:
+SWT_Close=\u00cenchide
\ No newline at end of file
diff --git a/org/eclipse/swt/internal/SWTMessages_ru.properties b/org/eclipse/swt/internal/SWTMessages_ru.properties
new file mode 100644
index 0000000..8d056cd
--- /dev/null
+++ b/org/eclipse/swt/internal/SWTMessages_ru.properties
@@ -0,0 +1,30 @@
+# Copyright by many contributors; see http://babel.eclipse.org/
+SWT_Yes=\u0414\u0430
+SWT_No=\u041d\u0435\u0442
+SWT_OK=OK
+SWT_Cancel=\u041e\u0442\u043c\u0435\u043d\u0438\u0442\u044c
+SWT_Abort=\u041f\u0440\u0435\u0440\u0432\u0430\u0442\u044c
+SWT_Retry=\u041f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c
+SWT_Ignore=\u0418\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c
+SWT_Sample=\u041f\u0440\u0438\u043c\u0435\u0440
+SWT_Selection=\u0412\u044b\u0431\u043e\u0440
+SWT_Font=\u0428\u0440\u0438\u0444\u0442
+SWT_Color=\u0426\u0432\u0435\u0442
+SWT_Size=\u0420\u0430\u0437\u043c\u0435\u0440
+SWT_Style=\u0421\u0442\u0438\u043b\u044c
+SWT_Save=\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c
+SWT_ColorDialog_Title=\u0426\u0432\u0435\u0442\u0430
+SWT_FontDialog_Title=\u0428\u0440\u0438\u0444\u0442\u044b
+SWT_NewFont=\u041d\u043e\u0432\u044b\u0439 \u0448\u0440\u0438\u0444\u0442
+SWT_Remove=\u0423\u0434\u0430\u043b\u0438\u0442\u044c
+SWT_Up=\u0412\u044b\u0448\u0435
+SWT_Down=\u041d\u0438\u0436\u0435
+SWT_Charset_ASCII=ASCII
+SWT_Password=\u041f\u0430\u0440\u043e\u043b\u044c:
+SWT_Username=\u0418\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f:
+SWT_Open=\u041e\u0442\u043a\u0440\u044b\u0442\u044c
+SWT_Close=\u0417\u0430\u043a\u0440\u044b\u0442\u044c
+SWT_Minimize=\u0421\u0432\u0435\u0440\u043d\u0443\u0442\u044c
+SWT_Maximize=\u0420\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u044c
+SWT_Restore=\u0412\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c
+SWT_Download_Started=\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430:
diff --git a/org/eclipse/swt/internal/SWTMessages_sv.properties b/org/eclipse/swt/internal/SWTMessages_sv.properties
new file mode 100644
index 0000000..b251051
--- /dev/null
+++ b/org/eclipse/swt/internal/SWTMessages_sv.properties
@@ -0,0 +1,25 @@
+# Copyright by many contributors; see http://babel.eclipse.org/
+SWT_Yes=Ja
+SWT_No=Nej
+SWT_OK=OK
+SWT_Cancel=Avbryt
+SWT_Abort=Avbryt
+SWT_Ignore=Ignorera
+SWT_Sample=Exempel
+SWT_Selection=Urval
+SWT_Font=Teckensnitt
+SWT_Color=F\u00e4rg
+SWT_Size=Storlek
+SWT_Style=Format
+SWT_Save=Spara
+SWT_FontDialog_Title=Teckensnitt
+SWT_Remove=Ta bort
+SWT_Up=Upp
+SWT_Down=Ned
+SWT_Charset_ASCII=ASCII
+SWT_Password=L\u00f6senord:
+SWT_Open=\u00d6ppna
+SWT_Close=St\u00e4ng
+SWT_Minimize=Minimera
+SWT_Maximize=Maximera
+SWT_Restore=\u00c5terst\u00e4ll
\ No newline at end of file
diff --git a/org/eclipse/swt/internal/SWTMessages_tr.properties b/org/eclipse/swt/internal/SWTMessages_tr.properties
new file mode 100644
index 0000000..19ba07c
--- /dev/null
+++ b/org/eclipse/swt/internal/SWTMessages_tr.properties
@@ -0,0 +1,66 @@
+# Copyright by many contributors; see http://babel.eclipse.org/
+SWT_Yes=Evet
+SWT_No=Hay\u0131r
+SWT_OK=Tamam
+SWT_Cancel=\u0130ptal
+SWT_Abort=Durdur
+SWT_Retry=Tekrar Dene
+SWT_Ignore=Yoksay
+SWT_Sample=\u00d6rnek
+SWT_A_Sample_Text=\u00d6rnek Metin
+SWT_Selection=Se\u00e7im
+SWT_Current_Selection=Ge\u00e7erli Se\u00e7im
+SWT_Font=Yaz\u0131y\u00fcz\u00fc
+SWT_Color=Renk
+SWT_Extended_style=Geni\u015fletilmi\u015f bi\u00e7em
+SWT_Size=B\u00fcy\u00fckl\u00fck
+SWT_Style=Bi\u00e7em
+SWT_Save=Sakla
+SWT_Character_set=Karakter k\u00fcmesi
+SWT_ColorDialog_Title=Renkler
+SWT_FontDialog_Title=Yaz\u0131tipleri
+SWT_FontSet=Yaz\u0131tipi k\u00fcmesi
+SWT_NewFont=Yeni Yazitipi
+SWT_Remove=Kald\u0131r
+SWT_Up=Yukar\u0131
+SWT_Down=A\u015fa\u011f\u0131
+SWT_Charset_Western=bat\u0131
+SWT_Charset_EastEuropean=do\u011fu
+SWT_Charset_SouthEuropean=g\u00fcney
+SWT_Charset_NorthEuropean=kuzey
+SWT_Charset_Cyrillic=kiril
+SWT_Charset_Arabic=arap\u00e7a
+SWT_Charset_Greek=yunanca
+SWT_Charset_Hebrew=ibranice
+SWT_Charset_Turkish=t\u00fcrk\u00e7e
+SWT_Charset_Nordic=iskandinav
+SWT_Charset_Thai=tai
+SWT_Charset_BalticRim=balt\u0131k k\u0131y\u0131s\u0131
+SWT_Charset_Celtic=kelt
+SWT_Charset_Euro=euro
+SWT_Charset_Romanian=romanca
+SWT_Charset_SimplifiedChinese=basitle\u015ftirilmi\u015f \u00e7in\u00e7e
+SWT_Charset_TraditionalChinese=geleneksel \u00e7ince
+SWT_Charset_Japanese=japonca
+SWT_Charset_Korean=korece
+SWT_Charset_Unicode=unicode
+SWT_Charset_ASCII=ASCII
+SWT_InputMethods=Giri\u015f Metodlar\u0131
+SWT_Password=Parola:
+SWT_Username=Kullan\u0131c\u0131 Ad\u0131:
+SWT_Switch=De\u011fi\u015ftir
+SWT_Press=Bas
+SWT_Open=A\u00e7
+SWT_Close=Kapat
+SWT_Minimize=Simge Durumuna K\u00fc\u00e7\u00fclt
+SWT_Maximize=Ekran Boyutuna Getir
+SWT_Restore=Geri Y\u00fckle
+SWT_ShowList=Listeyi G\u00f6ster
+SWT_FileDownload=Dosya \u0130ndirme
+SWT_Download_File=\u0130ndir: {0}
+SWT_Download_Location={1} adresinden {0} saklan\u0131yor
+SWT_Download_Started=\u0130ndiriliyor...
+SWT_Download_Status=\u0130ndirilen: {0,number,integer} KB / {1,number,integer} KB
+SWT_Authentication_Required=Kimlik Do\u011frulamas\u0131 Gerekiyor
+SWT_Enter_Username_and_Password={1} alan\u0131na {0} i\u00e7in kullan\u0131c\u0131 ad\u0131n\u0131 ve parolas\u0131n\u0131 girini\u015f
+SWT_Page_Load_Failed=Sayfa y\u00fcklemesi ba\u015far\u0131s\u0131z oldu: {0}
diff --git a/org/eclipse/swt/internal/SWTMessages_uk.properties b/org/eclipse/swt/internal/SWTMessages_uk.properties
new file mode 100644
index 0000000..0549844
--- /dev/null
+++ b/org/eclipse/swt/internal/SWTMessages_uk.properties
@@ -0,0 +1,66 @@
+# Copyright by many contributors; see http://babel.eclipse.org/
+SWT_Yes=\u0422\u0430\u043a
+SWT_No=\u041d\u0456
+SWT_OK=OK
+SWT_Cancel=\u0421\u043a\u0430\u0441\u0443\u0432\u0430\u0442\u0438
+SWT_Abort=\u041f\u0435\u0440\u0435\u0440\u0432\u0430\u0442\u0438
+SWT_Retry=\u041f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u0438
+SWT_Ignore=\u0406\u0433\u043d\u043e\u0440\u0443\u0432\u0430\u0442\u0438
+SWT_Sample=\u041f\u0440\u0438\u043a\u043b\u0430\u0434
+SWT_A_Sample_Text=\u0422\u0435\u043a\u0441\u0442 \u041f\u0440\u0438\u043a\u043b\u0430\u0434
+SWT_Selection=\u0412\u0438\u0431\u0456\u0440
+SWT_Current_Selection=\u041f\u043e\u0442\u043e\u0447\u043d\u0438\u0439 \u0412\u0438\u0431\u0456\u0440
+SWT_Font=\u0428\u0440\u0438\u0444\u0442
+SWT_Color=\u041a\u043e\u043b\u0456\u0440
+SWT_Extended_style=\u0420\u043e\u0437\u0448\u0438\u0440\u0435\u043d\u0438\u0439 \u0441\u0442\u0438\u043b\u044c
+SWT_Size=\u0420\u043e\u0437\u043c\u0456\u0440
+SWT_Style=\u0421\u0442\u0438\u043b\u044c
+SWT_Save=\u0417\u0431\u0435\u0440\u0435\u0433\u0442\u0438
+SWT_Character_set=\u041a\u043e\u0434\u043e\u0432\u0430 \u0441\u0442\u043e\u0440\u0456\u043d\u043a\u0430
+SWT_ColorDialog_Title=\u041a\u043e\u043b\u044c\u043e\u0440\u0438
+SWT_FontDialog_Title=\u0428\u0440\u0438\u0444\u0442\u0438
+SWT_FontSet=\u041d\u0430\u0431\u0456\u0440 \u0428\u0440\u0438\u0444\u0442\u0456\u0432
+SWT_NewFont=\u041d\u043e\u0432\u0438\u0439 \u0428\u0440\u0438\u0444\u0442
+SWT_Remove=\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438
+SWT_Up=\u041d\u0430\u0433\u043e\u0440\u0443
+SWT_Down=\u0412\u043d\u0438\u0437
+SWT_Charset_Western=\u0437\u0430\u0445\u0456\u0434\u043d\u0438\u0439
+SWT_Charset_EastEuropean=\u0441\u0445\u0456\u0434\u043d\u0438\u0439
+SWT_Charset_SouthEuropean=\u043f\u0456\u0432\u0434\u0435\u043d\u043d\u0438\u0439
+SWT_Charset_NorthEuropean=\u043f\u0456\u0432\u043d\u0456\u0447\u043d\u0438\u0439
+SWT_Charset_Cyrillic=\u043a\u0438\u0440\u0438\u043b\u0438\u0446\u044f
+SWT_Charset_Arabic=\u0430\u0440\u0430\u0431\u0441\u044c\u043a\u0430
+SWT_Charset_Greek=\u0433\u0440\u0435\u0446\u044c\u043a\u0430
+SWT_Charset_Hebrew=\u0433\u0435\u0431\u0440\u0435\u0439\u0441\u044c\u043a\u0430
+SWT_Charset_Turkish=\u0442\u0443\u0440\u0435\u0446\u044c\u043a\u0430
+SWT_Charset_Nordic=\u0441\u043a\u0430\u043d\u0434\u0438\u043d\u0430\u0432\u0441\u044c\u043a\u0430
+SWT_Charset_Thai=\u0442\u0430\u0439\u0441\u044c\u043a\u0430
+SWT_Charset_BalticRim=\u043f\u0440\u0438\u0431\u0430\u043b\u0442\u0456\u0439\u0441\u044c\u043a\u0430
+SWT_Charset_Celtic=\u043a\u0435\u043b\u044c\u0442\u0441\u044c\u043a\u0430
+SWT_Charset_Euro=\u0435\u0432\u0440\u043e\u043f\u0435\u0439\u0441\u044c\u043a\u0430
+SWT_Charset_Romanian=\u0440\u0443\u043c\u0443\u043d\u0441\u044c\u043a\u0430
+SWT_Charset_SimplifiedChinese=\u0441\u043f\u0440\u043e\u0449\u0435\u043d\u0430 \u043a\u0438\u0442\u0430\u0439\u0441\u044c\u043a\u0430
+SWT_Charset_TraditionalChinese=\u0442\u0440\u0430\u0434\u0438\u0446\u0456\u0439\u043d\u0430 \u043a\u0438\u0442\u0430\u0439\u0441\u044c\u043a\u0430
+SWT_Charset_Japanese=\u044f\u043f\u043e\u043d\u0441\u044c\u043a\u0430
+SWT_Charset_Korean=\u043a\u043e\u0440\u0435\u0439\u0441\u044c\u043a\u0430
+SWT_Charset_Unicode=\u0443\u043d\u0456\u043a\u043e\u0434
+SWT_Charset_ASCII=ASCII
+SWT_InputMethods=\u041c\u0435\u0442\u043e\u0434 \u0412\u0432\u043e\u0434\u0443
+SWT_Password=\u041f\u0430\u0440\u043e\u043b\u044c
+SWT_Username=\u0406\u043c\'\u044f \u041a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0430:
+SWT_Switch=\u041f\u0435\u0440\u0435\u043c\u0438\u043a\u0430\u0447
+SWT_Press=\u041d\u0430\u0442\u0438\u0441\u043d\u0456\u0442\u044c
+SWT_Open=\u0412\u0456\u0434\u043a\u0440\u0438\u0442\u0438
+SWT_Close=\u0417\u0430\u043a\u0440\u0438\u0442\u0438
+SWT_Minimize=\u041c\u0456\u043d\u0456\u043c\u0456\u0437\u0443\u0432\u0430\u0442\u0438
+SWT_Maximize=\u041c\u0430\u043a\u0441\u0438\u043c\u0456\u0437\u0443\u0432\u0430\u0442\u0438
+SWT_Restore=\u0412\u0456\u0434\u043d\u043e\u0432\u0438\u0442\u0438
+SWT_ShowList=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u0438 \u041f\u0435\u0440\u0435\u043b\u0456\u043a
+SWT_FileDownload=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0424\u0430\u0439\u043b\u0443
+SWT_Download_File=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f: {0}
+SWT_Download_Location=\u0417\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u043e {0} \u0437 {1}
+SWT_Download_Started=\u0422\u0440\u0438\u0432\u0430\u0454 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f...
+SWT_Download_Status=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f: {0,number,integer} KB \u0437 {1,number,integer} KB
+SWT_Authentication_Required=\u041f\u043e\u0442\u0440\u0456\u0431\u043d\u0430 \u0410\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0456\u044f
+SWT_Enter_Username_and_Password=\u0412\u0432\u0435\u0434\u0456\u0442\u044c \u0456\u043c\''\u044f \u043a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0430 \u0442\u0430 \u043f\u0430\u0440\u043e\u043b\u044c \u0434\u043b\u044f {0} \u0432 {1}
+SWT_Page_Load_Failed=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0441\u0442\u043e\u0440\u0456\u043d\u043a\u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043b\u043e\u0441\u044c \u043d\u0435\u0432\u0434\u0430\u043b\u043e \u0437 \u043f\u043e\u043c\u0438\u043b\u043a\u043e\u044e: {0}
diff --git a/org/eclipse/swt/internal/SWTMessages_zh.properties b/org/eclipse/swt/internal/SWTMessages_zh.properties
new file mode 100644
index 0000000..399df80
--- /dev/null
+++ b/org/eclipse/swt/internal/SWTMessages_zh.properties
@@ -0,0 +1,65 @@
+# Copyright by many contributors; see http://babel.eclipse.org/
+SWT_Yes=\u662f
+SWT_No=\u5426
+SWT_OK=\u786e\u5b9a
+SWT_Cancel=\u53d6\u6d88
+SWT_Abort=\u653e\u5f03
+SWT_Retry=\u91cd\u8bd5
+SWT_Ignore=\u5ffd\u7565
+SWT_Sample=\u6837\u672c
+SWT_A_Sample_Text=\u6837\u672c\u6587\u672c
+SWT_Selection=\u9009\u62e9
+SWT_Current_Selection=\u5f53\u524d\u9009\u62e9
+SWT_Font=\u5b57\u4f53
+SWT_Color=\u989c\u8272
+SWT_Extended_style=\u6269\u5c55\u6837\u5f0f
+SWT_Size=\u5927\u5c0f
+SWT_Style=\u6837\u5f0f
+SWT_Save=\u4fdd\u5b58
+SWT_Character_set=\u5b57\u7b26\u96c6
+SWT_ColorDialog_Title=\u989c\u8272
+SWT_FontDialog_Title=\u5b57\u4f53
+SWT_FontSet=\u5b57\u4f53\u96c6
+SWT_NewFont=\u65b0\u5b57\u4f53
+SWT_Remove=\u9664\u53bb
+SWT_Up=\u5411\u4e0a
+SWT_Down=\u5411\u4e0b
+SWT_Charset_Western=\u897f\u6b27\u8bed\u8a00
+SWT_Charset_EastEuropean=\u4e1c\u6b27\u8bed\u8a00
+SWT_Charset_SouthEuropean=\u5357\u6b27\u8bed\u8a00
+SWT_Charset_NorthEuropean=\u5317\u6b27\u8bed\u8a00
+SWT_Charset_Cyrillic=\u897f\u91cc\u5c14\u8bed
+SWT_Charset_Arabic=\u963f\u62c9\u4f2f\u8bed
+SWT_Charset_Greek=\u5e0c\u814a\u8bed
+SWT_Charset_Hebrew=\u5e0c\u4f2f\u83b1\u8bed
+SWT_Charset_Turkish=\u571f\u8033\u5176\u8bed
+SWT_Charset_Nordic=\u632a\u5a01\u8bed
+SWT_Charset_Thai=\u6cf0\u56fd\u8bed
+SWT_Charset_BalticRim=\u6ce2\u7f57\u7684\u8bed
+SWT_Charset_Celtic=\u51ef\u5c14\u7279\u8bed
+SWT_Charset_Euro=\u6b27\u6d32\u8bed\u8a00
+SWT_Charset_Romanian=\u7f57\u9a6c\u5c3c\u4e9a\u8bed
+SWT_Charset_SimplifiedChinese=\u7b80\u4f53\u4e2d\u6587
+SWT_Charset_TraditionalChinese=\u7e41\u4f53\u4e2d\u6587
+SWT_Charset_Japanese=\u65e5\u8bed
+SWT_Charset_Korean=\u671d\u9c9c\u8bed
+SWT_Charset_Unicode=Unicode
+SWT_Charset_ASCII=ASCII
+SWT_InputMethods=\u8f93\u5165\u6cd5
+SWT_Password=\u5bc6\u7801\uff1a
+SWT_Username=\u7528\u6237\u540d\uff1a
+SWT_Switch=\u5207\u6362
+SWT_Press=\u6309
+SWT_Open=\u6253\u5f00
+SWT_Close=\u5173\u95ed
+SWT_Minimize=\u6700\u5c0f\u5316
+SWT_Maximize=\u6700\u5927\u5316
+SWT_Restore=\u590d\u539f
+SWT_ShowList=\u663e\u793a\u5217\u8868
+SWT_FileDownload=\u6587\u4ef6\u4e0b\u8f7d
+SWT_Download_File=\u4e0b\u8f7d\uff1a{0}
+SWT_Download_Location=\u4fdd\u5b58 {1} \u4e2d\u7684 {0}
+SWT_Download_Started=\u6b63\u5728\u4e0b\u8f7d...
+SWT_Download_Status=\u4e0b\u8f7d\uff1a{0,number,integer} KB\uff08\u5171 {1,number,integer} KB\uff09
+SWT_Authentication_Required=\u9700\u8981\u8ba4\u8bc1
+SWT_Enter_Username_and_Password=\u8f93\u5165 {0}\uff08\u4f4d\u4e8e {1}\uff09\u7684\u7528\u6237\u540d\u548c\u5bc6\u7801
diff --git a/org/eclipse/swt/internal/SWTMessages_zh_TW.properties b/org/eclipse/swt/internal/SWTMessages_zh_TW.properties
new file mode 100644
index 0000000..9ec42cc
--- /dev/null
+++ b/org/eclipse/swt/internal/SWTMessages_zh_TW.properties
@@ -0,0 +1,64 @@
+# Copyright by many contributors; see http://babel.eclipse.org/
+SWT_Yes=\u662f
+SWT_No=\u5426
+SWT_OK=\u78ba\u5b9a
+SWT_Cancel=\u53d6\u6d88
+SWT_Abort=\u4e2d\u6b62
+SWT_Retry=\u91cd\u8a66
+SWT_Ignore=\u5ffd\u7565
+SWT_Sample=\u7bc4\u4f8b
+SWT_A_Sample_Text=\u7bc4\u4f8b\u6587\u5b57
+SWT_Selection=\u9078\u53d6
+SWT_Current_Selection=\u73fe\u884c\u9078\u64c7
+SWT_Font=\u5b57\u578b
+SWT_Color=\u984f\u8272
+SWT_Extended_style=\u5ef6\u4f38\u6a23\u5f0f
+SWT_Size=\u5927\u5c0f
+SWT_Style=\u6a23\u5f0f
+SWT_Save=\u5132\u5b58
+SWT_Character_set=\u5b57\u96c6
+SWT_ColorDialog_Title=\u984f\u8272
+SWT_FontDialog_Title=\u5b57\u578b
+SWT_FontSet=\u5b57\u578b\u8a2d\u5b9a
+SWT_NewFont=\u65b0\u5b57\u578b
+SWT_Remove=\u79fb\u9664
+SWT_Up=\u4e0a
+SWT_Down=\u4e0b
+SWT_Charset_Western=\u897f\u90e8
+SWT_Charset_EastEuropean=\u6771\u90e8
+SWT_Charset_SouthEuropean=\u5357\u90e8
+SWT_Charset_NorthEuropean=\u5317\u90e8
+SWT_Charset_Cyrillic=\u65af\u62c9\u592b\u6587
+SWT_Charset_Arabic=\u963f\u62c9\u4f2f\u6587
+SWT_Charset_Greek=\u5e0c\u81d8\u6587
+SWT_Charset_Hebrew=\u5e0c\u4f2f\u4f86\u6587
+SWT_Charset_Turkish=\u571f\u8033\u5176\u6587
+SWT_Charset_Nordic=\u65e5\u8033\u66fc\u6587
+SWT_Charset_Thai=\u6cf0\u6587
+SWT_Charset_BalticRim=\u6ce2\u7f85\u7684\u6d77\u5404\u65cf\u6587
+SWT_Charset_Celtic=\u585e\u723e\u7279\u6587
+SWT_Charset_Euro=\u6b50\u6d32
+SWT_Charset_Romanian=\u7f85\u99ac\u5c3c\u4e9e\u6587
+SWT_Charset_SimplifiedChinese=\u7c21\u9ad4\u4e2d\u6587
+SWT_Charset_TraditionalChinese=\u7e41\u9ad4\u4e2d\u6587
+SWT_Charset_Japanese=\u65e5\u6587
+SWT_Charset_Korean=\u97d3\u6587
+SWT_Charset_ASCII=ASCII
+SWT_InputMethods=\u8f38\u5165\u65b9\u6cd5
+SWT_Password=\u5bc6\u78bc\uff1a
+SWT_Username=\u4f7f\u7528\u8005\u540d\u7a31\uff1a
+SWT_Switch=\u5207\u63db
+SWT_Press=\u6309
+SWT_Open=\u958b\u555f
+SWT_Close=\u95dc\u9589
+SWT_Minimize=\u6700\u5c0f\u5316
+SWT_Maximize=\u6700\u5927\u5316
+SWT_Restore=\u9084\u539f
+SWT_ShowList=\u986f\u793a\u6e05\u55ae
+SWT_FileDownload=\u6a94\u6848\u4e0b\u8f09
+SWT_Download_File=\u4e0b\u8f09\uff1a{0}
+SWT_Download_Location=\u5132\u5b58 {1} \u7684 {0}
+SWT_Download_Started=\u6b63\u5728\u4e0b\u8f09...
+SWT_Download_Status=\u4e0b\u8f09\uff1a{0,number,integer} KB (\u5171 {1,number,integer} KB)
+SWT_Authentication_Required=\u9700\u8981\u9451\u5225
+SWT_Enter_Username_and_Password=\u65bc {1} \u8655\u8f38\u5165 {0} \u7684\u4f7f\u7528\u8005\u540d\u7a31\u53ca\u5bc6\u78bc
\ No newline at end of file
diff --git a/org/eclipse/swt/internal/accessibility/gtk/ATK.java b/org/eclipse/swt/internal/accessibility/gtk/ATK.java
index 77201aa..a54a31a 100644
--- a/org/eclipse/swt/internal/accessibility/gtk/ATK.java
+++ b/org/eclipse/swt/internal/accessibility/gtk/ATK.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others. All rights reserved.
+ * Copyright (c) 2000, 2010 IBM Corporation and others. All rights reserved.
  * The contents of this file are made available under the terms
  * of the GNU Lesser General Public License (LGPL) Version 2.1 that
  * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
@@ -22,11 +22,32 @@ public class ATK extends OS {
 	static {
 		Library.loadLibrary("swt-atk");
 	}
-	
+
 	/** Constants */
+	public static final int ATK_RELATION_NULL = 0;
+	public static final int ATK_RELATION_CONTROLLED_BY = 1;
+	public static final int ATK_RELATION_CONTROLLER_FOR = 2;
+	public static final int ATK_RELATION_LABEL_FOR = 3;
 	public static final int ATK_RELATION_LABELLED_BY = 4;
+	public static final int ATK_RELATION_MEMBER_OF = 5;
+	public static final int ATK_RELATION_NODE_CHILD_OF = 6;
+	public static final int ATK_RELATION_FLOWS_TO = 7;
+	public static final int ATK_RELATION_FLOWS_FROM = 8;
+	public static final int ATK_RELATION_SUBWINDOW_OF = 9;
+	public static final int ATK_RELATION_EMBEDS = 10;
+	public static final int ATK_RELATION_EMBEDDED_BY = 11;
+	public static final int ATK_RELATION_POPUP_FOR = 12; 
+	public static final int ATK_RELATION_PARENT_WINDOW_OF = 13;
+	public static final int ATK_RELATION_DESCRIBED_BY = 14;
+	public static final int ATK_RELATION_DESCRIPTION_FOR = 15;
+	public static final int ATK_ROLE_ALERT = 2;
+	public static final int ATK_ROLE_ANIMATION = 3;
+	public static final int ATK_ROLE_CALENDAR = 4;
+	public static final int ATK_ROLE_CANVAS = 6;
 	public static final int ATK_ROLE_CHECK_BOX = 7;
+	public static final int ATK_ROLE_CHECK_MENU_ITEM = 8;
 	public static final int ATK_ROLE_COMBO_BOX = 11;
+	public static final int ATK_ROLE_DATE_EDITOR = 12;
 	public static final int ATK_ROLE_DIALOG = 16;
 	public static final int ATK_ROLE_DRAWING_AREA = 18;
 	public static final int ATK_ROLE_WINDOW = 68;
@@ -38,12 +59,16 @@ public class ATK extends OS {
 	public static final int ATK_ROLE_MENU_ITEM = 34;
 	public static final int ATK_ROLE_PAGE_TAB = 36;
 	public static final int ATK_ROLE_PAGE_TAB_LIST = 37;
+	public static final int ATK_ROLE_PANEL = 38;
 	public static final int ATK_ROLE_PROGRESS_BAR = 41;
 	public static final int ATK_ROLE_PUSH_BUTTON = 42;
 	public static final int ATK_ROLE_RADIO_BUTTON = 43;
+	public static final int ATK_ROLE_RADIO_MENU_ITEM = 44;
 	public static final int ATK_ROLE_SCROLL_BAR = 47;
 	public static final int ATK_ROLE_SEPARATOR = 49;
 	public static final int ATK_ROLE_SLIDER = 50;
+	public static final int ATK_ROLE_SPIN_BUTTON = 52;
+	public static final int ATK_ROLE_STATUSBAR = 53;
 	public static final int ATK_ROLE_TABLE = 54;
 	public static final int ATK_ROLE_TABLE_CELL = 55;
 	public static final int ATK_ROLE_TABLE_COLUMN_HEADER = 56;
@@ -52,6 +77,17 @@ public class ATK extends OS {
 	public static final int ATK_ROLE_TOOL_BAR = 62;
 	public static final int ATK_ROLE_TOOL_TIP = 63;
 	public static final int ATK_ROLE_TREE = 64;
+	public static final int ATK_ROLE_HEADER = 69;
+	public static final int ATK_ROLE_FOOTER = 70;
+	public static final int ATK_ROLE_PARAGRAPH = 71;
+	public static final int ATK_ROLE_FORM = 85;
+	public static final int ATK_ROLE_HEADING = 81;
+	public static final int ATK_ROLE_DOCUMENT_FRAME = 80;
+	public static final int ATK_ROLE_IMAGE = 26;
+	public static final int ATK_ROLE_PAGE = 82;
+	public static final int ATK_ROLE_SECTION = 83;
+	public static final int ATK_ROLE_UNKNOWN = 66;
+	public static final int ATK_STATE_ACTIVE = 1;
 	public static final int ATK_STATE_ARMED = 2;
 	public static final int ATK_STATE_BUSY = 3;
 	public static final int ATK_STATE_CHECKED = 4;
@@ -61,13 +97,18 @@ public class ATK extends OS {
 	public static final int ATK_STATE_EXPANDED = 9;
 	public static final int ATK_STATE_FOCUSABLE = 10;
 	public static final int ATK_STATE_FOCUSED = 11;
+	public static final int ATK_STATE_MULTI_LINE = 15;
 	public static final int ATK_STATE_MULTISELECTABLE = 16;
 	public static final int ATK_STATE_PRESSED = 18;
 	public static final int ATK_STATE_RESIZABLE = 19;
 	public static final int ATK_STATE_SELECTABLE = 20;
 	public static final int ATK_STATE_SELECTED = 21;
 	public static final int ATK_STATE_SHOWING = 23;
+	public static final int ATK_STATE_SINGLE_LINE = 24;
 	public static final int ATK_STATE_TRANSIENT = 26;
+	public static final int ATK_STATE_REQUIRED = 32;
+	public static final int ATK_STATE_INVALID_ENTRY = 33;
+	public static final int ATK_STATE_SUPPORTS_AUTOCOMPLETION = 34;
 	public static final int ATK_STATE_VISIBLE = 28;
 	public static final int ATK_TEXT_BOUNDARY_CHAR = 0;
 	public static final int ATK_TEXT_BOUNDARY_WORD_START = 1;
@@ -76,20 +117,105 @@ public class ATK extends OS {
 	public static final int ATK_TEXT_BOUNDARY_SENTENCE_END = 4;
 	public static final int ATK_TEXT_BOUNDARY_LINE_START = 5;
 	public static final int ATK_TEXT_BOUNDARY_LINE_END = 6;
+	public static final int ATK_TEXT_CLIP_NONE = 0;
+	public static final int ATK_TEXT_CLIP_MIN = 1;
+	public static final int ATK_TEXT_CLIP_MAX = 2;
+	public static final int ATK_TEXT_CLIP_BOTH = 3;
+	public static final int ATK_TEXT_ATTR_LEFT_MARGIN = 1;
+	public static final int ATK_TEXT_ATTR_RIGHT_MARGIN = 2;
+	public static final int ATK_TEXT_ATTR_INDENT = 3;
+	public static final int ATK_TEXT_ATTR_INVISIBLE = 4;
+	public static final int ATK_TEXT_ATTR_EDITABLE = 5;
+	public static final int ATK_TEXT_ATTR_PIXELS_ABOVE_LINES = 6;
+	public static final int ATK_TEXT_ATTR_PIXELS_BELOW_LINES = 7;
+	public static final int ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP = 8;
+	public static final int ATK_TEXT_ATTR_BG_FULL_HEIGHT = 9;
+	public static final int ATK_TEXT_ATTR_RISE = 10;
+	public static final int ATK_TEXT_ATTR_UNDERLINE = 11;
+	public static final int ATK_TEXT_ATTR_STRIKETHROUGH = 12;
+	public static final int ATK_TEXT_ATTR_SIZE = 13;
+	public static final int ATK_TEXT_ATTR_SCALE = 14;
+	public static final int ATK_TEXT_ATTR_WEIGHT = 15;
+	public static final int ATK_TEXT_ATTR_LANGUAGE = 16;
+	public static final int ATK_TEXT_ATTR_FAMILY_NAME = 17;
+	public static final int ATK_TEXT_ATTR_BG_COLOR = 18;
+	public static final int ATK_TEXT_ATTR_FG_COLOR = 19;
+	public static final int ATK_TEXT_ATTR_BG_STIPPLE = 20;
+	public static final int ATK_TEXT_ATTR_FG_STIPPLE = 21;
+	public static final int ATK_TEXT_ATTR_WRAP_MODE = 22;
+	public static final int ATK__TEXT_ATTR_DIRECTION = 23;
+	public static final int ATK_TEXT_ATTR_JUSTIFICATION = 24;
+	public static final int ATK_TEXT_ATTR_STRETCH = 25;
+	public static final int ATK_TEXT_ATTR_VARIANT = 26;
+	public static final int ATK_TEXT_ATTR_STYLE = 27;
 	public static final int ATK_XY_WINDOW = 1;
 	
 	/** Signals */
 	public static final byte[] selection_changed = OS.ascii ("selection_changed");
+	public static final byte[] active_descendant_changed = OS.ascii ("active_descendant_changed");
 	public static final byte[] text_changed_insert = OS.ascii ("text_changed::insert");
 	public static final byte[] text_changed_delete = OS.ascii ("text_changed::delete");
 	public static final byte[] text_caret_moved = OS.ascii ("text_caret_moved");
 	public static final byte[] text_selection_changed = OS.ascii ("text_selection_changed");
+	public static final byte[] load_complete = OS.ascii ("load-complete");
+	public static final byte[] load_stopped = OS.ascii ("load-stopped");
+	public static final byte[] reload = OS.ascii ("reload");
+	public static final byte[] state_change = OS.ascii ("state-change");
+	public static final byte[] bounds_changed = OS.ascii ("bounds-changed");
+	public static final byte[] link_activated = OS.ascii ("link-activated");
+	public static final byte[] link_selected = OS.ascii ("link-selected");
+	public static final byte[] attributes_changed = OS.ascii ("attributes-changed");
+	public static final byte[] text_attributes_changed = OS.ascii ("text-attributes-changed");
+	public static final byte[] column_deleted = OS.ascii ("column-deleted");
+	public static final byte[] column_inserted = OS.ascii ("column-inserted");
+	public static final byte[] row_deleted = OS.ascii ("row-deleted");
+	public static final byte[] row_inserted = OS.ascii ("row-inserted");
+	public static final byte[] focus_event = OS.ascii ("focus-event");
+	
+	/** Properties */
+	public static final byte[] accessible_name = OS.ascii ("accessible-name");
+	public static final byte[] accessible_description = OS.ascii ("accessible-description");
+	public static final byte[] accessible_value = OS.ascii ("accessible-value");
+	public static final byte[] end_index = OS.ascii ("end-index");
+	public static final byte[] number_of_anchors = OS.ascii ("number-of-anchors");
+	public static final byte[] selected_link = OS.ascii ("selected-link");
+	public static final byte[] start_index = OS.ascii ("start-index");
+	public static final byte[] accessible_hypertext_nlinks = OS.ascii ("accessible-hypertext-nlinks");
+	public static final byte[] accessible_table_caption_object = OS.ascii ("accessible-table-caption-object");
+	public static final byte[] accessible_table_column_description = OS.ascii ("accessible-table-column-description");
+	public static final byte[] accessible_table_column_header = OS.ascii ("accessible-table-column-header");
+	public static final byte[] accessible_table_row_description = OS.ascii ("accessible-table-row-description");
+	public static final byte[] accessible_table_row_header = OS.ascii ("accessible-table-row-header");
+	public static final byte[] accessible_table_summary = OS.ascii ("accessible-table-summary");
 	
 /** 64 bit */
 public static final native int AtkObjectFactory_sizeof ();
 public static final native int AtkObjectFactoryClass_sizeof ();
+public static final native int AtkAttribute_sizeof ();
+public static final native int AtkTextRange_sizeof ();
+public static final native int AtkTextRectangle_sizeof ();
 	
 /** Natives */
+
+/** @method flags=const */
+public static final native int /*long*/ GTK_TYPE_ACCESSIBLE ();
+/** @method flags=const */
+public static final native int /*long*/ ATK_TYPE_ACTION ();
+/** @method flags=const */
+public static final native int /*long*/ ATK_TYPE_COMPONENT ();
+/** @method flags=const */
+public static final native int /*long*/ ATK_TYPE_HYPERTEXT ();
+/** @method flags=const */
+public static final native int /*long*/ ATK_TYPE_SELECTION ();
+/** @method flags=const */
+public static final native int /*long*/ ATK_TYPE_TABLE ();
+/** @method flags=const */
+public static final native int /*long*/ ATK_TYPE_TEXT ();
+/** @method flags=const */
+public static final native int /*long*/ ATK_TYPE_VALUE ();
+/** @method flags=const */
+public static final native int /*long*/ ATK_TYPE_OBJECT_FACTORY ();
+public static final native boolean ATK_IS_NO_OP_OBJECT_FACTORY (int /*long*/ obj);
 public static final native int /*long*/ _ATK_ACTION_GET_IFACE (int /*long*/ obj);
 public static final int /*long*/ ATK_ACTION_GET_IFACE (int /*long*/ obj) {
 	lock.lock();
@@ -109,19 +235,29 @@ public static final int /*long*/ ATK_COMPONENT_GET_IFACE(int /*long*/ atkHandle)
 	}
 }
 public static final native int /*long*/ _ATK_OBJECT_FACTORY_CLASS (int /*long*/ klass);
-public static final int /*long*/ ATK_OBJECT_FACTORY_CLASS (int /*long*/ klass) {
+public static final native int /*long*/ _ATK_SELECTION_GET_IFACE (int /*long*/ obj);
+public static final int /*long*/ ATK_SELECTION_GET_IFACE (int /*long*/ obj) {
 	lock.lock();
 	try {
-		return _ATK_OBJECT_FACTORY_CLASS(klass);
+		return _ATK_SELECTION_GET_IFACE(obj);
 	} finally {
 		lock.unlock();
 	}
 }
-public static final native int /*long*/ _ATK_SELECTION_GET_IFACE (int /*long*/ obj);
-public static final int /*long*/ ATK_SELECTION_GET_IFACE (int /*long*/ obj) {
+public static final native int /*long*/ _ATK_HYPERTEXT_GET_IFACE (int /*long*/ handle);
+public static final int /*long*/ ATK_HYPERTEXT_GET_IFACE (int /*long*/ handle) {
 	lock.lock();
 	try {
-		return _ATK_SELECTION_GET_IFACE(obj);
+		return _ATK_HYPERTEXT_GET_IFACE(handle);
+	} finally {
+		lock.unlock();
+	}
+}
+public static final native int /*long*/ _ATK_TABLE_GET_IFACE (int /*long*/ handle);
+public static final int /*long*/ ATK_TABLE_GET_IFACE (int /*long*/ handle) {
+	lock.lock();
+	try {
+		return _ATK_TABLE_GET_IFACE(handle);
 	} finally {
 		lock.unlock();
 	}
@@ -135,6 +271,15 @@ public static final int /*long*/ ATK_TEXT_GET_IFACE (int /*long*/ handle) {
 		lock.unlock();
 	}
 }
+public static final native int /*long*/ _ATK_VALUE_GET_IFACE (int /*long*/ handle);
+public static final int /*long*/ ATK_VALUE_GET_IFACE (int /*long*/ handle) {
+	lock.lock();
+	try {
+		return _ATK_VALUE_GET_IFACE(handle);
+	} finally {
+		lock.unlock();
+	}
+}
 public static final native int /*long*/ _GTK_ACCESSIBLE (int /*long*/ handle);
 public static final int /*long*/ GTK_ACCESSIBLE (int /*long*/ handle) {
 	lock.lock();
@@ -200,6 +345,16 @@ public static final void atk_object_initialize (int /*long*/ accessible, int /*l
 	}
 }
 /** @param accessible cast=(AtkObject *) */
+public static final native void _atk_object_notify_state_change (int /*long*/ accessible, int state, boolean value);
+public static final void atk_object_notify_state_change (int /*long*/ accessible, int state, boolean value) {
+	lock.lock();
+	try {
+		_atk_object_notify_state_change(accessible, state, value);
+	} finally {
+		lock.unlock();
+	}
+}
+/** @param accessible cast=(AtkObject *) */
 public static final native int /*long*/ _atk_object_ref_relation_set (int /*long*/ accessible);
 public static final int /*long*/ atk_object_ref_relation_set (int /*long*/ accessible) {
 	lock.lock();
@@ -210,6 +365,30 @@ public static final int /*long*/ atk_object_ref_relation_set (int /*long*/ acces
 	}
 }
 /**
+ * @param name cast=(const gchar *)
+ */
+public static final native int _atk_role_register (byte[] name);
+public static final int atk_role_register (byte[] name) {
+	lock.lock();
+	try {
+		return _atk_role_register(name);
+	} finally {
+		lock.unlock();
+	}
+}
+/**
+ * @param name cast=(const gchar *)
+ */
+public static final native int _atk_text_attribute_register (byte[] name);
+public static final int atk_text_attribute_register (byte[] name) {
+	lock.lock();
+	try {
+		return _atk_text_attribute_register(name);
+	} finally {
+		lock.unlock();
+	}
+}
+/**
  * @param registry cast=(AtkRegistry *)
  * @param type cast=(GType)
  */
@@ -291,6 +470,24 @@ public static final int /*long*/ atk_state_set_new () {
 		lock.unlock();
 	}
 }
+public static final native int /*long*/ _atk_text_attribute_get_name (int attr);
+public static final int /*long*/ atk_text_attribute_get_name (int attr) {
+	lock.lock();
+	try {
+		return _atk_text_attribute_get_name(attr);
+	} finally {
+		lock.unlock();
+	}
+}
+public static final native int /*long*/ _atk_text_attribute_get_value (int attr, int index);
+public static final int /*long*/ atk_text_attribute_get_value (int attr, int index) {
+	lock.lock();
+	try {
+		return _atk_text_attribute_get_value(attr, index);
+	} finally {
+		lock.unlock();
+	}
+}
 public static final native int /*long*/ _call (int /*long*/ function, int /*long*/ arg0);
 public static final int /*long*/ call (int /*long*/ function, int /*long*/ arg0) {
 	lock.lock();
@@ -345,13 +542,17 @@ public static final int /*long*/ call (int /*long*/ function, int /*long*/ arg0,
 		lock.unlock();
 	}
 }
+/** @param str cast=(char *) */
+public static final native int /*long*/ g_strdup (int /*long*/ str);
 public static final native void memmove (AtkActionIface dest, int /*long*/ src);
 public static final native void memmove (AtkComponentIface dest, int /*long*/ src);
 public static final native void memmove (AtkHypertextIface dest, int /*long*/ src);
 public static final native void memmove (AtkObjectClass dest, int /*long*/ src);
 public static final native void memmove (AtkObjectFactoryClass  dest, int /*long*/ src);
 public static final native void memmove (AtkSelectionIface dest, int /*long*/ src);	
+public static final native void memmove (AtkTableIface dest, int /*long*/ src);
 public static final native void memmove (AtkTextIface dest, int /*long*/ src);
+public static final native void memmove (AtkValueIface dest, int /*long*/ src);
 public static final native void memmove (GtkAccessible  dest, int /*long*/ src);
 public static final native void memmove (int /*long*/ dest, AtkActionIface src);
 public static final native void memmove (int /*long*/ dest, AtkComponentIface src);
@@ -359,5 +560,43 @@ public static final native void memmove (int /*long*/ dest, AtkHypertextIface sr
 public static final native void memmove (int /*long*/ dest, AtkObjectClass src);
 public static final native void memmove (int /*long*/ dest, AtkObjectFactoryClass src);
 public static final native void memmove (int /*long*/ dest, AtkSelectionIface src);
+public static final native void memmove (int /*long*/ dest, AtkTableIface src);
 public static final native void memmove (int /*long*/ dest, AtkTextIface src);
+public static final native void memmove (int /*long*/ dest, AtkValueIface src);
+/**
+ * @param dest cast=(void *)
+ * @param src cast=(const void *),flags=no_out
+ * @param size cast=(size_t)
+ */
+public static final native void memmove (int /*long*/ dest, AtkTextRectangle src, int size);
+/**
+ * @param dest cast=(void *)
+ * @param src cast=(const void *),flags=no_out
+ * @param size cast=(size_t)
+ */
+public static final native void memmove (AtkTextRectangle dest, int /*long*/ src, int size);
+/**
+ * @param dest cast=(void *)
+ * @param src cast=(const void *),flags=no_out
+ * @param size cast=(size_t)
+ */
+public static final native void memmove (int /*long*/ dest, AtkTextRange src, int size);
+/**
+ * @param dest cast=(void *)
+ * @param src cast=(const void *),flags=no_out
+ * @param size cast=(size_t)
+ */
+public static final native void memmove (AtkTextRange dest, int /*long*/ src, int size);
+/**
+ * @param dest cast=(void *)
+ * @param src cast=(const void *),flags=no_out
+ * @param size cast=(size_t)
+ */
+public static final native void memmove (int /*long*/ dest, AtkAttribute src, int size);
+/**
+ * @param dest cast=(void *)
+ * @param src cast=(const void *),flags=no_out
+ * @param size cast=(size_t)
+ */
+public static final native void memmove (AtkAttribute dest, int /*long*/ src, int size);
 }
diff --git a/org/eclipse/swt/internal/accessibility/gtk/AtkAttribute.java b/org/eclipse/swt/internal/accessibility/gtk/AtkAttribute.java
new file mode 100644
index 0000000..1615e45
--- /dev/null
+++ b/org/eclipse/swt/internal/accessibility/gtk/AtkAttribute.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2010 IBM Corporation and others. All rights reserved.
+ * The contents of this file are made available under the terms
+ * of the GNU Lesser General Public License (LGPL) Version 2.1 that
+ * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
+ * available at http://www.gnu.org/licenses/lgpl.html.  If the version
+ * of the LGPL at http://www.gnu.org is different to the version of
+ * the LGPL accompanying this distribution and there is any conflict
+ * between the two license versions, the terms of the LGPL accompanying
+ * this distribution shall govern.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.internal.accessibility.gtk;
+
+
+public class AtkAttribute {
+	/** @field cast=(char *) */
+	public int /*long*/ name;
+	/** @field cast=(char *) */
+	public int /*long*/ value;
+	public static final int sizeof = ATK.AtkAttribute_sizeof ();
+}
+
diff --git a/org/eclipse/swt/internal/accessibility/gtk/AtkObjectClass.java b/org/eclipse/swt/internal/accessibility/gtk/AtkObjectClass.java
index fc61911..c631c29 100644
--- a/org/eclipse/swt/internal/accessibility/gtk/AtkObjectClass.java
+++ b/org/eclipse/swt/internal/accessibility/gtk/AtkObjectClass.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others. All rights reserved.
+ * Copyright (c) 2000, 2010 IBM Corporation and others. All rights reserved.
  * The contents of this file are made available under the terms
  * of the GNU Lesser General Public License (LGPL) Version 2.1 that
  * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
@@ -62,4 +62,6 @@ public class AtkObjectClass {
 	public int /*long*/ state_change;
 	/** @field cast=(void (*)()) */
 	public int /*long*/ visible_data_changed;
+	/** @field accessor=SWT_AtkObjectClass_get_attributes,cast=(SWT_AtkObjectClass_get_attributes_cast) */
+	public int /*long*/ get_attributes;
 }
diff --git a/org/eclipse/swt/internal/accessibility/gtk/AtkTableIface.java b/org/eclipse/swt/internal/accessibility/gtk/AtkTableIface.java
new file mode 100644
index 0000000..9cbc506
--- /dev/null
+++ b/org/eclipse/swt/internal/accessibility/gtk/AtkTableIface.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2010 IBM Corporation and others. All rights reserved.
+ * The contents of this file are made available under the terms
+ * of the GNU Lesser General Public License (LGPL) Version 2.1 that
+ * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
+ * available at http://www.gnu.org/licenses/lgpl.html.  If the version
+ * of the LGPL at http://www.gnu.org is different to the version of
+ * the LGPL accompanying this distribution and there is any conflict
+ * between the two license versions, the terms of the LGPL accompanying
+ * this distribution shall govern.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.internal.accessibility.gtk;
+
+
+public class AtkTableIface {
+	/** @field cast=(AtkObject* (*)()) */
+	public int /*long*/ ref_at;
+	/** @field cast=(gint (*)()) */
+	public int /*long*/ get_index_at;
+	/** @field cast=(gint (*)()) */
+	public int /*long*/ get_column_at_index;
+	/** @field cast=(gint (*)()) */
+	public int /*long*/ get_row_at_index;
+	/** @field cast=(gint (*)()) */
+	public int /*long*/ get_n_columns;
+	/** @field cast=(gint (*)()) */
+	public int /*long*/ get_n_rows;
+	/** @field cast=(gint (*)()) */
+	public int /*long*/ get_column_extent_at;
+	/** @field cast=(gint (*)()) */
+	public int /*long*/ get_row_extent_at;
+	/** @field cast=(AtkObject* (*)()) */
+	public int /*long*/ get_caption;
+	/** @field cast=(G_CONST_RETURN gchar* (*)()) */
+	public int /*long*/ get_column_description;
+	/** @field cast=(AtkObject* (*)()) */
+	public int /*long*/ get_column_header;
+	/** @field cast=(G_CONST_RETURN gchar* (*)()) */
+	public int /*long*/ get_row_description;
+	/** @field cast=(AtkObject* (*)()) */
+	public int /*long*/ get_row_header;
+	/** @field cast=(AtkObject* (*)()) */
+	public int /*long*/ get_summary;
+	/** @field cast=(void (*)()) */
+	public int /*long*/ set_caption;
+	/** @field cast=(void (*)()) */
+	public int /*long*/ set_column_description;
+	/** @field cast=(void (*)()) */
+	public int /*long*/ set_column_header;
+	/** @field cast=(void (*)()) */
+	public int /*long*/ set_row_description;
+	/** @field cast=(void (*)()) */
+	public int /*long*/ set_row_header;
+	/** @field cast=(void (*)()) */
+	public int /*long*/ set_summary;
+	/** @field cast=(gint (*)()) */
+	public int /*long*/ get_selected_columns;
+	/** @field cast=(gint (*)()) */
+	public int /*long*/ get_selected_rows;
+	/** @field cast=(gboolean (*)()) */
+	public int /*long*/ is_column_selected;
+	/** @field cast=(gboolean (*)()) */
+	public int /*long*/ is_row_selected;
+	/** @field cast=(gboolean (*)()) */
+	public int /*long*/ is_selected;
+	/** @field cast=(gboolean (*)()) */
+	public int /*long*/ add_row_selection;
+	/** @field cast=(gboolean (*)()) */
+	public int /*long*/ remove_row_selection;
+	/** @field cast=(gboolean (*)()) */
+	public int /*long*/ add_column_selection;
+	/** @field cast=(gboolean (*)()) */
+	public int /*long*/ remove_column_selection;
+	/** @field cast=(void (*)()) */
+	public int /*long*/ row_inserted;
+	/** @field cast=(void (*)()) */
+	public int /*long*/ column_inserted;
+	/** @field cast=(void (*)()) */
+	public int /*long*/ row_deleted;
+	/** @field cast=(void (*)()) */
+	public int /*long*/ column_deleted;
+	/** @field cast=(void (*)()) */
+	public int /*long*/ row_reordered;
+	/** @field cast=(void (*)()) */
+	public int /*long*/ column_reordered;
+	/** @field cast=(void (*)()) */
+	public int /*long*/ model_changed;
+}
diff --git a/org/eclipse/swt/internal/accessibility/gtk/AtkTextIface.java b/org/eclipse/swt/internal/accessibility/gtk/AtkTextIface.java
index 5e74aa7..0ab9f65 100644
--- a/org/eclipse/swt/internal/accessibility/gtk/AtkTextIface.java
+++ b/org/eclipse/swt/internal/accessibility/gtk/AtkTextIface.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others. All rights reserved.
+ * Copyright (c) 2000, 2010 IBM Corporation and others. All rights reserved.
  * The contents of this file are made available under the terms
  * of the GNU Lesser General Public License (LGPL) Version 2.1 that
  * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
@@ -56,4 +56,8 @@ public class AtkTextIface {
 	public int /*long*/ text_caret_moved;
 	/** @field cast=(void (*)()) */
 	public int /*long*/ text_selection_changed;
+	/** @field cast=(void (*)()) */
+	public int /*long*/ get_range_extents;
+	/** @field cast=(AtkTextRange** (*)()) */
+	public int /*long*/ get_bounded_ranges;
 }
diff --git a/org/eclipse/swt/internal/accessibility/gtk/AtkTextRange.java b/org/eclipse/swt/internal/accessibility/gtk/AtkTextRange.java
new file mode 100644
index 0000000..fedd295
--- /dev/null
+++ b/org/eclipse/swt/internal/accessibility/gtk/AtkTextRange.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2010 IBM Corporation and others. All rights reserved.
+ * The contents of this file are made available under the terms
+ * of the GNU Lesser General Public License (LGPL) Version 2.1 that
+ * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
+ * available at http://www.gnu.org/licenses/lgpl.html.  If the version
+ * of the LGPL at http://www.gnu.org is different to the version of
+ * the LGPL accompanying this distribution and there is any conflict
+ * between the two license versions, the terms of the LGPL accompanying
+ * this distribution shall govern.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.internal.accessibility.gtk;
+
+
+public class AtkTextRange {
+	public AtkTextRectangle bounds = new AtkTextRectangle();
+	public int start_offset;
+	public int end_offset;
+	/** @field cast=(gchar *) */
+	public int /*long*/ content;
+	public static final int sizeof = ATK.AtkTextRange_sizeof ();
+
+}
+
diff --git a/org/eclipse/swt/internal/accessibility/gtk/AtkTextRectangle.java b/org/eclipse/swt/internal/accessibility/gtk/AtkTextRectangle.java
new file mode 100644
index 0000000..deb0586
--- /dev/null
+++ b/org/eclipse/swt/internal/accessibility/gtk/AtkTextRectangle.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2010 IBM Corporation and others. All rights reserved.
+ * The contents of this file are made available under the terms
+ * of the GNU Lesser General Public License (LGPL) Version 2.1 that
+ * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
+ * available at http://www.gnu.org/licenses/lgpl.html.  If the version
+ * of the LGPL at http://www.gnu.org is different to the version of
+ * the LGPL accompanying this distribution and there is any conflict
+ * between the two license versions, the terms of the LGPL accompanying
+ * this distribution shall govern.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.internal.accessibility.gtk;
+
+
+public class AtkTextRectangle {
+	public int x;
+	public int y;
+	public int width;
+	public int height;
+	public static final int sizeof = ATK.AtkTextRectangle_sizeof ();
+}
+
diff --git a/org/eclipse/swt/internal/accessibility/gtk/AtkValueIface.java b/org/eclipse/swt/internal/accessibility/gtk/AtkValueIface.java
new file mode 100644
index 0000000..26cfe52
--- /dev/null
+++ b/org/eclipse/swt/internal/accessibility/gtk/AtkValueIface.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2010 IBM Corporation and others. All rights reserved.
+ * The contents of this file are made available under the terms
+ * of the GNU Lesser General Public License (LGPL) Version 2.1 that
+ * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
+ * available at http://www.gnu.org/licenses/lgpl.html.  If the version
+ * of the LGPL at http://www.gnu.org is different to the version of
+ * the LGPL accompanying this distribution and there is any conflict
+ * between the two license versions, the terms of the LGPL accompanying
+ * this distribution shall govern.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.internal.accessibility.gtk;
+
+
+public class AtkValueIface {
+	/** @field cast=(void (*)()) */
+	public int /*long*/ get_current_value;
+	/** @field cast=(void (*)()) */
+	public int /*long*/ get_maximum_value;
+	/** @field cast=(void (*)()) */
+	public int /*long*/ get_minimum_value;
+	/** @field cast=(gboolean (*)()) */
+	public int /*long*/ set_current_value;
+}
diff --git a/org/eclipse/swt/internal/gnome/GNOME.java b/org/eclipse/swt/internal/gnome/GNOME.java
index 9802b71..30f539d 100644
--- a/org/eclipse/swt/internal/gnome/GNOME.java
+++ b/org/eclipse/swt/internal/gnome/GNOME.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others. All rights reserved.
+ * Copyright (c) 2000, 2010 IBM Corporation and others. All rights reserved.
  * The contents of this file are made available under the terms
  * of the GNU Lesser General Public License (LGPL) Version 2.1 that
  * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
@@ -25,6 +25,9 @@ public static final int GNOME_FILE_DOMAIN_PIXMAP = 4;
 public static final int GNOME_ICON_LOOKUP_FLAGS_NONE = 0;
 public static final int GNOME_PARAM_NONE = 0;
 public static final int GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_URIS = 0;
+public static final int GNOME_VFS_MIME_IDENTICAL = 1;
+public static final int GNOME_VFS_MIME_PARENT = 2;
+public static final int GNOME_VFS_MIME_UNRELATED = 0;
 public static final int GNOME_VFS_OK = 0;
 public static final int GNOME_VFS_MAKE_URI_DIR_NONE = 0;
 public static final int GNOME_VFS_MAKE_URI_DIR_HOMEDIR = 1<<0;
@@ -138,6 +141,17 @@ public static final int /*long*/ gnome_vfs_get_registered_mime_types() {
 		lock.unlock();
 	}
 }
+/** @param uri cast=(const char *) */
+public static final native int /*long*/ _gnome_vfs_get_mime_type(int /*long*/ uri);
+public static final int /*long*/ gnome_vfs_get_mime_type(int /*long*/ uri) {
+	lock.lock();
+	try {
+		return _gnome_vfs_get_mime_type(uri);
+	} finally {
+		lock.unlock();
+	}
+}
+
 public static final native boolean _gnome_vfs_init();
 public static final boolean gnome_vfs_init() {
 	lock.lock();
@@ -180,6 +194,16 @@ public static final void gnome_vfs_mime_application_free(int /*long*/ applicatio
 		lock.unlock();
 	}
 }
+/** @param command_string cast=(const char *) */
+public static final native boolean _gnome_vfs_is_executable_command_string(byte[] command_string);
+public static final boolean gnome_vfs_is_executable_command_string(byte[] command_string) {
+	lock.lock();
+	try {
+		return _gnome_vfs_is_executable_command_string(command_string);
+	} finally {
+		lock.unlock();
+	}
+}
 /**
  * @method flags=dynamic
  * @param application cast=(GnomeVFSMimeApplication *)
@@ -244,6 +268,19 @@ public static final int /*long*/ gnome_vfs_mime_type_from_name(byte[] file) {
 		lock.unlock();
 	}
 }
+/** 
+ * @param mime_type cast=(const char *)
+ * @param base_mime_type cast=(const char *) 
+ */
+public static final native int /*long*/ _gnome_vfs_mime_type_get_equivalence(int /*long*/ mime_type, byte [] base_mime_type);
+public static final int /*long*/ gnome_vfs_mime_type_get_equivalence(int /*long*/ mime_type, byte [] base_mime_type) {
+	lock.lock();
+	try {
+		return _gnome_vfs_mime_type_get_equivalence(mime_type, base_mime_type);
+	} finally {
+		lock.unlock();
+	}
+}
 /**
  * @method flags=dynamic
  * @param url cast=(const char *)
diff --git a/org/eclipse/swt/internal/gtk/GdkEventMotion.java b/org/eclipse/swt/internal/gtk/GdkEventMotion.java
index c85069f..e813867 100644
--- a/org/eclipse/swt/internal/gtk/GdkEventMotion.java
+++ b/org/eclipse/swt/internal/gtk/GdkEventMotion.java
@@ -1,42 +1,42 @@
-/*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others. All rights reserved.
- * The contents of this file are made available under the terms
- * of the GNU Lesser General Public License (LGPL) Version 2.1 that
- * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
- * available at http://www.gnu.org/licenses/lgpl.html.  If the version
- * of the LGPL at http://www.gnu.org is different to the version of
- * the LGPL accompanying this distribution and there is any conflict
- * between the two license versions, the terms of the LGPL accompanying
- * this distribution shall govern.
- * 
- * Contributors:
- *     IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.swt.internal.gtk;
-
-
-public class GdkEventMotion extends GdkEvent {
-	/** @field cast=(GdkWindow *) */
-	public int /*long*/ window;
-	/** @field cast=(gint8) */
-	public byte send_event;
-	/** @field cast=(guint32) */
-	public int time;
-	/** @field cast=(gdouble) */
-	public double x;
-	/** @field cast=(gdouble) */
-	public double y;
-	/** @field cast=(gdouble *) */
-	public int /*long*/ axes;
-	/** @field cast=(guint) */
-	public int state;
-	/** @field cast=(gint16) */
-	public short is_hint;
-	/** @field cast=(GdkDevice *) */
-	public int /*long*/ device;
-	/** @field cast=(gdouble) */
-	public double x_root;
-	/** @field cast=(gdouble) */
-	public double y_root;
-	public static final int sizeof = OS.GdkEventMotion_sizeof();
-}
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others. All rights reserved.
+ * The contents of this file are made available under the terms
+ * of the GNU Lesser General Public License (LGPL) Version 2.1 that
+ * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
+ * available at http://www.gnu.org/licenses/lgpl.html.  If the version
+ * of the LGPL at http://www.gnu.org is different to the version of
+ * the LGPL accompanying this distribution and there is any conflict
+ * between the two license versions, the terms of the LGPL accompanying
+ * this distribution shall govern.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.internal.gtk;
+
+
+public class GdkEventMotion extends GdkEvent {
+	/** @field cast=(GdkWindow *) */
+	public int /*long*/ window;
+	/** @field cast=(gint8) */
+	public byte send_event;
+	/** @field cast=(guint32) */
+	public int time;
+	/** @field cast=(gdouble) */
+	public double x;
+	/** @field cast=(gdouble) */
+	public double y;
+	/** @field cast=(gdouble *) */
+	public int /*long*/ axes;
+	/** @field cast=(guint) */
+	public int state;
+	/** @field cast=(gint16) */
+	public short is_hint;
+	/** @field cast=(GdkDevice *) */
+	public int /*long*/ device;
+	/** @field cast=(gdouble) */
+	public double x_root;
+	/** @field cast=(gdouble) */
+	public double y_root;
+	public static final int sizeof = OS.GdkEventMotion_sizeof();
+}
diff --git a/org/eclipse/swt/internal/gtk/GdkEventProperty.java b/org/eclipse/swt/internal/gtk/GdkEventProperty.java
new file mode 100644
index 0000000..1abcbd6
--- /dev/null
+++ b/org/eclipse/swt/internal/gtk/GdkEventProperty.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 IBM Corporation and others. All rights reserved.
+ * The contents of this file are made available under the terms
+ * of the GNU Lesser General Public License (LGPL) Version 2.1 that
+ * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
+ * available at http://www.gnu.org/licenses/lgpl.html.  If the version
+ * of the LGPL at http://www.gnu.org is different to the version of
+ * the LGPL accompanying this distribution and there is any conflict
+ * between the two license versions, the terms of the LGPL accompanying
+ * this distribution shall govern.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.internal.gtk;
+
+public class GdkEventProperty extends GdkEvent {
+	/** @field cast=(GdkWindow *) */
+	public int /*long*/ window;
+	/** @field cast=(gint8) */
+	public byte send_event;
+	/** @field cast=(GdkAtom) */
+	public int /*long*/ atom;
+	/** @field cast=(guint32) */
+	public int time;
+	/** @field cast=(guint) */
+	public int state;
+	public static final int sizeof = OS.GdkEventProperty_sizeof();
+}
diff --git a/org/eclipse/swt/internal/gtk/OS.java b/org/eclipse/swt/internal/gtk/OS.java
index 29323e0..7bdd8a6 100644
--- a/org/eclipse/swt/internal/gtk/OS.java
+++ b/org/eclipse/swt/internal/gtk/OS.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others. All rights reserved.
+ * Copyright (c) 2000, 2010 IBM Corporation and others. All rights reserved.
  * The contents of this file are made available under the terms
  * of the GNU Lesser General Public License (LGPL) Version 2.1 that
  * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
@@ -38,7 +38,11 @@ public class OS extends C {
 	}
 
 	/** Constants */
+	public static final int /*long*/ AnyPropertyType = 0;
 	public static final int ATK_RELATION_LABELLED_BY = 4;
+	public static final int G_FILE_TEST_IS_DIR = 1 << 2;
+	public static final int G_FILE_TEST_IS_EXECUTABLE = 1 << 3;
+	public static final int G_SIGNAL_MATCH_FUNC = 1 << 3;
 	public static final int G_SIGNAL_MATCH_DATA = 1 << 4;
 	public static final int G_SIGNAL_MATCH_ID = 1 << 0;
 	public static final int GDK_2BUTTON_PRESS = 0x5;
@@ -109,6 +113,11 @@ public class OS extends C {
 	public static final int GDK_F13 = 0xffca;
 	public static final int GDK_F14 = 0xffcb;
 	public static final int GDK_F15 = 0xffcc;
+	public static final int GDK_F16 = 0xffcd;
+	public static final int GDK_F17 = 0xffce;
+	public static final int GDK_F18 = 0xffcf;
+	public static final int GDK_F19 = 0xffd0;
+	public static final int GDK_F20 = 0xffd1;
 	public static final int GDK_F2 = 0xffbf;
 	public static final int GDK_F3 = 0xffc0;
 	public static final int GDK_F4 = 0xffc1;
@@ -195,6 +204,7 @@ public class OS extends C {
 	public static final int GDK_POINTER_MOTION_HINT_MASK = 0x8;
 	public static final int GDK_POINTER_MOTION_MASK = 0x4;
 	public static final int GDK_PROPERTY_NOTIFY = 16;
+	public static final int GDK_PROPERTY_CHANGE_MASK = 1 << 16;
 	public static final int GDK_Page_Down = 0xff56;
 	public static final int GDK_Page_Up = 0xff55;
 	public static final int GDK_Pause = 0xff13;
@@ -260,6 +270,8 @@ public class OS extends C {
 	public static final int GTK_DIALOG_MODAL = 1 << 0;
 	public static final int GTK_DIR_TAB_FORWARD = 0;
 	public static final int GTK_DIR_TAB_BACKWARD = 1;
+	public static final int GTK_ENTRY_ICON_PRIMARY = 0;
+	public static final int GTK_ENTRY_ICON_SECONDARY = 1;
 	public static final int GTK_FILE_CHOOSER_ACTION_OPEN = 0;
 	public static final int GTK_FILE_CHOOSER_ACTION_SAVE = 1;
 	public static final int GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER = 2;
@@ -382,6 +394,9 @@ public class OS extends C {
 	public static final int G_LOG_FLAG_FATAL = 0x2;
 	public static final int G_LOG_FLAG_RECURSION = 0x1;
 	public static final int G_LOG_LEVEL_MASK = 0xfffffffc;
+	public static final int G_APP_INFO_CREATE_NONE = 0;
+	public static final int G_APP_INFO_CREATE_NEEDS_TERMINAL = (1 << 0);
+	public static final int G_APP_INFO_CREATE_SUPPORTS_URIS  = (1 << 1); 
 	public static final int None = 0;
 	public static final int PANGO_ALIGN_LEFT = 0;
 	public static final int PANGO_ALIGN_CENTER = 1;
@@ -410,6 +425,7 @@ public class OS extends C {
 	public static final int RTLD_GLOBAL = 0x100;
 	public static final int RTLD_LAZY = 1;
 	public static final int RTLD_NOW = 2;
+	public static final int X_OK = 0x01;
 	public static final int XA_CARDINAL = 6;
 	public static final int XA_WINDOW = 33;
 	
@@ -445,6 +461,7 @@ public class OS extends C {
 	public static final byte[] focus_out_event = ascii("focus-out-event");
 	public static final byte[] grab_focus = ascii("grab-focus");
 	public static final byte[] hide = ascii("hide");
+	public static final byte[] icon_release = ascii("icon-release");
 	public static final byte[] input = ascii("input");
 	public static final byte[] insert_text = ascii("insert-text");
 	public static final byte[] key_press_event = ascii("key-press-event");
@@ -460,6 +477,7 @@ public class OS extends C {
 	public static final byte[] popup_menu = ascii("popup-menu");
 	public static final byte[] populate_popup = ascii("populate-popup");
 	public static final byte[] preedit_changed = ascii("preedit-changed");
+	public static final byte[] property_notify_event = ascii("property-notify-event");
 	public static final byte[] realize = ascii("realize");
 	public static final byte[] row_activated = ascii("row-activated");
 	public static final byte[] row_changed = ascii("row-changed");
@@ -468,10 +486,12 @@ public class OS extends C {
 	public static final byte[] scroll_child = ascii("scroll-child");
 	public static final byte[] scroll_event = ascii("scroll-event");
 	public static final byte[] select = ascii("select");
+	public static final byte[] selection_done = ascii("selection-done");
 	public static final byte[] show = ascii("show");
 	public static final byte[] show_help = ascii("show-help");
 	public static final byte[] size_allocate = ascii("size-allocate");
 	public static final byte[] size_request = ascii("size-request");
+	public static final byte[] start_interactive_search = ascii("start-interactive-search");
 	public static final byte[] style_set = ascii("style-set");
 	public static final byte[] switch_page = ascii("switch-page");
 	public static final byte[] test_collapse_row = ascii("test-collapse-row");
@@ -512,6 +532,9 @@ public class OS extends C {
 	public static final byte[] xalign = ascii("xalign");
 	public static final byte[] ypad = ascii("ypad");
 	public static final byte[] GTK_PRINT_SETTINGS_OUTPUT_URI = ascii("output-uri");
+	public static final byte[] GTK_STOCK_FIND = ascii("gtk-find");
+	public static final byte[] GTK_STOCK_CANCEL = ascii("gtk-cancel");
+	public static final byte[] GTK_STOCK_CLEAR = ascii("gtk-clear");
 	
 	public static final int GTK_VERSION = VERSION(gtk_major_version(), gtk_minor_version(), gtk_micro_version()); 
 	
@@ -545,6 +568,7 @@ public static final native int GdkEventExpose_sizeof();
 public static final native int GdkEventFocus_sizeof();
 public static final native int GdkEventKey_sizeof();
 public static final native int GdkEventMotion_sizeof();
+public static final native int GdkEventProperty_sizeof();
 public static final native int GdkEventScroll_sizeof();
 public static final native int GdkEventVisibility_sizeof();
 public static final native int GdkEventWindowState_sizeof();
@@ -583,7 +607,6 @@ public static final native int PangoLayoutRun_sizeof();
 public static final native int PangoLogAttr_sizeof();
 public static final native int PangoRectangle_sizeof();
 public static final native int XAnyEvent_sizeof();
-public static final native int XButtonEvent_sizeof();
 public static final native int XClientMessageEvent_sizeof();
 public static final native int XEvent_sizeof();
 public static final native int XCrossingEvent_sizeof();
@@ -618,6 +641,18 @@ public static final native int /*long*/ GTK_WIDGET_WINDOW(int /*long*/ widget);
 public static final native int GTK_WIDGET_X(int /*long*/ widget);
 /** @param widget cast=(GtkWidget *) */
 public static final native int GTK_WIDGET_Y(int /*long*/ widget);
+/** @param widget cast=(GtkRange *) */
+public static final native int GTK_RANGE_SLIDER_START(int /*long*/ widget);
+/** @param widget cast=(GtkRange *) */
+public static final native int GTK_RANGE_SLIDER_END(int /*long*/ widget);
+/** @param widget cast=(GtkRange *) */
+public static final native boolean GTK_RANGE_HAS_STEPPER_A(int /*long*/ widget);
+/** @param widget cast=(GtkRange *) */
+public static final native boolean GTK_RANGE_HAS_STEPPER_B(int /*long*/ widget);
+/** @param widget cast=(GtkRange *) */
+public static final native boolean GTK_RANGE_HAS_STEPPER_C(int /*long*/ widget);
+/** @param widget cast=(GtkRange *) */
+public static final native boolean GTK_RANGE_HAS_STEPPER_D(int /*long*/ widget);
 /** @param widget cast=(GtkScrolledWindow *) */
 public static final native int /*long*/ GTK_SCROLLED_WINDOW_HSCROLLBAR(int /*long*/ widget);
 /** @param widget cast=(GtkScrolledWindow *) */
@@ -812,6 +847,21 @@ public static final void XFree(int /*long*/ address) {
 /**
  * @param display cast=(Display *)
  * @param selection cast=(Atom)
+ * @param owner cast=(Window)
+ * @param time cast=(Time)
+ */
+public static final native int /*long*/ _XSetSelectionOwner(int /*long*/ display, int /*long*/ selection, int /*long*/ window, int time);
+public static final int /*long*/ XSetSelectionOwner(int /*long*/ display, int /*long*/ selection, int /*long*/ window, int time) {
+	lock.lock();
+	try {
+		return _XSetSelectionOwner(display, selection, window, time);
+	} finally {
+		lock.unlock();
+	}
+}
+/**
+ * @param display cast=(Display *)
+ * @param selection cast=(Atom)
  */
 public static final native int /*long*/ _XGetSelectionOwner(int /*long*/ display, int /*long*/ selection);
 public static final int /*long*/ XGetSelectionOwner(int /*long*/ display, int /*long*/ selection) {
@@ -822,6 +872,30 @@ public static final int /*long*/ XGetSelectionOwner(int /*long*/ display, int /*
 		lock.unlock();
 	}
 }
+
+/**
+ * @param display cast=(Display *)
+ * @param window cast=(Window)
+ * @param property cast=(Atom)
+ * @param req_type cast=(Atom)
+ * @param actual_type_return cast=(Atom*)
+ * @param actual_format_return cast=(Atom*)
+ * @param actual_format_return cast=(int *)
+ * @param nitems_return cast=(unsigned long *)
+ * @param bytes_after_return cast=(unsigned long *)
+ * @param prop_return cast=(unsigned char **)
+ */
+public static final native int /*long*/ _XGetWindowProperty(int /*long*/ display, int /*long*/ window, int /*long*/ property, int offset, int length, boolean delete, int /*long*/ req_type, int /*long*/ [] actual_type_return, int [] actual_format_return , int[] nitems_return, int[] bytes_after_return, int /*long*/ [] prop_return);
+public static final int /*long*/ XGetWindowProperty(int /*long*/ display, int /*long*/ window, int /*long*/ property, int offset, int length, boolean delete, int /*long*/ req_type, int /*long*/ [] actual_type_return, int [] actual_format_return, int[] nitems_return, int[] bytes_after_return, int /*long*/ [] prop_return) {
+	lock.lock();
+	try {
+		return _XGetWindowProperty(display, window, property, offset, length, delete, req_type, actual_type_return, actual_format_return , nitems_return, bytes_after_return, prop_return);
+	} finally {
+		lock.unlock();
+	}
+}
+
+
 /**
  * @param display cast=(Display *)
  * @param name cast=(char *)
@@ -1168,12 +1242,6 @@ public static final void gdk_window_remove_filter(int /*long*/ window, int /*lon
  * @param src cast=(const void *),flags=no_out
  * @param size cast=(size_t)
  */
-public static final native void memmove(int /*long*/ dest, XButtonEvent src, int /*long*/ size);
-/**
- * @param dest cast=(void *)
- * @param src cast=(const void *),flags=no_out
- * @param size cast=(size_t)
- */
 public static final native void memmove(int /*long*/ dest, XClientMessageEvent src, int /*long*/ size);
 /**
  * @param dest cast=(void *)
@@ -1198,12 +1266,6 @@ public static final native void memmove(int /*long*/ dest, XFocusChangeEvent src
  * @param src cast=(const void *)
  * @param size cast=(size_t)
  */
-public static final native void memmove(XButtonEvent dest, int /*long*/ src, int /*long*/ size);
-/**
- * @param dest cast=(void *),flags=no_in
- * @param src cast=(const void *)
- * @param size cast=(size_t)
- */
 public static final native void memmove(XCrossingEvent dest, int /*long*/ src, int /*long*/ size);
 /**
  * @param dest cast=(void *),flags=no_in
@@ -1328,6 +1390,12 @@ public static final int /*long*/ XRenderFindVisualFormat(int /*long*/ display, i
 	}
 }
 
+/** Custom callbacks */
+
+/** @method flags=no_gen */
+public static final native int /*long*/ pangoLayoutNewProc_CALLBACK(int /*long*/ func);
+
+
 /** Natives */
 public static final native int Call (int /*long*/ func, int /*long*/ arg0, int arg1, int arg2);
 public static final native long Call (int /*long*/ func, int /*long*/ arg0, int arg1, long arg2);
@@ -1378,6 +1446,15 @@ public static final boolean GTK_IS_BUTTON(int /*long*/ obj) {
 		lock.unlock();
 	}
 }
+public static final native boolean _GTK_IS_SCROLLED_WINDOW(int /*long*/ obj);
+public static final boolean GTK_IS_SCROLLED_WINDOW(int /*long*/ obj) {
+	lock.lock();
+	try {
+		return _GTK_IS_SCROLLED_WINDOW(obj);
+	} finally {
+		lock.unlock();
+	}
+}
 public static final native boolean _GTK_IS_WINDOW(int /*long*/ obj);
 public static final boolean GTK_IS_WINDOW(int /*long*/ obj) {
 	lock.lock();
@@ -1657,25 +1734,16 @@ public static final int /*long*/ G_OBJECT_TYPE_NAME (int /*long*/ object) {
 	}
 }
 /** @method flags=const */
-public static final native int /*long*/ _G_TYPE_BOOLEAN();
-public static final int /*long*/ G_TYPE_BOOLEAN() {
-	lock.lock();
-	try {
-		return _G_TYPE_BOOLEAN();
-	} finally {
-		lock.unlock();
-	}
-}
+public static final native int /*long*/ G_TYPE_BOOLEAN();
 /** @method flags=const */
-public static final native int /*long*/ _G_TYPE_INT();
-public static final int /*long*/ G_TYPE_INT() {
-	lock.lock();
-	try {
-		return _G_TYPE_INT();
-	} finally {
-		lock.unlock();
-	}
-}
+public static final native int /*long*/ G_TYPE_DOUBLE();
+/** @method flags=const */
+public static final native int /*long*/ G_TYPE_FLOAT();
+/** @method flags=const */
+public static final native int /*long*/ G_TYPE_INT();
+/** @method flags=const */
+public static final native int /*long*/ G_TYPE_INT64();
+public static final native int /*long*/ G_VALUE_TYPE(int /*long*/ value);
 public static final native int /*long*/ _G_OBJECT_TYPE (int /*long*/ instance);
 public static final int /*long*/ G_OBJECT_TYPE (int /*long*/ instance) {
 	lock.lock();
@@ -1757,6 +1825,307 @@ public static final int /*long*/ dlsym(int /*long*/ handle, byte[] symbol) {
 		lock.unlock();
 	}
 }
+/** @method flags=dynamic */
+public static final native int /*long*/ _g_app_info_create_from_commandline(byte[] commandline, byte[] applName, int /*long*/ flags, int /*long*/ error);
+public static final int /*long*/ g_app_info_create_from_commandline(byte[] commandline, byte[] applName, int /*long*/ flags, int /*long*/ error) {
+	lock.lock();
+	try {
+		return _g_app_info_create_from_commandline(commandline, applName, flags, error);
+	} finally {
+		lock.unlock();
+	}
+}
+/** @method flags=dynamic */
+public static final native int /*long*/ _g_app_info_get_all();
+public static final int /*long*/ g_app_info_get_all() {
+	lock.lock();
+	try {
+		return _g_app_info_get_all();
+	} finally {
+		lock.unlock();
+	}
+}
+/** @method flags=dynamic */
+public static final native int /*long*/ _g_app_info_get_executable(int /*long*/ appInfo);
+public static final int /*long*/ g_app_info_get_executable(int /*long*/ appInfo) {
+	lock.lock();
+	try {
+		return _g_app_info_get_executable(appInfo);
+	} finally {
+		lock.unlock();
+	}
+}
+/** @method flags=dynamic */
+public static final native int /*long*/ _g_app_info_get_icon(int /*long*/ appInfo);
+public static final int /*long*/ g_app_info_get_icon(int /*long*/ appInfo) {
+	lock.lock();
+	try {
+		return _g_app_info_get_icon(appInfo);
+	} finally {
+		lock.unlock();
+	}
+}
+/** @method flags=dynamic */
+public static final native int /*long*/ _g_app_info_get_id(int /*long*/ appInfo);
+public static final int /*long*/ g_app_info_get_id(int /*long*/ appInfo) {
+	lock.lock();
+	try {
+		return _g_app_info_get_id(appInfo);
+	} finally {
+		lock.unlock();
+	}
+}
+/** @method flags=dynamic */
+public static final native int /*long*/ _g_app_info_get_name(int /*long*/ appInfo);
+public static final int /*long*/ g_app_info_get_name(int /*long*/ appInfo) {
+	lock.lock();
+	try {
+		return _g_app_info_get_name(appInfo);
+	} finally {
+		lock.unlock();
+	}
+}
+/** @method flags=dynamic */
+public static final native boolean _g_app_info_launch(int /*long*/ appInfo, int /*long*/ list, int /*long*/ launchContext, int /*long*/ error);
+public static final boolean g_app_info_launch(int /*long*/ appInfo, int /*long*/ list, int /*long*/ launchContext, int /*long*/ error) {
+	lock.lock();
+	try {
+		return _g_app_info_launch(appInfo, list, launchContext, error);
+	} finally {
+		lock.unlock();
+	}
+}
+/** @method flags=dynamic */
+public static final native int /*long*/ _g_app_info_get_default_for_type(byte[] mimeType, boolean mustSupportURIs);
+public static final int /*long*/ g_app_info_get_default_for_type(byte[] mimeType, boolean mustSupportURIs) {
+	lock.lock();
+	try {
+		return _g_app_info_get_default_for_type(mimeType, mustSupportURIs);
+	} finally {
+		lock.unlock();
+	}
+}
+/** @method flags=dynamic */
+public static final native boolean _g_app_info_launch_default_for_uri(int /*long*/ uri, int /*long*/ launchContext, int /*long*/ error);
+public static final boolean g_app_info_launch_default_for_uri(int /*long*/ appInfo, int /*long*/ launchContext, int /*long*/ error) {
+	lock.lock();
+	try {
+		return _g_app_info_launch_default_for_uri(appInfo, launchContext, error);
+	} finally {
+		lock.unlock();
+	}
+}
+/** @method flags=dynamic */
+public static final native boolean _g_app_info_should_show(int /*long*/ appInfo);
+public static final boolean g_app_info_should_show(int /*long*/ appInfo) {
+	lock.lock();
+	try {
+		return _g_app_info_should_show(appInfo);
+	} finally {
+		lock.unlock();
+	}
+}
+/** @method flags=dynamic */
+public static final native boolean _g_app_info_supports_uris(int /*long*/ appInfo);
+public static final boolean g_app_info_supports_uris(int /*long*/ appInfo) {
+	lock.lock();
+	try {
+		return _g_app_info_supports_uris(appInfo);
+	} finally {
+		lock.unlock();
+	}
+}
+/** @method flags=dynamic */
+public static final native int /*long*/ _g_data_input_stream_new(int /*long*/ input_stream);
+public static final int /*long*/ g_data_input_stream_new(int /*long*/ input_stream) {
+	lock.lock();
+	try {
+		return _g_data_input_stream_new(input_stream);
+	} finally {
+		lock.unlock();
+	}
+}
+/** @method flags=dynamic */
+public static final native int /*long*/ _g_data_input_stream_read_line(int /*long*/ stream, int[] count, int /*long*/ cancellable, int /*long*/ error);
+public static final int /*long*/ g_data_input_stream_read_line(int /*long*/ stream, int[] count, int /*long*/ cancellable, int /*long*/ error) {
+	lock.lock();
+	try {
+		return _g_data_input_stream_read_line(stream, count, cancellable, error);
+	} finally {
+		lock.unlock();
+	}
+}
+/** @method flags=dynamic */
+public static final native boolean _g_content_type_equals(int /*long*/ type1, byte[] type2);
+public static final boolean g_content_type_equals(int /*long*/ type1, byte[] type2) {
+	lock.lock();
+	try {
+		return _g_content_type_equals(type1, type2);
+	} finally {
+		lock.unlock();
+	}
+}
+/** @method flags=dynamic */
+public static final native boolean _g_content_type_is_a(int /*long*/ type, byte[] supertype);
+public static final boolean g_content_type_is_a(int /*long*/ type, byte[] supertype) {
+	lock.lock();
+	try {
+		return _g_content_type_is_a(type, supertype);
+	} finally {
+		lock.unlock();
+	}
+}
+/** @method flags=dynamic */
+public static final native int /*long*/ _g_content_type_get_mime_type(byte[] mime_type);
+public static final int /*long*/ g_content_type_get_mime_type(byte[] mime_type) {
+	lock.lock();
+	try {
+		return _g_content_type_get_mime_type(mime_type);
+	} finally {
+		lock.unlock();
+	}
+}
+/** @method flags=dynamic */
+public static final native int /*long*/ _g_content_types_get_registered();
+public static final int /*long*/ g_content_types_get_registered() {
+	lock.lock();
+	try {
+		return _g_content_types_get_registered();
+	} finally {
+		lock.unlock();
+	}
+}
+/** @method flags=dynamic */
+public static final native int /*long*/ _g_desktop_app_info_new_from_filename(byte[] fileName);
+public static final int /*long*/ g_desktop_app_info_new_from_filename(byte[] fileName) {
+	lock.lock();
+	try {
+		return _g_desktop_app_info_new_from_filename(fileName);
+	} finally {
+		lock.unlock();
+	}
+}
+/** @method flags=dynamic */
+public static final native int /*long*/ _g_file_info_get_content_type (int /*long*/ info);
+public static final int /*long*/ g_file_info_get_content_type (int /*long*/ info) {
+	lock.lock();
+	try {
+		return _g_file_info_get_content_type (info);
+	} finally {
+		lock.unlock();
+	}
+}
+/** @method flags=dynamic */
+public static final native int /*long*/ _g_file_get_path(int /*long*/ file);
+public static final int /*long*/ g_file_get_path (int /*long*/ file) {
+	lock.lock();
+	try {
+		return _g_file_get_path(file);
+	} finally {
+		lock.unlock();
+	}
+}
+/** @method flags=dynamic */
+public static final native int /*long*/ _g_file_get_uri(int /*long*/ file);
+public static final int /*long*/ g_file_get_uri (int /*long*/ file) {
+	lock.lock();
+	try {
+		return _g_file_get_uri(file);
+	} finally {
+		lock.unlock();
+	}
+}
+/** @method flags=dynamic */
+public static final native void _g_file_info_get_modification_time(int /*long*/ info, int /*long*/[] result);
+public static final void g_file_info_get_modification_time(int /*long*/ info, int /*long*/[] result) {
+	lock.lock();
+	try {
+		_g_file_info_get_modification_time(info, result);
+	} finally {
+		lock.unlock();
+	}
+}
+/** @method flags=dynamic */
+public static final native int /*long*/ _g_file_icon_get_file(int /*long*/ icon);
+public static final int /*long*/ g_file_icon_get_file(int /*long*/ icon) {
+	lock.lock();
+	try {
+		return _g_file_icon_get_file(icon);
+	} finally {
+		lock.unlock();
+	}
+}
+/** @method flags=dynamic */
+public static final native int /*long*/ _g_file_new_for_path(byte[] fileName);
+public static final int /*long*/ g_file_new_for_path(byte[] fileName) {
+	lock.lock();
+	try {
+		return _g_file_new_for_path(fileName);
+	} finally {
+		lock.unlock();
+	}
+}
+/** @method flags=dynamic */
+public static final native int /*long*/ _g_file_new_for_uri(byte[] fileName);
+public static final int /*long*/ g_file_new_for_uri(byte[] fileName) {
+	lock.lock();
+	try {
+		return _g_file_new_for_uri(fileName);
+	} finally {
+		lock.unlock();
+	}
+}
+/** @method flags=dynamic */
+public static final native int /*long*/ _g_file_query_info  (int /*long*/ file, byte[] attributes, int /*long*/ flags, int /*long*/ cancellable, int /*long*/ error);
+public static final int /*long*/ g_file_query_info  (int /*long*/ file,byte[] attributes, int /*long*/ flags, int /*long*/ cancellable, int /*long*/ error) {
+	lock.lock();
+	try {
+		return _g_file_query_info (file, attributes, flags, cancellable, error);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/** @method flags=dynamic */
+public static final native int /*long*/ _g_file_read(int /*long*/ file, int /*long*/ cancellable, int /*long*/ error);
+public static final int /*long*/ g_file_read(int /*long*/ file, int /*long*/ cancellable, int /*long*/ error) {
+	lock.lock();
+	try {
+		return _g_file_read(file, cancellable, error);
+	} finally {
+		lock.unlock();
+	}
+}
+/** @method flags=dynamic */
+public static final native boolean /*long*/ _g_file_test(byte[] file, int test);
+public static final boolean /*long*/ g_file_test(byte[] file, int test) {
+	lock.lock();
+	try {
+		return _g_file_test(file, test);
+	} finally {
+		lock.unlock();
+	}
+}
+/** @method flags=dynamic */
+public static final native int /*long*/ _g_icon_to_string(int /*long*/ icon);
+public static final int /*long*/ g_icon_to_string (int /*long*/ icon) {
+	lock.lock();
+	try {
+		return _g_icon_to_string(icon);
+	} finally {
+		lock.unlock();
+	}
+}
+/** @method flags=dynamic */
+public static final native int /*long*/ _g_icon_new_for_string(byte[] str, int /*long*/ error[]);
+public static final int /*long*/ g_icon_new_for_string (byte[] str, int /*long*/ error[]) {
+	lock.lock();
+	try {
+		return _g_icon_new_for_string(str, error);
+	} finally {
+		lock.unlock();
+	}
+}
 /**
  * @param signal_id cast=(guint)
  * @param detail cast=(GQuark)
@@ -2323,6 +2692,20 @@ public static final void g_object_set(int /*long*/ object, byte[] first_property
 }
 /**
  * @param object cast=(gpointer)
+ * @param first_property_name cast=(const gchar *),flags=no_out
+ * @param terminator cast=(const gchar *),flags=sentinel
+ */
+public static final native void _g_object_set(int /*long*/ object, byte[] first_property_name, byte[] data, int /*long*/ terminator);
+public static final void g_object_set(int /*long*/ object, byte[] first_property_name, byte[] data, int /*long*/ terminator) {
+	lock.lock();
+	try {
+		_g_object_set(object, first_property_name, data, terminator);
+	} finally {
+		lock.unlock();
+	}
+}
+/**
+ * @param object cast=(gpointer)
  * @param first_property_name cast=(const gchar *)
  * @param terminator cast=(const gchar *),flags=sentinel
  */
@@ -2512,6 +2895,19 @@ public static final void g_signal_emit_by_name(int /*long*/ instance, byte[] det
  * @param instance cast=(gpointer)
  * @param detailed_signal cast=(const gchar *),flags=no_out
  */
+public static final native void _g_signal_emit_by_name(int /*long*/ instance, byte[] detailed_signal, GdkRectangle data);
+public static final void g_signal_emit_by_name(int /*long*/ instance, byte[] detailed_signal, GdkRectangle data) {
+	lock.lock();
+	try {
+		_g_signal_emit_by_name(instance, detailed_signal, data);
+	} finally {
+		lock.unlock();
+	}
+}
+/**
+ * @param instance cast=(gpointer)
+ * @param detailed_signal cast=(const gchar *),flags=no_out
+ */
 public static final native void _g_signal_emit_by_name(int /*long*/ instance, byte[] detailed_signal, int /*long*/ data1, int /*long*/ data2);
 public static final void g_signal_emit_by_name(int /*long*/ instance, byte[] detailed_signal, int /*long*/ data1, int /*long*/ data2) {
 	lock.lock();
@@ -2549,6 +2945,22 @@ public static final void g_signal_handler_disconnect(int /*long*/ instance, int
 }
 /**
  * @param instance cast=(gpointer)
+ * @param detail cast=(GQuark)
+ * @param closure cast=(GClosure *)
+ * @param func cast=(gpointer)
+ * @param data cast=(gpointer)
+ */
+public static final native int _g_signal_handler_find(int /*long*/ instance, int mask, int signal_id, int detail, int /*long*/ closure, int /*long*/ func, int /*long*/ data);
+public static final int g_signal_handler_find(int /*long*/ instance, int mask, int signal_id, int detail, int /*long*/ closure, int /*long*/ func, int /*long*/ data) {
+	lock.lock();
+	try {
+		return _g_signal_handler_find(instance, mask, signal_id, detail, closure, func, data);
+	} finally {
+		lock.unlock();
+	}
+}
+/**
+ * @param instance cast=(gpointer)
  * @param mask cast=(GSignalMatchType)
  * @param signal_id cast=(guint)
  * @param detail cast=(GQuark)
@@ -2685,6 +3097,32 @@ public static final void g_strfreev(int /*long*/ string_array) {
 	}
 }
 /**
+ * @method flags=getter
+ * @param string cast=(GString *)
+ */
+public static final native int _GString_len(int /*long*/ string);
+public static final int GString_len(int /*long*/ string) {
+	lock.lock();
+	try { 
+		return _GString_len(string);
+	} finally {
+		lock.unlock();
+	}
+}
+/**
+ * @method flags=getter
+ * @param string cast=(GString *)
+ */
+public static final native int /*long*/ _GString_str(int /*long*/ string);
+public static final int /*long*/ GString_str(int /*long*/ string) {
+	lock.lock();
+	try { 
+		return _GString_str(string);
+	} finally {
+		lock.unlock();
+	}
+}
+/**
  * @param str cast=(const gchar *)
  * @param endptr cast=(gchar **)
  */
@@ -2932,6 +3370,29 @@ public static final int /*long*/ g_utf8_to_utf16(int /*long*/ str, int /*long*/
 		lock.unlock();
 	}
 }
+/**
+ * @param value cast=(GValue *)
+ * @param type cast=(GType)
+ */
+public static final native int /*long*/ g_value_init (int /*long*/ value, int /*long*/ type);
+/** @param value cast=(GValue *) */
+public static final native int g_value_get_int (int /*long*/ value);
+/** @param value cast=(GValue *) */
+public static final native void g_value_set_int (int /*long*/ value, int v);
+/** @param value cast=(GValue *) */
+public static final native double g_value_get_double (int /*long*/ value);
+/** @param value cast=(GValue *) */
+public static final native void g_value_set_double (int /*long*/ value, double v);
+/** @param value cast=(GValue *) */
+public static final native float g_value_get_float (int /*long*/ value);
+/** @param value cast=(GValue *) */
+public static final native void g_value_set_float (int /*long*/ value, float v);
+/** @param value cast=(GValue *) */
+public static final native long g_value_get_int64 (int /*long*/ value);
+/** @param value cast=(GValue *) */
+public static final native void g_value_set_int64 (int /*long*/ value, long v);
+/** @param value cast=(GValue *) */
+public static final native void g_value_unset (int /*long*/ value);
 /** @param value cast=(const GValue *) */
 public static final native int /*long*/ _g_value_peek_pointer (int /*long*/ value);
 public static final  int /*long*/ g_value_peek_pointer (int /*long*/ value) {
@@ -3861,6 +4322,15 @@ public static final int gdk_keyval_to_unicode(int keyval) {
 		lock.unlock();
 	}
 }
+public static final native int /*long*/ _gdk_pango_attr_embossed_new(boolean embossed);
+public static final int /*long*/ gdk_pango_attr_embossed_new(boolean embossed) {
+	lock.lock();
+	try {
+		return _gdk_pango_attr_embossed_new(embossed);
+	} finally {
+		lock.unlock();
+	}
+}
 public static final native int /*long*/ _gdk_pango_context_get();
 public static final int /*long*/ gdk_pango_context_get() {
 	lock.lock();
@@ -4822,6 +5292,16 @@ public static final void gdk_window_move(int /*long*/ window, int x, int y) {
 		lock.unlock();
 	}
 }
+/** @param window cast=(GdkWindow *) */
+public static final native void _gdk_window_move_resize(int /*long*/ window, int x, int y, int width, int height);
+public static final void gdk_window_move_resize(int /*long*/ window, int x, int y, int width, int height) {
+	lock.lock();
+	try {
+		_gdk_window_move_resize(window, x, y, width, height);
+	} finally {
+		lock.unlock();
+	}
+}
 /**
  * @param parent cast=(GdkWindow *)
  * @param attributes flags=no_out
@@ -4887,6 +5367,21 @@ public static final void gdk_window_resize(int /*long*/ window, int width, int h
 		lock.unlock();
 	}
 }
+/** 
+ * @method flags=dynamic
+ * @param window cast=(GdkWindow *)
+ * @param sibling cast=(GdkWindow *)
+ * @param above cast=(gboolean)
+ */
+public static final native void _gdk_window_restack(int /*long*/ window, int /*long*/ sibling, boolean above);
+public static final void gdk_window_restack(int /*long*/ window, int /*long*/ sibling, boolean above) {
+	lock.lock();
+	try {
+		_gdk_window_restack(window, sibling, above);
+	} finally {
+		lock.unlock();
+	}
+}
 /** @param window cast=(GdkWindow *) */
 public static final native void _gdk_window_scroll(int /*long*/ window, int dx, int dy);
 public static final void gdk_window_scroll(int /*long*/ window, int dx, int dy) {
@@ -5527,6 +6022,23 @@ public static final boolean gtk_clipboard_set_with_data(int /*long*/ clipboard,
 }
 /**
  * @param clipboard cast=(GtkClipboard *)
+ * @param target cast=(const GtkTargetEntry *)
+ * @param n_targets cast=(guint)
+ * @param get_func cast=(GtkClipboardGetFunc)
+ * @param clear_func cast=(GtkClipboardClearFunc)
+ * @param user_data cast=(GObject *)
+ */
+public static final native boolean _gtk_clipboard_set_with_owner(int /*long*/ clipboard, int /*long*/ target, int n_targets, int /*long*/ get_func, int /*long*/ clear_func, int /*long*/ user_data);
+public static final boolean gtk_clipboard_set_with_owner(int /*long*/ clipboard, int /*long*/ target, int n_targets, int /*long*/ get_func, int /*long*/ clear_func, int /*long*/ user_data) {
+	lock.lock();
+	try {
+		return _gtk_clipboard_set_with_owner(clipboard, target, n_targets, get_func, clear_func, user_data);
+	} finally {
+		lock.unlock();
+	}
+}
+/**
+ * @param clipboard cast=(GtkClipboard *)
  * @param target cast=(GdkAtom)
  */
 public static final native int /*long*/ _gtk_clipboard_wait_for_contents(int /*long*/ clipboard, int /*long*/ target);
@@ -6256,6 +6768,26 @@ public static final void gtk_entry_set_has_frame(int /*long*/ entry, boolean set
 		lock.unlock();
 	}
 }
+/** @method flags=dynamic */
+public static final native void _gtk_entry_set_icon_from_stock(int /*long*/ entry, int icon, byte[] stock);
+public static final void gtk_entry_set_icon_from_stock(int /*long*/ entry, int icon, byte[] stock) {
+	lock.lock();
+	try {
+		_gtk_entry_set_icon_from_stock(entry, icon, stock);
+	} finally {
+		lock.unlock();
+	}
+}
+/** @method flags=dynamic */
+public static final native void _gtk_entry_set_icon_sensitive(int /*long*/ entry, int icon_pos, boolean sensitive);
+public static final void gtk_entry_set_icon_sensitive(int /*long*/ entry, int icon_pos, boolean sensitive) {
+	lock.lock();
+	try {
+		_gtk_entry_set_icon_sensitive(entry, icon_pos, sensitive);
+	} finally {
+		lock.unlock();
+	}
+}
 /**
  * @param entry cast=(GtkEntry *)
  * @param ch cast=(gint)
@@ -6916,6 +7448,18 @@ public static final int /*long*/ gtk_hseparator_new() {
 		lock.unlock();
 	}
 }
+/**
+ * @method flags=dynamic
+ */
+public static final native void _gtk_icon_info_free(int /*long*/ icon_info);
+public static final void gtk_icon_info_free(int /*long*/ icon_info) {
+	lock.lock();
+	try {
+		_gtk_icon_info_free(icon_info);
+	} finally {
+		lock.unlock();
+	}
+}
 /** @param stock_id cast=(const gchar *) */
 public static final native int /*long*/ _gtk_icon_factory_lookup_default(byte[] stock_id);
 public static final int /*long*/ gtk_icon_factory_lookup_default(byte[] stock_id) {
@@ -6977,6 +7521,42 @@ public static final int /*long*/ gtk_icon_set_render_icon(int /*long*/ icon_set,
 	}
 }
 /**
+ * @method flags=dynamic
+ */
+public static final native int /*long*/ _gtk_icon_theme_get_default();
+public static final int /*long*/ gtk_icon_theme_get_default() {
+	lock.lock();
+	try {
+		return _gtk_icon_theme_get_default ();
+	} finally {
+		lock.unlock();
+	}
+}
+/**
+ * @method flags=dynamic
+ */
+public static final native int /*long*/ _gtk_icon_theme_lookup_by_gicon(int /*long*/ icon_theme, int /*long*/ icon, int size, int flags);
+public static final int /*long*/ gtk_icon_theme_lookup_by_gicon(int /*long*/ icon_theme, int /*long*/ icon, int size, int flags) {
+	lock.lock();
+	try {
+		return _gtk_icon_theme_lookup_by_gicon (icon_theme, icon, size, flags);
+	} finally {
+		lock.unlock();
+	}
+}
+/**
+ * @method flags=dynamic
+ */
+public static final native int /*long*/ _gtk_icon_info_load_icon(int /*long*/ icon_info, int /*long*/ error[]);
+public static final int /*long*/ gtk_icon_info_load_icon(int /*long*/ icon_info, int /*long*/ error[]) {
+	lock.lock();
+	try {
+		return _gtk_icon_info_load_icon(icon_info, error);
+	} finally {
+		lock.unlock();
+	}
+}
+/**
  * @param context cast=(GtkIMContext *)
  * @param event cast=(GdkEventKey *)
  */
@@ -9353,6 +9933,19 @@ public static final int /*long*/ gtk_spin_button_new(int /*long*/ adjustment, do
 		lock.unlock();
 	}
 }
+/** 
+ * @param spin_button cast=(GtkSpinButton*)
+ * @param adjustment cast=(GtkAdjustment *) 
+ **/
+public static final native void _gtk_spin_button_configure(int /*long*/ spin_button, int /*long*/ adjustment, double climb_rate, int digits);
+public static final void gtk_spin_button_configure(int /*long*/ spin_button, int /*long*/ adjustment, double climb_rate, int digits) {
+	lock.lock();
+	try {
+		_gtk_spin_button_configure(spin_button, adjustment, climb_rate, digits);
+	} finally {
+		lock.unlock();
+	}
+}
 /** @param spin_button cast=(GtkSpinButton*) */
 public static final native int /*long*/ _gtk_spin_button_get_adjustment(int /*long*/ spin_button);
 public static final int /*long*/ gtk_spin_button_get_adjustment(int /*long*/ spin_button) {
@@ -12028,6 +12621,16 @@ public static final int /*long*/ gtk_widget_get_parent(int /*long*/ widget) {
 	}
 }
 /** @param widget cast=(GtkWidget *) */
+public static final native int /*long*/ _gtk_widget_get_parent_window(int /*long*/ widget);
+public static final int /*long*/ gtk_widget_get_parent_window(int /*long*/ widget) {
+	lock.lock();
+	try {
+		return _gtk_widget_get_parent_window(widget);
+	} finally {
+		lock.unlock();
+	}
+}
+/** @param widget cast=(GtkWidget *) */
 public static final native int /*long*/ _gtk_widget_get_style(int /*long*/ widget);
 public static final int /*long*/ gtk_widget_get_style(int /*long*/ widget) {
 	lock.lock();
@@ -12670,6 +13273,16 @@ public static final int /*long*/ gtk_window_group_new() {
 	}
 }
 /** @param handle cast=(GtkWindow *) */
+public static final native boolean _gtk_window_is_active(int /*long*/ handle);
+public static final boolean gtk_window_is_active(int /*long*/ handle) {
+	lock.lock();
+	try {
+		return _gtk_window_is_active(handle);
+	} finally {
+		lock.unlock();
+	}
+}
+/** @param handle cast=(GtkWindow *) */
 public static final native void _gtk_window_iconify(int /*long*/ handle);
 public static final void gtk_window_iconify(int /*long*/ handle) {
 	lock.lock();
@@ -13050,6 +13663,11 @@ public static final native void memmove(GtkFileSelection dest, int /*long*/ src)
 /**
  * @param dest cast=(void *),flags=no_in
  * @param src cast=(const void *)
+ */
+public static final native void memmove(GdkEventProperty dest, int /*long*/ src);
+/**
+ * @param dest cast=(void *),flags=no_in
+ * @param src cast=(const void *)
  * @param size cast=(size_t)
  */
 public static final native void memmove(GdkDragContext dest, int /*long*/ src, int /*long*/ size);
@@ -13649,6 +14267,26 @@ public static final int pango_font_description_get_size(int /*long*/ desc) {
 	}
 }
 /** @param desc cast=(PangoFontDescription *) */
+public static final native int _pango_font_description_get_stretch(int /*long*/ desc);
+public static final int pango_font_description_get_stretch(int /*long*/ desc) {
+	lock.lock();
+	try {
+		return _pango_font_description_get_stretch(desc);
+	} finally {
+		lock.unlock();
+	}
+}
+/** @param desc cast=(PangoFontDescription *) */
+public static final native int _pango_font_description_get_variant(int /*long*/ desc);
+public static final int pango_font_description_get_variant(int /*long*/ desc) {
+	lock.lock();
+	try {
+		return _pango_font_description_get_variant(desc);
+	} finally {
+		lock.unlock();
+	}
+}
+/** @param desc cast=(PangoFontDescription *) */
 public static final native int _pango_font_description_get_style(int /*long*/ desc);
 public static final int pango_font_description_get_style(int /*long*/ desc) {
 	lock.lock();
@@ -14389,4 +15027,31 @@ public static final boolean atk_object_add_relationship (int /*long*/ object, in
 		lock.unlock();
 	}
 }
+/**
+ * @method flags=dynamic
+ * @param object cast=(AtkObject *)
+ * @param relationship cast=(AtkRelationType)
+ * @param target cast=(AtkObject *)
+ */
+public static final native boolean _atk_object_remove_relationship (int /*long*/ object, int relationship, int /*long*/ target);
+public static final boolean atk_object_remove_relationship (int /*long*/ object, int relationship, int /*long*/ target) {
+	lock.lock();
+	try {
+		return _atk_object_remove_relationship(object, relationship, target);
+	} finally {
+		lock.unlock();
+	}
+}
+/**
+ * @param path cast=(const char*)
+ */
+public static final native int _access (byte [] path, int amode);
+public static final int access (byte [] path, int amode) {
+	lock.lock();
+	try {
+		return _access(path, amode);
+	} finally {
+		lock.unlock();
+	}
+}
 }
diff --git a/org/eclipse/swt/internal/gtk/XButtonEvent.java b/org/eclipse/swt/internal/gtk/XButtonEvent.java
deleted file mode 100644
index 97edb2d..0000000
--- a/org/eclipse/swt/internal/gtk/XButtonEvent.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*******************************************************************************
- * 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
- *******************************************************************************/
-package org.eclipse.swt.internal.gtk;
-
- 
-public class XButtonEvent extends XAnyEvent {
-	public int root;
-	public int subwindow;
-	public int time;
-	public int x;
-	public int y;
-	public int x_root;
-	public int y_root;
-	public int state;
-	public int button;
-	public int same_screen;
-	public static final int sizeof = OS.XButtonEvent_sizeof();
-}
diff --git a/org/eclipse/swt/internal/image/PNGFileFormat.java b/org/eclipse/swt/internal/image/PNGFileFormat.java
index cf563d4..3d01237 100644
--- a/org/eclipse/swt/internal/image/PNGFileFormat.java
+++ b/org/eclipse/swt/internal/image/PNGFileFormat.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 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
@@ -252,9 +252,6 @@ void setPixelData(byte[] data, ImageData imageData) {
 			imageData.alphaData = alphaData;
 			break;
 		}		
-		case PngIhdrChunk.COLOR_TYPE_RGB:
-			imageData.data = data;
-			break;
 		case PngIhdrChunk.COLOR_TYPE_PALETTE:
 			imageData.data = data;
 			if (alphaPalette != null) {
@@ -268,8 +265,23 @@ void setPixelData(byte[] data, ImageData imageData) {
 				imageData.alphaData = alphaData;
 			}
 			break;
+		case PngIhdrChunk.COLOR_TYPE_RGB:
 		default:
-			imageData.data = data;
+			int height = imageData.height;
+			int destBytesPerLine = imageData.bytesPerLine;
+			int srcBytesPerLine = getAlignedBytesPerRow();
+			/*
+			* If the image uses 16-bit depth, it is converted
+			* to an 8-bit depth image.
+			*/
+			if (headerChunk.getBitDepth() > 8) srcBytesPerLine /= 2;
+			if (destBytesPerLine != srcBytesPerLine) {
+				for (int y = 0; y < height; y++) {
+					System.arraycopy(data, y * srcBytesPerLine, imageData.data, y * destBytesPerLine, srcBytesPerLine);
+				}
+			} else {
+				imageData.data = data;
+			}
 			break;
 	}
 }
diff --git a/org/eclipse/swt/internal/image/PngEncoder.java b/org/eclipse/swt/internal/image/PngEncoder.java
index 26fe574..28299db 100644
--- a/org/eclipse/swt/internal/image/PngEncoder.java
+++ b/org/eclipse/swt/internal/image/PngEncoder.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * Copyright (c) 2000, 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
@@ -246,11 +246,7 @@ void writeImageData() throws IOException {
 			
 			data.getPixels(0, y, width, lineData, 0);
 			
-			for (int x = 0; x < lineData.length; x++) {
-			
-				os.write(lineData[x]);
-			
-			}
+			os.write(lineData);
 		
 		}
 	
@@ -271,6 +267,8 @@ void writeImageData() throws IOException {
 		int blueShift = data.palette.blueShift;
 		int blueMask = data.palette.blueMask;
 		
+		byte[] lineBytes = new byte[width * (colorType == 6 ? 4 : 3)];
+		
 		for (int y = 0; y < height; y++) {
 		
 			int filter = 0;
@@ -282,27 +280,29 @@ void writeImageData() throws IOException {
 				data.getAlphas(0, y, width, alphaData, 0);
 			}
 			
+			int offset = 0;
 			for (int x = 0; x < lineData.length; x++) {
 			
 				int pixel = lineData[x];
 				
 				int r = pixel & redMask;
-				r = (redShift < 0) ? r >>> -redShift : r << redShift;
+				lineBytes[offset++] = (byte) ((redShift < 0) ? r >>> -redShift
+						: r << redShift);
 				int g = pixel & greenMask;
-				g = (greenShift < 0) ? g >>> -greenShift : g << greenShift;
+				lineBytes[offset++] = (byte) ((greenShift < 0) ? g >>> -greenShift
+						: g << greenShift);
 				int b = pixel & blueMask;
-				b = (blueShift < 0) ? b >>> -blueShift : b << blueShift;
-				
-				os.write(r);
-				os.write(g);
-				os.write(b);
+				lineBytes[offset++] = (byte) ((blueShift < 0) ? b >>> -blueShift
+						: b << blueShift);
 				
 				if (colorType == 6) {
-					os.write(alphaData[x]);
+					lineBytes[offset++] = alphaData[x];
 				}
 			
 			}
-		
+			
+			os.write(lineBytes);
+			
 		}
 	
 	}
diff --git a/org/eclipse/swt/internal/image/PngLzBlockReader.java b/org/eclipse/swt/internal/image/PngLzBlockReader.java
index e4b8d71..a2d9c1f 100644
--- a/org/eclipse/swt/internal/image/PngLzBlockReader.java
+++ b/org/eclipse/swt/internal/image/PngLzBlockReader.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * Copyright (c) 2000, 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
@@ -66,7 +66,7 @@ void setWindowSize(int windowSize) {
 
 void readNextBlockHeader() throws IOException {
 	isLastBlock = stream.getNextIdatBit() != 0;
-	compressionType = (byte)(stream.getNextIdatBits(2) & 0xFF);
+	compressionType = (byte) stream.getNextIdatBits(2);
 	if (compressionType > 2) stream.error();	
 	
 	if (compressionType == UNCOMPRESSED) {
@@ -92,14 +92,7 @@ byte getNextByte() throws IOException {
 		uncompressedBytesRemaining--;
 		return stream.getNextIdatByte();
 	} else {
-		byte value = getNextCompressedByte();
-		if (value == END_OF_COMPRESSED_BLOCK) {
-			if (isLastBlock) stream.error();
-			readNextBlockHeader();
-			return getNextByte();
-		} else {
-			return value;
-		}
+		return getNextCompressedByte();
 	}
 }
 
@@ -136,10 +129,10 @@ private byte getNextCompressedByte() throws IOException {
 	
 	int value = huffmanTables.getNextLiteralValue(stream);
 	if (value < END_OF_COMPRESSED_BLOCK) {
-		window[windowIndex] = (byte) (value & 0xFF);
+		window[windowIndex] = (byte) value;
 		windowIndex++;
 		if (windowIndex >= window.length) windowIndex = 0;
-		return (byte) (value & 0xFF);		
+		return (byte) value;		
 	} else if (value == END_OF_COMPRESSED_BLOCK) {
 		readNextBlockHeader();
 		return getNextByte();
diff --git a/org/eclipse/swt/internal/image/TIFFDirectory.java b/org/eclipse/swt/internal/image/TIFFDirectory.java
index da5f84c..dbcce8a 100644
--- a/org/eclipse/swt/internal/image/TIFFDirectory.java
+++ b/org/eclipse/swt/internal/image/TIFFDirectory.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * Copyright (c) 2000, 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
@@ -23,6 +23,7 @@ final class TIFFDirectory {
 	int depth;
 	
 	/* Directory fields */
+	int subfileType;
 	int imageWidth;
 	int imageLength;
 	int[] bitsPerSample;
@@ -41,19 +42,27 @@ final class TIFFDirectory {
 	
 	static final int NO_VALUE = -1;
 	
+	static final short TAG_NewSubfileType = 254;
+	static final short TAG_SubfileType = 255;
 	static final short TAG_ImageWidth = 256;
 	static final short TAG_ImageLength = 257;
 	static final short TAG_BitsPerSample = 258;
 	static final short TAG_Compression = 259;
 	static final short TAG_PhotometricInterpretation = 262;
+	static final short TAG_FillOrder = 266;
+	static final short TAG_ImageDescription = 270;
 	static final short TAG_StripOffsets = 273;
+	static final short TAG_Orientation = 274;
 	static final short TAG_SamplesPerPixel = 277;
 	static final short TAG_RowsPerStrip = 278;
 	static final short TAG_StripByteCounts = 279;
 	static final short TAG_XResolution = 282;
 	static final short TAG_YResolution = 283;
+	static final short TAG_PlanarConfiguration = 284;
 	static final short TAG_T4Options = 292;
 	static final short TAG_ResolutionUnit = 296;
+	static final short TAG_Software = 305;
+	static final short TAG_DateTime = 306;
 	static final short TAG_ColorMap = 320;
 	
 	static final int TYPE_BYTE = 1;
@@ -62,6 +71,13 @@ final class TIFFDirectory {
 	static final int TYPE_LONG = 4;
 	static final int TYPE_RATIONAL = 5;
 	
+	static final int FILETYPE_REDUCEDIMAGE = 1;
+	static final int FILETYPE_PAGE = 2;
+	static final int FILETYPE_MASK = 4;
+	static final int OFILETYPE_IMAGE = 1;
+	static final int OFILETYPE_REDUCEDIMAGE = 2;
+	static final int OFILETYPE_PAGE = 3;
+	
 	/* Different compression schemes */
 	static final int COMPRESSION_NONE = 1;
 	static final int COMPRESSION_CCITT_3_1 = 2;
@@ -85,12 +101,12 @@ int decodePackBits(byte[] src, byte[] dest, int offsetDest) {
 	int srcIndex = 0;
 	while (srcIndex < src.length) {
 		byte n = src[srcIndex];
-		if (0 <= n && n <= 127) {
+		if (n >= 0) {
 			/* Copy next n+1 bytes literally */
 			System.arraycopy(src, ++srcIndex, dest, destIndex, n + 1);
 			srcIndex += n + 1;		
 			destIndex += n + 1;	
-		} else if (-127 <= n && n <= -1) {
+		} else if (n >= -127) {
 			/* Copy next byte -n+1 times */
 			byte value = src[++srcIndex];
 			for (int j = 0; j < -n + 1; j++) {
@@ -299,6 +315,15 @@ void parseEntries(byte[] buffer) throws IOException {
 		int type = toInt(buffer, offset + 2, TYPE_SHORT);
 		int count = toInt(buffer, offset + 4, TYPE_LONG);
 		switch (tag) {
+			case TAG_NewSubfileType: {
+				subfileType = getEntryValue(type, buffer, offset);
+				break;
+			}
+			case TAG_SubfileType: {
+				int oldSubfileType = getEntryValue(type, buffer, offset);
+				subfileType = oldSubfileType == OFILETYPE_REDUCEDIMAGE ? FILETYPE_REDUCEDIMAGE : oldSubfileType == OFILETYPE_PAGE ? FILETYPE_PAGE : 0;
+				break;
+			}
 			case TAG_ImageWidth: {
 				imageWidth = getEntryValue(type, buffer, offset);
 				break;
@@ -317,6 +342,14 @@ void parseEntries(byte[] buffer) throws IOException {
 				compression = getEntryValue(type, buffer, offset);
 				break;
 			}
+			case TAG_FillOrder: {
+				/* Ignored: baseline only requires default fill order. */
+				break;
+			}
+			case TAG_ImageDescription: {
+				/* Ignored */
+				break;
+			}
 			case TAG_PhotometricInterpretation: {
 				photometricInterpretation = getEntryValue(type, buffer, offset);
 				break;
@@ -327,6 +360,10 @@ void parseEntries(byte[] buffer) throws IOException {
 				getEntryValue(type, buffer, offset, stripOffsets);
 				break;
 			}
+			case TAG_Orientation: {
+				/* Ignored: baseline only requires top left orientation. */
+				break;
+			}
 			case TAG_SamplesPerPixel: {
 				if (type != TYPE_SHORT) SWT.error(SWT.ERROR_INVALID_IMAGE);
 				samplesPerPixel = getEntryValue(type, buffer, offset);
@@ -351,6 +388,10 @@ void parseEntries(byte[] buffer) throws IOException {
 				/* Ignored */
 				break;
 			}
+			case TAG_PlanarConfiguration: {
+				/* Ignored: baseline only requires default planar configuration. */
+				break;
+			}
 			case TAG_T4Options: {
 				if (type != TYPE_LONG) SWT.error(SWT.ERROR_INVALID_IMAGE);
 				t4Options = getEntryValue(type, buffer, offset);
@@ -364,6 +405,14 @@ void parseEntries(byte[] buffer) throws IOException {
 				/* Ignored */
 				break;
 			}
+			case TAG_Software: {
+				/* Ignored */
+				break;
+			}
+			case TAG_DateTime: {
+				/* Ignored */
+				break;
+			}
 			case TAG_ColorMap: {
 				if (type != TYPE_SHORT) SWT.error(SWT.ERROR_INVALID_IMAGE);
 				/* Get the offset of the colorMap (use TYPE_LONG) */
@@ -374,7 +423,7 @@ void parseEntries(byte[] buffer) throws IOException {
 	}
 }
 
-public ImageData read() throws IOException {
+public ImageData read(int [] nextIFDOffset) throws IOException {
 	/* Set TIFF default values */
 	bitsPerSample = new int[] {1};
 	colorMapOffset = NO_VALUE;
@@ -392,6 +441,9 @@ public ImageData read() throws IOException {
 	int numberEntries = toInt(buffer, 0, TYPE_SHORT);
 	buffer = new byte[IFD_ENTRY_SIZE * numberEntries];
 	file.read(buffer);
+	byte buffer2[] = new byte[4];
+	file.read(buffer2);
+	nextIFDOffset[0] = toInt(buffer2, 0, TYPE_LONG);
 	parseEntries(buffer);
 	
 	PaletteData palette = null;
diff --git a/org/eclipse/swt/internal/image/TIFFFileFormat.java b/org/eclipse/swt/internal/image/TIFFFileFormat.java
index b419a57..2e0298b 100644
--- a/org/eclipse/swt/internal/image/TIFFFileFormat.java
+++ b/org/eclipse/swt/internal/image/TIFFFileFormat.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 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
@@ -53,11 +53,17 @@ ImageData[] loadFromByteStream() {
 		int offset = isLittleEndian ? 
 			(header[4] & 0xFF) | ((header[5] & 0xFF) << 8) | ((header[6] & 0xFF) << 16) | ((header[7] & 0xFF) << 24) :
 			(header[7] & 0xFF) | ((header[6] & 0xFF) << 8) | ((header[5] & 0xFF) << 16) | ((header[4] & 0xFF) << 24);
-		file.seek(offset);
-		TIFFDirectory directory = new TIFFDirectory(file, isLittleEndian, loader);
-		ImageData image = directory.read();
-		/* A baseline reader is only expected to read the first directory */
-		images = new ImageData[] {image};
+		while (offset != 0) {
+			file.seek(offset);
+			TIFFDirectory directory = new TIFFDirectory(file, isLittleEndian, loader);
+			int [] nextIFDOffset = new int[1];
+			ImageData image = directory.read(nextIFDOffset);
+			offset = nextIFDOffset[0];
+			ImageData[] oldImages = images;
+			images = new ImageData[oldImages.length + 1];
+			System.arraycopy(oldImages, 0, images, 0, oldImages.length);
+			images[images.length - 1] = image;
+		}
 	} catch (IOException e) {
 		SWT.error(SWT.ERROR_IO, e);
 	}
diff --git a/org/eclipse/swt/internal/image/WinBMPFileFormat.java b/org/eclipse/swt/internal/image/WinBMPFileFormat.java
index 81d08aa..04af102 100644
--- a/org/eclipse/swt/internal/image/WinBMPFileFormat.java
+++ b/org/eclipse/swt/internal/image/WinBMPFileFormat.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -181,6 +181,92 @@ int compressRLE8Data(byte[] src, int srcOffset, int numBytes, byte[] dest, boole
 	
 	return size;
 }
+void convertPixelsToBGR(ImageData image, byte[] dest) {
+	/*
+	 * For direct palette, uncompressed image, BMP encoders expect the
+	 * pixels to be in BGR format for 24 & 32 bit and RGB 1555 for 16 bit
+	 * On Linux and MacOS, the pixels are in RGB format. Also, in
+	 * MacOS, the alpha byte may be first. 
+	 * Hence, we use the palette information of the image and convert 
+	 * the pixels to the required format. Converted pixels are stored
+	 * in dest byte array.
+	 */
+	byte[] data = image.data;
+	PaletteData palette = image.palette;
+	for (int y = 0; y < image.height; y++) {
+		int index;
+		int srcX = 0, srcY = y;
+		int numOfBytes = image.depth / 8;
+		index = (y * image.bytesPerLine);
+
+		for (int i = 0; i < image.width; i++) {
+			int pixel = 0;
+			switch (image.depth) {
+				case 32:
+					pixel = ((data[index] & 0xFF) << 24)
+							| ((data[index + 1] & 0xFF) << 16)
+							| ((data[index + 2] & 0xFF) << 8)
+							| (data[index + 3] & 0xFF);
+					break;
+				case 24:
+					pixel = ((data[index] & 0xFF) << 16)
+							| ((data[index + 1] & 0xFF) << 8)
+							| (data[index + 2] & 0xFF);
+					break;
+				case 16:
+					pixel = ((data[index + 1] & 0xFF) << 8)
+							| (data[index] & 0xFF);
+					break;
+				default:
+					SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH);
+			}
+
+			if (image.depth == 16) {
+				/* convert to RGB 555 format */
+				int r = pixel & palette.redMask;
+				r = ((palette.redShift < 0) ? r >>> -palette.redShift
+						: r << palette.redShift);
+
+				int g = pixel & palette.greenMask;
+				g = ((palette.greenShift < 0) ? g >>> -palette.greenShift
+						: g << palette.greenShift);
+				g = (g & 0xF8);	/* In 565 format, G is 6 bit, mask it to 5 bit */
+
+				int b = pixel & palette.blueMask;
+				b = ((palette.blueShift < 0) ? b >>> -palette.blueShift
+						: b << palette.blueShift);
+
+				int modPixel = (r << 7) | (g << 2) | (b >> 3);
+				dest[index] = (byte) (modPixel & 0xFF);
+				dest[index + 1] = (byte) ((modPixel >> 8) & 0xFF);
+			} else {
+				/* convert to BGR format */
+				int b = pixel & palette.blueMask;
+				dest[index] = (byte) ((palette.blueShift < 0) ? b >>> -palette.blueShift
+						: b << palette.blueShift);
+
+				int g = pixel & palette.greenMask;
+				dest[index + 1] = (byte) ((palette.greenShift < 0) ? g >>> -palette.greenShift
+						: g << palette.greenShift);
+
+				int r = pixel & palette.redMask;
+				dest[index + 2] = (byte) ((palette.redShift < 0) ? r >>> -palette.redShift
+						: r << palette.redShift);
+
+				if (numOfBytes == 4) dest[index + 3] = 0;
+			}
+
+			srcX++;
+			if (srcX >= image.width) {
+				srcY++;
+				index = srcY * image.bytesPerLine;
+				srcX = 0;
+			} else {
+				index += numOfBytes;
+			}
+		}
+	}
+}
 void decompressData(byte[] src, byte[] dest, int stride, int cmp) {
 	if (cmp == 1) { // BMP_RLE8_COMPRESSION
 		if (decompressRLE8Data(src, src.length, stride, dest, dest.length) <= 0)
@@ -331,6 +417,21 @@ boolean isFileFormat(LEDataInputStream stream) {
 		return false;
 	}
 }
+boolean isPaletteBMP(PaletteData pal, int depth) {
+	switch(depth) {
+		case 32:
+		    if ((pal.redMask == 0xFF00) && (pal.greenMask == 0xFF0000) && (pal.blueMask == 0xFF000000)) return true;
+		    return false;
+		case 24:
+			if ((pal.redMask == 0xFF) && (pal.greenMask == 0xFF00) && (pal.blueMask == 0xFF0000)) return true;
+			return false;
+		case 16:
+		    if ((pal.redMask == 0x7C00) && (pal.greenMask == 0x3E0) && (pal.blueMask == 0x1F)) return true;
+		    return false;
+		default:
+			return true;
+	}
+}
 byte[] loadData(byte[] infoHeader) {
 	int width = (infoHeader[4] & 0xFF) | ((infoHeader[5] & 0xFF) << 8) | ((infoHeader[6] & 0xFF) << 16) | ((infoHeader[7] & 0xFF) << 24);
 	int height = (infoHeader[8] & 0xFF) | ((infoHeader[9] & 0xFF) << 8) | ((infoHeader[10] & 0xFF) << 16) | ((infoHeader[11] & 0xFF) << 24);
@@ -501,19 +602,20 @@ static byte[] paletteToBytes(PaletteData pal) {
  * Unload the given image's data into the given byte stream
  * using the given compression strategy. 
  * Answer the number of bytes written.
+ * Method modified to use the passed data if it is not null.
  */
-int unloadData(ImageData image, OutputStream out, int comp) {
+int unloadData(ImageData image, byte[] data, OutputStream out, int comp) {
 	int totalSize = 0;
 	try {
 		if (comp == 0)
-			return unloadDataNoCompression(image, out);
+			return unloadDataNoCompression(image, data, out);
 		int bpl = (image.width * image.depth + 7) / 8;
 		int bmpBpl = (bpl + 3) / 4 * 4; // BMP pads scanlines to multiples of 4 bytes
 		int imageBpl = image.bytesPerLine;
 		// Compression can actually take twice as much space, in worst case
 		byte[] buf = new byte[bmpBpl * 2];
 		int srcOffset = imageBpl * (image.height - 1); // Start at last line
-		byte[] data = image.data;
+		if (data == null) data = image.data;
 		totalSize = 0;
 		byte[] buf2 = new byte[32768];
 		int buf2Offset = 0;
@@ -539,15 +641,16 @@ int unloadData(ImageData image, OutputStream out, int comp) {
  * Prepare the given image's data for unloading into a byte stream
  * using no compression strategy.
  * Answer the number of bytes written.
+ * Method modified to use the passed data if it is not null.
  */
-int unloadDataNoCompression(ImageData image, OutputStream out) {
+int unloadDataNoCompression(ImageData image, byte[] data, OutputStream out) {
 	int bmpBpl = 0;
 	try {
 		int bpl = (image.width * image.depth + 7) / 8;
 		bmpBpl = (bpl + 3) / 4 * 4; // BMP pads scanlines to multiples of 4 bytes
 		int linesPerBuf = 32678 / bmpBpl;
 		byte[] buf = new byte[linesPerBuf * bmpBpl];
-		byte[] data = image.data;
+		if (data == null) data = image.data;
 		int imageBpl = image.bytesPerLine;
 		int dataIndex = imageBpl * (image.height - 1); // Start at last line
 		if (image.depth == 16) {
@@ -622,10 +725,18 @@ void unloadIntoByteStream(ImageLoader loader) {
 		fileHeader[4] += rgbs.length;
 	}
 
+	byte iData[] = null;
+	// If the pixels are not in the expected BMP format, convert them.
+	if (pal.isDirect && !isPaletteBMP(pal, image.depth)) {
+		// array to store the converted pixels
+	    iData = new byte[image.data.length];
+		convertPixelsToBGR(image, iData);
+	}
+	
 	// Prepare data. This is done first so we don't have to try to rewind
 	// the stream and fill in the details later.
 	ByteArrayOutputStream out = new ByteArrayOutputStream();
-	unloadData(image, out, comp);
+	unloadData(image, iData, out, comp);
 	byte[] data = out.toByteArray();
 	
 	// Calculate file size
diff --git a/org/eclipse/swt/internal/mozilla/XPCOM.java b/org/eclipse/swt/internal/mozilla/XPCOM.java
index f474386..79be3c2 100644
--- a/org/eclipse/swt/internal/mozilla/XPCOM.java
+++ b/org/eclipse/swt/internal/mozilla/XPCOM.java
@@ -44,9 +44,9 @@ public class XPCOM extends C {
 	public static final String DOMEVENT_MOUSEWHEEL = "DOMMouseScroll"; //$NON-NLS-1$
 	public static final String DOMEVENT_MOUSEOVER = "mouseover"; //$NON-NLS-1$
 	public static final String DOMEVENT_MOUSEOUT = "mouseout"; //$NON-NLS-1$
-	public static final String DOMEVENT_KEYUP = "keyup"; //$NON-NLS-1$
 	public static final String DOMEVENT_KEYDOWN = "keydown"; //$NON-NLS-1$
 	public static final String DOMEVENT_KEYPRESS = "keypress"; //$NON-NLS-1$
+	public static final String DOMEVENT_KEYUP = "keyup"; //$NON-NLS-1$
 	
 	/* CID constants */
 	public static final nsID EXTERNAL_CID = new nsID ("f2c59ad0-bd76-11dd-ad8b-0800200c9a66"); //$NON-NLS-1$
@@ -72,6 +72,7 @@ public class XPCOM extends C {
 	public static final String NS_FILEPICKER_CONTRACTID = "@mozilla.org/filepicker;1"; //$NON-NLS-1$
 	public static final String NS_HELPERAPPLAUNCHERDIALOG_CONTRACTID = "@mozilla.org/helperapplauncherdialog;1"; //$NON-NLS-1$
 	public static final String NS_MEMORY_CONTRACTID = "@mozilla.org/xpcom/memory-service;1"; //$NON-NLS-1$
+	public static final String NS_MIMEINPUTSTREAM_CONTRACTID = "@mozilla.org/network/mime-input-stream;1"; //$NON-NLS-1$
 	public static final String NS_SCRIPTSECURITYMANAGER_CONTRACTID = "@mozilla.org/scriptsecuritymanager;1"; //$NON-NLS-1$
 	public static final String NS_OBSERVER_CONTRACTID = "@mozilla.org/observer-service;1"; //$NON-NLS-1$
 	public static final String NS_PREFLOCALIZEDSTRING_CONTRACTID = "@mozilla.org/pref-localizedstring;1"; //$NON-NLS-1$
@@ -165,7 +166,16 @@ public static final int JS_EvaluateUCScriptForPrincipals(byte[] mozillaPath, int
 		lock.unlock();
 	}
 }
-
+/** @method flags=no_gen */
+public static final native boolean _NS_Free(byte[] mozillaPath, int /*long*/ aPtr);
+public static final boolean NS_Free(byte[] mozillaPath, int /*long*/ aPtr) {
+	lock.lock();
+	try {
+		return _NS_Free(mozillaPath, aPtr);
+	} finally {
+		lock.unlock();
+	}
+}
 /** @param result cast=(nsIComponentManager**) */
 public static final native int _NS_GetComponentManager(int /*long*/[] result);
 public static final int NS_GetComponentManager(int /*long*/[] result) {
@@ -2259,9 +2269,4 @@ static final int VtblCall(int fnNumber, int /*long*/ ppVtbl, long arg0, int arg1
 	}
 }
 
-/**
- * @method flags=no_gen
- */
-public static final native int GetAddress(int ptr, int index);
-
 }
diff --git a/org/eclipse/swt/internal/mozilla/nsICookieService.java b/org/eclipse/swt/internal/mozilla/nsICookieService.java
index f3faf9b..eebe8ab 100644
--- a/org/eclipse/swt/internal/mozilla/nsICookieService.java
+++ b/org/eclipse/swt/internal/mozilla/nsICookieService.java
@@ -1,64 +1,63 @@
-package org.eclipse.swt.internal.mozilla;
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by Netscape are Copyright (C) 1998-1999
- * Netscape Communications Corporation.  All Rights Reserved.
- *
- * Contributor(s):
- *
- * IBM
- * -  Binding to permit interfacing between Mozilla and SWT
- * -  Copyright (C) 2003, 2008 IBM Corp.  All Rights Reserved.
- *
- * ***** END LICENSE BLOCK ***** */
-
-
-public class nsICookieService extends nsISupports {
-
-	static final int LAST_METHOD_ID = nsISupports.LAST_METHOD_ID + 5;
-
-	public static final String NS_ICOOKIESERVICE_IID_STR =
-		"011c3190-1434-11d6-a618-0010a401eb10";
-
-	public static final nsID NS_ICOOKIESERVICE_IID =
-		new nsID(NS_ICOOKIESERVICE_IID_STR);
-
-	public nsICookieService(int /*long*/ address) {
-		super(address);
-	}
-
-	public int GetCookieString(int /*long*/ aURI, int /*long*/ aChannel, int /*long*/[] _retval) {
-		return XPCOM.VtblCall(nsISupports.LAST_METHOD_ID + 1, getAddress(), aURI, aChannel, _retval);
-	}
-
-	public int GetCookieStringFromHttp(int /*long*/ aURI, int /*long*/ aFirstURI, int /*long*/ aChannel, int /*long*/[] _retval) {
-		return XPCOM.VtblCall(nsISupports.LAST_METHOD_ID + 2, getAddress(), aURI, aFirstURI, aChannel, _retval);
-	}
-
-	public int SetCookieString(int /*long*/ aURI, int /*long*/ aPrompt, byte[] aCookie, int /*long*/ aChannel) {
-		return XPCOM.VtblCall(nsISupports.LAST_METHOD_ID + 3, getAddress(), aURI, aPrompt, aCookie, aChannel);
-	}
-
-	public int SetCookieStringFromHttp(int /*long*/ aURI, int /*long*/ aFirstURI, int /*long*/ aPrompt, byte[] aCookie, byte[] aServerTime, int /*long*/ aChannel) {
-		return XPCOM.VtblCall(nsISupports.LAST_METHOD_ID + 4, getAddress(), aURI, aFirstURI, aPrompt, aCookie, aServerTime, aChannel);
-	}
-
-	public int GetCookieIconIsVisible(int[] aCookieIconIsVisible) {
-		return XPCOM.VtblCall(nsISupports.LAST_METHOD_ID + 5, getAddress(), aCookieIconIsVisible);
-	}
-}
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by Netscape are Copyright (C) 1998-1999
+ * Netscape Communications Corporation.  All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * IBM
+ * -  Binding to permit interfacing between Mozilla and SWT
+ * -  Copyright (C) 2003, 2008 IBM Corp.  All Rights Reserved.
+ *
+ * ***** END LICENSE BLOCK ***** */
+package org.eclipse.swt.internal.mozilla;
+
+public class nsICookieService extends nsISupports {
+
+	static final int LAST_METHOD_ID = nsISupports.LAST_METHOD_ID + 5;
+
+	public static final String NS_ICOOKIESERVICE_IID_STR =
+		"011c3190-1434-11d6-a618-0010a401eb10";
+
+	public static final nsID NS_ICOOKIESERVICE_IID =
+		new nsID(NS_ICOOKIESERVICE_IID_STR);
+
+	public nsICookieService(int /*long*/ address) {
+		super(address);
+	}
+
+	public int GetCookieString(int /*long*/ aURI, int /*long*/ aChannel, int /*long*/[] _retval) {
+		return XPCOM.VtblCall(nsISupports.LAST_METHOD_ID + 1, getAddress(), aURI, aChannel, _retval);
+	}
+
+	public int GetCookieStringFromHttp(int /*long*/ aURI, int /*long*/ aFirstURI, int /*long*/ aChannel, int /*long*/[] _retval) {
+		return XPCOM.VtblCall(nsISupports.LAST_METHOD_ID + 2, getAddress(), aURI, aFirstURI, aChannel, _retval);
+	}
+
+	public int SetCookieString(int /*long*/ aURI, int /*long*/ aPrompt, byte[] aCookie, int /*long*/ aChannel) {
+		return XPCOM.VtblCall(nsISupports.LAST_METHOD_ID + 3, getAddress(), aURI, aPrompt, aCookie, aChannel);
+	}
+
+	public int SetCookieStringFromHttp(int /*long*/ aURI, int /*long*/ aFirstURI, int /*long*/ aPrompt, byte[] aCookie, byte[] aServerTime, int /*long*/ aChannel) {
+		return XPCOM.VtblCall(nsISupports.LAST_METHOD_ID + 4, getAddress(), aURI, aFirstURI, aPrompt, aCookie, aServerTime, aChannel);
+	}
+
+	public int GetCookieIconIsVisible(int[] aCookieIconIsVisible) {
+		return XPCOM.VtblCall(nsISupports.LAST_METHOD_ID + 5, getAddress(), aCookieIconIsVisible);
+	}
+}
diff --git a/org/eclipse/swt/internal/mozilla/nsICookieService_1_9.java b/org/eclipse/swt/internal/mozilla/nsICookieService_1_9.java
index 0824f34..429bba2 100644
--- a/org/eclipse/swt/internal/mozilla/nsICookieService_1_9.java
+++ b/org/eclipse/swt/internal/mozilla/nsICookieService_1_9.java
@@ -1,59 +1,59 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by Netscape are Copyright (C) 1998-1999
- * Netscape Communications Corporation.  All Rights Reserved.
- *
- * Contributor(s):
- *
- * IBM
- * -  Binding to permit interfacing between Mozilla and SWT
- * -  Copyright (C) 2003, 2008 IBM Corp.  All Rights Reserved.
- *
- * ***** END LICENSE BLOCK ***** */
-package org.eclipse.swt.internal.mozilla;
-
-public class  nsICookieService_1_9 extends nsISupports {
-
-	static final int LAST_METHOD_ID = nsISupports.LAST_METHOD_ID + 4;
-
-	public static final String NS_ICOOKIESERVICE_IID_STR =
-		"2aaa897a-293c-4d2b-a657-8c9b7136996d";
-
-	public static final nsID NS_ICOOKIESERVICE_IID =
-		new nsID(NS_ICOOKIESERVICE_IID_STR);
-
-	public  nsICookieService_1_9(int /*long*/ address) {
-		super(address);
-	}
-
-	public int GetCookieString(int /*long*/ aURI, int /*long*/ aChannel, int /*long*/[] _retval) {
-		return XPCOM.VtblCall(nsISupports.LAST_METHOD_ID + 1, getAddress(), aURI, aChannel, _retval);
-	}
-
-	public int GetCookieStringFromHttp(int /*long*/ aURI, int /*long*/ aFirstURI, int /*long*/ aChannel, int /*long*/[] _retval) {
-		return XPCOM.VtblCall(nsISupports.LAST_METHOD_ID + 2, getAddress(), aURI, aFirstURI, aChannel, _retval);
-	}
-
-	public int SetCookieString(int /*long*/ aURI, int /*long*/ aPrompt, byte[] aCookie, int /*long*/ aChannel) {
-		return XPCOM.VtblCall(nsISupports.LAST_METHOD_ID + 3, getAddress(), aURI, aPrompt, aCookie, aChannel);
-	}
-
-	public int SetCookieStringFromHttp(int /*long*/ aURI, int /*long*/ aFirstURI, int /*long*/ aPrompt, byte[] aCookie, byte[] aServerTime, int /*long*/ aChannel) {
-		return XPCOM.VtblCall(nsISupports.LAST_METHOD_ID + 4, getAddress(), aURI, aFirstURI, aPrompt, aCookie, aServerTime, aChannel);
-	}
-}
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by Netscape are Copyright (C) 1998-1999
+ * Netscape Communications Corporation.  All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * IBM
+ * -  Binding to permit interfacing between Mozilla and SWT
+ * -  Copyright (C) 2003, 2008 IBM Corp.  All Rights Reserved.
+ *
+ * ***** END LICENSE BLOCK ***** */
+package org.eclipse.swt.internal.mozilla;
+
+public class  nsICookieService_1_9 extends nsISupports {
+
+	static final int LAST_METHOD_ID = nsISupports.LAST_METHOD_ID + 4;
+
+	public static final String NS_ICOOKIESERVICE_IID_STR =
+		"2aaa897a-293c-4d2b-a657-8c9b7136996d";
+
+	public static final nsID NS_ICOOKIESERVICE_IID =
+		new nsID(NS_ICOOKIESERVICE_IID_STR);
+
+	public  nsICookieService_1_9(int /*long*/ address) {
+		super(address);
+	}
+
+	public int GetCookieString(int /*long*/ aURI, int /*long*/ aChannel, int /*long*/[] _retval) {
+		return XPCOM.VtblCall(nsISupports.LAST_METHOD_ID + 1, getAddress(), aURI, aChannel, _retval);
+	}
+
+	public int GetCookieStringFromHttp(int /*long*/ aURI, int /*long*/ aFirstURI, int /*long*/ aChannel, int /*long*/[] _retval) {
+		return XPCOM.VtblCall(nsISupports.LAST_METHOD_ID + 2, getAddress(), aURI, aFirstURI, aChannel, _retval);
+	}
+
+	public int SetCookieString(int /*long*/ aURI, int /*long*/ aPrompt, byte[] aCookie, int /*long*/ aChannel) {
+		return XPCOM.VtblCall(nsISupports.LAST_METHOD_ID + 3, getAddress(), aURI, aPrompt, aCookie, aChannel);
+	}
+
+	public int SetCookieStringFromHttp(int /*long*/ aURI, int /*long*/ aFirstURI, int /*long*/ aPrompt, byte[] aCookie, byte[] aServerTime, int /*long*/ aChannel) {
+		return XPCOM.VtblCall(nsISupports.LAST_METHOD_ID + 4, getAddress(), aURI, aFirstURI, aPrompt, aCookie, aServerTime, aChannel);
+	}
+}
diff --git a/org/eclipse/swt/internal/mozilla/nsID.java b/org/eclipse/swt/internal/mozilla/nsID.java
index a5fd6d8..716aab3 100644
--- a/org/eclipse/swt/internal/mozilla/nsID.java
+++ b/org/eclipse/swt/internal/mozilla/nsID.java
@@ -54,24 +54,68 @@ public boolean Equals(nsID other) {
 	return result;
 }
 
-public void Parse (String aIDStr) {
-	if (aIDStr == null) throw new Error ();
+public void Parse(String aIDStr) {
+	if(aIDStr == null) throw new Error ();
 	int i = 0;
-	for (; i < 8; i++) m0 = (m0 << 4) + Integer.parseInt (aIDStr.substring (i, i + 1), 16);
+	for (; i < 8; i++) {
+		int digit = Character.digit (aIDStr.charAt (i), 16);
+		if (digit == -1) throw new Error ();
+		m0 = (m0 << 4) + digit;
+	}
 	if (aIDStr.charAt (i++) != '-') throw new Error ();
-	for (; i < 13; i++) m1 = (short)((m1 << 4) + Integer.parseInt (aIDStr.substring (i, i + 1), 16));
+	for (; i < 13; i++) {
+		int digit = Character.digit (aIDStr.charAt (i), 16);
+		if (digit == -1) throw new Error ();
+		m1 = (short)((m1 << 4) + digit);
+	}
 	if (aIDStr.charAt (i++) != '-') throw new Error ();
-	for (; i < 18; i++) m2 = (short)((m2 << 4) + Integer.parseInt (aIDStr.substring (i, i + 1), 16));
+	for (; i < 18; i++) {
+		int digit = Character.digit (aIDStr.charAt (i), 16);
+		if (digit == -1) throw new Error ();
+		m2 = (short)((m2 << 4) + digit);
+	}
 	if (aIDStr.charAt (i++) != '-') throw new Error ();
-	for (; i < 21; i++) m3[0] = (byte)((m3[0] << 4) + Integer.parseInt (aIDStr.substring (i, i + 1), 16));
-	for (; i < 23; i++) m3[1] = (byte)((m3[1] << 4) + Integer.parseInt (aIDStr.substring (i, i + 1), 16));
+	for (; i < 21; i++) {
+		int digit = Character.digit (aIDStr.charAt (i), 16);
+		if (digit == -1) throw new Error ();
+		m3[0] = (byte)((m3[0] << 4) + digit);
+	}
+	for (; i < 23; i++) {
+		int digit = Character.digit (aIDStr.charAt (i), 16);
+		if (digit == -1) throw new Error ();
+		m3[1] = (byte)((m3[1] << 4) + digit);
+	}
 	if (aIDStr.charAt (i++) != '-') throw new Error ();
-	for (; i < 26; i++) m3[2] = (byte)((m3[2] << 4) + Integer.parseInt (aIDStr.substring (i, i + 1), 16));
-	for (; i < 28; i++) m3[3] = (byte)((m3[3] << 4) + Integer.parseInt (aIDStr.substring (i, i + 1), 16));
-	for (; i < 30; i++) m3[4] = (byte)((m3[4] << 4) + Integer.parseInt (aIDStr.substring (i, i + 1), 16));
-	for (; i < 32; i++) m3[5] = (byte)((m3[5] << 4) + Integer.parseInt (aIDStr.substring (i, i + 1), 16));
-	for (; i < 34; i++) m3[6] = (byte)((m3[6] << 4) + Integer.parseInt (aIDStr.substring (i, i + 1), 16));
-	for (; i < 36; i++) m3[7] = (byte)((m3[7] << 4) + Integer.parseInt (aIDStr.substring (i, i + 1), 16));
+	for (; i < 26; i++) {
+		int digit = Character.digit (aIDStr.charAt (i), 16);
+		if (digit == -1) throw new Error ();
+		m3[2] = (byte)((m3[2] << 4) + digit);
+	}
+	for (; i < 28; i++) {
+		int digit = Character.digit (aIDStr.charAt (i), 16);
+		if (digit == -1) throw new Error ();
+		m3[3] = (byte)((m3[3] << 4) + digit);
+	}
+	for (; i < 30; i++) {
+		int digit = Character.digit (aIDStr.charAt (i), 16);
+		if (digit == -1) throw new Error ();
+		m3[4] = (byte)((m3[4] << 4) + digit);
+	}
+	for (; i < 32; i++) {
+		int digit = Character.digit (aIDStr.charAt (i), 16);
+		if (digit == -1) throw new Error ();
+		m3[5] = (byte)((m3[5] << 4) + digit);
+	}
+	for (; i < 34; i++) {
+		int digit = Character.digit (aIDStr.charAt (i), 16);
+		if (digit == -1) throw new Error ();
+		m3[6] = (byte)((m3[6] << 4) + digit);
+	}
+	for (; i < 36; i++) {
+		int digit = Character.digit (aIDStr.charAt (i), 16);
+		if (digit == -1) throw new Error ();
+		m3[7] = (byte)((m3[7] << 4) + digit);
+	}
 }
 
-}
\ No newline at end of file
+}
diff --git a/org/eclipse/swt/internal/mozilla/nsIDataType.java b/org/eclipse/swt/internal/mozilla/nsIDataType.java
index 88e6093..d54f3d7 100644
--- a/org/eclipse/swt/internal/mozilla/nsIDataType.java
+++ b/org/eclipse/swt/internal/mozilla/nsIDataType.java
@@ -1,6 +1,32 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by Netscape are Copyright (C) 1998-1999
+ * Netscape Communications Corporation.  All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * IBM
+ * -  Binding to permit interfacing between Mozilla and SWT
+ * -  Copyright (C) 2003, 2009 IBM Corp.  All Rights Reserved.
+ *
+ * ***** END LICENSE BLOCK ***** */
 package org.eclipse.swt.internal.mozilla;
 
-
 public class nsIDataType extends nsISupports {
 
 	static final int LAST_METHOD_ID = nsISupports.LAST_METHOD_ID + 0;
diff --git a/org/eclipse/swt/internal/mozilla/nsIMIMEInputStream.java b/org/eclipse/swt/internal/mozilla/nsIMIMEInputStream.java
new file mode 100644
index 0000000..2d1d44e
--- /dev/null
+++ b/org/eclipse/swt/internal/mozilla/nsIMIMEInputStream.java
@@ -0,0 +1,59 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by Netscape are Copyright (C) 1998-1999
+ * Netscape Communications Corporation.  All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * IBM
+ * -  Binding to permit interfacing between Mozilla and SWT
+ * -  Copyright (C) 2003, 2009 IBM Corp.  All Rights Reserved.
+ *
+ * ***** END LICENSE BLOCK ***** */
+package org.eclipse.swt.internal.mozilla;
+
+public class  nsIMIMEInputStream extends nsIInputStream {
+
+	static final int LAST_METHOD_ID = nsIInputStream.LAST_METHOD_ID + 4;
+
+	public static final String NS_IMIMEINPUTSTREAM_IID_STR =
+		"dcbce63c-1dd1-11b2-b94d-91f6d49a3161";
+
+	public static final nsID NS_IMIMEINPUTSTREAM_IID =
+		new nsID(NS_IMIMEINPUTSTREAM_IID_STR);
+
+	public  nsIMIMEInputStream(int /*long*/ address) {
+		super(address);
+	}
+
+	public int GetAddContentLength(int[] aAddContentLength) {
+		return XPCOM.VtblCall(nsIInputStream.LAST_METHOD_ID + 1, getAddress(), aAddContentLength);
+	}
+
+	public int SetAddContentLength(int aAddContentLength) {
+		return XPCOM.VtblCall(nsIInputStream.LAST_METHOD_ID + 2, getAddress(), aAddContentLength);
+	}
+
+	public int AddHeader(byte[] name, byte[] value) {
+		return XPCOM.VtblCall(nsIInputStream.LAST_METHOD_ID + 3, getAddress(), name, value);
+	}
+
+	public int SetData(int /*long*/ stream) {
+		return XPCOM.VtblCall(nsIInputStream.LAST_METHOD_ID + 4, getAddress(), stream);
+	}
+}
\ No newline at end of file
diff --git a/org/eclipse/swt/internal/mozilla/nsISecurityCheckedComponent.java b/org/eclipse/swt/internal/mozilla/nsISecurityCheckedComponent.java
index bc58ffa..017ed67 100644
--- a/org/eclipse/swt/internal/mozilla/nsISecurityCheckedComponent.java
+++ b/org/eclipse/swt/internal/mozilla/nsISecurityCheckedComponent.java
@@ -1,6 +1,32 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by Netscape are Copyright (C) 1998-1999
+ * Netscape Communications Corporation.  All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * IBM
+ * -  Binding to permit interfacing between Mozilla and SWT
+ * -  Copyright (C) 2003, 2009 IBM Corp.  All Rights Reserved.
+ *
+ * ***** END LICENSE BLOCK ***** */
 package org.eclipse.swt.internal.mozilla;
 
-
 public class nsISecurityCheckedComponent extends nsISupports {
 
 	static final int LAST_METHOD_ID = nsISupports.LAST_METHOD_ID + 4;
diff --git a/org/eclipse/swt/internal/mozilla/nsIWritableVariant.java b/org/eclipse/swt/internal/mozilla/nsIWritableVariant.java
index 30b340c..76566dd 100644
--- a/org/eclipse/swt/internal/mozilla/nsIWritableVariant.java
+++ b/org/eclipse/swt/internal/mozilla/nsIWritableVariant.java
@@ -1,6 +1,32 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by Netscape are Copyright (C) 1998-1999
+ * Netscape Communications Corporation.  All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * IBM
+ * -  Binding to permit interfacing between Mozilla and SWT
+ * -  Copyright (C) 2003, 2009 IBM Corp.  All Rights Reserved.
+ *
+ * ***** END LICENSE BLOCK ***** */
 package org.eclipse.swt.internal.mozilla;
 
-
 public class nsIWritableVariant extends nsIVariant {
 
 	static final int LAST_METHOD_ID = nsIVariant.LAST_METHOD_ID + 31;
diff --git a/org/eclipse/swt/internal/webkit/JSClassDefinition.java b/org/eclipse/swt/internal/webkit/JSClassDefinition.java
new file mode 100644
index 0000000..391ce4a
--- /dev/null
+++ b/org/eclipse/swt/internal/webkit/JSClassDefinition.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2010 IBM Corporation and others. All rights reserved.
+ * The contents of this file are made available under the terms
+ * of the GNU Lesser General Public License (LGPL) Version 2.1 that
+ * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
+ * available at http://www.gnu.org/licenses/lgpl.html.  If the version
+ * of the LGPL at http://www.gnu.org is different to the version of
+ * the LGPL accompanying this distribution and there is any conflict
+ * between the two license versions, the terms of the LGPL accompanying
+ * this distribution shall govern.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.internal.webkit;
+
+
+public class JSClassDefinition {
+    public int version;
+    /** @field cast=(JSClassAttributes) */
+    public int attributes;
+    /** @field cast=(const char*) */
+    public int /*long*/ className;
+    /** @field cast=(JSClassRef) */
+    public int /*long*/ parentClass;
+    /** @field cast=(const JSStaticValue*) */
+    public int /*long*/ staticValues;
+    /** @field cast=(const JSStaticFunction*) */
+    public int /*long*/ staticFunctions;
+    /** @field cast=(JSObjectInitializeCallback) */
+    public int /*long*/ initialize;
+    /** @field cast=(JSObjectFinalizeCallback) */
+    public int /*long*/ finalize;
+    /** @field cast=(JSObjectHasPropertyCallback) */
+    public int /*long*/ hasProperty;
+    /** @field cast=(JSObjectGetPropertyCallback) */
+    public int /*long*/ getProperty;
+    /** @field cast=(JSObjectSetPropertyCallback) */
+    public int /*long*/ setProperty;
+    /** @field cast=(JSObjectDeletePropertyCallback) */
+    public int /*long*/ deleteProperty;
+    /** @field cast=(JSObjectGetPropertyNamesCallback) */
+    public int /*long*/ getPropertyNames;
+    /** @field cast=(JSObjectCallAsFunctionCallback) */
+    public int /*long*/ callAsFunction;
+    /** @field cast=(JSObjectCallAsConstructorCallback) */
+    public int /*long*/ callAsConstructor;
+    /** @field cast=(JSObjectHasInstanceCallback) */
+    public int /*long*/ hasInstance;
+    /** @field cast=(JSObjectConvertToTypeCallback) */
+    public int /*long*/ convertToType;
+    
+    public static final int sizeof = WebKitGTK.JSClassDefinition_sizeof();
+}
diff --git a/org/eclipse/swt/internal/webkit/WebKitGTK.java b/org/eclipse/swt/internal/webkit/WebKitGTK.java
new file mode 100644
index 0000000..a564b4d
--- /dev/null
+++ b/org/eclipse/swt/internal/webkit/WebKitGTK.java
@@ -0,0 +1,1368 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2010 IBM Corporation and others. All rights reserved.
+ * The contents of this file are made available under the terms
+ * of the GNU Lesser General Public License (LGPL) Version 2.1 that
+ * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
+ * available at http://www.gnu.org/licenses/lgpl.html.  If the version
+ * of the LGPL at http://www.gnu.org is different to the version of
+ * the LGPL accompanying this distribution and there is any conflict
+ * between the two license versions, the terms of the LGPL accompanying
+ * this distribution shall govern.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.internal.webkit;
+
+
+import org.eclipse.swt.internal.C;
+
+public class WebKitGTK extends C {
+
+	/** Constants */
+	public static final int kJSTypeUndefined = 0;
+	public static final int kJSTypeNull = 1;
+	public static final int kJSTypeBoolean = 2;
+	public static final int kJSTypeNumber = 3;
+	public static final int kJSTypeString = 4;
+	public static final int kJSTypeObject = 5;
+	public static final int SOUP_MEMORY_TAKE = 1;
+	public static final int WEBKIT_DOWNLOAD_STATUS_ERROR = -1;
+	public static final int WEBKIT_DOWNLOAD_STATUS_CANCELLED = 2;
+	public static final int WEBKIT_DOWNLOAD_STATUS_FINISHED = 3;
+	public static final int WEBKIT_LOAD_COMMITTED = 1;
+	public static final int WEBKIT_LOAD_FINISHED = 2;
+
+	/** Signals */
+	public static final byte[] authenticate = ascii ("authenticate"); // $NON-NLS-1$
+	public static final byte[] close_web_view = ascii ("close-web-view"); // $NON-NLS-1$
+	public static final byte[] console_message = ascii ("console-message"); // $NON-NLS-1$
+	public static final byte[] create_web_view = ascii ("create-web-view"); // $NON-NLS-1$
+	public static final byte[] download_requested = ascii ("download-requested"); // $NON-NLS-1$
+	public static final byte[] hovering_over_link = ascii ("hovering-over-link"); // $NON-NLS-1$
+	public static final byte[] mime_type_policy_decision_requested = ascii ("mime-type-policy-decision-requested"); // $NON-NLS-1$
+	public static final byte[] navigation_policy_decision_requested = ascii ("navigation-policy-decision-requested"); // $NON-NLS-1$
+	public static final byte[] notify_load_status = ascii ("notify::load-status"); // $NON-NLS-1$
+	public static final byte[] notify_progress = ascii ("notify::progress"); // $NON-NLS-1$
+	public static final byte[] notify_title = ascii ("notify::title"); // $NON-NLS-1$
+	public static final byte[] populate_popup = ascii ("populate-popup"); // $NON-NLS-1$
+	public static final byte[] resource_request_starting = ascii ("resource_request_starting"); // $NON-NLS-1$
+	public static final byte[] status_bar_text_changed = ascii ("status-bar-text-changed"); // $NON-NLS-1$
+	public static final byte[] web_view_ready = ascii ("web-view-ready"); // $NON-NLS-1$
+	public static final byte[] window_object_cleared = ascii ("window-object-cleared"); // $NON-NLS-1$
+
+	/** Properties */
+	public static final byte[] enable_scripts = ascii ("enable-scripts"); // $NON-NLS-1$
+	public static final byte[] enable_universal_access_from_file_uris = ascii ("enable-universal-access-from-file-uris"); // $NON-NLS-1$
+	public static final byte[] height = ascii ("height"); // $NON-NLS-1$
+	public static final byte[] javascript_can_open_windows_automatically = ascii ("javascript-can-open-windows-automatically"); // $NON-NLS-1$
+	public static final byte[] locationbar_visible = ascii ("locationbar-visible"); // $NON-NLS-1$
+	public static final byte[] menubar_visible = ascii ("menubar-visible"); // $NON-NLS-1$
+	public static final byte[] SOUP_SESSION_PROXY_URI = ascii ("proxy-uri"); // $NON-NLS-1$
+	public static final byte[] statusbar_visible = ascii ("statusbar-visible"); // $NON-NLS-1$
+	public static final byte[] toolbar_visible = ascii ("toolbar-visible"); // $NON-NLS-1$
+	public static final byte[] user_agent = ascii ("user-agent"); // $NON-NLS-1$
+	public static final byte[] width = ascii ("width"); // $NON-NLS-1$
+	public static final byte[] x = ascii ("x"); // $NON-NLS-1$
+	public static final byte[] y = ascii ("y"); // $NON-NLS-1$
+
+protected static byte [] ascii (String name) {
+	int length = name.length ();
+	char [] chars = new char [length];
+	name.getChars (0, length, chars, 0);
+	byte [] buffer = new byte [length + 1];
+	for (int i=0; i<length; i++) {
+		buffer [i] = (byte) chars [i];
+	}
+	return buffer;
+}
+
+
+/**
+ * @param definition cast=(const JSClassDefinition*)
+ */
+public static final native int /*long*/ _JSClassCreate (int /*long*/ definition);
+public static final int /*long*/ JSClassCreate (int /*long*/ definition) {
+	lock.lock();
+	try {
+		return _JSClassCreate (definition);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param ctx cast=(JSContextRef)
+ */
+public static final native int /*long*/ _JSContextGetGlobalObject (int /*long*/ ctx);
+public static final int /*long*/ JSContextGetGlobalObject (int /*long*/ ctx) {
+	lock.lock();
+	try {
+		return _JSContextGetGlobalObject (ctx);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param ctx cast=(JSContextRef)
+ * @param script cast=(JSStringRef)
+ * @param thisObject cast=(JSObjectRef)
+ * @param sourceURL cast=(JSStringRef)
+ * @param exception cast=(JSValueRef *)
+ */
+public static final native int /*long*/ _JSEvaluateScript (int /*long*/ ctx, int /*long*/ script, int /*long*/ thisObject, int /*long*/ sourceURL, int startingLineNumber, int /*long*/[] exception);
+public static final int /*long*/ JSEvaluateScript (int /*long*/ ctx, int /*long*/ script, int /*long*/ thisObject, int /*long*/ sourceURL, int startingLineNumber, int /*long*/[] exception) {
+	lock.lock();
+	try {
+		return _JSEvaluateScript (ctx, script, thisObject, sourceURL, startingLineNumber, exception);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param object cast=(JSObjectRef)
+ */
+public static final native int /*long*/ _JSObjectGetPrivate (int /*long*/ object);
+public static final int /*long*/ JSObjectGetPrivate (int /*long*/ object) {
+	lock.lock();
+	try {
+		return _JSObjectGetPrivate (object);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param ctx cast=(JSContextRef)
+ * @param object cast=(JSObjectRef)
+ * @param propertyName cast=(JSStringRef)
+ * @param exception cast=(JSValueRef*)
+ */
+public static final native int /*long*/ _JSObjectGetProperty (int /*long*/ ctx, int /*long*/ object, int /*long*/ propertyName, int /*long*/[] exception);
+public static final int /*long*/ JSObjectGetProperty (int /*long*/ ctx, int /*long*/ object, int /*long*/ propertyName, int /*long*/[] exception) {
+	lock.lock();
+	try {
+		return _JSObjectGetProperty (ctx, object, propertyName, exception);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param ctx cast=(JSContextRef)
+ * @param object cast=(JSObjectRef)
+ * @param propertyIndex cast=(unsigned)
+ * @param exception cast=(JSValueRef*)
+ */
+public static final native int /*long*/ _JSObjectGetPropertyAtIndex (int /*long*/ ctx, int /*long*/ object, int propertyIndex, int /*long*/[] exception);
+public static final int /*long*/ JSObjectGetPropertyAtIndex (int /*long*/ ctx, int /*long*/ object, int propertyIndex, int /*long*/[] exception) {
+	lock.lock();
+	try {
+		return _JSObjectGetPropertyAtIndex (ctx, object, propertyIndex, exception);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param ctx cast=(JSContextRef)
+ * @param jsClass cast=(JSClassRef)
+ * @param data cast=(void *)
+ */
+public static final native int /*long*/ _JSObjectMake (int /*long*/ ctx, int /*long*/ jsClass, int /*long*/ data);
+public static final int /*long*/ JSObjectMake (int /*long*/ ctx, int /*long*/ jsClass, int /*long*/ data) {
+	lock.lock();
+	try {
+		return _JSObjectMake (ctx, jsClass, data);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param ctx cast=(JSContextRef)
+ * @param argumentCount cast=(size_t)
+ * @param arguments cast=(const struct OpaqueJSValue * const*)
+ * @param exception cast=(JSValueRef*)
+ */
+public static final native int /*long*/ _JSObjectMakeArray (int /*long*/ ctx, int /*long*/ argumentCount, int /*long*/[] arguments, int /*long*/[] exception);
+public static final int /*long*/ JSObjectMakeArray (int /*long*/ ctx, int /*long*/ argumentCount, int /*long*/[] arguments, int /*long*/[] exception) {
+	lock.lock();
+	try {
+		return _JSObjectMakeArray (ctx, argumentCount, arguments, exception);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param ctx cast=(JSContextRef)
+ * @param name cast=(JSStringRef)
+ * @param callAsFunction cast=(JSObjectCallAsFunctionCallback)
+ */
+public static final native int /*long*/ _JSObjectMakeFunctionWithCallback (int /*long*/ ctx, int /*long*/ name, int /*long*/ callAsFunction);
+public static final int /*long*/ JSObjectMakeFunctionWithCallback (int /*long*/ ctx, int /*long*/ name, int /*long*/ callAsFunction) {
+	lock.lock();
+	try {
+		return _JSObjectMakeFunctionWithCallback (ctx, name, callAsFunction);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param ctx cast=(JSContextRef)
+ * @param object cast=(JSObjectRef)
+ * @param propertyName cast=(JSStringRef)
+ * @param value cast=(JSValueRef)
+ * @param attributes cast=(JSPropertyAttributes)
+ * @param exception cast=(JSValueRef *)
+ */
+public static final native void _JSObjectSetProperty (int /*long*/ ctx, int /*long*/ object, int /*long*/ propertyName, int /*long*/ value, int attributes, int /*long*/[] exception);
+public static final void JSObjectSetProperty (int /*long*/ ctx, int /*long*/ object, int /*long*/ propertyName, int /*long*/ value, int attributes, int /*long*/[] exception) {
+	lock.lock();
+	try {
+		_JSObjectSetProperty (ctx, object, propertyName, value, attributes, exception);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param string cast=(const char *)
+ */
+public static final native int /*long*/ _JSStringCreateWithUTF8CString (byte[] string);
+public static final int /*long*/ JSStringCreateWithUTF8CString (byte[] string) {
+	lock.lock();
+	try {
+		return _JSStringCreateWithUTF8CString (string);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param string cast=(JSStringRef)
+ */
+public static final native int /*long*/ _JSStringGetLength (int /*long*/ string);
+public static final int /*long*/ JSStringGetLength (int /*long*/ string) {
+	lock.lock();
+	try {
+		return _JSStringGetLength (string);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param string cast=(JSStringRef)
+ */
+public static final native int /*long*/ _JSStringGetMaximumUTF8CStringSize (int /*long*/ string);
+public static final int /*long*/ JSStringGetMaximumUTF8CStringSize (int /*long*/ string) {
+	lock.lock();
+	try {
+		return _JSStringGetMaximumUTF8CStringSize (string);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param string cast=(JSStringRef)
+ * @param buffer cast=(char *)
+ * @param bufferSize cast=(size_t)
+ */
+public static final native int /*long*/ _JSStringGetUTF8CString (int /*long*/ string, byte[] buffer, int /*long*/ bufferSize);
+public static final int /*long*/ JSStringGetUTF8CString (int /*long*/ string, byte[] buffer, int /*long*/ bufferSize) {
+	lock.lock();
+	try {
+		return _JSStringGetUTF8CString (string, buffer, bufferSize);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param a cast=(JSStringRef)
+ * @param b cast=(const char *)
+ */
+public static final native int _JSStringIsEqualToUTF8CString (int /*long*/ a, byte[] b);
+public static final int JSStringIsEqualToUTF8CString (int /*long*/ a, byte[] b) {
+	lock.lock();
+	try {
+		return _JSStringIsEqualToUTF8CString (a, b);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param string cast=(JSStringRef)
+ */
+public static final native void _JSStringRelease (int /*long*/ string);
+public static final void JSStringRelease (int /*long*/ string) {
+	lock.lock();
+	try {
+		_JSStringRelease (string);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param ctx cast=(JSContextRef)
+ * @param value cast=(JSValueRef)
+ */
+public static final native int _JSValueGetType (int /*long*/ ctx, int /*long*/ value);
+public static final int JSValueGetType (int /*long*/ ctx, int /*long*/ value) {
+	lock.lock();
+	try {
+		return _JSValueGetType (ctx, value);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param ctx cast=(JSContextRef)
+ * @param value cast=(JSValueRef)
+ * @param jsClass cast=(JSClassRef)
+ */
+public static final native int _JSValueIsObjectOfClass (int /*long*/ ctx, int /*long*/ value, int /*long*/ jsClass);
+public static final int JSValueIsObjectOfClass (int /*long*/ ctx, int /*long*/ value, int /*long*/ jsClass) {
+	lock.lock();
+	try {
+		return _JSValueIsObjectOfClass (ctx, value, jsClass);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param ctx cast=(JSContextRef)
+ * @param bool cast=(bool)
+ */
+public static final native int /*long*/ _JSValueMakeBoolean (int /*long*/ ctx, int bool);
+public static final int /*long*/ JSValueMakeBoolean (int /*long*/ ctx, int bool) {
+	lock.lock();
+	try {
+		return _JSValueMakeBoolean (ctx, bool);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param ctx cast=(JSContextRef)
+ * @param number cast=(double)
+ */
+public static final native int /*long*/ _JSValueMakeNumber (int /*long*/ ctx, double number);
+public static final int /*long*/ JSValueMakeNumber (int /*long*/ ctx, double number) {
+	lock.lock();
+	try {
+		return _JSValueMakeNumber (ctx, number);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param ctx cast=(JSContextRef)
+ * @param string cast=(JSStringRef)
+ */
+public static final native int /*long*/ _JSValueMakeString (int /*long*/ ctx, int /*long*/ string);
+public static final int /*long*/ JSValueMakeString (int /*long*/ ctx, int /*long*/ string) {
+	lock.lock();
+	try {
+		return _JSValueMakeString (ctx, string);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param ctx cast=(JSContextRef)
+ */
+public static final native int /*long*/ _JSValueMakeUndefined (int /*long*/ ctx);
+public static final int /*long*/ JSValueMakeUndefined (int /*long*/ ctx) {
+	lock.lock();
+	try {
+		return _JSValueMakeUndefined (ctx);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param ctx cast=(JSContextRef)
+ * @param value cast=(JSValueRef)
+ */
+public static final native int _JSValueToBoolean (int /*long*/ ctx, int /*long*/ value);
+public static final int JSValueToBoolean (int /*long*/ ctx, int /*long*/ value) {
+	lock.lock();
+	try {
+		return _JSValueToBoolean (ctx, value);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param ctx cast=(JSContextRef)
+ * @param value cast=(JSValueRef)
+ * @param exception cast=(JSValueRef*)
+ */
+public static final native double _JSValueToNumber (int /*long*/ ctx, int /*long*/ value, int /*long*/[] exception);
+public static final double JSValueToNumber (int /*long*/ ctx, int /*long*/ value, int /*long*/[] exception) {
+	lock.lock();
+	try {
+		return _JSValueToNumber (ctx, value, exception);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param ctx cast=(JSContextRef)
+ * @param value cast=(JSValueRef)
+ * @param exception cast=(JSValueRef*)
+ */
+public static final native int /*long*/ _JSValueToStringCopy (int /*long*/ ctx, int /*long*/ value, int /*long*/[] exception);
+public static final int /*long*/ JSValueToStringCopy (int /*long*/ ctx, int /*long*/ value, int /*long*/[] exception) {
+	lock.lock();
+	try {
+		return _JSValueToStringCopy (ctx, value, exception);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/* --------------------- start libsoup natives --------------------- */
+
+/**
+ * @param auth cast=(SoupAuth *)
+ * @param username cast=(const char *)
+ * @param password cast=(const char *)
+ */
+public static final native void _soup_auth_authenticate (int /*long*/ auth, byte[] username, byte[] password);
+public static final void soup_auth_authenticate (int /*long*/ auth, byte[] username, byte[] password) {
+	lock.lock();
+	try {
+		_soup_auth_authenticate (auth, username, password);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param auth cast=(SoupAuth *)
+ */
+public static final native int /*long*/ _soup_auth_get_host (int /*long*/ auth);
+public static final int /*long*/ soup_auth_get_host (int /*long*/ auth) {
+	lock.lock();
+	try {
+		return _soup_auth_get_host (auth);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param auth cast=(SoupAuth *)
+ */
+public static final native int /*long*/ _soup_auth_get_scheme_name (int /*long*/ auth);
+public static final int /*long*/ soup_auth_get_scheme_name (int /*long*/ auth) {
+	lock.lock();
+	try {
+		return _soup_auth_get_scheme_name (auth);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param jar cast=(SoupCookieJar *)
+ * @param cookie cast=(SoupCookie *)
+ */
+public static final native void _soup_cookie_jar_add_cookie (int /*long*/ jar, int /*long*/ cookie);
+public static final void soup_cookie_jar_add_cookie (int /*long*/ jar, int /*long*/ cookie) {
+	lock.lock();
+	try {
+		_soup_cookie_jar_add_cookie (jar, cookie);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param jar cast=(SoupCookieJar *)
+ */
+public static final native int /*long*/ _soup_cookie_jar_all_cookies (int /*long*/ jar);
+public static final int /*long*/ soup_cookie_jar_all_cookies (int /*long*/ jar) {
+	lock.lock();
+	try {
+		return _soup_cookie_jar_all_cookies (jar);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param jar cast=(SoupCookieJar *)
+ * @param cookie cast=(SoupCookie *)
+ */
+public static final native void _soup_cookie_jar_delete_cookie (int /*long*/ jar, int /*long*/ cookie);
+public static final void soup_cookie_jar_delete_cookie (int /*long*/ jar, int /*long*/ cookie) {
+	lock.lock();
+	try {
+		_soup_cookie_jar_delete_cookie (jar, cookie);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param jar cast=(SoupCookieJar *)
+ * @param uri cast=(SoupURI *)
+ */
+public static final native int /*long*/ _soup_cookie_jar_get_cookies (int /*long*/ jar, int /*long*/ uri, int for_http);
+public static final int /*long*/ soup_cookie_jar_get_cookies (int /*long*/ jar, int /*long*/ uri, int for_http) {
+	lock.lock();
+	try {
+		return _soup_cookie_jar_get_cookies (jar, uri, for_http);
+	} finally {
+		lock.unlock();
+	}
+}
+
+public static final native int _soup_cookie_jar_get_type ();
+public static final int soup_cookie_jar_get_type () {
+	lock.lock();
+	try {
+		return _soup_cookie_jar_get_type ();
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param header cast=(const char *)
+ * @param origin cast=(SoupURI *)
+ */
+public static final native int /*long*/ _soup_cookie_parse (byte[] header, int /*long*/ origin);
+public static final int /*long*/ soup_cookie_parse (byte[] header, int /*long*/ origin) {
+	lock.lock();
+	try {
+		return _soup_cookie_parse (header, origin);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @method flags=getter
+ * @param cookie cast=(SoupCookie *)
+ */
+public static final native int /*long*/ _SoupCookie_expires (int /*long*/ cookie);
+public static final int /*long*/ SoupCookie_expires (int /*long*/ cookie) {
+	lock.lock();
+	try {
+		return _SoupCookie_expires (cookie);
+	} finally {
+		lock.unlock();
+	}
+}
+
+public static final native boolean _SOUP_IS_SESSION (int /*long*/ object);
+public static final boolean SOUP_IS_SESSION (int /*long*/ object) {
+	lock.lock();
+	try {
+		return _SOUP_IS_SESSION (object);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @method flags=setter
+ * @param message cast=(SoupMessage *)
+ * @param method cast=(const char *)
+ */
+public static final native void _SoupMessage_method (int /*long*/ message, int /*long*/ method);
+public static final void SoupMessage_method (int /*long*/ message, int /*long*/ method) {
+	lock.lock();
+	try {
+		_SoupMessage_method (message, method);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @method flags=getter
+ * @param message cast=(SoupMessage *)
+ */
+public static final native int /*long*/ _SoupMessage_request_body (int /*long*/ message);
+public static final int /*long*/ SoupMessage_request_body (int /*long*/ message) {
+	lock.lock();
+	try {
+		return _SoupMessage_request_body (message);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @method flags=getter
+ * @param message cast=(SoupMessage *)
+ */
+public static final native int /*long*/ _SoupMessage_request_headers (int /*long*/ message);
+public static final int /*long*/ SoupMessage_request_headers (int /*long*/ message) {
+	lock.lock();
+	try {
+		return _SoupMessage_request_headers (message);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param body cast=(SoupMessageBody *)
+ * @param use cast=(SoupMemoryUse)
+ * @param data cast=(gconstpointer)
+ * @param length cast=(gsize)
+ */
+public static final native void _soup_message_body_append (int /*long*/ body, int use, int /*long*/ data, int /*long*/ length);
+public static final void soup_message_body_append (int /*long*/ body, int use, int /*long*/ data, int /*long*/ length) {
+	lock.lock();
+	try {
+		_soup_message_body_append (body, use, data, length);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param body cast=(SoupMessageBody *)
+ */
+public static final native void _soup_message_body_flatten (int /*long*/ body);
+public static final void soup_message_body_flatten (int /*long*/ body) {
+	lock.lock();
+	try {
+		_soup_message_body_flatten (body);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param msg cast=(SoupMessage *)
+ */
+public static final native int /*long*/ _soup_message_get_uri (int /*long*/ msg);
+public static final int /*long*/ soup_message_get_uri (int /*long*/ msg) {
+	lock.lock();
+	try {
+		return _soup_message_get_uri (msg);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param headers cast=(SoupMessageHeaders *)
+ * @param name cast=(const char *)
+ * @param value cast=(const char *)
+ */
+public static final native void _soup_message_headers_append (int /*long*/ headers, byte[] name, byte[] value);
+public static final void soup_message_headers_append (int /*long*/ headers, byte[] name, byte[] value) {
+	lock.lock();
+	try {
+		_soup_message_headers_append (headers, name, value);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param session cast=(SoupSession *)
+ * @param type cast=(GType)
+ */
+public static final native void _soup_session_add_feature_by_type (int /*long*/ session, int type);
+public static final void soup_session_add_feature_by_type (int /*long*/ session, int type) {
+	lock.lock();
+	try {
+		_soup_session_add_feature_by_type (session, type);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param session cast=(SoupSession *)
+ * @param feature_type cast=(GType)
+ */
+public static final native int /*long*/ _soup_session_get_feature (int /*long*/ session, int feature_type);
+public static final int /*long*/ soup_session_get_feature (int /*long*/ session, int feature_type) {
+	lock.lock();
+	try {
+		return _soup_session_get_feature (session, feature_type);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param feature cast=(SoupSessionFeature *)
+ * @param session cast=(SoupSession *)
+ */
+public static final native void _soup_session_feature_attach (int /*long*/ feature, int /*long*/ session);
+public static final void soup_session_feature_attach (int /*long*/ feature, int /*long*/ session) {
+	lock.lock();
+	try {
+		_soup_session_feature_attach (feature, session);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param feature cast=(SoupSessionFeature *)
+ * @param session cast=(SoupSession *)
+ */
+public static final native void _soup_session_feature_detach (int /*long*/ feature, int /*long*/ session);
+public static final void soup_session_feature_detach (int /*long*/ feature, int /*long*/ session) {
+	lock.lock();
+	try {
+		_soup_session_feature_detach (feature, session);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param uri cast=(SoupURI *)
+ */
+public static final native void _soup_uri_free (int /*long*/ uri);
+public static final void soup_uri_free (int /*long*/ uri) {
+	lock.lock();
+	try {
+		_soup_uri_free (uri);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param uri_string cast=(const char *)
+ */
+public static final native int /*long*/ _soup_uri_new (byte[] uri_string);
+public static final int /*long*/ soup_uri_new (byte[] uri_string) {
+	lock.lock();
+	try {
+		return _soup_uri_new (uri_string);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param uri cast=(SoupURI *)
+ */
+public static final native int /*long*/ _soup_uri_to_string (int /*long*/ uri, int just_path_and_query);
+public static final int /*long*/ soup_uri_to_string (int /*long*/ uri, int just_path_and_query) {
+	lock.lock();
+	try {
+		return _soup_uri_to_string (uri, just_path_and_query);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/* --------------------- start WebKitGTK natives --------------------- */
+
+/**
+ * @param download cast=(WebKitDownload *)
+ */
+public static final native void _webkit_download_cancel (int /*long*/ download);
+public static final void webkit_download_cancel (int /*long*/ download) {
+	lock.lock();
+	try {
+		_webkit_download_cancel (download);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param download cast=(WebKitDownload *)
+ */
+public static final native long _webkit_download_get_current_size (int /*long*/ download);
+public static final long webkit_download_get_current_size (int /*long*/ download) {
+	lock.lock();
+	try {
+		return _webkit_download_get_current_size (download);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param download cast=(WebKitDownload *)
+ */
+public static final native int _webkit_download_get_status (int /*long*/ download);
+public static final int webkit_download_get_status (int /*long*/ download) {
+	lock.lock();
+	try {
+		return _webkit_download_get_status (download);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param download cast=(WebKitDownload *)
+ */
+public static final native int /*long*/ _webkit_download_get_suggested_filename (int /*long*/ download);
+public static final int /*long*/ webkit_download_get_suggested_filename (int /*long*/ download) {
+	lock.lock();
+	try {
+		return _webkit_download_get_suggested_filename (download);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param download cast=(WebKitDownload *)
+ */
+public static final native long _webkit_download_get_total_size (int /*long*/ download);
+public static final long webkit_download_get_total_size (int /*long*/ download) {
+	lock.lock();
+	try {
+		return _webkit_download_get_total_size (download);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param download cast=(WebKitDownload *)
+ */
+public static final native int /*long*/ _webkit_download_get_uri (int /*long*/ download);
+public static final int /*long*/ webkit_download_get_uri (int /*long*/ download) {
+	lock.lock();
+	try {
+		return _webkit_download_get_uri (download);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param download cast=(WebKitDownload *)
+ * @param destination_uri cast=(const gchar *)
+ */
+public static final native void _webkit_download_set_destination_uri (int /*long*/ download, byte[] destination_uri);
+public static final void webkit_download_set_destination_uri (int /*long*/ download, byte[] destination_uri) {
+	lock.lock();
+	try {
+		_webkit_download_set_destination_uri (download, destination_uri);
+	} finally {
+		lock.unlock();
+	}
+}
+
+public static final native int /*long*/ _webkit_get_default_session ();
+public static final int /*long*/ webkit_get_default_session () {
+	lock.lock();
+	try {
+		return _webkit_get_default_session ();
+	} finally {
+		lock.unlock();
+	}
+}
+
+public static final native boolean _WEBKIT_IS_WEB_FRAME (int /*long*/ object);
+public static final boolean WEBKIT_IS_WEB_FRAME (int /*long*/ object) {
+	lock.lock();
+	try {
+		return _WEBKIT_IS_WEB_FRAME (object);
+	} finally {
+		lock.unlock();
+	}
+}
+
+public static final native int _webkit_major_version ();
+public static final int webkit_major_version () {
+	lock.lock();
+	try {
+		return _webkit_major_version ();
+	} finally {
+		lock.unlock();
+	}
+}
+
+public static final native int _webkit_micro_version ();
+public static final int webkit_micro_version () {
+	lock.lock();
+	try {
+		return _webkit_micro_version ();
+	} finally {
+		lock.unlock();
+	}
+}
+
+public static final native int _webkit_minor_version ();
+public static final int webkit_minor_version () {
+	lock.lock();
+	try {
+		return _webkit_minor_version ();
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param request cast=(WebKitNetworkRequest *)
+ */
+public static final native int /*long*/ _webkit_network_request_get_message (int /*long*/ request);
+public static final int /*long*/ webkit_network_request_get_message (int /*long*/ request) {
+	lock.lock();
+	try {
+		return _webkit_network_request_get_message (request);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param request cast=(WebKitNetworkRequest *)
+ */
+public static final native int /*long*/ _webkit_network_request_get_uri (int /*long*/ request);
+public static final int /*long*/ webkit_network_request_get_uri (int /*long*/ request) {
+	lock.lock();
+	try {
+		return _webkit_network_request_get_uri (request);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param uri cast=(const gchar *)
+ */
+public static final native int /*long*/ _webkit_network_request_new (byte[] uri);
+public static final int /*long*/ webkit_network_request_new (byte[] uri) {
+	lock.lock();
+	try {
+		return _webkit_network_request_new (uri);
+	} finally {
+		lock.unlock();
+	}
+}
+
+public static final native int _webkit_soup_auth_dialog_get_type ();
+public static final int webkit_soup_auth_dialog_get_type () {
+	lock.lock();
+	try {
+		return _webkit_soup_auth_dialog_get_type ();
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param data_source cast=(WebKitWebDataSource *)
+ */
+public static final native int /*long*/ _webkit_web_data_source_get_data (int /*long*/ data_source);
+public static final int /*long*/ webkit_web_data_source_get_data (int /*long*/ data_source) {
+	lock.lock();
+	try {
+		return _webkit_web_data_source_get_data (data_source);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param data_source cast=(WebKitWebDataSource *)
+ */
+public static final native int /*long*/ _webkit_web_data_source_get_encoding (int /*long*/ data_source);
+public static final int /*long*/ webkit_web_data_source_get_encoding (int /*long*/ data_source) {
+	lock.lock();
+	try {
+		return _webkit_web_data_source_get_encoding (data_source);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param frame cast=(WebKitWebFrame *)
+ */
+public static final native int /*long*/ _webkit_web_frame_get_data_source (int /*long*/ frame);
+public static final int /*long*/ webkit_web_frame_get_data_source (int /*long*/ frame) {
+	lock.lock();
+	try {
+		return _webkit_web_frame_get_data_source (frame);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param frame cast=(WebKitWebFrame *)
+ */
+public static final native int /*long*/ _webkit_web_frame_get_global_context (int /*long*/ frame);
+public static final int /*long*/ webkit_web_frame_get_global_context (int /*long*/ frame) {
+	lock.lock();
+	try {
+		return _webkit_web_frame_get_global_context (frame);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param frame cast=(WebKitWebFrame *)
+ */
+public static final native int _webkit_web_frame_get_load_status (int /*long*/ frame);
+public static final int webkit_web_frame_get_load_status (int /*long*/ frame) {
+	lock.lock();
+	try {
+		return _webkit_web_frame_get_load_status (frame);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param frame cast=(WebKitWebFrame *)
+ */
+public static final native int /*long*/ _webkit_web_frame_get_parent (int /*long*/ frame);
+public static final int /*long*/ webkit_web_frame_get_parent (int /*long*/ frame) {
+	lock.lock();
+	try {
+		return _webkit_web_frame_get_parent (frame);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param frame cast=(WebKitWebFrame *)
+ */
+public static final native int /*long*/ _webkit_web_frame_get_title (int /*long*/ frame);
+public static final int /*long*/ webkit_web_frame_get_title (int /*long*/ frame) {
+	lock.lock();
+	try {
+		return _webkit_web_frame_get_title (frame);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param frame cast=(WebKitWebFrame *)
+ */
+public static final native int /*long*/ _webkit_web_frame_get_uri (int /*long*/ frame);
+public static final int /*long*/ webkit_web_frame_get_uri (int /*long*/ frame) {
+	lock.lock();
+	try {
+		return _webkit_web_frame_get_uri (frame);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param frame cast=(WebKitWebFrame *)
+ */
+public static final native int /*long*/ _webkit_web_frame_get_web_view (int /*long*/ frame);
+public static final int /*long*/ webkit_web_frame_get_web_view (int /*long*/ frame) {
+	lock.lock();
+	try {
+		return _webkit_web_frame_get_web_view (frame);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param decision cast=(WebKitWebPolicyDecision *)
+ */
+public static final native void _webkit_web_policy_decision_download (int /*long*/ decision);
+public static final void webkit_web_policy_decision_download (int /*long*/ decision) {
+	lock.lock();
+	try {
+		_webkit_web_policy_decision_download (decision);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param decision cast=(WebKitWebPolicyDecision *)
+ */
+public static final native void _webkit_web_policy_decision_ignore (int /*long*/ decision);
+public static final void webkit_web_policy_decision_ignore (int /*long*/ decision) {
+	lock.lock();
+	try {
+		_webkit_web_policy_decision_ignore (decision);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param web_view cast=(WebKitWebView *)
+ */
+public static final native int _webkit_web_view_can_go_back (int /*long*/ web_view);
+public static final int webkit_web_view_can_go_back (int /*long*/ web_view) {
+	lock.lock();
+	try {
+		return _webkit_web_view_can_go_back (web_view);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param web_view cast=(WebKitWebView *)
+ */
+public static final native int _webkit_web_view_can_go_forward (int /*long*/ web_view);
+public static final int webkit_web_view_can_go_forward (int /*long*/ web_view) {
+	lock.lock();
+	try {
+		return _webkit_web_view_can_go_forward (web_view);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param web_view cast=(WebKitWebView *)
+ * @param mime_type cast=(const gchar *)
+ */
+public static final native int _webkit_web_view_can_show_mime_type (int /*long*/ web_view, int /*long*/ mime_type);
+public static final int webkit_web_view_can_show_mime_type (int /*long*/ web_view, int /*long*/ mime_type) {
+	lock.lock();
+	try {
+		return _webkit_web_view_can_show_mime_type (web_view, mime_type);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param web_view cast=(WebKitWebView *)
+ * @param script cast=(const gchar *)
+ */
+public static final native void _webkit_web_view_execute_script (int /*long*/ web_view, byte[] script);
+public static final void webkit_web_view_execute_script (int /*long*/ web_view, byte[] script) {
+	lock.lock();
+	try {
+		_webkit_web_view_execute_script (web_view, script);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param web_view cast=(WebKitWebView *)
+ */
+public static final native int _webkit_web_view_get_load_status (int /*long*/ web_view);
+public static final int webkit_web_view_get_load_status (int /*long*/ web_view) {
+	lock.lock();
+	try {
+		return _webkit_web_view_get_load_status (web_view);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param web_view cast=(WebKitWebView *)
+ */
+public static final native int /*long*/ _webkit_web_view_get_main_frame (int /*long*/ web_view);
+public static final int /*long*/ webkit_web_view_get_main_frame (int /*long*/ web_view) {
+	lock.lock();
+	try {
+		return _webkit_web_view_get_main_frame (web_view);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param web_view cast=(WebKitWebView *)
+ */
+public static final native double _webkit_web_view_get_progress (int /*long*/ web_view);
+public static final double webkit_web_view_get_progress (int /*long*/ web_view) {
+	lock.lock();
+	try {
+		return _webkit_web_view_get_progress (web_view);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param web_view cast=(WebKitWebView *)
+ */
+public static final native int /*long*/ _webkit_web_view_get_settings (int /*long*/ web_view);
+public static final int /*long*/ webkit_web_view_get_settings (int /*long*/ web_view) {
+	lock.lock();
+	try {
+		return _webkit_web_view_get_settings (web_view);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param web_view cast=(WebKitWebView *)
+ */
+public static final native int /*long*/ _webkit_web_view_get_title (int /*long*/ web_view);
+public static final int /*long*/ webkit_web_view_get_title (int /*long*/ web_view) {
+	lock.lock();
+	try {
+		return _webkit_web_view_get_title (web_view);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param web_view cast=(WebKitWebView *)
+ */
+public static final native int /*long*/ _webkit_web_view_get_uri (int /*long*/ web_view);
+public static final int /*long*/ webkit_web_view_get_uri (int /*long*/ web_view) {
+	lock.lock();
+	try {
+		return _webkit_web_view_get_uri (web_view);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param web_view cast=(WebKitWebView *)
+ */
+public static final native int /*long*/ _webkit_web_view_get_window_features (int /*long*/ web_view);
+public static final int /*long*/ webkit_web_view_get_window_features (int /*long*/ web_view) {
+	lock.lock();
+	try {
+		return _webkit_web_view_get_window_features (web_view);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param web_view cast=(WebKitWebView *)
+ */
+public static final native void _webkit_web_view_go_back (int /*long*/ web_view);
+public static final void webkit_web_view_go_back (int /*long*/ web_view) {
+	lock.lock();
+	try {
+		_webkit_web_view_go_back (web_view);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param web_view cast=(WebKitWebView *)
+ */
+public static final native void _webkit_web_view_go_forward (int /*long*/ web_view);
+public static final void webkit_web_view_go_forward (int /*long*/ web_view) {
+	lock.lock();
+	try {
+		_webkit_web_view_go_forward (web_view);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param web_view cast=(WebKitWebView *)
+ * @param content cast=(const gchar *)
+ * @param mime_type cast=(const gchar *)
+ * @param encoding cast=(const gchar *)
+ * @param base_uri cast=(const gchar *)
+ */
+public static final native void _webkit_web_view_load_string (int /*long*/ web_view, byte[] content, byte[] mime_type, byte[] encoding, byte[] base_uri);
+public static final void webkit_web_view_load_string (int /*long*/ web_view, byte[] content, byte[] mime_type, byte[] encoding, byte[] base_uri) {
+	lock.lock();
+	try {
+		_webkit_web_view_load_string (web_view, content, mime_type, encoding, base_uri);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param web_view cast=(WebKitWebView *)
+ * @param uri cast=(const gchar *)
+ */
+public static final native void _webkit_web_view_load_uri (int /*long*/ web_view, byte[] uri);
+public static final void webkit_web_view_load_uri (int /*long*/ web_view, byte[] uri) {
+	lock.lock();
+	try {
+		_webkit_web_view_load_uri (web_view, uri);
+	} finally {
+		lock.unlock();
+	}
+}
+
+public static final native int /*long*/ _webkit_web_view_new ();
+public static final int /*long*/ webkit_web_view_new () {
+	lock.lock();
+	try {
+		return _webkit_web_view_new ();
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param web_view cast=(WebKitWebView *)
+ */
+public static final native void _webkit_web_view_reload (int /*long*/ web_view);
+public static final void webkit_web_view_reload (int /*long*/ web_view) {
+	lock.lock();
+	try {
+		_webkit_web_view_reload (web_view);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/**
+ * @param web_view cast=(WebKitWebView *)
+ */
+public static final native void _webkit_web_view_stop_loading (int /*long*/ web_view);
+public static final void webkit_web_view_stop_loading (int /*long*/ web_view) {
+	lock.lock();
+	try {
+		_webkit_web_view_stop_loading (web_view);
+	} finally {
+		lock.unlock();
+	}
+}
+
+/* --------------------- start SWT natives --------------------- */
+
+public static final native int JSClassDefinition_sizeof ();
+
+/**
+ * @param dest cast=(void *)
+ * @param src cast=(const void *),flags=no_out
+ * @param size cast=(size_t)
+ */
+public static final native void memmove (int /*long*/ dest, JSClassDefinition src, int /*long*/ size);
+
+}
diff --git a/org/eclipse/swt/layout/GridData.java b/org/eclipse/swt/layout/GridData.java
index d26c60c..3d0bac8 100644
--- a/org/eclipse/swt/layout/GridData.java
+++ b/org/eclipse/swt/layout/GridData.java
@@ -26,11 +26,19 @@ import org.eclipse.swt.widgets.*;
  * 		gridData.horizontalAlignment = GridData.FILL;
  * 		gridData.grabExcessHorizontalSpace = true;
  * 		button1.setLayoutData(gridData);
+ * 
+ * 		gridData = new GridData();
+ * 		gridData.horizontalAlignment = GridData.FILL;
+ * 		gridData.verticalAlignment = GridData.FILL;
+ * 		gridData.grabExcessHorizontalSpace = true;
+ * 		gridData.grabExcessVerticalSpace = true;
+ * 		gridData.horizontalSpan = 2;
+ * 		button2.setLayoutData(gridData);
  * </pre>
- * The second is to take advantage of convenience style bits defined 
- * by <code>GridData</code>:
+ * The second is to take advantage of <code>GridData</code> convenience constructors, for example: 
  * <pre>
- *      button1.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
+ *      button1.setLayoutData(new GridData (SWT.FILL, SWT.CENTER, true, false));
+ *      button2.setLayoutData(new GridData (SWT.FILL, SWT.FILL, true, true, 2, 1));
  * </pre>
  * </p>
  * <p>
diff --git a/org/eclipse/swt/printing/PrintDialog.java b/org/eclipse/swt/printing/PrintDialog.java
index f8bc7cb..03cbb14 100644
--- a/org/eclipse/swt/printing/PrintDialog.java
+++ b/org/eclipse/swt/printing/PrintDialog.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -110,6 +110,7 @@ public PrintDialog (Shell parent, int style) {
  * @since 3.4
  */
 public void setPrinterData(PrinterData data) {
+	if (data == null) data = new PrinterData();
 	this.printerData = data;
 }
 
@@ -354,7 +355,11 @@ public PrinterData open() {
 		OS.gtk_print_unix_dialog_set_settings(handle, settings);
 		OS.gtk_print_unix_dialog_set_page_setup(handle, page_setup);
 		OS.g_object_unref(settings);
-		OS.g_object_unref(page_setup);		
+		OS.g_object_unref(page_setup);
+		if (OS.GTK_VERSION >= OS.VERSION (2, 10, 0)) {
+			int /*long*/ group = OS.gtk_window_get_group(0);
+			OS.gtk_window_group_add_window (group, handle);
+		}
 		OS.gtk_window_set_modal(handle, true);
 		PrinterData data = null;
 		//TODO: Handle 'Print Preview' (GTK_RESPONSE_APPLY).
diff --git a/org/eclipse/swt/printing/Printer.java b/org/eclipse/swt/printing/Printer.java
index 8ff2500..0812440 100644
--- a/org/eclipse/swt/printing/Printer.java
+++ b/org/eclipse/swt/printing/Printer.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -367,6 +367,8 @@ public Font getSystemFont () {
  *
  * @param data the platform specific GC data 
  * @return the platform specific GC handle
+ * 
+ * @noreference This method is not intended to be referenced by clients.
  */
 public int /*long*/ internal_new_GC(GCData data) {
 	GdkVisual visual = new GdkVisual ();
@@ -407,6 +409,8 @@ public int /*long*/ internal_new_GC(GCData data) {
  *
  * @param hDC the platform specific GC handle
  * @param data the platform specific GC data 
+ * 
+ * @noreference This method is not intended to be referenced by clients.
  */
 public void internal_dispose_GC(int /*long*/ gdkGC, GCData data) {
 	if (data != null) isGCCreated = false;
@@ -501,6 +505,8 @@ public void endJob() {
 	if (printJob == 0) return;
 	Cairo.cairo_surface_finish(surface);
 	OS.gtk_print_job_send(printJob, 0, 0, 0);
+	OS.g_object_unref(printJob);
+	printJob = 0;
 }
 
 /**
@@ -514,8 +520,9 @@ public void cancelJob() {
 	checkDevice();
 	if (printJob == 0) return;
 	//TODO: Need to implement (waiting on gtk bug 339323) 
-	//OS.g_object_unref(printJob);
-	//printJob = 0;
+	Cairo.cairo_surface_finish(surface);
+	OS.g_object_unref(printJob);
+	printJob = 0;
 }
 
 /**
diff --git a/org/eclipse/swt/printing/PrinterData.java b/org/eclipse/swt/printing/PrinterData.java
index c9930c8..98fc552 100644
--- a/org/eclipse/swt/printing/PrinterData.java
+++ b/org/eclipse/swt/printing/PrinterData.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -69,13 +69,13 @@ public final class PrinterData extends DeviceData {
 	 * the start page of a page range, used when scope is PAGE_RANGE.
 	 * This value can be from 1 to the maximum number of pages for the platform.
 	 */
-	public int startPage = 0;
+	public int startPage = 1;
 
 	/**
 	 * the end page of a page range, used when scope is PAGE_RANGE.
 	 * This value can be from 1 to the maximum number of pages for the platform.
 	 */
-	public int endPage = 0;
+	public int endPage = 1;
 	
 	/**
 	 * whether or not the print job should go to a file
diff --git a/org/eclipse/swt/program/Program.java b/org/eclipse/swt/program/Program.java
index 57456d5..6f78ce2 100644
--- a/org/eclipse/swt/program/Program.java
+++ b/org/eclipse/swt/program/Program.java
@@ -36,12 +36,15 @@ public final class Program {
 	String iconPath;
 	Display display;
 
-	/* Gnome specific
+	/* Gnome & GIO specific
 	 * true if command expects a URI
 	 * false if expects a path
 	 */
 	boolean gnomeExpectUri;
 	
+	static int /*long*/ modTime;
+	static Hashtable mimeTable;
+	
 	static int /*long*/ cdeShell;
 
 	static final String[] CDE_ICON_EXT = { ".m.pm",   ".l.pm",   ".s.pm",   ".t.pm" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
@@ -53,7 +56,8 @@ public final class Program {
 	static final int DESKTOP_UNKNOWN = 0;
 	static final int DESKTOP_GNOME = 1;
 	static final int DESKTOP_GNOME_24 = 2;
-	static final int DESKTOP_CDE = 3;
+	static final int DESKTOP_GIO = 3;
+	static final int DESKTOP_CDE = 4;
 	static final int PREFERRED_ICON_SIZE = 16;
 	
 /**
@@ -107,19 +111,31 @@ static int getDesktop(final Display display) {
 					 * Note.  gnome_icon_theme_new uses g_object_new to allocate the
 					 * data it returns. Use g_object_unref to free the pointer it returns.
 					 */
-					if (gnomeIconTheme.value != 0) GNOME.g_object_unref(gnomeIconTheme.value);
+					if (gnomeIconTheme.value != 0) OS.g_object_unref(gnomeIconTheme.value);
 				}
 			});
-			/* Check for libgnomevfs-2 version 2.4 */
-			byte[] buffer = Converter.wcsToMbcs(null, "libgnomevfs-2.so.0", true);
-			int /*long*/ libgnomevfs = OS.dlopen(buffer, OS.RTLD_LAZY);
-			if (libgnomevfs != 0) {
-				buffer = Converter.wcsToMbcs(null, "gnome_vfs_url_show", true);
-				int /*long*/ gnome_vfs_url_show = OS.dlsym(libgnomevfs, buffer);
-				if (gnome_vfs_url_show != 0) {
-					desktop = DESKTOP_GNOME_24;
+			/* Check for the existence of libgio libraries */
+			byte[] buffer = Converter.wcsToMbcs(null, "libgio-2.0.so.0", true);
+			int /*long*/ libgio = OS.dlopen(buffer, OS.RTLD_LAZY);
+			if (libgio != 0) {
+				buffer = Converter.wcsToMbcs(null, "g_app_info_launch_default_for_uri", true);
+				int /*long*/ g_app_info_launch_default_for_uri = OS.dlsym(libgio, buffer);
+				if (g_app_info_launch_default_for_uri != 0) {
+					desktop = DESKTOP_GIO;
+				}
+				OS.dlclose(libgio);
+			} else {
+				/* Check for libgnomevfs-2 version 2.4 */
+				buffer = Converter.wcsToMbcs(null, "libgnomevfs-2.so.0", true);
+				int /*long*/ libgnomevfs = OS.dlopen(buffer, OS.RTLD_LAZY);
+				if (libgnomevfs != 0) {
+					buffer = Converter.wcsToMbcs(null, "gnome_vfs_url_show", true);
+					int /*long*/ gnome_vfs_url_show = OS.dlsym(libgnomevfs, buffer);
+					if (gnome_vfs_url_show != 0) {
+						desktop = DESKTOP_GNOME_24;
+					}
+					OS.dlclose(libgnomevfs);
 				}
-				OS.dlclose(libgnomevfs);
 			}
 		}
 	}
@@ -293,6 +309,12 @@ static boolean cde_init(Display display) {
 	return initOK;
 }
 
+static boolean cde_isExecutable(String fileName) {
+	byte [] fileNameBuffer = Converter.wcsToMbcs(null, fileName, true);
+	return OS.access(fileNameBuffer, OS.X_OK) == 0;
+	//TODO find the content type of the file and check if it is executable
+}
+
 static String[] parseCommand(String cmd) {
 	Vector args = new Vector();
 	int sIndex = 0;
@@ -534,6 +556,25 @@ static boolean gnome_init() {
 	}
 }
 
+static boolean gnome_isExecutable(String fileName) {
+	/* check if the file is executable */
+	byte [] fileNameBuffer = Converter.wcsToMbcs(null, fileName, true);
+	if (!GNOME.gnome_vfs_is_executable_command_string(fileNameBuffer)) return false;
+	
+	/* check if the mime type is executable */
+	int /*long*/ uri = GNOME.gnome_vfs_make_uri_from_input(fileNameBuffer);
+	int /*long*/ mimeType = GNOME.gnome_vfs_get_mime_type(uri);
+	GNOME.g_free(uri);
+	
+	byte[] exeType = Converter.wcsToMbcs (null, "application/x-executable", true); //$NON-NLS-1$
+	boolean result = GNOME.gnome_vfs_mime_type_get_equivalence(mimeType, exeType) != GNOME.GNOME_VFS_MIME_UNRELATED;
+	if (!result) {
+		byte [] shellType = Converter.wcsToMbcs (null, "application/x-shellscript", true); //$NON-NLS-1$
+		result = GNOME.gnome_vfs_mime_type_get_equivalence(mimeType, shellType) == GNOME.GNOME_VFS_MIME_IDENTICAL;
+	}
+	return result;
+}
+
 /**
  * Finds the program that is associated with an extension.
  * The extension may or may not begin with a '.'.  Note that
@@ -562,6 +603,7 @@ static Program findProgram(Display display, String extension) {
 	int desktop = getDesktop(display);
 	String mimeType = null;
 	switch (desktop) {
+		case DESKTOP_GIO: mimeType = gio_getMimeType(extension); break;
 		case DESKTOP_GNOME_24:
 		case DESKTOP_GNOME: mimeType = gnome_getMimeType(extension); break;
 		case DESKTOP_CDE: mimeType = cde_getMimeType(extension); break;
@@ -569,7 +611,8 @@ static Program findProgram(Display display, String extension) {
 	if (mimeType == null) return null;
 	Program program = null;
 	switch (desktop) {
-		case DESKTOP_GNOME_24:
+		case DESKTOP_GIO: program = gio_getProgram(display, mimeType); break;
+		case DESKTOP_GNOME_24: 
 		case DESKTOP_GNOME: program = gnome_getProgram(display, mimeType); break;
 		case DESKTOP_CDE: program = cde_getProgram(display, mimeType); break;
 	}
@@ -595,6 +638,7 @@ static String[] getExtensions(Display display) {
 	int desktop = getDesktop(display);
 	Hashtable mimeInfo = null;
 	switch (desktop) {
+		case DESKTOP_GIO: return gio_getExtensions();
 		case DESKTOP_GNOME_24: break;
 		case DESKTOP_GNOME: mimeInfo = gnome_getMimeInfo(); break;
 		case DESKTOP_CDE: mimeInfo = cde_getDataTypeInfo(); break;
@@ -641,6 +685,7 @@ static Program[] getPrograms(Display display) {
 	int desktop = getDesktop(display);
 	Hashtable mimeInfo = null;
 	switch (desktop) {
+		case DESKTOP_GIO: return gio_getPrograms(display);
 		case DESKTOP_GNOME_24: break;
 		case DESKTOP_GNOME: mimeInfo = gnome_getMimeInfo(); break;
 		case DESKTOP_CDE: mimeInfo = cde_getDataTypeInfo(); break;
@@ -664,6 +709,306 @@ static Program[] getPrograms(Display display) {
 	return programList;
 }
 
+ImageData gio_getImageData() {
+	if (iconPath == null) return null;
+	ImageData data = null;
+	int /*long*/ icon_theme =OS.gtk_icon_theme_get_default();
+	byte[] icon = Converter.wcsToMbcs (null, iconPath, true);
+	int /*long*/ gicon = OS.g_icon_new_for_string(icon, null);
+	if (gicon != 0) {
+		int /*long*/ gicon_info = OS.gtk_icon_theme_lookup_by_gicon (icon_theme, gicon, 16/*size*/, 0);
+		if (gicon_info != 0) {
+			int /*long*/ pixbuf = OS.gtk_icon_info_load_icon(gicon_info, null);		
+			if (pixbuf != 0) {
+				int stride = OS.gdk_pixbuf_get_rowstride(pixbuf);
+				int /*long*/ pixels = OS.gdk_pixbuf_get_pixels(pixbuf);
+				int height = OS.gdk_pixbuf_get_height(pixbuf);
+				int width = OS.gdk_pixbuf_get_width(pixbuf);
+				boolean hasAlpha = OS.gdk_pixbuf_get_has_alpha(pixbuf);
+				byte[] srcData = new byte[stride * height];
+				OS.memmove(srcData, pixels, srcData.length);
+				OS.g_object_unref(pixbuf);
+				if (hasAlpha) {
+					PaletteData palette = new PaletteData(0xFF000000, 0xFF0000, 0xFF00);
+					data = new ImageData(width, height, 32, palette, 4, srcData);
+					data.bytesPerLine = stride;
+					int s = 3, a = 0;
+					byte[] alphaData = new byte[width*height];
+					for (int y=0; y<height; y++) {
+						for (int x=0; x<width; x++) {
+							alphaData[a++] = srcData[s];
+							srcData[s] = 0;
+							s+=4;
+						}
+					}
+					data.alphaData = alphaData;
+				} else {
+					PaletteData palette = new PaletteData(0xFF0000, 0xFF00, 0xFF);
+					data = new ImageData(width, height, 24, palette, 4, srcData);
+					data.bytesPerLine = stride;
+				}
+			}
+			OS.gtk_icon_info_free(gicon_info);
+		}
+		OS.g_object_unref(gicon);
+	}
+	return data;
+}
+
+static Hashtable gio_getMimeInfo() {
+	int /*long*/ mimeDatabase = 0, fileInfo = 0;
+	/*
+	* The file 'globs' contain the file extensions  
+	* associated to the mime-types. Each line that has 
+	* to be parsed corresponds to a different extension 
+	* of a mime-type. The template of such line is -
+	* application/pdf:*.pdf
+	*/
+	byte[] buffer = Converter.wcsToMbcs (null, "/usr/share/mime/globs", true);
+	mimeDatabase = OS.g_file_new_for_path (buffer);
+	int /*long*/ fileInputStream = OS.g_file_read (mimeDatabase, 0, 0);
+	try {
+		if (fileInputStream != 0) {
+			int /*long*/ [] modTimestamp = new int /*long*/ [2];
+			buffer = Converter.wcsToMbcs (null, "*", true);
+			fileInfo = OS.g_file_query_info(mimeDatabase, buffer, 0, 0, 0);
+			OS.g_file_info_get_modification_time(fileInfo, modTimestamp);
+			if (modTime != 0 && modTimestamp[0] == modTime) {
+				return mimeTable;
+			} else {
+				mimeTable = new Hashtable();
+				modTime = modTimestamp[0];
+				int /*long*/ reader = OS.g_data_input_stream_new (fileInputStream);
+				int[] length = new int[1];
+				
+				if (reader != 0) {
+					int /*long*/ linePtr = OS.g_data_input_stream_read_line (reader, length, 0, 0);
+					while (linePtr != 0) {
+						byte[] lineBytes = new byte[length[0]];
+						OS.memmove(lineBytes, linePtr, length[0]);
+						String line = new String (Converter.mbcsToWcs (null, lineBytes));
+			
+						int separatorIndex = line.indexOf (':');
+						if (separatorIndex > 0) {
+							Vector mimeTypes = new Vector ();
+						    String mimeType = line.substring (0, separatorIndex);
+							String extensionFormat = line.substring (separatorIndex+1);
+							int extensionIndex = extensionFormat.indexOf (".");
+							if (extensionIndex > 0) {
+								String extension = extensionFormat.substring (extensionIndex);
+								mimeTypes.add (mimeType);
+								if (mimeTable.containsKey (extension)) {
+									/*
+									 * If mimeType already exists, it is required to update
+									 * the existing key (mime-type) with the new extension. 
+									 */
+									Vector value = (Vector) mimeTable.get (extension);
+									mimeTypes.addAll (value);
+								}
+								mimeTable.put (extension, mimeTypes);
+							}
+						}
+						OS.g_free(linePtr);
+						linePtr = OS.g_data_input_stream_read_line (reader, length, 0, 0);
+					}
+				}
+				if (reader != 0) OS.g_object_unref (reader);
+				return mimeTable;
+			}
+		} 
+		return null;
+	} finally {
+		if (fileInfo != 0) OS.g_object_unref(fileInfo);
+		if (fileInputStream != 0) OS.g_object_unref(fileInputStream);
+		if (mimeDatabase != 0) 	OS.g_object_unref (mimeDatabase);
+	}
+}
+
+static String gio_getMimeType(String extension) {
+	String mimeType = null;
+	Hashtable h = gio_getMimeInfo();
+	if (h != null && h.containsKey(extension)) {
+		Vector mimeTypes = (Vector) h.get(extension);
+		mimeType = (String) mimeTypes.get(0);
+	}
+	return mimeType;
+}
+
+static Program gio_getProgram(Display display, String mimeType) {
+	Program program = null;
+	byte[] mimeTypeBuffer = Converter.wcsToMbcs (null, mimeType, true);
+	int /*long*/ application = OS.g_app_info_get_default_for_type (mimeTypeBuffer, false);
+	if (application != 0) {
+		program = gio_getProgram(display, application);
+	}
+	return program;
+}
+
+static Program gio_getProgram (Display display, int /*long*/ application) {
+	Program program = new Program();
+	program.display = display;
+	int length;
+	byte[] buffer;
+	int /*long*/ applicationName = OS.g_app_info_get_name (application);
+	if (applicationName != 0) {
+		length = OS.strlen (applicationName);
+		if (length > 0) {
+			buffer = new byte [length];
+			OS.memmove (buffer, applicationName, length);
+			program.name = new String (Converter.mbcsToWcs (null, buffer));
+		}
+	}
+	int /*long*/ applicationCommand = OS.g_app_info_get_executable (application);
+	if (applicationCommand != 0) {
+		length = OS.strlen (applicationCommand);
+		if (length > 0) {
+			buffer = new byte [length];
+			OS.memmove (buffer, applicationCommand, length);
+			program.command = new String (Converter.mbcsToWcs (null, buffer));
+		}
+	}
+	program.gnomeExpectUri = OS.g_app_info_supports_uris(application);
+	int /*long*/ icon = OS.g_app_info_get_icon(application);
+	if (icon != 0) {
+		int /*long*/ icon_name = OS.g_icon_to_string(icon);
+		if (icon_name != 0) {
+			length = OS.strlen(icon_name);
+			if (length > 0) {
+				buffer = new byte[length];
+				OS.memmove(buffer, icon_name, length);
+				program.iconPath = new String(Converter.mbcsToWcs(null, buffer));
+			}
+			OS.g_free(icon_name);
+		}
+		OS.g_object_unref(icon);
+	}
+	return program;
+}
+
+static Program[] gio_getPrograms(Display display) {
+	int /*long*/ applicationList = OS.g_app_info_get_all ();
+	int /*long*/ list = applicationList;
+	Program program;
+	Vector programs = new Vector();
+	while (list != 0) {
+		int /*long*/ application = OS.g_list_data(list);
+		if (application != 0) {
+			//TODO: Should the list be filtered or not?
+//			if (OS.g_app_info_should_show(application)) {
+				program = gio_getProgram(display, application);
+				if (program != null) programs.addElement(program);
+//			}
+		}
+		list = OS.g_list_next(list);
+	}
+	if (applicationList != 0) OS.g_list_free(applicationList);
+	Program[] programList = new Program[programs.size()];
+	for (int index = 0; index < programList.length; index++) {
+		programList[index] = (Program)programs.elementAt(index);
+	}
+	return programList;
+}
+
+static boolean gio_isExecutable(String fileName) {
+	byte[] fileNameBuffer = Converter.wcsToMbcs (null, fileName, true);
+	if (OS.g_file_test(fileNameBuffer, OS.G_FILE_TEST_IS_DIR)) return false;
+	if (!OS.g_file_test(fileNameBuffer, OS.G_FILE_TEST_IS_EXECUTABLE)) return false;
+	int /*long*/ file = OS.g_file_new_for_path (fileNameBuffer);
+	boolean result = false;
+	if (file != 0) {
+		byte[] buffer = Converter.wcsToMbcs (null, "*", true); //$NON-NLS-1$
+		int /*long*/ fileInfo = OS.g_file_query_info(file, buffer, 0, 0, 0);
+		if (fileInfo != 0) {
+			int /*long*/ contentType = OS.g_file_info_get_content_type(fileInfo);
+			if (contentType != 0) {
+				byte[] exeType = Converter.wcsToMbcs (null, "application/x-executable", true); //$NON-NLS-1$
+				result = OS.g_content_type_is_a(contentType, exeType);
+				if (!result) {
+					byte [] shellType = Converter.wcsToMbcs (null, "application/x-shellscript", true); //$NON-NLS-1$
+					result = OS.g_content_type_equals(contentType, shellType);
+				}
+			}
+			OS.g_object_unref(fileInfo);
+		}
+		OS.g_object_unref (file);
+	}
+	return result;
+}
+
+/**
+ * GNOME 2.4 - Launch the default program for the given file. 
+ */
+static boolean gio_launch(String fileName) {
+	boolean result = false;
+	byte[] fileNameBuffer = Converter.wcsToMbcs (null, fileName, true);
+	int /*long*/ file = OS.g_file_new_for_path (fileNameBuffer);
+	if (file != 0) {
+		int /*long*/ uri = OS.g_file_get_uri (file);
+		if (uri != 0) {
+			result = OS.g_app_info_launch_default_for_uri (uri, 0, 0);
+			OS.g_free(uri);
+		}
+		OS.g_object_unref (file);
+	}
+	return result;
+}
+
+/**
+ * GIO - Execute the program for the given file. 
+ */
+boolean gio_execute(String fileName) {
+	boolean result = false;
+	byte[] commandBuffer = Converter.wcsToMbcs (null, command, true);
+	byte[] nameBuffer = Converter.wcsToMbcs (null, name, true);
+	int /*long*/ application = OS.g_app_info_create_from_commandline(commandBuffer, nameBuffer, gnomeExpectUri
+				? OS.G_APP_INFO_CREATE_SUPPORTS_URIS : OS.G_APP_INFO_CREATE_NONE, 0);
+	if (application != 0) {
+		byte[] fileNameBuffer = Converter.wcsToMbcs (null, fileName, true);
+		int /*long*/ file = 0;
+		if (OS.g_app_info_supports_uris (application)) {
+			file = OS.g_file_new_for_uri (fileNameBuffer);
+		} else {
+			file = OS.g_file_new_for_path (fileNameBuffer);
+		}
+		if (file != 0) {
+			int /*long*/ list = OS.g_list_append (0, file);
+			result = OS.g_app_info_launch (application, list, 0, 0);
+			OS.g_list_free (list);
+			OS.g_object_unref (file);
+		}
+		OS.g_object_unref (application);
+	}
+	return result;
+}
+
+static String[] gio_getExtensions() {
+	Hashtable mimeInfo = gio_getMimeInfo();
+	if (mimeInfo == null) return new String[0];
+	/* Create a unique set of the file extensions. */
+	Vector extensions = new Vector();
+	Enumeration keys = mimeInfo.keys();
+	while (keys.hasMoreElements()) {
+		String extension = (String)keys.nextElement();
+		extensions.add(extension);
+	}
+	/* Return the list of extensions. */
+	String [] extStrings = new String[extensions.size()];
+	for (int index = 0; index < extensions.size(); index++) {
+		extStrings[index] = (String)extensions.elementAt(index);
+	}	
+	return extStrings;
+}
+
+static boolean isExecutable(Display display, String fileName) {
+	switch(getDesktop(display)) {
+		case DESKTOP_GIO: return gio_isExecutable(fileName);
+		case DESKTOP_GNOME_24:
+		case DESKTOP_GNOME: return gnome_isExecutable(fileName);
+		case DESKTOP_CDE: return false; //cde_isExecutable()
+	}
+	return false;
+}
+
 /**
  * Launches the operating system executable associated with the file or
  * URL (http:// or https://).  If the file is an executable then the
@@ -678,16 +1023,49 @@ static Program[] getPrograms(Display display) {
  * </ul>
  */
 public static boolean launch(String fileName) {
-	return launch(Display.getCurrent(), fileName);
+	return launch(Display.getCurrent(), fileName, null);
+}
+
+/**
+ * Launches the operating system executable associated with the file or
+ * URL (http:// or https://).  If the file is an executable then the
+ * executable is launched. The program is launched with the specified
+ * working directory only when the <code>workingDir</code> exists and
+ * <code>fileName</code> is an executable.
+ * Note that a <code>Display</code> must already exist to guarantee
+ * that this method returns an appropriate result.
+ *
+ * @param fileName the file name or program name or URL (http:// or https://)
+ * @param workingDir the name of the working directory or null
+ * @return <code>true</code> if the file is launched, otherwise <code>false</code>
+ * 
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_NULL_ARGUMENT when fileName is null</li>
+ * </ul>
+ * 
+ * @since 3.6
+ */
+public static boolean launch (String fileName, String workingDir) {
+	return launch(Display.getCurrent(), fileName, workingDir);
 }
 
 /*
  *  API: When support for multiple displays is added, this method will
  *       become public and the original method above can be deprecated.
  */
-static boolean launch (Display display, String fileName) {
+static boolean launch (Display display, String fileName, String workingDir) {
 	if (fileName == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
+	if (workingDir != null && isExecutable(display, fileName)) {
+		try {
+			Compatibility.exec (new String [] {fileName}, null, workingDir);
+			return true;
+		} catch (IOException e) {
+			return false;
+		}
+	}
 	switch (getDesktop (display)) {
+		case DESKTOP_GIO:
+			if (gio_launch (fileName)) return true;
 		case DESKTOP_GNOME_24:
 			if (gnome_24_launch (fileName)) return true;
 		default:
@@ -707,8 +1085,9 @@ static boolean launch (Display display, String fileName) {
 			}
 			break;
 	}
+	/* If the above launch attempts didn't launch the file, then try with exec().*/
 	try {
-		Compatibility.exec (fileName);
+		Compatibility.exec (new String [] {fileName}, null, workingDir);
 		return true;
 	} catch (IOException e) {
 		return false;
@@ -749,6 +1128,7 @@ public boolean execute(String fileName) {
 	if (fileName == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
 	int desktop = getDesktop(display);
 	switch (desktop) {
+		case DESKTOP_GIO: return gio_execute(fileName);
 		case DESKTOP_GNOME_24: return gnome_24_execute(fileName);
 		case DESKTOP_GNOME: return gnome_execute(fileName);
 		case DESKTOP_CDE: return cde_execute(fileName);
@@ -765,6 +1145,7 @@ public boolean execute(String fileName) {
  */
 public ImageData getImageData() {
 	switch (getDesktop(display)) {
+		case DESKTOP_GIO: return gio_getImageData();
 		case DESKTOP_GNOME_24:
 		case DESKTOP_GNOME: return gnome_getImageData();
 		case DESKTOP_CDE: return cde_getImageData();
diff --git a/org/eclipse/swt/widgets/Button.java b/org/eclipse/swt/widgets/Button.java
index 41802dc..f16b2d4 100644
--- a/org/eclipse/swt/widgets/Button.java
+++ b/org/eclipse/swt/widgets/Button.java
@@ -118,6 +118,12 @@ static int checkStyle (int style) {
  * <code>widgetSelected</code> is called when the control is selected by the user.
  * <code>widgetDefaultSelected</code> is not called.
  * </p>
+ * <p>
+ * When the <code>SWT.RADIO</code> style bit is set, the <code>widgetSelected</code> method is
+ * also called when the receiver loses selection because another item in the same radio group 
+ * was selected by the user. During <code>widgetSelected</code> the application can use
+ * <code>getSelection()</code> to determine the current selected state of the receiver.
+ * </p>
  *
  * @param listener the listener which should be notified
  *
@@ -407,7 +413,7 @@ int /*long*/ gtk_clicked (int /*long*/ widget) {
 			}
 		}
 	}
-	postEvent (SWT.Selection);
+	sendSelectionEvent (SWT.Selection);
 	return 0;
 }
 
@@ -650,7 +656,7 @@ boolean setRadioSelection (boolean value) {
 	if ((style & SWT.RADIO) == 0) return false;
 	if (getSelection () != value) {
 		setSelection (value);
-		postEvent (SWT.Selection);
+		sendSelectionEvent (SWT.Selection);
 	}
 	return true;
 }
diff --git a/org/eclipse/swt/widgets/Canvas.java b/org/eclipse/swt/widgets/Canvas.java
index ea6a149..3fd382c 100644
--- a/org/eclipse/swt/widgets/Canvas.java
+++ b/org/eclipse/swt/widgets/Canvas.java
@@ -96,10 +96,7 @@ public Canvas (Composite parent, int style) {
  * @since 3.2
  */
 public void drawBackground (GC gc, int x, int y, int width, int height) {
-	checkWidget ();
-	if (gc == null) error (SWT.ERROR_NULL_ARGUMENT);
-	if (gc.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
-	super.drawBackground (gc, x, y, width, height);
+	drawBackground (gc, x, y, width, height, 0, 0);
 }
 
 /**
@@ -211,12 +208,18 @@ void releaseChildren (boolean destroy) {
 	super.releaseChildren (destroy);
 }
 
+void reskinChildren (int flags) {
+	if (caret != null) caret.reskin (flags);
+	if (ime != null)  ime.reskin (flags);
+	super.reskinChildren (flags);
+}
+
 /**
  * Scrolls a rectangular area of the receiver by first copying 
  * the source area to the destination and then causing the area
  * of the source which is not covered by the destination to
  * be repainted. Children that intersect the rectangle are
- * optionally moved during the operation. In addition, outstanding
+ * optionally moved during the operation. In addition, all outstanding
  * paint events are flushed before the source area is copied to
  * ensure that the contents of the canvas are drawn correctly.
  *
diff --git a/org/eclipse/swt/widgets/ColorDialog.java b/org/eclipse/swt/widgets/ColorDialog.java
index 257f07a..1605c49 100644
--- a/org/eclipse/swt/widgets/ColorDialog.java
+++ b/org/eclipse/swt/widgets/ColorDialog.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -125,6 +125,10 @@ public RGB open () {
 			OS.g_list_free (pixbufs);
 		}
 	}
+	if (OS.GTK_VERSION >= OS.VERSION (2, 10, 0)) {
+		int /*long*/ group = OS.gtk_window_get_group(0);
+		OS.gtk_window_group_add_window (group, handle);
+	}
 	OS.gtk_window_set_modal (handle, true);
 	GtkColorSelectionDialog dialog = new GtkColorSelectionDialog ();
 	OS.memmove (dialog, handle);
diff --git a/org/eclipse/swt/widgets/Combo.java b/org/eclipse/swt/widgets/Combo.java
index 6e526d3..389aa23 100644
--- a/org/eclipse/swt/widgets/Combo.java
+++ b/org/eclipse/swt/widgets/Combo.java
@@ -42,7 +42,7 @@ import org.eclipse.swt.events.*;
  * <dt><b>Styles:</b></dt>
  * <dd>DROP_DOWN, READ_ONLY, SIMPLE</dd>
  * <dt><b>Events:</b></dt>
- * <dd>DefaultSelection, Modify, Selection, Verify</dd>
+ * <dd>DefaultSelection, Modify, Selection, Verify, OrientationChange</dd>
  * </dl>
  * <p>
  * Note: Only one of the styles DROP_DOWN and SIMPLE may be specified.
@@ -57,13 +57,13 @@ import org.eclipse.swt.events.*;
  * @noextend This class is not intended to be subclassed by clients.
  */
 public class Combo extends Composite {
-	int /*long*/ buttonHandle, entryHandle, listHandle, textRenderer, cellHandle, popupHandle;
-	int lastEventTime, visibleCount = 5;
+	int /*long*/ buttonHandle, entryHandle, listHandle, textRenderer, cellHandle, popupHandle, menuHandle;
+	int lastEventTime, visibleCount = 10;
 	int /*long*/ gdkEventKey = 0;
 	int fixStart = -1, fixEnd = -1;
 	String [] items = new String [0];
-	boolean ignoreSelect, lockText;
-
+	boolean ignoreSelect, lockText, selectionAdded;
+	int indexSelected;
 	/**
 	 * the operating system limit for the number of characters
 	 * that the text field in an instance of this class can hold
@@ -457,28 +457,16 @@ void createHandle (int index) {
 		display.setWarnings (warnings);
 		OS.gtk_cell_layout_pack_start (handle, textRenderer, true);
 		OS.gtk_cell_layout_set_attributes (handle, textRenderer, OS.text, 0, 0);
-
-		/*
-		* Feature in GTK.  There is no API to query the button
-		* handle from a combo box although it is possible to get the
-		* text field.  The button handle is needed to hook events.  The
-		* fix is to walk the combo tree and find the first child that is 
-		* an instance of button.
+ 		/*
+		* Feature in GTK. Toggle button creation differs between GTK versions. The 
+		* fix is to call size_request() to force the creation of the button 
+		* for those versions of GTK that defer the creation. 
 		*/
-		OS.gtk_container_forall (handle, display.allChildrenProc, 0);
-		if (display.allChildren != 0) {
-			int /*long*/ list = display.allChildren;
-			while (list != 0) {
-				int /*long*/ widget = OS.g_list_data (list);
-				if (OS.GTK_IS_BUTTON (widget)) {
-					buttonHandle = widget;
-					break;
-				}
-				list = OS.g_list_next (list);
-			}
-			OS.g_list_free (display.allChildren);
-			display.allChildren = 0;
+		if (OS.GTK_VERSION < OS.VERSION (2, 8, 0)) {
+			OS.gtk_widget_size_request(handle, new GtkRequisition());
 		}
+		if (popupHandle != 0) findMenuHandle ();
+		findButtonHandle ();
 		/*
 		* Feature in GTK. By default, read only combo boxes 
 		* process the RETURN key rather than allowing the 
@@ -563,6 +551,8 @@ void deregister () {
 	if (buttonHandle != 0) display.removeWidget (buttonHandle);
 	if (entryHandle != 0) display.removeWidget (entryHandle);
 	if (listHandle != 0) display.removeWidget (listHandle);
+	if (popupHandle != 0) display.removeWidget (popupHandle);
+	if (menuHandle != 0) display.removeWidget (menuHandle);
 	int /*long*/ imContext = imContext ();
 	if (imContext != 0) display.removeWidget (imContext);
 }
@@ -609,6 +599,48 @@ int /*long*/ findPopupHandle (int /*long*/ oldList) {
 	return hdl;
 }
 
+
+void findButtonHandle() {
+	/*
+	* Feature in GTK.  There is no API to query the button
+	* handle from a combo box although it is possible to get the
+	* text field.  The button handle is needed to hook events.  The
+	* fix is to walk the combo tree and find the first child that is 
+	* an instance of button.
+	*/
+	OS.gtk_container_forall (handle, display.allChildrenProc, 0);
+	if (display.allChildren != 0) {
+		int /*long*/ list = display.allChildren;
+		while (list != 0) {
+			int /*long*/ widget = OS.g_list_data (list);
+			if (OS.GTK_IS_BUTTON (widget)) {
+				buttonHandle = widget;
+				break;
+			}
+			list = OS.g_list_next (list);
+		}
+		OS.g_list_free (display.allChildren);
+		display.allChildren = 0;
+	}
+}
+
+void findMenuHandle() {
+	OS.gtk_container_forall (popupHandle, display.allChildrenProc, 0);
+	if (display.allChildren != 0) {
+	int /*long*/ list = display.allChildren;
+		while (list != 0) {
+		int /*long*/ widget = OS.g_list_data (list);
+		if (OS.G_OBJECT_TYPE (widget) == OS.GTK_TYPE_MENU ()) {
+			menuHandle = widget;
+			break;
+		}
+		list = OS.g_list_next (list);
+	}
+	OS.g_list_free (display.allChildren);
+	display.allChildren = 0;
+	}
+}
+	
 void fixModal (int /*long*/ group, int /*long*/ modalGroup) {
 	if (popupHandle != 0) {
 		if (group != 0) {
@@ -676,7 +708,7 @@ void hookEvents () {
 	}
 	int eventMask =	OS.GDK_POINTER_MOTION_MASK | OS.GDK_BUTTON_PRESS_MASK | 
 		OS.GDK_BUTTON_RELEASE_MASK;
- 	int /*long*/ [] handles = new int /*long*/ [] {buttonHandle, entryHandle, listHandle};
+ 	int /*long*/ [] handles = new int /*long*/ [] {buttonHandle, entryHandle, listHandle, menuHandle};
 	for (int i=0; i<handles.length; i++) {
 		int /*long*/ eventHandle = handles [i];
 		if (eventHandle != 0) {
@@ -709,6 +741,8 @@ void hookEvents () {
 		int blockMask =  OS.G_SIGNAL_MATCH_DATA | OS.G_SIGNAL_MATCH_ID;
 		OS.g_signal_handlers_block_matched (imContext, blockMask, id, 0, 0, 0, entryHandle);
 	}
+	
+	if (menuHandle != 0) OS.g_signal_connect_closure(menuHandle, OS.selection_done, display.closures[SELECTION_DONE], true);
 }
 
 int /*long*/ imContext () {
@@ -1105,7 +1139,7 @@ public int getVisibleItemCount () {
 }
 
 int /*long*/ gtk_activate (int /*long*/ widget) {
-	postEvent (SWT.DefaultSelection);
+	sendSelectionEvent (SWT.DefaultSelection);
 	return 0;
 }
 
@@ -1118,7 +1152,7 @@ int /*long*/ gtk_button_press_event (int /*long*/ widget, int /*long*/ event) {
 	if (OS.GTK_VERSION >= OS.VERSION (2, 4, 0)) {
 		GdkEventButton gdkEvent = new GdkEventButton ();
 		OS.memmove (gdkEvent, event, GdkEventButton.sizeof);
-		if (gdkEvent.type == OS.GDK_BUTTON_PRESS && gdkEvent.button == 1 && (style & SWT.READ_ONLY) != 0) {
+		if (gdkEvent.type == OS.GDK_BUTTON_PRESS && gdkEvent.button == 1) {
 			return gtk_button_press_event(widget, event, false);
 		}
 	}
@@ -1144,7 +1178,8 @@ int /*long*/ gtk_changed (int /*long*/ widget) {
 			* item and not matching the item as the user types.
 			*/
 			int index = OS.gtk_combo_box_get_active (handle);
-			if (index != -1) postEvent (SWT.Selection);
+			if (index != -1) sendSelectionEvent (SWT.Selection);
+			indexSelected = -1;
 			return 0;
 		}
 	} else {
@@ -1156,7 +1191,7 @@ int /*long*/ gtk_changed (int /*long*/ widget) {
 			String text = new String (Converter.mbcsToWcs (null, buffer));
 			for (int i = 0; i < items.length; i++) {
 				if (items [i].equals (text)) {
-					postEvent (SWT.Selection);
+					sendSelectionEvent (SWT.Selection);
 					break;
 				}
 			}
@@ -1234,6 +1269,7 @@ int /*long*/ gtk_delete_text (int /*long*/ widget, int /*long*/ start_pos, int /
 		return 0;
 	}
 	if (!hooks (SWT.Verify) && !filters (SWT.Verify)) return 0;
+	if (end_pos == -1) end_pos = OS.g_utf8_strlen (OS.gtk_entry_get_text (entryHandle), -1);
 	String newText = verifyText ("", (int)/*64*/start_pos, (int)/*64*/end_pos);
 	if (newText == null) {
 		OS.g_signal_stop_emission_by_name (entryHandle, OS.delete_text);
@@ -1272,10 +1308,23 @@ int /*long*/ gtk_event_after (int /*long*/ widget, int /*long*/ gdkEvent)  {
 		OS.memmove (event, gdkEvent, GdkEvent.sizeof);
 		switch (event.type) {
 			case OS.GDK_BUTTON_PRESS: {
+				if (OS.GTK_VERSION < OS.VERSION (2, 8, 0) && !selectionAdded) {
+					int /*long*/ grabHandle = OS.gtk_grab_get_current ();
+					if (grabHandle != 0) {
+						if (OS.G_OBJECT_TYPE (grabHandle) == OS.GTK_TYPE_MENU ()) {
+							menuHandle = grabHandle;
+							OS.g_signal_connect_closure_by_id (menuHandle, display.signalIds [BUTTON_RELEASE_EVENT], 0, display.closures [BUTTON_RELEASE_EVENT], false);
+							OS.g_signal_connect_closure_by_id (menuHandle, display.signalIds [BUTTON_RELEASE_EVENT], 0, display.closures [BUTTON_RELEASE_EVENT_INVERSE], true);
+							OS.g_signal_connect_closure (menuHandle, OS.selection_done, display.closures [SELECTION_DONE], false);
+							display.addWidget (menuHandle, this);
+							selectionAdded = true;
+						}
+					}
+				}
 				GdkEventButton gdkEventButton = new GdkEventButton ();
 				OS.memmove (gdkEventButton, gdkEvent, GdkEventButton.sizeof);
 				if (gdkEventButton.button == 1) {
-					if ((style & SWT.READ_ONLY) != 0 && !sendMouseEvent (SWT.MouseDown, gdkEventButton.button, display.clickCount, 0, false, gdkEventButton.time, gdkEventButton.x_root, gdkEventButton.y_root, false, gdkEventButton.state)) {
+					if (!sendMouseEvent (SWT.MouseDown, gdkEventButton.button, display.clickCount, 0, false, gdkEventButton.time, gdkEventButton.x_root, gdkEventButton.y_root, false, gdkEventButton.state)) {
 						return 1;
 					}
 					if (OS.GTK_VERSION >= OS.VERSION (2, 6, 0)) {
@@ -1358,7 +1407,11 @@ int /*long*/ gtk_insert_text (int /*long*/ widget, int /*long*/ new_text, int /*
 
 int /*long*/ gtk_key_press_event (int /*long*/ widget, int /*long*/ event) {
 	int /*long*/ result = super.gtk_key_press_event (widget, event);
-	if (result != 0) fixIM ();
+	if (result != 0) {
+	    gdkEventKey = 0;
+	    fixIM ();
+	    return result;
+	}
 	if (gdkEventKey == -1) result = 1;
 	gdkEventKey = 0;
 	if (OS.GTK_VERSION >= OS.VERSION (2, 4, 0) && (style & SWT.READ_ONLY) == 0) {
@@ -1411,6 +1464,16 @@ int /*long*/ gtk_populate_popup (int /*long*/ widget, int /*long*/ menu) {
 	return 0;
 }
 
+int /*long*/ gtk_selection_done(int /*long*/ menushell) {
+	int index = OS.gtk_combo_box_get_active (handle);
+	if (indexSelected == -1){
+		indexSelected = index;
+	}
+	else if (index != -1 && indexSelected == index) {
+		sendSelectionEvent (SWT.Selection);
+	}
+	return 0;
+}
 /**
  * Searches the receiver's list starting at the first item
  * (index 0) until an item is found that is equal to the 
@@ -1511,6 +1574,8 @@ void register () {
 	if (buttonHandle != 0) display.addWidget (buttonHandle, this);
 	if (entryHandle != 0) display.addWidget (entryHandle, this);
 	if (listHandle != 0) display.addWidget (listHandle, this);
+	if (popupHandle != 0) display.addWidget (popupHandle, this);
+	if (menuHandle != 0) display.addWidget (menuHandle, this);
 	int /*long*/ imContext = imContext ();
 	if (imContext != 0) display.addWidget (imContext, this);
 }
@@ -1785,6 +1850,7 @@ void setBackgroundColor (GdkColor color) {
 	super.setBackgroundColor (color);
 	if (OS.GTK_VERSION >= OS.VERSION (2, 4, 0)) {
 		if (entryHandle != 0) OS.gtk_widget_modify_base (entryHandle, 0, color);
+		if (cellHandle != 0) OS.g_object_set (cellHandle, OS.background_gdk, color, 0);
 		OS.g_object_set (textRenderer, OS.background_gdk, color, 0);
 	} else {
 		OS.gtk_widget_modify_base (entryHandle, 0, color);
diff --git a/org/eclipse/swt/widgets/Composite.java b/org/eclipse/swt/widgets/Composite.java
index 62cda31..483032f 100644
--- a/org/eclipse/swt/widgets/Composite.java
+++ b/org/eclipse/swt/widgets/Composite.java
@@ -210,6 +210,7 @@ int /*long*/ childStyle () {
 
 public Point computeSize (int wHint, int hHint, boolean changed) {
 	checkWidget ();
+	display.runSkin();
 	if (wHint != SWT.DEFAULT && wHint < 0) wHint = 0;
 	if (hHint != SWT.DEFAULT && hHint < 0) hHint = 0;
 	Point size;
@@ -250,7 +251,7 @@ Widget [] computeTabList () {
 }
 
 void createHandle (int index) {
-	state |= HANDLE | CANVAS;
+	state |= HANDLE | CANVAS | CHECK_SUBWINDOW;
 	boolean scrolled = (style & (SWT.H_SCROLL | SWT.V_SCROLL)) != 0;
 	if (!scrolled) state |= THEME_BACKGROUND;
 	createHandle (index, true, scrolled || (style & SWT.BORDER) != 0);
@@ -329,7 +330,37 @@ void deregister () {
 	if (socketHandle != 0) display.removeWidget (socketHandle);
 }
 
-void drawBackground (GC gc, int x, int y, int width, int height) {
+/** 
+ * Fills the interior of the rectangle specified by the arguments,
+ * with the receiver's background. 
+ *
+ * <p>The <code>offsetX</code> and <code>offsetY</code> are used to map from
+ * the <code>gc</code> origin to the origin of the parent image background. This is useful
+ * to ensure proper alignment of the image background.</p>
+ * 
+ * @param gc the gc where the rectangle is to be filled
+ * @param x the x coordinate of the rectangle to be filled
+ * @param y the y coordinate of the rectangle to be filled
+ * @param width the width of the rectangle to be filled
+ * @param height the height of the rectangle to be filled
+ * @param offsetX the image background x offset 
+ * @param offsetY the image background y offset
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_NULL_ARGUMENT - if the gc is null</li>
+ *    <li>ERROR_INVALID_ARGUMENT - if the gc has been disposed</li>
+ * </ul>
+ * @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>
+ * 
+ * @since 3.6
+ */
+public void drawBackground (GC gc, int x, int y, int width, int height, int offsetX, int offsetY) {
+	checkWidget ();
+	if (gc == null) error (SWT.ERROR_NULL_ARGUMENT);
+	if (gc.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
 	Control control = findBackgroundControl ();
 	if (control != null) {
 		GCData data = gc.getGCData ();
@@ -338,9 +369,9 @@ void drawBackground (GC gc, int x, int y, int width, int height) {
 			Cairo.cairo_save (cairo);
 			if (control.backgroundImage != null) {
 				Point pt = display.map (this, control, 0, 0);
-				Cairo.cairo_translate (cairo, -pt.x, -pt.y);
-				x += pt.x;
-				y += pt.y;
+				Cairo.cairo_translate (cairo, -pt.x - offsetX, -pt.y - offsetY);
+				x += pt.x + offsetX;
+				y += pt.y + offsetY;
 				int /*long*/ xDisplay = OS.GDK_DISPLAY ();
 				int /*long*/ xVisual = OS.gdk_x11_visual_get_xvisual (OS.gdk_visual_get_system());
 				int /*long*/ drawable = control.backgroundImage.pixmap;
@@ -373,7 +404,7 @@ void drawBackground (GC gc, int x, int y, int width, int height) {
 			if (control.backgroundImage != null) {
 				Point pt = display.map (this, control, 0, 0);
 				OS.gdk_gc_set_fill (gdkGC, OS.GDK_TILED);
-				OS.gdk_gc_set_ts_origin (gdkGC, -pt.x, -pt.y);
+				OS.gdk_gc_set_ts_origin (gdkGC, -pt.x - offsetX, -pt.y - offsetY);
 				OS.gdk_gc_set_tile (gdkGC, control.backgroundImage.pixmap);
 				OS.gdk_draw_rectangle (data.drawable, gdkGC, 1, x, y, width, height);
 				OS.gdk_gc_set_fill (gdkGC, values.fill);
@@ -951,42 +982,119 @@ public void layout (boolean changed, boolean all) {
 public void layout (Control [] changed) {
 	checkWidget ();
 	if (changed == null) error (SWT.ERROR_INVALID_ARGUMENT);
-	for (int i=0; i<changed.length; i++) {
-		Control control = changed [i];
-		if (control == null) error (SWT.ERROR_INVALID_ARGUMENT);
-		if (control.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
-		boolean ancestor = false;
-		Composite composite = control.parent;
-		while (composite != null) {
-			ancestor = composite == this;
-			if (ancestor) break;
-			composite = composite.parent;
+	layout (changed, SWT.NONE);
+}
+
+/**
+ * Forces a lay out (that is, sets the size and location) of all widgets that 
+ * are in the parent hierarchy of the changed control up to and including the 
+ * receiver. 
+ * <p>
+ * The parameter <code>flags</code> may be a combination of:
+ * <dl>
+ * <dt><b>SWT.ALL</b></dt>
+ * <dd>all children in the receiver's widget tree should be laid out</dd>
+ * <dt><b>SWT.CHANGED</b></dt>
+ * <dd>the layout must flush its caches</dd>
+ * <dt><b>SWT.DEFER</b></dt>
+ * <dd>layout will be deferred</dd>
+ * </dl>
+ * </p>
+ * <p>
+ * When the <code>changed</code> array is specified, the flags <code>SWT.ALL</code>
+ * and <code>SWT.CHANGED</code> have no effect. In this case, the layouts in the 
+ * hierarchy must not rely on any information cached about the changed control or
+ * any of its ancestors.  The layout may (potentially) optimize the
+ * work it is doing by assuming that none of the peers of the changed
+ * control have changed state since the last layout.
+ * If an ancestor does not have a layout, skip it.
+ * </p>
+ * <p>
+ * When the <code>changed</code> array is not specified, the flag <code>SWT.ALL</code>
+ * indicates that the whole widget tree should be laid out. And the flag
+ * <code>SWT.CHANGED</code> indicates that the layouts should flush any cached
+ * information for all controls that are laid out. 
+ * </p>
+ * <p>
+ * The <code>SWT.DEFER</code> flag always causes the layout to be deferred by
+ * calling <code>Composite.setLayoutDeferred(true)</code> and scheduling a call
+ * to <code>Composite.setLayoutDeferred(false)</code>, which will happen when
+ * appropriate (usually before the next event is handled). When this flag is set,
+ * the application should not call <code>Composite.setLayoutDeferred(boolean)</code>.
+ * </p>
+ * <p>
+ * Note: Layout is different from painting. If a child is
+ * moved or resized such that an area in the parent is
+ * exposed, then the parent will paint. If no child is
+ * affected, the parent will not paint.
+ * </p>
+ * 
+ * @param changed a control that has had a state change which requires a recalculation of its size
+ * @param flags the flags specifying how the layout should happen
+ * 
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_INVALID_ARGUMENT - if any of the controls in changed is null or has been disposed</li> 
+ *    <li>ERROR_INVALID_PARENT - if any control in changed is not in the widget tree of the receiver</li>
+ * </ul>
+ * @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>
+ *
+ * @since 3.6
+ */
+public void layout (Control [] changed, int flags) {
+	checkWidget ();
+	if (changed != null) {
+		for (int i=0; i<changed.length; i++) {
+			Control control = changed [i];
+			if (control == null) error (SWT.ERROR_INVALID_ARGUMENT);
+			if (control.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
+			boolean ancestor = false;
+			Composite composite = control.parent;
+			while (composite != null) {
+				ancestor = composite == this;
+				if (ancestor) break;
+				composite = composite.parent;
+			}
+			if (!ancestor) error (SWT.ERROR_INVALID_PARENT);
 		}
-		if (!ancestor) error (SWT.ERROR_INVALID_PARENT);
-	}
-	int updateCount = 0;
-	Composite [] update = new Composite [16];
-	for (int i=0; i<changed.length; i++) {
-		Control child = changed [i];
-		Composite composite = child.parent;
-		while (child != this) {
-			if (composite.layout != null) {
-				composite.state |= LAYOUT_NEEDED;
-				if (!composite.layout.flushCache (child)) {
-					composite.state |= LAYOUT_CHANGED;
+		int updateCount = 0;
+		Composite [] update = new Composite [16];
+		for (int i=0; i<changed.length; i++) {
+			Control child = changed [i];
+			Composite composite = child.parent;
+			while (child != this) {
+				if (composite.layout != null) {
+					composite.state |= LAYOUT_NEEDED;
+					if (!composite.layout.flushCache (child)) {
+						composite.state |= LAYOUT_CHANGED;
+					}
 				}
+				if (updateCount == update.length) {
+					Composite [] newUpdate = new Composite [update.length + 16];
+					System.arraycopy (update, 0, newUpdate, 0, update.length);
+					update = newUpdate;
+				}
+				child = update [updateCount++] = composite;
+				composite = child.parent;
 			}
-			if (updateCount == update.length) {
-				Composite [] newUpdate = new Composite [update.length + 16];
-				System.arraycopy (update, 0, newUpdate, 0, update.length);
-				update = newUpdate;
-			}
-			child = update [updateCount++] = composite;
-			composite = child.parent;
 		}
-	}
-	for (int i=updateCount-1; i>=0; i--) {
-		update [i].updateLayout (false);
+		if ((flags & SWT.DEFER) != 0) {
+			setLayoutDeferred (true);
+			display.addLayoutDeferred (this);
+		}
+		for (int i=updateCount-1; i>=0; i--) {
+			update [i].updateLayout (false);
+		}
+	} else {
+		if (layout == null && (flags & SWT.ALL) == 0) return;
+		markLayout ((flags & SWT.CHANGED) != 0, (flags & SWT.ALL) != 0);
+		if ((flags & SWT.DEFER) != 0) {
+			setLayoutDeferred (true);
+			display.addLayoutDeferred (this);
+		}
+		updateLayout ((flags & SWT.ALL) != 0);
 	}
 }
 
@@ -1205,6 +1313,15 @@ void removeControl (Control control) {
 	fixTabList (control);
 }
 
+void reskinChildren (int flags) {
+	super.reskinChildren (flags);
+	Control [] children = _getChildren ();
+	for (int i=0; i<children.length; i++) {
+		Control child = children [i];
+		if (child != null) child.reskin (flags);
+	}
+}
+
 void resizeHandle (int width, int height) {
 	super.resizeHandle (width, height);
 	if (socketHandle != 0) OS.gtk_widget_set_size_request (socketHandle, width, height);
@@ -1380,7 +1497,7 @@ void showWidget () {
 }
 
 boolean checkSubwindow () {
-	return true;
+	return (state & CHECK_SUBWINDOW) != 0;
 }
 
 boolean translateMnemonic (Event event, Control control) {
@@ -1425,6 +1542,7 @@ void updateLayout (boolean all) {
 	if ((state & LAYOUT_NEEDED) != 0) {
 		boolean changed = (state & LAYOUT_CHANGED) != 0;
 		state &= ~(LAYOUT_NEEDED | LAYOUT_CHANGED);
+		display.runSkin();
 		layout.layout (this, changed);
 	}
 	if (all) {
diff --git a/org/eclipse/swt/widgets/Control.java b/org/eclipse/swt/widgets/Control.java
index cabd66b..a69add3 100644
--- a/org/eclipse/swt/widgets/Control.java
+++ b/org/eclipse/swt/widgets/Control.java
@@ -16,7 +16,6 @@ import org.eclipse.swt.accessibility.*;
 import org.eclipse.swt.events.*;
 import org.eclipse.swt.graphics.*;
 import org.eclipse.swt.internal.*;
-import org.eclipse.swt.internal.accessibility.gtk.*;
 import org.eclipse.swt.internal.cairo.*;
 import org.eclipse.swt.internal.gtk.*;
 
@@ -29,7 +28,8 @@ import org.eclipse.swt.internal.gtk.*;
  * <dd>LEFT_TO_RIGHT, RIGHT_TO_LEFT</dd>
  * <dt><b>Events:</b>
  * <dd>DragDetect, FocusIn, FocusOut, Help, KeyDown, KeyUp, MenuDetect, MouseDoubleClick, MouseDown, MouseEnter,
- *     MouseExit, MouseHover, MouseUp, MouseMove, Move, Paint, Resize, Traverse</dd>
+ *     MouseExit, MouseHover, MouseUp, MouseMove, MouseWheel, MouseHorizontalWheel, MouseVerticalWheel, Move,
+ *     Paint, Resize, Traverse</dd>
  * </dl>
  * </p><p>
  * Only one of LEFT_TO_RIGHT or RIGHT_TO_LEFT may be specified.
@@ -56,8 +56,7 @@ public abstract class Control extends Widget implements Drawable {
 	String toolTipText;
 	Object layoutData;
 	Accessible accessible;
-	
-	static final String IS_ACTIVE = "org.eclipse.swt.internal.control.isactive"; //$NON-NLS-1$
+	Control labelRelation;
 
 Control () {
 }
@@ -109,6 +108,23 @@ void deregister () {
 	if (imHandle != 0) display.removeWidget (imHandle);
 }
 
+void drawBackground (Control control, int /*long*/ window, int /*long*/ region, int x, int y, int width, int height) {
+	int /*long*/ gdkGC = OS.gdk_gc_new (window);
+	if (region != 0) OS.gdk_gc_set_clip_region (gdkGC, region);
+	if (control.backgroundImage != null) {
+		Point pt = display.map (this, control, 0, 0);
+		OS.gdk_gc_set_fill (gdkGC, OS.GDK_TILED);
+		OS.gdk_gc_set_ts_origin (gdkGC, -pt.x, -pt.y);
+		OS.gdk_gc_set_tile (gdkGC, control.backgroundImage.pixmap);
+		OS.gdk_draw_rectangle (window, gdkGC, 1, x, y, width, height);
+	} else {
+		GdkColor color = control.getBackgroundColor ();
+		OS.gdk_gc_set_foreground (gdkGC, color);
+		OS.gdk_draw_rectangle (window, gdkGC, 1, x, y, width, height);
+	}
+	OS.g_object_unref (gdkGC);
+}
+
 boolean drawGripper (int x, int y, int width, int height, boolean vertical) {
 	int /*long*/ paintHandle = paintHandle ();
 	int /*long*/ window = OS.GTK_WIDGET_WINDOW (paintHandle);
@@ -526,7 +542,7 @@ void createWidget (int index) {
 	checkOrientation (parent);
 	super.createWidget (index);
 	checkBackground ();
-	if ((state & PARENT_BACKGROUND) != 0) setBackground ();
+	if ((state & PARENT_BACKGROUND) != 0) setParentBackground ();
 	checkBuffered ();
 	showWidget ();
 	setInitialBounds ();
@@ -633,6 +649,10 @@ void forceResize () {
  */
 public Accessible getAccessible () {
 	checkWidget ();
+	return _getAccessible ();
+}
+
+Accessible _getAccessible () {
 	if (accessible == null) {
 		accessible = Accessible.internal_new_Accessible (this);
 	}
@@ -1087,6 +1107,7 @@ public void moveAbove (Control control) {
 	if (control != null) {
 		if (control.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
 		if (parent != control.parent) return;
+		if (this == control) return;
 	}
 	setZOrder (control, true, true);
 }
@@ -1116,6 +1137,7 @@ public void moveBelow (Control control) {
 	if (control != null) {
 		if (control.isDisposed ()) error(SWT.ERROR_INVALID_ARGUMENT);
 		if (parent != control.parent) return;
+		if (this == control) return;
 	}
 	setZOrder (control, false, true);
 }
@@ -1890,19 +1912,14 @@ public void removePaintListener(PaintListener listener) {
 }
 
 /*
- * Remove "Labelled by" relations from the receiver.
+ * Remove "Labelled by" relation from the receiver.
  */
 void removeRelation () {
 	if (!isDescribedByLabel ()) return;		/* there will not be any */
-	int /*long*/ accessible = OS.gtk_widget_get_accessible (handle);
-	if (accessible == 0) return;
-	int /*long*/ set = ATK.atk_object_ref_relation_set (accessible);
-	int count = ATK.atk_relation_set_get_n_relations (set);
-	for (int i = 0; i < count; i++) {
-		int /*long*/ relation = ATK.atk_relation_set_get_relation (set, 0);
-		ATK.atk_relation_set_remove (set, relation);
+	if (labelRelation != null) {
+		_getAccessible().removeRelation (ACC.RELATION_LABELLED_BY, labelRelation._getAccessible());
+		labelRelation = null;
 	}
-	OS.g_object_unref (set);
 }
 
 /**
@@ -1950,7 +1967,7 @@ public void removeTraverseListener(TraverseListener listener) {
  * @return <code>true</code> if the gesture occurred, and <code>false</code> otherwise.
  *
  * @exception IllegalArgumentException <ul>
- *   <li>ERROR_NULL_ARGUMENT when the event is null</li>
+ *   <li>ERROR_NULL_ARGUMENT if the event is null</li>
  * </ul>
  * @exception SWTException <ul>
  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
@@ -1992,7 +2009,7 @@ public boolean dragDetect (Event event) {
  * @return <code>true</code> if the gesture occurred, and <code>false</code> otherwise.
  *
  * @exception IllegalArgumentException <ul>
- *   <li>ERROR_NULL_ARGUMENT when the event is null</li>
+ *   <li>ERROR_NULL_ARGUMENT if the event is null</li>
  * </ul>
  * @exception SWTException <ul>
  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
@@ -2269,11 +2286,6 @@ public Cursor getCursor () {
 	return cursor;
 }
 
-public Object getData(String key) {
-	if (key.equals(IS_ACTIVE)) return new Boolean(isActive ());
-	return super.getData(key);
-}
-
 /**
  * Returns <code>true</code> if the receiver is detecting
  * drag gestures, and  <code>false</code> otherwise. 
@@ -2412,6 +2424,11 @@ public Menu getMenu () {
  * 
  * @return the receiver's monitor
  * 
+ * @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>
+ * 
  * @since 3.0
  */
 public Monitor getMonitor () {
@@ -2632,20 +2649,7 @@ int /*long*/ gtk_button_press_event (int /*long*/ widget, int /*long*/ event, bo
 int /*long*/ gtk_button_release_event (int /*long*/ widget, int /*long*/ event) {
 	GdkEventButton gdkEvent = new GdkEventButton ();
 	OS.memmove (gdkEvent, event, GdkEventButton.sizeof);
-	/*
-	* Feature in GTK.  When button 4, 5, 6, or 7 is released, GTK
-	* does not deliver a corresponding GTK event.  Button 6 and 7
-	* are mapped to buttons 4 and 5 in SWT.  The fix is to change
-	* the button number of the event to a negative number so that
-	* it gets dispatched by GTK.  SWT has been modified to look
-	* for negative button numbers.
-	*/
-	int button = gdkEvent.button;
-	switch (button) {
-		case -6: button = 4; break;
-		case -7: button = 5; break;
-	}
-	return sendMouseEvent (SWT.MouseUp, button, display.clickCount, 0, false, gdkEvent.time, gdkEvent.x_root, gdkEvent.y_root, false, gdkEvent.state) ? 0 : 1;
+	return sendMouseEvent (SWT.MouseUp, gdkEvent.button, display.clickCount, 0, false, gdkEvent.time, gdkEvent.x_root, gdkEvent.y_root, false, gdkEvent.state) ? 0 : 1;
 }
 
 int /*long*/ gtk_commit (int /*long*/ imcontext, int /*long*/ text) {
@@ -2921,8 +2925,7 @@ int /*long*/ gtk_realize (int /*long*/ widget) {
 		OS.gtk_im_context_set_client_window (imHandle, window);
 	}
 	if (backgroundImage != null) {
-		int /*long*/ window = OS.GTK_WIDGET_WINDOW (paintHandle ());
-		if (window != 0) OS.gdk_window_set_back_pixmap (window, backgroundImage.pixmap, false);
+		setBackgroundPixmap (backgroundImage.pixmap);
 	}
 	return 0;
 }
@@ -2936,9 +2939,9 @@ int /*long*/ gtk_scroll_event (int /*long*/ widget, int /*long*/ eventPtr) {
 		case OS.GDK_SCROLL_DOWN:
 			return sendMouseEvent (SWT.MouseWheel, 0, -3, SWT.SCROLL_LINE, true, gdkEvent.time, gdkEvent.x_root, gdkEvent.y_root, false, gdkEvent.state) ? 0 : 1;
 		case OS.GDK_SCROLL_LEFT:
-			return sendMouseEvent (SWT.MouseDown, 4, gdkEvent.time, gdkEvent.x_root, gdkEvent.y_root, false, gdkEvent.state) ? 0 : 1;
+			return sendMouseEvent (SWT.MouseHorizontalWheel, 0, 3, 0, true, gdkEvent.time, gdkEvent.x_root, gdkEvent.y_root, false, gdkEvent.state) ? 0 : 1;
 		case OS.GDK_SCROLL_RIGHT:
-			return sendMouseEvent (SWT.MouseDown, 5, gdkEvent.time, gdkEvent.x_root, gdkEvent.y_root, false, gdkEvent.state) ? 0 : 1;
+			return sendMouseEvent (SWT.MouseHorizontalWheel, 0, -3, 0, true, gdkEvent.time, gdkEvent.x_root, gdkEvent.y_root, false, gdkEvent.state) ? 0 : 1;
 	}
 	return 0;
 }
@@ -3000,6 +3003,8 @@ void gtk_widget_size_request (int /*long*/ widget, GtkRequisition requisition) {
  *
  * @param data the platform specific GC data 
  * @return the platform specific GC handle
+ * 
+ * @noreference This method is not intended to be referenced by clients.
  */
 public int /*long*/ internal_new_GC (GCData data) {
 	checkWidget ();
@@ -3043,6 +3048,8 @@ int /*long*/ imHandle () {
  *
  * @param hDC the platform specific GC handle
  * @param data the platform specific GC data 
+ * 
+ * @noreference This method is not intended to be referenced by clients.
  */
 public void internal_dispose_GC (int /*long*/ gdkGC, GCData data) {
 	checkWidget ();
@@ -3285,14 +3292,18 @@ void release (boolean destroy) {
 			if (children [index] == this) break;
 			index++;
 		}
-		if (0 < index && (index + 1) < children.length) {
-			next = children [index + 1];
+		if (index > 0) {
 			previous = children [index - 1];
 		}
+		if (index + 1 < children.length) {
+			next = children [index + 1];
+			next.removeRelation ();
+		}
+		removeRelation ();
 	}
 	super.release (destroy);
 	if (destroy) {
-		if (previous != null) previous.addRelation (next);
+		if (previous != null && next != null) previous.addRelation (next);
 	}
 }
 
@@ -3332,6 +3343,30 @@ void releaseWidget () {
 	region = null;
 }
 
+void restackWindow (int /*long*/ window, int /*long*/ sibling, boolean above) {
+	    if (OS.GTK_VERSION >= OS.VERSION (2, 17, 11)) {
+	    	OS.gdk_window_restack (window, sibling, above);
+	    } else {
+	    	/*
+			* Feature in X. If the receiver is a top level, XConfigureWindow ()
+			* will fail (with a BadMatch error) for top level shells because top
+			* level shells are reparented by the window manager and do not share
+			* the same X window parent.  This is the correct behavior but it is
+			* unexpected.  The fix is to use XReconfigureWMWindow () instead.
+			* When the receiver is not a top level shell, XReconfigureWMWindow ()
+			* behaves the same as XConfigureWindow ().
+			*/
+			int /*long*/ xDisplay = OS.gdk_x11_drawable_get_xdisplay (window);
+			int /*long*/ xWindow = OS.gdk_x11_drawable_get_xid (window);
+			int xScreen = OS.XDefaultScreen (xDisplay);
+			int flags = OS.CWStackMode | OS.CWSibling;			
+			XWindowChanges changes = new XWindowChanges ();
+			changes.sibling = OS.gdk_x11_drawable_get_xid (sibling);
+			changes.stack_mode = above ? OS.Above : OS.Below;
+			OS.XReconfigureWMWindow (xDisplay, xWindow, xScreen, flags, changes);
+	    }
+	}
+
 boolean sendDragEvent (int button, int stateMask, int x, int y, boolean isStateMask) {
 	Event event = new Event ();
 	event.button = button;
@@ -3425,12 +3460,14 @@ boolean sendMouseEvent (int type, int button, int count, int detail, boolean sen
 }
 
 void setBackground () {
-	if ((state & PARENT_BACKGROUND) != 0 && (state & BACKGROUND) == 0 && backgroundImage == null) {
-		setParentBackground ();
-	} else {
-		setWidgetBackground ();
+	if ((state & BACKGROUND) == 0 && backgroundImage == null) {
+		if ((state & PARENT_BACKGROUND) != 0) {
+			setParentBackground ();
+		} else {
+			setWidgetBackground ();
+		}
+		redrawWidget (0, 0, 0, 0, true, false, false);
 	}
-	redrawWidget (0, 0, 0, 0, true, false, false);
 }
 
 /**
@@ -3483,14 +3520,27 @@ void setBackgroundColor (int /*long*/ handle, GdkColor color) {
 	int /*long*/ style = OS.gtk_widget_get_modifier_style (handle);
 	int /*long*/ ptr = OS.gtk_rc_style_get_bg_pixmap_name (style, index);
 	if (ptr != 0) OS.g_free (ptr);
-	String name = color == null ? "<parent>" : "<none>";
-	byte[] buffer = Converter.wcsToMbcs (null, name, true);
-	ptr = OS.g_malloc (buffer.length);
-	OS.memmove (ptr, buffer, buffer.length);
+	ptr = 0;
+	
+	String pixmapName = null;
+	int flags = OS.gtk_rc_style_get_color_flags (style, index);
+	if (color != null) {
+		flags |= OS.GTK_RC_BG;
+		pixmapName = "<none>";
+	} else {
+		flags &= ~OS.GTK_RC_BG;
+		if (backgroundImage == null && (state & PARENT_BACKGROUND) != 0) {
+			pixmapName = "<parent>";
+		}
+	}
+	if (pixmapName != null) {
+		byte[] buffer = Converter.wcsToMbcs (null, pixmapName, true);
+		ptr = OS.g_malloc (buffer.length);
+		OS.memmove (ptr, buffer, buffer.length);
+	}
+	
 	OS.gtk_rc_style_set_bg_pixmap_name (style, index, ptr);
 	OS.gtk_rc_style_set_bg (style, index, color);
-	int flags = OS.gtk_rc_style_get_color_flags (style, index);
-	flags = (color == null) ? flags & ~OS.GTK_RC_BG : flags | OS.GTK_RC_BG;
 	OS.gtk_rc_style_set_color_flags (style, index, flags);
 	modifyStyle (handle, style);
 }
@@ -3537,7 +3587,7 @@ public void setBackgroundImage (Image image) {
 
 void setBackgroundPixmap (int /*long*/ pixmap) {
 	int /*long*/ window = OS.GTK_WIDGET_WINDOW (paintHandle ());
-	if (window != 0) OS.gdk_window_set_back_pixmap (window, backgroundImage.pixmap, false);
+	if (window != 0) OS.gdk_window_set_back_pixmap (window, pixmap, false);
 }
 
 /**
@@ -3682,15 +3732,7 @@ public void setEnabled (boolean enabled) {
 			if (!OS.GDK_WINDOWING_X11 ()) {
 				OS.gdk_window_raise (enableWindow);
 			} else {
-				int /*long*/ topWindow = OS.GTK_WIDGET_WINDOW (topHandle);			
-				int /*long*/ xDisplay = OS.gdk_x11_drawable_get_xdisplay (topWindow);
-				int /*long*/ xWindow = OS.gdk_x11_drawable_get_xid (enableWindow);
-				int xScreen = OS.XDefaultScreen (xDisplay);
-				int flags = OS.CWStackMode | OS.CWSibling;			
-				XWindowChanges changes = new XWindowChanges ();
-				changes.sibling = OS.gdk_x11_drawable_get_xid (topWindow);
-				changes.stack_mode = OS.Above;
-				OS.XReconfigureWMWindow (xDisplay, xWindow, xScreen, flags, changes);
+				restackWindow (enableWindow, OS.GTK_WIDGET_WINDOW (topHandle), true);
 			}
 			if (OS.GTK_WIDGET_VISIBLE (topHandle)) OS.gdk_window_show_unraised (enableWindow);
 		}
@@ -3917,6 +3959,7 @@ public boolean setParent (Composite parent) {
 	OS.gtk_fixed_move (newParent, topHandle, x, y);
 	this.parent = parent;
 	setZOrder (null, false, true);
+	reskin (SWT.ALL);
 	return true;
 }
 
@@ -3961,10 +4004,18 @@ public void setRedraw (boolean redraw) {
 		if (--drawCount == 0) {
 			if (redrawWindow != 0) {
 				int /*long*/ window = paintWindow ();
+				/*
+				* Bug in GTK. For some reason, the window does not
+				* redraw in versions of GTK greater than 2.18. The fix
+				* is to hide and show it (without changing the z order).
+			    */
+				boolean fixRedraw = OS.GTK_VERSION >= OS.VERSION (2, 17, 0) && OS.gdk_window_is_visible(window);
+				if (fixRedraw) OS.gdk_window_hide(window);
 				/* Explicitly hiding the window avoids flicker on GTK+ >= 2.6 */
 				OS.gdk_window_hide (redrawWindow);
 				OS.gdk_window_destroy (redrawWindow);
 				OS.gdk_window_set_events (window, OS.gtk_widget_get_events (paintHandle ()));
+				if (fixRedraw) OS.gdk_window_show_unraised(window);
 				redrawWindow = 0;
 			}
 		}
@@ -3987,6 +4038,9 @@ public void setRedraw (boolean redraw) {
 						OS.GDK_BUTTON2_MOTION_MASK | OS.GDK_BUTTON3_MOTION_MASK;
 					OS.gdk_window_set_events (window, OS.gdk_window_get_events (window) & ~mouseMask);
 					OS.gdk_window_set_back_pixmap (redrawWindow, 0, false);
+					//System.out.println("Redraw " + redrawWindow + " WIndow " + window);
+//					OS.gdk_x11_drawable_get_xid(redrawWindow);
+//					OS.gdk_x11_drawable_get_xid(window);
 					OS.gdk_window_show (redrawWindow);
 				}
 			}
@@ -4170,29 +4224,12 @@ void setZOrder (Control sibling, boolean above, boolean fixRelations, boolean fi
 				OS.gdk_window_lower (window);
 			}
 		} else {
-			XWindowChanges changes = new XWindowChanges ();
-			changes.sibling = OS.gdk_x11_drawable_get_xid (siblingWindow != 0 ? siblingWindow : redrawWindow);
-			changes.stack_mode = above ? OS.Above : OS.Below;
-			if (redrawWindow != 0 && siblingWindow == 0) changes.stack_mode = OS.Below;
-			int /*long*/ xDisplay = OS.gdk_x11_drawable_get_xdisplay (window);
-			int /*long*/ xWindow = OS.gdk_x11_drawable_get_xid (window);
-			int xScreen = OS.XDefaultScreen (xDisplay);
-			int flags = OS.CWStackMode | OS.CWSibling;
-			/*
-			* Feature in X. If the receiver is a top level, XConfigureWindow ()
-			* will fail (with a BadMatch error) for top level shells because top
-			* level shells are reparented by the window manager and do not share
-			* the same X window parent.  This is the correct behavior but it is
-			* unexpected.  The fix is to use XReconfigureWMWindow () instead.
-			* When the receiver is not a top level shell, XReconfigureWMWindow ()
-			* behaves the same as XConfigureWindow ().
-			*/
-			OS.XReconfigureWMWindow (xDisplay, xWindow, xScreen, flags, changes);			
+			int /*long*/ siblingW = siblingWindow != 0 ? siblingWindow : redrawWindow;
+			boolean stack_mode = above;
+			if (redrawWindow != 0 && siblingWindow == 0) stack_mode = false;
+			restackWindow (window, siblingW, stack_mode);
 			if (enableWindow != 0) {
-				changes.sibling = OS.gdk_x11_drawable_get_xid (window);
-				changes.stack_mode = OS.Above;
-				xWindow = OS.gdk_x11_drawable_get_xid (enableWindow);
-				OS.XReconfigureWMWindow (xDisplay, xWindow, xScreen, flags, changes);
+				 restackWindow (enableWindow, window, true);
 			}
 		}
 	}
@@ -4241,12 +4278,9 @@ void setZOrder (Control sibling, boolean above, boolean fixRelations, boolean fi
 }
 
 void setWidgetBackground  () {
-	if (fixedHandle != 0) {
-		int /*long*/ style = OS.gtk_widget_get_modifier_style (fixedHandle);
-		modifyStyle (fixedHandle, style);
-	}
-	int /*long*/ style = OS.gtk_widget_get_modifier_style (handle);
-	modifyStyle (handle, style);
+	GdkColor color = (state & BACKGROUND) != 0 ? getBackgroundColor () : null;
+	if (fixedHandle != 0) setBackgroundColor (fixedHandle, color);
+	setBackgroundColor (handle, color);
 }
 
 boolean showMenu (int x, int y) {
@@ -4305,7 +4339,8 @@ void sort (int [] items) {
  * traversal action. The argument should be one of the constants:
  * <code>SWT.TRAVERSE_ESCAPE</code>, <code>SWT.TRAVERSE_RETURN</code>, 
  * <code>SWT.TRAVERSE_TAB_NEXT</code>, <code>SWT.TRAVERSE_TAB_PREVIOUS</code>, 
- * <code>SWT.TRAVERSE_ARROW_NEXT</code> and <code>SWT.TRAVERSE_ARROW_PREVIOUS</code>.
+ * <code>SWT.TRAVERSE_ARROW_NEXT</code>, <code>SWT.TRAVERSE_ARROW_PREVIOUS</code>,
+ * <code>SWT.TRAVERSE_PAGE_NEXT</code> and <code>SWT.TRAVERSE_PAGE_PREVIOUS</code>.
  *
  * @param traversal the type of traversal
  * @return true if the traversal succeeded
@@ -4323,6 +4358,180 @@ public boolean traverse (int traversal) {
 	return traverse (event);
 }
 
+/**
+ * Performs a platform traversal action corresponding to a <code>KeyDown</code> event.
+ * 
+ * <p>Valid traversal values are
+ * <code>SWT.TRAVERSE_NONE</code>, <code>SWT.TRAVERSE_MNEMONIC</code>,
+ * <code>SWT.TRAVERSE_ESCAPE</code>, <code>SWT.TRAVERSE_RETURN</code>,
+ * <code>SWT.TRAVERSE_TAB_NEXT</code>, <code>SWT.TRAVERSE_TAB_PREVIOUS</code>, 
+ * <code>SWT.TRAVERSE_ARROW_NEXT</code>, <code>SWT.TRAVERSE_ARROW_PREVIOUS</code>,
+ * <code>SWT.TRAVERSE_PAGE_NEXT</code> and <code>SWT.TRAVERSE_PAGE_PREVIOUS</code>.
+ * If <code>traversal</code> is <code>SWT.TRAVERSE_NONE</code> then the Traverse
+ * event is created with standard values based on the KeyDown event.  If
+ * <code>traversal</code> is one of the other traversal constants then the Traverse
+ * event is created with this detail, and its <code>doit</code> is taken from the
+ * KeyDown event. 
+ * </p>
+ *
+ * @param traversal the type of traversal, or <code>SWT.TRAVERSE_NONE</code> to compute
+ * this from <code>event</code>
+ * @param event the KeyDown event
+ * 
+ * @return <code>true</code> if the traversal succeeded
+ *
+ * @exception IllegalArgumentException <ul>
+ *   <li>ERROR_NULL_ARGUMENT if the event is null</li>
+ * </ul>
+ * @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>
+ *
+ * @since 3.6
+ */
+public boolean traverse (int traversal, Event event) {
+	checkWidget ();
+	if (event == null) error (SWT.ERROR_NULL_ARGUMENT);
+	return traverse (traversal, event.character, event.keyCode, event.keyLocation, event.stateMask, event.doit);
+}
+
+/**
+ * Performs a platform traversal action corresponding to a <code>KeyDown</code> event.
+ * 
+ * <p>Valid traversal values are
+ * <code>SWT.TRAVERSE_NONE</code>, <code>SWT.TRAVERSE_MNEMONIC</code>,
+ * <code>SWT.TRAVERSE_ESCAPE</code>, <code>SWT.TRAVERSE_RETURN</code>,
+ * <code>SWT.TRAVERSE_TAB_NEXT</code>, <code>SWT.TRAVERSE_TAB_PREVIOUS</code>, 
+ * <code>SWT.TRAVERSE_ARROW_NEXT</code>, <code>SWT.TRAVERSE_ARROW_PREVIOUS</code>,
+ * <code>SWT.TRAVERSE_PAGE_NEXT</code> and <code>SWT.TRAVERSE_PAGE_PREVIOUS</code>.
+ * If <code>traversal</code> is <code>SWT.TRAVERSE_NONE</code> then the Traverse
+ * event is created with standard values based on the KeyDown event.  If
+ * <code>traversal</code> is one of the other traversal constants then the Traverse
+ * event is created with this detail, and its <code>doit</code> is taken from the
+ * KeyDown event. 
+ * </p>
+ *
+ * @param traversal the type of traversal, or <code>SWT.TRAVERSE_NONE</code> to compute
+ * this from <code>event</code>
+ * @param event the KeyDown event
+ * 
+ * @return <code>true</code> if the traversal succeeded
+ *
+ * @exception IllegalArgumentException <ul>
+ *   <li>ERROR_NULL_ARGUMENT if the event is null</li>
+ * </ul>
+ * @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>
+ *
+ * @since 3.6
+ */
+public boolean traverse (int traversal, KeyEvent event) {
+	checkWidget ();
+	if (event == null) error (SWT.ERROR_NULL_ARGUMENT);
+	return traverse (traversal, event.character, event.keyCode, event.keyLocation, event.stateMask, event.doit);
+}
+
+boolean traverse (int traversal, char character, int keyCode, int keyLocation, int stateMask, boolean doit) {
+	if (traversal == SWT.TRAVERSE_NONE) {
+		switch (keyCode) {
+			case SWT.ESC: {
+				traversal = SWT.TRAVERSE_ESCAPE;
+				doit = true;
+				break;
+			}
+			case SWT.CR: {
+				traversal = SWT.TRAVERSE_RETURN;
+				doit = true;
+				break;
+			}
+			case SWT.ARROW_DOWN:
+			case SWT.ARROW_RIGHT: {
+				traversal = SWT.TRAVERSE_ARROW_NEXT;
+				doit = false;
+				break;
+			}
+			case SWT.ARROW_UP:
+			case SWT.ARROW_LEFT: {
+				traversal = SWT.TRAVERSE_ARROW_PREVIOUS;
+				doit = false;
+				break;
+			}
+			case SWT.TAB: {
+				traversal = (stateMask & SWT.SHIFT) != 0 ? SWT.TRAVERSE_TAB_PREVIOUS : SWT.TRAVERSE_TAB_NEXT;
+				doit = true;
+				break;
+			}
+			case SWT.PAGE_DOWN: {
+				if ((stateMask & SWT.CTRL) != 0) {
+					traversal = SWT.TRAVERSE_PAGE_NEXT;
+					doit = true;
+				}
+				break;
+			}
+			case SWT.PAGE_UP: {
+				if ((stateMask & SWT.CTRL) != 0) {
+					traversal = SWT.TRAVERSE_PAGE_PREVIOUS;
+					doit = true;
+				}
+				break;
+			}
+			default: {
+				if (character != 0 && (stateMask & (SWT.ALT | SWT.CTRL)) == SWT.ALT) {
+					traversal = SWT.TRAVERSE_MNEMONIC;
+					doit = true;
+				}
+				break;
+			}
+		}
+	}
+
+	Event event = new Event ();
+	event.character = character;
+	event.detail = traversal;
+	event.doit = doit;
+	event.keyCode = keyCode;
+	event.keyLocation = keyLocation;
+	event.stateMask = stateMask;
+	Shell shell = getShell ();
+
+	boolean all = false;
+	switch (traversal) {
+		case SWT.TRAVERSE_ESCAPE:
+		case SWT.TRAVERSE_RETURN:
+		case SWT.TRAVERSE_PAGE_NEXT:
+		case SWT.TRAVERSE_PAGE_PREVIOUS: {
+			all = true;
+			// FALL THROUGH
+		}
+		case SWT.TRAVERSE_ARROW_NEXT:
+		case SWT.TRAVERSE_ARROW_PREVIOUS:
+		case SWT.TRAVERSE_TAB_NEXT:
+		case SWT.TRAVERSE_TAB_PREVIOUS: {
+			/* traversal is a valid traversal action */
+			break;
+		}
+		case SWT.TRAVERSE_MNEMONIC: {
+			return translateMnemonic (event, null) || shell.translateMnemonic (event, this);
+		}
+		default: {
+			/* traversal is not a valid traversal action */
+			return false;
+		}
+	}
+
+	Control control = this;
+	do {
+		if (control.traverse (event)) return true;
+		if (!event.doit && control.hooks (SWT.Traverse)) return false;
+		if (control == shell) return false;
+		control = control.parent;
+	} while (all && control != null);
+	return false;
+}
+
 boolean translateMnemonic (Event event, Control control) {
 	if (control == this) return false;
 	if (!isVisible () || !isEnabled ()) return false;
diff --git a/org/eclipse/swt/widgets/CoolBar.java b/org/eclipse/swt/widgets/CoolBar.java
index 8abac1a..44e878d 100644
--- a/org/eclipse/swt/widgets/CoolBar.java
+++ b/org/eclipse/swt/widgets/CoolBar.java
@@ -1099,6 +1099,19 @@ public void setWrapIndices (int[] indices) {
 	}
 	relayout();
 }
+
+void reskinChildren (int flags) {
+	if (items != null) {
+		for (int row = 0; row < items.length; row++) {
+			for (int i = 0; i < items[row].length; i++) {
+				CoolItem item = items[row][i];
+				if (item != null) item.reskin (flags);
+			}
+		}
+	}
+	super.reskinChildren (flags);
+}
+
 public void setCursor (Cursor cursor) {
 	checkWidget ();
 	super.setCursor (this.cursor = cursor);
diff --git a/org/eclipse/swt/widgets/CoolItem.java b/org/eclipse/swt/widgets/CoolItem.java
index 2681e09..8f3b17a 100644
--- a/org/eclipse/swt/widgets/CoolItem.java
+++ b/org/eclipse/swt/widgets/CoolItem.java
@@ -398,7 +398,8 @@ void onSelection (Event ev) {
 		event.x = bounds.x;
 		event.y = bounds.y + bounds.height;
 	}
-	postEvent (SWT.Selection, event);
+	event.stateMask = ev.stateMask;
+	sendSelectionEvent (SWT.Selection, event, false);
 }
 /**
  * Removes the listener from the collection of listeners that
diff --git a/org/eclipse/swt/widgets/DateTime.java b/org/eclipse/swt/widgets/DateTime.java
index 11248e3..e69a998 100644
--- a/org/eclipse/swt/widgets/DateTime.java
+++ b/org/eclipse/swt/widgets/DateTime.java
@@ -489,7 +489,7 @@ int /*long*/ gtk_day_selected (int /*long*/ widget) {
 }
 
 int /*long*/ gtk_day_selected_double_click (int /*long*/ widget) {
-	postEvent(SWT.DefaultSelection);
+	sendSelectionEvent (SWT.DefaultSelection);
 	return 0;
 }
 
@@ -580,7 +580,7 @@ void onKeyDown(Event event) {
 			setTextField(fieldName, calendar.getActualMaximum(fieldName), true, true);
 			break;
 		case SWT.CR:
-			postEvent(SWT.DefaultSelection);
+			sendSelectionEvent (SWT.DefaultSelection);
 			break;
 		default:
 			switch (event.character) {
@@ -745,7 +745,7 @@ void sendSelectionEvent () {
 		year = y[0];
 		month = m[0];
 		day = d[0];
-		postEvent (SWT.Selection);
+		sendSelectionEvent (SWT.Selection);
 	}
 }
 
@@ -809,7 +809,7 @@ void setField(int fieldName, int value) {
 		calendar.roll(Calendar.HOUR_OF_DAY, 12); // TODO: needs more work for setFormat and locale
 	}
 	calendar.set(fieldName, value);
-	postEvent(SWT.Selection);
+	sendSelectionEvent (SWT.Selection);
 }
 
 void setTextField(int fieldName, int value, boolean commit, boolean adjust) {
@@ -1091,7 +1091,7 @@ int unformattedIntValue(int fieldName, String newText, boolean adjust, int max)
 	return newValue;
 }
 
-public void updateControl() {
+void updateControl() {
 	if (text != null) {
 		String string = getFormattedString(style);
 		ignoreVerify = true;
diff --git a/org/eclipse/swt/widgets/Decorations.java b/org/eclipse/swt/widgets/Decorations.java
index 38ed5a2..2e570bf 100644
--- a/org/eclipse/swt/widgets/Decorations.java
+++ b/org/eclipse/swt/widgets/Decorations.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -292,7 +292,9 @@ void fixDecorations (Decorations newDecorations, Control control, Menu [] menus)
  */
 public Button getDefaultButton () {
 	checkWidget();
-	return defaultButton != null ? defaultButton : saveDefault;
+	Button button = defaultButton != null ? defaultButton : saveDefault;
+	if (button != null && button.isDisposed ()) return null;
+	return button;
 }
 
 /**
@@ -489,6 +491,17 @@ void releaseWidget () {
 	defaultButton = saveDefault = null;
 }
 
+void reskinChildren (int flags) {
+	if (menuBar != null) menuBar.reskin (flags);
+	if (menus != null) {
+		for (int i=0; i<menus.length; i++) {
+			Menu menu = menus [i];
+			if (menu != null) menu.reskin (flags);
+		}
+	}
+	super.reskinChildren (flags);
+}
+
 boolean restoreFocus () {
 	if (savedFocus != null && savedFocus.isDisposed ()) savedFocus = null;
 	boolean restored = savedFocus != null && savedFocus.setFocus ();
diff --git a/org/eclipse/swt/widgets/DirectoryDialog.java b/org/eclipse/swt/widgets/DirectoryDialog.java
index 8b31222..06e08e1 100644
--- a/org/eclipse/swt/widgets/DirectoryDialog.java
+++ b/org/eclipse/swt/widgets/DirectoryDialog.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -133,6 +133,10 @@ String openChooserDialog () {
 	} else {
 		handle = OS.gtk_file_chooser_dialog_new (titleBytes, shellHandle, OS.GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, OS.GTK_STOCK_OK (), OS.GTK_RESPONSE_OK, OS.GTK_STOCK_CANCEL (), OS.GTK_RESPONSE_CANCEL, 0);
 	}
+	if (OS.GTK_VERSION >= OS.VERSION (2, 10, 0)) {
+		int /*long*/ group = OS.gtk_window_get_group(0);
+		OS.gtk_window_group_add_window (group, handle);
+	}
 	OS.gtk_window_set_modal (handle, true);
 	int /*long*/ pixbufs = OS.gtk_window_get_icon_list (shellHandle);
 	if (pixbufs != 0) {
diff --git a/org/eclipse/swt/widgets/Display.java b/org/eclipse/swt/widgets/Display.java
index 0e1945f..d8ca0ab 100644
--- a/org/eclipse/swt/widgets/Display.java
+++ b/org/eclipse/swt/widgets/Display.java
@@ -79,7 +79,7 @@ import org.eclipse.swt.graphics.*;
  * <dt><b>Styles:</b></dt>
  * <dd>(none)</dd>
  * <dt><b>Events:</b></dt>
- * <dd>Close, Dispose, Settings</dd>
+ * <dd>Close, Dispose, OpenDocument, Settings, Skin</dd>
  * </dl>
  * <p>
  * IMPORTANT: This class is <em>not</em> intended to be subclassed.
@@ -111,6 +111,7 @@ public class Display extends Device {
 	Callback windowCallback2, windowCallback3, windowCallback4, windowCallback5;
 	EventTable eventTable, filterTable;
 	static String APP_NAME = "SWT"; //$NON-NLS-1$
+	static String APP_VERSION = ""; //$NON-NLS-1$
 	static final String DISPATCH_EVENT_KEY = "org.eclipse.swt.internal.gtk.dispatchEvent"; //$NON-NLS-1$
 	static final String ADD_WIDGET_KEY = "org.eclipse.swt.internal.addWidget"; //$NON-NLS-1$
 	int /*long*/ [] closures;
@@ -160,6 +161,10 @@ public class Display extends Device {
 	/* Display Shutdown */
 	Runnable [] disposeList;
 	
+	/* Deferred Layout list */
+	Composite[] layoutDeferred;
+	int layoutDeferredCount;
+
 	/* System Tray */
 	Tray tray;
 	
@@ -231,10 +236,12 @@ public class Display extends Device {
 	Callback allChildrenCallback;
 
 	/* Settings callbacks */
-	int /*long*/ styleSetProc;
-	Callback styleSetCallback;
+	int /*long*/ signalProc;
+	Callback signalCallback;
 	int /*long*/ shellHandle;
 	boolean settingsChanged, runSettings;
+	static final int STYLE_SET = 1;
+	static final int PROPERTY_NOTIFY = 2;
 	
 	/* Entry focus behaviour */
 	boolean entrySelectOnFocus;
@@ -280,8 +287,12 @@ public class Display extends Device {
 	int lastEventTime, lastUserEventTime;
 	
 	/* Pango layout constructor */
-	int /*long*/ pangoLayoutNewProc, pangoLayoutNewDefaultProc;
-	Callback pangoLayoutNewCallback;
+	int /*long*/ pangoLayoutNewProc;
+	
+	/* Custom Resize */
+	double resizeLocationX, resizeLocationY;
+	int resizeBoundsX, resizeBoundsY, resizeBoundsWidth, resizeBoundsHeight;
+	int resizeMode;
 	
 	/* Fixed Subclass */
 	static int /*long*/ fixed_type;
@@ -356,6 +367,11 @@ public class Display extends Device {
 		{OS.GDK_F13,		SWT.F13},
 		{OS.GDK_F14,		SWT.F14},
 		{OS.GDK_F15,		SWT.F15},
+		{OS.GDK_F16,		SWT.F16},
+		{OS.GDK_F17,		SWT.F17},
+		{OS.GDK_F18,		SWT.F18},
+		{OS.GDK_F19,		SWT.F19},
+		{OS.GDK_F20,		SWT.F20},
 		
 		/* Numeric Keypad Keys */
 		{OS.GDK_KP_Multiply,		SWT.KEYPAD_MULTIPLY},
@@ -391,6 +407,10 @@ public class Display extends Device {
 	static Display Default;
 	static Display [] Displays = new Display [4];
 
+	/* Skinning support */
+	Widget [] skinList = new Widget [GROW_SIZE];
+	int skinCount;
+	
 	/* Package name */
 	static final String PACKAGE_PREFIX = "org.eclipse.swt.widgets."; //$NON-NLS-1$
 	/* This code is intentionally commented.
@@ -522,6 +542,16 @@ public void addFilter (int eventType, Listener listener) {
 	filterTable.hook (eventType, listener);
 }
 
+void addLayoutDeferred (Composite comp) {
+	if (layoutDeferred == null) layoutDeferred = new Composite [64];
+	if (layoutDeferredCount == layoutDeferred.length) {
+		Composite [] temp = new Composite [layoutDeferred.length + 64];
+		System.arraycopy (layoutDeferred, 0, temp, 0, layoutDeferred.length);
+		layoutDeferred = temp;
+	}
+	layoutDeferred[layoutDeferredCount++] = comp;
+}
+
 void addGdkEvent (int /*long*/ event) {
 	if (gdkEvents == null) {
 		int length = GROW_SIZE;
@@ -623,6 +653,15 @@ void addPopup (Menu menu) {
 	popups [index] = menu;
 }
 
+void addSkinnableWidget (Widget widget) {
+	if (skinCount >= skinList.length) {
+		Widget[] newSkinWidgets = new Widget [skinList.length + GROW_SIZE];
+		System.arraycopy (skinList, 0, newSkinWidgets, 0, skinList.length);
+		skinList = newSkinWidgets;
+	}
+	skinList [skinCount++] = widget;
+}
+
 void addWidget (int /*long*/ handle, Widget widget) {
 	if (handle == 0) return;
 	if (freeSlot == -1) {
@@ -960,6 +999,20 @@ void createDisplay (DeviceData data) {
 	filterProc = filterCallback.getAddress ();
 	if (filterProc == 0) error (SWT.ERROR_NO_MORE_CALLBACKS);
 	OS.gdk_window_add_filter  (0, filterProc, 0);
+
+	if (OS.GDK_WINDOWING_X11 ()) {
+		int /*long*/ xWindow = OS.gdk_x11_drawable_get_xid (OS.GTK_WIDGET_WINDOW (shellHandle));
+		byte[] atomName = Converter.wcsToMbcs (null, "SWT_Window_" + APP_NAME, true); //$NON-NLS-1$
+		int /*long*/ atom = OS.XInternAtom (OS.GDK_DISPLAY (), atomName, false);
+		OS.XSetSelectionOwner (OS.GDK_DISPLAY (), atom, xWindow, OS.CurrentTime);
+		OS.XGetSelectionOwner (OS.GDK_DISPLAY (), atom);
+	}
+
+	signalCallback = new Callback (this, "signalProc", 3); //$NON-NLS-1$
+	signalProc = signalCallback.getAddress ();
+	if (signalProc == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS);
+	OS.gtk_widget_add_events (shellHandle, OS.GDK_PROPERTY_CHANGE_MASK);
+	OS.g_signal_connect (shellHandle, OS.property_notify_event, signalProc, PROPERTY_NOTIFY);
 }
 
 Image createImage (String name) {
@@ -1204,6 +1257,8 @@ int /*long*/ eventProc (int /*long*/ event, int /*long*/ data) {
  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
  *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
  * </ul>
+ * 
+ * @noreference This method is not intended to be referenced by clients.
  */
 public Widget findWidget (int /*long*/ handle) {
 	checkDevice ();
@@ -1230,6 +1285,8 @@ public Widget findWidget (int /*long*/ handle) {
  *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
  * </ul>
  * 
+ * @noreference This method is not intended to be referenced by clients.
+ * 
  * @since 3.1
  */
 public Widget findWidget (int /*long*/ handle, int /*long*/ id) {
@@ -1474,28 +1531,6 @@ boolean filters (int eventType) {
 }
 
 int /*long*/ filterProc (int /*long*/ xEvent, int /*long*/ gdkEvent, int /*long*/ data) {
-	if (data == 0) {
-		/*
-		* Feature in GTK.  When button 4, 5, 6, or 7 is released, GTK
-		* does not deliver a corresponding GTK event.  Button 6 and 7
-		* are mapped to buttons 4 and 5 in SWT.  The fix is to change
-		* the button number of the event to a negative number so that
-		* it gets dispatched by GTK.  SWT has been modified to look
-		* for negative button numbers.
-		*/
-		XButtonEvent mouseEvent = new XButtonEvent ();
-		OS.memmove (mouseEvent, xEvent, 4);
-		if (mouseEvent.type == OS.ButtonRelease) {
-			OS.memmove (mouseEvent, xEvent, XButtonEvent.sizeof);
-			switch (mouseEvent.button) {
-				case 6:
-				case 7:
-					mouseEvent.button = -mouseEvent.button;
-					OS.memmove (xEvent, mouseEvent, XButtonEvent.sizeof);
-					break;
-			}
-		}
-	}
 	Widget widget = getWidget (data);
 	if (widget == null) return 0;
 	return widget.filterProc (xEvent, gdkEvent, data);
@@ -2270,6 +2305,23 @@ public Font getSystemFont () {
 }
 
 /**
+ * Returns the single instance of the system taskBar or null
+ * when there is no system taskBar available for the platform.
+ *
+ * @return the system taskBar or <code>null</code>
+ * 
+ * @exception SWTException <ul>
+ *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @since 3.6
+ */
+public TaskBar getSystemTaskBar () {
+	checkDevice ();
+	return null;
+}
+
+/**
  * Returns the single instance of the system tray or null
  * when there is no system tray available for the platform.
  *
@@ -2400,7 +2452,9 @@ void initializeCallbacks () {
 	closures [Widget.PREEDIT_CHANGED] = OS.g_cclosure_new (windowProc2, Widget.PREEDIT_CHANGED, 0);
 	closures [Widget.REALIZE] = OS.g_cclosure_new (windowProc2, Widget.REALIZE, 0);
 	closures [Widget.SELECT] = OS.g_cclosure_new (windowProc2, Widget.SELECT, 0);
+	closures [Widget.SELECTION_DONE] = OS.g_cclosure_new (windowProc2, Widget.SELECTION_DONE, 0);
 	closures [Widget.SHOW] = OS.g_cclosure_new (windowProc2, Widget.SHOW, 0);
+	closures [Widget.START_INTERACTIVE_SEARCH] = OS.g_cclosure_new (windowProc2, Widget.START_INTERACTIVE_SEARCH, 0);
 	closures [Widget.VALUE_CHANGED] = OS.g_cclosure_new (windowProc2, Widget.VALUE_CHANGED, 0);
 	closures [Widget.UNMAP] = OS.g_cclosure_new (windowProc2, Widget.UNMAP, 0);
 	closures [Widget.UNREALIZE] = OS.g_cclosure_new (windowProc2, Widget.UNREALIZE, 0);
@@ -2450,6 +2504,7 @@ void initializeCallbacks () {
 
 	closures [Widget.DELETE_RANGE] = OS.g_cclosure_new (windowProc4, Widget.DELETE_RANGE, 0);
 	closures [Widget.DELETE_TEXT] = OS.g_cclosure_new (windowProc4, Widget.DELETE_TEXT, 0);
+	closures [Widget.ICON_RELEASE] = OS.g_cclosure_new (windowProc4, Widget.ICON_RELEASE, 0);
 	closures [Widget.ROW_ACTIVATED] = OS.g_cclosure_new (windowProc4, Widget.ROW_ACTIVATED, 0);
 	closures [Widget.SCROLL_CHILD] = OS.g_cclosure_new (windowProc4, Widget.SCROLL_CHILD, 0);
 	closures [Widget.STATUS_ICON_POPUP_MENU] = OS.g_cclosure_new (windowProc4, Widget.STATUS_ICON_POPUP_MENU, 0);
@@ -2537,22 +2592,16 @@ void initializeCallbacks () {
 
 void initializeSubclasses () {
 	if (OS.GTK_VERSION >= OS.VERSION (2, 4, 0)) {
-		pangoLayoutNewCallback = new Callback (this, "pangoLayoutNewProc", 3); //$NON-NLS-1$
-		pangoLayoutNewProc = pangoLayoutNewCallback.getAddress ();
-		if (pangoLayoutNewProc == 0) error (SWT.ERROR_NO_MORE_CALLBACKS);
 		int /*long*/ pangoLayoutType = OS.PANGO_TYPE_LAYOUT ();
 		int /*long*/ pangoLayoutClass = OS.g_type_class_ref (pangoLayoutType);
-		pangoLayoutNewDefaultProc = OS.G_OBJECT_CLASS_CONSTRUCTOR (pangoLayoutClass);
-		OS.G_OBJECT_CLASS_SET_CONSTRUCTOR (pangoLayoutClass, pangoLayoutNewProc);
+		pangoLayoutNewProc = OS.G_OBJECT_CLASS_CONSTRUCTOR (pangoLayoutClass);
+		OS.G_OBJECT_CLASS_SET_CONSTRUCTOR (pangoLayoutClass, OS.pangoLayoutNewProc_CALLBACK(pangoLayoutNewProc));
 		OS.g_type_class_unref (pangoLayoutClass);
 	}
 }
 
 void initializeSystemSettings () {
-	styleSetCallback = new Callback (this, "styleSetProc", 3); //$NON-NLS-1$
-	styleSetProc = styleSetCallback.getAddress ();
-	if (styleSetProc == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS);
-	OS.g_signal_connect (shellHandle, OS.style_set, styleSetProc, 0);
+	OS.g_signal_connect (shellHandle, OS.style_set, signalProc, STYLE_SET);
 	
 	/*
 	* Feature in GTK.  Despite the fact that the
@@ -2609,6 +2658,8 @@ void initializeWindowManager () {
  *
  * @param hDC the platform specific GC handle
  * @param data the platform specific GC data 
+ * 
+ * @noreference This method is not intended to be referenced by clients.
  */
 public void internal_dispose_GC (int /*long*/ gdkGC, GCData data) {
 	OS.g_object_unref (gdkGC);
@@ -2633,6 +2684,8 @@ public void internal_dispose_GC (int /*long*/ gdkGC, GCData data) {
  * @exception SWTError <ul>
  *    <li>ERROR_NO_HANDLES if a handle could not be obtained for gc creation</li>
  * </ul>
+ * 
+ * @noreference This method is not intended to be referenced by clients.
  */
 public int /*long*/ internal_new_GC (GCData data) {
 	if (isDisposed()) SWT.error(SWT.ERROR_DEVICE_DISPOSED);
@@ -2897,12 +2950,6 @@ int /*long*/ mouseHoverProc (int /*long*/ handle) {
 	return widget.hoverProc (handle);
 }
 
-int /*long*/ pangoLayoutNewProc (int /*long*/ type, int /*long*/ n_construct_properties, int /*long*/ construct_properties) {
-	int /*long*/ layout = OS.Call (pangoLayoutNewDefaultProc, type, (int)/*64*/n_construct_properties, construct_properties);
-	OS.pango_layout_set_auto_dir (layout, false);
-	return layout;
-}
-
 /**
  * Generate a low level system event.
  * 
@@ -3104,6 +3151,8 @@ void putGdkEvents () {
  */
 public boolean readAndDispatch () {
 	checkDevice ();
+	runSkin ();
+	runDeferredLayouts ();
 	boolean events = false;
 	events |= runSettings ();
 	events |= runPopups ();
@@ -3313,18 +3362,16 @@ void releaseDisplay () {
 	shellHandle = 0;
 	
 	/* Dispose the settings callback */
-	styleSetCallback.dispose(); styleSetCallback = null;
-	styleSetProc = 0;
+	signalCallback.dispose(); signalCallback = null;
+	signalProc = 0;
 
 	/* Dispose subclass */
 	if (OS.GTK_VERSION >= OS.VERSION (2, 4, 0)) {
 		int /*long*/ pangoLayoutType = OS.PANGO_TYPE_LAYOUT ();
 		int /*long*/ pangoLayoutClass = OS.g_type_class_ref (pangoLayoutType);
-		OS.G_OBJECT_CLASS_SET_CONSTRUCTOR (pangoLayoutClass, pangoLayoutNewDefaultProc);
+		OS.G_OBJECT_CLASS_SET_CONSTRUCTOR (pangoLayoutClass, pangoLayoutNewProc);
 		OS.g_type_class_unref (pangoLayoutClass);
-		pangoLayoutNewCallback.dispose ();
-		pangoLayoutNewCallback = null;
-		pangoLayoutNewDefaultProc = pangoLayoutNewProc = 0;
+		pangoLayoutNewProc = 0;
 	}
 	
 	/* Release the sleep resources */
@@ -3506,6 +3553,21 @@ boolean runDeferredEvents () {
 	return run;
 }
 
+boolean runDeferredLayouts () {
+	if (layoutDeferredCount != 0) {
+		Composite[] temp = layoutDeferred;
+		int count = layoutDeferredCount;
+		layoutDeferred = null;
+		layoutDeferredCount = 0;
+		for (int i = 0; i < count; i++) {
+			Composite comp = temp[i];
+			if (!comp.isDisposed()) comp.setLayoutDeferred (false);
+		}
+		return true;
+	}	
+	return false;
+}
+
 boolean runPopups () {
 	if (popups == null) return false;
 	boolean result = false;
@@ -3541,11 +3603,66 @@ boolean runSettings () {
 	return true;
 }
 
+boolean runSkin () {
+	if (skinCount > 0) {
+		Widget [] oldSkinWidgets = skinList;	
+		int count = skinCount;	
+		skinList = new Widget[GROW_SIZE];
+		skinCount = 0;
+		if (eventTable != null && eventTable.hooks(SWT.Skin)) {
+			for (int i = 0; i < count; i++) {
+				Widget widget = oldSkinWidgets[i];
+				if (widget != null && !widget.isDisposed()) {
+					widget.state &= ~Widget.SKIN_NEEDED;
+					oldSkinWidgets[i] = null;
+					Event event = new Event ();
+					event.widget = widget;
+					sendEvent (SWT.Skin, event);
+				}
+			}
+		}
+		return true;
+	}	
+	return false;
+}
+
 /**
- * On platforms which support it, sets the application name
- * to be the argument. On Motif, for example, this can be used
- * to set the name used for resource lookup.  Specifying
- * <code>null</code> for the name clears it.
+ * Returns the application name.
+ *
+ * @return the application name
+ * 
+ * @see #setAppName(String)
+ * 
+ * @since 3.6
+ */
+public static String getAppName () {
+	return APP_NAME;
+}
+	
+/**
+ * Returns the application version.
+ *
+ * @return the application version
+ * 
+ * @see #setAppVersion(String)
+ * 
+ * @since 3.6
+ */
+public static String getAppVersion () {
+	return APP_VERSION;
+}
+
+/**
+ * Sets the application name to the argument.
+ * <p>
+ * The application name can be used in several ways,
+ * depending on the platform and tools being used.
+ * On Motif, for example, this can be used to set
+ * the name used for resource lookup. Accessibility
+ * tools may also ask for the application name.
+ * </p><p>
+ * Specifying <code>null</code> for the name clears it.
+ * </p>
  *
  * @param name the new app name or <code>null</code>
  */
@@ -3554,6 +3671,17 @@ public static void setAppName (String name) {
 }
 
 /**
+ * Sets the application version to the argument.
+ *
+ * @param version the new app version
+ * 
+ * @since 3.6
+ */
+public static void setAppVersion (String version) {
+	APP_VERSION = version;
+}
+
+/**
  * Sets the location of the on-screen pointer relative to the top left corner
  * of the screen.  <b>Note: It is typically considered bad practice for a
  * program to move the on-screen pointer location.</b>
@@ -4071,8 +4199,49 @@ int /*long*/ shellMapProc (int /*long*/ handle, int /*long*/ arg0, int /*long*/
 	return widget.shellMapProc (handle, arg0, user_data);
 }
 
-int /*long*/ styleSetProc (int /*long*/ gobject, int /*long*/ arg1, int /*long*/ user_data) {
-	settingsChanged = true;
+int /*long*/ signalProc (int /*long*/ gobject, int /*long*/ arg1, int /*long*/ user_data) {
+	switch((int)/*64*/user_data) {
+		case STYLE_SET:
+			settingsChanged = true;
+			break;
+		case PROPERTY_NOTIFY:
+			GdkEventProperty gdkEvent = new GdkEventProperty ();
+			OS.memmove (gdkEvent, arg1);
+			if (gdkEvent.type == OS.GDK_PROPERTY_NOTIFY) {
+				byte[] name = Converter.wcsToMbcs (null, "org.eclipse.swt.filePath.message", true); //$NON-NLS-1$
+				int /*long*/ atom = OS.gdk_x11_atom_to_xatom (OS.gdk_atom_intern (name, true));
+				if (atom == OS.gdk_x11_atom_to_xatom (gdkEvent.atom)) {
+					int /*long*/ xWindow = OS.gdk_x11_drawable_get_xid (OS.GTK_WIDGET_WINDOW( shellHandle));
+					int /*long*/ [] type = new int /*long*/ [1];
+					int [] format = new int [1];
+					int [] nitems = new int [1];
+					int [] bytes_after = new int [1];
+					int /*long*/ [] data = new int /*long*/ [1];
+					OS.XGetWindowProperty (OS.GDK_DISPLAY (), xWindow, atom, 0, -1, true, OS.AnyPropertyType,
+							type, format, nitems, bytes_after, data);
+					
+					if (nitems [0] > 0) {
+						byte [] buffer = new byte [nitems [0]];
+						OS.memmove(buffer, data [0], buffer.length);
+						OS.XFree (data [0]);
+						char[] chars = Converter.mbcsToWcs(null, buffer);
+						String string = new String (chars);
+						
+						int lastIndex = 0;
+						int index = string.indexOf (':');
+						while (index != -1) {
+							String file = string.substring (lastIndex, index);
+							Event event = new Event ();
+							event.text = file;
+							sendEvent (SWT.OpenDocument, event);
+							lastIndex = index+1;
+							index = string.indexOf(':', lastIndex);
+						}
+					}
+				}
+			}
+			break;
+	}
 	return 0;
 }
 
diff --git a/org/eclipse/swt/widgets/Event.java b/org/eclipse/swt/widgets/Event.java
index a37abe1..d67ea3d 100644
--- a/org/eclipse/swt/widgets/Event.java
+++ b/org/eclipse/swt/widgets/Event.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 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
@@ -109,9 +109,10 @@ public class Event {
 
 	/**
 	 * depending on the event type, the number of following
-	 * paint events which are pending which may always be zero
-	 * on some platforms or the number of lines or pages to
-	 * scroll using the mouse wheel
+	 * paint events that are pending which may always be zero
+	 * on some platforms, or the number of lines or pages to
+	 * scroll using the mouse wheel, or the number of times the
+	 * mouse has been clicked
 	 */
 	public int count;
 	
@@ -156,10 +157,35 @@ public class Event {
 	public int keyCode;
 	
 	/**
+	 * depending on the event, the location of key specified by the 
+	 * keyCode or character. The possible values for this field are 
+	 * <code>SWT.LEFT</code>, <code>SWT.RIGHT</code>, <code>SWT.KEYPAD</code>,
+	 * or <code>SWT.NONE</code> representing the main keyboard area.
+	 * <p>
+	 * The location field can be used to differentiate key events that have 
+	 * the same key code and character but are generated by different keys 
+	 * in the keyboard. For example, a key down event with the key code equals
+	 * to SWT.SHIFT can be generated by the left and the right shift keys in the 
+	 * keyboard. The location field can only be used to determine the location 
+	 * of the key code or character in the current event. It does not 
+	 * include information about the location of modifiers in state
+	 * mask.
+	 * </p>
+	 * 
+	 * @see org.eclipse.swt.SWT#LEFT
+	 * @see org.eclipse.swt.SWT#RIGHT
+	 * @see org.eclipse.swt.SWT#KEYPAD
+	 * 
+	 * @since 3.6
+	 */
+	public int keyLocation;
+	
+	/**
 	 * depending on the event, the state of the keyboard modifier
 	 * keys and mouse masks at the time the event was generated.
 	 * 
-	 * @see org.eclipse.swt.SWT
+	 * @see org.eclipse.swt.SWT#MODIFIER_MASK
+	 * @see org.eclipse.swt.SWT#BUTTON_MASK
 	 */
 	public int stateMask;
 	
diff --git a/org/eclipse/swt/widgets/ExpandBar.java b/org/eclipse/swt/widgets/ExpandBar.java
index b3584f8..ec6e586 100644
--- a/org/eclipse/swt/widgets/ExpandBar.java
+++ b/org/eclipse/swt/widgets/ExpandBar.java
@@ -408,6 +408,7 @@ int /*long*/ gtk_button_release_event (int /*long*/ widget, int /*long*/ event)
 }
 
 int /*long*/ gtk_expose_event (int /*long*/ widget, int /*long*/ eventPtr) {
+	if ((state & OBSCURED) != 0) return 0;
 	if (OS.GTK_VERSION < OS.VERSION (2, 4, 0)) {
 		GdkEventExpose gdkEvent = new GdkEventExpose ();
 		OS.memmove(gdkEvent, eventPtr, GdkEventExpose.sizeof);
@@ -601,6 +602,16 @@ public void removeExpandListener (ExpandListener listener) {
 	eventTable.unhook (SWT.Collapse, listener);
 }
 
+void reskinChildren (int flags) {
+	if (items != null) {
+		for (int i=0; i<items.length; i++) {
+			ExpandItem item = items [i];
+			if (item != null ) item.reskin (flags);
+		}
+	}
+	super.reskinChildren (flags);
+}
+
 int setBounds (int x, int y, int width, int height, boolean move, boolean resize) {
 	int result = super.setBounds (x, y, width, height, move, resize);
 	if (OS.GTK_VERSION < OS.VERSION (2, 4, 0)) {
diff --git a/org/eclipse/swt/widgets/FileDialog.java b/org/eclipse/swt/widgets/FileDialog.java
index 6cbca21..1dd6921 100644
--- a/org/eclipse/swt/widgets/FileDialog.java
+++ b/org/eclipse/swt/widgets/FileDialog.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -49,6 +49,7 @@ public class FileDialog extends Dialog {
 	int /*long*/ handle;
 	static final char SEPARATOR = System.getProperty ("file.separator").charAt (0);
 	static final char EXTENSION_SEPARATOR = ';';
+	static final char FILE_EXTENSION_SEPARATOR = '.';
 	
 /**
  * Constructs a new instance of this class given only its parent.
@@ -101,7 +102,7 @@ public FileDialog (Shell parent, int style) {
 String computeResultChooserDialog () {
 	/* MULTI is only valid if the native dialog's action is Open */
 	fullPath = null;
-	if ((style & (SWT.SAVE | SWT.MULTI)) == SWT.MULTI) {
+	if ((style & SWT.MULTI) != 0) {
 		int /*long*/ list = 0;
 		if (uriMode) {
 			list = OS.gtk_file_chooser_get_uris (handle);
@@ -197,9 +198,24 @@ String computeResultChooserDialog () {
 		int separatorIndex = fullPath.lastIndexOf (SEPARATOR);
 		fileName = fullPath.substring (separatorIndex + 1);
 		filterPath = fullPath.substring (0, separatorIndex);
+		int fileExtensionIndex = fileName.indexOf(FILE_EXTENSION_SEPARATOR);
+		if ((style & SWT.SAVE) != 0 && fileExtensionIndex == -1 && filterIndex != -1) {
+			if (filterExtensions.length > filterIndex) {
+				String selection = filterExtensions [filterIndex];
+				int length = selection.length ();
+				int index = selection.indexOf (EXTENSION_SEPARATOR);
+				if (index == -1) index = length;
+				String extension = selection.substring (0, index).trim ();
+				if (!extension.equals ("*") && !extension.equals ("*.*")) {
+					if (extension.startsWith ("*.")) extension = extension.substring (1);
+					fullPath = fullPath + extension;
+				}	
+			}
+		}
 	}
 	return fullPath;
 }
+
 String computeResultClassicDialog () {
 	filterIndex = -1;
 	GtkFileSelection selection = new GtkFileSelection ();
@@ -248,7 +264,6 @@ String computeResultClassicDialog () {
 	OS.g_free (utf16Ptr);
 	OS.g_free (utf8Ptr);
 
-	if (osAnswer == null) return null;
 	int separatorIndex = osAnswer.lastIndexOf (SEPARATOR);
 	if (separatorIndex+1 == osAnswer.length ()) return null;
 	
@@ -399,6 +414,10 @@ String openChooserDialog () {
 		handle = OS.gtk_file_chooser_dialog_new (titleBytes, shellHandle, action, OS.GTK_STOCK_OK (), OS.GTK_RESPONSE_OK, OS.GTK_STOCK_CANCEL (), OS.GTK_RESPONSE_CANCEL, 0);
 	}
 	OS.gtk_window_set_modal (handle, true);
+	if (OS.GTK_VERSION >= OS.VERSION (2, 10, 0)) {
+		int /*long*/ group = OS.gtk_window_get_group(0);
+		OS.gtk_window_group_add_window (group, handle);
+	}
 	int /*long*/ pixbufs = OS.gtk_window_get_icon_list (shellHandle);
 	if (pixbufs != 0) {
 		OS.gtk_window_set_icon_list (handle, pixbufs);
@@ -531,7 +550,11 @@ void presetChooserDialog () {
 			*/
 			int /*long*/ ptr = OS.realpath (buffer, null);
 			if (ptr != 0) {
-				OS.gtk_file_chooser_set_filename (handle, ptr);
+				if (fileName.length() > 0) {
+					OS.gtk_file_chooser_set_filename (handle, ptr);
+				} else { 
+					OS.gtk_file_chooser_set_current_folder (handle, ptr);	
+				}
 				OS.g_free (ptr);
 			}
 		}
diff --git a/org/eclipse/swt/widgets/FontDialog.java b/org/eclipse/swt/widgets/FontDialog.java
index d2c7d32..8ba5db6 100644
--- a/org/eclipse/swt/widgets/FontDialog.java
+++ b/org/eclipse/swt/widgets/FontDialog.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -148,6 +148,10 @@ public FontData open () {
 			OS.g_list_free (pixbufs);
 		}
 	}
+	if (OS.GTK_VERSION >= OS.VERSION (2, 10, 0)) {
+		int /*long*/ group = OS.gtk_window_get_group(0);
+		OS.gtk_window_group_add_window (group, handle);
+	}
 	OS.gtk_window_set_modal (handle, true);
 	if (fontData != null) {
 		Font font = new Font (display, fontData);
diff --git a/org/eclipse/swt/widgets/Label.java b/org/eclipse/swt/widgets/Label.java
index 82ec5be..7d5b03a 100644
--- a/org/eclipse/swt/widgets/Label.java
+++ b/org/eclipse/swt/widgets/Label.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -14,6 +14,7 @@ package org.eclipse.swt.widgets;
 import org.eclipse.swt.*;
 import org.eclipse.swt.internal.*;
 import org.eclipse.swt.internal.gtk.*;
+import org.eclipse.swt.accessibility.*;
 import org.eclipse.swt.graphics.*;
 
 /**
@@ -108,11 +109,8 @@ static int checkStyle (int style) {
 void addRelation (Control control) {
 	if (!control.isDescribedByLabel ()) return;
 	if (labelHandle == 0) return;
-	int /*long*/ accessible = OS.gtk_widget_get_accessible (labelHandle);
-	int /*long*/ controlAccessible = OS.gtk_widget_get_accessible (control.handle);
-	if (accessible != 0 && controlAccessible != 0) {
-		OS.atk_object_add_relationship (controlAccessible, OS.ATK_RELATION_LABELLED_BY, accessible);
-	}
+	control._getAccessible().addRelation(ACC.RELATION_LABELLED_BY, _getAccessible());
+	control.labelRelation = this;
 }
 
 public Point computeSize (int wHint, int hHint, boolean changed) {
diff --git a/org/eclipse/swt/widgets/Link.java b/org/eclipse/swt/widgets/Link.java
index 265b3dc..6495b79 100644
--- a/org/eclipse/swt/widgets/Link.java
+++ b/org/eclipse/swt/widgets/Link.java
@@ -337,7 +337,7 @@ int /*long*/ gtk_button_release_event (int /*long*/ widget, int /*long*/ event)
 			if (rect.contains (x, y)) {
 				Event ev = new Event ();
 				ev.text = ids [focusIndex];
-				sendEvent (SWT.Selection, ev);
+				sendSelectionEvent (SWT.Selection, ev, true);
 				return result;
 			}
 		}
@@ -410,7 +410,7 @@ int /*long*/ gtk_key_press_event (int /*long*/ widget, int /*long*/ eventPtr) {
 		case OS.GDK_space:
 			Event event = new Event ();
 			event.text = ids [focusIndex];
-			sendEvent (SWT.Selection, event);
+			sendSelectionEvent (SWT.Selection, event, true);
 			break;
 		case OS.GDK_Tab:
 			if (focusIndex < offsets.length - 1) {
@@ -465,6 +465,38 @@ int /*long*/ gtk_motion_notify_event (int /*long*/ widget, int /*long*/ event) {
 	return result;
 }
 
+boolean mnemonicHit (char key) {
+	char uckey = Character.toUpperCase (key);
+	String parsedText = layout.getText();
+	for (int i = 0; i < mnemonics.length - 1; i++) {
+		if (mnemonics[i] != -1) {
+			char mnemonic = parsedText.charAt(mnemonics[i]);
+			if (uckey == Character.toUpperCase (mnemonic)) {
+				if (!setFocus ()) return false;
+				focusIndex = i;
+				redraw ();
+				return  true;
+			}
+		}
+	}
+	return false;
+}
+
+boolean mnemonicMatch (char key) {
+	char uckey = Character.toUpperCase (key);
+	String parsedText = layout.getText();
+	for (int i = 0; i < mnemonics.length - 1; i++) {
+		if (mnemonics[i] != -1) {
+			char mnemonic = parsedText.charAt(mnemonics[i]);
+			if (uckey == Character.toUpperCase (mnemonic)) { 
+				return true;
+			}
+		}
+	}
+	return false;
+}
+
+
 void releaseWidget () {
 	super.releaseWidget ();
 	if (layout != null)	layout.dispose ();
@@ -680,6 +712,18 @@ void setFontDescription (int /*long*/ font) {
  * include the mnemonic character and line delimiters. The only delimiter
  * the HREF attribute supports is the quotation mark (").
  * </p>
+ * <p>
+ * Mnemonics are indicated by an '&amp;' that causes the next
+ * character to be the mnemonic. The receiver can have a    
+ * mnemonic in the text preceding each link. When the user presses a
+ * key sequence that matches the mnemonic, focus is assigned
+ * to the link that follows the text. Mnemonics in links and in
+ * the trailing text are ignored. On most platforms,
+ * the mnemonic appears underlined but may be emphasised in a
+ * platform specific manner.  The mnemonic indicator character
+ * '&amp;' can be escaped by doubling it in the string, causing
+ * a single '&amp;' to be displayed.
+ * </p> 
  * 
  * @param string the new text
  *
diff --git a/org/eclipse/swt/widgets/List.java b/org/eclipse/swt/widgets/List.java
index b1df97f..064475d 100644
--- a/org/eclipse/swt/widgets/List.java
+++ b/org/eclipse/swt/widgets/List.java
@@ -715,7 +715,7 @@ public int getTopIndex () {
 }
 
 int /*long*/ gtk_changed (int /*long*/ widget) {
-	postEvent (SWT.Selection);
+	sendSelectionEvent (SWT.Selection);
 	return 0;
 }
 
@@ -790,7 +790,7 @@ int /*long*/ gtk_key_press_event (int /*long*/ widget, int /*long*/ event) {
 		switch (key) {
 			case OS.GDK_Return:
 			case OS.GDK_KP_Enter: {
-				postEvent (SWT.DefaultSelection);
+				sendSelectionEvent (SWT.DefaultSelection);
 				break;
 			}
 		}
@@ -813,7 +813,7 @@ int /*long*/ gtk_popup_menu (int /*long*/ widget) {
 }
 
 int /*long*/ gtk_row_activated (int /*long*/ tree, int /*long*/ path, int /*long*/ column) {
-	postEvent (SWT.DefaultSelection);
+	sendSelectionEvent (SWT.DefaultSelection);
 	return 0;
 }
 
diff --git a/org/eclipse/swt/widgets/Menu.java b/org/eclipse/swt/widgets/Menu.java
index 5e042a6..e585ee1 100644
--- a/org/eclipse/swt/widgets/Menu.java
+++ b/org/eclipse/swt/widgets/Menu.java
@@ -834,6 +834,15 @@ public void removeHelpListener (HelpListener listener) {
 	eventTable.unhook (SWT.Help, listener);
 }
 
+void reskinChildren (int flags) {
+	MenuItem [] items = getItems ();
+	for (int i=0; i<items.length; i++) {
+		MenuItem item = items [i];
+		item.reskin (flags);
+	}
+	super.reskinChildren (flags);
+}
+
 boolean sendHelpEvent (int /*long*/ helpType) {
 	if (selectedItem != null && !selectedItem.isDisposed()) {
 		if (selectedItem.hooks (SWT.Help)) {
diff --git a/org/eclipse/swt/widgets/MenuItem.java b/org/eclipse/swt/widgets/MenuItem.java
index d676e46..d98c282 100644
--- a/org/eclipse/swt/widgets/MenuItem.java
+++ b/org/eclipse/swt/widgets/MenuItem.java
@@ -197,7 +197,13 @@ public void addHelpListener (HelpListener listener) {
  * When <code>widgetSelected</code> is called, the stateMask field of the event object is valid.
  * <code>widgetDefaultSelected</code> is not called.
  * </p>
- *
+ * <p>
+ * When the <code>SWT.RADIO</code> style bit is set, the <code>widgetSelected</code> method is
+ * also called when the receiver loses selection because another item in the same radio group 
+ * was selected by the user. During <code>widgetSelected</code> the application can use
+ * <code>getSelection()</code> to determine the current selected state of the receiver.
+ * </p>
+ * 
  * @param listener the listener which should be notified when the menu item is selected by the user
  *
  * @exception IllegalArgumentException <ul>
@@ -411,31 +417,12 @@ int /*long*/ gtk_activate (int /*long*/ widget) {
 	* activate signals when an ancestor menu is disabled.
 	*/
 	if (!isEnabled ()) return 0;
-	Event event = new Event ();
-	int /*long*/ ptr = OS.gtk_get_current_event ();
-	if (ptr != 0) {
-		GdkEvent gdkEvent = new GdkEvent ();
-		OS.memmove (gdkEvent, ptr, GdkEvent.sizeof);
-		switch (gdkEvent.type) {
-			case OS.GDK_KEY_PRESS:
-			case OS.GDK_KEY_RELEASE: 
-			case OS.GDK_BUTTON_PRESS:
-			case OS.GDK_2BUTTON_PRESS: 
-			case OS.GDK_BUTTON_RELEASE: {
-				int [] state = new int [1];
-				OS.gdk_event_get_state (ptr, state);
-				setInputState (event, state [0]);
-				break;
-			}
-		}
-		OS.gdk_event_free (ptr);
-	}
 	if ((style & SWT.RADIO) != 0) {
 		if ((parent.getStyle () & SWT.NO_RADIO_GROUP) == 0) {
 			selectRadio ();
 		}
 	}
-	postEvent (SWT.Selection, event);
+	sendSelectionEvent (SWT.Selection);
 	return 0;
 }
 
@@ -593,6 +580,12 @@ public void removeSelectionListener (SelectionListener listener) {
 	eventTable.unhook (SWT.Selection, listener);
 	eventTable.unhook (SWT.DefaultSelection,listener);	
 }
+void reskinChildren (int flags) {
+	if (menu != null) {
+		menu.reskin (flags);
+	}
+	super.reskinChildren (flags);
+}
 void selectRadio () {
 	int index = 0;
 	MenuItem [] items = parent.getItems ();
@@ -765,7 +758,7 @@ boolean setRadioSelection (boolean value) {
 	if ((style & SWT.RADIO) == 0) return false;
 	if (getSelection () != value) {
 		setSelection (value);
-		postEvent (SWT.Selection);
+		sendSelectionEvent (SWT.Selection);
 	}
 	return true;
 }
diff --git a/org/eclipse/swt/widgets/MessageBox.java b/org/eclipse/swt/widgets/MessageBox.java
index 3d1cfd1..2a74df6 100644
--- a/org/eclipse/swt/widgets/MessageBox.java
+++ b/org/eclipse/swt/widgets/MessageBox.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -167,6 +167,16 @@ public int open () {
 	OS.gtk_window_set_title(handle,buffer);
 	display.addIdleProc ();
 	Dialog oldModal = null;
+	/*
+	* In order to allow the dialog to be modal of it's
+	* parent shells, it is required to assign the 
+	* dialog to the same window group as of the shells.
+	*/
+	if (OS.GTK_VERSION >= OS.VERSION (2, 10, 0)) {
+		int /*long*/ group = OS.gtk_window_get_group(0);
+		OS.gtk_window_group_add_window (group, handle);
+	}
+	
 	if (OS.gtk_window_get_modal (handle)) {
 		oldModal = display.getModalDialog ();
 		display.setModalDialog (this);
diff --git a/org/eclipse/swt/widgets/Sash.java b/org/eclipse/swt/widgets/Sash.java
index 4c5d29c..b2747da 100644
--- a/org/eclipse/swt/widgets/Sash.java
+++ b/org/eclipse/swt/widgets/Sash.java
@@ -193,7 +193,7 @@ int /*long*/ gtk_button_press_event (int /*long*/ widget, int /*long*/ eventPtr)
 		event.detail = SWT.DRAG;
 	}
 	if ((parent.style & SWT.MIRRORED) != 0) event.x = parent.getClientWidth () - width  - event.x;
-	sendEvent (SWT.Selection, event);
+	sendSelectionEvent (SWT.Selection, event, true);
 	if (isDisposed ()) return 0;
 	if (event.doit) {
 		dragging = true;
@@ -229,7 +229,7 @@ int /*long*/ gtk_button_release_event (int /*long*/ widget, int /*long*/ eventPt
 	event.height = height;
 	drawBand (lastX, lastY, width, height);
 	if ((parent.style & SWT.MIRRORED) != 0) event.x = parent.getClientWidth () - width  - event.x;
-	sendEvent (SWT.Selection, event);
+	sendSelectionEvent (SWT.Selection, event, true);
 	if (isDisposed ()) return result;
 	if (event.doit) {
 		if ((style & SWT.SMOOTH) != 0) {
@@ -300,7 +300,7 @@ int /*long*/ gtk_key_press_event (int /*long*/ widget, int /*long*/ eventPtr) {
 			event.width = width;
 			event.height = height;
 			if ((parent.style & SWT.MIRRORED) != 0) event.x = parent.getClientWidth () - width  - event.x;
-			sendEvent (SWT.Selection, event);
+			sendSelectionEvent (SWT.Selection, event, true);
 			if (ptrGrabResult == OS.GDK_GRAB_SUCCESS) OS.gdk_pointer_ungrab (OS.GDK_CURRENT_TIME);
 			if (isDisposed ()) break;
 			
@@ -373,7 +373,7 @@ int /*long*/ gtk_motion_notify_event (int /*long*/ widget, int /*long*/ eventPtr
 		event.detail = SWT.DRAG;
 	}
 	if ((parent.style & SWT.MIRRORED) != 0) event.x = parent.getClientWidth() - width  - event.x;
-	sendEvent (SWT.Selection, event);
+	sendSelectionEvent (SWT.Selection, event, true);
 	if (isDisposed ()) return 0;
 	if (event.doit) {
 		lastX = event.x;
diff --git a/org/eclipse/swt/widgets/Scale.java b/org/eclipse/swt/widgets/Scale.java
index 47e6ebb..8784f03 100644
--- a/org/eclipse/swt/widgets/Scale.java
+++ b/org/eclipse/swt/widgets/Scale.java
@@ -240,7 +240,7 @@ public int getSelection () {
 }
 
 int /*long*/ gtk_value_changed (int /*long*/ adjustment) {
-	postEvent (SWT.Selection);
+	sendSelectionEvent  (SWT.Selection);
 	return 0;
 }
 
diff --git a/org/eclipse/swt/widgets/ScrollBar.java b/org/eclipse/swt/widgets/ScrollBar.java
index b2fcd24..07580ec 100644
--- a/org/eclipse/swt/widgets/ScrollBar.java
+++ b/org/eclipse/swt/widgets/ScrollBar.java
@@ -306,8 +306,7 @@ public Point getSize () {
 }
 
 /**
- * Returns the size of the receiver's thumb relative to the
- * difference between its maximum and minimum values.
+ * Returns the receiver's thumb value.
  *
  * @return the thumb value
  *
@@ -326,6 +325,109 @@ public int getThumb () {
 }
 
 /**
+ * Returns a rectangle describing the size and location of the
+ * receiver's thumb relative to its parent.
+ * 
+ * @return the thumb bounds, relative to the {@link #getParent() parent}
+ *
+ * @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>
+ * 
+ * @since 3.6
+ */
+public Rectangle getThumbBounds () {
+	checkWidget();
+	int slider_start = OS.GTK_RANGE_SLIDER_START (handle);
+	int slider_end = OS.GTK_RANGE_SLIDER_END (handle);
+	int x, y, width, height;
+	if ((style & SWT.VERTICAL) != 0) {
+		x = OS.GTK_WIDGET_X (handle);
+		y = slider_start;
+		width = OS.GTK_WIDGET_WIDTH (handle);
+		height = slider_end - slider_start;
+	} else {
+		x = slider_start;
+		y = OS.GTK_WIDGET_Y (handle);
+		width = slider_end - slider_start;
+		height = OS.GTK_WIDGET_HEIGHT (handle);
+	}
+	Rectangle rect = new Rectangle(x, y, width, height);
+	int [] origin_x = new int [1], origin_y = new int [1];
+	int /*long*/ window = OS.GTK_WIDGET_WINDOW (parent.scrolledHandle);
+	if (window != 0) OS.gdk_window_get_origin (window, origin_x, origin_y);
+	rect.x += origin_x [0];
+	rect.y += origin_y [0];
+	window = OS.GTK_WIDGET_WINDOW (parent.handle);
+	if (window != 0) OS.gdk_window_get_origin (window, origin_x, origin_y);
+	rect.x -= origin_x [0];
+	rect.y -= origin_y [0];
+	return rect;
+}
+
+/**
+ * Returns a rectangle describing the size and location of the
+ * receiver's thumb track relative to its parent. This rectangle
+ * comprises the areas 2, 3, and 4 as described in {@link ScrollBar}.
+ * 
+ * @return the thumb track bounds, relative to the {@link #getParent() parent}
+ *
+ * @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>
+ * 
+ * @since 3.6
+ */
+public Rectangle getThumbTrackBounds () {
+	checkWidget();
+	int x = 0, y = 0, width, height;
+	boolean hasA = OS.GTK_RANGE_HAS_STEPPER_A (handle);
+	boolean hasB = OS.GTK_RANGE_HAS_STEPPER_B (handle);
+	boolean hasC = OS.GTK_RANGE_HAS_STEPPER_C (handle);
+	boolean hasD = OS.GTK_RANGE_HAS_STEPPER_D (handle);
+	if ((style & SWT.VERTICAL) != 0) {
+		int stepperSize = OS.GTK_WIDGET_WIDTH (handle);
+		x = OS.GTK_WIDGET_X (handle);
+		if (hasA) y += stepperSize;
+		if (hasB) y += stepperSize;
+		width = OS.GTK_WIDGET_WIDTH (handle);
+		height = OS.GTK_WIDGET_HEIGHT (handle) - y;
+		if (hasC) height -= stepperSize;
+		if (hasD) height -= stepperSize;
+		if (height < 0) {
+			y = OS.GTK_RANGE_SLIDER_START (handle);
+			height = 0;
+		}
+	} else {
+		int stepperSize = OS.GTK_WIDGET_HEIGHT (handle);
+		if (hasA) x += stepperSize;
+		if (hasB) x += stepperSize;
+		y = OS.GTK_WIDGET_Y (handle);
+		width = OS.GTK_WIDGET_WIDTH (handle) - x;
+		if (hasC) width -= stepperSize;
+		if (hasD) width -= stepperSize;
+		height = OS.GTK_WIDGET_HEIGHT (handle);
+		if (width < 0) {
+			x = OS.GTK_RANGE_SLIDER_START (handle);
+			width = 0;
+		}
+	}
+	Rectangle rect = new Rectangle(x, y, width, height);
+	int [] origin_x = new int [1], origin_y = new int [1];
+	int /*long*/ window = OS.GTK_WIDGET_WINDOW (parent.scrolledHandle);
+	if (window != 0) OS.gdk_window_get_origin (window, origin_x, origin_y);
+	rect.x += origin_x [0];
+	rect.y += origin_y [0];
+	window = OS.GTK_WIDGET_WINDOW (parent.handle);
+	if (window != 0) OS.gdk_window_get_origin (window, origin_x, origin_y);
+	rect.x -= origin_x [0];
+	rect.y -= origin_y [0];
+	return rect;
+}
+
+/**
  * Returns <code>true</code> if the receiver is visible, and
  * <code>false</code> otherwise.
  * <p>
@@ -390,7 +492,7 @@ int /*long*/ gtk_value_changed (int /*long*/ adjustment) {
 	}
 	detail = OS.GTK_SCROLL_NONE;
 	if (!dragSent) detail = OS.GTK_SCROLL_NONE;
-	postEvent (SWT.Selection, event);
+	sendSelectionEvent (SWT.Selection, event, false);
 	parent.updateScrollBarValue (this);
 	return 0;
 }
@@ -406,9 +508,9 @@ int /*long*/ gtk_event_after (int /*long*/ widget, int /*long*/ gdkEvent) {
 				if (!dragSent) {
 					Event event = new Event ();
 					event.detail = SWT.DRAG;
-					postEvent (SWT.Selection, event);
+					sendSelectionEvent (SWT.Selection, event, false);
 				}
-				postEvent (SWT.Selection);
+				sendSelectionEvent (SWT.Selection);
 			}
 			detail = OS.GTK_SCROLL_NONE;
 			dragSent = false;
@@ -670,10 +772,13 @@ public void setSelection (int value) {
 }
 
 /**
- * Sets the size of the receiver's thumb relative to the
- * difference between its maximum and minimum values.  This new
- * value will be ignored if it is less than one, and will be
+ * Sets the thumb value. The thumb value should be used to represent 
+ * the size of the visual portion of the current range. This value is
+ * usually the same as the page increment value.
+ * <p>
+ * This new value will be ignored if it is less than one, and will be 
  * clamped if it exceeds the receiver's current range.
+ * </p>
  *
  * @param value the new thumb value, which must be at least one and not
  * larger than the size of the current range
diff --git a/org/eclipse/swt/widgets/Scrollable.java b/org/eclipse/swt/widgets/Scrollable.java
index ab33045..e349be0 100644
--- a/org/eclipse/swt/widgets/Scrollable.java
+++ b/org/eclipse/swt/widgets/Scrollable.java
@@ -276,6 +276,12 @@ int hScrollBarWidth() {
 	return requisition.height + spacing;
 }
 
+void reskinChildren (int flags) {
+	if (horizontalBar != null) horizontalBar.reskin (flags);
+	if (verticalBar != null) verticalBar.reskin (flags);
+	super.reskinChildren (flags);
+}
+
 boolean sendLeaveNotify () {
 	return scrolledHandle != 0;
 }
diff --git a/org/eclipse/swt/widgets/Shell.java b/org/eclipse/swt/widgets/Shell.java
index 9e3a131..b1d93b6 100644
--- a/org/eclipse/swt/widgets/Shell.java
+++ b/org/eclipse/swt/widgets/Shell.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -125,6 +125,7 @@ public class Shell extends Decorations {
 	ToolTip [] toolTips;
 
 	static final int MAXIMUM_TRIM = 128;
+	static final int BORDER = 3;
 
 /**
  * Constructs a new instance of this class. This is equivalent
@@ -275,6 +276,7 @@ Shell (Display display, Shell parent, int style, int /*long*/ handle, boolean em
 			state |= FOREIGN_HANDLE;
 		}
 	}
+	reskinWidget();
 	createWidget (0);
 }
 
@@ -375,6 +377,8 @@ public static Shell gtk_new (Display display, int /*long*/ handle) {
  * @param handle the handle for the shell
  * @return a new shell object containing the specified display and handle
  * 
+ * @noreference This method is not intended to be referenced by clients.
+ * 
  * @since 3.3
  */
 public static Shell internal_new (Display display, int /*long*/ handle) {
@@ -384,7 +388,7 @@ public static Shell internal_new (Display display, int /*long*/ handle) {
 static int checkStyle (Shell parent, int style) {
 	style = Decorations.checkStyle (style);
 	style &= ~SWT.TRANSPARENT;
-	if ((style & SWT.ON_TOP) != 0) style &= ~SWT.SHELL_TRIM;
+	if ((style & SWT.ON_TOP) != 0) style &= ~(SWT.CLOSE | SWT.TITLE | SWT.MIN | SWT.MAX);
 	int mask = SWT.SYSTEM_MODAL | SWT.APPLICATION_MODAL | SWT.PRIMARY_MODAL;
 	if ((style & SWT.SHEET) != 0) {
 		style &= ~SWT.SHEET;
@@ -620,6 +624,9 @@ public Rectangle computeTrim (int x, int y, int width, int height) {
 	if ((style & (SWT.NO_TRIM | SWT.BORDER | SWT.SHELL_TRIM)) == 0) {
 		border = OS.gtk_container_get_border_width (shellHandle);
 	}
+	if (isCustomResize ()) {
+		border = OS.gtk_container_get_border_width (shellHandle);
+	}
 	int trimWidth = trimWidth (), trimHeight = trimHeight ();
 	trim.x -= (trimWidth / 2) + border;
 	trim.y -= trimHeight - (trimWidth / 2) + border;
@@ -679,6 +686,9 @@ void createHandle (int index) {
 			OS.gtk_style_get_black (OS.gtk_widget_get_style (shellHandle), color);
 			OS.gtk_widget_modify_bg (shellHandle,  OS.GTK_STATE_NORMAL, color);
 		}
+		if (isCustomResize ()) {
+			OS.gtk_container_set_border_width (shellHandle, BORDER);
+		} 
 	} else {
 		vboxHandle = OS.gtk_bin_get_child (shellHandle);
 		if (vboxHandle == 0) error (SWT.ERROR_NO_HANDLES);
@@ -718,6 +728,10 @@ int /*long*/ filterProc (int /*long*/ xEvent, int /*long*/ gdkEvent, int /*long*
 						display.activeShell = this;
 						display.activePending = false;
 						sendEvent (SWT.Activate);
+						if (isDisposed ()) return 0;
+						if (isCustomResize ()) {
+							OS.gdk_window_invalidate_rect (OS.GTK_WIDGET_WINDOW (shellHandle), null, false);
+						}
 						break;
 				}
 			} 
@@ -736,6 +750,10 @@ int /*long*/ filterProc (int /*long*/ xEvent, int /*long*/ gdkEvent, int /*long*
 							display.activeShell = null;
 							display.activePending = false;
 						}
+						if (isDisposed ()) return 0;
+						if (isCustomResize ()) {
+							OS.gdk_window_invalidate_rect (OS.GTK_WIDGET_WINDOW (shellHandle), null, false);
+						}
 						break;
 				}
 			}
@@ -768,6 +786,14 @@ void hookEvents () {
 	OS.g_signal_connect_closure (shellHandle, OS.move_focus, display.closures [MOVE_FOCUS], false);
 	int /*long*/ window = OS.GTK_WIDGET_WINDOW (shellHandle);
 	OS.gdk_window_add_filter  (window, display.filterProc, shellHandle);
+	if (isCustomResize ()) {
+		int mask = OS.GDK_POINTER_MOTION_MASK | OS.GDK_BUTTON_RELEASE_MASK | OS.GDK_BUTTON_PRESS_MASK |  OS.GDK_ENTER_NOTIFY_MASK | OS.GDK_LEAVE_NOTIFY_MASK;
+		OS.gtk_widget_add_events (shellHandle, mask);
+		OS.g_signal_connect_closure_by_id (shellHandle, display.signalIds [EXPOSE_EVENT], 0, display.closures[EXPOSE_EVENT], false);
+		OS.g_signal_connect_closure_by_id (shellHandle, display.signalIds [LEAVE_NOTIFY_EVENT], 0, display.closures [LEAVE_NOTIFY_EVENT], false);
+		OS.g_signal_connect_closure_by_id (shellHandle, display.signalIds [MOTION_NOTIFY_EVENT], 0, display.closures [MOTION_NOTIFY_EVENT], false);
+		OS.g_signal_connect_closure_by_id (shellHandle, display.signalIds [BUTTON_PRESS_EVENT], 0, display.closures [BUTTON_PRESS_EVENT], false);
+	}
 }
 
 public boolean isEnabled () {
@@ -781,6 +807,10 @@ boolean isUndecorated () {
 		(style & (SWT.NO_TRIM | SWT.ON_TOP)) != 0;
 }
 
+boolean isCustomResize () {
+	return (style & SWT.NO_TRIM) == 0 && (style & (SWT.RESIZE | SWT.ON_TOP)) == (SWT.RESIZE | SWT.ON_TOP);
+}
+
 public boolean isVisible () {
 	checkWidget();
 	return getVisible ();
@@ -876,6 +906,31 @@ public int getAlpha () {
 	return 255;  
 }
 
+int getResizeMode (double x, double y) {
+	int width = OS.GTK_WIDGET_WIDTH (shellHandle);
+	int height = OS.GTK_WIDGET_HEIGHT (shellHandle);
+	int border = OS.gtk_container_get_border_width (shellHandle);
+	int mode = 0;
+	if (y >= height - border) {
+		mode = OS.GDK_BOTTOM_SIDE ;
+		if (x >= width - border - 16) mode = OS.GDK_BOTTOM_RIGHT_CORNER;
+		else if (x <= border + 16) mode = OS.GDK_BOTTOM_LEFT_CORNER;
+	} else if (x >= width - border) {
+		mode = OS.GDK_RIGHT_SIDE;
+		if (y >= height - border - 16) mode = OS.GDK_BOTTOM_RIGHT_CORNER;
+		else if (y <= border + 16) mode = OS.GDK_TOP_RIGHT_CORNER;
+	} else if (y <= border) {
+		mode = OS.GDK_TOP_SIDE;
+		if (x <= border + 16) mode = OS.GDK_TOP_LEFT_CORNER;
+		else if (x >= width - border - 16) mode = OS.GDK_TOP_RIGHT_CORNER;
+	} else if (x <= border) {
+		mode = OS.GDK_LEFT_SIDE;
+		if (y <= border + 16) mode = OS.GDK_TOP_LEFT_CORNER;
+		else if (y >= height - border - 16) mode = OS.GDK_BOTTOM_LEFT_CORNER;
+	}
+	return mode;
+}
+
 /**
  * Returns <code>true</code> if the receiver is currently
  * in fullscreen state, and false otherwise. 
@@ -1070,6 +1125,30 @@ public Shell [] getShells () {
 	return result;
 }
 
+int /*long*/ gtk_button_press_event (int /*long*/ widget, int /*long*/ event) {
+	if (widget == shellHandle) {
+		if (isCustomResize ()) {
+			if ((style & SWT.ON_TOP) != 0 && (style & SWT.NO_FOCUS) == 0) {
+				forceActive ();
+			}
+			GdkEventButton gdkEvent = new GdkEventButton ();
+			OS.memmove (gdkEvent, event, GdkEventButton.sizeof);
+			if (gdkEvent.button == 1) {
+				display.resizeLocationX = gdkEvent.x_root;
+				display.resizeLocationY = gdkEvent.y_root;
+				int [] x = new int [1], y = new int [1];
+				OS.gtk_window_get_position (shellHandle, x, y);
+				display.resizeBoundsX = x [0];
+				display.resizeBoundsY = y [0];
+				display.resizeBoundsWidth = OS.GTK_WIDGET_WIDTH (shellHandle);
+				display.resizeBoundsHeight = OS.GTK_WIDGET_HEIGHT (shellHandle);
+			}
+		}
+		return 0;
+	}
+	return super.gtk_button_press_event (widget, event);
+}
+
 int /*long*/ gtk_configure_event (int /*long*/ widget, int /*long*/ event) {
 	int [] x = new int [1], y = new int [1];
 	OS.gtk_window_get_position (shellHandle, x, y);
@@ -1095,13 +1174,43 @@ int /*long*/ gtk_enter_notify_event (int /*long*/ widget, int /*long*/ event) {
 	return 0;
 }
 
+int /*long*/ gtk_expose_event (int /*long*/ widget, int /*long*/ event) {
+	if (widget == shellHandle) {
+		if (isCustomResize ()) {
+			GdkEventExpose gdkEventExpose = new GdkEventExpose ();
+			OS.memmove (gdkEventExpose, event, GdkEventExpose.sizeof);
+			int /*long*/ style = OS.gtk_widget_get_style (widget);
+			int /*long*/ window = OS.GTK_WIDGET_WINDOW (widget);
+			int [] width = new int [1];
+			int [] height = new int [1];
+			OS.gdk_drawable_get_size (window, width, height);
+			GdkRectangle area = new GdkRectangle ();
+			area.x = gdkEventExpose.area_x;
+			area.y = gdkEventExpose.area_y;
+			area.width = gdkEventExpose.area_width;
+			area.height = gdkEventExpose.area_height;
+			byte [] detail = Converter.wcsToMbcs (null, "base", true); //$NON-NLS-1$
+			int border = OS.gtk_container_get_border_width (widget);
+			int state = display.activeShell == this ? OS.GTK_STATE_SELECTED : OS.GTK_STATE_PRELIGHT;
+			OS.gtk_paint_flat_box (style, window, state, OS.GTK_SHADOW_NONE, area, widget, detail, 0, 0, width [0], border);
+			OS.gtk_paint_flat_box (style, window, state, OS.GTK_SHADOW_NONE, area, widget, detail, 0, height [0] - border, width [0], border);
+			OS.gtk_paint_flat_box (style, window, state, OS.GTK_SHADOW_NONE, area, widget, detail, 0, border, border, height [0] - border - border);
+			OS.gtk_paint_flat_box (style, window, state, OS.GTK_SHADOW_NONE, area, widget, detail, width [0] - border, border, border, height [0] - border - border);
+			OS.gtk_paint_box (style, window, state, OS.GTK_SHADOW_OUT, area, widget, detail, 0, 0, width [0], height [0]);
+			return 1;
+		}
+		return 0;
+	}
+	return super.gtk_expose_event (widget, event);
+}
+
 int /*long*/ gtk_focus (int /*long*/ widget, int /*long*/ directionType) {
 	switch ((int)/*64*/directionType) {
 		case OS.GTK_DIR_TAB_FORWARD:
 		case OS.GTK_DIR_TAB_BACKWARD:
 			Control control = display.getFocusControl ();
 			if (control != null) {
-				if ((control.state & CANVAS) != 0 && (control.style & SWT.EMBEDDED) != 0) {
+				if ((control.state & CANVAS) != 0 && (control.style & SWT.EMBEDDED) != 0 && control.getShell () == this) {
 					int traversal = directionType == OS.GTK_DIR_TAB_FORWARD ? SWT.TRAVERSE_TAB_NEXT : SWT.TRAVERSE_TAB_PREVIOUS;
 					control.traverse (traversal);
 					return 1;
@@ -1112,6 +1221,22 @@ int /*long*/ gtk_focus (int /*long*/ widget, int /*long*/ directionType) {
 	return super.gtk_focus (widget, directionType);
 }
 
+int /*long*/ gtk_leave_notify_event (int /*long*/ widget, int /*long*/ event) {
+	if (widget == shellHandle) {
+		if (isCustomResize ()) {
+			GdkEventCrossing gdkEvent = new GdkEventCrossing ();
+			OS.memmove (gdkEvent, event, GdkEventCrossing.sizeof);
+			if ((gdkEvent.state & OS.GDK_BUTTON1_MASK) == 0) {
+				int /*long*/ window = OS.GTK_WIDGET_WINDOW (shellHandle);
+				OS.gdk_window_set_cursor (window, 0);
+				display.resizeMode = 0;
+			}
+		}
+		return 0;
+	}
+	return super.gtk_leave_notify_event (widget, event);
+}
+
 int /*long*/ gtk_move_focus (int /*long*/ widget, int /*long*/ directionType) {
 	Control control = display.getFocusControl ();
 	if (control != null) {
@@ -1122,6 +1247,78 @@ int /*long*/ gtk_move_focus (int /*long*/ widget, int /*long*/ directionType) {
 	return 1;
 }
 
+int /*long*/ gtk_motion_notify_event (int /*long*/ widget, int /*long*/ event) {
+	if (widget == shellHandle) {
+		if (isCustomResize ()) {
+			GdkEventMotion gdkEvent = new GdkEventMotion ();
+			OS.memmove (gdkEvent, event, GdkEventMotion.sizeof);
+			if ((gdkEvent.state & OS.GDK_BUTTON1_MASK) != 0) {
+				int border = OS.gtk_container_get_border_width (shellHandle);
+				int dx = (int)(gdkEvent.x_root - display.resizeLocationX);
+				int dy = (int)(gdkEvent.y_root - display.resizeLocationY);
+				int x = display.resizeBoundsX;
+				int y = display.resizeBoundsY;
+				int width = display.resizeBoundsWidth;
+				int height = display.resizeBoundsHeight;
+				int newWidth = Math.max(width - dx, Math.max(minWidth, border + border));
+				int newHeight = Math.max(height - dy, Math.max(minHeight, border + border));
+				switch (display.resizeMode) {
+					case OS.GDK_LEFT_SIDE:
+						x += width - newWidth;
+						width = newWidth;
+						break;
+					case OS.GDK_TOP_LEFT_CORNER:
+						x += width - newWidth;
+						width = newWidth;
+						y += height - newHeight;
+						height = newHeight;
+						break;
+					case OS.GDK_TOP_SIDE:
+						y += height - newHeight;
+						height = newHeight;
+						break;
+					case OS.GDK_TOP_RIGHT_CORNER:
+						width = Math.max(width + dx, Math.max(minWidth, border + border));
+						y += height - newHeight;
+						height = newHeight;
+						break;
+					case OS.GDK_RIGHT_SIDE:
+						width = Math.max(width + dx, Math.max(minWidth, border + border));
+						break;
+					case OS.GDK_BOTTOM_RIGHT_CORNER:
+						width = Math.max(width + dx, Math.max(minWidth, border + border));
+						height = Math.max(height + dy, Math.max(minHeight, border + border));
+						break;
+					case OS.GDK_BOTTOM_SIDE:
+						height = Math.max(height + dy, Math.max(minHeight, border + border));
+						break;
+					case OS.GDK_BOTTOM_LEFT_CORNER:
+						x += width - newWidth;
+						width = newWidth;
+						height = Math.max(height + dy, Math.max(minHeight, border + border));
+						break;
+				}
+				if (x != display.resizeBoundsX || y != display.resizeBoundsY) {
+					OS.gdk_window_move_resize (OS.GTK_WIDGET_WINDOW (shellHandle), x, y, width, height);
+				} else {
+					OS.gtk_window_resize (shellHandle, width, height);
+				}
+			} else {
+				int mode = getResizeMode (gdkEvent.x, gdkEvent.y);
+				if (mode != display.resizeMode) {
+					int /*long*/ window = OS.GTK_WIDGET_WINDOW (shellHandle);
+					int /*long*/ cursor = OS.gdk_cursor_new (mode);
+					OS.gdk_window_set_cursor (window, cursor);
+					OS.gdk_cursor_destroy (cursor);
+					display.resizeMode = mode;
+				}
+			}
+		}
+		return 0;
+	}
+	return super.gtk_motion_notify_event (widget, event);
+}
+
 int /*long*/ gtk_key_press_event (int /*long*/ widget, int /*long*/ event) {
 	/* Stop menu mnemonics when the shell is disabled */
 	if (widget == shellHandle) {
@@ -1260,6 +1457,21 @@ void removeTooTip (ToolTip toolTip) {
 	}
 }
 
+void reskinChildren (int flags) {
+	Shell [] shells = getShells ();
+	for (int i=0; i<shells.length; i++) {
+		Shell shell = shells [i];
+		if (shell != null) shell.reskin (flags);
+	}
+	if (toolTips != null) {
+		for (int i=0; i<toolTips.length; i++) {
+			ToolTip toolTip = toolTips [i];
+			if (toolTip != null) toolTip.reskin (flags);
+		}
+	}
+	super.reskinChildren (flags);
+}
+
 /**
  * If the receiver is visible, moves it to the top of the 
  * drawing order for the display on which it was created 
@@ -1406,7 +1618,11 @@ int setBounds (int x, int y, int width, int height, boolean move, boolean resize
 	if (resize) {
 		width = Math.max (1, Math.max (minWidth, width - trimWidth ()));
 		height = Math.max (1, Math.max (minHeight, height - trimHeight ()));
-		if ((style & SWT.RESIZE) != 0) OS.gtk_window_resize (shellHandle, width, height);
+		/*
+		* If the shell is created without a RESIZE style bit, and the
+		* minWidth/minHeight has been set, allow the resize.
+		*/
+		if ((style & SWT.RESIZE) != 0 || (minHeight != 0 || minWidth != 0)) OS.gtk_window_resize (shellHandle, width, height);
 		boolean changed = width != oldWidth || height != oldHeight;
 		if (changed) {
 			oldWidth = width;
@@ -1842,7 +2058,18 @@ int /*long*/ shellMapProc (int /*long*/ handle, int /*long*/ arg0, int /*long*/
 }
 
 void showWidget () {
-	if ((state & FOREIGN_HANDLE) != 0) return;
+	if ((state & FOREIGN_HANDLE) != 0) {
+		/*
+		* In case of foreign handles, activeShell might not be initialised as 
+		* no focusIn events are generated on the window until the window loses
+		* and gain focus.
+		*/
+		if (OS.GTK_VERSION >= OS.VERSION (2, 4, 0) && OS.gtk_window_is_active (shellHandle)) {
+			display.activeShell = this;
+			display.activePending = true;
+		}
+		return;
+	}
 	OS.gtk_container_add (shellHandle, vboxHandle);
 	if (scrolledHandle != 0) OS.gtk_widget_show (scrolledHandle);
 	if (handle != 0) OS.gtk_widget_show (handle);
@@ -1918,13 +2145,27 @@ int trimWidth () {
 }
 
 void updateModal () {
+	if (OS.GTK_IS_PLUG (shellHandle)) return;
 	int /*long*/ group = 0;
+	boolean isModalShell = false;
 	if (display.getModalDialog () == null) {
 		Shell modal = getModalShell ();
 		int mask = SWT.PRIMARY_MODAL | SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL;
 		Composite shell = null;
 		if (modal == null) {
-			if ((style & mask) != 0) shell = this;
+			if ((style & mask) != 0) {
+				shell = this;
+				/*
+				* Feature in GTK. If a modal shell is reassigned to
+				* a different group, then it's modal state is not.
+				* persisted against the new group. 
+				* The fix is to reset the modality before it is changed
+				* into a different group and then, set back after it
+				* assigned into new group.
+				*/
+				isModalShell = OS.gtk_window_get_modal (shellHandle);
+				if (isModalShell) OS.gtk_window_set_modal (shellHandle, false);
+			}
 		} else {
 			shell = modal;
 		}
@@ -1947,6 +2188,7 @@ void updateModal () {
 	}
 	if (group != 0) {
 		OS.gtk_window_group_add_window (group, shellHandle);
+		if (isModalShell) OS.gtk_window_set_modal (shellHandle, true);
 	} else {
 		if (modalGroup != 0) {
 			OS.gtk_window_group_remove_window (modalGroup, shellHandle);
diff --git a/org/eclipse/swt/widgets/Slider.java b/org/eclipse/swt/widgets/Slider.java
index 61d636b..957b792 100644
--- a/org/eclipse/swt/widgets/Slider.java
+++ b/org/eclipse/swt/widgets/Slider.java
@@ -210,7 +210,7 @@ int /*long*/ gtk_value_changed (int /*long*/ adjustment) {
 		case OS.GTK_SCROLL_STEP_BACKWARD:	event.detail = SWT.ARROW_UP; break;
 	}
 	if (!dragSent) detail = OS.GTK_SCROLL_NONE;
-	postEvent (SWT.Selection, event);
+	sendSelectionEvent (SWT.Selection, event, false);
 	return 0;
 }
 
@@ -225,9 +225,9 @@ int /*long*/ gtk_event_after (int /*long*/ widget, int /*long*/ gdkEvent) {
 				if (!dragSent) {
 					Event event = new Event ();
 					event.detail = SWT.DRAG;
-					postEvent (SWT.Selection, event);
+					sendSelectionEvent (SWT.Selection, event, false);
 				}
-				postEvent (SWT.Selection);
+				sendSelectionEvent (SWT.Selection);
 			}
 			detail = OS.GTK_SCROLL_NONE;
 			dragSent = false;
@@ -365,8 +365,7 @@ public int getSelection () {
 }
 
 /**
- * Returns the size of the receiver's thumb relative to the
- * difference between its maximum and minimum values.
+ * Returns the receiver's thumb value.
  *
  * @return the thumb value
  *
@@ -538,10 +537,13 @@ public void setSelection (int value) {
 }
 
 /**
- * Sets the size of the receiver's thumb relative to the
- * difference between its maximum and minimum values.  This new
- * value will be ignored if it is less than one, and will be
+ * Sets the thumb value. The thumb value should be used to represent 
+ * the size of the visual portion of the current range. This value is
+ * usually the same as the page increment value.
+ * <p>
+ * This new value will be ignored if it is less than one, and will be 
  * clamped if it exceeds the receiver's current range.
+ * </p>
  *
  * @param value the new thumb value, which must be at least one and not
  * larger than the size of the current range
diff --git a/org/eclipse/swt/widgets/Spinner.java b/org/eclipse/swt/widgets/Spinner.java
index b08c147..d8c0dd1 100644
--- a/org/eclipse/swt/widgets/Spinner.java
+++ b/org/eclipse/swt/widgets/Spinner.java
@@ -47,6 +47,7 @@ public class Spinner extends Composite {
 	int lastEventTime = 0;
 	int /*long*/ gdkEventKey = 0;
 	int fixStart = -1, fixEnd = -1;
+	double climbRate = 1;
 	
 	/**
 	 * the operating system limit for the number of characters
@@ -292,7 +293,7 @@ void createHandle (int index) {
 	OS.gtk_fixed_set_has_window (fixedHandle, true);
 	int /*long*/ adjustment = OS.gtk_adjustment_new (0, 0, 100, 1, 10, 0);
 	if (adjustment == 0) error (SWT.ERROR_NO_HANDLES);
-	handle = OS.gtk_spin_button_new (adjustment, 1, 0);
+	handle = OS.gtk_spin_button_new (adjustment, climbRate, 0);
 	if (handle == 0) error (SWT.ERROR_NO_HANDLES);
 	OS.gtk_container_add (fixedHandle, handle);
 	OS.gtk_editable_set_editable (handle, (style & SWT.READ_ONLY) == 0);
@@ -559,7 +560,7 @@ String getDecimalSeparator () {
 }
 
 int /*long*/ gtk_activate (int /*long*/ widget) {
-	postEvent (SWT.DefaultSelection);
+	sendSelectionEvent (SWT.DefaultSelection);
 	return 0;
 }
 
@@ -646,6 +647,7 @@ int /*long*/ gtk_commit (int /*long*/ imContext, int /*long*/ text) {
 
 int /*long*/ gtk_delete_text (int /*long*/ widget, int /*long*/ start_pos, int /*long*/ end_pos) {
 	if (!hooks (SWT.Verify) && !filters (SWT.Verify)) return 0;
+	if (end_pos == -1) end_pos = OS.g_utf8_strlen (OS.gtk_entry_get_text (handle), -1);
 	String newText = verifyText ("", (int)/*64*/start_pos, (int)/*64*/end_pos);
 	if (newText == null) {
 		OS.g_signal_stop_emission_by_name (handle, OS.delete_text);
@@ -733,7 +735,7 @@ int /*long*/ gtk_populate_popup (int /*long*/ widget, int /*long*/ menu) {
 }
 
 int /*long*/ gtk_value_changed (int /*long*/ widget) {
-	postEvent (SWT.Selection);
+	sendSelectionEvent (SWT.Selection);
 	return 0;
 }
 
@@ -911,11 +913,11 @@ public void setIncrement (int value) {
 
 /**
  * Sets the maximum value that the receiver will allow.  This new
- * value will be ignored if it is not greater than the receiver's current
+ * value will be ignored if it is less than the receiver's current
  * minimum value.  If the new maximum is applied then the receiver's
  * selection value will be adjusted if necessary to fall within its new range.
  *
- * @param value the new maximum, which must be greater than the current minimum
+ * @param value the new maximum, which must be greater than or equal to the current minimum
  *
  * @exception SWTException <ul>
  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
@@ -930,7 +932,7 @@ public void setMaximum (int value) {
 	double newValue = value;
 	int digits = OS.gtk_spin_button_get_digits (handle);
 	for (int i = 0; i < digits; i++) newValue /= 10;
-	if (newValue <= adjustment.lower) return;
+	if (newValue < adjustment.lower) return;
 	OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, VALUE_CHANGED);
 	OS.gtk_spin_button_set_range (handle, adjustment.lower, newValue);
 	OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, VALUE_CHANGED);
@@ -938,11 +940,11 @@ public void setMaximum (int value) {
 
 /**
  * Sets the minimum value that the receiver will allow.  This new
- * value will be ignored if it is not less than the receiver's
+ * value will be ignored if it is greater than the receiver's
  * current maximum value.  If the new minimum is applied then the receiver's
  * selection value will be adjusted if necessary to fall within its new range.
  *
- * @param value the new minimum, which must be less than the current maximum
+ * @param value the new minimum, which must be less than or equal to the current maximum
  *
  * @exception SWTException <ul>
  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
@@ -957,7 +959,7 @@ public void setMinimum (int value) {
 	double newValue = value;
 	int digits = OS.gtk_spin_button_get_digits (handle);
 	for (int i = 0; i < digits; i++) newValue /= 10;
-	if (newValue >= adjustment.upper) return;
+	if (newValue > adjustment.upper) return;
 	OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, VALUE_CHANGED);
 	OS.gtk_spin_button_set_range (handle, newValue, adjustment.upper);
 	OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, VALUE_CHANGED);
@@ -1077,15 +1079,17 @@ public void setDigits (int value) {
 		adjustment.lower *= factor;
 		adjustment.step_increment *= factor;
 		adjustment.page_increment *= factor;
+		climbRate *= factor;
 	} else {
 		adjustment.value /= factor;
 		adjustment.upper /= factor;
 		adjustment.lower /= factor;
 		adjustment.step_increment /= factor;
 		adjustment.page_increment /= factor;
+		climbRate /= factor;
 	}
 	OS.memmove (hAdjustment, adjustment);
-	OS.gtk_spin_button_set_digits (handle, value);
+	OS.gtk_spin_button_configure (handle, hAdjustment, climbRate, value);
 }
 
 /**
@@ -1113,7 +1117,7 @@ public void setDigits (int value) {
  */
 public void setValues (int selection, int minimum, int maximum, int digits, int increment, int pageIncrement) {
 	checkWidget ();
-	if (maximum <= minimum) return;
+	if (maximum < minimum) return;
 	if (digits < 0) return;
 	if (increment < 1) return;
 	if (pageIncrement < 1) return;
@@ -1124,7 +1128,15 @@ public void setValues (int selection, int minimum, int maximum, int digits, int
 	OS.gtk_spin_button_set_range (handle, minimum / factor, maximum / factor);
 	OS.gtk_spin_button_set_increments (handle, increment / factor, pageIncrement / factor);
 	OS.gtk_spin_button_set_value (handle, selection / factor);
-	OS.gtk_spin_button_set_digits (handle, digits);
+	/*
+	* The value of climb-rate indicates the acceleration rate 
+	* to spin the value when the button is pressed and hold 
+	* on the arrow button. This value should be varied 
+	* depending upon the value of digits.
+	*/
+	climbRate = 1.0 / factor;
+	int /*long*/ adjustment = OS.gtk_spin_button_get_adjustment(handle);
+	OS.gtk_spin_button_configure (handle, adjustment, climbRate, digits);
 	OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, VALUE_CHANGED);
 }
 
diff --git a/org/eclipse/swt/widgets/TabFolder.java b/org/eclipse/swt/widgets/TabFolder.java
index 68ddc4b..81846bc 100644
--- a/org/eclipse/swt/widgets/TabFolder.java
+++ b/org/eclipse/swt/widgets/TabFolder.java
@@ -248,7 +248,7 @@ void createItem (TabItem item, int index) {
 		OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, SWITCH_PAGE);
 		Event event = new Event();
 		event.item = items[0];
-		sendEvent (SWT.Selection, event);
+		sendSelectionEvent (SWT.Selection, event, false);
 		// the widget could be destroyed at this point
 	}
 }
@@ -277,7 +277,7 @@ void destroyItem (TabItem item) {
 			}
 			Event event = new Event ();
 			event.item = items [newIndex];
-			sendEvent (SWT.Selection, event);	
+			sendSelectionEvent (SWT.Selection, event, true);	
 			// the widget could be destroyed at this point
 		}
 	}
@@ -448,7 +448,7 @@ int /*long*/ gtk_switch_page (int /*long*/ widget, int /*long*/ page, int /*long
 	}
 	Event event = new Event();
 	event.item = item;
-	postEvent(SWT.Selection, event);
+	sendSelectionEvent (SWT.Selection, event, false);
 	return 0;
 }
 
@@ -587,6 +587,21 @@ public void removeSelectionListener (SelectionListener listener) {
 	eventTable.unhook (SWT.DefaultSelection,listener);	
 }
 
+void reskinChildren (int flags) {
+	if (items != null) {
+		int /*long*/ list = OS.gtk_container_get_children (handle);
+		if (list != 0){
+			int count = OS.g_list_length (list);
+			OS.g_list_free (list);
+			for (int i=0; i<count; i++) {
+				TabItem item = items [i];
+				if (item != null) item.reskin (flags);
+			}
+		}
+	}
+	super.reskinChildren (flags);
+}
+
 int setBounds (int x, int y, int width, int height, boolean move, boolean resize) {
 	int result = super.setBounds (x, y, width, height, move, resize);
 	if ((result & RESIZED) != 0) {
@@ -666,7 +681,7 @@ void setSelection (int index, boolean notify) {
 		if (notify) {
 			Event event = new Event ();
 			event.item = item;
-			sendEvent (SWT.Selection, event);
+			sendSelectionEvent (SWT.Selection, event, true);
 		}
 	}
 }
diff --git a/org/eclipse/swt/widgets/Table.java b/org/eclipse/swt/widgets/Table.java
index 451650d..d0dfe65 100644
--- a/org/eclipse/swt/widgets/Table.java
+++ b/org/eclipse/swt/widgets/Table.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -579,8 +579,7 @@ void createColumn (TableColumn column, int index) {
 		column.handle = columnHandle;
 		column.modelIndex = modelIndex;
 	}
-	/* Disable searching when using VIRTUAL */
-	if ((style & SWT.VIRTUAL) != 0) {
+	if (!searchEnabled ()) {
 		/*
 		* Bug in GTK. Until GTK 2.6.5, calling gtk_tree_view_set_enable_search(FALSE)
 		* would prevent the user from being able to type in text to search the tree.
@@ -632,12 +631,13 @@ void createHandle (int index) {
 	int vsp = (style & SWT.V_SCROLL) != 0 ? OS.GTK_POLICY_AUTOMATIC : OS.GTK_POLICY_NEVER;
 	OS.gtk_scrolled_window_set_policy (scrolledHandle, hsp, vsp);
 	if ((style & SWT.BORDER) != 0) OS.gtk_scrolled_window_set_shadow_type (scrolledHandle, OS.GTK_SHADOW_ETCHED_IN);
-	/* Disable searching when using VIRTUAL */
 	if ((style & SWT.VIRTUAL) != 0) {
 		/* The fixed_height_mode property only exists in GTK 2.3.2 and greater */
 		if (OS.GTK_VERSION >= OS.VERSION (2, 3, 2)) {
 			OS.g_object_set (handle, OS.fixed_height_mode, true, 0);
 		}
+	}
+	if (!searchEnabled ()) {
 		/*
 		* Bug in GTK. Until GTK 2.6.5, calling gtk_tree_view_set_enable_search(FALSE)
 		* would prevent the user from being able to type in text to search the tree.
@@ -1045,8 +1045,7 @@ void destroyItem (TableColumn column) {
 			createRenderers (checkColumn.handle, checkColumn.modelIndex, true, checkColumn.style);
 		}
 	}
-	/* Disable searching when using VIRTUAL */
-	if ((style & SWT.VIRTUAL) != 0) {
+	if (!searchEnabled ()) {
 		/*
 		* Bug in GTK. Until GTK 2.6.5, calling gtk_tree_view_set_enable_search(FALSE)
 		* would prevent the user from being able to type in text to search the tree.
@@ -1929,11 +1928,42 @@ int /*long*/ gtk_changed (int /*long*/ widget) {
 	if (item != null) {
 		Event event = new Event ();
 		event.item = item; 
-		postEvent (SWT.Selection, event);
+		sendSelectionEvent (SWT.Selection, event, false);
 	}
 	return 0;
 }
 
+int /*long*/ gtk_expose_event (int /*long*/ widget, int /*long*/ eventPtr) {
+	if ((state & OBSCURED) != 0) return 0;
+	if ((state & PARENT_BACKGROUND) != 0 || backgroundImage != null) {
+		Control control = findBackgroundControl ();
+		if (control != null) {
+			GdkEventExpose gdkEvent = new GdkEventExpose ();
+			OS.memmove (gdkEvent, eventPtr, GdkEventExpose.sizeof);
+			int /*long*/ window = OS.gtk_tree_view_get_bin_window (handle);
+			if (window == gdkEvent.window) {
+				int [] width = new int [1], height = new int [1];
+				OS.gdk_drawable_get_size (window, width, height);
+				int bottom = 0;
+				if (itemCount != 0) {
+					int /*long*/ iter = OS.g_malloc (OS.GtkTreeIter_sizeof ());
+					OS.gtk_tree_model_iter_nth_child (modelHandle, iter, 0, itemCount - 1);
+					int /*long*/ path = OS.gtk_tree_model_get_path (modelHandle, iter);
+					GdkRectangle rect = new GdkRectangle ();
+					OS.gtk_tree_view_get_cell_area (handle, path, 0, rect);
+					bottom = rect.y + rect.height;
+					OS.gtk_tree_path_free (path);
+					OS.g_free (iter);
+				}
+				if (height [0] > bottom) {
+					drawBackground (control, window, gdkEvent.region, 0, bottom, width [0], height [0] - bottom);
+				}
+			}
+		}
+	}
+	return super.gtk_expose_event (widget, eventPtr);
+}
+
 int /*long*/ gtk_key_press_event (int /*long*/ widget, int /*long*/ eventPtr) {
 	int /*long*/ result = super.gtk_key_press_event (widget, eventPtr);
 	if (result != 0) return result;
@@ -1951,7 +1981,7 @@ int /*long*/ gtk_key_press_event (int /*long*/ widget, int /*long*/ eventPtr) {
 			case OS.GDK_KP_Enter: {
 				Event event = new Event ();
 				event.item = getFocusItem (); 
-				postEvent (SWT.DefaultSelection, event);
+				sendSelectionEvent (SWT.DefaultSelection, event, false);
 				break;
 			}
 		}
@@ -1989,7 +2019,7 @@ int /*long*/ gtk_row_activated (int /*long*/ tree, int /*long*/ path, int /*long
 	}
 	Event event = new Event ();
 	event.item = item;
-	postEvent (SWT.DefaultSelection, event);
+	sendSelectionEvent (SWT.DefaultSelection, event, false);
 	return 0;
 }
 
@@ -2006,7 +2036,13 @@ int gtk_row_inserted (int model, int path, int iter) {
 	}
 	return 0;
 }
-
+int /*long*/ gtk_start_interactive_search(int /*long*/ widget) {
+	if (!searchEnabled()) {
+		OS.g_signal_stop_emission_by_name(widget, OS.start_interactive_search); 
+		return 1;
+	}
+	return 0;
+}
 int /*long*/ gtk_toggled (int /*long*/ renderer, int /*long*/ pathStr) {
 	int /*long*/ path = OS.gtk_tree_path_new_from_string (pathStr);
 	if (path == 0) return 0;
@@ -2019,7 +2055,7 @@ int /*long*/ gtk_toggled (int /*long*/ renderer, int /*long*/ pathStr) {
 		Event event = new Event ();
 		event.detail = SWT.CHECK;
 		event.item = item;
-		postEvent (SWT.Selection, event);
+		sendSelectionEvent (SWT.Selection, event, false);
 	}
 	OS.gtk_tree_path_free (path);
 	return 0;
@@ -2071,6 +2107,7 @@ void hookEvents () {
 	if (checkRenderer != 0) {
 		OS.g_signal_connect_closure (checkRenderer, OS.toggled, display.closures [TOGGLED], false);
 	}
+	OS.g_signal_connect_closure (handle, OS.start_interactive_search, display.closures[START_INTERACTIVE_SEARCH], false);
 	if (fixAccessibility ()) {
 		OS.g_signal_connect_closure (modelHandle, OS.row_inserted, display.closures [ROW_INSERTED], true);
 		OS.g_signal_connect_closure (modelHandle, OS.row_deleted, display.closures [ROW_DELETED], true);
@@ -2436,8 +2473,7 @@ public void removeAll () {
 	OS.g_signal_handlers_unblock_matched (selection, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED);
 
 	resetCustomDraw ();
-	/* Disable searching when using VIRTUAL */
-	if ((style & SWT.VIRTUAL) != 0) {
+	if (!searchEnabled ()) {
 		/*
 		* Bug in GTK. Until GTK 2.6.5, calling gtk_tree_view_set_enable_search(FALSE)
 		* would prevent the user from being able to type in text to search the tree.
@@ -2584,17 +2620,25 @@ int /*long*/ rendererRenderProc (int /*long*/ cell, int /*long*/ window, int /*l
 			OS.gtk_tree_path_free (path);
 			
 			if ((drawState & SWT.SELECTED) == 0) {
-				Control control = findBackgroundControl ();
-				if (control != null && control.backgroundImage != null) {
-					OS.gdk_window_clear_area (window, rect.x, rect.y, rect.width, rect.height);
+				if ((state & PARENT_BACKGROUND) != 0 || backgroundImage != null) {
+					Control control = findBackgroundControl ();
+					if (control != null) {
+						drawBackground (control, window, 0, rect.x, rect.y, rect.width, rect.height);
+					}
 				}
 			}
 
+			//send out measure before erase
+			int /*long*/ textRenderer =  getTextRenderer (columnHandle);
+			if (textRenderer != 0) OS.gtk_cell_renderer_get_size (textRenderer, handle, null, null, null, null, null);
+			
+
 			if (hooks (SWT.EraseItem)) {
-				boolean wasSelected = false; 
-				if ((drawState & SWT.SELECTED) != 0) {
-					wasSelected = true;
-					OS.gdk_window_clear_area (window, rect.x, rect.y, rect.width, rect.height);
+				boolean wasSelected = (drawState & SWT.SELECTED) != 0;
+				if (wasSelected) {
+					Control control = findBackgroundControl ();
+					if (control == null) control = this;
+					drawBackground (control, window, 0, rect.x, rect.y, rect.width, rect.height);
 				}
 				GC gc = new GC (this);
 				if ((drawState & SWT.SELECTED) != 0) {
@@ -2716,6 +2760,35 @@ void resetCustomDraw () {
 	firstCustomDraw = false;
 }
 
+void reskinChildren (int flags) {
+	if (items != null) {
+		for (int i=0; i<itemCount; i++) {
+			TableItem item = items [i];
+			if (item != null) item.reskin (flags);
+		}
+	}
+	if (columns != null) {
+		for (int i=0; i<columnCount; i++) {
+			TableColumn column = columns [i];
+			if (!column.isDisposed ()) column.reskin (flags);
+		}
+	}
+	super.reskinChildren (flags);
+}
+
+boolean searchEnabled () {
+	/* Disable searching when using VIRTUAL */
+	if ((style & SWT.VIRTUAL) != 0) return false;
+	if (OS.GTK_VERSION < OS.VERSION (2, 6, 0)) {
+		int mask = SWT.PRIMARY_MODAL | SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL;
+		Shell shell = getShell();
+		if ((shell.style & mask) != 0) {
+			return false;
+		}
+	}
+	return true;
+}
+
 /**
  * Selects the item at the given zero-relative index in the receiver. 
  * If the item at the index was already selected, it remains
@@ -2890,9 +2963,8 @@ void setBackgroundColor (GdkColor color) {
 }
 
 void setBackgroundPixmap (int /*long*/ pixmap) {
-	super.setBackgroundPixmap (pixmap);
-	int /*long*/ window = paintWindow ();
-	if (window != 0) OS.gdk_window_set_back_pixmap (window, 0, true);	
+	ownerDraw = true;
+	recreateRenderers ();
 }
 
 int setBounds (int x, int y, int width, int height, boolean move, boolean resize) {
@@ -3064,9 +3136,8 @@ public void setLinesVisible (boolean show) {
 }
 
 void setParentBackground () {
-	super.setParentBackground ();
-	int /*long*/ window = paintWindow ();
-	if (window != 0) OS.gdk_window_set_back_pixmap (window, 0, true);
+	ownerDraw = true;
+	recreateRenderers ();
 }
 
 void setParentWindow (int /*long*/ widget) {
@@ -3540,4 +3611,31 @@ void updateScrollBarValue (ScrollBar bar) {
 	OS.g_list_free (list);
 }
 
+int /*long*/ windowProc (int /*long*/ handle, int /*long*/ arg0, int /*long*/ user_data) {
+	switch ((int)/*64*/user_data) {
+		case EXPOSE_EVENT_INVERSE: {
+			/*
+			 * Feature in GTK. When the GtkTreeView has no items it does not propagate
+			 * expose events. The fix is to fill the background in the inverse expose
+			 * event.
+			 */
+			if (itemCount == 0 && (state & OBSCURED) == 0) {
+				if ((state & PARENT_BACKGROUND) != 0 || backgroundImage != null) {
+					Control control = findBackgroundControl ();
+					if (control != null) {
+						GdkEventExpose gdkEvent = new GdkEventExpose ();
+						OS.memmove (gdkEvent, arg0, GdkEventExpose.sizeof);
+						int /*long*/ window = OS.gtk_tree_view_get_bin_window (handle);
+						if (window == gdkEvent.window) {
+							drawBackground (control, window, gdkEvent.region, gdkEvent.area_x, gdkEvent.area_y, gdkEvent.area_width, gdkEvent.area_height);
+						}
+					}
+				}
+			}
+			break;
+		}
+	}
+	return super.windowProc (handle, arg0, user_data);
+}
+
 }
diff --git a/org/eclipse/swt/widgets/TableColumn.java b/org/eclipse/swt/widgets/TableColumn.java
index 4a62dfe..e0ab44f 100644
--- a/org/eclipse/swt/widgets/TableColumn.java
+++ b/org/eclipse/swt/widgets/TableColumn.java
@@ -362,7 +362,7 @@ int /*long*/ gtk_clicked (int /*long*/ widget) {
 			}
 		}
 	}
-	if (postEvent) postEvent (doubleClick ? SWT.DefaultSelection : SWT.Selection);
+	if (postEvent) sendSelectionEvent (doubleClick ? SWT.DefaultSelection : SWT.Selection);
 	return 0;
 }
 
@@ -696,6 +696,35 @@ public void setWidth (int width) {
 	if (width != 0) OS.gtk_widget_realize (parent.handle);
 	OS.gtk_tree_view_column_set_visible (handle, width != 0);
 	lastWidth = width;
+	/*
+	 * Bug in GTK. When the column is made visible the event window of column
+	 * header is raised above the gripper window of the previous column. In 
+	 * some cases, this can cause the previous column to be not resizable by
+	 * the mouse. The fix is to find the event window and lower it to bottom to
+	 * the z-order stack. 
+	 */
+	if (width != 0) {
+		if (buttonHandle != 0) {
+			int /*long*/ window = OS.gtk_widget_get_parent_window (buttonHandle);
+			if (window != 0) {
+				int /*long*/ windowList = OS.gdk_window_get_children (window);
+				if (windowList != 0) {
+					int /*long*/ windows = windowList;
+					int /*long*/ [] userData = new int /*long*/ [1];
+					while (windows != 0) {
+						int /*long*/ child = OS.g_list_data (windows);
+						OS.gdk_window_get_user_data (child, userData);
+						if (userData[0] == buttonHandle) {
+							OS.gdk_window_lower (child);
+							break;
+						}
+						windows = OS.g_list_next (windows);
+					}
+					OS.g_list_free (windowList);
+				}
+			}
+		}
+	}
 	sendEvent (SWT.Resize);
 }
 
diff --git a/org/eclipse/swt/widgets/TableItem.java b/org/eclipse/swt/widgets/TableItem.java
index f348437..3307d50 100644
--- a/org/eclipse/swt/widgets/TableItem.java
+++ b/org/eclipse/swt/widgets/TableItem.java
@@ -252,10 +252,10 @@ public Color getBackground () {
 }
 
 /**
- * Returns a rectangle describing the receiver's size and location
- * relative to its parent.
+ * Returns a rectangle describing the size and location of the receiver's
+ * text relative to its parent.
  *
- * @return the receiver's bounding rectangle
+ * @return the bounding rectangle of the receiver's text
  *
  * @exception SWTException <ul>
  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
diff --git a/org/eclipse/swt/widgets/TaskBar.java b/org/eclipse/swt/widgets/TaskBar.java
new file mode 100644
index 0000000..56a5e0a
--- /dev/null
+++ b/org/eclipse/swt/widgets/TaskBar.java
@@ -0,0 +1,181 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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.widgets;
+
+
+import org.eclipse.swt.*;
+
+/**
+ * Instances of this class represent the system task bar.
+ * 
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>(none)</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>(none)</dd>
+ * </dl>
+ * 
+ * @see Display#getSystemTaskBar
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
+ * 
+ * @since 3.6
+ * 
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class TaskBar extends Widget {
+	int itemCount;
+	TaskItem [] items = new TaskItem [4];
+
+TaskBar (Display display, int style) {
+	if (display == null) display = Display.getCurrent ();
+	if (display == null) display = Display.getDefault ();
+	if (!display.isValidThread ()) {
+		error (SWT.ERROR_THREAD_INVALID_ACCESS);
+	}
+	this.display = display;
+	reskinWidget ();
+}
+
+void createItem (TaskItem item, int index) {
+	if (index == -1) index = itemCount;
+	if (!(0 <= index && index <= itemCount)) error (SWT.ERROR_INVALID_RANGE);
+	if (itemCount == items.length) {
+		TaskItem [] newItems = new TaskItem [items.length + 4];
+		System.arraycopy (items, 0, newItems, 0, items.length);
+		items = newItems;
+	}
+	System.arraycopy (items, index, items, index + 1, itemCount++ - index);
+	items [index] = item;
+}
+
+void createItems () {
+}
+
+void destroyItem (TaskItem item) {
+	int index = 0;
+	while (index < itemCount) {
+		if (items [index] == item) break;
+		index++;
+	}
+	if (index == itemCount) return;
+	System.arraycopy (items, index + 1, items, index, --itemCount - index);
+	items [itemCount] = null;
+}
+
+/**
+ * Returns the item at the given, zero-relative index in the
+ * receiver. Throws an exception if the index is out of range.
+ *
+ * @param index the index of the item to return
+ * @return the item at the given index
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
+ * </ul>
+ * @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>
+ */
+public TaskItem getItem (int index) {
+	checkWidget ();
+	createItems ();
+	if (!(0 <= index && index < itemCount)) error (SWT.ERROR_INVALID_RANGE);
+	return items [index];
+}
+
+/**
+ * Returns the number of items contained in the receiver.
+ *
+ * @return the number of items
+ *
+ * @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>
+ */
+public int getItemCount () {
+	checkWidget ();
+	createItems ();
+	return itemCount;
+}
+
+/**
+ * Returns the <code>TaskItem</code> for the given <code>Shell</code> or the <code>TaskItem</code> 
+ * for the application if the <code>Shell</code> parameter is <code>null</code>.
+ * If the requested item is not supported by the platform it returns <code>null</code>.
+ * 
+ * @param shell the shell for which the task item is requested, or null to request the application item
+ * @return the task item for the given shell or the application
+ *
+ * @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>
+ */
+public TaskItem getItem (Shell shell) {
+	checkWidget ();
+	return null;
+}
+
+/**
+ * Returns an array of <code>TaskItem</code>s which are the items
+ * in the receiver. 
+ * <p>
+ * Note: This is not the actual structure used by the receiver
+ * to maintain its list of items, so modifying the array will
+ * not affect the receiver. 
+ * </p>
+ *
+ * @return the items in the receiver
+ *
+ * @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>
+ */
+public TaskItem [] getItems () {
+	checkWidget ();
+	createItems ();
+	TaskItem [] result = new TaskItem [itemCount];
+	System.arraycopy (items, 0, result, 0, result.length);
+	return result;
+}
+
+void releaseChildren (boolean destroy) {
+	if (items != null) {
+		for (int i=0; i<items.length; i++) {
+			TaskItem item = items [i];
+			if (item != null && !item.isDisposed ()) {
+				item.release (false);
+			}
+		}
+		items = null;
+	}
+	super.releaseChildren (destroy);
+}
+
+void releaseParent () {
+	super.releaseParent ();
+//	if (display.taskBar == this) display.taskBar = null;
+}
+
+void reskinChildren (int flags) {	
+	if (items != null) {
+		for (int i=0; i<items.length; i++) {
+			TaskItem item = items [i];
+			if (item != null) item.reskin (flags);
+		}
+	}
+	super.reskinChildren (flags);
+}
+
+}
diff --git a/org/eclipse/swt/widgets/TaskItem.java b/org/eclipse/swt/widgets/TaskItem.java
new file mode 100644
index 0000000..4c76d88
--- /dev/null
+++ b/org/eclipse/swt/widgets/TaskItem.java
@@ -0,0 +1,372 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 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.widgets;
+
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+
+/**
+ * Instances of this class represent a task item.
+ * 
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>(none)</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>(none)</dd>
+ * </dl>
+ *
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
+ * 
+ * @since 3.6
+ * 
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class TaskItem extends Item {
+	TaskBar parent;
+	Shell shell;
+	int progress, progressState = SWT.DEFAULT;
+	Image overlayImage;
+	String overlayText = "";
+	Menu menu;
+
+	static final int PROGRESS_MAX = 100;
+/**
+ * Constructs a new instance of this class given its parent
+ * (which must be a <code>Tray</code>) and a style value
+ * describing its behavior and appearance. The item is added
+ * to the end of the items maintained by its parent.
+ * <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 composite control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control 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>
+ *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+TaskItem (TaskBar parent, int style) {
+	super (parent, style);
+	this.parent = parent;
+	parent.createItem (this, -1);
+}
+
+protected void checkSubclass () {
+	if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS);
+}
+
+void destroyWidget () {
+	parent.destroyItem (this);
+	releaseHandle ();
+}
+
+/**
+ * Returns the receiver's pop up menu if it has one, or null
+ * if it does not.
+ *
+ * @return the receiver's menu
+ *
+ * @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>
+ */
+public Menu getMenu () {
+	checkWidget ();
+	return menu;
+} 
+
+/**
+ * Returns the receiver's overlay image if it has one, or null
+ * if it does not.
+ *
+ * @return the receiver's overlay image
+ *
+ * @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>
+ */
+public Image getOverlayImage () {
+	checkWidget();
+	return overlayImage;
+}
+
+/**
+ * Returns the receiver's overlay text, which will be an empty
+ * string if it has never been set.
+ *
+ * @return the receiver's overlay text
+ *
+ * @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>
+ */
+public String getOverlayText () {
+	checkWidget();
+	return overlayText;
+}
+
+/**
+ * Returns the receiver's parent, which must be a <code>TaskBar</code>.
+ *
+ * @return the receiver's parent
+ *
+ * @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>
+ * 
+ */
+public TaskBar getParent () {
+	checkWidget ();
+	return parent;
+}
+
+/**
+ * Returns the receiver's progress.
+ *
+ * @return the receiver's progress
+ *
+ * @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>
+ */
+public int getProgress () {
+	checkWidget ();
+	return progress;
+}
+
+/**
+ * Returns the receiver's progress state.
+ *
+ * @return the receiver's progress 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>
+ */
+public int getProgressState () {
+	checkWidget ();
+	return progressState;
+}
+
+void releaseHandle () {
+	super.releaseHandle ();
+	parent = null;
+}
+
+void releaseWidget () {
+	super.releaseWidget ();
+	overlayImage = null;
+	overlayText = null;
+}
+
+/**
+ * Sets the receiver's pop up menu to the argument. The way the menu is
+ * shown is platform specific.
+ * 
+ * <p>
+ * This feature might not be available for the receiver on all
+ * platforms. The application code can check if it is supported
+ * by calling the respective get method. When the feature is not
+ * available, the get method will always return the NULL.</p>
+ *
+ * <p>
+ * For better cross platform support, the application code should
+ * set this feature on the <code>TaskItem</code> for application.<br>
+ * On Windows, this feature will only work on RCP applications.</p>
+ *
+ * <p>
+ * The menu should be fully created before this method is called.
+ * Dynamic changes to the menu after the method is called will not be reflected
+ * in the native menu.</p> 
+ *
+ * @param menu the new pop up menu
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_MENU_NOT_POP_UP - the menu is not a pop up menu</li>
+ *    <li>ERROR_INVALID_ARGUMENT - if the menu has been disposed</li> 
+ * </ul>
+ * @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>
+ */
+public void setMenu (Menu menu) {
+	checkWidget ();
+	if (menu != null) {
+		if (menu.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+		if ((menu.style & SWT.POP_UP) == 0) {
+			error (SWT.ERROR_MENU_NOT_POP_UP);
+		}
+	}
+	this.menu = menu;
+}
+
+/**
+ * Sets the receiver's overlay image, which may be null
+ * indicating that no image should be displayed. The bounds
+ * for the overlay image is determined by the platform and in 
+ * general it should be a small image.
+ *
+ * <p>
+ * This feature might not be available for the receiver on all
+ * platforms. The application code can check if it is supported
+ * by calling the respective get method. When the feature is not
+ * available, the get method will always return the NULL.</p>
+ *
+ * <p>
+ * For better cross platform support, the application code should
+ * first try to set this feature on the <code>TaskItem</code> for the 
+ * main shell then on the <code>TaskItem</code> for the application.</p>
+ *
+ * @param overlayImage the new overlay image (may be null)
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_INVALID_ARGUMENT - if the overlayImage has been disposed</li> 
+ * </ul>
+ * @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>
+ */
+public void setOverlayImage (Image overlayImage) {
+	checkWidget ();
+	if (overlayImage != null && overlayImage.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
+	this.overlayImage = overlayImage;
+}
+
+/**
+ * Sets the receiver's overlay text. The space available to display the
+ * overlay text is platform dependent and in general it should be no longer
+ * than a few characters.
+ *
+ * <p>
+ * This feature might not be available for the receiver on all
+ * platforms. The application code can check if it is supported
+ * by calling the respective get method. When the feature is not
+ * available, the get method will always return an empty string.</p>
+ *
+ * <p>
+ * For better cross platform support, the application code should
+ * first try to set this feature on the <code>TaskItem</code> for the 
+ * main shell then on the <code>TaskItem</code> for the application.</p>
+ *
+ * @param overlayText the new overlay text
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_NULL_ARGUMENT - if the overlayText is null</li>
+ * </ul>
+ * @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>
+ */
+public void setOverlayText (String overlayText) {
+	checkWidget ();
+	if (overlayText == null) error (SWT.ERROR_NULL_ARGUMENT);
+	this.overlayText = overlayText;
+}
+
+/**
+ * Sets the receiver's progress state, the state can be one of
+ * the following:
+ * <p><ul>
+ * <li>{@link SWT#DEFAULT}</li>
+ * <li>{@link SWT#NORMAL}</li>
+ * <li>{@link SWT#PAUSED}</li>
+ * <li>{@link SWT#ERROR}</li>
+ * <li>{@link SWT#INDETERMINATE}</li>
+ * </ul></p>
+ * 
+ * The percentage of progress shown by the states <code>SWT#NORMAL</code>, <code>SWT#PAUSED</code>, 
+ * <code>SWT#ERROR</code> is set with <code>setProgress()</code>. <br>
+ * The state <code>SWT#DEFAULT</code> indicates that no progress should be shown.
+ *
+ * <p>
+ * This feature might not be available for the receiver on all
+ * platforms. The application code can check if it is supported
+ * by calling the respective get method. When the feature is not
+ * available, the get method will always return <code>SWT#DEFAULT</code>.</p>
+ *
+ * <p>
+ * For better cross platform support, the application code should
+ * first try to set this feature on the <code>TaskItem</code> for the 
+ * main shell then on the <code>TaskItem</code> for the application.</p>
+ *
+ * @param progressState the new progress 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 {@link #setProgress(int)}
+ */
+public void setProgressState (int progressState) {
+	checkWidget ();
+	if (this.progressState == progressState) return;
+	this.progressState = progressState;
+}
+
+/**
+ * Sets the receiver's progress, the progress represents a percentage and
+ * should be in range from 0 to 100. The progress is only shown when the progress
+ * state is different than <code>SWT#DEFAULT</code>.
+ *
+ * <p>
+ * This feature might not be available for the receiver on all
+ * platforms. The application code can check if it is supported
+ * by calling the respective get method. When the feature is not
+ * available, the get method will always return zero.</p>
+ *
+ * <p>
+ * For better cross platform support, the application code should
+ * first try to set this feature on the <code>TaskItem</code> for the 
+ * main shell then on the <code>TaskItem</code> for the application.</p>
+ *
+ * @param progress the new progress
+ *
+ * @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 {@link #setProgressState(int)}
+ */
+public void setProgress (int progress) {
+	checkWidget ();
+	progress = Math.max(0, Math.min(progress, PROGRESS_MAX));
+	if (this.progress == progress) return;
+	this.progress = progress;
+}
+
+}
diff --git a/org/eclipse/swt/widgets/Text.java b/org/eclipse/swt/widgets/Text.java
index 0973f06..c62de00 100644
--- a/org/eclipse/swt/widgets/Text.java
+++ b/org/eclipse/swt/widgets/Text.java
@@ -32,7 +32,7 @@ import org.eclipse.swt.events.*;
  * <dt><b>Styles:</b></dt>
  * <dd>CENTER, ICON_CANCEL, ICON_SEARCH, LEFT, MULTI, PASSWORD, SEARCH, SINGLE, RIGHT, READ_ONLY, WRAP</dd>
  * <dt><b>Events:</b></dt>
- * <dd>DefaultSelection, Modify, Verify</dd>
+ * <dd>DefaultSelection, Modify, Verify, OrientationChange</dd>
  * </dl>
  * <p>
  * Note: Only one of the styles MULTI and SINGLE may be specified,
@@ -131,6 +131,27 @@ public class Text extends Scrollable {
  */
 public Text (Composite parent, int style) {
 	super (parent, checkStyle (style));
+	if (OS.GTK_VERSION >= OS.VERSION (2, 16, 0)) {
+		if ((style & SWT.SEARCH) != 0) {
+			/*
+			 * Ensure that SWT.ICON_CANCEL and ICON_SEARCH are set.
+			 * NOTE: ICON_CANCEL has the same value as H_SCROLL and
+			 * ICON_SEARCH has the same value as V_SCROLL so it is
+			 * necessary to first clear these bits to avoid a scroll
+			 * bar and then reset the bit using the original style
+			 * supplied by the programmer.
+			 */
+			if ((style & SWT.ICON_CANCEL) != 0) {
+				this.style |= SWT.ICON_CANCEL;
+				OS.gtk_entry_set_icon_from_stock (handle, OS.GTK_ENTRY_ICON_SECONDARY, OS.GTK_STOCK_CLEAR);
+				OS.gtk_entry_set_icon_sensitive (handle, OS.GTK_ENTRY_ICON_SECONDARY, false);
+			}
+			if ((style & SWT.ICON_SEARCH) != 0) {
+				this.style |= SWT.ICON_SEARCH;
+				OS.gtk_entry_set_icon_from_stock (handle, OS.GTK_ENTRY_ICON_PRIMARY, OS.GTK_STOCK_FIND);
+			}
+		}
+	}
 }
 
 static int checkStyle (int style) {
@@ -1101,7 +1122,7 @@ public int getTopPixel () {
 }
 
 int /*long*/ gtk_activate (int /*long*/ widget) {
-	postEvent (SWT.DefaultSelection);
+	sendSelectionEvent (SWT.DefaultSelection);
 	return 0;
 }
 
@@ -1146,6 +1167,12 @@ int /*long*/ gtk_changed (int /*long*/ widget) {
 	} else {
 		sendEvent (SWT.Modify);
 	}
+	if ((style & SWT.SEARCH) != 0) {
+		if ((style & SWT.ICON_CANCEL) != 0) {
+			int /*long*/ ptr = OS.gtk_entry_get_text (handle);
+			OS.gtk_entry_set_icon_sensitive (handle, OS.GTK_ENTRY_ICON_SECONDARY, OS.g_utf8_strlen (ptr, -1) > 0);
+		}
+	}
 	return 0;
 }
 
@@ -1229,6 +1256,7 @@ int /*long*/ gtk_delete_range (int /*long*/ widget, int /*long*/ iter1, int /*lo
 
 int /*long*/ gtk_delete_text (int /*long*/ widget, int /*long*/ start_pos, int /*long*/ end_pos) {
 	if (!hooks (SWT.Verify) && !filters (SWT.Verify)) return 0;
+	if (end_pos == -1) end_pos = OS.g_utf8_strlen (OS.gtk_entry_get_text (handle), -1);
 	String newText = verifyText ("", (int)/*64*/start_pos, (int)/*64*/end_pos);
 	if (newText == null) {
 		/* Remember the selection when the text was deleted */
@@ -1360,6 +1388,18 @@ int /*long*/ gtk_grab_focus (int /*long*/ widget) {
 	return result;
 }
 
+int /*long*/ gtk_icon_release (int /*long*/ widget, int /*long*/ icon_pos, int /*long*/ event) {
+	Event e = new Event();
+	if (icon_pos == OS.GTK_ENTRY_ICON_PRIMARY) {
+		e.detail = SWT.ICON_SEARCH;
+	} else {
+		e.detail = SWT.ICON_CANCEL;
+		OS.gtk_editable_delete_text (handle, 0, -1);
+	}
+	sendSelectionEvent (SWT.DefaultSelection, e, false);
+	return 0;
+}
+
 int /*long*/ gtk_insert_text (int /*long*/ widget, int /*long*/ new_text, int /*long*/ new_text_length, int /*long*/ position) {
 	if (!hooks (SWT.Verify) && !filters (SWT.Verify)) return 0;
 	if (new_text == 0 || new_text_length == 0) return 0;
@@ -1462,6 +1502,9 @@ void hookEvents () {
 		OS.g_signal_connect_closure (handle, OS.activate, display.closures [ACTIVATE], false);
 		OS.g_signal_connect_closure (handle, OS.grab_focus, display.closures [GRAB_FOCUS], false);
 		OS.g_signal_connect_closure (handle, OS.populate_popup, display.closures [POPULATE_POPUP], false);
+		if ((style & SWT.SEARCH) != 0 && OS.GTK_VERSION >= OS.VERSION (2, 16, 0)) {
+			OS.g_signal_connect_closure (handle, OS.icon_release, display.closures [ICON_RELEASE], false);
+		}
 	} else {
 		OS.g_signal_connect_closure (bufferHandle, OS.changed, display.closures [CHANGED], false);
 		OS.g_signal_connect_closure (bufferHandle, OS.insert_text, display.closures [TEXT_BUFFER_INSERT_TEXT], false);
@@ -1527,7 +1570,17 @@ int /*long*/ paintWindow () {
 	if ((style & SWT.SINGLE) != 0) {
 		int /*long*/ window = super.paintWindow ();
 		int /*long*/ children = OS.gdk_window_get_children (window);
-		if (children != 0) window = OS.g_list_data (children);
+		if (children != 0) {
+			/*
+			* When search or cancel icons are added to Text, those
+			* icon window(s) are added to the beginning of the list. 
+			* In order to always return the correct window for Text,
+			* browse to the end of the list. 
+			*/
+			do {
+				window = OS.g_list_data (children);
+			} while ((children = OS.g_list_next (children)) != 0);
+		}
 		OS.g_list_free (children);
 		return window;
 	}
diff --git a/org/eclipse/swt/widgets/ToolBar.java b/org/eclipse/swt/widgets/ToolBar.java
index 2d7306e..a87565f 100644
--- a/org/eclipse/swt/widgets/ToolBar.java
+++ b/org/eclipse/swt/widgets/ToolBar.java
@@ -391,7 +391,7 @@ int /*long*/ gtk_key_press_event (int /*long*/ widget, int /*long*/ eventPtr) {
 					event.x = OS.GTK_WIDGET_X (topHandle);
 					event.y = OS.GTK_WIDGET_Y (topHandle) + OS.GTK_WIDGET_HEIGHT (topHandle);
 					if ((style & SWT.MIRRORED) != 0) event.x = getClientWidth() - OS.GTK_WIDGET_WIDTH(topHandle) - event.x;
-					item.postEvent (SWT.Selection, event);
+					item.sendSelectionEvent  (SWT.Selection, event, false);
 					return result;
 				}
 			}
@@ -498,6 +498,17 @@ void removeControl (Control control) {
 	}
 }
 
+void reskinChildren (int flags) {
+	ToolItem[] items = _getItems();
+	if (items != null) {
+		for (int i=0; i<items.length; i++) {
+			ToolItem item = items [i];
+			if (item != null) item.reskin (flags);
+		}
+	}
+	super.reskinChildren (flags);
+}
+
 int setBounds (int x, int y, int width, int height, boolean move, boolean resize) {
 	int result = super.setBounds (x, y, width, height, move, resize);
 	if ((result & RESIZED) != 0) relayout ();
diff --git a/org/eclipse/swt/widgets/ToolItem.java b/org/eclipse/swt/widgets/ToolItem.java
index 6013cfc..4c5c7d9 100644
--- a/org/eclipse/swt/widgets/ToolItem.java
+++ b/org/eclipse/swt/widgets/ToolItem.java
@@ -141,6 +141,12 @@ public ToolItem (ToolBar parent, int style, int index) {
  * the event object detail field contains the value <code>SWT.ARROW</code>.
  * <code>widgetDefaultSelected</code> is not called.
  * </p>
+ * <p>
+ * When the <code>SWT.RADIO</code> style bit is set, the <code>widgetSelected</code> method is
+ * also called when the receiver loses selection because another item in the same radio group 
+ * was selected by the user. During <code>widgetSelected</code> the application can use
+ * <code>getSelection()</code> to determine the current selected state of the receiver.
+ * </p>
  *
  * @param listener the listener which should be notified when the control is selected by the user,
  *
@@ -554,7 +560,7 @@ int /*long*/ gtk_clicked (int /*long*/ widget) {
 			selectRadio ();
 		}
 	}
-	postEvent (SWT.Selection, event);
+	sendSelectionEvent (SWT.Selection, event, false);
 	return 0;
 }
 
@@ -855,6 +861,17 @@ public void setEnabled (boolean enabled) {
 			OS.gtk_widget_hide (handle);
 			OS.gtk_widget_show (handle);
 		}
+	} else {
+		/*
+		* Bug in GTK. Starting with 2.14, if a button is disabled 
+		* through on a button press, the field which keeps track 
+		* whether the pointer is currently in the button is never updated.
+		* As a result, when it is re-enabled it automatically enters
+		* a PRELIGHT state. The fix is to set a NORMAL state.
+		*/
+		if (OS.GTK_VERSION >= OS.VERSION (2, 14, 0)) {
+			OS.gtk_widget_set_state (topHandle, OS.GTK_STATE_NORMAL);
+		}
 	}
 }
 
@@ -953,7 +970,7 @@ boolean setRadioSelection (boolean value) {
 	if ((style & SWT.RADIO) == 0) return false;
 	if (getSelection () != value) {
 		setSelection (value);
-		postEvent (SWT.Selection);
+		sendSelectionEvent (SWT.Selection);
 	}
 	return true;
 }
diff --git a/org/eclipse/swt/widgets/ToolTip.java b/org/eclipse/swt/widgets/ToolTip.java
index a106744..34b765f 100644
--- a/org/eclipse/swt/widgets/ToolTip.java
+++ b/org/eclipse/swt/widgets/ToolTip.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -463,12 +463,13 @@ public boolean getVisible () {
 }
 
 int /*long*/ gtk_button_press_event (int /*long*/ widget, int /*long*/ event) {
-	notifyListeners (SWT.Selection, new Event ());
+	sendSelectionEvent (SWT.Selection, null, true);
 	setVisible (false);
 	return 0;
 }
 
 int /*long*/ gtk_expose_event (int /*long*/ widget, int /*long*/ eventPtr) {
+	if ((state & OBSCURED) != 0) return 0;
 	int /*long*/ window = OS.GTK_WIDGET_WINDOW (handle);
 	int /*long*/ gdkGC = OS.gdk_gc_new (window);
 	OS.gdk_draw_polygon (window, gdkGC, 0, borderPolygon, borderPolygon.length / 2);
@@ -498,6 +499,8 @@ int /*long*/ gtk_expose_event (int /*long*/ widget, int /*long*/ eventPtr) {
 			x += IMAGE_SIZE;
 		}
 		x += INSET;
+		Color foreground = display.getSystemColor (SWT.COLOR_INFO_FOREGROUND);
+		OS.gdk_gc_set_foreground (gdkGC, foreground.handle);
 		OS.gdk_draw_layout (window, gdkGC, x, y, layoutText);
 		int [] w = new int [1], h = new int [1];
 		OS.pango_layout_get_size (layoutText, w, h);
@@ -505,6 +508,8 @@ int /*long*/ gtk_expose_event (int /*long*/ widget, int /*long*/ eventPtr) {
 	}
 	if (layoutMessage != 0) {
 		x = BORDER + PADDING + INSET;
+		Color foreground = display.getSystemColor (SWT.COLOR_INFO_FOREGROUND);
+		OS.gdk_gc_set_foreground (gdkGC, foreground.handle);
 		OS.gdk_draw_layout (window, gdkGC, x, y, layoutMessage);
 	}
 	OS.g_object_unref (gdkGC);
diff --git a/org/eclipse/swt/widgets/Tracker.java b/org/eclipse/swt/widgets/Tracker.java
index e5729d3..9bb9bc7 100644
--- a/org/eclipse/swt/widgets/Tracker.java
+++ b/org/eclipse/swt/widgets/Tracker.java
@@ -132,6 +132,7 @@ public Tracker (Display display, int style) {
 	}
 	this.style = checkStyle (style);
 	this.display = display;
+	reskinWidget ();
 }
 
 /**
diff --git a/org/eclipse/swt/widgets/Tray.java b/org/eclipse/swt/widgets/Tray.java
index 53fadef..e7c4ecf 100644
--- a/org/eclipse/swt/widgets/Tray.java
+++ b/org/eclipse/swt/widgets/Tray.java
@@ -45,6 +45,7 @@ Tray (Display display, int style) {
 		error (SWT.ERROR_THREAD_INVALID_ACCESS);
 	}
 	this.display = display;
+	reskinWidget ();
 }
 	
 void createItem (TrayItem item, int index) {
@@ -146,4 +147,14 @@ void releaseParent () {
 	if (display.tray == this) display.tray = null;
 }
 
+void reskinChildren (int flags) {	
+	if (items != null) {
+		for (int i=0; i<items.length; i++) {
+			TrayItem item = items [i];
+			if (item != null) item.reskin (flags);
+		}
+	}
+	super.reskinChildren (flags);
+}
+
 }
diff --git a/org/eclipse/swt/widgets/TrayItem.java b/org/eclipse/swt/widgets/TrayItem.java
index 7d1fb1f..ca2e9be 100644
--- a/org/eclipse/swt/widgets/TrayItem.java
+++ b/org/eclipse/swt/widgets/TrayItem.java
@@ -255,7 +255,7 @@ public String getToolTipText () {
 }
 
 int /*long*/ gtk_activate (int /*long*/ widget) {
-	postEvent (SWT.Selection);
+	sendSelectionEvent (SWT.Selection);
 	/*
 	* Feature in GTK. GTK will generate a single-click event before sending 
 	* a double-click event. To know when to send a DefaultSelection, look for 
@@ -273,7 +273,7 @@ int /*long*/ gtk_activate (int /*long*/ widget) {
 		}
 		OS.gdk_event_free (nextEvent);
 		if (currEventType == OS.GDK_BUTTON_PRESS && nextEventType == OS.GDK_2BUTTON_PRESS) {
-			postEvent (SWT.DefaultSelection);
+			sendSelectionEvent (SWT.DefaultSelection);
 		}
 	}
 	return 0;
@@ -288,9 +288,9 @@ int /*long*/ gtk_button_press_event (int /*long*/ widget, int /*long*/ eventPtr)
 		return 0;
 	}
 	if (gdkEvent.type == OS.GDK_2BUTTON_PRESS) {
-		postEvent (SWT.DefaultSelection);
+		sendSelectionEvent (SWT.DefaultSelection);
 	} else {
-		postEvent (SWT.Selection);
+		sendSelectionEvent (SWT.Selection);
 	}
 	return 0;
 }
diff --git a/org/eclipse/swt/widgets/Tree.java b/org/eclipse/swt/widgets/Tree.java
index e6a26ce..db619d7 100644
--- a/org/eclipse/swt/widgets/Tree.java
+++ b/org/eclipse/swt/widgets/Tree.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -674,8 +674,7 @@ void createColumn (TreeColumn column, int index) {
 		column.handle = columnHandle;
 		column.modelIndex = modelIndex;
 	}
-	/* Disable searching when using VIRTUAL */
-	if ((style & SWT.VIRTUAL) != 0) {
+	if (!searchEnabled ()) {
 		/*
 		* Bug in GTK. Until GTK 2.6.5, calling gtk_tree_view_set_enable_search(FALSE)
 		* would prevent the user from being able to type in text to search the tree.
@@ -727,12 +726,13 @@ void createHandle (int index) {
 	int vsp = (style & SWT.V_SCROLL) != 0 ? OS.GTK_POLICY_AUTOMATIC : OS.GTK_POLICY_NEVER;
 	OS.gtk_scrolled_window_set_policy (scrolledHandle, hsp, vsp);
 	if ((style & SWT.BORDER) != 0) OS.gtk_scrolled_window_set_shadow_type (scrolledHandle, OS.GTK_SHADOW_ETCHED_IN);
-	/* Disable searching when using VIRTUAL */
 	if ((style & SWT.VIRTUAL) != 0) {
 		/* The fixed_height_mode property only exists in GTK 2.3.2 and greater */
 		if (OS.GTK_VERSION >= OS.VERSION (2, 3, 2)) {
 			OS.g_object_set (handle, OS.fixed_height_mode, true, 0);
 		}
+	}
+	if (!searchEnabled ()) {
 		/*
 		* Bug in GTK. Until GTK 2.6.5, calling gtk_tree_view_set_enable_search(FALSE)
 		* would prevent the user from being able to type in text to search the tree.
@@ -1054,8 +1054,7 @@ void destroyItem (TreeColumn column) {
 			createRenderers (firstColumn.handle, firstColumn.modelIndex, true, firstColumn.style);
 		}
 	}
-	/* Disable searching when using VIRTUAL */
-	if ((style & SWT.VIRTUAL) != 0) {
+	if (!searchEnabled ()) {
 		/*
 		* Bug in GTK. Until GTK 2.6.5, calling gtk_tree_view_set_enable_search(FALSE)
 		* would prevent the user from being able to type in text to search the tree.
@@ -1927,7 +1926,7 @@ int /*long*/ gtk_changed (int /*long*/ widget) {
 	if (item != null) {
 		Event event = new Event ();
 		event.item = item;
-		postEvent (SWT.Selection, event);
+		sendSelectionEvent (SWT.Selection, event, false);
 	}
 	return 0;
 }
@@ -1938,6 +1937,42 @@ int /*long*/ gtk_expand_collapse_cursor_row (int /*long*/ widget, int /*long*/ l
 	return 0;
 }
 
+int /*long*/ gtk_expose_event (int /*long*/ widget, int /*long*/ eventPtr) {
+	if ((state & OBSCURED) != 0) return 0;
+	if ((state & PARENT_BACKGROUND) != 0 || backgroundImage != null) {
+		Control control = findBackgroundControl ();
+		if (control != null) {
+			GdkEventExpose gdkEvent = new GdkEventExpose ();
+			OS.memmove (gdkEvent, eventPtr, GdkEventExpose.sizeof);
+			int /*long*/ window = OS.gtk_tree_view_get_bin_window (handle);
+			if (window == gdkEvent.window) {
+				int [] width = new int [1], height = new int [1];
+				OS.gdk_drawable_get_size (window, width, height);
+				int /*long*/ parent = 0;
+				int itemCount = OS.gtk_tree_model_iter_n_children (modelHandle, parent);
+				GdkRectangle rect = new GdkRectangle ();
+				boolean expanded = true;
+				while (itemCount != 0 && expanded && height [0] > (rect.y + rect.height)) {
+					int /*long*/ iter = OS.g_malloc (OS.GtkTreeIter_sizeof ());
+					OS.gtk_tree_model_iter_nth_child (modelHandle, iter, parent, itemCount - 1);
+					itemCount = OS.gtk_tree_model_iter_n_children (modelHandle, iter);
+					int /*long*/ path = OS.gtk_tree_model_get_path (modelHandle, iter);
+					OS.gtk_tree_view_get_cell_area (handle, path, 0, rect);
+					expanded = OS.gtk_tree_view_row_expanded (handle, path); 
+					OS.gtk_tree_path_free (path);
+					if (parent != 0) OS.g_free (parent);
+					parent = iter;
+				}
+				if (parent != 0) OS.g_free (parent);
+				if (height [0] > (rect.y + rect.height)) {
+					drawBackground (control, window, gdkEvent.region, 0, rect.y + rect.height, width [0], height [0] - (rect.y + rect.height));
+				}
+			}
+		}
+	}
+	return super.gtk_expose_event (widget, eventPtr);
+}
+
 int /*long*/ gtk_key_press_event (int /*long*/ widget, int /*long*/ eventPtr) {
 	int /*long*/ result = super.gtk_key_press_event (widget, eventPtr);
 	if (result != 0) return result;
@@ -1955,7 +1990,7 @@ int /*long*/ gtk_key_press_event (int /*long*/ widget, int /*long*/ eventPtr) {
 			case OS.GDK_KP_Enter: {
 				Event event = new Event ();
 				event.item = getFocusItem (); 
-				postEvent (SWT.DefaultSelection, event);
+				sendSelectionEvent (SWT.DefaultSelection, event, false);
 				break;
 			}
 		}
@@ -1995,7 +2030,7 @@ int /*long*/ gtk_row_activated (int /*long*/ tree, int /*long*/ path, int /*long
 	OS.g_free (iter);
 	Event event = new Event ();
 	event.item = item;
-	postEvent (SWT.DefaultSelection, event);
+	sendSelectionEvent (SWT.DefaultSelection, event, false);
 	return 0;
 }
 
@@ -2013,6 +2048,14 @@ int gtk_row_inserted (int model, int path, int iter) {
 	return 0;
 }
 
+int /*long*/ gtk_start_interactive_search(int /*long*/ widget) {
+	if (!searchEnabled()) {
+		OS.g_signal_stop_emission_by_name(widget, OS.start_interactive_search); 
+		return 1;
+	}
+	return 0;
+}
+
 int /*long*/ gtk_test_collapse_row (int /*long*/ tree, int /*long*/ iter, int /*long*/ path) {
 	int [] index = new int [1];
 	OS.gtk_tree_model_get (modelHandle, iter, ID_COLUMN, index, -1);
@@ -2108,7 +2151,7 @@ int /*long*/ gtk_toggled (int /*long*/ renderer, int /*long*/ pathStr) {
 		Event event = new Event ();
 		event.detail = SWT.CHECK;
 		event.item = item;
-		postEvent (SWT.Selection, event);
+		sendSelectionEvent (SWT.Selection, event, false);
 	}
 	return 0;
 }
@@ -2162,6 +2205,7 @@ void hookEvents () {
 	if (checkRenderer != 0) {
 		OS.g_signal_connect_closure (checkRenderer, OS.toggled, display.closures [TOGGLED], false);
 	}
+	OS.g_signal_connect_closure (handle, OS.start_interactive_search, display.closures[START_INTERACTIVE_SEARCH], false);
 	if (fixAccessibility ()) {
 		OS.g_signal_connect_closure (modelHandle, OS.row_inserted, display.closures [ROW_INSERTED], true);
 		OS.g_signal_connect_closure (modelHandle, OS.row_deleted, display.closures [ROW_DELETED], true);
@@ -2409,8 +2453,7 @@ public void removeAll () {
 	}
 	OS.g_signal_handlers_unblock_matched (selection, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED);
 	
-	/* Disable searching when using VIRTUAL */
-	if ((style & SWT.VIRTUAL) != 0) {
+	if (!searchEnabled ()) {
 		/*
 		* Bug in GTK. Until GTK 2.6.5, calling gtk_tree_view_set_enable_search(FALSE)
 		* would prevent the user from being able to type in text to search the tree.
@@ -2567,17 +2610,24 @@ int /*long*/ rendererRenderProc (int /*long*/ cell, int /*long*/ window, int /*l
 			OS.gtk_tree_path_free (path);
 			
 			if ((drawState & SWT.SELECTED) == 0) {
-				Control control = findBackgroundControl ();
-				if (control != null && control.backgroundImage != null) {
-					OS.gdk_window_clear_area (window, rect.x, rect.y, rect.width, rect.height);
+				if ((state & PARENT_BACKGROUND) != 0 || backgroundImage != null) {
+					Control control = findBackgroundControl ();
+					if (control != null) {
+						drawBackground (control, window, 0, rect.x, rect.y, rect.width, rect.height);
+					}
 				}
 			}
 
+			//send out measure before erase
+			int /*long*/ textRenderer =  getTextRenderer (columnHandle);
+			if (textRenderer != 0) OS.gtk_cell_renderer_get_size (textRenderer, handle, null, null, null, null, null);
+			
 			if (hooks (SWT.EraseItem)) {
-				boolean wasSelected = false; 
-				if ((drawState & SWT.SELECTED) != 0) {
-					wasSelected = true;
-					OS.gdk_window_clear_area (window, rect.x, rect.y, rect.width, rect.height);
+				boolean wasSelected = (drawState & SWT.SELECTED) != 0;
+				if (wasSelected) {
+					Control control = findBackgroundControl ();
+					if (control == null) control = this;
+					drawBackground (control, window, 0, rect.x, rect.y, rect.width, rect.height);
 				}
 				GC gc = new GC (this);
 				if ((drawState & SWT.SELECTED) != 0) {
@@ -2713,6 +2763,33 @@ void resetCustomDraw () {
 	firstCustomDraw = false;
 }
 
+void reskinChildren (int flags) {
+	if (items != null) {
+		for (int i=0; i<items.length; i++) {
+			TreeItem item = items [i];
+			if (item != null) item.reskinChildren (flags);
+		}
+	}
+	if (columns != null) {
+		for (int i=0; i<columns.length; i++) {
+			TreeColumn column = columns [i];
+			if (column != null) column.reskinChildren (flags);
+		}
+	}
+	super.reskinChildren (flags);
+}
+boolean searchEnabled () {
+	/* Disable searching when using VIRTUAL */
+	if ((style & SWT.VIRTUAL) != 0) return false;
+	if (OS.GTK_VERSION < OS.VERSION (2, 6, 0)) {
+		int mask = SWT.PRIMARY_MODAL | SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL;
+		Shell shell = getShell();
+		if ((shell.style & mask) != 0) {
+			return false;
+		}
+	}
+	return true;
+}
 /**
  * Display a mark indicating the point at which an item will be inserted.
  * The drop insert item has a visual hint to show where a dragged item 
@@ -2853,9 +2930,8 @@ void setBackgroundColor (GdkColor color) {
 }
 
 void setBackgroundPixmap (int /*long*/ pixmap) {
-	super.setBackgroundPixmap (pixmap);
-	int /*long*/ window = paintWindow ();
-	if (window != 0) OS.gdk_window_set_back_pixmap (window, 0, true);	
+	ownerDraw = true;
+	recreateRenderers ();
 }
 
 int setBounds (int x, int y, int width, int height, boolean move, boolean resize) {
@@ -2988,9 +3064,8 @@ public void setLinesVisible (boolean show) {
 }
 
 void setParentBackground () {
-	super.setParentBackground ();
-	int /*long*/ window = paintWindow ();
-	if (window != 0) OS.gdk_window_set_back_pixmap (window, 0, true);
+	ownerDraw = true;
+	recreateRenderers ();
 }
 
 void setParentWindow (int /*long*/ widget) {
@@ -3382,4 +3457,32 @@ void updateScrollBarValue (ScrollBar bar) {
 	OS.g_list_free (list);
 }
 
+int /*long*/ windowProc (int /*long*/ handle, int /*long*/ arg0, int /*long*/ user_data) {
+	switch ((int)/*64*/user_data) {
+		case EXPOSE_EVENT_INVERSE: {
+			/*
+			 * Feature in GTK. When the GtkTreeView has no items it does not propagate
+			 * expose events. The fix is to fill the background in the inverse expose
+			 * event.
+			 */
+			int itemCount = OS.gtk_tree_model_iter_n_children (modelHandle, 0);
+			if (itemCount == 0 && (state & OBSCURED) == 0) {
+				if ((state & PARENT_BACKGROUND) != 0 || backgroundImage != null) {
+					Control control = findBackgroundControl ();
+					if (control != null) {
+						GdkEventExpose gdkEvent = new GdkEventExpose ();
+						OS.memmove (gdkEvent, arg0, GdkEventExpose.sizeof);
+						int /*long*/ window = OS.gtk_tree_view_get_bin_window (handle);
+						if (window == gdkEvent.window) {
+							drawBackground (control, window, gdkEvent.region, gdkEvent.area_x, gdkEvent.area_y, gdkEvent.area_width, gdkEvent.area_height);
+						}
+					}
+				}
+			}
+			break;
+		}
+	}
+	return super.windowProc (handle, arg0, user_data);
+}
+
 }
diff --git a/org/eclipse/swt/widgets/TreeColumn.java b/org/eclipse/swt/widgets/TreeColumn.java
index a3b6ee5..115c7f8 100644
--- a/org/eclipse/swt/widgets/TreeColumn.java
+++ b/org/eclipse/swt/widgets/TreeColumn.java
@@ -364,7 +364,7 @@ int /*long*/ gtk_clicked (int /*long*/ widget) {
 			}
 		}
 	}
-	if (postEvent) postEvent (doubleClick ? SWT.DefaultSelection : SWT.Selection);
+	if (postEvent) sendSelectionEvent (doubleClick ? SWT.DefaultSelection : SWT.Selection);
 	return 0;
 }
 
@@ -691,6 +691,35 @@ public void setWidth (int width) {
 	if (width != 0) OS.gtk_widget_realize (parent.handle);
 	OS.gtk_tree_view_column_set_visible (handle, width != 0);
 	lastWidth = width;
+	/*
+	 * Bug in GTK. When the column is made visible the event window of column
+	 * header is raised above the gripper window of the previous column. In 
+	 * some cases, this can cause the previous column to be not resizable by
+	 * the mouse. The fix is to find the event window and lower it to bottom to
+	 * the z-order stack. 
+	 */
+	if (width != 0) {
+		if (buttonHandle != 0) {
+			int /*long*/ window = OS.gtk_widget_get_parent_window (buttonHandle);
+			if (window != 0) {
+				int /*long*/ windowList = OS.gdk_window_get_children (window);
+				if (windowList != 0) {
+					int /*long*/ windows = windowList;
+					int /*long*/ [] userData = new int /*long*/ [1];
+					while (windows != 0) {
+						int /*long*/ child = OS.g_list_data (windows);
+						OS.gdk_window_get_user_data (child, userData);
+						if (userData[0] == buttonHandle) {
+							OS.gdk_window_lower (child);
+							break;
+						}
+						windows = OS.g_list_next (windows);
+					}
+					OS.g_list_free (windowList);
+				}
+			}
+		}
+	}
 	sendEvent (SWT.Resize);
 }
 
diff --git a/org/eclipse/swt/widgets/TreeItem.java b/org/eclipse/swt/widgets/TreeItem.java
index 1102499..c40dea4 100644
--- a/org/eclipse/swt/widgets/TreeItem.java
+++ b/org/eclipse/swt/widgets/TreeItem.java
@@ -479,10 +479,10 @@ public Rectangle getBounds (int index) {
 }
 
 /**
- * Returns a rectangle describing the receiver's size and location
- * relative to its parent.
+ * Returns a rectangle describing the size and location of the receiver's
+ * text relative to its parent.
  *
- * @return the receiver's bounding rectangle
+ * @return the bounding rectangle of the receiver's text
  *
  * @exception SWTException <ul>
  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
@@ -1449,8 +1449,6 @@ public void setFont (int index, Font font) {
  *
  * @param color the new color (or null)
  *
- * @since 2.0
- * 
  * @exception IllegalArgumentException <ul>
  *    <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> 
  * </ul>
diff --git a/org/eclipse/swt/widgets/TypedListener.java b/org/eclipse/swt/widgets/TypedListener.java
index d352c10..db4fb1d 100644
--- a/org/eclipse/swt/widgets/TypedListener.java
+++ b/org/eclipse/swt/widgets/TypedListener.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -46,6 +46,8 @@ public class TypedListener implements Listener {
  * </p>
  *
  * @param listener the event listener to store in the receiver
+ * 
+ * @noreference This method is not intended to be referenced by clients.
  */
 public TypedListener (SWTEventListener listener) {
 	eventListener = listener;
@@ -61,6 +63,8 @@ public TypedListener (SWTEventListener listener) {
  * </p>
  *
  * @return the receiver's event listener
+ * 
+ * @noreference This method is not intended to be referenced by clients.
  */
 public SWTEventListener getEventListener () {
 	return eventListener;
@@ -75,6 +79,8 @@ public SWTEventListener getEventListener () {
  * referenced from application code.
  * </p>
  * @param e the event to handle
+ * 
+ * @noreference This method is not intended to be referenced by clients.
  */
 public void handleEvent (Event e) {
 	switch (e.type) {
diff --git a/org/eclipse/swt/widgets/Widget.java b/org/eclipse/swt/widgets/Widget.java
index a391ca1..48e0601 100644
--- a/org/eclipse/swt/widgets/Widget.java
+++ b/org/eclipse/swt/widgets/Widget.java
@@ -53,6 +53,8 @@ public abstract class Widget {
 	 * within the packages provided by SWT. It is not available on all
 	 * platforms and should never be accessed from application code.
 	 * </p>
+	 * 
+	 * @noreference This field is not intended to be referenced by clients.
 	 */
 	public int /*long*/ handle;
 	int style, state;
@@ -94,6 +96,12 @@ public abstract class Widget {
 	static final int FOREIGN_HANDLE = 1<<22;
 	static final int DRAG_DETECT = 1<<23;
 	
+	/* Notify of the opportunity to skin this widget */
+	static final int SKIN_NEEDED = 1<<24;
+
+	/* Should sub-windows be checked when EnterNotify received */
+	static final int CHECK_SUBWINDOW = 1<<25;
+
 	/* Default size for widgets */
 	static final int DEFAULT_WIDTH	= 64;
 	static final int DEFAULT_HEIGHT	= 64;
@@ -165,7 +173,13 @@ public abstract class Widget {
 	static final int ROW_INSERTED = 64;
 	static final int ROW_DELETED = 65;
 	static final int DAY_SELECTED_DOUBLE_CLICK = 66;
-	static final int LAST_SIGNAL = 67;
+	static final int ICON_RELEASE = 67;
+	static final int SELECTION_DONE = 68;
+	static final int START_INTERACTIVE_SEARCH = 69;
+	static final int LAST_SIGNAL = 70;
+	
+	static final String IS_ACTIVE = "org.eclipse.swt.internal.control.isactive"; //$NON-NLS-1$
+	static final String KEY_CHECK_SUBWINDOW = "org.eclipse.swt.internal.control.checksubwindow"; //$NON-NLS-1$
 
 /**
  * Prevents uninitialized instances from being created outside the package.
@@ -206,6 +220,7 @@ public Widget (Widget parent, int style) {
 	checkParent (parent);
 	this.style = style;
 	display = parent.display;
+	reskinWidget ();
 }
 
 void _addListener (int eventType, Listener listener) {
@@ -420,6 +435,7 @@ void destroyWidget () {
  * <code>true</code> when sent the message <code>isDisposed()</code>.
  * Any internal connections between the widgets in the tree will
  * have been removed to facilitate garbage collection.
+ * This method does nothing if the widget is already disposed.
  * <p>
  * NOTE: This method is not called recursively on the descendants
  * of the receiver. This means that, widget implementers can not
@@ -503,6 +519,10 @@ public Object getData () {
 public Object getData (String key) {
 	checkWidget();
 	if (key == null) error (SWT.ERROR_NULL_ARGUMENT);
+	if (key.equals (KEY_CHECK_SUBWINDOW)) {
+		return new Boolean ((state & CHECK_SUBWINDOW) != 0);
+	}
+	if (key.equals(IS_ACTIVE)) return new Boolean(isActive ());
 	if ((state & KEYED_DATA) != 0) {
 		Object [] table = (Object []) data;
 		for (int i=1; i<table.length; i+=2) {
@@ -692,6 +712,10 @@ int /*long*/ gtk_hide (int /*long*/ widget) {
 	return 0;
 }
 
+int /*long*/ gtk_icon_release (int /*long*/ widget, int /*long*/ icon_pos, int /*long*/ event) {
+	return 0;
+}
+
 int /*long*/ gtk_input (int /*long*/ widget, int /*long*/ arg1) {
 	return 0;
 }
@@ -784,6 +808,10 @@ int /*long*/ gtk_select (int /*long*/ item) {
 	return 0;
 }
 
+int /*long*/ gtk_selection_done (int /*long*/ menushell) {
+	return 0;
+} 
+
 int /*long*/ gtk_show (int /*long*/ widget) {
 	return 0;
 }
@@ -800,6 +828,10 @@ int /*long*/ gtk_status_icon_popup_menu (int /*long*/ handle, int /*long*/ butto
 	return 0;
 }
 
+int /*long*/ gtk_start_interactive_search (int /*long*/ widget) {
+	return 0;
+}
+
 int /*long*/ gtk_style_set (int /*long*/ widget, int /*long*/ previousStyle) {
 	return 0;
 }
@@ -908,13 +940,17 @@ char [] fixMnemonic (String string, boolean replace) {
 	return result;
 }
 
+boolean isActive () {
+	return true;
+}
+
 /**
  * Returns <code>true</code> if the widget has been disposed,
  * and <code>false</code> otherwise.
  * <p>
  * This method gets the dispose state for the widget.
  * When a widget has been disposed, it is an error to
- * invoke any other method using the widget.
+ * invoke any other method (except {@link #dispose()}) using the widget.
  * </p>
  *
  * @return <code>true</code> when the widget is disposed and <code>false</code> otherwise
@@ -1130,6 +1166,8 @@ public void removeListener (int eventType, Listener handler) {
  *
  * @see Listener
  * @see #addListener
+ * 
+ * @noreference This method is not intended to be referenced by clients.
  */
 protected void removeListener (int eventType, SWTEventListener handler) {
 	checkWidget ();
@@ -1147,6 +1185,50 @@ int /*long*/ rendererRenderProc (int /*long*/ cell, int /*long*/ window, int /*l
 }
 
 /**
+ * Marks the widget to be skinned. 
+ * <p>
+ * The skin event is sent to the receiver's display when appropriate (usually before the next event
+ * is handled). Widgets are automatically marked for skinning upon creation as well as when its skin
+ * id or class changes. The skin id and/or class can be changed by calling <code>Display.setData(String, Object)</code> 
+ * with the keys SWT.SKIN_ID and/or SWT.SKIN_CLASS. Once the skin event is sent to a widget, it 
+ * will not be sent again unless <code>reskin(int)</code> is called on the widget or on an ancestor 
+ * while specifying the <code>SWT.ALL</code> flag.  
+ * </p>
+ * <p>
+ * The parameter <code>flags</code> may be either:
+ * <dl>
+ * <dt><b>SWT.ALL</b></dt>
+ * <dd>all children in the receiver's widget tree should be skinned</dd>
+ * <dt><b>SWT.NONE</b></dt>
+ * <dd>only the receiver should be skinned</dd>
+ * </dl>
+ * </p>
+ * @param flags the flags specifying how to reskin
+ * 
+ * @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>
+ * @since 3.6
+ */
+public void reskin (int flags) {
+	checkWidget ();
+	reskinWidget ();
+	if ((flags & SWT.ALL) != 0) reskinChildren (flags);
+}
+
+void reskinChildren (int flags) {	
+}
+
+void reskinWidget() {
+	if ((state & SKIN_NEEDED) != SKIN_NEEDED) {
+		this.state |= SKIN_NEEDED;
+		display.addSkinnableWidget(this);
+	}
+}
+
+/**
  * Removes the listener from the collection of listeners who will
  * be notified when the widget is disposed.
  *
@@ -1284,6 +1366,36 @@ char [] sendIMKeyEvent (int type, GdkEventKey keyEvent, char [] chars) {
 	return chars;
 }
 
+void sendSelectionEvent (int eventType) {
+	sendSelectionEvent (eventType, null, false);
+}
+
+void sendSelectionEvent (int eventType, Event event, boolean send) {
+	if (eventTable == null && !display.filters (eventType)) {
+		return;
+	}
+	if (event == null) event = new Event ();
+	int /*long*/ ptr = OS.gtk_get_current_event ();
+	if (ptr != 0) {
+		GdkEvent gdkEvent = new GdkEvent ();
+		OS.memmove (gdkEvent, ptr, GdkEvent.sizeof);
+		switch (gdkEvent.type) {
+			case OS.GDK_KEY_PRESS:
+			case OS.GDK_KEY_RELEASE: 
+			case OS.GDK_BUTTON_PRESS:
+			case OS.GDK_2BUTTON_PRESS: 
+			case OS.GDK_BUTTON_RELEASE: {
+				int [] state = new int [1];
+				OS.gdk_event_get_state (ptr, state);
+				setInputState (event, state [0]);
+				break;
+			}
+		}
+		OS.gdk_event_free (ptr);
+	}
+	sendEvent (eventType, event, send);
+}
+
 /**
  * Sets the application defined widget data associated
  * with the receiver to be the argument. The <em>widget
@@ -1342,6 +1454,18 @@ public void setData (Object data) {
 public void setData (String key, Object value) {
 	checkWidget();
 	if (key == null) error (SWT.ERROR_NULL_ARGUMENT);
+
+	if (key.equals (KEY_CHECK_SUBWINDOW)) {
+		if (value != null && value instanceof Boolean) {
+			if (((Boolean)value).booleanValue ()) {
+				state |= CHECK_SUBWINDOW;
+			} else {
+				state &= ~CHECK_SUBWINDOW;
+			}
+		}
+		return;
+	}
+
 	int index = 1;
 	Object [] table = null;
 	if ((state & KEYED_DATA) != 0) {
@@ -1382,6 +1506,7 @@ public void setData (String key, Object value) {
 			}
 		}
 	}
+	if (key.equals(SWT.SKIN_CLASS) || key.equals(SWT.SKIN_ID)) this.reskin(SWT.ALL);
 }
 
 void setForegroundColor (int /*long*/ handle, GdkColor color) {
@@ -1456,12 +1581,58 @@ boolean setKeyState (Event event, GdkEventKey keyEvent) {
 			}
 		}
 	}
+	setLocationState(event, keyEvent);
 	if (event.keyCode == 0 && event.character == 0) {
 		if (!isNull) return false;
 	}
 	return setInputState (event, keyEvent.state);
 }
 
+void setLocationState (Event event, GdkEventKey keyEvent) {
+	switch (keyEvent.keyval) {
+		case OS.GDK_Alt_L:
+		case OS.GDK_Shift_L:
+		case OS.GDK_Control_L:
+			event.keyLocation = SWT.LEFT;
+			break;
+		case OS.GDK_Alt_R:
+		case OS.GDK_Shift_R:
+		case OS.GDK_Control_R:
+				event.keyLocation = SWT.RIGHT;
+			break;
+		case OS.GDK_KP_0:
+		case OS.GDK_KP_1:
+		case OS.GDK_KP_2:
+		case OS.GDK_KP_3:
+		case OS.GDK_KP_4:
+		case OS.GDK_KP_5:
+		case OS.GDK_KP_6:
+		case OS.GDK_KP_7:
+		case OS.GDK_KP_8:
+		case OS.GDK_KP_9:
+		case OS.GDK_KP_Add:
+		case OS.GDK_KP_Decimal:
+		case OS.GDK_KP_Delete:
+		case OS.GDK_KP_Divide:
+		case OS.GDK_KP_Down:
+		case OS.GDK_KP_End:
+		case OS.GDK_KP_Enter:
+		case OS.GDK_KP_Equal:
+		case OS.GDK_KP_Home:
+		case OS.GDK_KP_Insert:
+		case OS.GDK_KP_Left:
+		case OS.GDK_KP_Multiply:
+		case OS.GDK_KP_Page_Down:
+		case OS.GDK_KP_Page_Up:
+		case OS.GDK_KP_Right:
+		case OS.GDK_KP_Subtract:
+		case OS.GDK_KP_Up:
+		case OS.GDK_Num_Lock:
+			event.keyLocation = SWT.KEYPAD;
+			break;
+	}
+}
+
 void setOrientation () {
 }
 
@@ -1531,7 +1702,9 @@ int /*long*/ windowProc (int /*long*/ handle, int /*long*/ user_data) {
 		case POPUP_MENU: return gtk_popup_menu (handle);
 		case PREEDIT_CHANGED: return gtk_preedit_changed (handle);
 		case REALIZE: return gtk_realize (handle);
+		case START_INTERACTIVE_SEARCH: return gtk_start_interactive_search (handle);
 		case SELECT: return gtk_select (handle);
+		case SELECTION_DONE: return gtk_selection_done (handle);
 		case SHOW: return gtk_show (handle);
 		case VALUE_CHANGED: return gtk_value_changed (handle);
 		case UNMAP: return gtk_unmap (handle);
@@ -1593,6 +1766,7 @@ int /*long*/ windowProc (int /*long*/ handle, int /*long*/ arg0, int /*long*/ ar
 	switch ((int)/*64*/user_data) {
 		case DELETE_RANGE: return gtk_delete_range (handle, arg0, arg1);
 		case DELETE_TEXT: return gtk_delete_text (handle, arg0, arg1);
+		case ICON_RELEASE: return gtk_icon_release (handle, arg0, arg1);
 		case ROW_ACTIVATED: return gtk_row_activated (handle, arg0, arg1);
 		case SCROLL_CHILD: return gtk_scroll_child (handle, arg0, arg1);
 		case STATUS_ICON_POPUP_MENU: return gtk_status_icon_popup_menu (handle, arg0, arg1);
diff --git a/os.c b/os.c
index 7e69ea0..90076c4 100644
--- a/os.c
+++ b/os.c
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others. All rights reserved.
+ * Copyright (c) 2000, 2010 IBM Corporation and others. All rights reserved.
  * The contents of this file are made available under the terms
  * of the GNU Lesser General Public License (LGPL) Version 2.1 that
  * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
@@ -147,6 +147,78 @@ JNIEXPORT jintLong JNICALL OS_NATIVE(GTK_1ENTRY_1IM_1CONTEXT)
 }
 #endif
 
+#ifndef NO_GTK_1RANGE_1HAS_1STEPPER_1A
+JNIEXPORT jboolean JNICALL OS_NATIVE(GTK_1RANGE_1HAS_1STEPPER_1A)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jboolean rc = 0;
+	OS_NATIVE_ENTER(env, that, GTK_1RANGE_1HAS_1STEPPER_1A_FUNC);
+	rc = (jboolean)GTK_RANGE_HAS_STEPPER_A((GtkRange *)arg0);
+	OS_NATIVE_EXIT(env, that, GTK_1RANGE_1HAS_1STEPPER_1A_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO_GTK_1RANGE_1HAS_1STEPPER_1B
+JNIEXPORT jboolean JNICALL OS_NATIVE(GTK_1RANGE_1HAS_1STEPPER_1B)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jboolean rc = 0;
+	OS_NATIVE_ENTER(env, that, GTK_1RANGE_1HAS_1STEPPER_1B_FUNC);
+	rc = (jboolean)GTK_RANGE_HAS_STEPPER_B((GtkRange *)arg0);
+	OS_NATIVE_EXIT(env, that, GTK_1RANGE_1HAS_1STEPPER_1B_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO_GTK_1RANGE_1HAS_1STEPPER_1C
+JNIEXPORT jboolean JNICALL OS_NATIVE(GTK_1RANGE_1HAS_1STEPPER_1C)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jboolean rc = 0;
+	OS_NATIVE_ENTER(env, that, GTK_1RANGE_1HAS_1STEPPER_1C_FUNC);
+	rc = (jboolean)GTK_RANGE_HAS_STEPPER_C((GtkRange *)arg0);
+	OS_NATIVE_EXIT(env, that, GTK_1RANGE_1HAS_1STEPPER_1C_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO_GTK_1RANGE_1HAS_1STEPPER_1D
+JNIEXPORT jboolean JNICALL OS_NATIVE(GTK_1RANGE_1HAS_1STEPPER_1D)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jboolean rc = 0;
+	OS_NATIVE_ENTER(env, that, GTK_1RANGE_1HAS_1STEPPER_1D_FUNC);
+	rc = (jboolean)GTK_RANGE_HAS_STEPPER_D((GtkRange *)arg0);
+	OS_NATIVE_EXIT(env, that, GTK_1RANGE_1HAS_1STEPPER_1D_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO_GTK_1RANGE_1SLIDER_1END
+JNIEXPORT jint JNICALL OS_NATIVE(GTK_1RANGE_1SLIDER_1END)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jint rc = 0;
+	OS_NATIVE_ENTER(env, that, GTK_1RANGE_1SLIDER_1END_FUNC);
+	rc = (jint)GTK_RANGE_SLIDER_END((GtkRange *)arg0);
+	OS_NATIVE_EXIT(env, that, GTK_1RANGE_1SLIDER_1END_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO_GTK_1RANGE_1SLIDER_1START
+JNIEXPORT jint JNICALL OS_NATIVE(GTK_1RANGE_1SLIDER_1START)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jint rc = 0;
+	OS_NATIVE_ENTER(env, that, GTK_1RANGE_1SLIDER_1START_FUNC);
+	rc = (jint)GTK_RANGE_SLIDER_START((GtkRange *)arg0);
+	OS_NATIVE_EXIT(env, that, GTK_1RANGE_1SLIDER_1START_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO_GTK_1SCROLLED_1WINDOW_1HSCROLLBAR
 JNIEXPORT jintLong JNICALL OS_NATIVE(GTK_1SCROLLED_1WINDOW_1HSCROLLBAR)
 	(JNIEnv *env, jclass that, jintLong arg0)
@@ -387,6 +459,78 @@ JNIEXPORT void JNICALL OS_NATIVE(G_1OBJECT_1CLASS_1SET_1CONSTRUCTOR)
 }
 #endif
 
+#ifndef NO_G_1TYPE_1BOOLEAN
+JNIEXPORT jintLong JNICALL OS_NATIVE(G_1TYPE_1BOOLEAN)
+	(JNIEnv *env, jclass that)
+{
+	jintLong rc = 0;
+	OS_NATIVE_ENTER(env, that, G_1TYPE_1BOOLEAN_FUNC);
+	rc = (jintLong)G_TYPE_BOOLEAN;
+	OS_NATIVE_EXIT(env, that, G_1TYPE_1BOOLEAN_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO_G_1TYPE_1DOUBLE
+JNIEXPORT jintLong JNICALL OS_NATIVE(G_1TYPE_1DOUBLE)
+	(JNIEnv *env, jclass that)
+{
+	jintLong rc = 0;
+	OS_NATIVE_ENTER(env, that, G_1TYPE_1DOUBLE_FUNC);
+	rc = (jintLong)G_TYPE_DOUBLE;
+	OS_NATIVE_EXIT(env, that, G_1TYPE_1DOUBLE_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO_G_1TYPE_1FLOAT
+JNIEXPORT jintLong JNICALL OS_NATIVE(G_1TYPE_1FLOAT)
+	(JNIEnv *env, jclass that)
+{
+	jintLong rc = 0;
+	OS_NATIVE_ENTER(env, that, G_1TYPE_1FLOAT_FUNC);
+	rc = (jintLong)G_TYPE_FLOAT;
+	OS_NATIVE_EXIT(env, that, G_1TYPE_1FLOAT_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO_G_1TYPE_1INT
+JNIEXPORT jintLong JNICALL OS_NATIVE(G_1TYPE_1INT)
+	(JNIEnv *env, jclass that)
+{
+	jintLong rc = 0;
+	OS_NATIVE_ENTER(env, that, G_1TYPE_1INT_FUNC);
+	rc = (jintLong)G_TYPE_INT;
+	OS_NATIVE_EXIT(env, that, G_1TYPE_1INT_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO_G_1TYPE_1INT64
+JNIEXPORT jintLong JNICALL OS_NATIVE(G_1TYPE_1INT64)
+	(JNIEnv *env, jclass that)
+{
+	jintLong rc = 0;
+	OS_NATIVE_ENTER(env, that, G_1TYPE_1INT64_FUNC);
+	rc = (jintLong)G_TYPE_INT64;
+	OS_NATIVE_EXIT(env, that, G_1TYPE_1INT64_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO_G_1VALUE_1TYPE
+JNIEXPORT jintLong JNICALL OS_NATIVE(G_1VALUE_1TYPE)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	OS_NATIVE_ENTER(env, that, G_1VALUE_1TYPE_FUNC);
+	rc = (jintLong)G_VALUE_TYPE(arg0);
+	OS_NATIVE_EXIT(env, that, G_1VALUE_1TYPE_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO_GdkColor_1sizeof
 JNIEXPORT jint JNICALL OS_NATIVE(GdkColor_1sizeof)
 	(JNIEnv *env, jclass that)
@@ -495,6 +639,18 @@ JNIEXPORT jint JNICALL OS_NATIVE(GdkEventMotion_1sizeof)
 }
 #endif
 
+#ifndef NO_GdkEventProperty_1sizeof
+JNIEXPORT jint JNICALL OS_NATIVE(GdkEventProperty_1sizeof)
+	(JNIEnv *env, jclass that)
+{
+	jint rc = 0;
+	OS_NATIVE_ENTER(env, that, GdkEventProperty_1sizeof_FUNC);
+	rc = (jint)GdkEventProperty_sizeof();
+	OS_NATIVE_EXIT(env, that, GdkEventProperty_1sizeof_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO_GdkEventScroll_1sizeof
 JNIEXPORT jint JNICALL OS_NATIVE(GdkEventScroll_1sizeof)
 	(JNIEnv *env, jclass that)
@@ -963,18 +1119,6 @@ JNIEXPORT jint JNICALL OS_NATIVE(XAnyEvent_1sizeof)
 }
 #endif
 
-#ifndef NO_XButtonEvent_1sizeof
-JNIEXPORT jint JNICALL OS_NATIVE(XButtonEvent_1sizeof)
-	(JNIEnv *env, jclass that)
-{
-	jint rc = 0;
-	OS_NATIVE_ENTER(env, that, XButtonEvent_1sizeof_FUNC);
-	rc = (jint)XButtonEvent_sizeof();
-	OS_NATIVE_EXIT(env, that, XButtonEvent_1sizeof_FUNC);
-	return rc;
-}
-#endif
-
 #ifndef NO_XClientMessageEvent_1sizeof
 JNIEXPORT jint JNICALL OS_NATIVE(XClientMessageEvent_1sizeof)
 	(JNIEnv *env, jclass that)
@@ -1191,6 +1335,30 @@ JNIEXPORT jintLong JNICALL OS_NATIVE(_1GDK_1TYPE_1PIXBUF)
 }
 #endif
 
+#ifndef NO__1GString_1len
+JNIEXPORT jint JNICALL OS_NATIVE(_1GString_1len)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jint rc = 0;
+	OS_NATIVE_ENTER(env, that, _1GString_1len_FUNC);
+	rc = (jint)((GString *)arg0)->len;
+	OS_NATIVE_EXIT(env, that, _1GString_1len_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1GString_1str
+JNIEXPORT jintLong JNICALL OS_NATIVE(_1GString_1str)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	OS_NATIVE_ENTER(env, that, _1GString_1str_FUNC);
+	rc = (jintLong)((GString *)arg0)->str;
+	OS_NATIVE_EXIT(env, that, _1GString_1str_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO__1GTK_1IS_1BUTTON
 JNIEXPORT jboolean JNICALL OS_NATIVE(_1GTK_1IS_1BUTTON)
 	(JNIEnv *env, jclass that, jintLong arg0)
@@ -1287,6 +1455,18 @@ JNIEXPORT jboolean JNICALL OS_NATIVE(_1GTK_1IS_1PLUG)
 }
 #endif
 
+#ifndef NO__1GTK_1IS_1SCROLLED_1WINDOW
+JNIEXPORT jboolean JNICALL OS_NATIVE(_1GTK_1IS_1SCROLLED_1WINDOW)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jboolean rc = 0;
+	OS_NATIVE_ENTER(env, that, _1GTK_1IS_1SCROLLED_1WINDOW_FUNC);
+	rc = (jboolean)GTK_IS_SCROLLED_WINDOW(arg0);
+	OS_NATIVE_EXIT(env, that, _1GTK_1IS_1SCROLLED_1WINDOW_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO__1GTK_1IS_1SOCKET
 JNIEXPORT jboolean JNICALL OS_NATIVE(_1GTK_1IS_1SOCKET)
 	(JNIEnv *env, jclass that, jintLong arg0)
@@ -1571,30 +1751,6 @@ JNIEXPORT jintLong JNICALL OS_NATIVE(_1G_1OBJECT_1TYPE_1NAME)
 }
 #endif
 
-#ifndef NO__1G_1TYPE_1BOOLEAN
-JNIEXPORT jintLong JNICALL OS_NATIVE(_1G_1TYPE_1BOOLEAN)
-	(JNIEnv *env, jclass that)
-{
-	jintLong rc = 0;
-	OS_NATIVE_ENTER(env, that, _1G_1TYPE_1BOOLEAN_FUNC);
-	rc = (jintLong)G_TYPE_BOOLEAN;
-	OS_NATIVE_EXIT(env, that, _1G_1TYPE_1BOOLEAN_FUNC);
-	return rc;
-}
-#endif
-
-#ifndef NO__1G_1TYPE_1INT
-JNIEXPORT jintLong JNICALL OS_NATIVE(_1G_1TYPE_1INT)
-	(JNIEnv *env, jclass that)
-{
-	jintLong rc = 0;
-	OS_NATIVE_ENTER(env, that, _1G_1TYPE_1INT_FUNC);
-	rc = (jintLong)G_TYPE_INT;
-	OS_NATIVE_EXIT(env, that, _1G_1TYPE_1INT_FUNC);
-	return rc;
-}
-#endif
-
 #ifndef NO__1G_1TYPE_1STRING
 JNIEXPORT jintLong JNICALL OS_NATIVE(_1G_1TYPE_1STRING)
 	(JNIEnv *env, jclass that)
@@ -1735,6 +1891,34 @@ JNIEXPORT jintLong JNICALL OS_NATIVE(_1XGetSelectionOwner)
 }
 #endif
 
+#ifndef NO__1XGetWindowProperty
+JNIEXPORT jintLong JNICALL OS_NATIVE(_1XGetWindowProperty)
+	(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1, jintLong arg2, jint arg3, jint arg4, jboolean arg5, jintLong arg6, jintLongArray arg7, jintArray arg8, jintArray arg9, jintArray arg10, jintLongArray arg11)
+{
+	jintLong *lparg7=NULL;
+	jint *lparg8=NULL;
+	jint *lparg9=NULL;
+	jint *lparg10=NULL;
+	jintLong *lparg11=NULL;
+	jintLong rc = 0;
+	OS_NATIVE_ENTER(env, that, _1XGetWindowProperty_FUNC);
+	if (arg7) if ((lparg7 = (*env)->GetIntLongArrayElements(env, arg7, NULL)) == NULL) goto fail;
+	if (arg8) if ((lparg8 = (*env)->GetIntArrayElements(env, arg8, NULL)) == NULL) goto fail;
+	if (arg9) if ((lparg9 = (*env)->GetIntArrayElements(env, arg9, NULL)) == NULL) goto fail;
+	if (arg10) if ((lparg10 = (*env)->GetIntArrayElements(env, arg10, NULL)) == NULL) goto fail;
+	if (arg11) if ((lparg11 = (*env)->GetIntLongArrayElements(env, arg11, NULL)) == NULL) goto fail;
+	rc = (jintLong)XGetWindowProperty((Display *)arg0, (Window)arg1, (Atom)arg2, arg3, arg4, arg5, (Atom)arg6, (Atom*)lparg7, (int *)lparg8, (unsigned long *)lparg9, (unsigned long *)lparg10, (unsigned char **)lparg11);
+fail:
+	if (arg11 && lparg11) (*env)->ReleaseIntLongArrayElements(env, arg11, lparg11, 0);
+	if (arg10 && lparg10) (*env)->ReleaseIntArrayElements(env, arg10, lparg10, 0);
+	if (arg9 && lparg9) (*env)->ReleaseIntArrayElements(env, arg9, lparg9, 0);
+	if (arg8 && lparg8) (*env)->ReleaseIntArrayElements(env, arg8, lparg8, 0);
+	if (arg7 && lparg7) (*env)->ReleaseIntLongArrayElements(env, arg7, lparg7, 0);
+	OS_NATIVE_EXIT(env, that, _1XGetWindowProperty_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO__1XInternAtom
 JNIEXPORT jintLong JNICALL OS_NATIVE(_1XInternAtom)
 	(JNIEnv *env, jclass that, jintLong arg0, jbyteArray arg1, jboolean arg2)
@@ -2098,6 +2282,18 @@ JNIEXPORT jint JNICALL OS_NATIVE(_1XSetInputFocus)
 }
 #endif
 
+#ifndef NO__1XSetSelectionOwner
+JNIEXPORT jintLong JNICALL OS_NATIVE(_1XSetSelectionOwner)
+	(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1, jintLong arg2, jint arg3)
+{
+	jintLong rc = 0;
+	OS_NATIVE_ENTER(env, that, _1XSetSelectionOwner_FUNC);
+	rc = (jintLong)XSetSelectionOwner((Display *)arg0, (Atom)arg1, arg2, (Time)arg3);
+	OS_NATIVE_EXIT(env, that, _1XSetSelectionOwner_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO__1XSetTransientForHint
 JNIEXPORT jint JNICALL OS_NATIVE(_1XSetTransientForHint)
 	(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1, jintLong arg2)
@@ -2164,6 +2360,22 @@ JNIEXPORT jint JNICALL OS_NATIVE(_1XWarpPointer)
 }
 #endif
 
+#ifndef NO__1access
+JNIEXPORT jint JNICALL OS_NATIVE(_1access)
+	(JNIEnv *env, jclass that, jbyteArray arg0, jint arg1)
+{
+	jbyte *lparg0=NULL;
+	jint rc = 0;
+	OS_NATIVE_ENTER(env, that, _1access_FUNC);
+	if (arg0) if ((lparg0 = (*env)->GetByteArrayElements(env, arg0, NULL)) == NULL) goto fail;
+	rc = (jint)access((const char*)lparg0, arg1);
+fail:
+	if (arg0 && lparg0) (*env)->ReleaseByteArrayElements(env, arg0, lparg0, 0);
+	OS_NATIVE_EXIT(env, that, _1access_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO__1atk_1object_1add_1relationship
 JNIEXPORT jboolean JNICALL OS_NATIVE(_1atk_1object_1add_1relationship)
 	(JNIEnv *env, jclass that, jintLong arg0, jint arg1, jintLong arg2)
@@ -2184,6 +2396,26 @@ JNIEXPORT jboolean JNICALL OS_NATIVE(_1atk_1object_1add_1relationship)
 }
 #endif
 
+#ifndef NO__1atk_1object_1remove_1relationship
+JNIEXPORT jboolean JNICALL OS_NATIVE(_1atk_1object_1remove_1relationship)
+	(JNIEnv *env, jclass that, jintLong arg0, jint arg1, jintLong arg2)
+{
+	jboolean rc = 0;
+	OS_NATIVE_ENTER(env, that, _1atk_1object_1remove_1relationship_FUNC);
+/*
+	rc = (jboolean)atk_object_remove_relationship((AtkObject *)arg0, (AtkRelationType)arg1, (AtkObject *)arg2);
+*/
+	{
+		LOAD_FUNCTION(fp, atk_object_remove_relationship)
+		if (fp) {
+			rc = (jboolean)((jboolean (CALLING_CONVENTION*)(AtkObject *, AtkRelationType, AtkObject *))fp)((AtkObject *)arg0, (AtkRelationType)arg1, (AtkObject *)arg2);
+		}
+	}
+	OS_NATIVE_EXIT(env, that, _1atk_1object_1remove_1relationship_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO__1call
 JNIEXPORT jintLong JNICALL OS_NATIVE(_1call)
 	(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1, jintLong arg2, jintLong arg3, jintLong arg4, jintLong arg5, jintLong arg6, jintLong arg7)
@@ -2240,6 +2472,237 @@ fail:
 }
 #endif
 
+#ifndef NO__1g_1app_1info_1create_1from_1commandline
+JNIEXPORT jintLong JNICALL OS_NATIVE(_1g_1app_1info_1create_1from_1commandline)
+	(JNIEnv *env, jclass that, jbyteArray arg0, jbyteArray arg1, jintLong arg2, jintLong arg3)
+{
+	jbyte *lparg0=NULL;
+	jbyte *lparg1=NULL;
+	jintLong rc = 0;
+	OS_NATIVE_ENTER(env, that, _1g_1app_1info_1create_1from_1commandline_FUNC);
+	if (arg0) if ((lparg0 = (*env)->GetByteArrayElements(env, arg0, NULL)) == NULL) goto fail;
+	if (arg1) if ((lparg1 = (*env)->GetByteArrayElements(env, arg1, NULL)) == NULL) goto fail;
+/*
+	rc = (jintLong)g_app_info_create_from_commandline(lparg0, lparg1, arg2, arg3);
+*/
+	{
+		LOAD_FUNCTION(fp, g_app_info_create_from_commandline)
+		if (fp) {
+			rc = (jintLong)((jintLong (CALLING_CONVENTION*)(jbyte *, jbyte *, jintLong, jintLong))fp)(lparg0, lparg1, arg2, arg3);
+		}
+	}
+fail:
+	if (arg1 && lparg1) (*env)->ReleaseByteArrayElements(env, arg1, lparg1, 0);
+	if (arg0 && lparg0) (*env)->ReleaseByteArrayElements(env, arg0, lparg0, 0);
+	OS_NATIVE_EXIT(env, that, _1g_1app_1info_1create_1from_1commandline_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1g_1app_1info_1get_1all
+JNIEXPORT jintLong JNICALL OS_NATIVE(_1g_1app_1info_1get_1all)
+	(JNIEnv *env, jclass that)
+{
+	jintLong rc = 0;
+	OS_NATIVE_ENTER(env, that, _1g_1app_1info_1get_1all_FUNC);
+/*
+	rc = (jintLong)g_app_info_get_all();
+*/
+	{
+		LOAD_FUNCTION(fp, g_app_info_get_all)
+		if (fp) {
+			rc = (jintLong)((jintLong (CALLING_CONVENTION*)())fp)();
+		}
+	}
+	OS_NATIVE_EXIT(env, that, _1g_1app_1info_1get_1all_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1g_1app_1info_1get_1default_1for_1type
+JNIEXPORT jintLong JNICALL OS_NATIVE(_1g_1app_1info_1get_1default_1for_1type)
+	(JNIEnv *env, jclass that, jbyteArray arg0, jboolean arg1)
+{
+	jbyte *lparg0=NULL;
+	jintLong rc = 0;
+	OS_NATIVE_ENTER(env, that, _1g_1app_1info_1get_1default_1for_1type_FUNC);
+	if (arg0) if ((lparg0 = (*env)->GetByteArrayElements(env, arg0, NULL)) == NULL) goto fail;
+/*
+	rc = (jintLong)g_app_info_get_default_for_type(lparg0, arg1);
+*/
+	{
+		LOAD_FUNCTION(fp, g_app_info_get_default_for_type)
+		if (fp) {
+			rc = (jintLong)((jintLong (CALLING_CONVENTION*)(jbyte *, jboolean))fp)(lparg0, arg1);
+		}
+	}
+fail:
+	if (arg0 && lparg0) (*env)->ReleaseByteArrayElements(env, arg0, lparg0, 0);
+	OS_NATIVE_EXIT(env, that, _1g_1app_1info_1get_1default_1for_1type_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1g_1app_1info_1get_1executable
+JNIEXPORT jintLong JNICALL OS_NATIVE(_1g_1app_1info_1get_1executable)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	OS_NATIVE_ENTER(env, that, _1g_1app_1info_1get_1executable_FUNC);
+/*
+	rc = (jintLong)g_app_info_get_executable(arg0);
+*/
+	{
+		LOAD_FUNCTION(fp, g_app_info_get_executable)
+		if (fp) {
+			rc = (jintLong)((jintLong (CALLING_CONVENTION*)(jintLong))fp)(arg0);
+		}
+	}
+	OS_NATIVE_EXIT(env, that, _1g_1app_1info_1get_1executable_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1g_1app_1info_1get_1icon
+JNIEXPORT jintLong JNICALL OS_NATIVE(_1g_1app_1info_1get_1icon)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	OS_NATIVE_ENTER(env, that, _1g_1app_1info_1get_1icon_FUNC);
+/*
+	rc = (jintLong)g_app_info_get_icon(arg0);
+*/
+	{
+		LOAD_FUNCTION(fp, g_app_info_get_icon)
+		if (fp) {
+			rc = (jintLong)((jintLong (CALLING_CONVENTION*)(jintLong))fp)(arg0);
+		}
+	}
+	OS_NATIVE_EXIT(env, that, _1g_1app_1info_1get_1icon_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1g_1app_1info_1get_1id
+JNIEXPORT jintLong JNICALL OS_NATIVE(_1g_1app_1info_1get_1id)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	OS_NATIVE_ENTER(env, that, _1g_1app_1info_1get_1id_FUNC);
+/*
+	rc = (jintLong)g_app_info_get_id(arg0);
+*/
+	{
+		LOAD_FUNCTION(fp, g_app_info_get_id)
+		if (fp) {
+			rc = (jintLong)((jintLong (CALLING_CONVENTION*)(jintLong))fp)(arg0);
+		}
+	}
+	OS_NATIVE_EXIT(env, that, _1g_1app_1info_1get_1id_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1g_1app_1info_1get_1name
+JNIEXPORT jintLong JNICALL OS_NATIVE(_1g_1app_1info_1get_1name)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	OS_NATIVE_ENTER(env, that, _1g_1app_1info_1get_1name_FUNC);
+/*
+	rc = (jintLong)g_app_info_get_name(arg0);
+*/
+	{
+		LOAD_FUNCTION(fp, g_app_info_get_name)
+		if (fp) {
+			rc = (jintLong)((jintLong (CALLING_CONVENTION*)(jintLong))fp)(arg0);
+		}
+	}
+	OS_NATIVE_EXIT(env, that, _1g_1app_1info_1get_1name_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1g_1app_1info_1launch
+JNIEXPORT jboolean JNICALL OS_NATIVE(_1g_1app_1info_1launch)
+	(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1, jintLong arg2, jintLong arg3)
+{
+	jboolean rc = 0;
+	OS_NATIVE_ENTER(env, that, _1g_1app_1info_1launch_FUNC);
+/*
+	rc = (jboolean)g_app_info_launch(arg0, arg1, arg2, arg3);
+*/
+	{
+		LOAD_FUNCTION(fp, g_app_info_launch)
+		if (fp) {
+			rc = (jboolean)((jboolean (CALLING_CONVENTION*)(jintLong, jintLong, jintLong, jintLong))fp)(arg0, arg1, arg2, arg3);
+		}
+	}
+	OS_NATIVE_EXIT(env, that, _1g_1app_1info_1launch_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1g_1app_1info_1launch_1default_1for_1uri
+JNIEXPORT jboolean JNICALL OS_NATIVE(_1g_1app_1info_1launch_1default_1for_1uri)
+	(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1, jintLong arg2)
+{
+	jboolean rc = 0;
+	OS_NATIVE_ENTER(env, that, _1g_1app_1info_1launch_1default_1for_1uri_FUNC);
+/*
+	rc = (jboolean)g_app_info_launch_default_for_uri(arg0, arg1, arg2);
+*/
+	{
+		LOAD_FUNCTION(fp, g_app_info_launch_default_for_uri)
+		if (fp) {
+			rc = (jboolean)((jboolean (CALLING_CONVENTION*)(jintLong, jintLong, jintLong))fp)(arg0, arg1, arg2);
+		}
+	}
+	OS_NATIVE_EXIT(env, that, _1g_1app_1info_1launch_1default_1for_1uri_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1g_1app_1info_1should_1show
+JNIEXPORT jboolean JNICALL OS_NATIVE(_1g_1app_1info_1should_1show)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jboolean rc = 0;
+	OS_NATIVE_ENTER(env, that, _1g_1app_1info_1should_1show_FUNC);
+/*
+	rc = (jboolean)g_app_info_should_show(arg0);
+*/
+	{
+		LOAD_FUNCTION(fp, g_app_info_should_show)
+		if (fp) {
+			rc = (jboolean)((jboolean (CALLING_CONVENTION*)(jintLong))fp)(arg0);
+		}
+	}
+	OS_NATIVE_EXIT(env, that, _1g_1app_1info_1should_1show_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1g_1app_1info_1supports_1uris
+JNIEXPORT jboolean JNICALL OS_NATIVE(_1g_1app_1info_1supports_1uris)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jboolean rc = 0;
+	OS_NATIVE_ENTER(env, that, _1g_1app_1info_1supports_1uris_FUNC);
+/*
+	rc = (jboolean)g_app_info_supports_uris(arg0);
+*/
+	{
+		LOAD_FUNCTION(fp, g_app_info_supports_uris)
+		if (fp) {
+			rc = (jboolean)((jboolean (CALLING_CONVENTION*)(jintLong))fp)(arg0);
+		}
+	}
+	OS_NATIVE_EXIT(env, that, _1g_1app_1info_1supports_1uris_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO__1g_1cclosure_1new
 JNIEXPORT jintLong JNICALL OS_NATIVE(_1g_1cclosure_1new)
 	(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1, jintLong arg2)
@@ -2274,6 +2737,384 @@ JNIEXPORT void JNICALL OS_NATIVE(_1g_1closure_1unref)
 }
 #endif
 
+#ifndef NO__1g_1content_1type_1equals
+JNIEXPORT jboolean JNICALL OS_NATIVE(_1g_1content_1type_1equals)
+	(JNIEnv *env, jclass that, jintLong arg0, jbyteArray arg1)
+{
+	jbyte *lparg1=NULL;
+	jboolean rc = 0;
+	OS_NATIVE_ENTER(env, that, _1g_1content_1type_1equals_FUNC);
+	if (arg1) if ((lparg1 = (*env)->GetByteArrayElements(env, arg1, NULL)) == NULL) goto fail;
+/*
+	rc = (jboolean)g_content_type_equals(arg0, lparg1);
+*/
+	{
+		LOAD_FUNCTION(fp, g_content_type_equals)
+		if (fp) {
+			rc = (jboolean)((jboolean (CALLING_CONVENTION*)(jintLong, jbyte *))fp)(arg0, lparg1);
+		}
+	}
+fail:
+	if (arg1 && lparg1) (*env)->ReleaseByteArrayElements(env, arg1, lparg1, 0);
+	OS_NATIVE_EXIT(env, that, _1g_1content_1type_1equals_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1g_1content_1type_1get_1mime_1type
+JNIEXPORT jintLong JNICALL OS_NATIVE(_1g_1content_1type_1get_1mime_1type)
+	(JNIEnv *env, jclass that, jbyteArray arg0)
+{
+	jbyte *lparg0=NULL;
+	jintLong rc = 0;
+	OS_NATIVE_ENTER(env, that, _1g_1content_1type_1get_1mime_1type_FUNC);
+	if (arg0) if ((lparg0 = (*env)->GetByteArrayElements(env, arg0, NULL)) == NULL) goto fail;
+/*
+	rc = (jintLong)g_content_type_get_mime_type(lparg0);
+*/
+	{
+		LOAD_FUNCTION(fp, g_content_type_get_mime_type)
+		if (fp) {
+			rc = (jintLong)((jintLong (CALLING_CONVENTION*)(jbyte *))fp)(lparg0);
+		}
+	}
+fail:
+	if (arg0 && lparg0) (*env)->ReleaseByteArrayElements(env, arg0, lparg0, 0);
+	OS_NATIVE_EXIT(env, that, _1g_1content_1type_1get_1mime_1type_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1g_1content_1type_1is_1a
+JNIEXPORT jboolean JNICALL OS_NATIVE(_1g_1content_1type_1is_1a)
+	(JNIEnv *env, jclass that, jintLong arg0, jbyteArray arg1)
+{
+	jbyte *lparg1=NULL;
+	jboolean rc = 0;
+	OS_NATIVE_ENTER(env, that, _1g_1content_1type_1is_1a_FUNC);
+	if (arg1) if ((lparg1 = (*env)->GetByteArrayElements(env, arg1, NULL)) == NULL) goto fail;
+/*
+	rc = (jboolean)g_content_type_is_a(arg0, lparg1);
+*/
+	{
+		LOAD_FUNCTION(fp, g_content_type_is_a)
+		if (fp) {
+			rc = (jboolean)((jboolean (CALLING_CONVENTION*)(jintLong, jbyte *))fp)(arg0, lparg1);
+		}
+	}
+fail:
+	if (arg1 && lparg1) (*env)->ReleaseByteArrayElements(env, arg1, lparg1, 0);
+	OS_NATIVE_EXIT(env, that, _1g_1content_1type_1is_1a_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1g_1content_1types_1get_1registered
+JNIEXPORT jintLong JNICALL OS_NATIVE(_1g_1content_1types_1get_1registered)
+	(JNIEnv *env, jclass that)
+{
+	jintLong rc = 0;
+	OS_NATIVE_ENTER(env, that, _1g_1content_1types_1get_1registered_FUNC);
+/*
+	rc = (jintLong)g_content_types_get_registered();
+*/
+	{
+		LOAD_FUNCTION(fp, g_content_types_get_registered)
+		if (fp) {
+			rc = (jintLong)((jintLong (CALLING_CONVENTION*)())fp)();
+		}
+	}
+	OS_NATIVE_EXIT(env, that, _1g_1content_1types_1get_1registered_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1g_1data_1input_1stream_1new
+JNIEXPORT jintLong JNICALL OS_NATIVE(_1g_1data_1input_1stream_1new)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	OS_NATIVE_ENTER(env, that, _1g_1data_1input_1stream_1new_FUNC);
+/*
+	rc = (jintLong)g_data_input_stream_new(arg0);
+*/
+	{
+		LOAD_FUNCTION(fp, g_data_input_stream_new)
+		if (fp) {
+			rc = (jintLong)((jintLong (CALLING_CONVENTION*)(jintLong))fp)(arg0);
+		}
+	}
+	OS_NATIVE_EXIT(env, that, _1g_1data_1input_1stream_1new_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1g_1data_1input_1stream_1read_1line
+JNIEXPORT jintLong JNICALL OS_NATIVE(_1g_1data_1input_1stream_1read_1line)
+	(JNIEnv *env, jclass that, jintLong arg0, jintArray arg1, jintLong arg2, jintLong arg3)
+{
+	jint *lparg1=NULL;
+	jintLong rc = 0;
+	OS_NATIVE_ENTER(env, that, _1g_1data_1input_1stream_1read_1line_FUNC);
+	if (arg1) if ((lparg1 = (*env)->GetIntArrayElements(env, arg1, NULL)) == NULL) goto fail;
+/*
+	rc = (jintLong)g_data_input_stream_read_line(arg0, lparg1, arg2, arg3);
+*/
+	{
+		LOAD_FUNCTION(fp, g_data_input_stream_read_line)
+		if (fp) {
+			rc = (jintLong)((jintLong (CALLING_CONVENTION*)(jintLong, jint *, jintLong, jintLong))fp)(arg0, lparg1, arg2, arg3);
+		}
+	}
+fail:
+	if (arg1 && lparg1) (*env)->ReleaseIntArrayElements(env, arg1, lparg1, 0);
+	OS_NATIVE_EXIT(env, that, _1g_1data_1input_1stream_1read_1line_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1g_1desktop_1app_1info_1new_1from_1filename
+JNIEXPORT jintLong JNICALL OS_NATIVE(_1g_1desktop_1app_1info_1new_1from_1filename)
+	(JNIEnv *env, jclass that, jbyteArray arg0)
+{
+	jbyte *lparg0=NULL;
+	jintLong rc = 0;
+	OS_NATIVE_ENTER(env, that, _1g_1desktop_1app_1info_1new_1from_1filename_FUNC);
+	if (arg0) if ((lparg0 = (*env)->GetByteArrayElements(env, arg0, NULL)) == NULL) goto fail;
+/*
+	rc = (jintLong)g_desktop_app_info_new_from_filename(lparg0);
+*/
+	{
+		LOAD_FUNCTION(fp, g_desktop_app_info_new_from_filename)
+		if (fp) {
+			rc = (jintLong)((jintLong (CALLING_CONVENTION*)(jbyte *))fp)(lparg0);
+		}
+	}
+fail:
+	if (arg0 && lparg0) (*env)->ReleaseByteArrayElements(env, arg0, lparg0, 0);
+	OS_NATIVE_EXIT(env, that, _1g_1desktop_1app_1info_1new_1from_1filename_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1g_1file_1get_1path
+JNIEXPORT jintLong JNICALL OS_NATIVE(_1g_1file_1get_1path)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	OS_NATIVE_ENTER(env, that, _1g_1file_1get_1path_FUNC);
+/*
+	rc = (jintLong)g_file_get_path(arg0);
+*/
+	{
+		LOAD_FUNCTION(fp, g_file_get_path)
+		if (fp) {
+			rc = (jintLong)((jintLong (CALLING_CONVENTION*)(jintLong))fp)(arg0);
+		}
+	}
+	OS_NATIVE_EXIT(env, that, _1g_1file_1get_1path_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1g_1file_1get_1uri
+JNIEXPORT jintLong JNICALL OS_NATIVE(_1g_1file_1get_1uri)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	OS_NATIVE_ENTER(env, that, _1g_1file_1get_1uri_FUNC);
+/*
+	rc = (jintLong)g_file_get_uri(arg0);
+*/
+	{
+		LOAD_FUNCTION(fp, g_file_get_uri)
+		if (fp) {
+			rc = (jintLong)((jintLong (CALLING_CONVENTION*)(jintLong))fp)(arg0);
+		}
+	}
+	OS_NATIVE_EXIT(env, that, _1g_1file_1get_1uri_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1g_1file_1icon_1get_1file
+JNIEXPORT jintLong JNICALL OS_NATIVE(_1g_1file_1icon_1get_1file)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	OS_NATIVE_ENTER(env, that, _1g_1file_1icon_1get_1file_FUNC);
+/*
+	rc = (jintLong)g_file_icon_get_file(arg0);
+*/
+	{
+		LOAD_FUNCTION(fp, g_file_icon_get_file)
+		if (fp) {
+			rc = (jintLong)((jintLong (CALLING_CONVENTION*)(jintLong))fp)(arg0);
+		}
+	}
+	OS_NATIVE_EXIT(env, that, _1g_1file_1icon_1get_1file_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1g_1file_1info_1get_1content_1type
+JNIEXPORT jintLong JNICALL OS_NATIVE(_1g_1file_1info_1get_1content_1type)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	OS_NATIVE_ENTER(env, that, _1g_1file_1info_1get_1content_1type_FUNC);
+/*
+	rc = (jintLong)g_file_info_get_content_type(arg0);
+*/
+	{
+		LOAD_FUNCTION(fp, g_file_info_get_content_type)
+		if (fp) {
+			rc = (jintLong)((jintLong (CALLING_CONVENTION*)(jintLong))fp)(arg0);
+		}
+	}
+	OS_NATIVE_EXIT(env, that, _1g_1file_1info_1get_1content_1type_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1g_1file_1info_1get_1modification_1time
+JNIEXPORT void JNICALL OS_NATIVE(_1g_1file_1info_1get_1modification_1time)
+	(JNIEnv *env, jclass that, jintLong arg0, jintLongArray arg1)
+{
+	jintLong *lparg1=NULL;
+	OS_NATIVE_ENTER(env, that, _1g_1file_1info_1get_1modification_1time_FUNC);
+	if (arg1) if ((lparg1 = (*env)->GetIntLongArrayElements(env, arg1, NULL)) == NULL) goto fail;
+/*
+	g_file_info_get_modification_time(arg0, lparg1);
+*/
+	{
+		LOAD_FUNCTION(fp, g_file_info_get_modification_time)
+		if (fp) {
+			((void (CALLING_CONVENTION*)(jintLong, jintLong *))fp)(arg0, lparg1);
+		}
+	}
+fail:
+	if (arg1 && lparg1) (*env)->ReleaseIntLongArrayElements(env, arg1, lparg1, 0);
+	OS_NATIVE_EXIT(env, that, _1g_1file_1info_1get_1modification_1time_FUNC);
+}
+#endif
+
+#ifndef NO__1g_1file_1new_1for_1path
+JNIEXPORT jintLong JNICALL OS_NATIVE(_1g_1file_1new_1for_1path)
+	(JNIEnv *env, jclass that, jbyteArray arg0)
+{
+	jbyte *lparg0=NULL;
+	jintLong rc = 0;
+	OS_NATIVE_ENTER(env, that, _1g_1file_1new_1for_1path_FUNC);
+	if (arg0) if ((lparg0 = (*env)->GetByteArrayElements(env, arg0, NULL)) == NULL) goto fail;
+/*
+	rc = (jintLong)g_file_new_for_path(lparg0);
+*/
+	{
+		LOAD_FUNCTION(fp, g_file_new_for_path)
+		if (fp) {
+			rc = (jintLong)((jintLong (CALLING_CONVENTION*)(jbyte *))fp)(lparg0);
+		}
+	}
+fail:
+	if (arg0 && lparg0) (*env)->ReleaseByteArrayElements(env, arg0, lparg0, 0);
+	OS_NATIVE_EXIT(env, that, _1g_1file_1new_1for_1path_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1g_1file_1new_1for_1uri
+JNIEXPORT jintLong JNICALL OS_NATIVE(_1g_1file_1new_1for_1uri)
+	(JNIEnv *env, jclass that, jbyteArray arg0)
+{
+	jbyte *lparg0=NULL;
+	jintLong rc = 0;
+	OS_NATIVE_ENTER(env, that, _1g_1file_1new_1for_1uri_FUNC);
+	if (arg0) if ((lparg0 = (*env)->GetByteArrayElements(env, arg0, NULL)) == NULL) goto fail;
+/*
+	rc = (jintLong)g_file_new_for_uri(lparg0);
+*/
+	{
+		LOAD_FUNCTION(fp, g_file_new_for_uri)
+		if (fp) {
+			rc = (jintLong)((jintLong (CALLING_CONVENTION*)(jbyte *))fp)(lparg0);
+		}
+	}
+fail:
+	if (arg0 && lparg0) (*env)->ReleaseByteArrayElements(env, arg0, lparg0, 0);
+	OS_NATIVE_EXIT(env, that, _1g_1file_1new_1for_1uri_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1g_1file_1query_1info
+JNIEXPORT jintLong JNICALL OS_NATIVE(_1g_1file_1query_1info)
+	(JNIEnv *env, jclass that, jintLong arg0, jbyteArray arg1, jintLong arg2, jintLong arg3, jintLong arg4)
+{
+	jbyte *lparg1=NULL;
+	jintLong rc = 0;
+	OS_NATIVE_ENTER(env, that, _1g_1file_1query_1info_FUNC);
+	if (arg1) if ((lparg1 = (*env)->GetByteArrayElements(env, arg1, NULL)) == NULL) goto fail;
+/*
+	rc = (jintLong)g_file_query_info(arg0, lparg1, arg2, arg3, arg4);
+*/
+	{
+		LOAD_FUNCTION(fp, g_file_query_info)
+		if (fp) {
+			rc = (jintLong)((jintLong (CALLING_CONVENTION*)(jintLong, jbyte *, jintLong, jintLong, jintLong))fp)(arg0, lparg1, arg2, arg3, arg4);
+		}
+	}
+fail:
+	if (arg1 && lparg1) (*env)->ReleaseByteArrayElements(env, arg1, lparg1, 0);
+	OS_NATIVE_EXIT(env, that, _1g_1file_1query_1info_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1g_1file_1read
+JNIEXPORT jintLong JNICALL OS_NATIVE(_1g_1file_1read)
+	(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1, jintLong arg2)
+{
+	jintLong rc = 0;
+	OS_NATIVE_ENTER(env, that, _1g_1file_1read_FUNC);
+/*
+	rc = (jintLong)g_file_read(arg0, arg1, arg2);
+*/
+	{
+		LOAD_FUNCTION(fp, g_file_read)
+		if (fp) {
+			rc = (jintLong)((jintLong (CALLING_CONVENTION*)(jintLong, jintLong, jintLong))fp)(arg0, arg1, arg2);
+		}
+	}
+	OS_NATIVE_EXIT(env, that, _1g_1file_1read_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1g_1file_1test
+JNIEXPORT jboolean JNICALL OS_NATIVE(_1g_1file_1test)
+	(JNIEnv *env, jclass that, jbyteArray arg0, jint arg1)
+{
+	jbyte *lparg0=NULL;
+	jboolean rc = 0;
+	OS_NATIVE_ENTER(env, that, _1g_1file_1test_FUNC);
+	if (arg0) if ((lparg0 = (*env)->GetByteArrayElements(env, arg0, NULL)) == NULL) goto fail;
+/*
+	rc = (jboolean)g_file_test(lparg0, arg1);
+*/
+	{
+		LOAD_FUNCTION(fp, g_file_test)
+		if (fp) {
+			rc = (jboolean)((jboolean (CALLING_CONVENTION*)(jbyte *, jint))fp)(lparg0, arg1);
+		}
+	}
+fail:
+	if (arg0 && lparg0) (*env)->ReleaseByteArrayElements(env, arg0, lparg0, 0);
+	OS_NATIVE_EXIT(env, that, _1g_1file_1test_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO__1g_1filename_1from_1uri
 JNIEXPORT jintLong JNICALL OS_NATIVE(_1g_1filename_1from_1uri)
 	(JNIEnv *env, jclass that, jintLong arg0, jintLongArray arg1, jintLongArray arg2)
@@ -2363,6 +3204,53 @@ JNIEXPORT void JNICALL OS_NATIVE(_1g_1free)
 }
 #endif
 
+#ifndef NO__1g_1icon_1new_1for_1string
+JNIEXPORT jintLong JNICALL OS_NATIVE(_1g_1icon_1new_1for_1string)
+	(JNIEnv *env, jclass that, jbyteArray arg0, jintLongArray arg1)
+{
+	jbyte *lparg0=NULL;
+	jintLong *lparg1=NULL;
+	jintLong rc = 0;
+	OS_NATIVE_ENTER(env, that, _1g_1icon_1new_1for_1string_FUNC);
+	if (arg0) if ((lparg0 = (*env)->GetByteArrayElements(env, arg0, NULL)) == NULL) goto fail;
+	if (arg1) if ((lparg1 = (*env)->GetIntLongArrayElements(env, arg1, NULL)) == NULL) goto fail;
+/*
+	rc = (jintLong)g_icon_new_for_string(lparg0, lparg1);
+*/
+	{
+		LOAD_FUNCTION(fp, g_icon_new_for_string)
+		if (fp) {
+			rc = (jintLong)((jintLong (CALLING_CONVENTION*)(jbyte *, jintLong *))fp)(lparg0, lparg1);
+		}
+	}
+fail:
+	if (arg1 && lparg1) (*env)->ReleaseIntLongArrayElements(env, arg1, lparg1, 0);
+	if (arg0 && lparg0) (*env)->ReleaseByteArrayElements(env, arg0, lparg0, 0);
+	OS_NATIVE_EXIT(env, that, _1g_1icon_1new_1for_1string_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1g_1icon_1to_1string
+JNIEXPORT jintLong JNICALL OS_NATIVE(_1g_1icon_1to_1string)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	OS_NATIVE_ENTER(env, that, _1g_1icon_1to_1string_FUNC);
+/*
+	rc = (jintLong)g_icon_to_string(arg0);
+*/
+	{
+		LOAD_FUNCTION(fp, g_icon_to_string)
+		if (fp) {
+			rc = (jintLong)((jintLong (CALLING_CONVENTION*)(jintLong))fp)(arg0);
+		}
+	}
+	OS_NATIVE_EXIT(env, that, _1g_1icon_1to_1string_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO__1g_1idle_1add
 JNIEXPORT jint JNICALL OS_NATIVE(_1g_1idle_1add)
 	(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1)
@@ -2940,6 +3828,34 @@ fail:
 }
 #endif
 
+#if (!defined(NO__1g_1object_1set__I_3B_3BI) && !defined(JNI64)) || (!defined(NO__1g_1object_1set__J_3B_3BJ) && defined(JNI64))
+#ifndef JNI64
+JNIEXPORT void JNICALL OS_NATIVE(_1g_1object_1set__I_3B_3BI)(JNIEnv *env, jclass that, jintLong arg0, jbyteArray arg1, jbyteArray arg2, jintLong arg3)
+#else
+JNIEXPORT void JNICALL OS_NATIVE(_1g_1object_1set__J_3B_3BJ)(JNIEnv *env, jclass that, jintLong arg0, jbyteArray arg1, jbyteArray arg2, jintLong arg3)
+#endif
+{
+	jbyte *lparg1=NULL;
+	jbyte *lparg2=NULL;
+#ifndef JNI64
+	OS_NATIVE_ENTER(env, that, _1g_1object_1set__I_3B_3BI_FUNC);
+#else
+	OS_NATIVE_ENTER(env, that, _1g_1object_1set__J_3B_3BJ_FUNC);
+#endif
+	if (arg1) if ((lparg1 = (*env)->GetByteArrayElements(env, arg1, NULL)) == NULL) goto fail;
+	if (arg2) if ((lparg2 = (*env)->GetByteArrayElements(env, arg2, NULL)) == NULL) goto fail;
+	g_object_set((gpointer)arg0, (const gchar *)lparg1, lparg2, (const gchar *)NULL);
+fail:
+	if (arg2 && lparg2) (*env)->ReleaseByteArrayElements(env, arg2, lparg2, 0);
+	if (arg1 && lparg1) (*env)->ReleaseByteArrayElements(env, arg1, lparg1, JNI_ABORT);
+#ifndef JNI64
+	OS_NATIVE_EXIT(env, that, _1g_1object_1set__I_3B_3BI_FUNC);
+#else
+	OS_NATIVE_EXIT(env, that, _1g_1object_1set__J_3B_3BJ_FUNC);
+#endif
+}
+#endif
+
 #ifndef NO__1g_1object_1set_1qdata
 JNIEXPORT void JNICALL OS_NATIVE(_1g_1object_1set_1qdata)
 	(JNIEnv *env, jclass that, jintLong arg0, jint arg1, jintLong arg2)
@@ -3137,6 +4053,34 @@ fail:
 }
 #endif
 
+#if (!defined(NO__1g_1signal_1emit_1by_1name__I_3BLorg_eclipse_swt_internal_gtk_GdkRectangle_2) && !defined(JNI64)) || (!defined(NO__1g_1signal_1emit_1by_1name__J_3BLorg_eclipse_swt_internal_gtk_GdkRectangle_2) && defined(JNI64))
+#ifndef JNI64
+JNIEXPORT void JNICALL OS_NATIVE(_1g_1signal_1emit_1by_1name__I_3BLorg_eclipse_swt_internal_gtk_GdkRectangle_2)(JNIEnv *env, jclass that, jintLong arg0, jbyteArray arg1, jobject arg2)
+#else
+JNIEXPORT void JNICALL OS_NATIVE(_1g_1signal_1emit_1by_1name__J_3BLorg_eclipse_swt_internal_gtk_GdkRectangle_2)(JNIEnv *env, jclass that, jintLong arg0, jbyteArray arg1, jobject arg2)
+#endif
+{
+	jbyte *lparg1=NULL;
+	GdkRectangle _arg2, *lparg2=NULL;
+#ifndef JNI64
+	OS_NATIVE_ENTER(env, that, _1g_1signal_1emit_1by_1name__I_3BLorg_eclipse_swt_internal_gtk_GdkRectangle_2_FUNC);
+#else
+	OS_NATIVE_ENTER(env, that, _1g_1signal_1emit_1by_1name__J_3BLorg_eclipse_swt_internal_gtk_GdkRectangle_2_FUNC);
+#endif
+	if (arg1) if ((lparg1 = (*env)->GetByteArrayElements(env, arg1, NULL)) == NULL) goto fail;
+	if (arg2) if ((lparg2 = getGdkRectangleFields(env, arg2, &_arg2)) == NULL) goto fail;
+	g_signal_emit_by_name((gpointer)arg0, (const gchar *)lparg1, lparg2);
+fail:
+	if (arg2 && lparg2) setGdkRectangleFields(env, arg2, lparg2);
+	if (arg1 && lparg1) (*env)->ReleaseByteArrayElements(env, arg1, lparg1, JNI_ABORT);
+#ifndef JNI64
+	OS_NATIVE_EXIT(env, that, _1g_1signal_1emit_1by_1name__I_3BLorg_eclipse_swt_internal_gtk_GdkRectangle_2_FUNC);
+#else
+	OS_NATIVE_EXIT(env, that, _1g_1signal_1emit_1by_1name__J_3BLorg_eclipse_swt_internal_gtk_GdkRectangle_2_FUNC);
+#endif
+}
+#endif
+
 #if (!defined(NO__1g_1signal_1emit_1by_1name__I_3B_3B) && !defined(JNI64)) || (!defined(NO__1g_1signal_1emit_1by_1name__J_3B_3B) && defined(JNI64))
 #ifndef JNI64
 JNIEXPORT void JNICALL OS_NATIVE(_1g_1signal_1emit_1by_1name__I_3B_3B)(JNIEnv *env, jclass that, jintLong arg0, jbyteArray arg1, jbyteArray arg2)
@@ -3175,6 +4119,18 @@ JNIEXPORT void JNICALL OS_NATIVE(_1g_1signal_1handler_1disconnect)
 }
 #endif
 
+#ifndef NO__1g_1signal_1handler_1find
+JNIEXPORT jint JNICALL OS_NATIVE(_1g_1signal_1handler_1find)
+	(JNIEnv *env, jclass that, jintLong arg0, jint arg1, jint arg2, jint arg3, jintLong arg4, jintLong arg5, jintLong arg6)
+{
+	jint rc = 0;
+	OS_NATIVE_ENTER(env, that, _1g_1signal_1handler_1find_FUNC);
+	rc = (jint)g_signal_handler_find((gpointer)arg0, arg1, arg2, (GQuark)arg3, (GClosure *)arg4, (gpointer)arg5, (gpointer)arg6);
+	OS_NATIVE_EXIT(env, that, _1g_1signal_1handler_1find_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO__1g_1signal_1handlers_1block_1matched
 JNIEXPORT jint JNICALL OS_NATIVE(_1g_1signal_1handlers_1block_1matched)
 	(JNIEnv *env, jclass that, jintLong arg0, jint arg1, jint arg2, jint arg3, jintLong arg4, jintLong arg5, jintLong arg6)
@@ -4738,6 +5694,18 @@ JNIEXPORT jint JNICALL OS_NATIVE(_1gdk_1keyval_1to_1unicode)
 }
 #endif
 
+#ifndef NO__1gdk_1pango_1attr_1embossed_1new
+JNIEXPORT jintLong JNICALL OS_NATIVE(_1gdk_1pango_1attr_1embossed_1new)
+	(JNIEnv *env, jclass that, jboolean arg0)
+{
+	jintLong rc = 0;
+	OS_NATIVE_ENTER(env, that, _1gdk_1pango_1attr_1embossed_1new_FUNC);
+	rc = (jintLong)gdk_pango_attr_embossed_new(arg0);
+	OS_NATIVE_EXIT(env, that, _1gdk_1pango_1attr_1embossed_1new_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO__1gdk_1pango_1context_1get
 JNIEXPORT jintLong JNICALL OS_NATIVE(_1gdk_1pango_1context_1get)
 	(JNIEnv *env, jclass that)
@@ -5879,6 +6847,16 @@ JNIEXPORT void JNICALL OS_NATIVE(_1gdk_1window_1move)
 }
 #endif
 
+#ifndef NO__1gdk_1window_1move_1resize
+JNIEXPORT void JNICALL OS_NATIVE(_1gdk_1window_1move_1resize)
+	(JNIEnv *env, jclass that, jintLong arg0, jint arg1, jint arg2, jint arg3, jint arg4)
+{
+	OS_NATIVE_ENTER(env, that, _1gdk_1window_1move_1resize_FUNC);
+	gdk_window_move_resize((GdkWindow *)arg0, arg1, arg2, arg3, arg4);
+	OS_NATIVE_EXIT(env, that, _1gdk_1window_1move_1resize_FUNC);
+}
+#endif
+
 #ifndef NO__1gdk_1window_1new
 JNIEXPORT jintLong JNICALL OS_NATIVE(_1gdk_1window_1new)
 	(JNIEnv *env, jclass that, jintLong arg0, jobject arg1, jint arg2)
@@ -5944,6 +6922,24 @@ JNIEXPORT void JNICALL OS_NATIVE(_1gdk_1window_1resize)
 }
 #endif
 
+#ifndef NO__1gdk_1window_1restack
+JNIEXPORT void JNICALL OS_NATIVE(_1gdk_1window_1restack)
+	(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1, jboolean arg2)
+{
+	OS_NATIVE_ENTER(env, that, _1gdk_1window_1restack_FUNC);
+/*
+	gdk_window_restack((GdkWindow *)arg0, (GdkWindow *)arg1, (gboolean)arg2);
+*/
+	{
+		LOAD_FUNCTION(fp, gdk_window_restack)
+		if (fp) {
+			((void (CALLING_CONVENTION*)(GdkWindow *, GdkWindow *, gboolean))fp)((GdkWindow *)arg0, (GdkWindow *)arg1, (gboolean)arg2);
+		}
+	}
+	OS_NATIVE_EXIT(env, that, _1gdk_1window_1restack_FUNC);
+}
+#endif
+
 #ifndef NO__1gdk_1window_1scroll
 JNIEXPORT void JNICALL OS_NATIVE(_1gdk_1window_1scroll)
 	(JNIEnv *env, jclass that, jintLong arg0, jint arg1, jint arg2)
@@ -6720,6 +7716,18 @@ JNIEXPORT jboolean JNICALL OS_NATIVE(_1gtk_1clipboard_1set_1with_1data)
 }
 #endif
 
+#ifndef NO__1gtk_1clipboard_1set_1with_1owner
+JNIEXPORT jboolean JNICALL OS_NATIVE(_1gtk_1clipboard_1set_1with_1owner)
+	(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1, jint arg2, jintLong arg3, jintLong arg4, jintLong arg5)
+{
+	jboolean rc = 0;
+	OS_NATIVE_ENTER(env, that, _1gtk_1clipboard_1set_1with_1owner_FUNC);
+	rc = (jboolean)gtk_clipboard_set_with_owner((GtkClipboard *)arg0, (const GtkTargetEntry *)arg1, (guint)arg2, (GtkClipboardGetFunc)arg3, (GtkClipboardClearFunc)arg4, (GObject *)arg5);
+	OS_NATIVE_EXIT(env, that, _1gtk_1clipboard_1set_1with_1owner_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO__1gtk_1clipboard_1wait_1for_1contents
 JNIEXPORT jintLong JNICALL OS_NATIVE(_1gtk_1clipboard_1wait_1for_1contents)
 	(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1)
@@ -7518,6 +8526,46 @@ JNIEXPORT void JNICALL OS_NATIVE(_1gtk_1entry_1set_1has_1frame)
 }
 #endif
 
+#ifndef NO__1gtk_1entry_1set_1icon_1from_1stock
+JNIEXPORT void JNICALL OS_NATIVE(_1gtk_1entry_1set_1icon_1from_1stock)
+	(JNIEnv *env, jclass that, jintLong arg0, jint arg1, jbyteArray arg2)
+{
+	jbyte *lparg2=NULL;
+	OS_NATIVE_ENTER(env, that, _1gtk_1entry_1set_1icon_1from_1stock_FUNC);
+	if (arg2) if ((lparg2 = (*env)->GetByteArrayElements(env, arg2, NULL)) == NULL) goto fail;
+/*
+	gtk_entry_set_icon_from_stock(arg0, arg1, lparg2);
+*/
+	{
+		LOAD_FUNCTION(fp, gtk_entry_set_icon_from_stock)
+		if (fp) {
+			((void (CALLING_CONVENTION*)(jintLong, jint, jbyte *))fp)(arg0, arg1, lparg2);
+		}
+	}
+fail:
+	if (arg2 && lparg2) (*env)->ReleaseByteArrayElements(env, arg2, lparg2, 0);
+	OS_NATIVE_EXIT(env, that, _1gtk_1entry_1set_1icon_1from_1stock_FUNC);
+}
+#endif
+
+#ifndef NO__1gtk_1entry_1set_1icon_1sensitive
+JNIEXPORT void JNICALL OS_NATIVE(_1gtk_1entry_1set_1icon_1sensitive)
+	(JNIEnv *env, jclass that, jintLong arg0, jint arg1, jboolean arg2)
+{
+	OS_NATIVE_ENTER(env, that, _1gtk_1entry_1set_1icon_1sensitive_FUNC);
+/*
+	gtk_entry_set_icon_sensitive(arg0, arg1, arg2);
+*/
+	{
+		LOAD_FUNCTION(fp, gtk_entry_set_icon_sensitive)
+		if (fp) {
+			((void (CALLING_CONVENTION*)(jintLong, jint, jboolean))fp)(arg0, arg1, arg2);
+		}
+	}
+	OS_NATIVE_EXIT(env, that, _1gtk_1entry_1set_1icon_1sensitive_FUNC);
+}
+#endif
+
 #ifndef NO__1gtk_1entry_1set_1invisible_1char
 JNIEXPORT void JNICALL OS_NATIVE(_1gtk_1entry_1set_1invisible_1char)
 	(JNIEnv *env, jclass that, jintLong arg0, jchar arg1)
@@ -8516,6 +9564,48 @@ fail:
 }
 #endif
 
+#ifndef NO__1gtk_1icon_1info_1free
+JNIEXPORT void JNICALL OS_NATIVE(_1gtk_1icon_1info_1free)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	OS_NATIVE_ENTER(env, that, _1gtk_1icon_1info_1free_FUNC);
+/*
+	gtk_icon_info_free(arg0);
+*/
+	{
+		LOAD_FUNCTION(fp, gtk_icon_info_free)
+		if (fp) {
+			((void (CALLING_CONVENTION*)(jintLong))fp)(arg0);
+		}
+	}
+	OS_NATIVE_EXIT(env, that, _1gtk_1icon_1info_1free_FUNC);
+}
+#endif
+
+#ifndef NO__1gtk_1icon_1info_1load_1icon
+JNIEXPORT jintLong JNICALL OS_NATIVE(_1gtk_1icon_1info_1load_1icon)
+	(JNIEnv *env, jclass that, jintLong arg0, jintLongArray arg1)
+{
+	jintLong *lparg1=NULL;
+	jintLong rc = 0;
+	OS_NATIVE_ENTER(env, that, _1gtk_1icon_1info_1load_1icon_FUNC);
+	if (arg1) if ((lparg1 = (*env)->GetIntLongArrayElements(env, arg1, NULL)) == NULL) goto fail;
+/*
+	rc = (jintLong)gtk_icon_info_load_icon(arg0, lparg1);
+*/
+	{
+		LOAD_FUNCTION(fp, gtk_icon_info_load_icon)
+		if (fp) {
+			rc = (jintLong)((jintLong (CALLING_CONVENTION*)(jintLong, jintLong *))fp)(arg0, lparg1);
+		}
+	}
+fail:
+	if (arg1 && lparg1) (*env)->ReleaseIntLongArrayElements(env, arg1, lparg1, 0);
+	OS_NATIVE_EXIT(env, that, _1gtk_1icon_1info_1load_1icon_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO__1gtk_1icon_1set_1render_1icon
 JNIEXPORT jintLong JNICALL OS_NATIVE(_1gtk_1icon_1set_1render_1icon)
 	(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1, jint arg2, jint arg3, jint arg4, jintLong arg5, jintLong arg6)
@@ -8560,6 +9650,46 @@ JNIEXPORT void JNICALL OS_NATIVE(_1gtk_1icon_1source_1set_1pixbuf)
 }
 #endif
 
+#ifndef NO__1gtk_1icon_1theme_1get_1default
+JNIEXPORT jintLong JNICALL OS_NATIVE(_1gtk_1icon_1theme_1get_1default)
+	(JNIEnv *env, jclass that)
+{
+	jintLong rc = 0;
+	OS_NATIVE_ENTER(env, that, _1gtk_1icon_1theme_1get_1default_FUNC);
+/*
+	rc = (jintLong)gtk_icon_theme_get_default();
+*/
+	{
+		LOAD_FUNCTION(fp, gtk_icon_theme_get_default)
+		if (fp) {
+			rc = (jintLong)((jintLong (CALLING_CONVENTION*)())fp)();
+		}
+	}
+	OS_NATIVE_EXIT(env, that, _1gtk_1icon_1theme_1get_1default_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1gtk_1icon_1theme_1lookup_1by_1gicon
+JNIEXPORT jintLong JNICALL OS_NATIVE(_1gtk_1icon_1theme_1lookup_1by_1gicon)
+	(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1, jint arg2, jint arg3)
+{
+	jintLong rc = 0;
+	OS_NATIVE_ENTER(env, that, _1gtk_1icon_1theme_1lookup_1by_1gicon_FUNC);
+/*
+	rc = (jintLong)gtk_icon_theme_lookup_by_gicon(arg0, arg1, arg2, arg3);
+*/
+	{
+		LOAD_FUNCTION(fp, gtk_icon_theme_lookup_by_gicon)
+		if (fp) {
+			rc = (jintLong)((jintLong (CALLING_CONVENTION*)(jintLong, jintLong, jint, jint))fp)(arg0, arg1, arg2, arg3);
+		}
+	}
+	OS_NATIVE_EXIT(env, that, _1gtk_1icon_1theme_1lookup_1by_1gicon_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO__1gtk_1im_1context_1filter_1keypress
 JNIEXPORT jboolean JNICALL OS_NATIVE(_1gtk_1im_1context_1filter_1keypress)
 	(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1)
@@ -11665,6 +12795,16 @@ JNIEXPORT jintLong JNICALL OS_NATIVE(_1gtk_1socket_1new)
 }
 #endif
 
+#ifndef NO__1gtk_1spin_1button_1configure
+JNIEXPORT void JNICALL OS_NATIVE(_1gtk_1spin_1button_1configure)
+	(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1, jdouble arg2, jint arg3)
+{
+	OS_NATIVE_ENTER(env, that, _1gtk_1spin_1button_1configure_FUNC);
+	gtk_spin_button_configure((GtkSpinButton*)arg0, (GtkAdjustment *)arg1, arg2, arg3);
+	OS_NATIVE_EXIT(env, that, _1gtk_1spin_1button_1configure_FUNC);
+}
+#endif
+
 #ifndef NO__1gtk_1spin_1button_1get_1adjustment
 JNIEXPORT jintLong JNICALL OS_NATIVE(_1gtk_1spin_1button_1get_1adjustment)
 	(JNIEnv *env, jclass that, jintLong arg0)
@@ -14636,6 +15776,18 @@ JNIEXPORT jintLong JNICALL OS_NATIVE(_1gtk_1widget_1get_1parent)
 }
 #endif
 
+#ifndef NO__1gtk_1widget_1get_1parent_1window
+JNIEXPORT jintLong JNICALL OS_NATIVE(_1gtk_1widget_1get_1parent_1window)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	OS_NATIVE_ENTER(env, that, _1gtk_1widget_1get_1parent_1window_FUNC);
+	rc = (jintLong)gtk_widget_get_parent_window((GtkWidget *)arg0);
+	OS_NATIVE_EXIT(env, that, _1gtk_1widget_1get_1parent_1window_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO__1gtk_1widget_1get_1size_1request
 JNIEXPORT void JNICALL OS_NATIVE(_1gtk_1widget_1get_1size_1request)
 	(JNIEnv *env, jclass that, jintLong arg0, jintArray arg1, jintArray arg2)
@@ -15359,6 +16511,18 @@ JNIEXPORT void JNICALL OS_NATIVE(_1gtk_1window_1iconify)
 }
 #endif
 
+#ifndef NO__1gtk_1window_1is_1active
+JNIEXPORT jboolean JNICALL OS_NATIVE(_1gtk_1window_1is_1active)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jboolean rc = 0;
+	OS_NATIVE_ENTER(env, that, _1gtk_1window_1is_1active_FUNC);
+	rc = (jboolean)gtk_window_is_active((GtkWindow *)arg0);
+	OS_NATIVE_EXIT(env, that, _1gtk_1window_1is_1active_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO__1gtk_1window_1list_1toplevels
 JNIEXPORT jintLong JNICALL OS_NATIVE(_1gtk_1window_1list_1toplevels)
 	(JNIEnv *env, jclass that)
@@ -16183,6 +17347,18 @@ JNIEXPORT jint JNICALL OS_NATIVE(_1pango_1font_1description_1get_1size)
 }
 #endif
 
+#ifndef NO__1pango_1font_1description_1get_1stretch
+JNIEXPORT jint JNICALL OS_NATIVE(_1pango_1font_1description_1get_1stretch)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jint rc = 0;
+	OS_NATIVE_ENTER(env, that, _1pango_1font_1description_1get_1stretch_FUNC);
+	rc = (jint)pango_font_description_get_stretch((PangoFontDescription *)arg0);
+	OS_NATIVE_EXIT(env, that, _1pango_1font_1description_1get_1stretch_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO__1pango_1font_1description_1get_1style
 JNIEXPORT jint JNICALL OS_NATIVE(_1pango_1font_1description_1get_1style)
 	(JNIEnv *env, jclass that, jintLong arg0)
@@ -16195,6 +17371,18 @@ JNIEXPORT jint JNICALL OS_NATIVE(_1pango_1font_1description_1get_1style)
 }
 #endif
 
+#ifndef NO__1pango_1font_1description_1get_1variant
+JNIEXPORT jint JNICALL OS_NATIVE(_1pango_1font_1description_1get_1variant)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jint rc = 0;
+	OS_NATIVE_ENTER(env, that, _1pango_1font_1description_1get_1variant_FUNC);
+	rc = (jint)pango_font_description_get_variant((PangoFontDescription *)arg0);
+	OS_NATIVE_EXIT(env, that, _1pango_1font_1description_1get_1variant_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO__1pango_1font_1description_1get_1weight
 JNIEXPORT jint JNICALL OS_NATIVE(_1pango_1font_1description_1get_1weight)
 	(JNIEnv *env, jclass that, jintLong arg0)
@@ -17055,6 +18243,116 @@ JNIEXPORT void JNICALL OS_NATIVE(g_1main_1context_1wakeup)
 }
 #endif
 
+#ifndef NO_g_1value_1get_1double
+JNIEXPORT jdouble JNICALL OS_NATIVE(g_1value_1get_1double)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jdouble rc = 0;
+	OS_NATIVE_ENTER(env, that, g_1value_1get_1double_FUNC);
+	rc = (jdouble)g_value_get_double((GValue *)arg0);
+	OS_NATIVE_EXIT(env, that, g_1value_1get_1double_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO_g_1value_1get_1float
+JNIEXPORT jfloat JNICALL OS_NATIVE(g_1value_1get_1float)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jfloat rc = 0;
+	OS_NATIVE_ENTER(env, that, g_1value_1get_1float_FUNC);
+	rc = (jfloat)g_value_get_float((GValue *)arg0);
+	OS_NATIVE_EXIT(env, that, g_1value_1get_1float_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO_g_1value_1get_1int
+JNIEXPORT jint JNICALL OS_NATIVE(g_1value_1get_1int)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jint rc = 0;
+	OS_NATIVE_ENTER(env, that, g_1value_1get_1int_FUNC);
+	rc = (jint)g_value_get_int((GValue *)arg0);
+	OS_NATIVE_EXIT(env, that, g_1value_1get_1int_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO_g_1value_1get_1int64
+JNIEXPORT jlong JNICALL OS_NATIVE(g_1value_1get_1int64)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jlong rc = 0;
+	OS_NATIVE_ENTER(env, that, g_1value_1get_1int64_FUNC);
+	rc = (jlong)g_value_get_int64((GValue *)arg0);
+	OS_NATIVE_EXIT(env, that, g_1value_1get_1int64_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO_g_1value_1init
+JNIEXPORT jintLong JNICALL OS_NATIVE(g_1value_1init)
+	(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1)
+{
+	jintLong rc = 0;
+	OS_NATIVE_ENTER(env, that, g_1value_1init_FUNC);
+	rc = (jintLong)g_value_init((GValue *)arg0, (GType)arg1);
+	OS_NATIVE_EXIT(env, that, g_1value_1init_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO_g_1value_1set_1double
+JNIEXPORT void JNICALL OS_NATIVE(g_1value_1set_1double)
+	(JNIEnv *env, jclass that, jintLong arg0, jdouble arg1)
+{
+	OS_NATIVE_ENTER(env, that, g_1value_1set_1double_FUNC);
+	g_value_set_double((GValue *)arg0, arg1);
+	OS_NATIVE_EXIT(env, that, g_1value_1set_1double_FUNC);
+}
+#endif
+
+#ifndef NO_g_1value_1set_1float
+JNIEXPORT void JNICALL OS_NATIVE(g_1value_1set_1float)
+	(JNIEnv *env, jclass that, jintLong arg0, jfloat arg1)
+{
+	OS_NATIVE_ENTER(env, that, g_1value_1set_1float_FUNC);
+	g_value_set_float((GValue *)arg0, arg1);
+	OS_NATIVE_EXIT(env, that, g_1value_1set_1float_FUNC);
+}
+#endif
+
+#ifndef NO_g_1value_1set_1int
+JNIEXPORT void JNICALL OS_NATIVE(g_1value_1set_1int)
+	(JNIEnv *env, jclass that, jintLong arg0, jint arg1)
+{
+	OS_NATIVE_ENTER(env, that, g_1value_1set_1int_FUNC);
+	g_value_set_int((GValue *)arg0, arg1);
+	OS_NATIVE_EXIT(env, that, g_1value_1set_1int_FUNC);
+}
+#endif
+
+#ifndef NO_g_1value_1set_1int64
+JNIEXPORT void JNICALL OS_NATIVE(g_1value_1set_1int64)
+	(JNIEnv *env, jclass that, jintLong arg0, jlong arg1)
+{
+	OS_NATIVE_ENTER(env, that, g_1value_1set_1int64_FUNC);
+	g_value_set_int64((GValue *)arg0, arg1);
+	OS_NATIVE_EXIT(env, that, g_1value_1set_1int64_FUNC);
+}
+#endif
+
+#ifndef NO_g_1value_1unset
+JNIEXPORT void JNICALL OS_NATIVE(g_1value_1unset)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	OS_NATIVE_ENTER(env, that, g_1value_1unset_FUNC);
+	g_value_unset((GValue *)arg0);
+	OS_NATIVE_EXIT(env, that, g_1value_1unset_FUNC);
+}
+#endif
+
 #ifndef NO_localeconv_1decimal_1point
 JNIEXPORT jintLong JNICALL OS_NATIVE(localeconv_1decimal_1point)
 	(JNIEnv *env, jclass that)
@@ -17340,30 +18638,6 @@ fail:
 }
 #endif
 
-#if (!defined(NO_memmove__ILorg_eclipse_swt_internal_gtk_XButtonEvent_2I) && !defined(JNI64)) || (!defined(NO_memmove__JLorg_eclipse_swt_internal_gtk_XButtonEvent_2J) && defined(JNI64))
-#ifndef JNI64
-JNIEXPORT void JNICALL OS_NATIVE(memmove__ILorg_eclipse_swt_internal_gtk_XButtonEvent_2I)(JNIEnv *env, jclass that, jintLong arg0, jobject arg1, jintLong arg2)
-#else
-JNIEXPORT void JNICALL OS_NATIVE(memmove__JLorg_eclipse_swt_internal_gtk_XButtonEvent_2J)(JNIEnv *env, jclass that, jintLong arg0, jobject arg1, jintLong arg2)
-#endif
-{
-	XButtonEvent _arg1, *lparg1=NULL;
-#ifndef JNI64
-	OS_NATIVE_ENTER(env, that, memmove__ILorg_eclipse_swt_internal_gtk_XButtonEvent_2I_FUNC);
-#else
-	OS_NATIVE_ENTER(env, that, memmove__JLorg_eclipse_swt_internal_gtk_XButtonEvent_2J_FUNC);
-#endif
-	if (arg1) if ((lparg1 = getXButtonEventFields(env, arg1, &_arg1)) == NULL) goto fail;
-	memmove((void *)arg0, (const void *)lparg1, (size_t)arg2);
-fail:
-#ifndef JNI64
-	OS_NATIVE_EXIT(env, that, memmove__ILorg_eclipse_swt_internal_gtk_XButtonEvent_2I_FUNC);
-#else
-	OS_NATIVE_EXIT(env, that, memmove__JLorg_eclipse_swt_internal_gtk_XButtonEvent_2J_FUNC);
-#endif
-}
-#endif
-
 #if (!defined(NO_memmove__ILorg_eclipse_swt_internal_gtk_XClientMessageEvent_2I) && !defined(JNI64)) || (!defined(NO_memmove__JLorg_eclipse_swt_internal_gtk_XClientMessageEvent_2J) && defined(JNI64))
 #ifndef JNI64
 JNIEXPORT void JNICALL OS_NATIVE(memmove__ILorg_eclipse_swt_internal_gtk_XClientMessageEvent_2I)(JNIEnv *env, jclass that, jintLong arg0, jobject arg1, jintLong arg2)
@@ -17731,6 +19005,27 @@ fail:
 }
 #endif
 
+#if (!defined(NO_memmove__Lorg_eclipse_swt_internal_gtk_GdkEventProperty_2I) && !defined(JNI64)) || (!defined(NO_memmove__Lorg_eclipse_swt_internal_gtk_GdkEventProperty_2J) && defined(JNI64))
+#ifndef JNI64
+JNIEXPORT void JNICALL OS_NATIVE(memmove__Lorg_eclipse_swt_internal_gtk_GdkEventProperty_2I)(JNIEnv *env, jclass that, jobject arg0, jintLong arg1)
+#else
+JNIEXPORT void JNICALL OS_NATIVE(memmove__Lorg_eclipse_swt_internal_gtk_GdkEventProperty_2J)(JNIEnv *env, jclass that, jobject arg0, jintLong arg1)
+#endif
+{
+#ifndef JNI64
+	OS_NATIVE_ENTER(env, that, memmove__Lorg_eclipse_swt_internal_gtk_GdkEventProperty_2I_FUNC);
+#else
+	OS_NATIVE_ENTER(env, that, memmove__Lorg_eclipse_swt_internal_gtk_GdkEventProperty_2J_FUNC);
+#endif
+	if (arg0) setGdkEventPropertyFields(env, arg0, (GdkEventProperty *)arg1);
+#ifndef JNI64
+	OS_NATIVE_EXIT(env, that, memmove__Lorg_eclipse_swt_internal_gtk_GdkEventProperty_2I_FUNC);
+#else
+	OS_NATIVE_EXIT(env, that, memmove__Lorg_eclipse_swt_internal_gtk_GdkEventProperty_2J_FUNC);
+#endif
+}
+#endif
+
 #if (!defined(NO_memmove__Lorg_eclipse_swt_internal_gtk_GdkEventScroll_2II) && !defined(JNI64)) || (!defined(NO_memmove__Lorg_eclipse_swt_internal_gtk_GdkEventScroll_2JJ) && defined(JNI64))
 #ifndef JNI64
 JNIEXPORT void JNICALL OS_NATIVE(memmove__Lorg_eclipse_swt_internal_gtk_GdkEventScroll_2II)(JNIEnv *env, jclass that, jobject arg0, jintLong arg1, jintLong arg2)
@@ -18295,31 +19590,6 @@ fail:
 }
 #endif
 
-#if (!defined(NO_memmove__Lorg_eclipse_swt_internal_gtk_XButtonEvent_2II) && !defined(JNI64)) || (!defined(NO_memmove__Lorg_eclipse_swt_internal_gtk_XButtonEvent_2JJ) && defined(JNI64))
-#ifndef JNI64
-JNIEXPORT void JNICALL OS_NATIVE(memmove__Lorg_eclipse_swt_internal_gtk_XButtonEvent_2II)(JNIEnv *env, jclass that, jobject arg0, jintLong arg1, jintLong arg2)
-#else
-JNIEXPORT void JNICALL OS_NATIVE(memmove__Lorg_eclipse_swt_internal_gtk_XButtonEvent_2JJ)(JNIEnv *env, jclass that, jobject arg0, jintLong arg1, jintLong arg2)
-#endif
-{
-	XButtonEvent _arg0, *lparg0=NULL;
-#ifndef JNI64
-	OS_NATIVE_ENTER(env, that, memmove__Lorg_eclipse_swt_internal_gtk_XButtonEvent_2II_FUNC);
-#else
-	OS_NATIVE_ENTER(env, that, memmove__Lorg_eclipse_swt_internal_gtk_XButtonEvent_2JJ_FUNC);
-#endif
-	if (arg0) if ((lparg0 = &_arg0) == NULL) goto fail;
-	memmove((void *)lparg0, (const void *)arg1, (size_t)arg2);
-fail:
-	if (arg0 && lparg0) setXButtonEventFields(env, arg0, lparg0);
-#ifndef JNI64
-	OS_NATIVE_EXIT(env, that, memmove__Lorg_eclipse_swt_internal_gtk_XButtonEvent_2II_FUNC);
-#else
-	OS_NATIVE_EXIT(env, that, memmove__Lorg_eclipse_swt_internal_gtk_XButtonEvent_2JJ_FUNC);
-#endif
-}
-#endif
-
 #if (!defined(NO_memmove__Lorg_eclipse_swt_internal_gtk_XCrossingEvent_2II) && !defined(JNI64)) || (!defined(NO_memmove__Lorg_eclipse_swt_internal_gtk_XCrossingEvent_2JJ) && defined(JNI64))
 #ifndef JNI64
 JNIEXPORT void JNICALL OS_NATIVE(memmove__Lorg_eclipse_swt_internal_gtk_XCrossingEvent_2II)(JNIEnv *env, jclass that, jobject arg0, jintLong arg1, jintLong arg2)
diff --git a/os.h b/os.h
index e930b9b..6948505 100644
--- a/os.h
+++ b/os.h
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others. All rights reserved.
+ * Copyright (c) 2000, 2010 IBM Corporation and others. All rights reserved.
  * The contents of this file are made available under the terms
  * of the GNU Lesser General Public License (LGPL) Version 2.1 that
  * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
@@ -31,6 +31,7 @@
 #include <string.h>
 #include <dlfcn.h>
 #include <locale.h>
+#include <unistd.h>
 
 #ifndef GDK_WINDOWING_X11
 
diff --git a/os_custom.c b/os_custom.c
index 216645e..5d757b0 100644
--- a/os_custom.c
+++ b/os_custom.c
@@ -35,6 +35,25 @@ JNIEXPORT jboolean JNICALL OS_NATIVE(GDK_1WINDOWING_1X11)
 }
 #endif
 
+#ifndef NO_pangoLayoutNewProc_1CALLBACK
+static jintLong superPangoLayoutNewProc;
+static PangoLayout * pangoLayoutNewProc (GType type, guint n_construct_properties, GObjectConstructParam * construct_properties) {
+	PangoLayout* layout = ((PangoLayout * (*)(GType, guint, GObjectConstructParam *))superPangoLayoutNewProc)(type, n_construct_properties, construct_properties);
+	pango_layout_set_auto_dir (layout, 0);
+	return layout;
+}
+JNIEXPORT jintLong JNICALL OS_NATIVE(pangoLayoutNewProc_1CALLBACK)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	OS_NATIVE_ENTER(env, that, pangoLayoutNewProc_1CALLBACK_FUNC);
+	superPangoLayoutNewProc = arg0;
+	rc = (jintLong)pangoLayoutNewProc;
+	OS_NATIVE_EXIT(env, that, pangoLayoutNewProc_1CALLBACK_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO__1gtk_1file_1chooser_1dialog_1new
 JNIEXPORT jintLong JNICALL OS_NATIVE(_1gtk_1file_1chooser_1dialog_1new)
 	(JNIEnv *env, jclass that, jbyteArray arg0, jintLong arg1, jint arg2, jintLong arg3, jint arg4, jintLong arg5, jint arg6, jintLong arg7)
diff --git a/os_custom.h b/os_custom.h
index 0bb68c3..90533e5 100644
--- a/os_custom.h
+++ b/os_custom.h
@@ -1,5 +1,5 @@
 /*******************************************************************************
-* Copyright (c) 2000, 2009 IBM Corporation and others. All rights reserved.
+* Copyright (c) 2000, 2010 IBM Corporation and others. All rights reserved.
 * The contents of this file are made available under the terms
 * of the GNU Lesser General Public License (LGPL) Version 2.1 that
 * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
@@ -85,6 +85,10 @@
 #define gtk_expander_set_label_LIB "libgtk-x11-2.0.so.0"
 #define gtk_expander_set_label_widget_LIB "libgtk-x11-2.0.so.0"
 #define gtk_label_set_line_wrap_mode_LIB "libgtk-x11-2.0.so.0"
+#define gtk_icon_info_load_icon_LIB "libgtk-x11-2.0.so.0"
+#define gtk_icon_info_free_LIB "libgtk-x11-2.0.so.0"
+#define gtk_icon_theme_lookup_by_gicon_LIB "libgtk-x11-2.0.so.0"
+#define gtk_icon_theme_get_default_LIB "libgtk-x11-2.0.so.0"
 #define gtk_menu_shell_set_take_focus_LIB "libgtk-x11-2.0.so.0"
 #define gtk_window_set_keep_below_LIB "libgtk-x11-2.0.so.0"
 #define gtk_tooltip_trigger_tooltip_query_LIB "libgtk-x11-2.0.so.0"
@@ -93,6 +97,8 @@
 #define gtk_tree_view_column_cell_get_position_LIB "libgtk-x11-2.0.so.0"
 #define gtk_tree_view_set_grid_lines_LIB "libgtk-x11-2.0.so.0"
 #define gtk_entry_set_alignment_LIB "libgtk-x11-2.0.so.0"
+#define gtk_entry_set_icon_from_stock_LIB "libgtk-x11-2.0.so.0"
+#define gtk_entry_set_icon_sensitive_LIB "libgtk-x11-2.0.so.0"
 #define gdk_cursor_new_from_pixbuf_LIB "libgdk-x11-2.0.so.0"
 #define gdk_display_get_default_LIB "libgdk-x11-2.0.so.0"
 #define gdk_display_supports_cursor_color_LIB "libgdk-x11-2.0.so.0"
@@ -112,6 +118,7 @@
 #define gtk_status_icon_set_tooltip_LIB "libgtk-x11-2.0.so.0"
 #define gtk_window_get_group_LIB "libgtk-x11-2.0.so.0"
 #define gtk_window_get_opacity_LIB "libgtk-x11-2.0.so.0"
+#define gdk_window_restack_LIB "libgdk-x11-2.0.so.0"
 #define gdk_window_set_keep_above_LIB "libgdk-x11-2.0.so.0"
 #define gdk_window_set_accept_focus_LIB "libgdk-x11-2.0.so.0"
 #define gtk_window_set_opacity_LIB "libgtk-x11-2.0.so.0"
@@ -122,6 +129,7 @@
 #define gdk_x11_screen_lookup_visual_LIB "libgdk-x11-2.0.so.0"
 
 #define atk_object_add_relationship_LIB "libatk-1.0.so.0"
+#define atk_object_remove_relationship_LIB "libatk-1.0.so.0"
 #define pango_attr_underline_color_new_LIB "libpango-1.0.so.0"
 #define pango_attr_strikethrough_color_new_LIB "libpango-1.0.so.0"
 #define pango_font_metrics_get_underline_thickness_LIB "libpango-1.0.so.0"
@@ -210,11 +218,48 @@
 #define gtk_printer_is_default_LIB "libgtk-x11-2.0.so.0"
 #define FcConfigAppFontAddFile_LIB "libfontconfig.so.1"
 
+#define g_app_info_create_from_commandline_LIB "libgio-2.0.so.0"
+#define g_app_info_get_all_LIB "libgio-2.0.so.0"
+#define g_app_info_get_executable_LIB "libgio-2.0.so.0"
+#define g_app_info_get_icon_LIB "libgio-2.0.so.0"
+#define g_app_info_get_id_LIB "libgio-2.0.so.0"
+#define g_app_info_get_name_LIB "libgio-2.0.so.0"
+#define g_app_info_launch_LIB "libgio-2.0.so.0"
+#define g_app_info_get_default_for_type_LIB "libgio-2.0.so.0"
+#define g_app_info_launch_default_for_uri_LIB "libgio-2.0.so.0"
+#define g_app_info_supports_uris_LIB "libgio-2.0.so.0"
+#define g_app_info_should_show_LIB "libgio-2.0.so.0"
+#define g_data_input_stream_new_LIB "libgio-2.0.so.0"
+#define g_data_input_stream_read_line_LIB "libgio-2.0.so.0"
+#define g_content_type_equals_LIB "libgio-2.0.so.0"
+#define g_content_type_get_mime_type_LIB "libgio-2.0.so.0"
+#define g_content_type_is_a_LIB "libgio-2.0.so.0"
+#define g_content_types_get_registered_LIB "libgio-2.0.so.0"
+#define g_desktop_app_info_new_from_filename_LIB "libgio-2.0.so.0"
+#define g_file_get_path_LIB "libgio-2.0.so.0"
+#define g_file_get_uri_LIB "libgio-2.0.so.0"
+#define g_file_icon_get_file_LIB "libgio-2.0.so.0"
+#define g_file_info_get_content_type_LIB "libgio-2.0.so.0"
+#define g_file_info_get_modification_time_LIB "libgio-2.0.so.0"
+#define g_file_new_for_path_LIB "libgio-2.0.so.0"
+#define g_file_new_for_uri_LIB "libgio-2.0.so.0"
+#define g_file_read_LIB "libgio-2.0.so.0"
+#define g_file_test_LIB "libgio-2.0.so.0"
+#define g_icon_to_string_LIB "libgio-2.0.so.0"
+#define g_icon_new_for_string_LIB "libgio-2.0.so.0"
+#define g_file_query_info_LIB "libgio-2.0.so.0"
+
 /* Field accessors */
 #define G_OBJECT_CLASS_CONSTRUCTOR(arg0) (arg0)->constructor
 #define G_OBJECT_CLASS_SET_CONSTRUCTOR(arg0, arg1) (arg0)->constructor = (GObject* (*) (GType, guint, GObjectConstructParam *))arg1
 #define GTK_ACCEL_LABEL_SET_ACCEL_STRING(arg0, arg1) (arg0)->accel_string = arg1
 #define GTK_ACCEL_LABEL_GET_ACCEL_STRING(arg0) (arg0)->accel_string
+#define GTK_RANGE_SLIDER_START(arg0) (arg0)->slider_start
+#define GTK_RANGE_SLIDER_END(arg0) (arg0)->slider_end
+#define GTK_RANGE_HAS_STEPPER_A(arg0) (arg0)->has_stepper_a
+#define GTK_RANGE_HAS_STEPPER_B(arg0) (arg0)->has_stepper_b
+#define GTK_RANGE_HAS_STEPPER_C(arg0) (arg0)->has_stepper_c
+#define GTK_RANGE_HAS_STEPPER_D(arg0) (arg0)->has_stepper_d
 #define GTK_SCROLLED_WINDOW_HSCROLLBAR(arg0) (arg0)->hscrollbar
 #define GTK_SCROLLED_WINDOW_SCROLLBAR_SPACING(arg0) (GTK_SCROLLED_WINDOW_GET_CLASS (arg0)->scrollbar_spacing >= 0 ? GTK_SCROLLED_WINDOW_GET_CLASS (arg0)->scrollbar_spacing : 3)		
 #define GTK_SCROLLED_WINDOW_VSCROLLBAR(arg0) (arg0)->vscrollbar
diff --git a/os_stats.c b/os_stats.c
index 5f5fbe5..7f522de 100644
--- a/os_stats.c
+++ b/os_stats.c
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others. All rights reserved.
+ * Copyright (c) 2000, 2010 IBM Corporation and others. All rights reserved.
  * The contents of this file are made available under the terms
  * of the GNU Lesser General Public License (LGPL) Version 2.1 that
  * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
@@ -18,8 +18,8 @@
 
 #ifdef NATIVE_STATS
 
-int OS_nativeFunctionCount = 1291;
-int OS_nativeFunctionCallCount[1291];
+int OS_nativeFunctionCount = 1366;
+int OS_nativeFunctionCallCount[1366];
 char * OS_nativeFunctionNames[] = {
 #ifndef JNI64
 	"Call__IIII",
@@ -39,6 +39,12 @@ char * OS_nativeFunctionNames[] = {
 	"GTK_1ACCEL_1LABEL_1GET_1ACCEL_1STRING",
 	"GTK_1ACCEL_1LABEL_1SET_1ACCEL_1STRING",
 	"GTK_1ENTRY_1IM_1CONTEXT",
+	"GTK_1RANGE_1HAS_1STEPPER_1A",
+	"GTK_1RANGE_1HAS_1STEPPER_1B",
+	"GTK_1RANGE_1HAS_1STEPPER_1C",
+	"GTK_1RANGE_1HAS_1STEPPER_1D",
+	"GTK_1RANGE_1SLIDER_1END",
+	"GTK_1RANGE_1SLIDER_1START",
 	"GTK_1SCROLLED_1WINDOW_1HSCROLLBAR",
 	"GTK_1SCROLLED_1WINDOW_1SCROLLBAR_1SPACING",
 	"GTK_1SCROLLED_1WINDOW_1VSCROLLBAR",
@@ -60,6 +66,12 @@ char * OS_nativeFunctionNames[] = {
 	"GTypeQuery_1sizeof",
 	"G_1OBJECT_1CLASS_1CONSTRUCTOR",
 	"G_1OBJECT_1CLASS_1SET_1CONSTRUCTOR",
+	"G_1TYPE_1BOOLEAN",
+	"G_1TYPE_1DOUBLE",
+	"G_1TYPE_1FLOAT",
+	"G_1TYPE_1INT",
+	"G_1TYPE_1INT64",
+	"G_1VALUE_1TYPE",
 	"GdkColor_1sizeof",
 	"GdkDragContext_1sizeof",
 	"GdkEventAny_1sizeof",
@@ -69,6 +81,7 @@ char * OS_nativeFunctionNames[] = {
 	"GdkEventFocus_1sizeof",
 	"GdkEventKey_1sizeof",
 	"GdkEventMotion_1sizeof",
+	"GdkEventProperty_1sizeof",
 	"GdkEventScroll_1sizeof",
 	"GdkEventVisibility_1sizeof",
 	"GdkEventWindowState_1sizeof",
@@ -108,7 +121,6 @@ char * OS_nativeFunctionNames[] = {
 	"PangoLogAttr_1sizeof",
 	"PangoRectangle_1sizeof",
 	"XAnyEvent_1sizeof",
-	"XButtonEvent_1sizeof",
 	"XClientMessageEvent_1sizeof",
 	"XCrossingEvent_1sizeof",
 	"XEvent_1sizeof",
@@ -126,6 +138,8 @@ char * OS_nativeFunctionNames[] = {
 	"_1GDK_1ROOT_1PARENT",
 	"_1GDK_1TYPE_1COLOR",
 	"_1GDK_1TYPE_1PIXBUF",
+	"_1GString_1len",
+	"_1GString_1str",
 	"_1GTK_1IS_1BUTTON",
 	"_1GTK_1IS_1CELL_1RENDERER_1PIXBUF",
 	"_1GTK_1IS_1CELL_1RENDERER_1TEXT",
@@ -134,6 +148,7 @@ char * OS_nativeFunctionNames[] = {
 	"_1GTK_1IS_1IMAGE_1MENU_1ITEM",
 	"_1GTK_1IS_1MENU_1ITEM",
 	"_1GTK_1IS_1PLUG",
+	"_1GTK_1IS_1SCROLLED_1WINDOW",
 	"_1GTK_1IS_1SOCKET",
 	"_1GTK_1IS_1WINDOW",
 	"_1GTK_1STOCK_1CANCEL",
@@ -158,8 +173,6 @@ char * OS_nativeFunctionNames[] = {
 	"_1G_1OBJECT_1GET_1CLASS",
 	"_1G_1OBJECT_1TYPE",
 	"_1G_1OBJECT_1TYPE_1NAME",
-	"_1G_1TYPE_1BOOLEAN",
-	"_1G_1TYPE_1INT",
 	"_1G_1TYPE_1STRING",
 	"_1PANGO_1PIXELS",
 	"_1PANGO_1TYPE_1FONT_1DESCRIPTION",
@@ -172,6 +185,7 @@ char * OS_nativeFunctionNames[] = {
 	"_1XFlush",
 	"_1XFree",
 	"_1XGetSelectionOwner",
+	"_1XGetWindowProperty",
 	"_1XInternAtom",
 	"_1XKeysymToKeycode",
 	"_1XListProperties",
@@ -191,25 +205,58 @@ char * OS_nativeFunctionNames[] = {
 	"_1XSetErrorHandler",
 	"_1XSetIOErrorHandler",
 	"_1XSetInputFocus",
+	"_1XSetSelectionOwner",
 	"_1XSetTransientForHint",
 	"_1XSynchronize",
 	"_1XTestFakeButtonEvent",
 	"_1XTestFakeKeyEvent",
 	"_1XTestFakeMotionEvent",
 	"_1XWarpPointer",
+	"_1access",
 	"_1atk_1object_1add_1relationship",
+	"_1atk_1object_1remove_1relationship",
 	"_1call",
 	"_1dlclose",
 	"_1dlopen",
 	"_1dlsym",
+	"_1g_1app_1info_1create_1from_1commandline",
+	"_1g_1app_1info_1get_1all",
+	"_1g_1app_1info_1get_1default_1for_1type",
+	"_1g_1app_1info_1get_1executable",
+	"_1g_1app_1info_1get_1icon",
+	"_1g_1app_1info_1get_1id",
+	"_1g_1app_1info_1get_1name",
+	"_1g_1app_1info_1launch",
+	"_1g_1app_1info_1launch_1default_1for_1uri",
+	"_1g_1app_1info_1should_1show",
+	"_1g_1app_1info_1supports_1uris",
 	"_1g_1cclosure_1new",
 	"_1g_1closure_1ref",
 	"_1g_1closure_1unref",
+	"_1g_1content_1type_1equals",
+	"_1g_1content_1type_1get_1mime_1type",
+	"_1g_1content_1type_1is_1a",
+	"_1g_1content_1types_1get_1registered",
+	"_1g_1data_1input_1stream_1new",
+	"_1g_1data_1input_1stream_1read_1line",
+	"_1g_1desktop_1app_1info_1new_1from_1filename",
+	"_1g_1file_1get_1path",
+	"_1g_1file_1get_1uri",
+	"_1g_1file_1icon_1get_1file",
+	"_1g_1file_1info_1get_1content_1type",
+	"_1g_1file_1info_1get_1modification_1time",
+	"_1g_1file_1new_1for_1path",
+	"_1g_1file_1new_1for_1uri",
+	"_1g_1file_1query_1info",
+	"_1g_1file_1read",
+	"_1g_1file_1test",
 	"_1g_1filename_1from_1uri",
 	"_1g_1filename_1from_1utf8",
 	"_1g_1filename_1to_1uri",
 	"_1g_1filename_1to_1utf8",
 	"_1g_1free",
+	"_1g_1icon_1new_1for_1string",
+	"_1g_1icon_1to_1string",
 	"_1g_1idle_1add",
 	"_1g_1list_1append",
 	"_1g_1list_1data",
@@ -270,6 +317,11 @@ char * OS_nativeFunctionNames[] = {
 #else
 	"_1g_1object_1set__J_3BZJ",
 #endif
+#ifndef JNI64
+	"_1g_1object_1set__I_3B_3BI",
+#else
+	"_1g_1object_1set__J_3B_3BJ",
+#endif
 	"_1g_1object_1set_1qdata",
 	"_1g_1object_1unref",
 	"_1g_1quark_1from_1string",
@@ -295,11 +347,17 @@ char * OS_nativeFunctionNames[] = {
 	"_1g_1signal_1emit_1by_1name__J_3BJJ",
 #endif
 #ifndef JNI64
+	"_1g_1signal_1emit_1by_1name__I_3BLorg_eclipse_swt_internal_gtk_GdkRectangle_2",
+#else
+	"_1g_1signal_1emit_1by_1name__J_3BLorg_eclipse_swt_internal_gtk_GdkRectangle_2",
+#endif
+#ifndef JNI64
 	"_1g_1signal_1emit_1by_1name__I_3B_3B",
 #else
 	"_1g_1signal_1emit_1by_1name__J_3B_3B",
 #endif
 	"_1g_1signal_1handler_1disconnect",
+	"_1g_1signal_1handler_1find",
 	"_1g_1signal_1handlers_1block_1matched",
 	"_1g_1signal_1handlers_1disconnect_1matched",
 	"_1g_1signal_1handlers_1unblock_1matched",
@@ -415,6 +473,7 @@ char * OS_nativeFunctionNames[] = {
 	"_1gdk_1keymap_1translate_1keyboard_1state",
 	"_1gdk_1keyval_1to_1lower",
 	"_1gdk_1keyval_1to_1unicode",
+	"_1gdk_1pango_1attr_1embossed_1new",
 	"_1gdk_1pango_1context_1get",
 	"_1gdk_1pango_1context_1set_1colormap",
 	"_1gdk_1pango_1layout_1get_1clip_1region",
@@ -497,12 +556,14 @@ char * OS_nativeFunctionNames[] = {
 	"_1gdk_1window_1lookup",
 	"_1gdk_1window_1lower",
 	"_1gdk_1window_1move",
+	"_1gdk_1window_1move_1resize",
 	"_1gdk_1window_1new",
 	"_1gdk_1window_1process_1all_1updates",
 	"_1gdk_1window_1process_1updates",
 	"_1gdk_1window_1raise",
 	"_1gdk_1window_1remove_1filter",
 	"_1gdk_1window_1resize",
+	"_1gdk_1window_1restack",
 	"_1gdk_1window_1scroll",
 	"_1gdk_1window_1set_1accept_1focus",
 	"_1gdk_1window_1set_1back_1pixmap",
@@ -564,6 +625,7 @@ char * OS_nativeFunctionNames[] = {
 	"_1gtk_1clipboard_1clear",
 	"_1gtk_1clipboard_1get",
 	"_1gtk_1clipboard_1set_1with_1data",
+	"_1gtk_1clipboard_1set_1with_1owner",
 	"_1gtk_1clipboard_1wait_1for_1contents",
 	"_1gtk_1color_1selection_1dialog_1new",
 	"_1gtk_1color_1selection_1get_1current_1color",
@@ -625,6 +687,8 @@ char * OS_nativeFunctionNames[] = {
 	"_1gtk_1entry_1set_1activates_1default",
 	"_1gtk_1entry_1set_1alignment",
 	"_1gtk_1entry_1set_1has_1frame",
+	"_1gtk_1entry_1set_1icon_1from_1stock",
+	"_1gtk_1entry_1set_1icon_1sensitive",
 	"_1gtk_1entry_1set_1invisible_1char",
 	"_1gtk_1entry_1set_1max_1length",
 	"_1gtk_1entry_1set_1text",
@@ -690,10 +754,14 @@ char * OS_nativeFunctionNames[] = {
 	"_1gtk_1hscrollbar_1new",
 	"_1gtk_1hseparator_1new",
 	"_1gtk_1icon_1factory_1lookup_1default",
+	"_1gtk_1icon_1info_1free",
+	"_1gtk_1icon_1info_1load_1icon",
 	"_1gtk_1icon_1set_1render_1icon",
 	"_1gtk_1icon_1source_1free",
 	"_1gtk_1icon_1source_1new",
 	"_1gtk_1icon_1source_1set_1pixbuf",
+	"_1gtk_1icon_1theme_1get_1default",
+	"_1gtk_1icon_1theme_1lookup_1by_1gicon",
 	"_1gtk_1im_1context_1filter_1keypress",
 	"_1gtk_1im_1context_1focus_1in",
 	"_1gtk_1im_1context_1focus_1out",
@@ -926,6 +994,7 @@ char * OS_nativeFunctionNames[] = {
 	"_1gtk_1settings_1get_1default",
 	"_1gtk_1socket_1get_1id",
 	"_1gtk_1socket_1new",
+	"_1gtk_1spin_1button_1configure",
 	"_1gtk_1spin_1button_1get_1adjustment",
 	"_1gtk_1spin_1button_1get_1digits",
 	"_1gtk_1spin_1button_1new",
@@ -1197,6 +1266,7 @@ char * OS_nativeFunctionNames[] = {
 	"_1gtk_1widget_1get_1modifier_1style",
 	"_1gtk_1widget_1get_1pango_1context",
 	"_1gtk_1widget_1get_1parent",
+	"_1gtk_1widget_1get_1parent_1window",
 	"_1gtk_1widget_1get_1size_1request",
 	"_1gtk_1widget_1get_1style",
 	"_1gtk_1widget_1get_1toplevel",
@@ -1262,6 +1332,7 @@ char * OS_nativeFunctionNames[] = {
 	"_1gtk_1window_1group_1new",
 	"_1gtk_1window_1group_1remove_1window",
 	"_1gtk_1window_1iconify",
+	"_1gtk_1window_1is_1active",
 	"_1gtk_1window_1list_1toplevels",
 	"_1gtk_1window_1maximize",
 	"_1gtk_1window_1move",
@@ -1323,7 +1394,9 @@ char * OS_nativeFunctionNames[] = {
 	"_1pango_1font_1description_1from_1string",
 	"_1pango_1font_1description_1get_1family",
 	"_1pango_1font_1description_1get_1size",
+	"_1pango_1font_1description_1get_1stretch",
 	"_1pango_1font_1description_1get_1style",
+	"_1pango_1font_1description_1get_1variant",
 	"_1pango_1font_1description_1get_1weight",
 	"_1pango_1font_1description_1new",
 	"_1pango_1font_1description_1set_1family",
@@ -1389,6 +1462,16 @@ char * OS_nativeFunctionNames[] = {
 	"_1pango_1tab_1array_1new",
 	"_1pango_1tab_1array_1set_1tab",
 	"g_1main_1context_1wakeup",
+	"g_1value_1get_1double",
+	"g_1value_1get_1float",
+	"g_1value_1get_1int",
+	"g_1value_1get_1int64",
+	"g_1value_1init",
+	"g_1value_1set_1double",
+	"g_1value_1set_1float",
+	"g_1value_1set_1int",
+	"g_1value_1set_1int64",
+	"g_1value_1unset",
 	"localeconv_1decimal_1point",
 #ifndef JNI64
 	"memmove__ILorg_eclipse_swt_internal_gtk_GInterfaceInfo_2I",
@@ -1451,11 +1534,6 @@ char * OS_nativeFunctionNames[] = {
 	"memmove__JLorg_eclipse_swt_internal_gtk_PangoAttribute_2J",
 #endif
 #ifndef JNI64
-	"memmove__ILorg_eclipse_swt_internal_gtk_XButtonEvent_2I",
-#else
-	"memmove__JLorg_eclipse_swt_internal_gtk_XButtonEvent_2J",
-#endif
-#ifndef JNI64
 	"memmove__ILorg_eclipse_swt_internal_gtk_XClientMessageEvent_2I",
 #else
 	"memmove__JLorg_eclipse_swt_internal_gtk_XClientMessageEvent_2J",
@@ -1531,6 +1609,11 @@ char * OS_nativeFunctionNames[] = {
 	"memmove__Lorg_eclipse_swt_internal_gtk_GdkEventMotion_2JJ",
 #endif
 #ifndef JNI64
+	"memmove__Lorg_eclipse_swt_internal_gtk_GdkEventProperty_2I",
+#else
+	"memmove__Lorg_eclipse_swt_internal_gtk_GdkEventProperty_2J",
+#endif
+#ifndef JNI64
 	"memmove__Lorg_eclipse_swt_internal_gtk_GdkEventScroll_2II",
 #else
 	"memmove__Lorg_eclipse_swt_internal_gtk_GdkEventScroll_2JJ",
@@ -1651,11 +1734,6 @@ char * OS_nativeFunctionNames[] = {
 	"memmove__Lorg_eclipse_swt_internal_gtk_PangoLogAttr_2JJ",
 #endif
 #ifndef JNI64
-	"memmove__Lorg_eclipse_swt_internal_gtk_XButtonEvent_2II",
-#else
-	"memmove__Lorg_eclipse_swt_internal_gtk_XButtonEvent_2JJ",
-#endif
-#ifndef JNI64
 	"memmove__Lorg_eclipse_swt_internal_gtk_XCrossingEvent_2II",
 #else
 	"memmove__Lorg_eclipse_swt_internal_gtk_XCrossingEvent_2JJ",
@@ -1675,6 +1753,7 @@ char * OS_nativeFunctionNames[] = {
 #else
 	"memmove__Lorg_eclipse_swt_internal_gtk_XVisibilityEvent_2JJ",
 #endif
+	"pangoLayoutNewProc_1CALLBACK",
 	"realpath",
 };
 
diff --git a/os_stats.h b/os_stats.h
index 86a696b..aa4c4d3 100644
--- a/os_stats.h
+++ b/os_stats.h
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others. All rights reserved.
+ * Copyright (c) 2000, 2010 IBM Corporation and others. All rights reserved.
  * The contents of this file are made available under the terms
  * of the GNU Lesser General Public License (LGPL) Version 2.1 that
  * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
@@ -47,6 +47,12 @@ typedef enum {
 	GTK_1ACCEL_1LABEL_1GET_1ACCEL_1STRING_FUNC,
 	GTK_1ACCEL_1LABEL_1SET_1ACCEL_1STRING_FUNC,
 	GTK_1ENTRY_1IM_1CONTEXT_FUNC,
+	GTK_1RANGE_1HAS_1STEPPER_1A_FUNC,
+	GTK_1RANGE_1HAS_1STEPPER_1B_FUNC,
+	GTK_1RANGE_1HAS_1STEPPER_1C_FUNC,
+	GTK_1RANGE_1HAS_1STEPPER_1D_FUNC,
+	GTK_1RANGE_1SLIDER_1END_FUNC,
+	GTK_1RANGE_1SLIDER_1START_FUNC,
 	GTK_1SCROLLED_1WINDOW_1HSCROLLBAR_FUNC,
 	GTK_1SCROLLED_1WINDOW_1SCROLLBAR_1SPACING_FUNC,
 	GTK_1SCROLLED_1WINDOW_1VSCROLLBAR_FUNC,
@@ -68,6 +74,12 @@ typedef enum {
 	GTypeQuery_1sizeof_FUNC,
 	G_1OBJECT_1CLASS_1CONSTRUCTOR_FUNC,
 	G_1OBJECT_1CLASS_1SET_1CONSTRUCTOR_FUNC,
+	G_1TYPE_1BOOLEAN_FUNC,
+	G_1TYPE_1DOUBLE_FUNC,
+	G_1TYPE_1FLOAT_FUNC,
+	G_1TYPE_1INT_FUNC,
+	G_1TYPE_1INT64_FUNC,
+	G_1VALUE_1TYPE_FUNC,
 	GdkColor_1sizeof_FUNC,
 	GdkDragContext_1sizeof_FUNC,
 	GdkEventAny_1sizeof_FUNC,
@@ -77,6 +89,7 @@ typedef enum {
 	GdkEventFocus_1sizeof_FUNC,
 	GdkEventKey_1sizeof_FUNC,
 	GdkEventMotion_1sizeof_FUNC,
+	GdkEventProperty_1sizeof_FUNC,
 	GdkEventScroll_1sizeof_FUNC,
 	GdkEventVisibility_1sizeof_FUNC,
 	GdkEventWindowState_1sizeof_FUNC,
@@ -116,7 +129,6 @@ typedef enum {
 	PangoLogAttr_1sizeof_FUNC,
 	PangoRectangle_1sizeof_FUNC,
 	XAnyEvent_1sizeof_FUNC,
-	XButtonEvent_1sizeof_FUNC,
 	XClientMessageEvent_1sizeof_FUNC,
 	XCrossingEvent_1sizeof_FUNC,
 	XEvent_1sizeof_FUNC,
@@ -134,6 +146,8 @@ typedef enum {
 	_1GDK_1ROOT_1PARENT_FUNC,
 	_1GDK_1TYPE_1COLOR_FUNC,
 	_1GDK_1TYPE_1PIXBUF_FUNC,
+	_1GString_1len_FUNC,
+	_1GString_1str_FUNC,
 	_1GTK_1IS_1BUTTON_FUNC,
 	_1GTK_1IS_1CELL_1RENDERER_1PIXBUF_FUNC,
 	_1GTK_1IS_1CELL_1RENDERER_1TEXT_FUNC,
@@ -142,6 +156,7 @@ typedef enum {
 	_1GTK_1IS_1IMAGE_1MENU_1ITEM_FUNC,
 	_1GTK_1IS_1MENU_1ITEM_FUNC,
 	_1GTK_1IS_1PLUG_FUNC,
+	_1GTK_1IS_1SCROLLED_1WINDOW_FUNC,
 	_1GTK_1IS_1SOCKET_FUNC,
 	_1GTK_1IS_1WINDOW_FUNC,
 	_1GTK_1STOCK_1CANCEL_FUNC,
@@ -166,8 +181,6 @@ typedef enum {
 	_1G_1OBJECT_1GET_1CLASS_FUNC,
 	_1G_1OBJECT_1TYPE_FUNC,
 	_1G_1OBJECT_1TYPE_1NAME_FUNC,
-	_1G_1TYPE_1BOOLEAN_FUNC,
-	_1G_1TYPE_1INT_FUNC,
 	_1G_1TYPE_1STRING_FUNC,
 	_1PANGO_1PIXELS_FUNC,
 	_1PANGO_1TYPE_1FONT_1DESCRIPTION_FUNC,
@@ -180,6 +193,7 @@ typedef enum {
 	_1XFlush_FUNC,
 	_1XFree_FUNC,
 	_1XGetSelectionOwner_FUNC,
+	_1XGetWindowProperty_FUNC,
 	_1XInternAtom_FUNC,
 	_1XKeysymToKeycode_FUNC,
 	_1XListProperties_FUNC,
@@ -199,25 +213,58 @@ typedef enum {
 	_1XSetErrorHandler_FUNC,
 	_1XSetIOErrorHandler_FUNC,
 	_1XSetInputFocus_FUNC,
+	_1XSetSelectionOwner_FUNC,
 	_1XSetTransientForHint_FUNC,
 	_1XSynchronize_FUNC,
 	_1XTestFakeButtonEvent_FUNC,
 	_1XTestFakeKeyEvent_FUNC,
 	_1XTestFakeMotionEvent_FUNC,
 	_1XWarpPointer_FUNC,
+	_1access_FUNC,
 	_1atk_1object_1add_1relationship_FUNC,
+	_1atk_1object_1remove_1relationship_FUNC,
 	_1call_FUNC,
 	_1dlclose_FUNC,
 	_1dlopen_FUNC,
 	_1dlsym_FUNC,
+	_1g_1app_1info_1create_1from_1commandline_FUNC,
+	_1g_1app_1info_1get_1all_FUNC,
+	_1g_1app_1info_1get_1default_1for_1type_FUNC,
+	_1g_1app_1info_1get_1executable_FUNC,
+	_1g_1app_1info_1get_1icon_FUNC,
+	_1g_1app_1info_1get_1id_FUNC,
+	_1g_1app_1info_1get_1name_FUNC,
+	_1g_1app_1info_1launch_FUNC,
+	_1g_1app_1info_1launch_1default_1for_1uri_FUNC,
+	_1g_1app_1info_1should_1show_FUNC,
+	_1g_1app_1info_1supports_1uris_FUNC,
 	_1g_1cclosure_1new_FUNC,
 	_1g_1closure_1ref_FUNC,
 	_1g_1closure_1unref_FUNC,
+	_1g_1content_1type_1equals_FUNC,
+	_1g_1content_1type_1get_1mime_1type_FUNC,
+	_1g_1content_1type_1is_1a_FUNC,
+	_1g_1content_1types_1get_1registered_FUNC,
+	_1g_1data_1input_1stream_1new_FUNC,
+	_1g_1data_1input_1stream_1read_1line_FUNC,
+	_1g_1desktop_1app_1info_1new_1from_1filename_FUNC,
+	_1g_1file_1get_1path_FUNC,
+	_1g_1file_1get_1uri_FUNC,
+	_1g_1file_1icon_1get_1file_FUNC,
+	_1g_1file_1info_1get_1content_1type_FUNC,
+	_1g_1file_1info_1get_1modification_1time_FUNC,
+	_1g_1file_1new_1for_1path_FUNC,
+	_1g_1file_1new_1for_1uri_FUNC,
+	_1g_1file_1query_1info_FUNC,
+	_1g_1file_1read_FUNC,
+	_1g_1file_1test_FUNC,
 	_1g_1filename_1from_1uri_FUNC,
 	_1g_1filename_1from_1utf8_FUNC,
 	_1g_1filename_1to_1uri_FUNC,
 	_1g_1filename_1to_1utf8_FUNC,
 	_1g_1free_FUNC,
+	_1g_1icon_1new_1for_1string_FUNC,
+	_1g_1icon_1to_1string_FUNC,
 	_1g_1idle_1add_FUNC,
 	_1g_1list_1append_FUNC,
 	_1g_1list_1data_FUNC,
@@ -278,6 +325,11 @@ typedef enum {
 #else
 	_1g_1object_1set__J_3BZJ_FUNC,
 #endif
+#ifndef JNI64
+	_1g_1object_1set__I_3B_3BI_FUNC,
+#else
+	_1g_1object_1set__J_3B_3BJ_FUNC,
+#endif
 	_1g_1object_1set_1qdata_FUNC,
 	_1g_1object_1unref_FUNC,
 	_1g_1quark_1from_1string_FUNC,
@@ -303,11 +355,17 @@ typedef enum {
 	_1g_1signal_1emit_1by_1name__J_3BJJ_FUNC,
 #endif
 #ifndef JNI64
+	_1g_1signal_1emit_1by_1name__I_3BLorg_eclipse_swt_internal_gtk_GdkRectangle_2_FUNC,
+#else
+	_1g_1signal_1emit_1by_1name__J_3BLorg_eclipse_swt_internal_gtk_GdkRectangle_2_FUNC,
+#endif
+#ifndef JNI64
 	_1g_1signal_1emit_1by_1name__I_3B_3B_FUNC,
 #else
 	_1g_1signal_1emit_1by_1name__J_3B_3B_FUNC,
 #endif
 	_1g_1signal_1handler_1disconnect_FUNC,
+	_1g_1signal_1handler_1find_FUNC,
 	_1g_1signal_1handlers_1block_1matched_FUNC,
 	_1g_1signal_1handlers_1disconnect_1matched_FUNC,
 	_1g_1signal_1handlers_1unblock_1matched_FUNC,
@@ -423,6 +481,7 @@ typedef enum {
 	_1gdk_1keymap_1translate_1keyboard_1state_FUNC,
 	_1gdk_1keyval_1to_1lower_FUNC,
 	_1gdk_1keyval_1to_1unicode_FUNC,
+	_1gdk_1pango_1attr_1embossed_1new_FUNC,
 	_1gdk_1pango_1context_1get_FUNC,
 	_1gdk_1pango_1context_1set_1colormap_FUNC,
 	_1gdk_1pango_1layout_1get_1clip_1region_FUNC,
@@ -505,12 +564,14 @@ typedef enum {
 	_1gdk_1window_1lookup_FUNC,
 	_1gdk_1window_1lower_FUNC,
 	_1gdk_1window_1move_FUNC,
+	_1gdk_1window_1move_1resize_FUNC,
 	_1gdk_1window_1new_FUNC,
 	_1gdk_1window_1process_1all_1updates_FUNC,
 	_1gdk_1window_1process_1updates_FUNC,
 	_1gdk_1window_1raise_FUNC,
 	_1gdk_1window_1remove_1filter_FUNC,
 	_1gdk_1window_1resize_FUNC,
+	_1gdk_1window_1restack_FUNC,
 	_1gdk_1window_1scroll_FUNC,
 	_1gdk_1window_1set_1accept_1focus_FUNC,
 	_1gdk_1window_1set_1back_1pixmap_FUNC,
@@ -572,6 +633,7 @@ typedef enum {
 	_1gtk_1clipboard_1clear_FUNC,
 	_1gtk_1clipboard_1get_FUNC,
 	_1gtk_1clipboard_1set_1with_1data_FUNC,
+	_1gtk_1clipboard_1set_1with_1owner_FUNC,
 	_1gtk_1clipboard_1wait_1for_1contents_FUNC,
 	_1gtk_1color_1selection_1dialog_1new_FUNC,
 	_1gtk_1color_1selection_1get_1current_1color_FUNC,
@@ -633,6 +695,8 @@ typedef enum {
 	_1gtk_1entry_1set_1activates_1default_FUNC,
 	_1gtk_1entry_1set_1alignment_FUNC,
 	_1gtk_1entry_1set_1has_1frame_FUNC,
+	_1gtk_1entry_1set_1icon_1from_1stock_FUNC,
+	_1gtk_1entry_1set_1icon_1sensitive_FUNC,
 	_1gtk_1entry_1set_1invisible_1char_FUNC,
 	_1gtk_1entry_1set_1max_1length_FUNC,
 	_1gtk_1entry_1set_1text_FUNC,
@@ -698,10 +762,14 @@ typedef enum {
 	_1gtk_1hscrollbar_1new_FUNC,
 	_1gtk_1hseparator_1new_FUNC,
 	_1gtk_1icon_1factory_1lookup_1default_FUNC,
+	_1gtk_1icon_1info_1free_FUNC,
+	_1gtk_1icon_1info_1load_1icon_FUNC,
 	_1gtk_1icon_1set_1render_1icon_FUNC,
 	_1gtk_1icon_1source_1free_FUNC,
 	_1gtk_1icon_1source_1new_FUNC,
 	_1gtk_1icon_1source_1set_1pixbuf_FUNC,
+	_1gtk_1icon_1theme_1get_1default_FUNC,
+	_1gtk_1icon_1theme_1lookup_1by_1gicon_FUNC,
 	_1gtk_1im_1context_1filter_1keypress_FUNC,
 	_1gtk_1im_1context_1focus_1in_FUNC,
 	_1gtk_1im_1context_1focus_1out_FUNC,
@@ -934,6 +1002,7 @@ typedef enum {
 	_1gtk_1settings_1get_1default_FUNC,
 	_1gtk_1socket_1get_1id_FUNC,
 	_1gtk_1socket_1new_FUNC,
+	_1gtk_1spin_1button_1configure_FUNC,
 	_1gtk_1spin_1button_1get_1adjustment_FUNC,
 	_1gtk_1spin_1button_1get_1digits_FUNC,
 	_1gtk_1spin_1button_1new_FUNC,
@@ -1205,6 +1274,7 @@ typedef enum {
 	_1gtk_1widget_1get_1modifier_1style_FUNC,
 	_1gtk_1widget_1get_1pango_1context_FUNC,
 	_1gtk_1widget_1get_1parent_FUNC,
+	_1gtk_1widget_1get_1parent_1window_FUNC,
 	_1gtk_1widget_1get_1size_1request_FUNC,
 	_1gtk_1widget_1get_1style_FUNC,
 	_1gtk_1widget_1get_1toplevel_FUNC,
@@ -1270,6 +1340,7 @@ typedef enum {
 	_1gtk_1window_1group_1new_FUNC,
 	_1gtk_1window_1group_1remove_1window_FUNC,
 	_1gtk_1window_1iconify_FUNC,
+	_1gtk_1window_1is_1active_FUNC,
 	_1gtk_1window_1list_1toplevels_FUNC,
 	_1gtk_1window_1maximize_FUNC,
 	_1gtk_1window_1move_FUNC,
@@ -1331,7 +1402,9 @@ typedef enum {
 	_1pango_1font_1description_1from_1string_FUNC,
 	_1pango_1font_1description_1get_1family_FUNC,
 	_1pango_1font_1description_1get_1size_FUNC,
+	_1pango_1font_1description_1get_1stretch_FUNC,
 	_1pango_1font_1description_1get_1style_FUNC,
+	_1pango_1font_1description_1get_1variant_FUNC,
 	_1pango_1font_1description_1get_1weight_FUNC,
 	_1pango_1font_1description_1new_FUNC,
 	_1pango_1font_1description_1set_1family_FUNC,
@@ -1397,6 +1470,16 @@ typedef enum {
 	_1pango_1tab_1array_1new_FUNC,
 	_1pango_1tab_1array_1set_1tab_FUNC,
 	g_1main_1context_1wakeup_FUNC,
+	g_1value_1get_1double_FUNC,
+	g_1value_1get_1float_FUNC,
+	g_1value_1get_1int_FUNC,
+	g_1value_1get_1int64_FUNC,
+	g_1value_1init_FUNC,
+	g_1value_1set_1double_FUNC,
+	g_1value_1set_1float_FUNC,
+	g_1value_1set_1int_FUNC,
+	g_1value_1set_1int64_FUNC,
+	g_1value_1unset_FUNC,
 	localeconv_1decimal_1point_FUNC,
 #ifndef JNI64
 	memmove__ILorg_eclipse_swt_internal_gtk_GInterfaceInfo_2I_FUNC,
@@ -1459,11 +1542,6 @@ typedef enum {
 	memmove__JLorg_eclipse_swt_internal_gtk_PangoAttribute_2J_FUNC,
 #endif
 #ifndef JNI64
-	memmove__ILorg_eclipse_swt_internal_gtk_XButtonEvent_2I_FUNC,
-#else
-	memmove__JLorg_eclipse_swt_internal_gtk_XButtonEvent_2J_FUNC,
-#endif
-#ifndef JNI64
 	memmove__ILorg_eclipse_swt_internal_gtk_XClientMessageEvent_2I_FUNC,
 #else
 	memmove__JLorg_eclipse_swt_internal_gtk_XClientMessageEvent_2J_FUNC,
@@ -1539,6 +1617,11 @@ typedef enum {
 	memmove__Lorg_eclipse_swt_internal_gtk_GdkEventMotion_2JJ_FUNC,
 #endif
 #ifndef JNI64
+	memmove__Lorg_eclipse_swt_internal_gtk_GdkEventProperty_2I_FUNC,
+#else
+	memmove__Lorg_eclipse_swt_internal_gtk_GdkEventProperty_2J_FUNC,
+#endif
+#ifndef JNI64
 	memmove__Lorg_eclipse_swt_internal_gtk_GdkEventScroll_2II_FUNC,
 #else
 	memmove__Lorg_eclipse_swt_internal_gtk_GdkEventScroll_2JJ_FUNC,
@@ -1659,11 +1742,6 @@ typedef enum {
 	memmove__Lorg_eclipse_swt_internal_gtk_PangoLogAttr_2JJ_FUNC,
 #endif
 #ifndef JNI64
-	memmove__Lorg_eclipse_swt_internal_gtk_XButtonEvent_2II_FUNC,
-#else
-	memmove__Lorg_eclipse_swt_internal_gtk_XButtonEvent_2JJ_FUNC,
-#endif
-#ifndef JNI64
 	memmove__Lorg_eclipse_swt_internal_gtk_XCrossingEvent_2II_FUNC,
 #else
 	memmove__Lorg_eclipse_swt_internal_gtk_XCrossingEvent_2JJ_FUNC,
@@ -1683,5 +1761,6 @@ typedef enum {
 #else
 	memmove__Lorg_eclipse_swt_internal_gtk_XVisibilityEvent_2JJ_FUNC,
 #endif
+	pangoLayoutNewProc_1CALLBACK_FUNC,
 	realpath_FUNC,
 } OS_FUNCS;
diff --git a/os_structs.c b/os_structs.c
index 5ef3c53..8c72e96 100644
--- a/os_structs.c
+++ b/os_structs.c
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others. All rights reserved.
+ * Copyright (c) 2000, 2010 IBM Corporation and others. All rights reserved.
  * The contents of this file are made available under the terms
  * of the GNU Lesser General Public License (LGPL) Version 2.1 that
  * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
@@ -711,6 +711,52 @@ void setGdkEventMotionFields(JNIEnv *env, jobject lpObject, GdkEventMotion *lpSt
 }
 #endif
 
+#ifndef NO_GdkEventProperty
+typedef struct GdkEventProperty_FID_CACHE {
+	int cached;
+	jclass clazz;
+	jfieldID window, send_event, atom, time, state;
+} GdkEventProperty_FID_CACHE;
+
+GdkEventProperty_FID_CACHE GdkEventPropertyFc;
+
+void cacheGdkEventPropertyFields(JNIEnv *env, jobject lpObject)
+{
+	if (GdkEventPropertyFc.cached) return;
+	cacheGdkEventFields(env, lpObject);
+	GdkEventPropertyFc.clazz = (*env)->GetObjectClass(env, lpObject);
+	GdkEventPropertyFc.window = (*env)->GetFieldID(env, GdkEventPropertyFc.clazz, "window", I_J);
+	GdkEventPropertyFc.send_event = (*env)->GetFieldID(env, GdkEventPropertyFc.clazz, "send_event", "B");
+	GdkEventPropertyFc.atom = (*env)->GetFieldID(env, GdkEventPropertyFc.clazz, "atom", I_J);
+	GdkEventPropertyFc.time = (*env)->GetFieldID(env, GdkEventPropertyFc.clazz, "time", "I");
+	GdkEventPropertyFc.state = (*env)->GetFieldID(env, GdkEventPropertyFc.clazz, "state", "I");
+	GdkEventPropertyFc.cached = 1;
+}
+
+GdkEventProperty *getGdkEventPropertyFields(JNIEnv *env, jobject lpObject, GdkEventProperty *lpStruct)
+{
+	if (!GdkEventPropertyFc.cached) cacheGdkEventPropertyFields(env, lpObject);
+	getGdkEventFields(env, lpObject, (GdkEvent *)lpStruct);
+	lpStruct->window = (GdkWindow *)(*env)->GetIntLongField(env, lpObject, GdkEventPropertyFc.window);
+	lpStruct->send_event = (gint8)(*env)->GetByteField(env, lpObject, GdkEventPropertyFc.send_event);
+	lpStruct->atom = (GdkAtom)(*env)->GetIntLongField(env, lpObject, GdkEventPropertyFc.atom);
+	lpStruct->time = (guint32)(*env)->GetIntField(env, lpObject, GdkEventPropertyFc.time);
+	lpStruct->state = (guint)(*env)->GetIntField(env, lpObject, GdkEventPropertyFc.state);
+	return lpStruct;
+}
+
+void setGdkEventPropertyFields(JNIEnv *env, jobject lpObject, GdkEventProperty *lpStruct)
+{
+	if (!GdkEventPropertyFc.cached) cacheGdkEventPropertyFields(env, lpObject);
+	setGdkEventFields(env, lpObject, (GdkEvent *)lpStruct);
+	(*env)->SetIntLongField(env, lpObject, GdkEventPropertyFc.window, (jintLong)lpStruct->window);
+	(*env)->SetByteField(env, lpObject, GdkEventPropertyFc.send_event, (jbyte)lpStruct->send_event);
+	(*env)->SetIntLongField(env, lpObject, GdkEventPropertyFc.atom, (jintLong)lpStruct->atom);
+	(*env)->SetIntField(env, lpObject, GdkEventPropertyFc.time, (jint)lpStruct->time);
+	(*env)->SetIntField(env, lpObject, GdkEventPropertyFc.state, (jint)lpStruct->state);
+}
+#endif
+
 #ifndef NO_GdkEventScroll
 typedef struct GdkEventScroll_FID_CACHE {
 	int cached;
@@ -2371,67 +2417,6 @@ void setXAnyEventFields(JNIEnv *env, jobject lpObject, XAnyEvent *lpStruct)
 }
 #endif
 
-#ifndef NO_XButtonEvent
-typedef struct XButtonEvent_FID_CACHE {
-	int cached;
-	jclass clazz;
-	jfieldID root, subwindow, time, x, y, x_root, y_root, state, button, same_screen;
-} XButtonEvent_FID_CACHE;
-
-XButtonEvent_FID_CACHE XButtonEventFc;
-
-void cacheXButtonEventFields(JNIEnv *env, jobject lpObject)
-{
-	if (XButtonEventFc.cached) return;
-	cacheXAnyEventFields(env, lpObject);
-	XButtonEventFc.clazz = (*env)->GetObjectClass(env, lpObject);
-	XButtonEventFc.root = (*env)->GetFieldID(env, XButtonEventFc.clazz, "root", "I");
-	XButtonEventFc.subwindow = (*env)->GetFieldID(env, XButtonEventFc.clazz, "subwindow", "I");
-	XButtonEventFc.time = (*env)->GetFieldID(env, XButtonEventFc.clazz, "time", "I");
-	XButtonEventFc.x = (*env)->GetFieldID(env, XButtonEventFc.clazz, "x", "I");
-	XButtonEventFc.y = (*env)->GetFieldID(env, XButtonEventFc.clazz, "y", "I");
-	XButtonEventFc.x_root = (*env)->GetFieldID(env, XButtonEventFc.clazz, "x_root", "I");
-	XButtonEventFc.y_root = (*env)->GetFieldID(env, XButtonEventFc.clazz, "y_root", "I");
-	XButtonEventFc.state = (*env)->GetFieldID(env, XButtonEventFc.clazz, "state", "I");
-	XButtonEventFc.button = (*env)->GetFieldID(env, XButtonEventFc.clazz, "button", "I");
-	XButtonEventFc.same_screen = (*env)->GetFieldID(env, XButtonEventFc.clazz, "same_screen", "I");
-	XButtonEventFc.cached = 1;
-}
-
-XButtonEvent *getXButtonEventFields(JNIEnv *env, jobject lpObject, XButtonEvent *lpStruct)
-{
-	if (!XButtonEventFc.cached) cacheXButtonEventFields(env, lpObject);
-	getXAnyEventFields(env, lpObject, (XAnyEvent *)lpStruct);
-	lpStruct->root = (*env)->GetIntField(env, lpObject, XButtonEventFc.root);
-	lpStruct->subwindow = (*env)->GetIntField(env, lpObject, XButtonEventFc.subwindow);
-	lpStruct->time = (*env)->GetIntField(env, lpObject, XButtonEventFc.time);
-	lpStruct->x = (*env)->GetIntField(env, lpObject, XButtonEventFc.x);
-	lpStruct->y = (*env)->GetIntField(env, lpObject, XButtonEventFc.y);
-	lpStruct->x_root = (*env)->GetIntField(env, lpObject, XButtonEventFc.x_root);
-	lpStruct->y_root = (*env)->GetIntField(env, lpObject, XButtonEventFc.y_root);
-	lpStruct->state = (*env)->GetIntField(env, lpObject, XButtonEventFc.state);
-	lpStruct->button = (*env)->GetIntField(env, lpObject, XButtonEventFc.button);
-	lpStruct->same_screen = (*env)->GetIntField(env, lpObject, XButtonEventFc.same_screen);
-	return lpStruct;
-}
-
-void setXButtonEventFields(JNIEnv *env, jobject lpObject, XButtonEvent *lpStruct)
-{
-	if (!XButtonEventFc.cached) cacheXButtonEventFields(env, lpObject);
-	setXAnyEventFields(env, lpObject, (XAnyEvent *)lpStruct);
-	(*env)->SetIntField(env, lpObject, XButtonEventFc.root, (jint)lpStruct->root);
-	(*env)->SetIntField(env, lpObject, XButtonEventFc.subwindow, (jint)lpStruct->subwindow);
-	(*env)->SetIntField(env, lpObject, XButtonEventFc.time, (jint)lpStruct->time);
-	(*env)->SetIntField(env, lpObject, XButtonEventFc.x, (jint)lpStruct->x);
-	(*env)->SetIntField(env, lpObject, XButtonEventFc.y, (jint)lpStruct->y);
-	(*env)->SetIntField(env, lpObject, XButtonEventFc.x_root, (jint)lpStruct->x_root);
-	(*env)->SetIntField(env, lpObject, XButtonEventFc.y_root, (jint)lpStruct->y_root);
-	(*env)->SetIntField(env, lpObject, XButtonEventFc.state, (jint)lpStruct->state);
-	(*env)->SetIntField(env, lpObject, XButtonEventFc.button, (jint)lpStruct->button);
-	(*env)->SetIntField(env, lpObject, XButtonEventFc.same_screen, (jint)lpStruct->same_screen);
-}
-#endif
-
 #ifndef NO_XClientMessageEvent
 typedef struct XClientMessageEvent_FID_CACHE {
 	int cached;
diff --git a/os_structs.h b/os_structs.h
index 4c1a302..6435b83 100644
--- a/os_structs.h
+++ b/os_structs.h
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others. All rights reserved.
+ * Copyright (c) 2000, 2010 IBM Corporation and others. All rights reserved.
  * The contents of this file are made available under the terms
  * of the GNU Lesser General Public License (LGPL) Version 2.1 that
  * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
@@ -183,6 +183,18 @@ void setGdkEventMotionFields(JNIEnv *env, jobject lpObject, GdkEventMotion *lpSt
 #define GdkEventMotion_sizeof() 0
 #endif
 
+#ifndef NO_GdkEventProperty
+void cacheGdkEventPropertyFields(JNIEnv *env, jobject lpObject);
+GdkEventProperty *getGdkEventPropertyFields(JNIEnv *env, jobject lpObject, GdkEventProperty *lpStruct);
+void setGdkEventPropertyFields(JNIEnv *env, jobject lpObject, GdkEventProperty *lpStruct);
+#define GdkEventProperty_sizeof() sizeof(GdkEventProperty)
+#else
+#define cacheGdkEventPropertyFields(a,b)
+#define getGdkEventPropertyFields(a,b,c) NULL
+#define setGdkEventPropertyFields(a,b,c)
+#define GdkEventProperty_sizeof() 0
+#endif
+
 #ifndef NO_GdkEventScroll
 void cacheGdkEventScrollFields(JNIEnv *env, jobject lpObject);
 GdkEventScroll *getGdkEventScrollFields(JNIEnv *env, jobject lpObject, GdkEventScroll *lpStruct);
@@ -555,18 +567,6 @@ void setXAnyEventFields(JNIEnv *env, jobject lpObject, XAnyEvent *lpStruct);
 #define XAnyEvent_sizeof() 0
 #endif
 
-#ifndef NO_XButtonEvent
-void cacheXButtonEventFields(JNIEnv *env, jobject lpObject);
-XButtonEvent *getXButtonEventFields(JNIEnv *env, jobject lpObject, XButtonEvent *lpStruct);
-void setXButtonEventFields(JNIEnv *env, jobject lpObject, XButtonEvent *lpStruct);
-#define XButtonEvent_sizeof() sizeof(XButtonEvent)
-#else
-#define cacheXButtonEventFields(a,b)
-#define getXButtonEventFields(a,b,c) NULL
-#define setXButtonEventFields(a,b,c)
-#define XButtonEvent_sizeof() 0
-#endif
-
 #ifndef NO_XClientMessageEvent
 void cacheXClientMessageEventFields(JNIEnv *env, jobject lpObject);
 XClientMessageEvent *getXClientMessageEventFields(JNIEnv *env, jobject lpObject, XClientMessageEvent *lpStruct);
diff --git a/swt_xpcom.rc b/swt_xpcom.rc
index 8293e74..f5598d4 100644
--- a/swt_xpcom.rc
+++ b/swt_xpcom.rc
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
diff --git a/version.txt b/version.txt
index a33f388..5a7cbe9 100644
--- a/version.txt
+++ b/version.txt
@@ -1 +1 @@
-version 3.555
\ No newline at end of file
+version 3.655
\ No newline at end of file
diff --git a/webkitgtk.c b/webkitgtk.c
new file mode 100644
index 0000000..1d6037a
--- /dev/null
+++ b/webkitgtk.c
@@ -0,0 +1,1232 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 IBM Corporation and others. All rights reserved.
+ * The contents of this file are made available under the terms
+ * of the GNU Lesser General Public License (LGPL) Version 2.1 that
+ * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
+ * available at http://www.gnu.org/licenses/lgpl.html.  If the version
+ * of the LGPL at http://www.gnu.org is different to the version of
+ * the LGPL accompanying this distribution and there is any conflict
+ * between the two license versions, the terms of the LGPL accompanying
+ * this distribution shall govern.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+#include "swt.h"
+#include "webkitgtk_structs.h"
+#include "webkitgtk_stats.h"
+
+#define WebKitGTK_NATIVE(func) Java_org_eclipse_swt_internal_webkit_WebKitGTK_##func
+
+#ifndef NO_JSClassDefinition_1sizeof
+JNIEXPORT jint JNICALL WebKitGTK_NATIVE(JSClassDefinition_1sizeof)
+	(JNIEnv *env, jclass that)
+{
+	jint rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, JSClassDefinition_1sizeof_FUNC);
+	rc = (jint)JSClassDefinition_sizeof();
+	WebKitGTK_NATIVE_EXIT(env, that, JSClassDefinition_1sizeof_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1JSClassCreate
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1JSClassCreate)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1JSClassCreate_FUNC);
+	rc = (jintLong)JSClassCreate((const JSClassDefinition*)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1JSClassCreate_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1JSContextGetGlobalObject
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1JSContextGetGlobalObject)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1JSContextGetGlobalObject_FUNC);
+	rc = (jintLong)JSContextGetGlobalObject((JSContextRef)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1JSContextGetGlobalObject_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1JSEvaluateScript
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1JSEvaluateScript)
+	(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1, jintLong arg2, jintLong arg3, jint arg4, jintLongArray arg5)
+{
+	jintLong *lparg5=NULL;
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1JSEvaluateScript_FUNC);
+	if (arg5) if ((lparg5 = (*env)->GetIntLongArrayElements(env, arg5, NULL)) == NULL) goto fail;
+	rc = (jintLong)JSEvaluateScript((JSContextRef)arg0, (JSStringRef)arg1, (JSObjectRef)arg2, (JSStringRef)arg3, arg4, (JSValueRef *)lparg5);
+fail:
+	if (arg5 && lparg5) (*env)->ReleaseIntLongArrayElements(env, arg5, lparg5, 0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1JSEvaluateScript_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1JSObjectGetPrivate
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1JSObjectGetPrivate)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1JSObjectGetPrivate_FUNC);
+	rc = (jintLong)JSObjectGetPrivate((JSObjectRef)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1JSObjectGetPrivate_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1JSObjectGetProperty
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1JSObjectGetProperty)
+	(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1, jintLong arg2, jintLongArray arg3)
+{
+	jintLong *lparg3=NULL;
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1JSObjectGetProperty_FUNC);
+	if (arg3) if ((lparg3 = (*env)->GetIntLongArrayElements(env, arg3, NULL)) == NULL) goto fail;
+	rc = (jintLong)JSObjectGetProperty((JSContextRef)arg0, (JSObjectRef)arg1, (JSStringRef)arg2, (JSValueRef*)lparg3);
+fail:
+	if (arg3 && lparg3) (*env)->ReleaseIntLongArrayElements(env, arg3, lparg3, 0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1JSObjectGetProperty_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1JSObjectGetPropertyAtIndex
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1JSObjectGetPropertyAtIndex)
+	(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1, jint arg2, jintLongArray arg3)
+{
+	jintLong *lparg3=NULL;
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1JSObjectGetPropertyAtIndex_FUNC);
+	if (arg3) if ((lparg3 = (*env)->GetIntLongArrayElements(env, arg3, NULL)) == NULL) goto fail;
+	rc = (jintLong)JSObjectGetPropertyAtIndex((JSContextRef)arg0, (JSObjectRef)arg1, (unsigned)arg2, (JSValueRef*)lparg3);
+fail:
+	if (arg3 && lparg3) (*env)->ReleaseIntLongArrayElements(env, arg3, lparg3, 0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1JSObjectGetPropertyAtIndex_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1JSObjectMake
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1JSObjectMake)
+	(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1, jintLong arg2)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1JSObjectMake_FUNC);
+	rc = (jintLong)JSObjectMake((JSContextRef)arg0, (JSClassRef)arg1, (void *)arg2);
+	WebKitGTK_NATIVE_EXIT(env, that, _1JSObjectMake_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1JSObjectMakeArray
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1JSObjectMakeArray)
+	(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1, jintLongArray arg2, jintLongArray arg3)
+{
+	jintLong *lparg2=NULL;
+	jintLong *lparg3=NULL;
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1JSObjectMakeArray_FUNC);
+	if (arg2) if ((lparg2 = (*env)->GetIntLongArrayElements(env, arg2, NULL)) == NULL) goto fail;
+	if (arg3) if ((lparg3 = (*env)->GetIntLongArrayElements(env, arg3, NULL)) == NULL) goto fail;
+	rc = (jintLong)JSObjectMakeArray((JSContextRef)arg0, (size_t)arg1, (const struct OpaqueJSValue * const*)lparg2, (JSValueRef*)lparg3);
+fail:
+	if (arg3 && lparg3) (*env)->ReleaseIntLongArrayElements(env, arg3, lparg3, 0);
+	if (arg2 && lparg2) (*env)->ReleaseIntLongArrayElements(env, arg2, lparg2, 0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1JSObjectMakeArray_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1JSObjectMakeFunctionWithCallback
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1JSObjectMakeFunctionWithCallback)
+	(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1, jintLong arg2)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1JSObjectMakeFunctionWithCallback_FUNC);
+	rc = (jintLong)JSObjectMakeFunctionWithCallback((JSContextRef)arg0, (JSStringRef)arg1, (JSObjectCallAsFunctionCallback)arg2);
+	WebKitGTK_NATIVE_EXIT(env, that, _1JSObjectMakeFunctionWithCallback_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1JSObjectSetProperty
+JNIEXPORT void JNICALL WebKitGTK_NATIVE(_1JSObjectSetProperty)
+	(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1, jintLong arg2, jintLong arg3, jint arg4, jintLongArray arg5)
+{
+	jintLong *lparg5=NULL;
+	WebKitGTK_NATIVE_ENTER(env, that, _1JSObjectSetProperty_FUNC);
+	if (arg5) if ((lparg5 = (*env)->GetIntLongArrayElements(env, arg5, NULL)) == NULL) goto fail;
+	JSObjectSetProperty((JSContextRef)arg0, (JSObjectRef)arg1, (JSStringRef)arg2, (JSValueRef)arg3, (JSPropertyAttributes)arg4, (JSValueRef *)lparg5);
+fail:
+	if (arg5 && lparg5) (*env)->ReleaseIntLongArrayElements(env, arg5, lparg5, 0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1JSObjectSetProperty_FUNC);
+}
+#endif
+
+#ifndef NO__1JSStringCreateWithUTF8CString
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1JSStringCreateWithUTF8CString)
+	(JNIEnv *env, jclass that, jbyteArray arg0)
+{
+	jbyte *lparg0=NULL;
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1JSStringCreateWithUTF8CString_FUNC);
+	if (arg0) if ((lparg0 = (*env)->GetByteArrayElements(env, arg0, NULL)) == NULL) goto fail;
+	rc = (jintLong)JSStringCreateWithUTF8CString((const char *)lparg0);
+fail:
+	if (arg0 && lparg0) (*env)->ReleaseByteArrayElements(env, arg0, lparg0, 0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1JSStringCreateWithUTF8CString_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1JSStringGetLength
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1JSStringGetLength)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1JSStringGetLength_FUNC);
+	rc = (jintLong)JSStringGetLength((JSStringRef)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1JSStringGetLength_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1JSStringGetMaximumUTF8CStringSize
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1JSStringGetMaximumUTF8CStringSize)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1JSStringGetMaximumUTF8CStringSize_FUNC);
+	rc = (jintLong)JSStringGetMaximumUTF8CStringSize((JSStringRef)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1JSStringGetMaximumUTF8CStringSize_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1JSStringGetUTF8CString
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1JSStringGetUTF8CString)
+	(JNIEnv *env, jclass that, jintLong arg0, jbyteArray arg1, jintLong arg2)
+{
+	jbyte *lparg1=NULL;
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1JSStringGetUTF8CString_FUNC);
+	if (arg1) if ((lparg1 = (*env)->GetByteArrayElements(env, arg1, NULL)) == NULL) goto fail;
+	rc = (jintLong)JSStringGetUTF8CString((JSStringRef)arg0, (char *)lparg1, (size_t)arg2);
+fail:
+	if (arg1 && lparg1) (*env)->ReleaseByteArrayElements(env, arg1, lparg1, 0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1JSStringGetUTF8CString_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1JSStringIsEqualToUTF8CString
+JNIEXPORT jint JNICALL WebKitGTK_NATIVE(_1JSStringIsEqualToUTF8CString)
+	(JNIEnv *env, jclass that, jintLong arg0, jbyteArray arg1)
+{
+	jbyte *lparg1=NULL;
+	jint rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1JSStringIsEqualToUTF8CString_FUNC);
+	if (arg1) if ((lparg1 = (*env)->GetByteArrayElements(env, arg1, NULL)) == NULL) goto fail;
+	rc = (jint)JSStringIsEqualToUTF8CString((JSStringRef)arg0, (const char *)lparg1);
+fail:
+	if (arg1 && lparg1) (*env)->ReleaseByteArrayElements(env, arg1, lparg1, 0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1JSStringIsEqualToUTF8CString_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1JSStringRelease
+JNIEXPORT void JNICALL WebKitGTK_NATIVE(_1JSStringRelease)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	WebKitGTK_NATIVE_ENTER(env, that, _1JSStringRelease_FUNC);
+	JSStringRelease((JSStringRef)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1JSStringRelease_FUNC);
+}
+#endif
+
+#ifndef NO__1JSValueGetType
+JNIEXPORT jint JNICALL WebKitGTK_NATIVE(_1JSValueGetType)
+	(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1)
+{
+	jint rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1JSValueGetType_FUNC);
+	rc = (jint)JSValueGetType((JSContextRef)arg0, (JSValueRef)arg1);
+	WebKitGTK_NATIVE_EXIT(env, that, _1JSValueGetType_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1JSValueIsObjectOfClass
+JNIEXPORT jint JNICALL WebKitGTK_NATIVE(_1JSValueIsObjectOfClass)
+	(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1, jintLong arg2)
+{
+	jint rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1JSValueIsObjectOfClass_FUNC);
+	rc = (jint)JSValueIsObjectOfClass((JSContextRef)arg0, (JSValueRef)arg1, (JSClassRef)arg2);
+	WebKitGTK_NATIVE_EXIT(env, that, _1JSValueIsObjectOfClass_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1JSValueMakeBoolean
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1JSValueMakeBoolean)
+	(JNIEnv *env, jclass that, jintLong arg0, jint arg1)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1JSValueMakeBoolean_FUNC);
+	rc = (jintLong)JSValueMakeBoolean((JSContextRef)arg0, (bool)arg1);
+	WebKitGTK_NATIVE_EXIT(env, that, _1JSValueMakeBoolean_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1JSValueMakeNumber
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1JSValueMakeNumber)
+	(JNIEnv *env, jclass that, jintLong arg0, jdouble arg1)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1JSValueMakeNumber_FUNC);
+	rc = (jintLong)JSValueMakeNumber((JSContextRef)arg0, (double)arg1);
+	WebKitGTK_NATIVE_EXIT(env, that, _1JSValueMakeNumber_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1JSValueMakeString
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1JSValueMakeString)
+	(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1JSValueMakeString_FUNC);
+	rc = (jintLong)JSValueMakeString((JSContextRef)arg0, (JSStringRef)arg1);
+	WebKitGTK_NATIVE_EXIT(env, that, _1JSValueMakeString_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1JSValueMakeUndefined
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1JSValueMakeUndefined)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1JSValueMakeUndefined_FUNC);
+	rc = (jintLong)JSValueMakeUndefined((JSContextRef)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1JSValueMakeUndefined_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1JSValueToBoolean
+JNIEXPORT jint JNICALL WebKitGTK_NATIVE(_1JSValueToBoolean)
+	(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1)
+{
+	jint rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1JSValueToBoolean_FUNC);
+	rc = (jint)JSValueToBoolean((JSContextRef)arg0, (JSValueRef)arg1);
+	WebKitGTK_NATIVE_EXIT(env, that, _1JSValueToBoolean_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1JSValueToNumber
+JNIEXPORT jdouble JNICALL WebKitGTK_NATIVE(_1JSValueToNumber)
+	(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1, jintLongArray arg2)
+{
+	jintLong *lparg2=NULL;
+	jdouble rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1JSValueToNumber_FUNC);
+	if (arg2) if ((lparg2 = (*env)->GetIntLongArrayElements(env, arg2, NULL)) == NULL) goto fail;
+	rc = (jdouble)JSValueToNumber((JSContextRef)arg0, (JSValueRef)arg1, (JSValueRef*)lparg2);
+fail:
+	if (arg2 && lparg2) (*env)->ReleaseIntLongArrayElements(env, arg2, lparg2, 0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1JSValueToNumber_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1JSValueToStringCopy
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1JSValueToStringCopy)
+	(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1, jintLongArray arg2)
+{
+	jintLong *lparg2=NULL;
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1JSValueToStringCopy_FUNC);
+	if (arg2) if ((lparg2 = (*env)->GetIntLongArrayElements(env, arg2, NULL)) == NULL) goto fail;
+	rc = (jintLong)JSValueToStringCopy((JSContextRef)arg0, (JSValueRef)arg1, (JSValueRef*)lparg2);
+fail:
+	if (arg2 && lparg2) (*env)->ReleaseIntLongArrayElements(env, arg2, lparg2, 0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1JSValueToStringCopy_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1SOUP_1IS_1SESSION
+JNIEXPORT jboolean JNICALL WebKitGTK_NATIVE(_1SOUP_1IS_1SESSION)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jboolean rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1SOUP_1IS_1SESSION_FUNC);
+	rc = (jboolean)SOUP_IS_SESSION(arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1SOUP_1IS_1SESSION_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1SoupCookie_1expires
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1SoupCookie_1expires)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1SoupCookie_1expires_FUNC);
+	rc = (jintLong)((SoupCookie *)arg0)->expires;
+	WebKitGTK_NATIVE_EXIT(env, that, _1SoupCookie_1expires_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1SoupMessage_1method
+JNIEXPORT void JNICALL WebKitGTK_NATIVE(_1SoupMessage_1method)
+	(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1)
+{
+	WebKitGTK_NATIVE_ENTER(env, that, _1SoupMessage_1method_FUNC);
+	((SoupMessage *)arg0)->method = ((const char *)arg1);
+	WebKitGTK_NATIVE_EXIT(env, that, _1SoupMessage_1method_FUNC);
+}
+#endif
+
+#ifndef NO__1SoupMessage_1request_1body
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1SoupMessage_1request_1body)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1SoupMessage_1request_1body_FUNC);
+	rc = (jintLong)((SoupMessage *)arg0)->request_body;
+	WebKitGTK_NATIVE_EXIT(env, that, _1SoupMessage_1request_1body_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1SoupMessage_1request_1headers
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1SoupMessage_1request_1headers)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1SoupMessage_1request_1headers_FUNC);
+	rc = (jintLong)((SoupMessage *)arg0)->request_headers;
+	WebKitGTK_NATIVE_EXIT(env, that, _1SoupMessage_1request_1headers_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1WEBKIT_1IS_1WEB_1FRAME
+JNIEXPORT jboolean JNICALL WebKitGTK_NATIVE(_1WEBKIT_1IS_1WEB_1FRAME)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jboolean rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1WEBKIT_1IS_1WEB_1FRAME_FUNC);
+	rc = (jboolean)WEBKIT_IS_WEB_FRAME(arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1WEBKIT_1IS_1WEB_1FRAME_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1soup_1auth_1authenticate
+JNIEXPORT void JNICALL WebKitGTK_NATIVE(_1soup_1auth_1authenticate)
+	(JNIEnv *env, jclass that, jintLong arg0, jbyteArray arg1, jbyteArray arg2)
+{
+	jbyte *lparg1=NULL;
+	jbyte *lparg2=NULL;
+	WebKitGTK_NATIVE_ENTER(env, that, _1soup_1auth_1authenticate_FUNC);
+	if (arg1) if ((lparg1 = (*env)->GetByteArrayElements(env, arg1, NULL)) == NULL) goto fail;
+	if (arg2) if ((lparg2 = (*env)->GetByteArrayElements(env, arg2, NULL)) == NULL) goto fail;
+	soup_auth_authenticate((SoupAuth *)arg0, (const char *)lparg1, (const char *)lparg2);
+fail:
+	if (arg2 && lparg2) (*env)->ReleaseByteArrayElements(env, arg2, lparg2, 0);
+	if (arg1 && lparg1) (*env)->ReleaseByteArrayElements(env, arg1, lparg1, 0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1soup_1auth_1authenticate_FUNC);
+}
+#endif
+
+#ifndef NO__1soup_1auth_1get_1host
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1soup_1auth_1get_1host)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1soup_1auth_1get_1host_FUNC);
+	rc = (jintLong)soup_auth_get_host((SoupAuth *)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1soup_1auth_1get_1host_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1soup_1auth_1get_1scheme_1name
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1soup_1auth_1get_1scheme_1name)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1soup_1auth_1get_1scheme_1name_FUNC);
+	rc = (jintLong)soup_auth_get_scheme_name((SoupAuth *)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1soup_1auth_1get_1scheme_1name_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1soup_1cookie_1jar_1add_1cookie
+JNIEXPORT void JNICALL WebKitGTK_NATIVE(_1soup_1cookie_1jar_1add_1cookie)
+	(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1)
+{
+	WebKitGTK_NATIVE_ENTER(env, that, _1soup_1cookie_1jar_1add_1cookie_FUNC);
+	soup_cookie_jar_add_cookie((SoupCookieJar *)arg0, (SoupCookie *)arg1);
+	WebKitGTK_NATIVE_EXIT(env, that, _1soup_1cookie_1jar_1add_1cookie_FUNC);
+}
+#endif
+
+#ifndef NO__1soup_1cookie_1jar_1all_1cookies
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1soup_1cookie_1jar_1all_1cookies)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1soup_1cookie_1jar_1all_1cookies_FUNC);
+	rc = (jintLong)soup_cookie_jar_all_cookies((SoupCookieJar *)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1soup_1cookie_1jar_1all_1cookies_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1soup_1cookie_1jar_1delete_1cookie
+JNIEXPORT void JNICALL WebKitGTK_NATIVE(_1soup_1cookie_1jar_1delete_1cookie)
+	(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1)
+{
+	WebKitGTK_NATIVE_ENTER(env, that, _1soup_1cookie_1jar_1delete_1cookie_FUNC);
+	soup_cookie_jar_delete_cookie((SoupCookieJar *)arg0, (SoupCookie *)arg1);
+	WebKitGTK_NATIVE_EXIT(env, that, _1soup_1cookie_1jar_1delete_1cookie_FUNC);
+}
+#endif
+
+#ifndef NO__1soup_1cookie_1jar_1get_1cookies
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1soup_1cookie_1jar_1get_1cookies)
+	(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1, jint arg2)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1soup_1cookie_1jar_1get_1cookies_FUNC);
+	rc = (jintLong)soup_cookie_jar_get_cookies((SoupCookieJar *)arg0, (SoupURI *)arg1, arg2);
+	WebKitGTK_NATIVE_EXIT(env, that, _1soup_1cookie_1jar_1get_1cookies_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1soup_1cookie_1jar_1get_1type
+JNIEXPORT jint JNICALL WebKitGTK_NATIVE(_1soup_1cookie_1jar_1get_1type)
+	(JNIEnv *env, jclass that)
+{
+	jint rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1soup_1cookie_1jar_1get_1type_FUNC);
+	rc = (jint)soup_cookie_jar_get_type();
+	WebKitGTK_NATIVE_EXIT(env, that, _1soup_1cookie_1jar_1get_1type_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1soup_1cookie_1parse
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1soup_1cookie_1parse)
+	(JNIEnv *env, jclass that, jbyteArray arg0, jintLong arg1)
+{
+	jbyte *lparg0=NULL;
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1soup_1cookie_1parse_FUNC);
+	if (arg0) if ((lparg0 = (*env)->GetByteArrayElements(env, arg0, NULL)) == NULL) goto fail;
+	rc = (jintLong)soup_cookie_parse((const char *)lparg0, (SoupURI *)arg1);
+fail:
+	if (arg0 && lparg0) (*env)->ReleaseByteArrayElements(env, arg0, lparg0, 0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1soup_1cookie_1parse_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1soup_1message_1body_1append
+JNIEXPORT void JNICALL WebKitGTK_NATIVE(_1soup_1message_1body_1append)
+	(JNIEnv *env, jclass that, jintLong arg0, jint arg1, jintLong arg2, jintLong arg3)
+{
+	WebKitGTK_NATIVE_ENTER(env, that, _1soup_1message_1body_1append_FUNC);
+	soup_message_body_append((SoupMessageBody *)arg0, (SoupMemoryUse)arg1, (gconstpointer)arg2, (gsize)arg3);
+	WebKitGTK_NATIVE_EXIT(env, that, _1soup_1message_1body_1append_FUNC);
+}
+#endif
+
+#ifndef NO__1soup_1message_1body_1flatten
+JNIEXPORT void JNICALL WebKitGTK_NATIVE(_1soup_1message_1body_1flatten)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	WebKitGTK_NATIVE_ENTER(env, that, _1soup_1message_1body_1flatten_FUNC);
+	soup_message_body_flatten((SoupMessageBody *)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1soup_1message_1body_1flatten_FUNC);
+}
+#endif
+
+#ifndef NO__1soup_1message_1get_1uri
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1soup_1message_1get_1uri)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1soup_1message_1get_1uri_FUNC);
+	rc = (jintLong)soup_message_get_uri((SoupMessage *)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1soup_1message_1get_1uri_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1soup_1message_1headers_1append
+JNIEXPORT void JNICALL WebKitGTK_NATIVE(_1soup_1message_1headers_1append)
+	(JNIEnv *env, jclass that, jintLong arg0, jbyteArray arg1, jbyteArray arg2)
+{
+	jbyte *lparg1=NULL;
+	jbyte *lparg2=NULL;
+	WebKitGTK_NATIVE_ENTER(env, that, _1soup_1message_1headers_1append_FUNC);
+	if (arg1) if ((lparg1 = (*env)->GetByteArrayElements(env, arg1, NULL)) == NULL) goto fail;
+	if (arg2) if ((lparg2 = (*env)->GetByteArrayElements(env, arg2, NULL)) == NULL) goto fail;
+	soup_message_headers_append((SoupMessageHeaders *)arg0, (const char *)lparg1, (const char *)lparg2);
+fail:
+	if (arg2 && lparg2) (*env)->ReleaseByteArrayElements(env, arg2, lparg2, 0);
+	if (arg1 && lparg1) (*env)->ReleaseByteArrayElements(env, arg1, lparg1, 0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1soup_1message_1headers_1append_FUNC);
+}
+#endif
+
+#ifndef NO__1soup_1session_1add_1feature_1by_1type
+JNIEXPORT void JNICALL WebKitGTK_NATIVE(_1soup_1session_1add_1feature_1by_1type)
+	(JNIEnv *env, jclass that, jintLong arg0, jint arg1)
+{
+	WebKitGTK_NATIVE_ENTER(env, that, _1soup_1session_1add_1feature_1by_1type_FUNC);
+	soup_session_add_feature_by_type((SoupSession *)arg0, (GType)arg1);
+	WebKitGTK_NATIVE_EXIT(env, that, _1soup_1session_1add_1feature_1by_1type_FUNC);
+}
+#endif
+
+#ifndef NO__1soup_1session_1feature_1attach
+JNIEXPORT void JNICALL WebKitGTK_NATIVE(_1soup_1session_1feature_1attach)
+	(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1)
+{
+	WebKitGTK_NATIVE_ENTER(env, that, _1soup_1session_1feature_1attach_FUNC);
+	soup_session_feature_attach((SoupSessionFeature *)arg0, (SoupSession *)arg1);
+	WebKitGTK_NATIVE_EXIT(env, that, _1soup_1session_1feature_1attach_FUNC);
+}
+#endif
+
+#ifndef NO__1soup_1session_1feature_1detach
+JNIEXPORT void JNICALL WebKitGTK_NATIVE(_1soup_1session_1feature_1detach)
+	(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1)
+{
+	WebKitGTK_NATIVE_ENTER(env, that, _1soup_1session_1feature_1detach_FUNC);
+	soup_session_feature_detach((SoupSessionFeature *)arg0, (SoupSession *)arg1);
+	WebKitGTK_NATIVE_EXIT(env, that, _1soup_1session_1feature_1detach_FUNC);
+}
+#endif
+
+#ifndef NO__1soup_1session_1get_1feature
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1soup_1session_1get_1feature)
+	(JNIEnv *env, jclass that, jintLong arg0, jint arg1)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1soup_1session_1get_1feature_FUNC);
+	rc = (jintLong)soup_session_get_feature((SoupSession *)arg0, (GType)arg1);
+	WebKitGTK_NATIVE_EXIT(env, that, _1soup_1session_1get_1feature_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1soup_1uri_1free
+JNIEXPORT void JNICALL WebKitGTK_NATIVE(_1soup_1uri_1free)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	WebKitGTK_NATIVE_ENTER(env, that, _1soup_1uri_1free_FUNC);
+	soup_uri_free((SoupURI *)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1soup_1uri_1free_FUNC);
+}
+#endif
+
+#ifndef NO__1soup_1uri_1new
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1soup_1uri_1new)
+	(JNIEnv *env, jclass that, jbyteArray arg0)
+{
+	jbyte *lparg0=NULL;
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1soup_1uri_1new_FUNC);
+	if (arg0) if ((lparg0 = (*env)->GetByteArrayElements(env, arg0, NULL)) == NULL) goto fail;
+	rc = (jintLong)soup_uri_new((const char *)lparg0);
+fail:
+	if (arg0 && lparg0) (*env)->ReleaseByteArrayElements(env, arg0, lparg0, 0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1soup_1uri_1new_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1soup_1uri_1to_1string
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1soup_1uri_1to_1string)
+	(JNIEnv *env, jclass that, jintLong arg0, jint arg1)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1soup_1uri_1to_1string_FUNC);
+	rc = (jintLong)soup_uri_to_string((SoupURI *)arg0, arg1);
+	WebKitGTK_NATIVE_EXIT(env, that, _1soup_1uri_1to_1string_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1webkit_1download_1cancel
+JNIEXPORT void JNICALL WebKitGTK_NATIVE(_1webkit_1download_1cancel)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1download_1cancel_FUNC);
+	webkit_download_cancel((WebKitDownload *)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1download_1cancel_FUNC);
+}
+#endif
+
+#ifndef NO__1webkit_1download_1get_1current_1size
+JNIEXPORT jlong JNICALL WebKitGTK_NATIVE(_1webkit_1download_1get_1current_1size)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jlong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1download_1get_1current_1size_FUNC);
+	rc = (jlong)webkit_download_get_current_size((WebKitDownload *)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1download_1get_1current_1size_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1webkit_1download_1get_1status
+JNIEXPORT jint JNICALL WebKitGTK_NATIVE(_1webkit_1download_1get_1status)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jint rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1download_1get_1status_FUNC);
+	rc = (jint)webkit_download_get_status((WebKitDownload *)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1download_1get_1status_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1webkit_1download_1get_1suggested_1filename
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1download_1get_1suggested_1filename)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1download_1get_1suggested_1filename_FUNC);
+	rc = (jintLong)webkit_download_get_suggested_filename((WebKitDownload *)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1download_1get_1suggested_1filename_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1webkit_1download_1get_1total_1size
+JNIEXPORT jlong JNICALL WebKitGTK_NATIVE(_1webkit_1download_1get_1total_1size)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jlong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1download_1get_1total_1size_FUNC);
+	rc = (jlong)webkit_download_get_total_size((WebKitDownload *)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1download_1get_1total_1size_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1webkit_1download_1get_1uri
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1download_1get_1uri)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1download_1get_1uri_FUNC);
+	rc = (jintLong)webkit_download_get_uri((WebKitDownload *)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1download_1get_1uri_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1webkit_1download_1set_1destination_1uri
+JNIEXPORT void JNICALL WebKitGTK_NATIVE(_1webkit_1download_1set_1destination_1uri)
+	(JNIEnv *env, jclass that, jintLong arg0, jbyteArray arg1)
+{
+	jbyte *lparg1=NULL;
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1download_1set_1destination_1uri_FUNC);
+	if (arg1) if ((lparg1 = (*env)->GetByteArrayElements(env, arg1, NULL)) == NULL) goto fail;
+	webkit_download_set_destination_uri((WebKitDownload *)arg0, (const gchar *)lparg1);
+fail:
+	if (arg1 && lparg1) (*env)->ReleaseByteArrayElements(env, arg1, lparg1, 0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1download_1set_1destination_1uri_FUNC);
+}
+#endif
+
+#ifndef NO__1webkit_1get_1default_1session
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1get_1default_1session)
+	(JNIEnv *env, jclass that)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1get_1default_1session_FUNC);
+	rc = (jintLong)webkit_get_default_session();
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1get_1default_1session_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1webkit_1major_1version
+JNIEXPORT jint JNICALL WebKitGTK_NATIVE(_1webkit_1major_1version)
+	(JNIEnv *env, jclass that)
+{
+	jint rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1major_1version_FUNC);
+	rc = (jint)webkit_major_version();
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1major_1version_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1webkit_1micro_1version
+JNIEXPORT jint JNICALL WebKitGTK_NATIVE(_1webkit_1micro_1version)
+	(JNIEnv *env, jclass that)
+{
+	jint rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1micro_1version_FUNC);
+	rc = (jint)webkit_micro_version();
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1micro_1version_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1webkit_1minor_1version
+JNIEXPORT jint JNICALL WebKitGTK_NATIVE(_1webkit_1minor_1version)
+	(JNIEnv *env, jclass that)
+{
+	jint rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1minor_1version_FUNC);
+	rc = (jint)webkit_minor_version();
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1minor_1version_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1webkit_1network_1request_1get_1message
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1network_1request_1get_1message)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1network_1request_1get_1message_FUNC);
+	rc = (jintLong)webkit_network_request_get_message((WebKitNetworkRequest *)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1network_1request_1get_1message_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1webkit_1network_1request_1get_1uri
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1network_1request_1get_1uri)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1network_1request_1get_1uri_FUNC);
+	rc = (jintLong)webkit_network_request_get_uri((WebKitNetworkRequest *)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1network_1request_1get_1uri_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1webkit_1network_1request_1new
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1network_1request_1new)
+	(JNIEnv *env, jclass that, jbyteArray arg0)
+{
+	jbyte *lparg0=NULL;
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1network_1request_1new_FUNC);
+	if (arg0) if ((lparg0 = (*env)->GetByteArrayElements(env, arg0, NULL)) == NULL) goto fail;
+	rc = (jintLong)webkit_network_request_new((const gchar *)lparg0);
+fail:
+	if (arg0 && lparg0) (*env)->ReleaseByteArrayElements(env, arg0, lparg0, 0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1network_1request_1new_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1webkit_1soup_1auth_1dialog_1get_1type
+JNIEXPORT jint JNICALL WebKitGTK_NATIVE(_1webkit_1soup_1auth_1dialog_1get_1type)
+	(JNIEnv *env, jclass that)
+{
+	jint rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1soup_1auth_1dialog_1get_1type_FUNC);
+	rc = (jint)webkit_soup_auth_dialog_get_type();
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1soup_1auth_1dialog_1get_1type_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1webkit_1web_1data_1source_1get_1data
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1web_1data_1source_1get_1data)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1web_1data_1source_1get_1data_FUNC);
+	rc = (jintLong)webkit_web_data_source_get_data((WebKitWebDataSource *)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1web_1data_1source_1get_1data_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1webkit_1web_1data_1source_1get_1encoding
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1web_1data_1source_1get_1encoding)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1web_1data_1source_1get_1encoding_FUNC);
+	rc = (jintLong)webkit_web_data_source_get_encoding((WebKitWebDataSource *)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1web_1data_1source_1get_1encoding_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1webkit_1web_1frame_1get_1data_1source
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1web_1frame_1get_1data_1source)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1web_1frame_1get_1data_1source_FUNC);
+	rc = (jintLong)webkit_web_frame_get_data_source((WebKitWebFrame *)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1web_1frame_1get_1data_1source_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1webkit_1web_1frame_1get_1global_1context
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1web_1frame_1get_1global_1context)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1web_1frame_1get_1global_1context_FUNC);
+	rc = (jintLong)webkit_web_frame_get_global_context((WebKitWebFrame *)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1web_1frame_1get_1global_1context_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1webkit_1web_1frame_1get_1load_1status
+JNIEXPORT jint JNICALL WebKitGTK_NATIVE(_1webkit_1web_1frame_1get_1load_1status)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jint rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1web_1frame_1get_1load_1status_FUNC);
+	rc = (jint)webkit_web_frame_get_load_status((WebKitWebFrame *)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1web_1frame_1get_1load_1status_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1webkit_1web_1frame_1get_1parent
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1web_1frame_1get_1parent)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1web_1frame_1get_1parent_FUNC);
+	rc = (jintLong)webkit_web_frame_get_parent((WebKitWebFrame *)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1web_1frame_1get_1parent_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1webkit_1web_1frame_1get_1title
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1web_1frame_1get_1title)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1web_1frame_1get_1title_FUNC);
+	rc = (jintLong)webkit_web_frame_get_title((WebKitWebFrame *)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1web_1frame_1get_1title_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1webkit_1web_1frame_1get_1uri
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1web_1frame_1get_1uri)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1web_1frame_1get_1uri_FUNC);
+	rc = (jintLong)webkit_web_frame_get_uri((WebKitWebFrame *)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1web_1frame_1get_1uri_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1webkit_1web_1frame_1get_1web_1view
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1web_1frame_1get_1web_1view)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1web_1frame_1get_1web_1view_FUNC);
+	rc = (jintLong)webkit_web_frame_get_web_view((WebKitWebFrame *)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1web_1frame_1get_1web_1view_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1webkit_1web_1policy_1decision_1download
+JNIEXPORT void JNICALL WebKitGTK_NATIVE(_1webkit_1web_1policy_1decision_1download)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1web_1policy_1decision_1download_FUNC);
+	webkit_web_policy_decision_download((WebKitWebPolicyDecision *)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1web_1policy_1decision_1download_FUNC);
+}
+#endif
+
+#ifndef NO__1webkit_1web_1policy_1decision_1ignore
+JNIEXPORT void JNICALL WebKitGTK_NATIVE(_1webkit_1web_1policy_1decision_1ignore)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1web_1policy_1decision_1ignore_FUNC);
+	webkit_web_policy_decision_ignore((WebKitWebPolicyDecision *)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1web_1policy_1decision_1ignore_FUNC);
+}
+#endif
+
+#ifndef NO__1webkit_1web_1view_1can_1go_1back
+JNIEXPORT jint JNICALL WebKitGTK_NATIVE(_1webkit_1web_1view_1can_1go_1back)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jint rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1web_1view_1can_1go_1back_FUNC);
+	rc = (jint)webkit_web_view_can_go_back((WebKitWebView *)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1web_1view_1can_1go_1back_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1webkit_1web_1view_1can_1go_1forward
+JNIEXPORT jint JNICALL WebKitGTK_NATIVE(_1webkit_1web_1view_1can_1go_1forward)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jint rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1web_1view_1can_1go_1forward_FUNC);
+	rc = (jint)webkit_web_view_can_go_forward((WebKitWebView *)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1web_1view_1can_1go_1forward_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1webkit_1web_1view_1can_1show_1mime_1type
+JNIEXPORT jint JNICALL WebKitGTK_NATIVE(_1webkit_1web_1view_1can_1show_1mime_1type)
+	(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1)
+{
+	jint rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1web_1view_1can_1show_1mime_1type_FUNC);
+	rc = (jint)webkit_web_view_can_show_mime_type((WebKitWebView *)arg0, (const gchar *)arg1);
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1web_1view_1can_1show_1mime_1type_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1webkit_1web_1view_1execute_1script
+JNIEXPORT void JNICALL WebKitGTK_NATIVE(_1webkit_1web_1view_1execute_1script)
+	(JNIEnv *env, jclass that, jintLong arg0, jbyteArray arg1)
+{
+	jbyte *lparg1=NULL;
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1web_1view_1execute_1script_FUNC);
+	if (arg1) if ((lparg1 = (*env)->GetByteArrayElements(env, arg1, NULL)) == NULL) goto fail;
+	webkit_web_view_execute_script((WebKitWebView *)arg0, (const gchar *)lparg1);
+fail:
+	if (arg1 && lparg1) (*env)->ReleaseByteArrayElements(env, arg1, lparg1, 0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1web_1view_1execute_1script_FUNC);
+}
+#endif
+
+#ifndef NO__1webkit_1web_1view_1get_1load_1status
+JNIEXPORT jint JNICALL WebKitGTK_NATIVE(_1webkit_1web_1view_1get_1load_1status)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jint rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1web_1view_1get_1load_1status_FUNC);
+	rc = (jint)webkit_web_view_get_load_status((WebKitWebView *)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1web_1view_1get_1load_1status_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1webkit_1web_1view_1get_1main_1frame
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1web_1view_1get_1main_1frame)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1web_1view_1get_1main_1frame_FUNC);
+	rc = (jintLong)webkit_web_view_get_main_frame((WebKitWebView *)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1web_1view_1get_1main_1frame_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1webkit_1web_1view_1get_1progress
+JNIEXPORT jdouble JNICALL WebKitGTK_NATIVE(_1webkit_1web_1view_1get_1progress)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jdouble rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1web_1view_1get_1progress_FUNC);
+	rc = (jdouble)webkit_web_view_get_progress((WebKitWebView *)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1web_1view_1get_1progress_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1webkit_1web_1view_1get_1settings
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1web_1view_1get_1settings)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1web_1view_1get_1settings_FUNC);
+	rc = (jintLong)webkit_web_view_get_settings((WebKitWebView *)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1web_1view_1get_1settings_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1webkit_1web_1view_1get_1title
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1web_1view_1get_1title)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1web_1view_1get_1title_FUNC);
+	rc = (jintLong)webkit_web_view_get_title((WebKitWebView *)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1web_1view_1get_1title_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1webkit_1web_1view_1get_1uri
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1web_1view_1get_1uri)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1web_1view_1get_1uri_FUNC);
+	rc = (jintLong)webkit_web_view_get_uri((WebKitWebView *)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1web_1view_1get_1uri_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1webkit_1web_1view_1get_1window_1features
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1web_1view_1get_1window_1features)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1web_1view_1get_1window_1features_FUNC);
+	rc = (jintLong)webkit_web_view_get_window_features((WebKitWebView *)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1web_1view_1get_1window_1features_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1webkit_1web_1view_1go_1back
+JNIEXPORT void JNICALL WebKitGTK_NATIVE(_1webkit_1web_1view_1go_1back)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1web_1view_1go_1back_FUNC);
+	webkit_web_view_go_back((WebKitWebView *)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1web_1view_1go_1back_FUNC);
+}
+#endif
+
+#ifndef NO__1webkit_1web_1view_1go_1forward
+JNIEXPORT void JNICALL WebKitGTK_NATIVE(_1webkit_1web_1view_1go_1forward)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1web_1view_1go_1forward_FUNC);
+	webkit_web_view_go_forward((WebKitWebView *)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1web_1view_1go_1forward_FUNC);
+}
+#endif
+
+#ifndef NO__1webkit_1web_1view_1load_1string
+JNIEXPORT void JNICALL WebKitGTK_NATIVE(_1webkit_1web_1view_1load_1string)
+	(JNIEnv *env, jclass that, jintLong arg0, jbyteArray arg1, jbyteArray arg2, jbyteArray arg3, jbyteArray arg4)
+{
+	jbyte *lparg1=NULL;
+	jbyte *lparg2=NULL;
+	jbyte *lparg3=NULL;
+	jbyte *lparg4=NULL;
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1web_1view_1load_1string_FUNC);
+	if (arg1) if ((lparg1 = (*env)->GetByteArrayElements(env, arg1, NULL)) == NULL) goto fail;
+	if (arg2) if ((lparg2 = (*env)->GetByteArrayElements(env, arg2, NULL)) == NULL) goto fail;
+	if (arg3) if ((lparg3 = (*env)->GetByteArrayElements(env, arg3, NULL)) == NULL) goto fail;
+	if (arg4) if ((lparg4 = (*env)->GetByteArrayElements(env, arg4, NULL)) == NULL) goto fail;
+	webkit_web_view_load_string((WebKitWebView *)arg0, (const gchar *)lparg1, (const gchar *)lparg2, (const gchar *)lparg3, (const gchar *)lparg4);
+fail:
+	if (arg4 && lparg4) (*env)->ReleaseByteArrayElements(env, arg4, lparg4, 0);
+	if (arg3 && lparg3) (*env)->ReleaseByteArrayElements(env, arg3, lparg3, 0);
+	if (arg2 && lparg2) (*env)->ReleaseByteArrayElements(env, arg2, lparg2, 0);
+	if (arg1 && lparg1) (*env)->ReleaseByteArrayElements(env, arg1, lparg1, 0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1web_1view_1load_1string_FUNC);
+}
+#endif
+
+#ifndef NO__1webkit_1web_1view_1load_1uri
+JNIEXPORT void JNICALL WebKitGTK_NATIVE(_1webkit_1web_1view_1load_1uri)
+	(JNIEnv *env, jclass that, jintLong arg0, jbyteArray arg1)
+{
+	jbyte *lparg1=NULL;
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1web_1view_1load_1uri_FUNC);
+	if (arg1) if ((lparg1 = (*env)->GetByteArrayElements(env, arg1, NULL)) == NULL) goto fail;
+	webkit_web_view_load_uri((WebKitWebView *)arg0, (const gchar *)lparg1);
+fail:
+	if (arg1 && lparg1) (*env)->ReleaseByteArrayElements(env, arg1, lparg1, 0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1web_1view_1load_1uri_FUNC);
+}
+#endif
+
+#ifndef NO__1webkit_1web_1view_1new
+JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1web_1view_1new)
+	(JNIEnv *env, jclass that)
+{
+	jintLong rc = 0;
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1web_1view_1new_FUNC);
+	rc = (jintLong)webkit_web_view_new();
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1web_1view_1new_FUNC);
+	return rc;
+}
+#endif
+
+#ifndef NO__1webkit_1web_1view_1reload
+JNIEXPORT void JNICALL WebKitGTK_NATIVE(_1webkit_1web_1view_1reload)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1web_1view_1reload_FUNC);
+	webkit_web_view_reload((WebKitWebView *)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1web_1view_1reload_FUNC);
+}
+#endif
+
+#ifndef NO__1webkit_1web_1view_1stop_1loading
+JNIEXPORT void JNICALL WebKitGTK_NATIVE(_1webkit_1web_1view_1stop_1loading)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1web_1view_1stop_1loading_FUNC);
+	webkit_web_view_stop_loading((WebKitWebView *)arg0);
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1web_1view_1stop_1loading_FUNC);
+}
+#endif
+
+#ifndef NO_memmove
+JNIEXPORT void JNICALL WebKitGTK_NATIVE(memmove)
+	(JNIEnv *env, jclass that, jintLong arg0, jobject arg1, jintLong arg2)
+{
+	JSClassDefinition _arg1, *lparg1=NULL;
+	WebKitGTK_NATIVE_ENTER(env, that, memmove_FUNC);
+	if (arg1) if ((lparg1 = getJSClassDefinitionFields(env, arg1, &_arg1)) == NULL) goto fail;
+	memmove((void *)arg0, (const void *)lparg1, (size_t)arg2);
+fail:
+	WebKitGTK_NATIVE_EXIT(env, that, memmove_FUNC);
+}
+#endif
+
diff --git a/webkitgtk.h b/webkitgtk.h
new file mode 100644
index 0000000..05b9a2e
--- /dev/null
+++ b/webkitgtk.h
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 IBM Corporation and others. All rights reserved.
+ * The contents of this file are made available under the terms
+ * of the GNU Lesser General Public License (LGPL) Version 2.1 that
+ * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
+ * available at http://www.gnu.org/licenses/lgpl.html.  If the version
+ * of the LGPL at http://www.gnu.org is different to the version of
+ * the LGPL accompanying this distribution and there is any conflict
+ * between the two license versions, the terms of the LGPL accompanying
+ * this distribution shall govern.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+  
+#ifndef INC_webkitgtk_H
+#define INC_webkitgtk_H
+
+#include <string.h>
+#include <JavaScriptCore/JSContextRef.h>
+#include <JavaScriptCore/JSObjectRef.h>
+#include <JavaScriptCore/JSStringRef.h>
+#include <libsoup/soup-cookie.h>
+#include <libsoup/soup-cookie-jar.h>
+#include <libsoup/soup-session-feature.h>
+#include <libsoup/soup-uri.h>
+#include <webkit/webkitdownload.h>
+#include <webkit/webkitnetworkrequest.h>
+#include <webkit/webkitsoupauthdialog.h>
+#include <webkit/webkitversion.h>
+#include <webkit/webkitwebpolicydecision.h>
+#include <webkit/webkitwebsettings.h>
+#include <webkit/webkitwebview.h>
+#endif /* INC_webkitgtk_H */
diff --git a/webkitgtk_stats.c b/webkitgtk_stats.c
new file mode 100644
index 0000000..31b101d
--- /dev/null
+++ b/webkitgtk_stats.c
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 IBM Corporation and others. All rights reserved.
+ * The contents of this file are made available under the terms
+ * of the GNU Lesser General Public License (LGPL) Version 2.1 that
+ * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
+ * available at http://www.gnu.org/licenses/lgpl.html.  If the version
+ * of the LGPL at http://www.gnu.org is different to the version of
+ * the LGPL accompanying this distribution and there is any conflict
+ * between the two license versions, the terms of the LGPL accompanying
+ * this distribution shall govern.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+#include "swt.h"
+#include "webkitgtk_stats.h"
+
+#ifdef NATIVE_STATS
+
+int WebKitGTK_nativeFunctionCount = 97;
+int WebKitGTK_nativeFunctionCallCount[97];
+char * WebKitGTK_nativeFunctionNames[] = {
+	"JSClassDefinition_1sizeof",
+	"_1JSClassCreate",
+	"_1JSContextGetGlobalObject",
+	"_1JSEvaluateScript",
+	"_1JSObjectGetPrivate",
+	"_1JSObjectGetProperty",
+	"_1JSObjectGetPropertyAtIndex",
+	"_1JSObjectMake",
+	"_1JSObjectMakeArray",
+	"_1JSObjectMakeFunctionWithCallback",
+	"_1JSObjectSetProperty",
+	"_1JSStringCreateWithUTF8CString",
+	"_1JSStringGetLength",
+	"_1JSStringGetMaximumUTF8CStringSize",
+	"_1JSStringGetUTF8CString",
+	"_1JSStringIsEqualToUTF8CString",
+	"_1JSStringRelease",
+	"_1JSValueGetType",
+	"_1JSValueIsObjectOfClass",
+	"_1JSValueMakeBoolean",
+	"_1JSValueMakeNumber",
+	"_1JSValueMakeString",
+	"_1JSValueMakeUndefined",
+	"_1JSValueToBoolean",
+	"_1JSValueToNumber",
+	"_1JSValueToStringCopy",
+	"_1SOUP_1IS_1SESSION",
+	"_1SoupCookie_1expires",
+	"_1SoupMessage_1method",
+	"_1SoupMessage_1request_1body",
+	"_1SoupMessage_1request_1headers",
+	"_1WEBKIT_1IS_1WEB_1FRAME",
+	"_1soup_1auth_1authenticate",
+	"_1soup_1auth_1get_1host",
+	"_1soup_1auth_1get_1scheme_1name",
+	"_1soup_1cookie_1jar_1add_1cookie",
+	"_1soup_1cookie_1jar_1all_1cookies",
+	"_1soup_1cookie_1jar_1delete_1cookie",
+	"_1soup_1cookie_1jar_1get_1cookies",
+	"_1soup_1cookie_1jar_1get_1type",
+	"_1soup_1cookie_1parse",
+	"_1soup_1message_1body_1append",
+	"_1soup_1message_1body_1flatten",
+	"_1soup_1message_1get_1uri",
+	"_1soup_1message_1headers_1append",
+	"_1soup_1session_1add_1feature_1by_1type",
+	"_1soup_1session_1feature_1attach",
+	"_1soup_1session_1feature_1detach",
+	"_1soup_1session_1get_1feature",
+	"_1soup_1uri_1free",
+	"_1soup_1uri_1new",
+	"_1soup_1uri_1to_1string",
+	"_1webkit_1download_1cancel",
+	"_1webkit_1download_1get_1current_1size",
+	"_1webkit_1download_1get_1status",
+	"_1webkit_1download_1get_1suggested_1filename",
+	"_1webkit_1download_1get_1total_1size",
+	"_1webkit_1download_1get_1uri",
+	"_1webkit_1download_1set_1destination_1uri",
+	"_1webkit_1get_1default_1session",
+	"_1webkit_1major_1version",
+	"_1webkit_1micro_1version",
+	"_1webkit_1minor_1version",
+	"_1webkit_1network_1request_1get_1message",
+	"_1webkit_1network_1request_1get_1uri",
+	"_1webkit_1network_1request_1new",
+	"_1webkit_1soup_1auth_1dialog_1get_1type",
+	"_1webkit_1web_1data_1source_1get_1data",
+	"_1webkit_1web_1data_1source_1get_1encoding",
+	"_1webkit_1web_1frame_1get_1data_1source",
+	"_1webkit_1web_1frame_1get_1global_1context",
+	"_1webkit_1web_1frame_1get_1load_1status",
+	"_1webkit_1web_1frame_1get_1parent",
+	"_1webkit_1web_1frame_1get_1title",
+	"_1webkit_1web_1frame_1get_1uri",
+	"_1webkit_1web_1frame_1get_1web_1view",
+	"_1webkit_1web_1policy_1decision_1download",
+	"_1webkit_1web_1policy_1decision_1ignore",
+	"_1webkit_1web_1view_1can_1go_1back",
+	"_1webkit_1web_1view_1can_1go_1forward",
+	"_1webkit_1web_1view_1can_1show_1mime_1type",
+	"_1webkit_1web_1view_1execute_1script",
+	"_1webkit_1web_1view_1get_1load_1status",
+	"_1webkit_1web_1view_1get_1main_1frame",
+	"_1webkit_1web_1view_1get_1progress",
+	"_1webkit_1web_1view_1get_1settings",
+	"_1webkit_1web_1view_1get_1title",
+	"_1webkit_1web_1view_1get_1uri",
+	"_1webkit_1web_1view_1get_1window_1features",
+	"_1webkit_1web_1view_1go_1back",
+	"_1webkit_1web_1view_1go_1forward",
+	"_1webkit_1web_1view_1load_1string",
+	"_1webkit_1web_1view_1load_1uri",
+	"_1webkit_1web_1view_1new",
+	"_1webkit_1web_1view_1reload",
+	"_1webkit_1web_1view_1stop_1loading",
+	"memmove",
+};
+
+#define STATS_NATIVE(func) Java_org_eclipse_swt_tools_internal_NativeStats_##func
+
+JNIEXPORT jint JNICALL STATS_NATIVE(WebKitGTK_1GetFunctionCount)
+	(JNIEnv *env, jclass that)
+{
+	return WebKitGTK_nativeFunctionCount;
+}
+
+JNIEXPORT jstring JNICALL STATS_NATIVE(WebKitGTK_1GetFunctionName)
+	(JNIEnv *env, jclass that, jint index)
+{
+	return (*env)->NewStringUTF(env, WebKitGTK_nativeFunctionNames[index]);
+}
+
+JNIEXPORT jint JNICALL STATS_NATIVE(WebKitGTK_1GetFunctionCallCount)
+	(JNIEnv *env, jclass that, jint index)
+{
+	return WebKitGTK_nativeFunctionCallCount[index];
+}
+
+#endif
diff --git a/webkitgtk_stats.h b/webkitgtk_stats.h
new file mode 100644
index 0000000..69398a9
--- /dev/null
+++ b/webkitgtk_stats.h
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 IBM Corporation and others. All rights reserved.
+ * The contents of this file are made available under the terms
+ * of the GNU Lesser General Public License (LGPL) Version 2.1 that
+ * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
+ * available at http://www.gnu.org/licenses/lgpl.html.  If the version
+ * of the LGPL at http://www.gnu.org is different to the version of
+ * the LGPL accompanying this distribution and there is any conflict
+ * between the two license versions, the terms of the LGPL accompanying
+ * this distribution shall govern.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+#ifdef NATIVE_STATS
+extern int WebKitGTK_nativeFunctionCount;
+extern int WebKitGTK_nativeFunctionCallCount[];
+extern char* WebKitGTK_nativeFunctionNames[];
+#define WebKitGTK_NATIVE_ENTER(env, that, func) WebKitGTK_nativeFunctionCallCount[func]++;
+#define WebKitGTK_NATIVE_EXIT(env, that, func) 
+#else
+#ifndef WebKitGTK_NATIVE_ENTER
+#define WebKitGTK_NATIVE_ENTER(env, that, func) 
+#endif
+#ifndef WebKitGTK_NATIVE_EXIT
+#define WebKitGTK_NATIVE_EXIT(env, that, func) 
+#endif
+#endif
+
+typedef enum {
+	JSClassDefinition_1sizeof_FUNC,
+	_1JSClassCreate_FUNC,
+	_1JSContextGetGlobalObject_FUNC,
+	_1JSEvaluateScript_FUNC,
+	_1JSObjectGetPrivate_FUNC,
+	_1JSObjectGetProperty_FUNC,
+	_1JSObjectGetPropertyAtIndex_FUNC,
+	_1JSObjectMake_FUNC,
+	_1JSObjectMakeArray_FUNC,
+	_1JSObjectMakeFunctionWithCallback_FUNC,
+	_1JSObjectSetProperty_FUNC,
+	_1JSStringCreateWithUTF8CString_FUNC,
+	_1JSStringGetLength_FUNC,
+	_1JSStringGetMaximumUTF8CStringSize_FUNC,
+	_1JSStringGetUTF8CString_FUNC,
+	_1JSStringIsEqualToUTF8CString_FUNC,
+	_1JSStringRelease_FUNC,
+	_1JSValueGetType_FUNC,
+	_1JSValueIsObjectOfClass_FUNC,
+	_1JSValueMakeBoolean_FUNC,
+	_1JSValueMakeNumber_FUNC,
+	_1JSValueMakeString_FUNC,
+	_1JSValueMakeUndefined_FUNC,
+	_1JSValueToBoolean_FUNC,
+	_1JSValueToNumber_FUNC,
+	_1JSValueToStringCopy_FUNC,
+	_1SOUP_1IS_1SESSION_FUNC,
+	_1SoupCookie_1expires_FUNC,
+	_1SoupMessage_1method_FUNC,
+	_1SoupMessage_1request_1body_FUNC,
+	_1SoupMessage_1request_1headers_FUNC,
+	_1WEBKIT_1IS_1WEB_1FRAME_FUNC,
+	_1soup_1auth_1authenticate_FUNC,
+	_1soup_1auth_1get_1host_FUNC,
+	_1soup_1auth_1get_1scheme_1name_FUNC,
+	_1soup_1cookie_1jar_1add_1cookie_FUNC,
+	_1soup_1cookie_1jar_1all_1cookies_FUNC,
+	_1soup_1cookie_1jar_1delete_1cookie_FUNC,
+	_1soup_1cookie_1jar_1get_1cookies_FUNC,
+	_1soup_1cookie_1jar_1get_1type_FUNC,
+	_1soup_1cookie_1parse_FUNC,
+	_1soup_1message_1body_1append_FUNC,
+	_1soup_1message_1body_1flatten_FUNC,
+	_1soup_1message_1get_1uri_FUNC,
+	_1soup_1message_1headers_1append_FUNC,
+	_1soup_1session_1add_1feature_1by_1type_FUNC,
+	_1soup_1session_1feature_1attach_FUNC,
+	_1soup_1session_1feature_1detach_FUNC,
+	_1soup_1session_1get_1feature_FUNC,
+	_1soup_1uri_1free_FUNC,
+	_1soup_1uri_1new_FUNC,
+	_1soup_1uri_1to_1string_FUNC,
+	_1webkit_1download_1cancel_FUNC,
+	_1webkit_1download_1get_1current_1size_FUNC,
+	_1webkit_1download_1get_1status_FUNC,
+	_1webkit_1download_1get_1suggested_1filename_FUNC,
+	_1webkit_1download_1get_1total_1size_FUNC,
+	_1webkit_1download_1get_1uri_FUNC,
+	_1webkit_1download_1set_1destination_1uri_FUNC,
+	_1webkit_1get_1default_1session_FUNC,
+	_1webkit_1major_1version_FUNC,
+	_1webkit_1micro_1version_FUNC,
+	_1webkit_1minor_1version_FUNC,
+	_1webkit_1network_1request_1get_1message_FUNC,
+	_1webkit_1network_1request_1get_1uri_FUNC,
+	_1webkit_1network_1request_1new_FUNC,
+	_1webkit_1soup_1auth_1dialog_1get_1type_FUNC,
+	_1webkit_1web_1data_1source_1get_1data_FUNC,
+	_1webkit_1web_1data_1source_1get_1encoding_FUNC,
+	_1webkit_1web_1frame_1get_1data_1source_FUNC,
+	_1webkit_1web_1frame_1get_1global_1context_FUNC,
+	_1webkit_1web_1frame_1get_1load_1status_FUNC,
+	_1webkit_1web_1frame_1get_1parent_FUNC,
+	_1webkit_1web_1frame_1get_1title_FUNC,
+	_1webkit_1web_1frame_1get_1uri_FUNC,
+	_1webkit_1web_1frame_1get_1web_1view_FUNC,
+	_1webkit_1web_1policy_1decision_1download_FUNC,
+	_1webkit_1web_1policy_1decision_1ignore_FUNC,
+	_1webkit_1web_1view_1can_1go_1back_FUNC,
+	_1webkit_1web_1view_1can_1go_1forward_FUNC,
+	_1webkit_1web_1view_1can_1show_1mime_1type_FUNC,
+	_1webkit_1web_1view_1execute_1script_FUNC,
+	_1webkit_1web_1view_1get_1load_1status_FUNC,
+	_1webkit_1web_1view_1get_1main_1frame_FUNC,
+	_1webkit_1web_1view_1get_1progress_FUNC,
+	_1webkit_1web_1view_1get_1settings_FUNC,
+	_1webkit_1web_1view_1get_1title_FUNC,
+	_1webkit_1web_1view_1get_1uri_FUNC,
+	_1webkit_1web_1view_1get_1window_1features_FUNC,
+	_1webkit_1web_1view_1go_1back_FUNC,
+	_1webkit_1web_1view_1go_1forward_FUNC,
+	_1webkit_1web_1view_1load_1string_FUNC,
+	_1webkit_1web_1view_1load_1uri_FUNC,
+	_1webkit_1web_1view_1new_FUNC,
+	_1webkit_1web_1view_1reload_FUNC,
+	_1webkit_1web_1view_1stop_1loading_FUNC,
+	memmove_FUNC,
+} WebKitGTK_FUNCS;
diff --git a/webkitgtk_structs.c b/webkitgtk_structs.c
new file mode 100644
index 0000000..a39af74
--- /dev/null
+++ b/webkitgtk_structs.c
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 IBM Corporation and others. All rights reserved.
+ * The contents of this file are made available under the terms
+ * of the GNU Lesser General Public License (LGPL) Version 2.1 that
+ * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
+ * available at http://www.gnu.org/licenses/lgpl.html.  If the version
+ * of the LGPL at http://www.gnu.org is different to the version of
+ * the LGPL accompanying this distribution and there is any conflict
+ * between the two license versions, the terms of the LGPL accompanying
+ * this distribution shall govern.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+#include "swt.h"
+#include "webkitgtk_structs.h"
+
+#ifndef NO_JSClassDefinition
+typedef struct JSClassDefinition_FID_CACHE {
+	int cached;
+	jclass clazz;
+	jfieldID version, attributes, className, parentClass, staticValues, staticFunctions, initialize, finalize, hasProperty, getProperty, setProperty, deleteProperty, getPropertyNames, callAsFunction, callAsConstructor, hasInstance, convertToType;
+} JSClassDefinition_FID_CACHE;
+
+JSClassDefinition_FID_CACHE JSClassDefinitionFc;
+
+void cacheJSClassDefinitionFields(JNIEnv *env, jobject lpObject)
+{
+	if (JSClassDefinitionFc.cached) return;
+	JSClassDefinitionFc.clazz = (*env)->GetObjectClass(env, lpObject);
+	JSClassDefinitionFc.version = (*env)->GetFieldID(env, JSClassDefinitionFc.clazz, "version", "I");
+	JSClassDefinitionFc.attributes = (*env)->GetFieldID(env, JSClassDefinitionFc.clazz, "attributes", "I");
+	JSClassDefinitionFc.className = (*env)->GetFieldID(env, JSClassDefinitionFc.clazz, "className", I_J);
+	JSClassDefinitionFc.parentClass = (*env)->GetFieldID(env, JSClassDefinitionFc.clazz, "parentClass", I_J);
+	JSClassDefinitionFc.staticValues = (*env)->GetFieldID(env, JSClassDefinitionFc.clazz, "staticValues", I_J);
+	JSClassDefinitionFc.staticFunctions = (*env)->GetFieldID(env, JSClassDefinitionFc.clazz, "staticFunctions", I_J);
+	JSClassDefinitionFc.initialize = (*env)->GetFieldID(env, JSClassDefinitionFc.clazz, "initialize", I_J);
+	JSClassDefinitionFc.finalize = (*env)->GetFieldID(env, JSClassDefinitionFc.clazz, "finalize", I_J);
+	JSClassDefinitionFc.hasProperty = (*env)->GetFieldID(env, JSClassDefinitionFc.clazz, "hasProperty", I_J);
+	JSClassDefinitionFc.getProperty = (*env)->GetFieldID(env, JSClassDefinitionFc.clazz, "getProperty", I_J);
+	JSClassDefinitionFc.setProperty = (*env)->GetFieldID(env, JSClassDefinitionFc.clazz, "setProperty", I_J);
+	JSClassDefinitionFc.deleteProperty = (*env)->GetFieldID(env, JSClassDefinitionFc.clazz, "deleteProperty", I_J);
+	JSClassDefinitionFc.getPropertyNames = (*env)->GetFieldID(env, JSClassDefinitionFc.clazz, "getPropertyNames", I_J);
+	JSClassDefinitionFc.callAsFunction = (*env)->GetFieldID(env, JSClassDefinitionFc.clazz, "callAsFunction", I_J);
+	JSClassDefinitionFc.callAsConstructor = (*env)->GetFieldID(env, JSClassDefinitionFc.clazz, "callAsConstructor", I_J);
+	JSClassDefinitionFc.hasInstance = (*env)->GetFieldID(env, JSClassDefinitionFc.clazz, "hasInstance", I_J);
+	JSClassDefinitionFc.convertToType = (*env)->GetFieldID(env, JSClassDefinitionFc.clazz, "convertToType", I_J);
+	JSClassDefinitionFc.cached = 1;
+}
+
+JSClassDefinition *getJSClassDefinitionFields(JNIEnv *env, jobject lpObject, JSClassDefinition *lpStruct)
+{
+	if (!JSClassDefinitionFc.cached) cacheJSClassDefinitionFields(env, lpObject);
+	lpStruct->version = (*env)->GetIntField(env, lpObject, JSClassDefinitionFc.version);
+	lpStruct->attributes = (JSClassAttributes)(*env)->GetIntField(env, lpObject, JSClassDefinitionFc.attributes);
+	lpStruct->className = (const char*)(*env)->GetIntLongField(env, lpObject, JSClassDefinitionFc.className);
+	lpStruct->parentClass = (JSClassRef)(*env)->GetIntLongField(env, lpObject, JSClassDefinitionFc.parentClass);
+	lpStruct->staticValues = (const JSStaticValue*)(*env)->GetIntLongField(env, lpObject, JSClassDefinitionFc.staticValues);
+	lpStruct->staticFunctions = (const JSStaticFunction*)(*env)->GetIntLongField(env, lpObject, JSClassDefinitionFc.staticFunctions);
+	lpStruct->initialize = (JSObjectInitializeCallback)(*env)->GetIntLongField(env, lpObject, JSClassDefinitionFc.initialize);
+	lpStruct->finalize = (JSObjectFinalizeCallback)(*env)->GetIntLongField(env, lpObject, JSClassDefinitionFc.finalize);
+	lpStruct->hasProperty = (JSObjectHasPropertyCallback)(*env)->GetIntLongField(env, lpObject, JSClassDefinitionFc.hasProperty);
+	lpStruct->getProperty = (JSObjectGetPropertyCallback)(*env)->GetIntLongField(env, lpObject, JSClassDefinitionFc.getProperty);
+	lpStruct->setProperty = (JSObjectSetPropertyCallback)(*env)->GetIntLongField(env, lpObject, JSClassDefinitionFc.setProperty);
+	lpStruct->deleteProperty = (JSObjectDeletePropertyCallback)(*env)->GetIntLongField(env, lpObject, JSClassDefinitionFc.deleteProperty);
+	lpStruct->getPropertyNames = (JSObjectGetPropertyNamesCallback)(*env)->GetIntLongField(env, lpObject, JSClassDefinitionFc.getPropertyNames);
+	lpStruct->callAsFunction = (JSObjectCallAsFunctionCallback)(*env)->GetIntLongField(env, lpObject, JSClassDefinitionFc.callAsFunction);
+	lpStruct->callAsConstructor = (JSObjectCallAsConstructorCallback)(*env)->GetIntLongField(env, lpObject, JSClassDefinitionFc.callAsConstructor);
+	lpStruct->hasInstance = (JSObjectHasInstanceCallback)(*env)->GetIntLongField(env, lpObject, JSClassDefinitionFc.hasInstance);
+	lpStruct->convertToType = (JSObjectConvertToTypeCallback)(*env)->GetIntLongField(env, lpObject, JSClassDefinitionFc.convertToType);
+	return lpStruct;
+}
+
+void setJSClassDefinitionFields(JNIEnv *env, jobject lpObject, JSClassDefinition *lpStruct)
+{
+	if (!JSClassDefinitionFc.cached) cacheJSClassDefinitionFields(env, lpObject);
+	(*env)->SetIntField(env, lpObject, JSClassDefinitionFc.version, (jint)lpStruct->version);
+	(*env)->SetIntField(env, lpObject, JSClassDefinitionFc.attributes, (jint)lpStruct->attributes);
+	(*env)->SetIntLongField(env, lpObject, JSClassDefinitionFc.className, (jintLong)lpStruct->className);
+	(*env)->SetIntLongField(env, lpObject, JSClassDefinitionFc.parentClass, (jintLong)lpStruct->parentClass);
+	(*env)->SetIntLongField(env, lpObject, JSClassDefinitionFc.staticValues, (jintLong)lpStruct->staticValues);
+	(*env)->SetIntLongField(env, lpObject, JSClassDefinitionFc.staticFunctions, (jintLong)lpStruct->staticFunctions);
+	(*env)->SetIntLongField(env, lpObject, JSClassDefinitionFc.initialize, (jintLong)lpStruct->initialize);
+	(*env)->SetIntLongField(env, lpObject, JSClassDefinitionFc.finalize, (jintLong)lpStruct->finalize);
+	(*env)->SetIntLongField(env, lpObject, JSClassDefinitionFc.hasProperty, (jintLong)lpStruct->hasProperty);
+	(*env)->SetIntLongField(env, lpObject, JSClassDefinitionFc.getProperty, (jintLong)lpStruct->getProperty);
+	(*env)->SetIntLongField(env, lpObject, JSClassDefinitionFc.setProperty, (jintLong)lpStruct->setProperty);
+	(*env)->SetIntLongField(env, lpObject, JSClassDefinitionFc.deleteProperty, (jintLong)lpStruct->deleteProperty);
+	(*env)->SetIntLongField(env, lpObject, JSClassDefinitionFc.getPropertyNames, (jintLong)lpStruct->getPropertyNames);
+	(*env)->SetIntLongField(env, lpObject, JSClassDefinitionFc.callAsFunction, (jintLong)lpStruct->callAsFunction);
+	(*env)->SetIntLongField(env, lpObject, JSClassDefinitionFc.callAsConstructor, (jintLong)lpStruct->callAsConstructor);
+	(*env)->SetIntLongField(env, lpObject, JSClassDefinitionFc.hasInstance, (jintLong)lpStruct->hasInstance);
+	(*env)->SetIntLongField(env, lpObject, JSClassDefinitionFc.convertToType, (jintLong)lpStruct->convertToType);
+}
+#endif
+
diff --git a/webkitgtk_structs.h b/webkitgtk_structs.h
new file mode 100644
index 0000000..8f53dd4
--- /dev/null
+++ b/webkitgtk_structs.h
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 IBM Corporation and others. All rights reserved.
+ * The contents of this file are made available under the terms
+ * of the GNU Lesser General Public License (LGPL) Version 2.1 that
+ * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
+ * available at http://www.gnu.org/licenses/lgpl.html.  If the version
+ * of the LGPL at http://www.gnu.org is different to the version of
+ * the LGPL accompanying this distribution and there is any conflict
+ * between the two license versions, the terms of the LGPL accompanying
+ * this distribution shall govern.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+#include "webkitgtk.h"
+
+#ifndef NO_JSClassDefinition
+void cacheJSClassDefinitionFields(JNIEnv *env, jobject lpObject);
+JSClassDefinition *getJSClassDefinitionFields(JNIEnv *env, jobject lpObject, JSClassDefinition *lpStruct);
+void setJSClassDefinitionFields(JNIEnv *env, jobject lpObject, JSClassDefinition *lpStruct);
+#define JSClassDefinition_sizeof() sizeof(JSClassDefinition)
+#else
+#define cacheJSClassDefinitionFields(a,b)
+#define getJSClassDefinitionFields(a,b,c) NULL
+#define setJSClassDefinitionFields(a,b,c)
+#define JSClassDefinition_sizeof() 0
+#endif
+
diff --git a/xpcom_custom.cpp b/xpcom_custom.cpp
index d84a81d..32741cf 100644
--- a/xpcom_custom.cpp
+++ b/xpcom_custom.cpp
@@ -57,7 +57,7 @@ JNIEXPORT jint JNICALL XPCOM_NATIVE(_1JS_1EvaluateUCScriptForPrincipals)
 #ifdef _WIN32
 		LOAD_FUNCTION(fp, JS_EvaluateUCScriptForPrincipals)
 		if (fp) {
-			rc = (jint)((jint (CALLING_CONVENTION*)(jintLong, jintLong, jintLong, jchar *, jint, jbyte *, jint, jintLong *))fp)(arg0, arg1, arg2, lparg3, arg4, lparg5, arg6, lparg7);
+			rc = (jint)((jint (*)(jintLong, jintLong, jintLong, jchar *, jint, jbyte *, jint, jintLong *))fp)(arg0, arg1, arg2, lparg3, arg4, lparg5, arg6, lparg7);
 		}
 #else
 #define CALLING_CONVENTION
@@ -85,4 +85,46 @@ fail:
 }
 #endif
 
+#ifndef NO__1NS_1Free
+JNIEXPORT jint JNICALL XPCOM_NATIVE(_1NS_1Free)
+	(JNIEnv *env, jclass that, jbyteArray mozillaPath, jintLong arg0)
+{
+	jbyte *lpmozillaPath=NULL;
+	jint rc = 0;
+	XPCOM_NATIVE_ENTER(env, that, _1NS_1Free_FUNC);
+	if (mozillaPath) if ((lpmozillaPath = env->GetByteArrayElements(mozillaPath, NULL)) == NULL) goto fail;
+/*
+	NS_Free((void*)arg0);
+*/
+	{
+	
+#ifdef _WIN32
+		LOAD_FUNCTION(fp, NS_Free)
+		if (fp) {
+			((jint (*)(void *))fp)((void *)arg0);
+			rc = 1;
+		}
+#else
+#define CALLING_CONVENTION
+		static int initialized = 0;
+		static void *fp = NULL;
+		if (!initialized) {
+			void* handle = dlopen((const char *)lpmozillaPath, RTLD_LAZY);
+			if (handle) {
+				fp = dlsym(handle, "NS_Free");
+			}
+			initialized = 1;
+		}
+		if (fp) {
+			((jint (CALLING_CONVENTION*)(void *))fp)((void *)arg0);
+			rc = 1;
+		}
+#endif /* _WIN32 */
+	}
+fail:
+	if (mozillaPath && lpmozillaPath) env->ReleaseByteArrayElements(mozillaPath, lpmozillaPath, 0);
+	XPCOM_NATIVE_EXIT(env, that, _1NS_1Free_FUNC);
+	return rc;
+}
+#endif
 }
diff --git a/xpcom_custom.h b/xpcom_custom.h
index c11fe30..21bc338 100644
--- a/xpcom_custom.h
+++ b/xpcom_custom.h
@@ -12,6 +12,7 @@
 #ifdef _WIN32
 #include <windows.h>
 #define JS_EvaluateUCScriptForPrincipals_LIB "js3250.dll"
+#define NS_Free_LIB "xpcom.dll"
 #define XP_WIN
 #else
 #include <dlfcn.h>
diff --git a/xpcom_stats.cpp b/xpcom_stats.cpp
index 3e9979b..f0ac6ad 100644
--- a/xpcom_stats.cpp
+++ b/xpcom_stats.cpp
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -17,7 +17,6 @@
 int XPCOM_nativeFunctionCount = 226;
 int XPCOM_nativeFunctionCallCount[226];
 char * XPCOM_nativeFunctionNames[] = {
-	"GetAddress",
 #ifndef JNI64
 	"_1Call__I",
 #else
@@ -34,6 +33,7 @@ char * XPCOM_nativeFunctionNames[] = {
 	"_1Call__JJJ_3BII_3I",
 #endif
 	"_1JS_1EvaluateUCScriptForPrincipals",
+	"_1NS_1Free",
 	"_1NS_1GetComponentManager",
 	"_1NS_1GetServiceManager",
 	"_1NS_1InitXPCOM2",
diff --git a/xpcom_stats.h b/xpcom_stats.h
index 0e0c0dc..eef0e1b 100644
--- a/xpcom_stats.h
+++ b/xpcom_stats.h
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -25,7 +25,6 @@ extern char* XPCOM_nativeFunctionNames[];
 #endif
 
 typedef enum {
-	GetAddress_FUNC,
 #ifndef JNI64
 	_1Call__I_FUNC,
 #else
@@ -42,6 +41,7 @@ typedef enum {
 	_1Call__JJJ_3BII_3I_FUNC,
 #endif
 	_1JS_1EvaluateUCScriptForPrincipals_FUNC,
+	_1NS_1Free_FUNC,
 	_1NS_1GetComponentManager_FUNC,
 	_1NS_1GetServiceManager_FUNC,
 	_1NS_1InitXPCOM2_FUNC,


hooks/post-receive
-- 
Debian packaging for swt-gtk.



More information about the pkg-java-commits mailing list