[libjogl2-java] 51/58: Imported Upstream version 2.1.4

Tony Mancill tmancill at moszumanska.debian.org
Thu Sep 4 03:59:29 UTC 2014


This is an automated email from the git hooks/post-receive script.

tmancill pushed a commit to branch master
in repository libjogl2-java.

commit eb302d633040368c935a6e335a942ada0ea5a5f5
Author: tony mancill <tmancill at debian.org>
Date:   Fri Aug 29 18:46:59 2014 -0700

    Imported Upstream version 2.1.4
---
 .classpath                                         |    1 +
 doc/HowToBuild.html                                |    5 +
 doc/deployment/JOGL-DEPLOYMENT.html                |   48 +-
 doc/userguide/index.html                           |    2 +-
 jnlp-files/jogl-applet-bug818_gljpanel01.html      |    4 +-
 ...nner-newt-ElektronenMultiplizierer-napplet.html |    5 +-
 ...pplet-runner-newt-ElektronenMultiplizierer.html |   29 +-
 ...nner-newt-GraphTextDemo01-applet3-napplet.html} |   14 +-
 ...applet-runner-newt-GraphTextDemo01-napplet.html |    2 -
 .../jogl-applet-runner-newt-GraphTextDemo01.html   |   26 +-
 ...pplet-runner-newt-GraphTextDemo01b-napplet.html |    2 -
 ...r-newt-GraphUISceneDemo01-applet3-napplet.html} |   17 +-
 ...let-runner-newt-GraphUISceneDemo01-napplet.html |    5 +-
 ...jogl-applet-runner-newt-GraphUISceneDemo01.html |   29 +-
 ...let-runner-newt-MovieCube-applet3-napplet.html} |   17 +-
 .../jogl-applet-runner-newt-MovieCube-napplet.html |    5 +-
 jnlp-files/jogl-applet-runner-newt-MovieCube.html  |   29 +-
 ...-applet-runner-newt-gears-applet3-napplet.html} |   67 +-
 ...runner-newt-gears-applet3-special-napplet.html} |   17 +-
 .../jogl-applet-runner-newt-gears-gl3-napplet.html |   46 +-
 ...plet-runner-newt-gears-normal-launcheronly.html |  143 ---
 ...gl-applet-runner-newt-gears-normal-napplet.html |   42 +-
 ...l-applet-runner-newt-gears-normal-napplet2.html |   42 +-
 .../jogl-applet-runner-newt-gears-normal.html      |  115 +-
 ...l-applet-runner-newt-gears-special-napplet.html |    5 +-
 .../jogl-applet-runner-newt-gears-special.html     |   29 +-
 jnlp-files/jogl-applet-runner-newt.jnlp            |    1 -
 ...ml => jogl-applet-version-applet3-napplet.html} |   26 +-
 jnlp-files/jogl-applet-version-lancheronly.html    |   56 -
 jnlp-files/jogl-applet-version-napplet.html        |    8 +-
 jnlp-files/jogl-applet-version.html                |   26 +-
 jnlp-files/jogl-applet-version.jnlp                |    4 +-
 jnlp-files/jogl-application-version.jnlp           |    4 +-
 jnlp-files/jogl-javaws-version.jnlp                |    1 -
 ...l-test-applets.html => jogl-test-applet3s.html} |  111 +-
 jnlp-files/jogl-test-applets.html                  |   28 +-
 make/build-common.xml                              |    7 +-
 make/build-jogl.xml                                |    2 +-
 make/build-newt.xml                                |   14 +-
 make/build-test.xml                                |    1 +
 make/config/jogl/gl-common.cfg                     |   78 +-
 make/config/jogl/gl-gl4bc.cfg                      |   46 +-
 make/config/jogl/gl-if-CustomJavaCode-es3.java     |    4 +
 make/config/jogl/gl-if-CustomJavaCode-gl2.java     |   40 +
 make/config/jogl/gl-if-es3.cfg                     |    4 +-
 make/config/jogl/gl-if-gl2.cfg                     |    1 +
 make/config/jogl/gl-impl-CustomCCode-gl4bc.c       |   91 +-
 make/config/jogl/gl-impl-CustomCCode-gles1.c       |   35 +
 make/config/jogl/gl-impl-CustomCCode-gles3.c       |   36 +
 .../config/jogl/gl-impl-CustomJavaCode-common.java |  157 ++-
 make/config/jogl/gl-impl-CustomJavaCode-gl4bc.java |  238 +++-
 make/config/jogl/gl-impl-CustomJavaCode-gles1.java |   59 +-
 make/config/jogl/gl-impl-CustomJavaCode-gles3.java |   69 +-
 make/joglversion                                   |    2 +
 make/joglversion-all                               |    2 +
 make/joglversion-test                              |    4 +
 make/joglversion-test-android                      |    1 +
 make/nativewindowversion                           |    2 +
 make/newtversion                                   |    2 +
 make/resources/android/AndroidManifest-jogl.xml    |   12 -
 make/resources/android/res-jogl/values/strings.xml |    2 -
 .../assets-test/crosshair-grey-alpha-64x64.png     |  Bin 0 -> 424 bytes
 .../resources/assets-test/jogamp-pointer-64x64.png |  Bin 0 -> 2843 bytes
 .../assets/jogl/util/data/av/test-ntsc01-57x32.png |  Bin 0 -> 969 bytes
 .../assets/newt/data/cross-grey-alpha-16x16.png    |  Bin 0 -> 286 bytes
 make/resources/assets/newt/data/jogamp-16x16.png   |  Bin 0 -> 549 bytes
 make/resources/assets/newt/data/jogamp-32x32.png   |  Bin 0 -> 1020 bytes
 .../assets/newt/data/pointer-grey-alpha-16x24.png  |  Bin 0 -> 511 bytes
 make/resources/misc/jogamp-48x48.png               |  Bin 0 -> 1278 bytes
 make/resources/misc/jogamp-64x64.png               |  Bin 0 -> 1833 bytes
 .../util/data/av => misc}/test-ntsc01-160x90.png   |  Bin
 make/scripts/create-i386-libs-symlinks.sh          |   10 +
 make/scripts/make.jogl.all.android-armv6-cross.sh  |    2 +
 make/scripts/setenv-jogl.sh                        |    2 +-
 make/scripts/test-win32-smb_share.bat              |   33 +
 make/scripts/tests-osx-x64-custom.sh               |    2 +-
 make/scripts/tests-osx-x64-java6.sh                |    2 +-
 make/scripts/tests-osx-x64.sh                      |    2 +-
 make/scripts/tests-win.bat                         |    6 +-
 make/scripts/tests-x64-dbg.bat                     |    3 +-
 make/scripts/tests.sh                              |  105 +-
 .../gluegen/opengl/BuildComposablePipeline.java    |   19 +-
 src/jogl/classes/com/jogamp/opengl/FBObject.java   |   33 +-
 .../com/jogamp/opengl/GLRendererQuirks.java        |   88 +-
 .../classes/com/jogamp/opengl/swt/GLCanvas.java    |    5 +
 .../com/jogamp/opengl/util/FPSAnimator.java        |   12 +-
 .../com/jogamp/opengl/util/GLArrayDataClient.java  |   74 +-
 .../com/jogamp/opengl/util/GLArrayDataServer.java  |  337 ++++--
 .../com/jogamp/opengl/util/GLArrayDataWrapper.java |  122 +-
 .../com/jogamp/opengl/util/GLPixelBuffer.java      |  100 ++
 .../com/jogamp/opengl/util/PNGPixelRect.java       |  335 ++++++
 .../com/jogamp/opengl/util/av/GLMediaPlayer.java   |   20 +-
 .../com/jogamp/opengl/util/texture/TextureIO.java  |   63 +-
 .../jogamp/opengl/util/texture/spi/DDSImage.java   |   33 +-
 .../jogamp/opengl/util/texture/spi/PNGImage.java   |  319 -----
 src/jogl/classes/javax/media/opengl/GLBase.java    |   89 +-
 .../javax/media/opengl/GLBufferStorage.java        |  150 +++
 src/jogl/classes/javax/media/opengl/GLContext.java |   42 +-
 src/jogl/classes/javax/media/opengl/GLProfile.java |    8 +-
 .../javax/media/opengl/GLSharedContextSetter.java  |   14 +-
 .../classes/javax/media/opengl/awt/GLCanvas.java   |   35 +-
 .../classes/javax/media/opengl/awt/GLJPanel.java   |   25 +-
 .../classes/jogamp/opengl/GLAutoDrawableBase.java  |    5 +
 .../jogamp/opengl/GLBufferObjectTracker.java       |  520 ++++++++
 .../classes/jogamp/opengl/GLBufferSizeTracker.java |  200 ----
 .../jogamp/opengl/GLBufferStateTracker.java        |  153 ++-
 src/jogl/classes/jogamp/opengl/GLContextImpl.java  |  138 ++-
 .../classes/jogamp/opengl/GLContextShareSet.java   |   24 -
 .../classes/jogamp/opengl/GLDrawableHelper.java    |   36 +-
 .../classes/jogamp/opengl/GLFBODrawableImpl.java   |    4 +-
 src/jogl/classes/jogamp/opengl/MemoryObject.java   |   33 +-
 src/jogl/classes/jogamp/opengl/egl/EGLContext.java |   35 +-
 .../classes/jogamp/opengl/egl/EGLDisplayUtil.java  |  219 ++--
 .../jogamp/opengl/egl/EGLDrawableFactory.java      |  126 +-
 .../opengl/egl/EGLDynamicLibraryBundleInfo.java    |    3 +
 .../opengl/egl/EGLGraphicsConfiguration.java       |   27 +-
 .../egl/EGLGraphicsConfigurationFactory.java       |   13 +-
 .../jogamp/opengl/egl/EGLUpstreamSurfaceHook.java  |    1 +
 .../jogamp/opengl/macosx/cgl/MacOSXCGLContext.java |    2 +-
 .../jogamp/opengl/openal/av/ALAudioSink.java       |    2 +-
 .../jogamp/opengl/util/av/GLMediaPlayerImpl.java   |   25 +-
 .../jogamp/opengl/util/av/NullGLMediaPlayer.java   |    2 +-
 .../opengl/util/av/impl/FFMPEGMediaPlayer.java     |   16 +-
 .../opengl/util/glsl/fixedfunc/FixedFuncHook.java  |   24 +-
 src/jogl/native/GLContext.c                        |    2 +-
 src/jogl/native/GLDebugMessageHandler.c            |   95 +-
 src/jogl/native/JoglCommon.c                       |   97 +-
 src/jogl/native/JoglCommon.h                       |   55 +-
 src/jogl/native/libav/ffmpeg_impl_template.c       |    4 +-
 .../macosx/MacOSXWindowSystemInterface-calayer.m   |    1 +
 .../jogamp_opengl_util_av_impl_OMXGLMediaPlayer.c  |    5 +-
 .../UpstreamSurfaceHookMutableSizePos.java         |   36 +
 .../com/jogamp/nativewindow/awt/JAWTWindow.java    |  160 +--
 .../jogamp/nativewindow/egl/EGLGraphicsDevice.java |   12 +
 .../jogamp/nativewindow/x11/X11GraphicsDevice.java |   15 +
 .../media/nativewindow/DefaultGraphicsDevice.java  |    2 +-
 .../media/nativewindow/NativeWindowFactory.java    |   65 +
 .../media/nativewindow/OffscreenLayerSurface.java  |   18 +
 .../javax/media/nativewindow/util/PixelFormat.java |  196 +++
 .../media/nativewindow/util/PixelFormatUtil.java   |  374 ++++++
 .../media/nativewindow/util/PixelRectangle.java    |  194 +++
 .../jogamp/nativewindow/ProxySurfaceImpl.java      |    6 +-
 .../classes/jogamp/nativewindow/WrappedWindow.java |   98 ++
 .../classes/jogamp/nativewindow/awt/AWTMisc.java   |   57 +
 .../jogamp/nativewindow/windows/GDIUtil.java       |    8 +-
 .../windows/RegisteredClassFactory.java            |    7 +-
 src/nativewindow/native/NativewindowCommon.c       |  107 +-
 src/nativewindow/native/NativewindowCommon.h       |   61 +-
 src/nativewindow/native/macosx/OSXmisc.m           |   51 +-
 src/nativewindow/native/win32/GDImisc.c            |   17 +-
 src/nativewindow/native/x11/Xmisc.c                |  162 ++-
 src/newt/classes/com/jogamp/newt/Display.java      |  180 ++-
 src/newt/classes/com/jogamp/newt/NewtFactory.java  |   86 +-
 src/newt/classes/com/jogamp/newt/Window.java       |   30 +
 .../classes/com/jogamp/newt/awt/NewtCanvasAWT.java |    4 +-
 .../jogamp/newt/awt/applet/JOGLNewtApplet1Run.java |    1 +
 .../classes/com/jogamp/newt/opengl/GLWindow.java   |   11 +
 .../applet/JOGLNewtApplet3Run.java}                |  324 ++---
 .../{awt => util}/applet/JOGLNewtAppletBase.java   |  108 +-
 .../jogamp/newt/util/applet/VersionApplet3.java    |  226 ++++
 src/newt/classes/jogamp/newt/DefaultEDTUtil.java   |   49 +-
 src/newt/classes/jogamp/newt/DisplayImpl.java      |  196 ++-
 src/newt/classes/jogamp/newt/PointerIconImpl.java  |  171 +++
 src/newt/classes/jogamp/newt/WindowImpl.java       |  404 ++++---
 .../newt/awt/event/AWTParentWindowAdapter.java     |   20 +-
 src/newt/classes/jogamp/newt/driver/PNGIcon.java   |   80 ++
 .../jogamp/newt/driver/android/DisplayDriver.java  |   11 +-
 .../driver/android/NewtDebugActivityLauncher.java  |   21 -
 .../newt/driver/android/NewtVersionActivity.java   |   88 +-
 .../android/NewtVersionActivityLauncher.java       |    2 +-
 .../driver/android/NewtVersionBaseActivity.java    |  120 --
 .../jogamp/newt/driver/android/WindowDriver.java   |  217 ++--
 .../newt/driver/bcm/vc/iv/DisplayDriver.java       |  132 +-
 .../jogamp/newt/driver/bcm/vc/iv/WindowDriver.java |  134 ++-
 .../jogamp/newt/driver/kd/DisplayDriver.java       |    1 +
 .../newt/driver/linux/LinuxMouseTracker.java       |   12 +-
 .../jogamp/newt/driver/macosx/DisplayDriver.java   |   57 +
 .../jogamp/newt/driver/macosx/WindowDriver.java    |   30 +-
 .../jogamp/newt/driver/opengl/JoglUtilPNGIcon.java |   89 ++
 .../jogamp/newt/driver/windows/DisplayDriver.java  |   60 +-
 .../jogamp/newt/driver/windows/WindowDriver.java   |   26 +-
 .../jogamp/newt/driver/x11/DisplayDriver.java      |   39 +-
 .../jogamp/newt/driver/x11/WindowDriver.java       |   98 +-
 src/newt/native/MacWindow.m                        |  201 +++-
 src/newt/native/NewtCommon.c                       |   96 +-
 src/newt/native/NewtCommon.h                       |   26 +-
 src/newt/native/NewtMacWindow.h                    |   96 +-
 src/newt/native/NewtMacWindow.m                    | 1257 ++++++++++----------
 src/newt/native/WindowsWindow.c                    |  159 ++-
 src/newt/native/X11Display.c                       |   57 +
 src/newt/native/X11Window.c                        |  173 ++-
 src/newt/native/bcm_vc_iv.c                        |  350 +++++-
 src/newt/native/bcm_vc_iv.h                        |  130 +-
 .../junit/jogl/acore/TestGLMesaBug658NEWT.java     |    2 +-
 .../test/junit/jogl/acore/TestGLProfile01NEWT.java |  322 ++++-
 .../junit/jogl/acore/TestInitConcurrent01NEWT.java |   20 +-
 .../junit/jogl/acore/TestMapBufferRead01NEWT.java  |   90 +-
 .../jogl/acore/TestSharedContextVBOES2NEWT0.java   |   67 +-
 .../jogl/acore/TestSharedContextVBOES2NEWT3.java   |   87 +-
 .../TestAWTCardLayoutAnimatorStartStopBug532.java  |   92 +-
 .../awt/TestBug664GLCanvasSetVisibleSwingAWT.java  |   96 +-
 ...estBug816JTabbedPanelVisibilityB849B878AWT.java |   47 +-
 .../jogl/awt/TestBug816OSXCALayerPos01AWT.java     |   41 +-
 .../awt/TestBug816OSXCALayerPos03aB729AWT.java     |    6 +-
 .../awt/TestBug816OSXCALayerPos03bB849AWT.java     |    6 +-
 .../awt/TestBug816OSXCALayerPos03cB849AWT.java     |    6 +-
 .../opengl/test/junit/jogl/demos/GearsObject.java  |   59 +-
 .../junit/jogl/demos/TextureSequenceDemo01.java    |    2 +-
 .../opengl/test/junit/jogl/demos/es1/GearsES1.java |   14 +-
 .../test/junit/jogl/demos/es1/GearsObjectES1.java  |   30 +-
 .../opengl/test/junit/jogl/demos/es2/GearsES2.java |   22 +-
 .../test/junit/jogl/demos/es2/GearsObjectES2.java  |   37 +-
 .../junit/jogl/demos/es2/RedSquareMappedES2.java   |  281 +++++
 .../test/junit/jogl/demos/es2/av/MovieSimple.java  |  287 +++--
 .../jogl/demos/es2/newt/TestGearsES2NEWT.java      |  131 +-
 .../jogl/demos/es2/newt/TestRedSquareES2NEWT.java  |   46 +-
 .../opengl/test/junit/jogl/demos/gl2/Teapot.java   |    4 +-
 .../test/junit/jogl/glsl/GLSLMiscHelper.java       |    4 +-
 .../jogl/perf/TestPerf001GLJPanelInit01AWT.java    |   15 +-
 .../jogl/perf/TestPerf001GLJPanelInit02AWT.java    |   15 +-
 .../jogl/perf/TestPerf001GLWindowInit03NEWT.java   |   15 +-
 .../jogl/util/DemoGL2ES1TextureImmModeSink.java    |    2 +-
 .../test/junit/jogl/util/texture/PNGTstFiles.java} |   36 +-
 .../texture/TestBug362DDSImageCreateFromData.java  |   98 ++
 .../jogl/util/texture/TestPNGImage00NEWT.java      |   92 --
 .../jogl/util/texture/TestPNGPixelRect00NEWT.java  |  226 ++++
 ...mage01NEWT.java => TestPNGPixelRect01NEWT.java} |  109 +-
 .../util/texture/TestPixelFormatUtil00NEWT.java    |  364 ++++++
 .../util/texture/TestPixelFormatUtil01NEWT.java    |  105 ++
 .../jogl/util/texture/cross-grey-alpha-16x16.png   |  Bin 0 -> 286 bytes
 .../jogl/util/texture/pointer-grey-alpha-16x24.png |  Bin 0 -> 511 bytes
 .../junit/jogl/util/texture/test-64x32_DXT1.dds    |  Bin 0 -> 1512 bytes
 .../junit/jogl/util/texture/test-64x32_DXT5.dds    |  Bin 0 -> 2896 bytes
 .../jogl/util/texture/test-64x32_uncompressed.dds  |  Bin 0 -> 8321 bytes
 .../parenting/NewtAWTReparentingKeyAdapter.java    |  103 +-
 .../junit/newt/parenting/TestParenting01dAWT.java  |    5 +-
 .../opengl/test/junit/util/AWTRobotUtil.java       |    4 +-
 .../jogamp/opengl/test/junit/util/QuitAdapter.java |   17 +-
 238 files changed, 11437 insertions(+), 4663 deletions(-)

diff --git a/.classpath b/.classpath
index 817f2b8..b0ed782 100644
--- a/.classpath
+++ b/.classpath
@@ -33,5 +33,6 @@
 	<classpathentry kind="lib" path="/gluegen/make/lib/android-sdk/15/android.jar" sourcepath="/gluegen/make/lib/android-sdk/15/android-java-src.zip"/>
 	<classpathentry combineaccessrules="false" kind="src" path="/joal"/>
 	<classpathentry kind="lib" path="/gluegen/make/lib/junit.jar" sourcepath="/gluegen/make/lib/junit-sources.jar"/>
+	<classpathentry kind="lib" path="make/lib/plugin3/plugin3-public.jar" sourcepath="make/lib/plugin3/plugin3-public-src.zip"/>
 	<classpathentry kind="output" path="build/eclipse-classes"/>
 </classpath>
diff --git a/doc/HowToBuild.html b/doc/HowToBuild.html
index 3503859..1cb3bad 100644
--- a/doc/HowToBuild.html
+++ b/doc/HowToBuild.html
@@ -91,8 +91,12 @@
                                         <li>libxinerama-dev</li>
                                         <li>libxrandr-dev</li>
                                         <li>libxrender-dev</li>
+                                        <li>libxcursor-dev</li>
                                         <li>Optional: Your card vendor's proprietary driver</li>
                                     </ul>
+                                    <pre>
+apt-get install git gcc libgl1-mesa-dev libglu1-mesa-dev xorg-dev libice-dev libsm-dev libx11-dev libxext-dev libxxf86vm-dev libxinerama-dev libxrandr-dev libxrender-dev libxcursor-dev
+                                    </pre>
                                 </li>
                                 <li> <b>OpenSuSE</b> 10.2 or later
                                     <ul>
@@ -119,6 +123,7 @@
                                         <li>libXinerama-devel</li>
                                         <li>libXrandr-devel</li>
                                         <li>libXrender-devel</li>
+                                        <li>libXcursor-devel</li>
                                         <li>Optional: Your card vendor's proprietary driver</li>
                                     </ul>
                                 </li>
diff --git a/doc/deployment/JOGL-DEPLOYMENT.html b/doc/deployment/JOGL-DEPLOYMENT.html
index d4916a2..81a028e 100644
--- a/doc/deployment/JOGL-DEPLOYMENT.html
+++ b/doc/deployment/JOGL-DEPLOYMENT.html
@@ -28,7 +28,7 @@
             <div id="main">
                 <div id="text" class="fill">
 
-                    <h1><a name="TraditionalApplets">Traditional Applets</a></h1>
+                    <h1><a name="NApplets">New Applets</a></h1>
 
                     <p>
                     You may choose to use traditional <a href="http://java.sun.com/applets/">Java Applets</a> to deploy your 
@@ -40,44 +40,34 @@
                     the <a href="#NativeJARFiles">native JAR files</a>.
                     </p>
 
-                    Examples are available:
-                    <ul>
-                        <li><a href="http://jausoft.com/jogamp/jogl-applet-runner-newt-gears-normal-napplet.html">Demo on jausoft.com and modules on jogamp.org</a></li>
-                        <li><a href="http://jogamp.org/deployment/jogamp-current/jogl-applet-runner-newt-gears-normal-napplet.html">Demo and modules on jogamp.org</a></li>
-                    </ul>
+                    <a href="http://jogamp.org/deployment/jogamp-current/jogl-demos/applet-gears-napplet.html">AWT/JOGL NApplet Example</a>:
                     <pre>
                         <object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
-                              width="200" height="200">
-                           <param name="code" value="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run">
-                           <param name="archive" value="jar/gluegen-rt.jar,
-                                                        jar/jogl-all.jar,
-                                                        jar/jogl-test.jar">
-                           <param name="java_arguments" value="-Dsun.java2d.noddraw=true">
-                           <param name="gl_event_listener_class" value="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2">
-                           <param name="gl_profile" value="GL2ES2">
-                           <param name="gl_swap_interval" value="1">
-                           <param name="gl_debug" value="false">
-                           <param name="gl_trace" value="false">
+                              width="600" height="400">
+                           <param name="code" value="demos.applets.GearsApplet">
+                           <param name="archive" value="../jar/gluegen-rt.jar,
+                                                           ../jar/jogl-all.jar,
+                                                           jar/jogl-demos.jar">
                            <comment>
-                             <embed code="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run"
-                                  width="200" height="200"
+                             <embed code="demos.applets.GearsApplet"
+                                  width="600" height="400"
                                   type="application/x-java-applet;version=1.6"
                                   pluginspage="http://java.sun.com/javase/downloads/ea.jsp"
-                                  archive="jar/gluegen-rt.jar,
-                                           jar/jogl-all.jar,
-                                           jar/jogl-test.jar"
-                                  java_arguments="-Dsun.java2d.noddraw=true"
-                                  gl_event_listener_class="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2"
-                                  gl_profile="GL2ES2"
-                                  gl_swap_interval="1"
-                                  gl_debug="false"
-                                  gl_trace="false">
+                                  archive="../jar/gluegen-rt.jar,
+                                           ../jar/jogl-all.jar,
+                                           jar/jogl-demos.jar">
                                 <noembed>Sorry, no Java support detected.</noembed>
                              </embed>
                            </comment>
                         </object>
                     </pre>
-
+                    <p>
+                    NEWT/JOGL NApplet Examples:
+                    <ul>
+                        <li><a href="http://jausoft.com/jogamp/jogl-applet-runner-newt-gears-normal-napplet.html">Demo on jausoft.com and modules on jogamp.org</a></li>
+                        <li><a href="http://jogamp.org/deployment/jogamp-current/jogl-applet-runner-newt-gears-normal-napplet.html">Demo and modules on jogamp.org</a></li>
+                    </ul>
+                    </p>
 
                     <h1><a name="JNLPFiles">JNLP Files</a></h1>
 
diff --git a/doc/userguide/index.html b/doc/userguide/index.html
index f90a260..8b3a510 100644
--- a/doc/userguide/index.html
+++ b/doc/userguide/index.html
@@ -213,7 +213,7 @@ libraries required to use JOGL
 without relying on the Java 
 library path or any platform-dependent environment variable allowing to set the location 
 of native libraries. This allows desktop applications as well as traditional Applets 
-<a href="../deployment/JOGL-DEPLOYMENT.html#TraditionalApplets">as traditional Applets</a> 
+<a href="../deployment/JOGL-DEPLOYMENT.html#NApplets">as NApplets</a> 
 to utilize the native library JAR files the same way Webstart/JNLP does.
 
 </p>
diff --git a/jnlp-files/jogl-applet-bug818_gljpanel01.html b/jnlp-files/jogl-applet-bug818_gljpanel01.html
index 84e612d..4bb09d0 100644
--- a/jnlp-files/jogl-applet-bug818_gljpanel01.html
+++ b/jnlp-files/jogl-applet-bug818_gljpanel01.html
@@ -16,15 +16,13 @@ Bug818 OSX GLJPanel NV GT330 Crash
    <param name="archive" value="jar/lib/gluegen-rt.jar,
                                 jar/lib/jogl-all.jar,
                                 jar/jogl-test.jar">
-   <param name="java_arguments" value="-Xms128M -Xmx512M -Dsun.java2d.noddraw=true"/>
    <comment>
      <embed code="com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.Bug818GLJPanelApplet"
           width="750" height="350"
           type="application/x-java-applet;version=1.6"
           archive="jar/gluegen-rt.jar,
                    jar/jogl-all.jar,
-                   jar/jogl-test.jar"
-          java_arguments="-Xms128M -Xmx512M -Dsun.java2d.noddraw=true">
+                   jar/jogl-test.jar">
         <noembed>Sorry, no Java support detected.</noembed>
      </embed>
    </comment>
diff --git a/jnlp-files/jogl-applet-runner-newt-ElektronenMultiplizierer-napplet.html b/jnlp-files/jogl-applet-runner-newt-ElektronenMultiplizierer-napplet.html
index 19a3b29..54ea05f 100644
--- a/jnlp-files/jogl-applet-runner-newt-ElektronenMultiplizierer-napplet.html
+++ b/jnlp-files/jogl-applet-runner-newt-ElektronenMultiplizierer-napplet.html
@@ -16,7 +16,6 @@ Demoscene Passivist's Elektronen-Multiplizierer
    <param name="archive" value="jar/gluegen-rt.jar,
                                 jar/jogl-all.jar,
                                 jar/jogl-test.jar">
-   <param name="java_arguments" value="-Dsun.java2d.noddraw=true">
    <param name="gl_event_listener_class" value="com.jogamp.opengl.test.junit.jogl.demos.es2.ElektronenMultiplizierer">
    <param name="gl_profile" value="GL2ES2">
    <param name="gl_swap_interval" value="1">
@@ -31,7 +30,6 @@ Demoscene Passivist's Elektronen-Multiplizierer
                    jar/jogl-all.jar,
                    jar/jogl-test.jar"
           codebase_lookup" value="false"
-          java_arguments="-Dsun.java2d.noddraw=true"
           gl_event_listener_class="com.jogamp.opengl.test.junit.jogl.demos.es2.ElektronenMultiplizierer"
           gl_profile="GL2ES2"
           gl_swap_interval="1"
@@ -58,6 +56,9 @@ JOGL NEWT JNLP Applet Runner Special Keys:<br>
     <li> f - toggle fullscreen </li>
     <li> r - in/out browser window </li>
     <li> a - on/off always-on-top </li>
+    <li> c - change mouse pointer </li>
+    <li> i - invisible mouse pointer </li>
+    <li> w - warp mouse pointer to center </li>
 </ul>
 </P>
 
diff --git a/jnlp-files/jogl-applet-runner-newt-ElektronenMultiplizierer.html b/jnlp-files/jogl-applet-runner-newt-ElektronenMultiplizierer.html
index 71c9baf..8768dd4 100644
--- a/jnlp-files/jogl-applet-runner-newt-ElektronenMultiplizierer.html
+++ b/jnlp-files/jogl-applet-runner-newt-ElektronenMultiplizierer.html
@@ -12,19 +12,10 @@ Demoscene Passivist's Elektronen-Multiplizierer
 <P>
 <object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
       width="640" height="480">
-   <param name="code" value="org.jdesktop.applet.util.JNLPAppletLauncher">
-   <param name="archive" value="jar/applet-launcher.jar,
-                                jar/gluegen-rt.jar,
+   <param name="code" value="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run">
+   <param name="archive" value="jar/gluegen-rt.jar,
                                 jar/jogl-all.jar,
                                 jar/jogl-test.jar">
-   <param name="codebase_lookup" value="false">
-   <param name="subapplet.classname" value="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run">
-   <param name="subapplet.displayname" value="ElektronenMultiplizierer">
-   <param name="noddraw.check" value="true">
-   <param name="progressbar" value="true">
-   <param name="jnlpNumExtensions" value="1">
-   <param name="jnlpExtension1" value="jogl-all-awt.jnlp">
-   <param name="java_arguments" value="-Dsun.java2d.noddraw=true">
    <param name="gl_event_listener_class" value="com.jogamp.opengl.test.junit.jogl.demos.es2.ElektronenMultiplizierer">
    <param name="gl_profile" value="GL2ES2">
    <param name="gl_swap_interval" value="1">
@@ -32,22 +23,13 @@ Demoscene Passivist's Elektronen-Multiplizierer
    <param name="gl_trace" value="false">
    <param name="jnlp_href" value="jogl-applet-runner-newt.jnlp">
    <comment>
-     <embed code="org.jdesktop.applet.util.JNLPAppletLauncher"
+     <embed code="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run"
           width="640" height="480"
           type="application/x-java-applet;version=1.6"
           pluginspage="http://java.sun.com/javase/downloads/ea.jsp"
-          archive="jar/applet-launcher.jar,
-                   jar/gluegen-rt.jar,
+          archive="jar/gluegen-rt.jar,
                    jar/jogl-all.jar,
                    jar/jogl-test.jar"
-          codebase_lookup" value="false"
-          subapplet.classname="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run"
-          subapplet.displayname="ElektronenMultiplizierer"
-          noddraw.check="true"
-          progressbar="true"
-          jnlpNumExtensions="1"
-          jnlpExtension1="jogl-all-awt.jnlp"
-          java_arguments="-Dsun.java2d.noddraw=true"
           gl_event_listener_class="com.jogamp.opengl.test.junit.jogl.demos.es2.ElektronenMultiplizierer"
           gl_profile="GL2ES2"
           gl_swap_interval="1"
@@ -75,6 +57,9 @@ JOGL NEWT JNLP Applet Runner Special Keys:<br>
     <li> f - toggle fullscreen </li>
     <li> r - in/out browser window </li>
     <li> a - on/off always-on-top </li>
+    <li> c - change mouse pointer </li>
+    <li> i - invisible mouse pointer </li>
+    <li> w - warp mouse pointer to center </li>
 </ul>
 </P>
 
diff --git a/jnlp-files/jogl-applet-runner-newt-GraphTextDemo01-napplet.html b/jnlp-files/jogl-applet-runner-newt-GraphTextDemo01-applet3-napplet.html
similarity index 81%
copy from jnlp-files/jogl-applet-runner-newt-GraphTextDemo01-napplet.html
copy to jnlp-files/jogl-applet-runner-newt-GraphTextDemo01-applet3-napplet.html
index 9648b57..6bfc9a4 100644
--- a/jnlp-files/jogl-applet-runner-newt-GraphTextDemo01-napplet.html
+++ b/jnlp-files/jogl-applet-runner-newt-GraphTextDemo01-applet3-napplet.html
@@ -1,22 +1,21 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
 <html>
 <head>
-<title>JOGL Graph Text Demo 01 (NApplet)</title>
+<title>JOGL Applet3 Graph Text Demo 01 (NApplet)</title>
 </head>
 <body  BGCOLOR="#ffffff">
 
 <P>
-JOGL Graph Text Demo 01
+JOGL Applet3 Graph Text Demo 01
 </P>
 
 <P>
 <object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
       width="800" height="400">
-   <param name="code" value="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run">
+   <param name="code" value="com.jogamp.newt.util.applet.JOGLNewtApplet3Run">
    <param name="archive" value="jar/gluegen-rt.jar,
-                                jar/jogl-all.jar,
+                                jar/jogl-all-noawt.jar,
                                 jar/jogl-test.jar">
-   <param name="java_arguments" value="-Dsun.java2d.noddraw=true">
    <param name="gl_event_listener_class" value="com.jogamp.opengl.test.junit.graph.demos.GPUTextGLListener0A">
    <param name="gl_profile" value="GL2ES2">
    <param name="gl_swap_interval" value="1">
@@ -26,14 +25,13 @@ JOGL Graph Text Demo 01
    <param name="gl_debug" value="false">
    <param name="gl_trace" value="false">
    <comment>
-     <embed code="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run"
+     <embed code="com.jogamp.newt.util.applet.JOGLNewtApplet3Run"
           width="800" height="400"
           type="application/x-java-applet;version=1.6"
           pluginspage="http://java.sun.com/javase/downloads/ea.jsp"
           archive="jar/gluegen-rt.jar,
-                   jar/jogl-all.jar,
+                   jar/jogl-all-noawt.jar,
                    jar/jogl-test.jar"
-          java_arguments="-Dsun.java2d.noddraw=true"
           gl_event_listener_class="com.jogamp.opengl.test.junit.graph.demos.GPUTextGLListener0A"
           gl_profile="GL2ES2"
           gl_swap_interval="1"
diff --git a/jnlp-files/jogl-applet-runner-newt-GraphTextDemo01-napplet.html b/jnlp-files/jogl-applet-runner-newt-GraphTextDemo01-napplet.html
index 9648b57..28fed66 100644
--- a/jnlp-files/jogl-applet-runner-newt-GraphTextDemo01-napplet.html
+++ b/jnlp-files/jogl-applet-runner-newt-GraphTextDemo01-napplet.html
@@ -16,7 +16,6 @@ JOGL Graph Text Demo 01
    <param name="archive" value="jar/gluegen-rt.jar,
                                 jar/jogl-all.jar,
                                 jar/jogl-test.jar">
-   <param name="java_arguments" value="-Dsun.java2d.noddraw=true">
    <param name="gl_event_listener_class" value="com.jogamp.opengl.test.junit.graph.demos.GPUTextGLListener0A">
    <param name="gl_profile" value="GL2ES2">
    <param name="gl_swap_interval" value="1">
@@ -33,7 +32,6 @@ JOGL Graph Text Demo 01
           archive="jar/gluegen-rt.jar,
                    jar/jogl-all.jar,
                    jar/jogl-test.jar"
-          java_arguments="-Dsun.java2d.noddraw=true"
           gl_event_listener_class="com.jogamp.opengl.test.junit.graph.demos.GPUTextGLListener0A"
           gl_profile="GL2ES2"
           gl_swap_interval="1"
diff --git a/jnlp-files/jogl-applet-runner-newt-GraphTextDemo01.html b/jnlp-files/jogl-applet-runner-newt-GraphTextDemo01.html
index 489984b..fc00b73 100644
--- a/jnlp-files/jogl-applet-runner-newt-GraphTextDemo01.html
+++ b/jnlp-files/jogl-applet-runner-newt-GraphTextDemo01.html
@@ -12,19 +12,10 @@ JOGL Graph Text Demo 01
 <P>
 <object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
       width="800" height="400">
-   <param name="code" value="org.jdesktop.applet.util.JNLPAppletLauncher">
-   <param name="archive" value="jar/applet-launcher.jar,
-                                jar/gluegen-rt.jar,
+   <param name="code" value="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run">
+   <param name="archive" value="jar/gluegen-rt.jar,
                                 jar/jogl-all.jar,
                                 jar/jogl-test.jar">
-   <param name="codebase_lookup" value="false">
-   <param name="subapplet.classname" value="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run">
-   <param name="subapplet.displayname" value="JOGL Graph Text Demo01">
-   <param name="noddraw.check" value="true">
-   <param name="progressbar" value="true">
-   <param name="jnlpNumExtensions" value="1">
-   <param name="jnlpExtension1" value="jogl-all-awt.jnlp">
-   <param name="java_arguments" value="-Dsun.java2d.noddraw=true">
    <param name="gl_event_listener_class" value="com.jogamp.opengl.test.junit.graph.demos.GPUTextGLListener0A">
    <param name="gl_profile" value="GL2ES2">
    <param name="gl_swap_interval" value="1">
@@ -35,22 +26,13 @@ JOGL Graph Text Demo 01
    <param name="gl_trace" value="false">
    <param name="jnlp_href" value="jogl-applet-runner-newt.jnlp">
    <comment>
-     <embed code="org.jdesktop.applet.util.JNLPAppletLauncher"
+     <embed code="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run"
           width="800" height="400"
           type="application/x-java-applet;version=1.6"
           pluginspage="http://java.sun.com/javase/downloads/ea.jsp"
-          archive="jar/applet-launcher.jar,
-                   jar/gluegen-rt.jar,
+          archive="jar/gluegen-rt.jar,
                    jar/jogl-all.jar,
                    jar/jogl-test.jar"
-          codebase_lookup" value="false"
-          subapplet.classname="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run"
-          subapplet.displayname="JOGL Graph Text Demo01"
-          noddraw.check="true"
-          progressbar="true"
-          jnlpNumExtensions="1"
-          jnlpExtension1="jogl-all-awt.jnlp"
-          java_arguments="-Dsun.java2d.noddraw=true"
           gl_event_listener_class="com.jogamp.opengl.test.junit.graph.demos.GPUTextGLListener0A"
           gl_profile="GL2ES2"
           gl_swap_interval="1"
diff --git a/jnlp-files/jogl-applet-runner-newt-GraphTextDemo01b-napplet.html b/jnlp-files/jogl-applet-runner-newt-GraphTextDemo01b-napplet.html
index c4c9494..cf0723e 100644
--- a/jnlp-files/jogl-applet-runner-newt-GraphTextDemo01b-napplet.html
+++ b/jnlp-files/jogl-applet-runner-newt-GraphTextDemo01b-napplet.html
@@ -17,7 +17,6 @@ JOGL Graph Text Demo 01b (w/ atomic/jogl-fonts-p0.jar in path)
                                 jar/jogl-all.jar,
                                 jar/atomic/jogl-fonts-p0.jar,
                                 jar/jogl-test.jar">
-   <param name="java_arguments" value="-Dsun.java2d.noddraw=true">
    <param name="gl_event_listener_class" value="com.jogamp.opengl.test.junit.graph.demos.GPUTextGLListener0A">
    <param name="gl_profile" value="GL2ES2">
    <param name="gl_swap_interval" value="1">
@@ -35,7 +34,6 @@ JOGL Graph Text Demo 01b (w/ atomic/jogl-fonts-p0.jar in path)
                    jar/jogl-all.jar,
                    jar/atomic/jogl-fonts-p0.jar,
                    jar/jogl-test.jar"
-          java_arguments="-Dsun.java2d.noddraw=true"
           gl_event_listener_class="com.jogamp.opengl.test.junit.graph.demos.GPUTextGLListener0A"
           gl_profile="GL2ES2"
           gl_swap_interval="1"
diff --git a/jnlp-files/jogl-applet-runner-newt-GraphUISceneDemo01-napplet.html b/jnlp-files/jogl-applet-runner-newt-GraphUISceneDemo01-applet3-napplet.html
similarity index 77%
copy from jnlp-files/jogl-applet-runner-newt-GraphUISceneDemo01-napplet.html
copy to jnlp-files/jogl-applet-runner-newt-GraphUISceneDemo01-applet3-napplet.html
index 8f9783f..4e7cf93 100644
--- a/jnlp-files/jogl-applet-runner-newt-GraphUISceneDemo01-napplet.html
+++ b/jnlp-files/jogl-applet-runner-newt-GraphUISceneDemo01-applet3-napplet.html
@@ -1,22 +1,21 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
 <html>
 <head>
-<title>JOGL Graph UI-Scene Demo 01 (NApplet)</title>
+<title>JOGL Applet3 Graph UI-Scene Demo 01 (NApplet)</title>
 </head>
 <body  BGCOLOR="#ffffff">
 
 <P>
-JOGL Graph UI-Scene Demo 01
+JOGL Applet3 Graph UI-Scene Demo 01
 </P>
 
 <P>
 <object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
       width="640" height="480">
-   <param name="code" value="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run">
+   <param name="code" value="com.jogamp.newt.util.applet.JOGLNewtApplet3Run">
    <param name="archive" value="jar/gluegen-rt.jar,
-                                jar/jogl-all.jar,
+                                jar/jogl-all-noawt.jar,
                                 jar/jogl-test.jar">
-   <param name="java_arguments" value="-Dsun.java2d.noddraw=true">
    <param name="gl_event_listener_class" value="com.jogamp.opengl.test.junit.graph.demos.GPUUISceneGLListener0A">
    <param name="gl_profile" value="GL2ES2">
    <param name="gl_swap_interval" value="1">
@@ -25,14 +24,13 @@ JOGL Graph UI-Scene Demo 01
    <param name="gl_debug" value="false">
    <param name="gl_trace" value="false">
    <comment>
-     <embed code="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run"
+     <embed code="com.jogamp.newt.util.applet.JOGLNewtApplet3Run"
           width="640" height="480"
           type="application/x-java-applet;version=1.6"
           pluginspage="http://java.sun.com/javase/downloads/ea.jsp"
           archive="jar/gluegen-rt.jar,
-                   jar/jogl-all.jar,
+                   jar/jogl-all-noawt.jar,
                    jar/jogl-test.jar"
-          java_arguments="-Dsun.java2d.noddraw=true"
           gl_event_listener_class="com.jogamp.opengl.test.junit.graph.demos.GPUUISceneGLListener0A"
           gl_profile="GL2ES2"
           gl_swap_interval="1"
@@ -60,6 +58,9 @@ JOGL NEWT JNLP Applet Runner Special Keys:<br>
     <li> f - toggle fullscreen </li>
     <li> r - in/out browser window </li>
     <li> a - on/off always-on-top </li>
+    <li> c - change mouse pointer </li>
+    <li> i - invisible mouse pointer </li>
+    <li> w - warp mouse pointer to center </li>
 </ul>
 </P>
 
diff --git a/jnlp-files/jogl-applet-runner-newt-GraphUISceneDemo01-napplet.html b/jnlp-files/jogl-applet-runner-newt-GraphUISceneDemo01-napplet.html
index 8f9783f..66f02da 100644
--- a/jnlp-files/jogl-applet-runner-newt-GraphUISceneDemo01-napplet.html
+++ b/jnlp-files/jogl-applet-runner-newt-GraphUISceneDemo01-napplet.html
@@ -16,7 +16,6 @@ JOGL Graph UI-Scene Demo 01
    <param name="archive" value="jar/gluegen-rt.jar,
                                 jar/jogl-all.jar,
                                 jar/jogl-test.jar">
-   <param name="java_arguments" value="-Dsun.java2d.noddraw=true">
    <param name="gl_event_listener_class" value="com.jogamp.opengl.test.junit.graph.demos.GPUUISceneGLListener0A">
    <param name="gl_profile" value="GL2ES2">
    <param name="gl_swap_interval" value="1">
@@ -32,7 +31,6 @@ JOGL Graph UI-Scene Demo 01
           archive="jar/gluegen-rt.jar,
                    jar/jogl-all.jar,
                    jar/jogl-test.jar"
-          java_arguments="-Dsun.java2d.noddraw=true"
           gl_event_listener_class="com.jogamp.opengl.test.junit.graph.demos.GPUUISceneGLListener0A"
           gl_profile="GL2ES2"
           gl_swap_interval="1"
@@ -60,6 +58,9 @@ JOGL NEWT JNLP Applet Runner Special Keys:<br>
     <li> f - toggle fullscreen </li>
     <li> r - in/out browser window </li>
     <li> a - on/off always-on-top </li>
+    <li> c - change mouse pointer </li>
+    <li> i - invisible mouse pointer </li>
+    <li> w - warp mouse pointer to center </li>
 </ul>
 </P>
 
diff --git a/jnlp-files/jogl-applet-runner-newt-GraphUISceneDemo01.html b/jnlp-files/jogl-applet-runner-newt-GraphUISceneDemo01.html
index 429e803..3efc951 100644
--- a/jnlp-files/jogl-applet-runner-newt-GraphUISceneDemo01.html
+++ b/jnlp-files/jogl-applet-runner-newt-GraphUISceneDemo01.html
@@ -12,19 +12,10 @@ JOGL Graph UI-Scene Demo 01
 <P>
 <object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
       width="640" height="480">
-   <param name="code" value="org.jdesktop.applet.util.JNLPAppletLauncher">
-   <param name="archive" value="jar/applet-launcher.jar,
-                                jar/gluegen-rt.jar,
+   <param name="code" value="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run">
+   <param name="archive" value="jar/gluegen-rt.jar,
                                 jar/jogl-all.jar,
                                 jar/jogl-test.jar">
-   <param name="codebase_lookup" value="false">
-   <param name="subapplet.classname" value="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run">
-   <param name="subapplet.displayname" value="JOGL Graph UI Demo01">
-   <param name="noddraw.check" value="true">
-   <param name="progressbar" value="true">
-   <param name="jnlpNumExtensions" value="1">
-   <param name="jnlpExtension1" value="jogl-all-awt.jnlp">
-   <param name="java_arguments" value="-Dsun.java2d.noddraw=true">
    <param name="gl_event_listener_class" value="com.jogamp.opengl.test.junit.graph.demos.GPUUISceneGLListener0A">
    <param name="gl_profile" value="GL2ES2">
    <param name="gl_swap_interval" value="1">
@@ -34,22 +25,13 @@ JOGL Graph UI-Scene Demo 01
    <param name="gl_trace" value="false">
    <param name="jnlp_href" value="jogl-applet-runner-newt.jnlp">
    <comment>
-     <embed code="org.jdesktop.applet.util.JNLPAppletLauncher"
+     <embed code="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run"
           width="640" height="480"
           type="application/x-java-applet;version=1.6"
           pluginspage="http://java.sun.com/javase/downloads/ea.jsp"
-          archive="jar/applet-launcher.jar,
-                   jar/gluegen-rt.jar,
+          archive="jar/gluegen-rt.jar,
                    jar/jogl-all.jar,
                    jar/jogl-test.jar"
-          codebase_lookup" value="false"
-          subapplet.classname="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run"
-          subapplet.displayname="JOGL Graph UI Demo01"
-          noddraw.check="true"
-          progressbar="true"
-          jnlpNumExtensions="1"
-          jnlpExtension1="jogl-all-awt.jnlp"
-          java_arguments="-Dsun.java2d.noddraw=true"
           gl_event_listener_class="com.jogamp.opengl.test.junit.graph.demos.GPUUISceneGLListener0A"
           gl_profile="GL2ES2"
           gl_swap_interval="1"
@@ -78,6 +60,9 @@ JOGL NEWT JNLP Applet Runner Special Keys:<br>
     <li> f - toggle fullscreen </li>
     <li> r - in/out browser window </li>
     <li> a - on/off always-on-top </li>
+    <li> c - change mouse pointer </li>
+    <li> i - invisible mouse pointer </li>
+    <li> w - warp mouse pointer to center </li>
 </ul>
 </P>
 
diff --git a/jnlp-files/jogl-applet-runner-newt-MovieCube-napplet.html b/jnlp-files/jogl-applet-runner-newt-MovieCube-applet3-napplet.html
similarity index 79%
copy from jnlp-files/jogl-applet-runner-newt-MovieCube-napplet.html
copy to jnlp-files/jogl-applet-runner-newt-MovieCube-applet3-napplet.html
index 5dc77f0..590bf30 100644
--- a/jnlp-files/jogl-applet-runner-newt-MovieCube-napplet.html
+++ b/jnlp-files/jogl-applet-runner-newt-MovieCube-applet3-napplet.html
@@ -1,39 +1,37 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
 <html>
 <head>
-<title>JogAmp's MovieCube - GLMediaPlayer Demo 01 (NApplet)</title>
+<title>JogAmp's Applet3 MovieCube - GLMediaPlayer Demo 01 (NApplet)</title>
 </head>
 <body  BGCOLOR="#ffffff">
 
 <P>
-JogAmp's MovieCube - GLMediaPlayer Demo 01
+JogAmp's Applet3 MovieCube - GLMediaPlayer Demo 01
 </P>
 
 <P>
 <object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
       width="510" height="300">
-   <param name="code" value="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run">
+   <param name="code" value="com.jogamp.newt.util.applet.JOGLNewtApplet3Run">
    <param name="archive" value="jar/gluegen-rt.jar,
                                 jar/joal.jar,
-                                jar/jogl-all.jar,
+                                jar/jogl-all-noawt.jar,
                                 jar/jogl-test.jar">
-   <param name="java_arguments" value="-Dsun.java2d.noddraw=true">
    <param name="gl_event_listener_class" value="com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieCube">
    <param name="gl_profile" value="GL2ES2">
    <param name="gl_swap_interval" value="1">
    <param name="gl_debug" value="false">
    <param name="gl_trace" value="false">
    <comment>
-     <embed code="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run"
+     <embed code="com.jogamp.newt.util.applet.JOGLNewtApplet3Run"
           width="510" height="300"
           type="application/x-java-applet;version=1.6"
           pluginspage="http://java.sun.com/javase/downloads/ea.jsp"
           archive="jar/gluegen-rt.jar,
                    jar/joal.jar,
-                   jar/jogl-all.jar,
+                   jar/jogl-all-noawt.jar,
                    jar/jogl-test.jar"
           codebase_lookup" value="false"
-          java_arguments="-Dsun.java2d.noddraw=true"
           gl_event_listener_class="com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieCube"
           gl_profile="GL2ES2"
           gl_swap_interval="1"
@@ -72,6 +70,9 @@ JOGL NEWT JNLP Applet Runner Special Keys:<br>
     <li> f - toggle fullscreen </li>
     <li> r - in/out browser window </li>
     <li> a - on/off always-on-top </li>
+    <li> c - change mouse pointer </li>
+    <li> i - invisible mouse pointer </li>
+    <li> w - warp mouse pointer to center </li>
 </ul>
 </P>
 
diff --git a/jnlp-files/jogl-applet-runner-newt-MovieCube-napplet.html b/jnlp-files/jogl-applet-runner-newt-MovieCube-napplet.html
index 5dc77f0..3630a15 100644
--- a/jnlp-files/jogl-applet-runner-newt-MovieCube-napplet.html
+++ b/jnlp-files/jogl-applet-runner-newt-MovieCube-napplet.html
@@ -17,7 +17,6 @@ JogAmp's MovieCube - GLMediaPlayer Demo 01
                                 jar/joal.jar,
                                 jar/jogl-all.jar,
                                 jar/jogl-test.jar">
-   <param name="java_arguments" value="-Dsun.java2d.noddraw=true">
    <param name="gl_event_listener_class" value="com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieCube">
    <param name="gl_profile" value="GL2ES2">
    <param name="gl_swap_interval" value="1">
@@ -33,7 +32,6 @@ JogAmp's MovieCube - GLMediaPlayer Demo 01
                    jar/jogl-all.jar,
                    jar/jogl-test.jar"
           codebase_lookup" value="false"
-          java_arguments="-Dsun.java2d.noddraw=true"
           gl_event_listener_class="com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieCube"
           gl_profile="GL2ES2"
           gl_swap_interval="1"
@@ -72,6 +70,9 @@ JOGL NEWT JNLP Applet Runner Special Keys:<br>
     <li> f - toggle fullscreen </li>
     <li> r - in/out browser window </li>
     <li> a - on/off always-on-top </li>
+    <li> c - change mouse pointer </li>
+    <li> i - invisible mouse pointer </li>
+    <li> w - warp mouse pointer to center </li>
 </ul>
 </P>
 
diff --git a/jnlp-files/jogl-applet-runner-newt-MovieCube.html b/jnlp-files/jogl-applet-runner-newt-MovieCube.html
index a154eb8..ba9a25c 100644
--- a/jnlp-files/jogl-applet-runner-newt-MovieCube.html
+++ b/jnlp-files/jogl-applet-runner-newt-MovieCube.html
@@ -12,20 +12,11 @@ JogAmp's MovieCube - GLMediaPlayer Demo 01
 <P>
 <object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
       width="510" height="300">
-   <param name="code" value="org.jdesktop.applet.util.JNLPAppletLauncher">
-   <param name="archive" value="jar/applet-launcher.jar,
-                                jar/gluegen-rt.jar,
+   <param name="code" value="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run">
+   <param name="archive" value="jar/gluegen-rt.jar,
                                 jar/joal.jar,
                                 jar/jogl-all.jar,
                                 jar/jogl-test.jar">
-   <param name="codebase_lookup" value="false">
-   <param name="subapplet.classname" value="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run">
-   <param name="subapplet.displayname" value="MovieCube">
-   <param name="noddraw.check" value="true">
-   <param name="progressbar" value="true">
-   <param name="jnlpNumExtensions" value="1">
-   <param name="jnlpExtension1" value="jogl-all-awt.jnlp">
-   <param name="java_arguments" value="-Dsun.java2d.noddraw=true">
    <param name="gl_event_listener_class" value="com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieCube">
    <param name="gl_profile" value="GL2ES2">
    <param name="gl_swap_interval" value="1">
@@ -33,23 +24,14 @@ JogAmp's MovieCube - GLMediaPlayer Demo 01
    <param name="gl_trace" value="false">
    <param name="jnlp_href" value="jogl-applet-runner-newt.jnlp">
    <comment>
-     <embed code="org.jdesktop.applet.util.JNLPAppletLauncher"
+     <embed code="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run"
           width="510" height="300"
           type="application/x-java-applet;version=1.6"
           pluginspage="http://java.sun.com/javase/downloads/ea.jsp"
-          archive="jar/applet-launcher.jar,
-                   jar/gluegen-rt.jar,
+          archive="jar/gluegen-rt.jar,
                    jar/joal.jar,
                    jar/jogl-all.jar,
                    jar/jogl-test.jar"
-          codebase_lookup" value="false"
-          subapplet.classname="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run"
-          subapplet.displayname="MovieCube"
-          noddraw.check="true"
-          progressbar="true"
-          jnlpNumExtensions="1"
-          jnlpExtension1="jogl-all-awt.jnlp"
-          java_arguments="-Dsun.java2d.noddraw=true"
           gl_event_listener_class="com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieCube"
           gl_profile="GL2ES2"
           gl_swap_interval="1"
@@ -89,6 +71,9 @@ JOGL NEWT JNLP Applet Runner Special Keys:<br>
     <li> f - toggle fullscreen </li>
     <li> r - in/out browser window </li>
     <li> a - on/off always-on-top </li>
+    <li> c - change mouse pointer </li>
+    <li> i - invisible mouse pointer </li>
+    <li> w - warp mouse pointer to center </li>
 </ul>
 </P>
 
diff --git a/jnlp-files/jogl-applet-runner-newt-gears-normal-napplet2.html b/jnlp-files/jogl-applet-runner-newt-gears-applet3-napplet.html
similarity index 64%
copy from jnlp-files/jogl-applet-runner-newt-gears-normal-napplet2.html
copy to jnlp-files/jogl-applet-runner-newt-gears-applet3-napplet.html
index 8970aea..ef287c7 100644
--- a/jnlp-files/jogl-applet-runner-newt-gears-normal-napplet2.html
+++ b/jnlp-files/jogl-applet-runner-newt-gears-applet3-napplet.html
@@ -1,48 +1,50 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
 <html>
 <head>
-<title>JOGL NEWT Applet Runner - GearsES2 - normal - (NApplet)  - Closeable</title>
+<title>JOGL NEWT Applet3 Runner - GearsES2 - normal - (NApplet) </title>
 </head>
 <body  BGCOLOR="#ffffff">
 
-<P>
-JOGL NEWT Applet Runner Special Keys:<br>
+<p>
+Applet3 (w/o AWT) launching using <a href="http://jogamp.org/jogl/doc/deployment/JOGL-DEPLOYMENT.html#NApplets">NApplet</a>.
+</p>
+
+<p>
+JOGL NEWT Applet3 Runner Special Keys:<br>
 <ul>
     <li> d - toggle decoration </li>
     <li> f - toggle fullscreen </li>
     <li> r - in/out browser window </li>
     <li> a - on/off always-on-top </li>
+    <li> c - change mouse pointer </li>
+    <li> i - invisible mouse pointer </li>
+    <li> w - warp mouse pointer to center </li>
 </ul>
-If Applet is out of browser window, it is closeable.
-</P>
+</p>
 
-<P>
+<p>
 <object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
       width="200" height="200">
-   <param name="code" value="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run">
+   <param name="code" value="com.jogamp.newt.util.applet.JOGLNewtApplet3Run">
    <param name="archive" value="jar/gluegen-rt.jar,
-                                jar/jogl-all.jar,
+                                jar/jogl-all-noawt.jar,
                                 jar/jogl-test.jar">
-   <param name="java_arguments" value="-Dsun.java2d.noddraw=true">
    <param name="gl_event_listener_class" value="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2">
    <param name="gl_profile" value="GL2ES2">
    <param name="gl_swap_interval" value="1">
-   <param name="gl_closeable" value="true">
    <param name="gl_debug" value="false">
    <param name="gl_trace" value="false">
    <comment>
-     <embed code="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run"
+     <embed code="com.jogamp.newt.util.applet.JOGLNewtApplet3Run"
           width="200" height="200"
           type="application/x-java-applet;version=1.6"
           pluginspage="http://java.sun.com/javase/downloads/ea.jsp"
           archive="jar/gluegen-rt.jar,
-                   jar/jogl-all.jar,
+                   jar/jogl-all-noawt.jar,
                    jar/jogl-test.jar"
-          java_arguments="-Dsun.java2d.noddraw=true"
           gl_event_listener_class="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2"
           gl_profile="GL2ES2"
           gl_swap_interval="1"
-          gl_closeable="true"
           gl_debug="false"
           gl_trace="false">
         <noembed>Sorry, no Java support detected.</noembed>
@@ -50,39 +52,35 @@ If Applet is out of browser window, it is closeable.
    </comment>
 </object>
 
-</P>
+</p>
 
-<P>
+<p>
 
 The applet above is instantiated with the following code:
 
 <pre>
 <object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
       width="200" height="200">
-   <param name="code" value="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run">
+   <param name="code" value="com.jogamp.newt.util.applet.JOGLNewtApplet3Run">
    <param name="archive" value="jar/gluegen-rt.jar,
-                                jar/jogl-all.jar,
+                                jar/jogl-all-noawt.jar,
                                 jar/jogl-test.jar">
-   <param name="java_arguments" value="-Dsun.java2d.noddraw=true">
    <param name="gl_event_listener_class" value="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2">
    <param name="gl_profile" value="GL2ES2">
    <param name="gl_swap_interval" value="1">
-   <param name="gl_closeable" value="true">
    <param name="gl_debug" value="false">
    <param name="gl_trace" value="false">
    <comment>
-     <embed code="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run"
+     <embed code="com.jogamp.newt.util.applet.JOGLNewtApplet3Run"
           width="200" height="200"
           type="application/x-java-applet;version=1.6"
           pluginspage="http://java.sun.com/javase/downloads/ea.jsp"
           archive="jar/gluegen-rt.jar,
-                   jar/jogl-all.jar,
+                   jar/jogl-all-noawt.jar,
                    jar/jogl-test.jar"
-          java_arguments="-Dsun.java2d.noddraw=true"
           gl_event_listener_class="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2"
           gl_profile="GL2ES2"
           gl_swap_interval="1"
-          gl_closeable="true"
           gl_debug="false"
           gl_trace="false">
         <noembed>Sorry, no Java support detected.</noembed>
@@ -92,17 +90,24 @@ The applet above is instantiated with the following code:
 
 </pre>
 
-</P>
-<P>
-
-Note that the jogl-test.jar, which contains the test applet class,
+</p>
+<p>
+<del>
+Note that the jogl-test.jar, which contains the GearsES2 class,
 <B>does not need to be signed</B>! JogAmp Community signs
-jogl.jar and gluegen-rt.jar, which contain
+jogl-all.jar and gluegen-rt.jar, which contain the
 JOGL's supporting classes; this is the only
 Java code which needs to be signed in order to deploy applets using
 JOGL and is the only certificate the end user must accept.
-
-</P>
+</del><br/>
+Sadly, due to Oracle's Java Applet Plugin update 7u51,
+unsigned applets are no more allowed and effectively 
+lower the bar to create user applets with raised privileges.<br/>
+Hence JogAmp Community <b>signs</b> jogl-all.jar and gluegen-rt.jar, which contain the
+JOGL's supporting classes as well as jogl-test.jar, which contains the users implementing Applet class.<br/>
+jogl-test.jar's manifest file uses <i>Permissions: sandbox</i>
+to <b>not raise privileges</b>.
+</p>
 
 </body>
 </html>
diff --git a/jnlp-files/jogl-applet-runner-newt-gears-special-napplet.html b/jnlp-files/jogl-applet-runner-newt-gears-applet3-special-napplet.html
similarity index 81%
copy from jnlp-files/jogl-applet-runner-newt-gears-special-napplet.html
copy to jnlp-files/jogl-applet-runner-newt-gears-applet3-special-napplet.html
index 7df1678..821d8f4 100644
--- a/jnlp-files/jogl-applet-runner-newt-gears-special-napplet.html
+++ b/jnlp-files/jogl-applet-runner-newt-gears-applet3-special-napplet.html
@@ -1,19 +1,18 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
 <html>
 <head>
-<title>JOGL NEWT JNLP Applet Runner - GearsES2 - special (NApplet)</title>
+<title>JOGL NEWT JNLP Applet3 Runner - GearsES2 - special (NApplet)</title>
 </head>
 <body  BGCOLOR="#ffffff">
 
 <P>
-JOGL NEWT JNLP Applet Runner Special Keys:
+JOGL NEWT JNLP Applet3 Runner Special Keys:
 <object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
       width="1" height="1">
-   <param name="code" value="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run">
+   <param name="code" value="com.jogamp.newt.util.applet.JOGLNewtApplet3Run">
    <param name="archive" value="jar/gluegen-rt.jar,
-                                jar/jogl-all.jar,
+                                jar/jogl-all-noawt.jar,
                                 jar/jogl-test.jar">
-   <param name="java_arguments" value="-Dsun.java2d.noddraw=true">
    <param name="gl_event_listener_class" value="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2">
    <param name="gl_profile" value="GL2ES2">
    <param name="gl_swap_interval" value="1">
@@ -27,14 +26,13 @@ JOGL NEWT JNLP Applet Runner Special Keys:
    <param name="gl_debug" value="false">
    <param name="gl_trace" value="false">
    <comment>
-     <embed code="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run"
+     <embed code="com.jogamp.newt.util.applet.JOGLNewtApplet3Run"
           width="1" height="1"
           type="application/x-java-applet;version=1.6"
           pluginspage="http://java.sun.com/javase/downloads/ea.jsp"
           archive="jar/gluegen-rt.jar,
-                   jar/jogl-all.jar,
+                   jar/jogl-all-noawt.jar,
                    jar/jogl-test.jar"
-          java_arguments="-Dsun.java2d.noddraw=true"
           gl_event_listener_class="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2"
           gl_profile="GL2ES2"
           gl_swap_interval="1"
@@ -57,6 +55,9 @@ JOGL NEWT JNLP Applet Runner Special Keys:
     <li> f - toggle fullscreen </li>
     <li> r - in/out browser window </li>
     <li> a - on/off always-on-top </li>
+    <li> c - change mouse pointer </li>
+    <li> i - invisible mouse pointer </li>
+    <li> w - warp mouse pointer to center </li>
 </ul>
 Normal webpage text - Normal webpage text - Normal webpage text - Normal webpage text<br>
 Normal webpage text - Normal webpage text - Normal webpage text - Normal webpage text<br>
diff --git a/jnlp-files/jogl-applet-runner-newt-gears-gl3-napplet.html b/jnlp-files/jogl-applet-runner-newt-gears-gl3-napplet.html
index cb2375e..c0861ee 100644
--- a/jnlp-files/jogl-applet-runner-newt-gears-gl3-napplet.html
+++ b/jnlp-files/jogl-applet-runner-newt-gears-gl3-napplet.html
@@ -5,24 +5,30 @@
 </head>
 <body  BGCOLOR="#ffffff">
 
-<P>
+<p>
+Applet launching using <a href="http://jogamp.org/jogl/doc/deployment/JOGL-DEPLOYMENT.html#NApplets">NApplet</a>.
+</p>
+
+<p>
 JOGL NEWT Applet Runner Special Keys:<br>
 <ul>
     <li> d - toggle decoration </li>
     <li> f - toggle fullscreen </li>
     <li> r - in/out browser window </li>
     <li> a - on/off always-on-top </li>
+    <li> c - change mouse pointer </li>
+    <li> i - invisible mouse pointer </li>
+    <li> w - warp mouse pointer to center </li>
 </ul>
-</P>
+</p>
 
-<P>
+<p>
 <object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
       width="200" height="200">
    <param name="code" value="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run">
    <param name="archive" value="jar/gluegen-rt.jar,
                                 jar/jogl-all.jar,
                                 jar/jogl-test.jar">
-   <param name="java_arguments" value="-Dsun.java2d.noddraw=true">
    <param name="gl_event_listener_class" value="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2">
    <param name="gl_profile" value="GL3">
    <param name="gl_swap_interval" value="1">
@@ -36,7 +42,6 @@ JOGL NEWT Applet Runner Special Keys:<br>
           archive="jar/gluegen-rt.jar,
                    jar/jogl-all.jar,
                    jar/jogl-test.jar"
-          java_arguments="-Dsun.java2d.noddraw=true"
           gl_event_listener_class="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2"
           gl_profile="GL3"
           gl_swap_interval="1"
@@ -47,13 +52,13 @@ JOGL NEWT Applet Runner Special Keys:<br>
    </comment>
 </object>
 
-</P>
+</p>
 
-<P>
+<p>
 Applet is using a GL3 core context, failure is expected if n/a on your platform!
-</P>
+</p>
 
-<P>
+<p>
 
 The applet above is instantiated with the following code:
 
@@ -64,7 +69,6 @@ The applet above is instantiated with the following code:
    <param name="archive" value="jar/gluegen-rt.jar,
                                 jar/jogl-all.jar,
                                 jar/jogl-test.jar">
-   <param name="java_arguments" value="-Dsun.java2d.noddraw=true">
    <param name="gl_event_listener_class" value="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2">
    <param name="gl_profile" value="GL3">
    <param name="gl_swap_interval" value="1">
@@ -78,7 +82,6 @@ The applet above is instantiated with the following code:
           archive="jar/gluegen-rt.jar,
                    jar/jogl-all.jar,
                    jar/jogl-test.jar"
-          java_arguments="-Dsun.java2d.noddraw=true"
           gl_event_listener_class="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2"
           gl_profile="GL3"
           gl_swap_interval="1"
@@ -91,17 +94,24 @@ The applet above is instantiated with the following code:
 
 </pre>
 
-</P>
-<P>
-
-Note that the jogl-test.jar, which contains the test applet class,
+</p>
+<p>
+<del>
+Note that the jogl-test.jar, which contains the GearsES2 class,
 <B>does not need to be signed</B>! JogAmp Community signs
-jogl.jar and gluegen-rt.jar, which contain
+jogl-all.jar and gluegen-rt.jar, which contain the
 JOGL's supporting classes; this is the only
 Java code which needs to be signed in order to deploy applets using
 JOGL and is the only certificate the end user must accept.
-
-</P>
+</del><br/>
+Sadly, due to Oracle's Java Applet Plugin update 7u51,
+unsigned applets are no more allowed and effectively 
+lower the bar to create user applets with raised privileges.<br/>
+Hence JogAmp Community <b>signs</b> jogl-all.jar and gluegen-rt.jar, which contain the
+JOGL's supporting classes as well as jogl-test.jar, which contains the users implementing Applet class.<br/>
+jogl-test.jar's manifest file uses <i>Permissions: sandbox</i>
+to <b>not raise privileges</b>.
+</p>
 
 </body>
 </html>
diff --git a/jnlp-files/jogl-applet-runner-newt-gears-normal-launcheronly.html b/jnlp-files/jogl-applet-runner-newt-gears-normal-launcheronly.html
deleted file mode 100644
index a9e42d3..0000000
--- a/jnlp-files/jogl-applet-runner-newt-gears-normal-launcheronly.html
+++ /dev/null
@@ -1,143 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html>
-<head>
-<title>JOGL NEWT JNLP Applet Runner - GearsES2 - normal - launcheronly</title>
-</head>
-<body  BGCOLOR="#ffffff">
-
-<P>
-JOGL NEWT JNLP Applet Runner Special Keys:<br>
-<ul>
-    <li> d - toggle decoration </li>
-    <li> f - toggle fullscreen </li>
-    <li> r - in/out browser window </li>
-    <li> a - on/off always-on-top </li>
-</ul>
-</P>
-
-<P>
-<object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
-      width="200" height="200">
-   <param name="code" value="org.jdesktop.applet.util.JNLPAppletLauncher">
-   <param name="archive" value="jar/applet-launcher.jar,
-                                jar/gluegen-rt.jar,
-                                jar/jogl-all.jar,
-                                jar/jogl-test.jar">
-   <param name="codebase_lookup" value="false">
-   <param name="subapplet.classname" value="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run">
-   <param name="subapplet.displayname" value="JOGL GearsES2 Applet">
-   <param name="noddraw.check" value="true">
-   <param name="progressbar" value="true">
-   <param name="jnlpNumExtensions" value="1">
-   <param name="jnlpExtension1" value="jogl-all-awt.jnlp">
-   <param name="java_arguments" value="-Dsun.java2d.noddraw=true">
-   <param name="gl_event_listener_class" value="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2">
-   <param name="gl_profile" value="GL2ES2">
-   <param name="gl_swap_interval" value="1">
-   <param name="gl_debug" value="false">
-   <param name="gl_trace" value="false">
-   <comment>
-     <embed code="org.jdesktop.applet.util.JNLPAppletLauncher"
-          width="200" height="200"
-          type="application/x-java-applet;version=1.6"
-          pluginspage="http://java.sun.com/javase/downloads/ea.jsp"
-          archive="jar/applet-launcher.jar,
-                   jar/gluegen-rt.jar,
-                   jar/jogl-all.jar,
-                   jar/jogl-test.jar"
-          codebase_lookup" value="false"
-          subapplet.classname="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run"
-          subapplet.displayname="JOGL GearsES2 Applet"
-          noddraw.check="true"
-          progressbar="true"
-          jnlpNumExtensions="1"
-          jnlpExtension1="jogl-all-awt.jnlp"
-          java_arguments="-Dsun.java2d.noddraw=true"
-          gl_event_listener_class="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2"
-          gl_profile="GL2ES2"
-          gl_swap_interval="1"
-          gl_debug="false"
-          gl_trace="false">
-        <noembed>Sorry, no Java support detected.</noembed>
-     </embed>
-   </comment>
-</object>
-
-</P>
-
-<P>
-
-The applet above is instantiated with the following code:
-
-<pre>
-<object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
-      width="200" height="200">
-   <param name="code" value="org.jdesktop.applet.util.JNLPAppletLauncher">
-   <param name="archive" value="jar/applet-launcher.jar,
-                                jar/gluegen-rt.jar,
-                                jar/jogl-all.jar,
-                                jar/jogl-test.jar">
-   <param name="codebase_lookup" value="false">
-   <param name="subapplet.classname" value="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run">
-   <param name="subapplet.displayname" value="JOGL GearsES2 Applet">
-   <param name="noddraw.check" value="true">
-   <param name="progressbar" value="true">
-   <param name="jnlpNumExtensions" value="1">
-   <param name="jnlpExtension1" value="jogl-all-awt.jnlp">
-   <param name="java_arguments" value="-Dsun.java2d.noddraw=true">
-   <param name="gl_event_listener_class" value="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2">
-   <param name="gl_profile" value="GL2ES2">
-   <param name="gl_swap_interval" value="1">
-   <param name="gl_debug" value="false">
-   <param name="gl_trace" value="false">
-   <comment>
-     <embed code="org.jdesktop.applet.util.JNLPAppletLauncher"
-          width="200" height="200"
-          type="application/x-java-applet;version=1.6"
-          pluginspage="http://java.sun.com/javase/downloads/ea.jsp"
-          archive="jar/applet-launcher.jar,
-                   jar/gluegen-rt.jar,
-                   jar/jogl-all.jar,
-                   jar/jogl-test.jar"
-          codebase_lookup" value="false"
-          subapplet.classname="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run"
-          subapplet.displayname="JOGL GearsES2 Applet"
-          noddraw.check="true"
-          progressbar="true"
-          jnlpNumExtensions="1"
-          jnlpExtension1="jogl-all-awt.jnlp"
-          java_arguments="-Dsun.java2d.noddraw=true"
-          gl_event_listener_class="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2"
-          gl_profile="GL2ES2"
-          gl_swap_interval="1"
-          gl_debug="false"
-          gl_trace="false">
-        <noembed>Sorry, no Java support detected.</noembed>
-     </embed>
-   </comment>
-</object>
-
-</pre>
-
-</P>
-<P>
-
-Note that the jogl-demos.jar, which contains the GearsApplet class,
-<B>does not need to be signed</B>! JogAmp Community signs
-applet-launcher.jar, jogl.jar and gluegen-rt.jar, which contain the
-JNLPAppletLauncher and JOGL's supporting classes; this is the only
-Java code which needs to be signed in order to deploy applets using
-JOGL and is the only certificate the end user must accept.
-
-</P>
-<P>
-
-The <a href="http://jogamp.org/applet-launcher/www/">JNLPAppletLauncher
-home page</a> contains more information about what files must be
-placed on the web server in order to enable the deployment of applets
-using JOGL and other extensions.
-
-</P>
-
-</body>
-</html>
diff --git a/jnlp-files/jogl-applet-runner-newt-gears-normal-napplet.html b/jnlp-files/jogl-applet-runner-newt-gears-normal-napplet.html
index 9b44839..be3c95d 100644
--- a/jnlp-files/jogl-applet-runner-newt-gears-normal-napplet.html
+++ b/jnlp-files/jogl-applet-runner-newt-gears-normal-napplet.html
@@ -5,24 +5,30 @@
 </head>
 <body  BGCOLOR="#ffffff">
 
-<P>
+<p>
+Applet launching using <a href="http://jogamp.org/jogl/doc/deployment/JOGL-DEPLOYMENT.html#NApplets">NApplet</a>.
+</p>
+
+<p>
 JOGL NEWT Applet Runner Special Keys:<br>
 <ul>
     <li> d - toggle decoration </li>
     <li> f - toggle fullscreen </li>
     <li> r - in/out browser window </li>
     <li> a - on/off always-on-top </li>
+    <li> c - change mouse pointer </li>
+    <li> i - invisible mouse pointer </li>
+    <li> w - warp mouse pointer to center </li>
 </ul>
-</P>
+</p>
 
-<P>
+<p>
 <object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
       width="200" height="200">
    <param name="code" value="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run">
    <param name="archive" value="jar/gluegen-rt.jar,
                                 jar/jogl-all.jar,
                                 jar/jogl-test.jar">
-   <param name="java_arguments" value="-Dsun.java2d.noddraw=true">
    <param name="gl_event_listener_class" value="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2">
    <param name="gl_profile" value="GL2ES2">
    <param name="gl_swap_interval" value="1">
@@ -36,7 +42,6 @@ JOGL NEWT Applet Runner Special Keys:<br>
           archive="jar/gluegen-rt.jar,
                    jar/jogl-all.jar,
                    jar/jogl-test.jar"
-          java_arguments="-Dsun.java2d.noddraw=true"
           gl_event_listener_class="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2"
           gl_profile="GL2ES2"
           gl_swap_interval="1"
@@ -47,9 +52,9 @@ JOGL NEWT Applet Runner Special Keys:<br>
    </comment>
 </object>
 
-</P>
+</p>
 
-<P>
+<p>
 
 The applet above is instantiated with the following code:
 
@@ -60,7 +65,6 @@ The applet above is instantiated with the following code:
    <param name="archive" value="jar/gluegen-rt.jar,
                                 jar/jogl-all.jar,
                                 jar/jogl-test.jar">
-   <param name="java_arguments" value="-Dsun.java2d.noddraw=true">
    <param name="gl_event_listener_class" value="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2">
    <param name="gl_profile" value="GL2ES2">
    <param name="gl_swap_interval" value="1">
@@ -74,7 +78,6 @@ The applet above is instantiated with the following code:
           archive="jar/gluegen-rt.jar,
                    jar/jogl-all.jar,
                    jar/jogl-test.jar"
-          java_arguments="-Dsun.java2d.noddraw=true"
           gl_event_listener_class="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2"
           gl_profile="GL2ES2"
           gl_swap_interval="1"
@@ -87,17 +90,24 @@ The applet above is instantiated with the following code:
 
 </pre>
 
-</P>
-<P>
-
-Note that the jogl-test.jar, which contains the test applet class,
+</p>
+<p>
+<del>
+Note that the jogl-test.jar, which contains the GearsES2 class,
 <B>does not need to be signed</B>! JogAmp Community signs
-jogl.jar and gluegen-rt.jar, which contain
+jogl-all.jar and gluegen-rt.jar, which contain the
 JOGL's supporting classes; this is the only
 Java code which needs to be signed in order to deploy applets using
 JOGL and is the only certificate the end user must accept.
-
-</P>
+</del><br/>
+Sadly, due to Oracle's Java Applet Plugin update 7u51,
+unsigned applets are no more allowed and effectively 
+lower the bar to create user applets with raised privileges.<br/>
+Hence JogAmp Community <b>signs</b> jogl-all.jar and gluegen-rt.jar, which contain the
+JOGL's supporting classes as well as jogl-test.jar, which contains the users implementing Applet class.<br/>
+jogl-test.jar's manifest file uses <i>Permissions: sandbox</i>
+to <b>not raise privileges</b>.
+</p>
 
 </body>
 </html>
diff --git a/jnlp-files/jogl-applet-runner-newt-gears-normal-napplet2.html b/jnlp-files/jogl-applet-runner-newt-gears-normal-napplet2.html
index 8970aea..919c29f 100644
--- a/jnlp-files/jogl-applet-runner-newt-gears-normal-napplet2.html
+++ b/jnlp-files/jogl-applet-runner-newt-gears-normal-napplet2.html
@@ -5,25 +5,31 @@
 </head>
 <body  BGCOLOR="#ffffff">
 
-<P>
+<p>
+Applet launching using <a href="http://jogamp.org/jogl/doc/deployment/JOGL-DEPLOYMENT.html#NApplets">NApplet</a>.
+</p>
+
+<p>
 JOGL NEWT Applet Runner Special Keys:<br>
 <ul>
     <li> d - toggle decoration </li>
     <li> f - toggle fullscreen </li>
     <li> r - in/out browser window </li>
     <li> a - on/off always-on-top </li>
+    <li> c - change mouse pointer </li>
+    <li> i - invisible mouse pointer </li>
+    <li> w - warp mouse pointer to center </li>
 </ul>
 If Applet is out of browser window, it is closeable.
-</P>
+</p>
 
-<P>
+<p>
 <object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
       width="200" height="200">
    <param name="code" value="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run">
    <param name="archive" value="jar/gluegen-rt.jar,
                                 jar/jogl-all.jar,
                                 jar/jogl-test.jar">
-   <param name="java_arguments" value="-Dsun.java2d.noddraw=true">
    <param name="gl_event_listener_class" value="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2">
    <param name="gl_profile" value="GL2ES2">
    <param name="gl_swap_interval" value="1">
@@ -38,7 +44,6 @@ If Applet is out of browser window, it is closeable.
           archive="jar/gluegen-rt.jar,
                    jar/jogl-all.jar,
                    jar/jogl-test.jar"
-          java_arguments="-Dsun.java2d.noddraw=true"
           gl_event_listener_class="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2"
           gl_profile="GL2ES2"
           gl_swap_interval="1"
@@ -50,9 +55,9 @@ If Applet is out of browser window, it is closeable.
    </comment>
 </object>
 
-</P>
+</p>
 
-<P>
+<p>
 
 The applet above is instantiated with the following code:
 
@@ -63,7 +68,6 @@ The applet above is instantiated with the following code:
    <param name="archive" value="jar/gluegen-rt.jar,
                                 jar/jogl-all.jar,
                                 jar/jogl-test.jar">
-   <param name="java_arguments" value="-Dsun.java2d.noddraw=true">
    <param name="gl_event_listener_class" value="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2">
    <param name="gl_profile" value="GL2ES2">
    <param name="gl_swap_interval" value="1">
@@ -78,7 +82,6 @@ The applet above is instantiated with the following code:
           archive="jar/gluegen-rt.jar,
                    jar/jogl-all.jar,
                    jar/jogl-test.jar"
-          java_arguments="-Dsun.java2d.noddraw=true"
           gl_event_listener_class="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2"
           gl_profile="GL2ES2"
           gl_swap_interval="1"
@@ -92,17 +95,24 @@ The applet above is instantiated with the following code:
 
 </pre>
 
-</P>
-<P>
-
-Note that the jogl-test.jar, which contains the test applet class,
+</p>
+<p>
+<del>
+Note that the jogl-test.jar, which contains the GearsES2 class,
 <B>does not need to be signed</B>! JogAmp Community signs
-jogl.jar and gluegen-rt.jar, which contain
+jogl-all.jar and gluegen-rt.jar, which contain the
 JOGL's supporting classes; this is the only
 Java code which needs to be signed in order to deploy applets using
 JOGL and is the only certificate the end user must accept.
-
-</P>
+</del><br/>
+Sadly, due to Oracle's Java Applet Plugin update 7u51,
+unsigned applets are no more allowed and effectively 
+lower the bar to create user applets with raised privileges.<br/>
+Hence JogAmp Community <b>signs</b> jogl-all.jar and gluegen-rt.jar, which contain the
+JOGL's supporting classes as well as jogl-test.jar, which contains the users implementing Applet class.<br/>
+jogl-test.jar's manifest file uses <i>Permissions: sandbox</i>
+to <b>not raise privileges</b>.
+</p>
 
 </body>
 </html>
diff --git a/jnlp-files/jogl-applet-runner-newt-gears-normal.html b/jnlp-files/jogl-applet-runner-newt-gears-normal.html
index a6dd16a..f6efeb1 100644
--- a/jnlp-files/jogl-applet-runner-newt-gears-normal.html
+++ b/jnlp-files/jogl-applet-runner-newt-gears-normal.html
@@ -5,46 +5,40 @@
 </head>
 <body  BGCOLOR="#ffffff">
 
-<P>
-In case your <a href="https://jdk6.dev.java.net/plugin2/jnlp/">Java Plugin supports JNLP</a>, 
-the <em>jogl-applet-runner-newt.jnlp</em> is used, 
-otherwise it shall fallback to <a href="http://jogamp.org/applet-launcher/www/">JNLPAppletLauncher</a>.
-</P>
+<p>
+In case your <a href="https://jdk6.dev.java.net/plugin2/jnlp/">Java Plugin supports JNLP</a>,
+the <em>applet-gears.jnlp</em> is used,
+otherwise it shall fallback to <a href="http://jogamp.org/jogl/doc/deployment/JOGL-DEPLOYMENT.html#NApplets">NApplets</a>.
+</p>
 
-<P>
+<p>
 Note that it is important for the startup time to have the same JVM arguments in the applet tags,
-as well as within the JNLP applet description, here see property <em>sun.java2d.noddraw</em>. <br>
+as well as within the JNLP applet description. <br>
 Only if JVM arguments of the JNLP applet description are satisfied by the applet tag's JVM,<br>
 the plugin will not need to start a new JVM. OF course, the applet tag's JVM spec may exceed the
 JNLP applet's one.
-</P>
+</p>
 
-<P>
+<p>
 JOGL NEWT JNLP Applet Runner Special Keys:<br>
 <ul>
     <li> d - toggle decoration </li>
     <li> f - toggle fullscreen </li>
     <li> r - in/out browser window </li>
     <li> a - on/off always-on-top </li>
+    <li> c - change mouse pointer </li>
+    <li> i - invisible mouse pointer </li>
+    <li> w - warp mouse pointer to center </li>
 </ul>
-</P>
+</p>
 
-<P>
+<p>
 <object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
       width="200" height="200">
-   <param name="code" value="org.jdesktop.applet.util.JNLPAppletLauncher">
-   <param name="archive" value="jar/applet-launcher.jar,
-                                jar/gluegen-rt.jar,
+   <param name="code" value="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run">
+   <param name="archive" value="jar/gluegen-rt.jar,
                                 jar/jogl-all.jar,
                                 jar/jogl-test.jar">
-   <param name="codebase_lookup" value="false">
-   <param name="subapplet.classname" value="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run">
-   <param name="subapplet.displayname" value="JOGL GearsES2 Applet">
-   <param name="noddraw.check" value="true">
-   <param name="progressbar" value="true">
-   <param name="jnlpNumExtensions" value="1">
-   <param name="jnlpExtension1" value="jogl-all-awt.jnlp">
-   <param name="java_arguments" value="-Dsun.java2d.noddraw=true">
    <param name="gl_event_listener_class" value="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2">
    <param name="gl_profile" value="GL2ES2">
    <param name="gl_swap_interval" value="1">
@@ -52,22 +46,13 @@ JOGL NEWT JNLP Applet Runner Special Keys:<br>
    <param name="gl_trace" value="false">
    <param name="jnlp_href" value="jogl-applet-runner-newt.jnlp">
    <comment>
-     <embed code="org.jdesktop.applet.util.JNLPAppletLauncher"
+     <embed code="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run"
           width="200" height="200"
           type="application/x-java-applet;version=1.6"
           pluginspage="http://java.sun.com/javase/downloads/ea.jsp"
-          archive="jar/applet-launcher.jar,
-                   jar/gluegen-rt.jar,
+          archive="jar/gluegen-rt.jar,
                    jar/jogl-all.jar,
                    jar/jogl-test.jar"
-          codebase_lookup" value="false"
-          subapplet.classname="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run"
-          subapplet.displayname="JOGL GearsES2 Applet"
-          noddraw.check="true"
-          progressbar="true"
-          jnlpNumExtensions="1"
-          jnlpExtension1="jogl-all-awt.jnlp"
-          java_arguments="-Dsun.java2d.noddraw=true"
           gl_event_listener_class="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2"
           gl_profile="GL2ES2"
           gl_swap_interval="1"
@@ -78,29 +63,19 @@ JOGL NEWT JNLP Applet Runner Special Keys:<br>
      </embed>
    </comment>
 </object>
+</p>
 
-</P>
-
-<P>
+<p>
 
 The applet above is instantiated with the following code:
 
 <pre>
 <object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
       width="200" height="200">
-   <param name="code" value="org.jdesktop.applet.util.JNLPAppletLauncher">
-   <param name="archive" value="jar/applet-launcher.jar,
-                                jar/gluegen-rt.jar,
+   <param name="code" value="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run">
+   <param name="archive" value="jar/gluegen-rt.jar,
                                 jar/jogl-all.jar,
                                 jar/jogl-test.jar">
-   <param name="codebase_lookup" value="false">
-   <param name="subapplet.classname" value="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run">
-   <param name="subapplet.displayname" value="JOGL GearsES2 Applet">
-   <param name="noddraw.check" value="true">
-   <param name="progressbar" value="true">
-   <param name="jnlpNumExtensions" value="1">
-   <param name="jnlpExtension1" value="jogl-all-awt.jnlp">
-   <param name="java_arguments" value="-Dsun.java2d.noddraw=true">
    <param name="gl_event_listener_class" value="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2">
    <param name="gl_profile" value="GL2ES2">
    <param name="gl_swap_interval" value="1">
@@ -108,22 +83,13 @@ The applet above is instantiated with the following code:
    <param name="gl_trace" value="false">
    <param name="jnlp_href" value="jogl-applet-runner-newt.jnlp">
    <comment>
-     <embed code="org.jdesktop.applet.util.JNLPAppletLauncher"
+     <embed code="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run"
           width="200" height="200"
           type="application/x-java-applet;version=1.6"
           pluginspage="http://java.sun.com/javase/downloads/ea.jsp"
-          archive="jar/applet-launcher.jar,
-                   jar/gluegen-rt.jar,
+          archive="jar/gluegen-rt.jar,
                    jar/jogl-all.jar,
                    jar/jogl-test.jar"
-          codebase_lookup" value="false"
-          subapplet.classname="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run"
-          subapplet.displayname="JOGL GearsES2 Applet"
-          noddraw.check="true"
-          progressbar="true"
-          jnlpNumExtensions="1"
-          jnlpExtension1="jogl-all-awt.jnlp"
-          java_arguments="-Dsun.java2d.noddraw=true"
           gl_event_listener_class="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2"
           gl_profile="GL2ES2"
           gl_swap_interval="1"
@@ -134,7 +100,6 @@ The applet above is instantiated with the following code:
      </embed>
    </comment>
 </object>
-
 </pre>
 
 Where the referenced JNLP file <em>jogl-applet-runner-newt.jnlp</em> looks as follow:
@@ -153,7 +118,6 @@ Where the referenced JNLP file <em>jogl-applet-runner-newt.jnlp</em> looks as fo
 
     <resources>
       <j2se href="http://java.sun.com/products/autodl/j2se" version="1.4+"/>
-      <property name="sun.java2d.noddraw" value="true"/>
       <jar href="jar/jogl-test.jar" main="true"/>
       <extension name="jogl-all-awt" href="http://jogamp.org/deployment/jogamp-current/jogl-all-awt.jnlp" />
     </resources>
@@ -167,25 +131,24 @@ Where the referenced JNLP file <em>jogl-applet-runner-newt.jnlp</em> looks as fo
 </jnlp>
 </pre>
 
-</P>
-<P>
-
-Note that the jogl-test.jar, which contains the test applet class,
+</p>
+<p>
+<del>
+Note that the jogl-test.jar, which contains the GearsES2 class,
 <B>does not need to be signed</B>! JogAmp Community signs
-applet-launcher.jar, jogl.jar and gluegen-rt.jar, which contain the
-JNLPAppletLauncher and JOGL's supporting classes; this is the only
+jogl-all.jar and gluegen-rt.jar, which contain the
+JOGL's supporting classes; this is the only
 Java code which needs to be signed in order to deploy applets using
 JOGL and is the only certificate the end user must accept.
-
-</P>
-<P>
-
-The <a href="http://jogamp.org/applet-launcher/www/">JNLPAppletLauncher
-home page</a> contains more information about what files must be
-placed on the web server in order to enable the deployment of applets
-using JOGL and other extensions.
-
-</P>
+</del><br/>
+Sadly, due to Oracle's Java Applet Plugin update 7u51,
+unsigned applets are no more allowed and effectively 
+lower the bar to create user applets with raised privileges.<br/>
+Hence JogAmp Community <b>signs</b> jogl-all.jar and gluegen-rt.jar, which contain the
+JOGL's supporting classes as well as jogl-test.jar, which contains the users implementing Applet class.<br/>
+jogl-test.jar's manifest file uses <i>Permissions: sandbox</i>
+to <b>not raise privileges</b>.
+</p>
 
 </body>
 </html>
diff --git a/jnlp-files/jogl-applet-runner-newt-gears-special-napplet.html b/jnlp-files/jogl-applet-runner-newt-gears-special-napplet.html
index 7df1678..2e81f52 100644
--- a/jnlp-files/jogl-applet-runner-newt-gears-special-napplet.html
+++ b/jnlp-files/jogl-applet-runner-newt-gears-special-napplet.html
@@ -13,7 +13,6 @@ JOGL NEWT JNLP Applet Runner Special Keys:
    <param name="archive" value="jar/gluegen-rt.jar,
                                 jar/jogl-all.jar,
                                 jar/jogl-test.jar">
-   <param name="java_arguments" value="-Dsun.java2d.noddraw=true">
    <param name="gl_event_listener_class" value="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2">
    <param name="gl_profile" value="GL2ES2">
    <param name="gl_swap_interval" value="1">
@@ -34,7 +33,6 @@ JOGL NEWT JNLP Applet Runner Special Keys:
           archive="jar/gluegen-rt.jar,
                    jar/jogl-all.jar,
                    jar/jogl-test.jar"
-          java_arguments="-Dsun.java2d.noddraw=true"
           gl_event_listener_class="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2"
           gl_profile="GL2ES2"
           gl_swap_interval="1"
@@ -57,6 +55,9 @@ JOGL NEWT JNLP Applet Runner Special Keys:
     <li> f - toggle fullscreen </li>
     <li> r - in/out browser window </li>
     <li> a - on/off always-on-top </li>
+    <li> c - change mouse pointer </li>
+    <li> i - invisible mouse pointer </li>
+    <li> w - warp mouse pointer to center </li>
 </ul>
 Normal webpage text - Normal webpage text - Normal webpage text - Normal webpage text<br>
 Normal webpage text - Normal webpage text - Normal webpage text - Normal webpage text<br>
diff --git a/jnlp-files/jogl-applet-runner-newt-gears-special.html b/jnlp-files/jogl-applet-runner-newt-gears-special.html
index 0f59114..6d6073e 100644
--- a/jnlp-files/jogl-applet-runner-newt-gears-special.html
+++ b/jnlp-files/jogl-applet-runner-newt-gears-special.html
@@ -9,19 +9,10 @@
 JOGL NEWT JNLP Applet Runner Special Keys:
 <object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
       width="1" height="1">
-   <param name="code" value="org.jdesktop.applet.util.JNLPAppletLauncher">
-   <param name="archive" value="jar/applet-launcher.jar,
-                                jar/gluegen-rt.jar,
+   <param name="code" value="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run">
+   <param name="archive" value="jar/gluegen-rt.jar,
                                 jar/jogl-all.jar,
                                 jar/jogl-test.jar">
-   <param name="codebase_lookup" value="false">
-   <param name="subapplet.classname" value="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run">
-   <param name="subapplet.displayname" value="JOGL GearsES2 Applet Transparent">
-   <param name="noddraw.check" value="true">
-   <param name="progressbar" value="true">
-   <param name="jnlpNumExtensions" value="1">
-   <param name="jnlpExtension1" value="jogl-all-awt.jnlp">
-   <param name="java_arguments" value="-Dsun.java2d.noddraw=true">
    <param name="gl_event_listener_class" value="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2">
    <param name="gl_profile" value="GL2ES2">
    <param name="gl_swap_interval" value="1">
@@ -36,22 +27,13 @@ JOGL NEWT JNLP Applet Runner Special Keys:
    <param name="gl_trace" value="false">
    <param name="jnlp_href" value="jogl-applet-runner-newt.jnlp">
    <comment>
-     <embed code="org.jdesktop.applet.util.JNLPAppletLauncher"
+     <embed code="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run"
           width="1" height="1"
           type="application/x-java-applet;version=1.6"
           pluginspage="http://java.sun.com/javase/downloads/ea.jsp"
-          archive="jar/applet-launcher.jar,
-                   jar/gluegen-rt.jar,
+          archive="jar/gluegen-rt.jar,
                    jar/jogl-all.jar,
                    jar/jogl-test.jar"
-          codebase_lookup" value="false"
-          subapplet.classname="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run"
-          subapplet.displayname="JOGL GearsES2 Applet Transparent"
-          noddraw.check="true"
-          progressbar="true"
-          jnlpNumExtensions="1"
-          jnlpExtension1="jogl-all-awt.jnlp"
-          java_arguments="-Dsun.java2d.noddraw=true"
           gl_event_listener_class="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2"
           gl_profile="GL2ES2"
           gl_swap_interval="1"
@@ -75,6 +57,9 @@ JOGL NEWT JNLP Applet Runner Special Keys:
     <li> f - toggle fullscreen </li>
     <li> r - in/out browser window </li>
     <li> a - on/off always-on-top </li>
+    <li> c - change mouse pointer </li>
+    <li> i - invisible mouse pointer </li>
+    <li> w - warp mouse pointer to center </li>
 </ul>
 Normal webpage text - Normal webpage text - Normal webpage text - Normal webpage text<br>
 Normal webpage text - Normal webpage text - Normal webpage text - Normal webpage text<br>
diff --git a/jnlp-files/jogl-applet-runner-newt.jnlp b/jnlp-files/jogl-applet-runner-newt.jnlp
index d53febd..62e0942 100644
--- a/jnlp-files/jogl-applet-runner-newt.jnlp
+++ b/jnlp-files/jogl-applet-runner-newt.jnlp
@@ -12,7 +12,6 @@
 
     <resources>
       <j2se href="http://java.sun.com/products/autodl/j2se" version="1.4+"/>
-      <property name="sun.java2d.noddraw" value="true"/>
       <jar href="jar/jogl-test.jar" main="true"/>
       <extension name="jogl-all-awt" href="jogl-all-awt.jnlp" />
     </resources>
diff --git a/jnlp-files/jogl-applet-version-napplet.html b/jnlp-files/jogl-applet-version-applet3-napplet.html
similarity index 57%
copy from jnlp-files/jogl-applet-version-napplet.html
copy to jnlp-files/jogl-applet-version-applet3-napplet.html
index aeccb71..1fc12f7 100644
--- a/jnlp-files/jogl-applet-version-napplet.html
+++ b/jnlp-files/jogl-applet-version-applet3-napplet.html
@@ -1,12 +1,12 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
 <html>
 <head>
-<title>JOGL JNLP Applet Version (NApplet)</title>
+<title>JOGL JNLP Applet3 Version (NApplet)</title>
 </head>
 <body>
 
 <P>
-The applet below shall show you the version of the Jogl components
+The applet3 below shall show you the version of the Jogl components
 and your platform.
 </P>
 
@@ -14,18 +14,16 @@ and your platform.
 
 <object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
       width="800" height="600">
-   <param name="code" value="jogamp.opengl.awt.VersionApplet">
+   <param name="code" value="com.jogamp.newt.util.applet.VersionApplet3">
    <param name="archive" value="jar/gluegen-rt.jar,
-                                jar/jogl-all.jar">
-   <param name="java_arguments" value="-Dsun.java2d.noddraw=true">
+                                jar/jogl-all-noawt.jar">
    <comment>
-     <embed code="jogamp.opengl.awt.VersionApplet"
+     <embed code="com.jogamp.newt.util.applet.VersionApplet3"
           width="800" height="600"
           type="application/x-java-applet;version=1.6"
           pluginspage="http://java.sun.com/javase/downloads/ea.jsp"
           archive="jar/gluegen-rt.jar,
-                   jar/jogl-all.jar"
-          java_arguments="-Dsun.java2d.noddraw=true">
+                   jar/jogl-all-noawt.jar">
         <noembed>Sorry, no Java support detected.</noembed>
      </embed>
    </comment>
@@ -34,23 +32,21 @@ and your platform.
 </P>
 <P>
 
-The applet above is instantiated with the following code:
+The applet3 above is instantiated with the following code:
 
 <pre>
 <object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
       width="800" height="600">
-   <param name="code" value="jogamp.opengl.awt.VersionApplet">
+   <param name="code" value="com.jogamp.newt.util.applet.VersionApplet3">
    <param name="archive" value="jar/gluegen-rt.jar,
-                                jar/jogl-all.jar">
-   <param name="java_arguments" value="-Dsun.java2d.noddraw=true">
+                                jar/jogl-all-noawt.jar">
    <comment>
-     <embed code="jogamp.opengl.awt.VersionApplet"
+     <embed code="com.jogamp.newt.util.applet.VersionApplet3"
           width="800" height="600"
           type="application/x-java-applet;version=1.6"
           pluginspage="http://java.sun.com/javase/downloads/ea.jsp"
           archive="jar/gluegen-rt.jar,
-                   jar/jogl-all.jar"
-          java_arguments="-Dsun.java2d.noddraw=true">
+                   jar/jogl-all-noawt.jar">
         <noembed>Sorry, no Java support detected.</noembed>
      </embed>
    </comment>
diff --git a/jnlp-files/jogl-applet-version-lancheronly.html b/jnlp-files/jogl-applet-version-lancheronly.html
deleted file mode 100644
index 6880152..0000000
--- a/jnlp-files/jogl-applet-version-lancheronly.html
+++ /dev/null
@@ -1,56 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html>
-<head>
-<title>JOGL JNLP Applet Version (Launcher)</title>
-</head>
-<body>
-
-<P>
-The applet below shall show you the version of the Jogl components
-and your platform.
-</P>
-<p>
-<a href="http://jogamp.org/applet-launcher/www/">JNLPAppletLauncher</a> only version.
-</p>
-
-<P>
-
-<object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
-      width="800" height="600">
-   <param name="code" value="org.jdesktop.applet.util.JNLPAppletLauncher">
-   <param name="archive" value="jar/applet-launcher.jar,
-                                jar/gluegen-rt.jar,
-                                jar/jogl-all.jar">
-   <param name="codebase_lookup" value="false">
-   <param name="subapplet.classname" value="jogamp.opengl.awt.VersionApplet">
-   <param name="subapplet.displayname" value="JOGL Applet Version">
-   <param name="noddraw.check" value="true">
-   <param name="progressbar" value="true">
-   <param name="jnlpNumExtensions" value="1">
-   <param name="jnlpExtension1" value="jogl-all-awt.jnlp">
-   <param name="java_arguments" value="-Dsun.java2d.noddraw=true">
-   <comment>
-     <embed code="org.jdesktop.applet.util.JNLPAppletLauncher"
-          width="800" height="600"
-          type="application/x-java-applet;version=1.6"
-          pluginspage="http://java.sun.com/javase/downloads/ea.jsp"
-          archive="jar/applet-launcher.jar,
-                   jar/gluegen-rt.jar,
-                   jar/jogl-all.jar"
-          codebase_lookup" value="false"
-          subapplet.classname="jogamp.opengl.awt.VersionApplet"
-          subapplet.displayname="JOGL Applet Version"
-          noddraw.check="true"
-          progressbar="true"
-          jnlpNumExtensions="1"
-          jnlpExtension1="jogl-all-awt.jnlp"
-          java_arguments="-Dsun.java2d.noddraw=true">
-        <noembed>Sorry, no Java support detected.</noembed>
-     </embed>
-   </comment>
-</object>
-
-</P>
-
-</body>
-</html>
diff --git a/jnlp-files/jogl-applet-version-napplet.html b/jnlp-files/jogl-applet-version-napplet.html
index aeccb71..6d65add 100644
--- a/jnlp-files/jogl-applet-version-napplet.html
+++ b/jnlp-files/jogl-applet-version-napplet.html
@@ -17,15 +17,13 @@ and your platform.
    <param name="code" value="jogamp.opengl.awt.VersionApplet">
    <param name="archive" value="jar/gluegen-rt.jar,
                                 jar/jogl-all.jar">
-   <param name="java_arguments" value="-Dsun.java2d.noddraw=true">
    <comment>
      <embed code="jogamp.opengl.awt.VersionApplet"
           width="800" height="600"
           type="application/x-java-applet;version=1.6"
           pluginspage="http://java.sun.com/javase/downloads/ea.jsp"
           archive="jar/gluegen-rt.jar,
-                   jar/jogl-all.jar"
-          java_arguments="-Dsun.java2d.noddraw=true">
+                   jar/jogl-all.jar">
         <noembed>Sorry, no Java support detected.</noembed>
      </embed>
    </comment>
@@ -42,15 +40,13 @@ The applet above is instantiated with the following code:
    <param name="code" value="jogamp.opengl.awt.VersionApplet">
    <param name="archive" value="jar/gluegen-rt.jar,
                                 jar/jogl-all.jar">
-   <param name="java_arguments" value="-Dsun.java2d.noddraw=true">
    <comment>
      <embed code="jogamp.opengl.awt.VersionApplet"
           width="800" height="600"
           type="application/x-java-applet;version=1.6"
           pluginspage="http://java.sun.com/javase/downloads/ea.jsp"
           archive="jar/gluegen-rt.jar,
-                   jar/jogl-all.jar"
-          java_arguments="-Dsun.java2d.noddraw=true">
+                   jar/jogl-all.jar">
         <noembed>Sorry, no Java support detected.</noembed>
      </embed>
    </comment>
diff --git a/jnlp-files/jogl-applet-version.html b/jnlp-files/jogl-applet-version.html
index 948e630..c550610 100644
--- a/jnlp-files/jogl-applet-version.html
+++ b/jnlp-files/jogl-applet-version.html
@@ -19,35 +19,17 @@ otherwise it shall fallback to <a href="http://jogamp.org/applet-launcher/www/">
 
 <object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
       width="800" height="600">
-   <param name="code" value="org.jdesktop.applet.util.JNLPAppletLauncher">
-   <param name="archive" value="jar/applet-launcher.jar,
-                                jar/gluegen-rt.jar,
+   <param name="code" value="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run">
+   <param name="archive" value="jar/gluegen-rt.jar,
                                 jar/jogl-all.jar">
-   <param name="codebase_lookup" value="false">
-   <param name="subapplet.classname" value="jogamp.opengl.awt.VersionApplet">
-   <param name="subapplet.displayname" value="JOGL Applet Version">
-   <param name="noddraw.check" value="true">
-   <param name="progressbar" value="true">
-   <param name="jnlpNumExtensions" value="1">
-   <param name="jnlpExtension1" value="jogl-all-awt.jnlp">
-   <param name="java_arguments" value="-Dsun.java2d.noddraw=true">
    <param name="jnlp_href" value="jogl-applet-version.jnlp">
    <comment>
-     <embed code="org.jdesktop.applet.util.JNLPAppletLauncher"
+     <embed code="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run"
           width="800" height="600"
           type="application/x-java-applet;version=1.6"
           pluginspage="http://java.sun.com/javase/downloads/ea.jsp"
-          archive="jar/applet-launcher.jar,
-                   jar/gluegen-rt.jar,
+          archive="jar/gluegen-rt.jar,
                    jar/jogl-all.jar"
-          codebase_lookup" value="false"
-          subapplet.classname="jogamp.opengl.awt.VersionApplet"
-          subapplet.displayname="JOGL Applet Version"
-          noddraw.check="true"
-          progressbar="true"
-          jnlpNumExtensions="1"
-          jnlpExtension1="jogl-all-awt.jnlp"
-          java_arguments="-Dsun.java2d.noddraw=true"
           jnlp_href="jogl-applet-version.jnlp">
         <noembed>Sorry, no Java support detected.</noembed>
      </embed>
diff --git a/jnlp-files/jogl-applet-version.jnlp b/jnlp-files/jogl-applet-version.jnlp
index a06ea83..bf69a7c 100644
--- a/jnlp-files/jogl-applet-version.jnlp
+++ b/jnlp-files/jogl-applet-version.jnlp
@@ -8,10 +8,12 @@
     <offline-allowed/>
   </information>
   <update check="background" policy="always"/>
+  <security>
+      <all-permissions/>
+  </security>
 
     <resources>
       <j2se href="http://java.sun.com/products/autodl/j2se" version="1.4+"/>
-      <!-- property name="sun.java2d.noddraw" value="true"/-->
       <extension name="jogl-all-awt" href="JOGL_CODEBASE_TAG/jogl-all-awt.jnlp" />
     </resources>
 
diff --git a/jnlp-files/jogl-application-version.jnlp b/jnlp-files/jogl-application-version.jnlp
index 3b3cb07..feba71c 100644
--- a/jnlp-files/jogl-application-version.jnlp
+++ b/jnlp-files/jogl-application-version.jnlp
@@ -8,10 +8,12 @@
     <offline-allowed/>
   </information>
   <update check="background" policy="always"/>
+  <security>
+      <all-permissions/>
+  </security>
 
     <resources>
       <j2se href="http://java.sun.com/products/autodl/j2se" version="1.4+"/>
-      <!-- property name="sun.java2d.noddraw" value="true"/-->
       <extension name="jogl-all-awt" href="JOGL_CODEBASE_TAG/jogl-all-awt.jnlp" />
     </resources>
 
diff --git a/jnlp-files/jogl-javaws-version.jnlp b/jnlp-files/jogl-javaws-version.jnlp
index 10f228c..e5f11fb 100755
--- a/jnlp-files/jogl-javaws-version.jnlp
+++ b/jnlp-files/jogl-javaws-version.jnlp
@@ -11,7 +11,6 @@
 
     <resources>
       <j2se href="http://java.sun.com/products/autodl/j2se" version="1.4+"/>
-      <!-- property name="sun.java2d.noddraw" value="true"/-->
       <extension name="jogl-all-awt" href="JOGL_CODEBASE_TAG/jogl-all-awt.jnlp" />
     </resources>
 
diff --git a/jnlp-files/jogl-test-applets.html b/jnlp-files/jogl-test-applet3s.html
similarity index 52%
copy from jnlp-files/jogl-test-applets.html
copy to jnlp-files/jogl-test-applet3s.html
index 8eda51d..3614083 100644
--- a/jnlp-files/jogl-test-applets.html
+++ b/jnlp-files/jogl-test-applet3s.html
@@ -3,7 +3,7 @@
     <head>
         <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
         <link href="../../style.css" rel="stylesheet" type="text/css"/>
-        <title>JOGL Test Applets</title>
+        <title>JOGL Test Applet3</title>
         <link href="../../SocialCoding/logo_symbol_finals/website_final_blue_favicon_symbol_16x16pel.ico" rel="shortcut icon"/>
     </head>
 <body>
@@ -30,11 +30,7 @@
         </div>
         <div id="text">
 
-<h2> Test page for JOGL Applets </h2>
-
-<div style="font : 10px serif;">
-See Legend below table
-</div>
+<h2> Test page for JOGL Applet3 </h2>
 
 <table width="100%" cellspacing="0" border="0" cellpadding="0"><tbody><tr valign="top">
 
@@ -47,32 +43,13 @@ See Legend below table
         </tr>
         <tr>
             <td>
-                <a href="../../jogl/www/media/jogl-applet-version.png">
-                    <img src="../../jogl/www/media/jogl-applet-version-small.png" width="200" alt="Full Size"/>
-                </a>
-            </td>
-            <td>
-                <a href="jogl-applet-version.html">Dual</a><br/>
-                <a href="jogl-applet-version-lancheronly.html">LApplet</a><br/>
-                <a href="jogl-applet-version-napplet.html">NApplet</a><br/>
-                <a href="jogl-application-version.jnlp">WebStart</a><br/>
-            </td>
-            <td>
-                JOGL Version Information.
-            </td>
-        </tr>
-        <tr>
-            <td>
                 <a href="../../jogl/www/media/jogl-applet-gearses2-normal.png">
                     <img src="../../jogl/www/media/jogl-applet-gearses2-normal-small.png" width="200" alt="Full Size"/>
                 </a>
             </td>
             <td>
-                <a href="jogl-applet-runner-newt-gears-normal.html">Dual</a><br/>
-                <a href="jogl-applet-runner-newt-gears-normal-launcheronly.html">LApplet</a><br/>
-                <a href="jogl-applet-runner-newt-gears-normal-napplet.html">NApplet</a>
-                 (<a href="jogl-applet-runner-newt-gears-normal-napplet2.html">closeable</a>, 
-                  <a href="jogl-applet-runner-newt-gears-gl3-napplet.html">force gl3</a>)<br/>
+                <a href="jogl-applet-runner-newt-gears-applet3-napplet.html">NApplet</a><br/>
+                <a href="jogl-applet-runner-newt-gears-applet3-normal.html">Dual</a>
             </td>
             <td>
                 Classic OpenGL Gears for ES2 
@@ -87,8 +64,7 @@ See Legend below table
                 </a>
             </td>
             <td>
-                <a href="jogl-applet-runner-newt-gears-special.html">Dual</a><br/>
-                <a href="jogl-applet-runner-newt-gears-special-napplet.html">NApplet</a><br/>
+                <a href="jogl-applet-runner-newt-gears-applet3-special-napplet.html">NApplet</a>
             </td>
             <td>
                 Classic OpenGL Gears for ES2 
@@ -102,8 +78,7 @@ See Legend below table
                 </a>
             </td>
             <td>
-                <a href="jogl-applet-runner-newt-MovieCube.html">Dual</a><br/>
-                <a href="jogl-applet-runner-newt-MovieCube-napplet.html">NApplet</a><br/>
+                <a href="jogl-applet-runner-newt-MovieCube-applet3-napplet.html">NApplet</a>
             </td>
             <td>
                 Movie Cube using JOGL's GLMediaPlayer.
@@ -126,9 +101,7 @@ See Legend below table
                 </a>
             </td>
             <td>
-                <a href="jogl-applet-runner-newt-GraphTextDemo01.html">Dual</a><br/>
-                <a href="jogl-applet-runner-newt-GraphTextDemo01-napplet.html">NApplet</a>
-                  (<a href="jogl-applet-runner-newt-GraphTextDemo01b-napplet.html">cp-fonts</a>)<br/>
+                <a href="jogl-applet-runner-newt-GraphTextDemo01-applet3-napplet.html">NApplet</a>
             </td>
             <td>
                 GPU accelerated Text Demo using JOGL's new Graph package.<br/>
@@ -142,86 +115,18 @@ See Legend below table
                 </a>
             </td>
             <td>
-                <a href="jogl-applet-runner-newt-GraphUISceneDemo01.html">Dual</a><br/>
-                <a href="jogl-applet-runner-newt-GraphUISceneDemo01-napplet.html">NApplet</a><br/>
+                <a href="jogl-applet-runner-newt-GraphUISceneDemo01-applet3-napplet.html">NApplet</a>
             </td>
             <td>
                 Demonstration of GPU accelerated Text and UI rendering and interaction
                 using JOGL's new Graph package.
             </td>
         </tr>
-        <tr>
-            <td>
-                <a href="../../jogl/www/media/jogl-applet-demoscene-elektronenmultiplizierer01.png">
-                    <img src="../../jogl/www/media/jogl-applet-demoscene-elektronenmultiplizierer01-small.png" width="200" alt="Full Size"/>
-                </a>
-            </td>
-            <td>
-                <a href="jogl-applet-runner-newt-ElektronenMultiplizierer.html">Dual</a><br/>
-                <a href="jogl-applet-runner-newt-ElektronenMultiplizierer-napplet.html">NApplet</a><br/>
-            </td>
-            <td>
-                Demoscene Passivist's ElektronenMultiplizierer
-            </td>
-        </tr>
     </tbody></table>
   </td>
 
 </tr></tbody></table>
 
-<div style="font : 10px serif;">
-Click on <i>Screenshot</i> for the full sized screenshot.<br/>
-Click on the <i>Launch</i> link to actually launch the demo.<br/>
-  <table border="0" cellpadding="0" cellspacing="10"><tbody>
-    <tr>
-        <th align="left" ><strong>Launch</strong></th>
-        <th align="left" ><strong>Description</strong></th>
-    </tr>
-    <tr>
-        <td> JApplet </td>
-        <td> Applet using JNLP-Applet mechanism only. </td>
-    </tr>
-    <tr>
-        <td> LApplet </td>
-        <td> Applet using JOGL's Applet Launcher mechanism only. </td>
-    </tr>
-    <tr>
-        <td> Dual </td>
-        <td> Applet using JNLP-Applet & JOGL's AppletLauncher mechanism.  (JApplet + LApplet) </td>
-    </tr>
-    <tr>
-        <td> NApplet </td>
-        <td> Applet just using Applet/Object or Embed tag, where native JARs are post-loaded by GlueGen/JOGL. </td>
-    </tr>
-    <tr>
-        <td> WebStart </td>
-        <td> Application using JNLP's WebStart mechanism. </td>
-    </tr>
-  </tbody></table>
-</div>
-
-<div style="font : 15px sans;">
-<p>
-Misc tests:
-<ul>
-  <li>Bug 816 - OSX CALayer Positioning Bug
-  <ul>
-      <li><a href="jogl-applet-bug816_glcanvas01.html">01: Custom bounds within applet</a></li>
-      <li><a href="jogl-applet-bug816_glcanvas02a.html">02a: Box layout within applet</a></li>
-      <li><a href="jogl-applet-bug816_glcanvas02b.html">02b: Grid layout within applet</a></li>
-      <li><a href="jogl-applet-bug816_layerpos03a.html">03a:  Applet w/ 1 JRootPanes and 2 JSplitPanes</a></li>
-      <li><a href="jogl-applet-bug816_layerpos03b.html">03b: JApplet w/ 2 JRootPanes and 2 JSplitPanes</a></li>
-  </ul></li>
-  <li>Misc Issues
-  <ul>
-      <li><a href="jogl-applet-bug818_gljpanel01.html">Bug 818: OSX 10.6.8 NV GT 330M GLJPanel Crash</a></li>
-      <li><a href="jogl-applet-bug848_glcanvas01.html">Bug 848: Applet on OSX w/ CALayer and 2 or more GLCanvas may crash</a></li>
-      <li><a href="Bug910-AppletLifecycleCheck.html">Bug 910: Extended AWT Applet Lifecycle Check</a></li>
-  </ul></li>
-</ul>
-</p>
-</div>
-
 </div> <!-- text -->
 </div> <!-- main -->
 
diff --git a/jnlp-files/jogl-test-applets.html b/jnlp-files/jogl-test-applets.html
index 8eda51d..106a56a 100644
--- a/jnlp-files/jogl-test-applets.html
+++ b/jnlp-files/jogl-test-applets.html
@@ -52,9 +52,8 @@ See Legend below table
                 </a>
             </td>
             <td>
-                <a href="jogl-applet-version.html">Dual</a><br/>
-                <a href="jogl-applet-version-lancheronly.html">LApplet</a><br/>
                 <a href="jogl-applet-version-napplet.html">NApplet</a><br/>
+                <a href="jogl-applet-version.html">Dual</a><br/>
                 <a href="jogl-application-version.jnlp">WebStart</a><br/>
             </td>
             <td>
@@ -68,11 +67,10 @@ See Legend below table
                 </a>
             </td>
             <td>
-                <a href="jogl-applet-runner-newt-gears-normal.html">Dual</a><br/>
-                <a href="jogl-applet-runner-newt-gears-normal-launcheronly.html">LApplet</a><br/>
                 <a href="jogl-applet-runner-newt-gears-normal-napplet.html">NApplet</a>
                  (<a href="jogl-applet-runner-newt-gears-normal-napplet2.html">closeable</a>, 
                   <a href="jogl-applet-runner-newt-gears-gl3-napplet.html">force gl3</a>)<br/>
+                <a href="jogl-applet-runner-newt-gears-normal.html">Dual</a><br/>
             </td>
             <td>
                 Classic OpenGL Gears for ES2 
@@ -87,8 +85,8 @@ See Legend below table
                 </a>
             </td>
             <td>
-                <a href="jogl-applet-runner-newt-gears-special.html">Dual</a><br/>
                 <a href="jogl-applet-runner-newt-gears-special-napplet.html">NApplet</a><br/>
+                <a href="jogl-applet-runner-newt-gears-special.html">Dual</a><br/>
             </td>
             <td>
                 Classic OpenGL Gears for ES2 
@@ -102,8 +100,8 @@ See Legend below table
                 </a>
             </td>
             <td>
-                <a href="jogl-applet-runner-newt-MovieCube.html">Dual</a><br/>
                 <a href="jogl-applet-runner-newt-MovieCube-napplet.html">NApplet</a><br/>
+                <a href="jogl-applet-runner-newt-MovieCube.html">Dual</a><br/>
             </td>
             <td>
                 Movie Cube using JOGL's GLMediaPlayer.
@@ -126,9 +124,9 @@ See Legend below table
                 </a>
             </td>
             <td>
-                <a href="jogl-applet-runner-newt-GraphTextDemo01.html">Dual</a><br/>
                 <a href="jogl-applet-runner-newt-GraphTextDemo01-napplet.html">NApplet</a>
                   (<a href="jogl-applet-runner-newt-GraphTextDemo01b-napplet.html">cp-fonts</a>)<br/>
+                <a href="jogl-applet-runner-newt-GraphTextDemo01.html">Dual</a><br/>
             </td>
             <td>
                 GPU accelerated Text Demo using JOGL's new Graph package.<br/>
@@ -142,8 +140,8 @@ See Legend below table
                 </a>
             </td>
             <td>
-                <a href="jogl-applet-runner-newt-GraphUISceneDemo01.html">Dual</a><br/>
                 <a href="jogl-applet-runner-newt-GraphUISceneDemo01-napplet.html">NApplet</a><br/>
+                <a href="jogl-applet-runner-newt-GraphUISceneDemo01.html">Dual</a><br/>
             </td>
             <td>
                 Demonstration of GPU accelerated Text and UI rendering and interaction
@@ -157,8 +155,8 @@ See Legend below table
                 </a>
             </td>
             <td>
-                <a href="jogl-applet-runner-newt-ElektronenMultiplizierer.html">Dual</a><br/>
                 <a href="jogl-applet-runner-newt-ElektronenMultiplizierer-napplet.html">NApplet</a><br/>
+                <a href="jogl-applet-runner-newt-ElektronenMultiplizierer.html">Dual</a><br/>
             </td>
             <td>
                 Demoscene Passivist's ElektronenMultiplizierer
@@ -179,19 +177,15 @@ Click on the <i>Launch</i> link to actually launch the demo.<br/>
     </tr>
     <tr>
         <td> JApplet </td>
-        <td> Applet using JNLP-Applet mechanism only. </td>
+        <td> Applet using <a href="https://jdk6.dev.java.net/plugin2/jnlp/">JNLP-Applet</a> mechanism. </td>
     </tr>
     <tr>
-        <td> LApplet </td>
-        <td> Applet using JOGL's Applet Launcher mechanism only. </td>
+        <td> <a href="http://jogamp.org/jogl/doc/deployment/JOGL-DEPLOYMENT.html#NApplets">NApplet</a> </td>
+        <td> Applet using traditional Applet/Object or Embed tag, where native JARs are post-loaded by GlueGen/JOGL. </td>
     </tr>
     <tr>
         <td> Dual </td>
-        <td> Applet using JNLP-Applet & JOGL's AppletLauncher mechanism.  (JApplet + LApplet) </td>
-    </tr>
-    <tr>
-        <td> NApplet </td>
-        <td> Applet just using Applet/Object or Embed tag, where native JARs are post-loaded by GlueGen/JOGL. </td>
+        <td> Applet using JNLP-Applet & JogAmp's <a href="http://jogamp.org/jogl/doc/deployment/JOGL-DEPLOYMENT.html#NApplets">NApplet</a> mechanism.  (JApplet + NApplet) </td>
     </tr>
     <tr>
         <td> WebStart </td>
diff --git a/make/build-common.xml b/make/build-common.xml
index 6583593..1a5703a 100644
--- a/make/build-common.xml
+++ b/make/build-common.xml
@@ -177,6 +177,9 @@
         </condition>
         <echo message="swt.jar=${swt.jar}" />
 
+        <property name="plugin3.jar" value="${project.root}/make/lib/plugin3/plugin3-public.jar"/>
+        <echo message="plugin3.jar=${plugin3.jar}" />
+
         <condition property="isSWTRuntimeAvailable">
           <or>
               <istrue value="${isWindowsAMD64}" />
@@ -426,7 +429,7 @@
         <property name="jogl-all-android.apk"           value="${jar}/jogl-all-android-${android.abi}.apk" />
 
         <!-- JavaSE combinations . JOAL (optional) -->
-        <property name="joal.jar"                       value="${build.joal}/joal.jar" />
+        <property name="joal.jar"                       value="${build.joal}/jar/joal.jar" />
         <condition property="joal-jars.available">
             <available file="${joal.jar}"/>
         </condition>
@@ -462,6 +465,7 @@
         <!-- NEWT Compilation .. -->
         <path id="jogl_nativewindow_gluegen.classpath">
             <pathelement location="${gluegen-rt.jar}" />
+            <pathelement location="${plugin3.jar}" />
             <pathelement location="${swt.jar}" />
             <path refid="nativewindow_all_atoms.classpath" />
             <path refid="jogl_all_atoms.classpath" />
@@ -470,6 +474,7 @@
         <path id="jogl_nativewindow_gluegen_android.classpath">
             <pathelement location="${android.jar}" />
             <pathelement location="${gluegen-rt-android.jar}" />
+            <pathelement location="${plugin3.jar}" />
             <pathelement location="${swt.jar}" />
             <path refid="nativewindow_all_atoms.classpath" />
             <path refid="jogl_all_atoms.classpath" />
diff --git a/make/build-jogl.xml b/make/build-jogl.xml
index 28b738b..4cdb93f 100644
--- a/make/build-jogl.xml
+++ b/make/build-jogl.xml
@@ -1833,7 +1833,7 @@
             <fileset dir="${classes}"
                      includes="${java.part.util} ${java.part.util.glsl} ${java.part.openal}"
                      excludes="${java.part.util.awt} ${java.part.util.gldesktop} ${java.part.util.fixedfuncemu} ${java.part.util.graph}"/>
-            <fileset dir="resources/assets" includes="jogl/util/**" />
+            <fileset dir="resources/assets" includes="jogl/util/data/**" />
         </jar>
         <jar manifest="${build.jogl}/manifest.mf" destfile="${jogl-util-graph.jar}" filesonly="true">
             <fileset dir="${classes}"
diff --git a/make/build-newt.xml b/make/build-newt.xml
index 960c7b5..dd0ccc1 100644
--- a/make/build-newt.xml
+++ b/make/build-newt.xml
@@ -100,10 +100,10 @@
         <!-- partitioning -->
 
         <property name="java.part.core"
-                  value="com/jogamp/newt/* com/jogamp/newt/event/* com/jogamp/newt/util/* jogamp/newt/* jogamp/newt/event/* jogamp/newt/driver/*"/>
+                  value="com/jogamp/newt/* com/jogamp/newt/event/* com/jogamp/newt/util/* com/jogamp/newt/util/applet/* jogamp/newt/* jogamp/newt/event/* jogamp/newt/driver/*"/>
 
         <property name="java.part.opengl"
-                  value="com/jogamp/newt/opengl/**"/>
+                  value="com/jogamp/newt/opengl/** jogamp/newt/driver/opengl/**"/>
 
         <property name="java.part.driver.awt"
                   value="jogamp/newt/driver/awt/**"/>
@@ -277,12 +277,14 @@
         <linkerarg value="-L/usr/local/lib"/>
         <syslibset libs="X11"/>
         <syslibset libs="Xrandr"/>
+        <syslibset libs="Xcursor"/>
       </linker>
 
       <linker id="linker.cfg.freebsd.amd64.newt.x11" extends="linker.cfg.freebsd.amd64">
         <linkerarg value="-L/usr/local/lib"/>
         <syslibset libs="X11"/>
         <syslibset libs="Xrandr"/>
+        <syslibset libs="Xcursor"/>
       </linker>
 
       <linker id="linker.cfg.linux.newt.bcm_egl" extends="linker.cfg.linux">
@@ -302,6 +304,7 @@
       <linker id="linker.cfg.linux.newt.x11" extends="linker.cfg.linux">
         <syslibset libs="X11"/>
         <syslibset libs="Xrandr"/>
+        <syslibset libs="Xcursor"/>
         <!--syslibset libs="xcb" /-->
         <!--syslibset libs="X11-xcb" /-->
       </linker>
@@ -309,6 +312,7 @@
       <linker id="linker.cfg.linux.x86.newt.x11" extends="linker.cfg.linux.x86">
         <syslibset libs="X11"/>
         <syslibset libs="Xrandr"/>
+        <syslibset libs="Xcursor"/>
         <!--syslibset libs="xcb" /-->
         <!--syslibset libs="X11-xcb" /-->
       </linker>
@@ -316,6 +320,7 @@
       <linker id="linker.cfg.linux.amd64.newt.x11" extends="linker.cfg.linux.amd64">
         <syslibset libs="X11"/>
         <syslibset libs="Xrandr"/>
+        <syslibset libs="Xcursor"/>
         <!--syslibset libs="xcb" /-->
         <!--syslibset libs="X11-xcb" /-->
       </linker>
@@ -323,6 +328,7 @@
       <linker id="linker.cfg.linux.armv6.newt.x11" extends="linker.cfg.linux.armv6">
         <syslibset dir="${env.TARGET_PLATFORM_ROOT}/usr/lib" libs="X11" />
         <syslibset dir="${env.TARGET_PLATFORM_ROOT}/usr/lib" libs="Xrandr" />
+        <syslibset dir="${env.TARGET_PLATFORM_ROOT}/usr/lib" libs="Xcursor" />
       </linker>
 
       <linker id="linker.cfg.android.newt" extends="linker.cfg.android">
@@ -332,18 +338,21 @@
       <linker id="linker.cfg.solaris.newt.x11" extends="linker.cfg.solaris">
         <syslibset libs="X11"/>
         <syslibset libs="Xrandr"/>
+        <syslibset libs="Xcursor"/>
       </linker>
 
       <linker id="linker.cfg.solaris.sparcv9.newt.x11" extends="linker.cfg.solaris.sparcv9">
         <linkerarg value="-L/usr/lib/sparcv9"/>
         <syslibset libs="X11"/>
         <syslibset libs="Xrandr"/>
+        <syslibset libs="Xcursor"/>
       </linker>
 
       <linker id="linker.cfg.solaris.amd64.newt.x11" extends="linker.cfg.solaris.amd64">
         <linkerarg value="-L/usr/lib/amd64"/>
         <syslibset libs="X11"/>
         <syslibset libs="Xrandr"/>
+        <syslibset libs="Xcursor"/>
       </linker>
 
       <linker id="linker.cfg.win32.mingw.newt" extends="linker.cfg.win32.mingw">
@@ -798,6 +807,7 @@
         <jar manifest="${build.newt}/manifest.mf" destfile="${newt-core.jar}" filesonly="true">
             <fileset dir="${classes}"
                      includes="${java.part.core}"/>
+            <fileset dir="resources/assets" includes="newt/data/**" />
         </jar>
         <jar manifest="${build.newt}/manifest.mf" destfile="${newt-event.jar}" filesonly="true">
             <fileset dir="${classes}">
diff --git a/make/build-test.xml b/make/build-test.xml
index d4274cd..2ae39d8 100644
--- a/make/build-test.xml
+++ b/make/build-test.xml
@@ -85,6 +85,7 @@
                 <filter token="SCM_BRANCH" value="${jogl.build.branch}"/>
                 <filter token="SCM_COMMIT" value="${jogl.build.commit}"/>
                 <filter token="BASEVERSION" value="${jogamp.version.base}"/>
+                <filter token="JAR_CODEBASE_TAG" value="${jogamp.jar.codebase}"/>
             </filterset>
         </copy>
 
diff --git a/make/config/jogl/gl-common.cfg b/make/config/jogl/gl-common.cfg
index b841154..74ead04 100644
--- a/make/config/jogl/gl-common.cfg
+++ b/make/config/jogl/gl-common.cfg
@@ -56,12 +56,66 @@ Ignore glDebugMessageCallbackARB
 Ignore glDebugMessageCallbackKHR
 Ignore glDebugMessageCallback
 
-# Manually implement glMapBuffer and glMapBufferRange as the size of the returned buffer
-# can only be computed by calling another routine
+#
+# Manually implement following GL functions to be redirected 
+# to GLBufferObjectTracker.
+#
+ManuallyImplement glBufferData
+ForceProcAddressGen glBufferData
+MethodJavadoc glBufferData * <p>
+MethodJavadoc glBufferData * Throws a {@link GLException} if GL-function constraints are not met or the native GL-function fails.
+MethodJavadoc glBufferData * </p>
+MethodJavadoc glBufferData * <p>
+MethodJavadoc glBufferData * @throws GLException if buffer is not bound to target
+MethodJavadoc glBufferData * @throws GLException if size is less-than zero
+MethodJavadoc glBufferData * @throws GLException if a native GL-Error occurs
+MethodJavadoc glBufferData * </p>
+
+# FIXME: Add for OpenGL 4.4
+#Ignore glBufferStorage
+#ManuallyImplement glBufferStorage
+#ForceProcAddressGen glBufferStorage
+#MethodJavadoc glBufferStorage * <p>
+#MethodJavadoc glBufferStorage * Throws a {@link GLException} if GL-function constraints are not met or the native GL-function fails.
+#MethodJavadoc glBufferStorage * </p>
+#MethodJavadoc glBufferStorage * <p>
+#MethodJavadoc glBufferStorage * @throws GLException if buffer is not bound to target
+#MethodJavadoc glBufferStorage * @throws GLException if size is less-or-equal zero
+#MethodJavadoc glBufferStorage * @throws GLException if a native GL-Error occurs
+#MethodJavadoc glBufferStorage * </p>
+
 ManuallyImplement glMapBuffer
 ForceProcAddressGen glMapBuffer
+MethodJavadoc glMapBuffer * <p>
+MethodJavadoc glMapBuffer * Throws a {@link GLException} if GL-function constraints are not met.
+MethodJavadoc glMapBuffer * </p>
+MethodJavadoc glMapBuffer * <p>
+MethodJavadoc glMapBuffer * Returns {@link GL#mapBuffer(int, int)}'s {@link GLBufferStorage#getMappedBuffer()}.
+MethodJavadoc glMapBuffer * </p>
+MethodJavadoc glMapBuffer * @throws GLException if buffer is not bound to target
+MethodJavadoc glMapBuffer * @throws GLException if buffer is not tracked
+MethodJavadoc glMapBuffer * @throws GLException if buffer is already mapped
+MethodJavadoc glMapBuffer * @throws GLException if buffer has invalid store size, i.e. less-than zero
+MethodJavadoc glMapBuffer * </p>
+
 ManuallyImplement glMapBufferRange
 ForceProcAddressGen glMapBufferRange
+MethodJavadoc glMapBufferRange * <p>
+MethodJavadoc glMapBufferRange * Throws a {@link GLException} if GL-function constraints are not met.
+MethodJavadoc glMapBufferRange * </p>
+MethodJavadoc glMapBufferRange * <p>
+MethodJavadoc glMapBufferRange * Returns {@link GL#mapBufferRange(int, long, long, int)}'s {@link GLBufferStorage#getMappedBuffer()}.
+MethodJavadoc glMapBufferRange * </p>
+MethodJavadoc glMapBufferRange * <p>
+MethodJavadoc glMapBufferRange * @throws GLException if buffer is not bound to target
+MethodJavadoc glMapBufferRange * @throws GLException if buffer is not tracked
+MethodJavadoc glMapBufferRange * @throws GLException if buffer is already mapped
+MethodJavadoc glMapBufferRange * @throws GLException if buffer has invalid store size, i.e. less-than zero
+MethodJavadoc glMapBufferRange * @throws GLException if buffer mapping range does not fit, incl. offset
+MethodJavadoc glMapBufferRange * </p>
+
+ManuallyImplement glUnmapBuffer
+ForceProcAddressGen glUnmapBuffer
 
 # Ignore the ATI_map_object_buffer extension for now unless someone
 # claims they need it, as it will undoubtedly require a similar
@@ -550,14 +604,18 @@ JavaEpilogue glBindFramebuffer  _context.setBoundFramebuffer(target, framebuffer
 # 
 JavaPrologue glBegin inBeginEndPair = true;
 JavaEpilogue glEnd   inBeginEndPair = false;
-JavaEpilogue glBindBuffer       bufferStateTracker.setBoundBufferObject({0}, {1});
-JavaEpilogue glBindBufferARB    bufferStateTracker.setBoundBufferObject({0}, {1});
-JavaEpilogue glBindVertexArray  bufferStateTracker.setBoundBufferObject(GL2GL3.GL_VERTEX_ARRAY_BINDING, {0});
-JavaEpilogue glPushClientAttrib bufferStateTracker.clearBufferObjectState();
-JavaEpilogue glPushClientAttrib glStateTracker.pushAttrib(mask);
-JavaEpilogue glPopClientAttrib  bufferStateTracker.clearBufferObjectState();
-JavaEpilogue glPopClientAttrib  glStateTracker.popAttrib();
-JavaEpilogue glBufferData       bufferSizeTracker.setBufferSize(bufferStateTracker, {0}, this, {1});
+
+JavaEpilogue glBindBuffer          bufferStateTracker.setBoundBufferObject({0}, {1});
+JavaEpilogue glBindBufferARB       bufferStateTracker.setBoundBufferObject({0}, {1});
+JavaEpilogue glBindBufferBase      bufferStateTracker.setBoundBufferObject({0}, {2});
+JavaEpilogue glBindBufferRange     bufferStateTracker.setBoundBufferObject({0}, {2});
+JavaEpilogue glBindVertexArray     bufferStateTracker.setBoundBufferObject(GL2GL3.GL_VERTEX_ARRAY_BINDING, {0});
+JavaEpilogue glPushClientAttrib    bufferStateTracker.clear();
+JavaEpilogue glPushClientAttrib    glStateTracker.pushAttrib(mask);
+JavaEpilogue glPopClientAttrib     bufferStateTracker.clear();
+JavaEpilogue glPopClientAttrib     glStateTracker.popAttrib();
+
+JavaPrologue glDeleteBuffers       bufferObjectTracker.notifyBuffersDeleted({0}, {1});
 
 BufferObjectKind Array glColorPointer
 BufferObjectKind Array glEdgeFlagPointer
diff --git a/make/config/jogl/gl-gl4bc.cfg b/make/config/jogl/gl-gl4bc.cfg
index c3a392c..6ccbace 100644
--- a/make/config/jogl/gl-gl4bc.cfg
+++ b/make/config/jogl/gl-gl4bc.cfg
@@ -55,11 +55,51 @@ Include gl3-desktop.cfg
 Include gl3-common.cfg
 Include gl2_es2-CustomJavaCode.cfg
 
-# Manually implement glMapNamedBufferEXT as the size of the returned buffer
-# can only be computed by calling another routine
+#
+# Manually implement following GL functions to be redirected 
+# to GLBufferObjectTracker.
+#
+ManuallyImplement glNamedBufferDataEXT
+ForceProcAddressGen glNamedBufferDataEXT
+MethodJavadoc glNamedBufferDataEXT * <p>
+MethodJavadoc glNamedBufferDataEXT * Throws a {@link GLException} if GL-function constraints are not met or the native GL-function fails.
+MethodJavadoc glNamedBufferDataEXT * </p>
+MethodJavadoc glNamedBufferDataEXT * <p>
+MethodJavadoc glNamedBufferDataEXT * @throws GLException if size is less-than zero
+MethodJavadoc glNamedBufferDataEXT * @throws GLException if a native GL-Error occurs
+MethodJavadoc glNamedBufferDataEXT * </p>
+
 ManuallyImplement glMapNamedBufferEXT
 ForceProcAddressGen glMapNamedBufferEXT
-JavaEpilogue glNamedBufferDataEXT bufferSizeTracker.setDirectStateBufferSize({0}, this, {1});
+MethodJavadoc glMapNamedBufferEXT * <p>
+MethodJavadoc glMapNamedBufferEXT * Throws a {@link GLException} if GL-function constraints are not met.
+MethodJavadoc glMapNamedBufferEXT * </p>
+MethodJavadoc glMapNamedBufferEXT * <p>
+MethodJavadoc glMapNamedBufferEXT * Returns {@link GL2#mapNamedBuffer(int, int)}'s {@link GLBufferStorage#getMappedBuffer()}.
+MethodJavadoc glMapNamedBufferEXT * </p>
+MethodJavadoc glMapNamedBufferEXT * <p>
+MethodJavadoc glMapNamedBufferEXT * @throws GLException if buffer is not tracked
+MethodJavadoc glMapNamedBufferEXT * @throws GLException if buffer is already mapped
+MethodJavadoc glMapNamedBufferEXT * @throws GLException if buffer has invalid store size, i.e. less-than zero
+MethodJavadoc glMapNamedBufferEXT * </p>
+
+ManuallyImplement glMapNamedBufferRangeEXT
+ForceProcAddressGen glMapNamedBufferRangeEXT
+MethodJavadoc glMapNamedBufferRangeEXT * <p>
+MethodJavadoc glMapNamedBufferRangeEXT * Throws a {@link GLException} if GL-function constraints are not met.
+MethodJavadoc glMapNamedBufferRangeEXT * </p>
+MethodJavadoc glMapNamedBufferRangeEXT * <p>
+MethodJavadoc glMapNamedBufferRangeEXT * Returns {@link GL2#mapNamedBufferRange(int, long, long, int)}'s {@link GLBufferStorage#getMappedBuffer()}.
+MethodJavadoc glMapNamedBufferRangeEXT * </p>
+MethodJavadoc glMapNamedBufferRangeEXT * <p>
+MethodJavadoc glMapNamedBufferRangeEXT * @throws GLException if buffer is not tracked
+MethodJavadoc glMapNamedBufferRangeEXT * @throws GLException if buffer is already mapped
+MethodJavadoc glMapNamedBufferRangeEXT * @throws GLException if buffer has invalid store size, i.e. less-than zero
+MethodJavadoc glMapNamedBufferRangeEXT * @throws GLException if buffer mapping range does not fit, incl. offset
+MethodJavadoc glMapNamedBufferRangeEXT * </p>
+
+ManuallyImplement glUnmapNamedBufferEXT
+ForceProcAddressGen glUnmapNamedBufferEXT
 
 # Manuall implement glDebugMessageCallback* using the proc address resolver
 ForceProcAddressGen glDebugMessageCallback
diff --git a/make/config/jogl/gl-if-CustomJavaCode-es3.java b/make/config/jogl/gl-if-CustomJavaCode-es3.java
index b68b512..3f976d5 100644
--- a/make/config/jogl/gl-if-CustomJavaCode-es3.java
+++ b/make/config/jogl/gl-if-CustomJavaCode-es3.java
@@ -8,7 +8,11 @@ public static final long GL_TIMEOUT_IGNORED = 0xFFFFFFFFFFFFFFFFL ;
 /** Part of <code>GL_ARB_shader_image_load_store</code> */
 public static final int GL_ALL_BARRIER_BITS = 0xFFFFFFFF ;
 
+/** @deprecated Avoid original GL API namespace conflict. Use {@link #isPBOPackBound()} */
 public boolean glIsPBOPackBound();
+public boolean isPBOPackBound();
 
+/** @deprecated Avoid original GL API namespace conflict. Use {@link #isPBOUnpackBound()} */
 public boolean glIsPBOUnpackBound();
+public boolean isPBOUnpackBound();
 
diff --git a/make/config/jogl/gl-if-CustomJavaCode-gl2.java b/make/config/jogl/gl-if-CustomJavaCode-gl2.java
new file mode 100644
index 0000000..283f72d
--- /dev/null
+++ b/make/config/jogl/gl-if-CustomJavaCode-gl2.java
@@ -0,0 +1,40 @@
+
+  //
+  // GLBufferObjectTracker Redirects
+  //
+
+  /**
+   * Returns the {@link GLBufferStorage} instance as mapped via OpenGL's native {@link GL2#glMapNamedBufferEXT(int, int) glMapNamedBufferEXT(..)} implementation.
+   * <p>
+   * Throws a {@link GLException} if GL-function constraints are not met.
+   * </p>
+   * <p>
+   * {@link GL2#glMapNamedBufferEXT(int, int)} wrapper calls this method and returns {@link GLBufferStorage#getMappedBuffer()}.
+   * </p>
+   * @param bufferName denotes the buffer
+   * @param access the mapping access mode
+   * @throws GLException if buffer is not tracked
+   * @throws GLException if buffer is already mapped
+   * @throws GLException if buffer has invalid store size, i.e. less-than zero
+   */
+  public GLBufferStorage mapNamedBuffer(int bufferName, int access) throws GLException;
+
+  /**
+   * Returns the {@link GLBufferStorage} instance as mapped via OpenGL's native {@link GL2#glMapNamedBufferRangeEXT(int, long, long, int) glMapNamedBufferRangeEXT(..)} implementation.
+   * <p>
+   * Throws a {@link GLException} if GL-function constraints are not met.
+   * </p>
+   * <p>
+   * {@link GL2#glMapNamedBufferRangeEXT(int, long, long, int)} wrapper calls this method and returns {@link GLBufferStorage#getMappedBuffer()}.
+   * </p>
+   * @param bufferName denotes the buffer
+   * @param offset offset of the mapped buffer's storage
+   * @param length length of the mapped buffer's storage
+   * @param access the mapping access mode
+   * @throws GLException if buffer is not tracked
+   * @throws GLException if buffer is already mapped
+   * @throws GLException if buffer has invalid store size, i.e. less-than zero
+   * @throws GLException if buffer mapping range does not fit, incl. offset
+   */
+  public GLBufferStorage mapNamedBufferRange(final int bufferName, final long offset, final long length, final int access) throws GLException;
+
diff --git a/make/config/jogl/gl-if-es3.cfg b/make/config/jogl/gl-if-es3.cfg
index 33e4176..66fd525 100644
--- a/make/config/jogl/gl-if-es3.cfg
+++ b/make/config/jogl/gl-if-es3.cfg
@@ -21,11 +21,13 @@ Extends GLES3 GLES2
 Extends GLES3 GL4ES3
 HierarchicalNativeOutput false
 Include gl-common.cfg
-Include gl-common-gpubufferonly.cfg
 Include gl-common-extensions.cfg
 Include gl2_es3-common.cfg
 Include gl2_es2-CustomJavaCode.cfg
 
+IncludeAs CustomJavaCode GLES3 gl2_es2-common-cpubufferJavaCode.java
+IncludeAs CustomJavaCode GLES3 gl2-common-cpubufferJavaCode.java
+
 ForceExtension GL_ARB_ES3_compatibility
 
 # dummy procaddress config / force procaddress for comments
diff --git a/make/config/jogl/gl-if-gl2.cfg b/make/config/jogl/gl-if-gl2.cfg
index 37f7b6f..0120bd6 100644
--- a/make/config/jogl/gl-if-gl2.cfg
+++ b/make/config/jogl/gl-if-gl2.cfg
@@ -26,6 +26,7 @@ Include gl-desktop.cfg
 Include gl-if-gl3-ignores.cfg
 Include gl-if-gl4-ignores.cfg
 
+IncludeAs CustomJavaCode GL2 gl-if-CustomJavaCode-gl2.java
 IncludeAs CustomJavaCode GL2 gl-if-CustomJavaCode-gl_compat.java
 IncludeAs CustomJavaCode GL2 gl2_es2-common-cpubufferJavaCode.java
 IncludeAs CustomJavaCode GL2 gl2-common-cpubufferJavaCode.java
diff --git a/make/config/jogl/gl-impl-CustomCCode-gl4bc.c b/make/config/jogl/gl-impl-CustomCCode-gl4bc.c
index 4ddc27b..42e5700 100644
--- a/make/config/jogl/gl-impl-CustomCCode-gl4bc.c
+++ b/make/config/jogl/gl-impl-CustomCCode-gl4bc.c
@@ -1,6 +1,77 @@
 /*   Java->C glue code:
  *   Java package: jogamp.opengl.gl4.GL4bcImpl
- *    Java method: long dispatch_glMapBuffer(int target, int access)
+ *    Java method: void dispatch_glBufferData(int target, long size, java.nio.Buffer data, int usage)
+ *     C function: void glBufferData(GLenum target, GLsizeiptr size, const GLvoid *  data, GLenum usage);
+ */
+JNIEXPORT void JNICALL
+Java_jogamp_opengl_gl4_GL4bcImpl_dispatch_1glBufferData(JNIEnv *env, jobject _unused, jint target, jlong size, jobject data, jint data_byte_offset, jboolean data_is_nio, jint usage, jlong procAddress) {
+  typedef void (APIENTRY*_local_PFNGLBUFFERDATAPROC)(GLenum target, GLsizeiptr size, const GLvoid *  data, GLenum usage);
+  _local_PFNGLBUFFERDATAPROC ptr_glBufferData;
+  GLvoid * _data_ptr = NULL;
+  if ( NULL != data ) {
+    _data_ptr = (GLvoid *) ( JNI_TRUE == data_is_nio ?  (*env)->GetDirectBufferAddress(env, data) :  (*env)->GetPrimitiveArrayCritical(env, data, NULL) );  }
+  ptr_glBufferData = (_local_PFNGLBUFFERDATAPROC) (intptr_t) procAddress;
+  assert(ptr_glBufferData != NULL);
+  (* ptr_glBufferData) ((GLenum) target, (GLsizeiptr) size, (GLvoid *) (((char *) _data_ptr) + data_byte_offset), (GLenum) usage);
+  if ( JNI_FALSE == data_is_nio && NULL != data ) {
+    (*env)->ReleasePrimitiveArrayCritical(env, data, _data_ptr, JNI_ABORT);  }
+}
+
+/** FIXME Add for OpenGL 4.4: glBufferStorage */
+
+/*   Java->C glue code:
+ *   Java package: jogamp.opengl.gl4.GL4bcImpl
+ *    Java method: void dispatch_glNamedBufferDataEXT(int buffer, long size, java.nio.Buffer data, int usage)
+ *     C function: void glNamedBufferDataEXT(GLuint buffer, GLsizeiptr size, const GLvoid *  data, GLenum usage);
+ */
+JNIEXPORT void JNICALL
+Java_jogamp_opengl_gl4_GL4bcImpl_dispatch_1glNamedBufferDataEXT(JNIEnv *env, jobject _unused, jint buffer, jlong size, jobject data, jint data_byte_offset, jboolean data_is_nio, jint usage, jlong procAddress) {
+  typedef void (APIENTRY*_local_PFNGLNAMEDBUFFERDATAEXTPROC)(GLuint buffer, GLsizeiptr size, const GLvoid *  data, GLenum usage);
+  _local_PFNGLNAMEDBUFFERDATAEXTPROC ptr_glNamedBufferDataEXT;
+  GLvoid * _data_ptr = NULL;
+  if ( NULL != data ) {
+    _data_ptr = (GLvoid *) ( JNI_TRUE == data_is_nio ?  (*env)->GetDirectBufferAddress(env, data) :  (*env)->GetPrimitiveArrayCritical(env, data, NULL) );  }
+  ptr_glNamedBufferDataEXT = (_local_PFNGLNAMEDBUFFERDATAEXTPROC) (intptr_t) procAddress;
+  assert(ptr_glNamedBufferDataEXT != NULL);
+  (* ptr_glNamedBufferDataEXT) ((GLuint) buffer, (GLsizeiptr) size, (GLvoid *) (((char *) _data_ptr) + data_byte_offset), (GLenum) usage);
+  if ( JNI_FALSE == data_is_nio && NULL != data ) {
+    (*env)->ReleasePrimitiveArrayCritical(env, data, _data_ptr, JNI_ABORT);  }
+}
+
+/*   Java->C glue code:
+ *   Java package: jogamp.opengl.gl4.GL4bcImpl
+ *    Java method: boolean dispatch_glUnmapBuffer(int target)
+ *     C function: GLboolean glUnmapBuffer(GLenum target);
+ */
+JNIEXPORT jboolean JNICALL
+Java_jogamp_opengl_gl4_GL4bcImpl_dispatch_1glUnmapBuffer(JNIEnv *env, jobject _unused, jint target, jlong procAddress) {
+  typedef GLboolean (APIENTRY*_local_PFNGLUNMAPBUFFERPROC)(GLenum target);
+  _local_PFNGLUNMAPBUFFERPROC ptr_glUnmapBuffer;
+  GLboolean _res;
+  ptr_glUnmapBuffer = (_local_PFNGLUNMAPBUFFERPROC) (intptr_t) procAddress;
+  assert(ptr_glUnmapBuffer != NULL);
+  _res = (* ptr_glUnmapBuffer) ((GLenum) target);
+  return _res;
+}
+
+/*   Java->C glue code:
+ *   Java package: jogamp.opengl.gl4.GL4bcImpl
+ *    Java method: boolean dispatch_glUnmapNamedBufferEXT(int buffer)
+ *     C function: GLboolean glUnmapNamedBufferEXT(GLuint buffer);
+ */
+JNIEXPORT jboolean JNICALL
+Java_jogamp_opengl_gl4_GL4bcImpl_dispatch_1glUnmapNamedBufferEXT(JNIEnv *env, jobject _unused, jint buffer, jlong procAddress) {
+  typedef GLboolean (APIENTRY*_local_PFNGLUNMAPNAMEDBUFFEREXTPROC)(GLuint buffer);
+  _local_PFNGLUNMAPNAMEDBUFFEREXTPROC ptr_glUnmapNamedBufferEXT;
+  GLboolean _res;
+  ptr_glUnmapNamedBufferEXT = (_local_PFNGLUNMAPNAMEDBUFFEREXTPROC) (intptr_t) procAddress;
+  assert(ptr_glUnmapNamedBufferEXT != NULL);
+  _res = (* ptr_glUnmapNamedBufferEXT) ((GLuint) buffer);
+  return _res;
+}
+
+/*   Java->C glue code:
+ *   Java package: jogamp.opengl.gl4.GL4bcImpl *    Java method: long dispatch_glMapBuffer(int target, int access)
  *     C function: void * glMapBuffer(GLenum target, GLenum access);
  */
 JNIEXPORT jlong JNICALL 
@@ -40,10 +111,26 @@ Java_jogamp_opengl_gl4_GL4bcImpl_dispatch_1glMapNamedBufferEXT(JNIEnv *env, jobj
   void * _res;
   ptr_glMapNamedBufferEXT = (PFNGLMAPNAMEDBUFFEREXTPROC) (intptr_t) glProcAddress;
   assert(ptr_glMapNamedBufferEXT != NULL);
-  _res = (* ptr_glMapNamedBufferEXT) ((GLenum) target, (GLenum) access);
+  _res = (* ptr_glMapNamedBufferEXT) ((GLuint) target, (GLenum) access);
+  return (jlong) (intptr_t) _res;
+}
+
+/*   Java->C glue code:
+ *   Java package: jogamp.opengl.gl4.GL4bcImpl
+ *    Java method: java.nio.ByteBuffer dispatch_glMapNamedBufferRangeEXT(int buffer, long offset, long length, int access)
+ *     C function: void *  glMapNamedBufferRangeEXT(GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access);
+ */
+JNIEXPORT jlong JNICALL
+Java_jogamp_opengl_gl4_GL4bcImpl_dispatch_1glMapNamedBufferRangeEXT(JNIEnv *env, jobject _unused, jint buffer, jlong offset, jlong length, jint access, jlong procAddress) {
+  PFNGLMAPNAMEDBUFFERRANGEEXTPROC ptr_glMapNamedBufferRangeEXT;
+  void *  _res;
+  ptr_glMapNamedBufferRangeEXT = (PFNGLMAPNAMEDBUFFERRANGEEXTPROC) (intptr_t) procAddress;
+  assert(ptr_glMapNamedBufferRangeEXT != NULL);
+  _res = (* ptr_glMapNamedBufferRangeEXT) ((GLuint) buffer, (GLintptr) offset, (GLsizeiptr) length, (GLbitfield) access);
   return (jlong) (intptr_t) _res;
 }
 
+
 /*   Java->C glue code:
  *   Java package: jogamp.opengl.gl4.GL4bcImpl
  *    Java method: ByteBuffer newDirectByteBuffer(long addr, long capacity);
diff --git a/make/config/jogl/gl-impl-CustomCCode-gles1.c b/make/config/jogl/gl-impl-CustomCCode-gles1.c
index 88cfe44..83b8c75 100644
--- a/make/config/jogl/gl-impl-CustomCCode-gles1.c
+++ b/make/config/jogl/gl-impl-CustomCCode-gles1.c
@@ -1,3 +1,38 @@
+/*   Java->C glue code:
+ *   Java package: jogamp.opengl.es1.GLES1Impl
+ *    Java method: void dispatch_glBufferData(int target, long size, java.nio.Buffer data, int usage)
+ *     C function: void glBufferData(GLenum target, GLsizeiptr size, const GLvoid *  data, GLenum usage);
+ */
+JNIEXPORT void JNICALL
+Java_jogamp_opengl_es1_GLES1Impl_dispatch_1glBufferData(JNIEnv *env, jobject _unused, jint target, jlong size, jobject data, jint data_byte_offset, jboolean data_is_nio, jint usage, jlong procAddress) {
+  typedef void (GL_APIENTRY*_local_PFNGLBUFFERDATAPROC)(GLenum target, GLsizeiptr size, const GLvoid *  data, GLenum usage);
+  _local_PFNGLBUFFERDATAPROC ptr_glBufferData;
+  GLvoid * _data_ptr = NULL;
+  if ( NULL != data ) {
+    _data_ptr = (GLvoid *) ( JNI_TRUE == data_is_nio ?  (*env)->GetDirectBufferAddress(env, data) :  (*env)->GetPrimitiveArrayCritical(env, data, NULL) );  }
+  ptr_glBufferData = (_local_PFNGLBUFFERDATAPROC) (intptr_t) procAddress;
+  assert(ptr_glBufferData != NULL);
+  (* ptr_glBufferData) ((GLenum) target, (GLsizeiptr) size, (GLvoid *) (((char *) _data_ptr) + data_byte_offset), (GLenum) usage);
+  if ( JNI_FALSE == data_is_nio && NULL != data ) {
+    (*env)->ReleasePrimitiveArrayCritical(env, data, _data_ptr, JNI_ABORT);  }
+}
+
+/*   Java->C glue code:
+ *   Java package: jogamp.opengl.es1.GLES1Impl
+ *    Java method: boolean dispatch_glUnmapBuffer(int target)
+ *     C function: GLboolean glUnmapBufferOES(GLenum target);
+ */
+JNIEXPORT jboolean JNICALL
+Java_jogamp_opengl_es1_GLES1Impl_dispatch_1glUnmapBuffer(JNIEnv *env, jobject _unused, jint target, jlong procAddress) {
+  typedef GLboolean (GL_APIENTRY*_local_PFNGLUNMAPBUFFEROESPROC)(GLenum target);
+  _local_PFNGLUNMAPBUFFEROESPROC ptr_glUnmapBufferOES;
+  GLboolean _res;
+  ptr_glUnmapBufferOES = (_local_PFNGLUNMAPBUFFEROESPROC) (intptr_t) procAddress;
+  assert(ptr_glUnmapBufferOES != NULL);
+  _res = (* ptr_glUnmapBufferOES) ((GLenum) target);
+  return _res;
+}
+
 typedef GLvoid* (GL_APIENTRY* PFNGLMAPBUFFERPROC) (GLenum target, GLenum access);
 /*   Java->C glue code:
  *   Java package: jogamp.opengl.es1.GLES1Impl
diff --git a/make/config/jogl/gl-impl-CustomCCode-gles3.c b/make/config/jogl/gl-impl-CustomCCode-gles3.c
index 2f3329b..ff1d42e 100644
--- a/make/config/jogl/gl-impl-CustomCCode-gles3.c
+++ b/make/config/jogl/gl-impl-CustomCCode-gles3.c
@@ -1,4 +1,40 @@
+/*   Java->C glue code:
+ *   Java package: jogamp.opengl.es3.GLES3Impl
+ *    Java method: void dispatch_glBufferData(int target, long size, java.nio.Buffer data, int usage)
+ *     C function: void glBufferData(GLenum target, GLsizeiptr size, const GLvoid *  data, GLenum usage);
+ */
+JNIEXPORT void JNICALL
+Java_jogamp_opengl_es3_GLES3Impl_dispatch_1glBufferData(JNIEnv *env, jobject _unused, jint target, jlong size, jobject data, jint data_byte_offset, jboolean data_is_nio, jint usage, jlong procAddress) {
+  typedef void (GL_APIENTRY*_local_PFNGLBUFFERDATAPROC)(GLenum target, GLsizeiptr size, const GLvoid *  data, GLenum usage);
+  _local_PFNGLBUFFERDATAPROC ptr_glBufferData;
+  GLvoid * _data_ptr = NULL;
+  if ( NULL != data ) {
+    _data_ptr = (GLvoid *) ( JNI_TRUE == data_is_nio ?  (*env)->GetDirectBufferAddress(env, data) :  (*env)->GetPrimitiveArrayCritical(env, data, NULL) );  }
+  ptr_glBufferData = (_local_PFNGLBUFFERDATAPROC) (intptr_t) procAddress;
+  assert(ptr_glBufferData != NULL);
+  (* ptr_glBufferData) ((GLenum) target, (GLsizeiptr) size, (GLvoid *) (((char *) _data_ptr) + data_byte_offset), (GLenum) usage);
+  if ( JNI_FALSE == data_is_nio && NULL != data ) {
+    (*env)->ReleasePrimitiveArrayCritical(env, data, _data_ptr, JNI_ABORT);  }
+}
+
+/*   Java->C glue code:
+ *   Java package: jogamp.opengl.es3.GLES3Impl
+ *    Java method: boolean dispatch_glUnmapBuffer(int target)
+ *     C function: GLboolean glUnmapBuffer(GLenum target);
+ */
+JNIEXPORT jboolean JNICALL
+Java_jogamp_opengl_es3_GLES3Impl_dispatch_1glUnmapBuffer(JNIEnv *env, jobject _unused, jint target, jlong procAddress) {
+  typedef GLboolean (GL_APIENTRY*_local_PFNGLUNMAPBUFFERPROC)(GLenum target);
+  _local_PFNGLUNMAPBUFFERPROC ptr_glUnmapBuffer;
+  GLboolean _res;
+  ptr_glUnmapBuffer = (_local_PFNGLUNMAPBUFFERPROC) (intptr_t) procAddress;
+  assert(ptr_glUnmapBuffer != NULL);
+  _res = (* ptr_glUnmapBuffer) ((GLenum) target);
+  return _res;
+}
+
 typedef GLvoid* (GL_APIENTRY* PFNGLMAPBUFFERPROC) (GLenum target, GLenum access);
+
 /*   Java->C glue code:
  *   Java package: jogamp.opengl.es3.GLES3Impl
  *    Java method: long dispatch_glMapBuffer(int target, int access)
diff --git a/make/config/jogl/gl-impl-CustomJavaCode-common.java b/make/config/jogl/gl-impl-CustomJavaCode-common.java
index b8da610..f024635 100644
--- a/make/config/jogl/gl-impl-CustomJavaCode-common.java
+++ b/make/config/jogl/gl-impl-CustomJavaCode-common.java
@@ -6,21 +6,37 @@
 
     @Override
     public final int glGetBoundBuffer(int target) {
+        return getBoundBuffer(target);
+    }
+    @Override
+    public final int getBoundBuffer(int target) {
         return bufferStateTracker.getBoundBufferObject(target, this);
     }
 
     @Override
-    public final long glGetBufferSize(int buffer) {
-        return bufferSizeTracker.getDirectStateBufferSize(buffer, this);
+    public final long glGetBufferSize(int bufferName) {
+        return bufferObjectTracker.getBufferSize(bufferName);
+    }
+    @Override
+    public final GLBufferStorage getBufferStorage(int bufferName) {
+        return bufferObjectTracker.getBufferStorage(bufferName);
     }
 
     @Override
     public final boolean glIsVBOArrayBound() {
+        return isVBOArrayBound();
+    }
+    @Override
+    public final boolean isVBOArrayBound() {
         return checkArrayVBOBound(false);
     }
 
     @Override
     public final boolean glIsVBOElementArrayBound() {
+        return isVBOElementArrayBound();
+    }
+    @Override
+    public final boolean isVBOElementArrayBound() {
         return checkElementVBOBound(false);
     }
 
@@ -128,95 +144,60 @@
       return _context.getDefaultReadBuffer();
     }
 
-    private final HashMap<MemoryObject, MemoryObject> arbMemCache = new HashMap<MemoryObject, MemoryObject>();
+    private final GLStateTracker       glStateTracker;
 
-    /** Entry point to C language function: <code> void *  {@native glMapBuffer}(GLenum target, GLenum access); </code> <br>Part of <code>GL_VERSION_1_5</code>; <code>GL_OES_mapbuffer</code>   */
-    private final java.nio.ByteBuffer glMapBufferImpl(int target, boolean useRange, long offset, long length, int access, long glProcAddress) {
-      if (glProcAddress == 0) {
-        throw new GLException("Method \""+(useRange?"glMapBufferRange":"glMapBuffer")+"\" not available");
-      }
-      final long sz = bufferSizeTracker.getBufferSize(bufferStateTracker, target, this);
-      if (0 == sz) {
-        return null;
-      }
-      if( !useRange ) {
-        length = sz;
-        offset = 0;
-      } else {
-        if( length + offset > sz ) {
-            throw new GLException("Out of range: offset "+offset+" + length "+length+" > size "+sz); 
-        }
-        if( 0 > length || 0 > offset ) {
-            throw new GLException("Invalid values: offset "+offset+", length "+length);
-        }
-        if( 0 == length ) {
-            return null;
-        }
-      }
-      final long addr = useRange ? dispatch_glMapBufferRange(target, offset, length, access, glProcAddress) :
-                                   dispatch_glMapBuffer(target, access, glProcAddress);
-      if (0 == addr) {
-        return null;
-      }
-      ByteBuffer buffer;
-      MemoryObject memObj0 = new MemoryObject(addr, length); // object and key
-      MemoryObject memObj1 = MemoryObject.getOrAddSafe(arbMemCache, memObj0);
-      if(memObj0 == memObj1) {
-        // just added ..
-        if(null != memObj0.getBuffer()) {
-            throw new InternalError();
-        }
-        buffer = newDirectByteBuffer(addr, length);
-        Buffers.nativeOrder(buffer);
-        memObj0.setBuffer(buffer);
-      } else {
-        // already mapped
-        buffer = memObj1.getBuffer();
-        if(null == buffer) {
-            throw new InternalError();
-        }
-      }
-      buffer.position(0);
-      return buffer;
+    //
+    // GLBufferObjectTracker Redirects
+    //
+    private final GLBufferObjectTracker bufferObjectTracker;
+    private final GLBufferStateTracker bufferStateTracker;
+
+    private final jogamp.opengl.GLBufferObjectTracker.CreateStorageDispatch createBoundMutableStorageDispatch = 
+        new jogamp.opengl.GLBufferObjectTracker.CreateStorageDispatch() {
+            public final void create(final int target, final long size, final Buffer data, final int mutableUsage, final long glProcAddress) {
+                final boolean data_is_direct = Buffers.isDirect(data);
+                dispatch_glBufferData(target, size, 
+                                      data_is_direct ? data : Buffers.getArray(data), 
+                                      data_is_direct ? Buffers.getDirectBufferByteOffset(data) : Buffers.getIndirectBufferByteOffset(data), 
+                                      data_is_direct, mutableUsage, glProcAddress);
+            }
+        };
+    private native void dispatch_glBufferData(int target, long size, Object data, int data_byte_offset, boolean data_is_direct, int usage, long procAddress);
+
+    private final jogamp.opengl.GLBufferObjectTracker.UnmapBufferDispatch unmapBoundBufferDispatch = 
+        new jogamp.opengl.GLBufferObjectTracker.UnmapBufferDispatch() {
+            public final boolean unmap(final int target, final long glProcAddress) {
+                return dispatch_glUnmapBuffer(target, glProcAddress);
+            }
+        };
+    private native boolean dispatch_glUnmapBuffer(int target, long procAddress);
+
+    @Override
+    public final java.nio.ByteBuffer glMapBuffer(int target, int access) {
+      return mapBuffer(target, access).getMappedBuffer();
+    }
+
+    @Override
+    public final ByteBuffer glMapBufferRange(int target, long offset, long length, int access)  {
+      return mapBufferRange(target, offset, length, access).getMappedBuffer();
     }
-    private native long dispatch_glMapBuffer(int target, int access, long glProcAddress);
-    private native long dispatch_glMapBufferRange(int target, long offset, long length, int access, long procAddress);
 
+    private final jogamp.opengl.GLBufferObjectTracker.MapBufferAllDispatch mapBoundBufferAllDispatch = 
+        new jogamp.opengl.GLBufferObjectTracker.MapBufferAllDispatch() {
+            public final ByteBuffer allocNioByteBuffer(final long addr, final long length) { return newDirectByteBuffer(addr, length); }
+            public final long mapBuffer(final int target, final int access, final long glProcAddress) {
+                return dispatch_glMapBuffer(target, access, glProcAddress);
+            }
+        };
+    private native long dispatch_glMapBuffer(int target, int access, long glProcAddress);
 
-    /** Entry point to C language function: <code> GLvoid *  {@native glMapNamedBufferEXT}(GLuint buffer, GLenum access); </code> <br>Part of <code>GL_EXT_direct_state_access</code>   */
-    private final java.nio.ByteBuffer glMapNamedBufferImpl(int bufferName, int access, long glProcAddress)  {
-      if (glProcAddress == 0) {
-        throw new GLException("Method \"glMapNamedBufferEXT\" not available");
-      }
-      final long sz = bufferSizeTracker.getDirectStateBufferSize(bufferName, this);
-      if (0 == sz) {
-        return null;
-      }
-      final long addr = dispatch_glMapNamedBufferEXT(bufferName, access, glProcAddress);
-      if (0 == addr) {
-        return null;
-      }
-      ByteBuffer buffer;
-      MemoryObject memObj0 = new MemoryObject(addr, sz); // object and key
-      MemoryObject memObj1 = MemoryObject.getOrAddSafe(arbMemCache, memObj0);
-      if(memObj0 == memObj1) {
-        // just added ..
-        if(null != memObj0.getBuffer()) {
-            throw new InternalError();
-        }
-        buffer = newDirectByteBuffer(addr, sz);
-        Buffers.nativeOrder(buffer);
-        memObj0.setBuffer(buffer);
-      } else {
-        // already mapped
-        buffer = memObj1.getBuffer();
-        if(null == buffer) {
-            throw new InternalError();
-        }
-      }
-      buffer.position(0);
-      return buffer;
-    }
-    private native long dispatch_glMapNamedBufferEXT(int buffer, int access, long procAddress);
+    private final jogamp.opengl.GLBufferObjectTracker.MapBufferRangeDispatch mapBoundBufferRangeDispatch = 
+        new jogamp.opengl.GLBufferObjectTracker.MapBufferRangeDispatch() {
+            public final ByteBuffer allocNioByteBuffer(final long addr, final long length) { return newDirectByteBuffer(addr, length); }
+            public final long mapBuffer(final int target, final long offset, final long length, final int access, final long glProcAddress) {
+                return dispatch_glMapBufferRange(target, offset, length, access, glProcAddress);
+            }
+        };
+    private native long dispatch_glMapBufferRange(int target, long offset, long length, int access, long glProcAddress);
 
     private native ByteBuffer newDirectByteBuffer(long addr, long capacity);
diff --git a/make/config/jogl/gl-impl-CustomJavaCode-gl4bc.java b/make/config/jogl/gl-impl-CustomJavaCode-gl4bc.java
index e7389de..f0adb53 100644
--- a/make/config/jogl/gl-impl-CustomJavaCode-gl4bc.java
+++ b/make/config/jogl/gl-impl-CustomJavaCode-gl4bc.java
@@ -18,11 +18,11 @@ public void setObjectTracker(GLObjectTracker tracker) {
 public GL4bcImpl(GLProfile glp, GLContextImpl context) {
   this._context = context; 
   if(null != context) {
-      this.bufferSizeTracker  = context.getBufferSizeTracker();
+      this.bufferObjectTracker  = context.getBufferObjectTracker();
       this.bufferStateTracker = context.getBufferStateTracker();
       this.glStateTracker     = context.getGLStateTracker();
   } else {
-      this.bufferSizeTracker  = null;
+      this.bufferObjectTracker  = null;
       this.bufferStateTracker = null;
       this.glStateTracker     = null;
   }
@@ -280,10 +280,6 @@ public final void glFreeMemoryNV(java.nio.ByteBuffer pointer) {
 // Helpers for ensuring the correct amount of texture data
 //
 
-private final GLBufferSizeTracker  bufferSizeTracker;
-private final GLBufferStateTracker bufferStateTracker;
-private final GLStateTracker       glStateTracker;
-
 private boolean haveARBPixelBufferObject;
 private boolean haveEXTPixelBufferObject;
 private boolean haveGL15;
@@ -431,67 +427,207 @@ private final boolean checkPackPBOBound(boolean throwException) {
 
 @Override
 public final boolean glIsPBOPackBound() {
+    return isPBOPackBound();
+}
+ at Override
+public final boolean isPBOPackBound() {
     return checkPackPBOBound(false);
 }
 
 @Override
 public final boolean glIsPBOUnpackBound() {
+    return isPBOUnpackBound();
+}
+ at Override
+public final boolean isPBOUnpackBound() {
     return checkUnpackPBOBound(false);
 }
 
-/** Entry point to C language function: <code> void *  {@native glMapBuffer}(GLenum target, GLenum access); </code> <br>Part of <code>GL_VERSION_1_5</code>; <code>GL_OES_mapbuffer</code>   */
-public final java.nio.ByteBuffer glMapBuffer(int target, int access) {
-  return glMapBufferImpl(target, false, 0, 0, access, ((GL4bcProcAddressTable)_context.getGLProcAddressTable())._addressof_glMapBuffer);
+ at Override
+public final void glVertexPointer(GLArrayData array) {
+  if(array.getComponentCount()==0) return;
+  if(array.isVBO()) {
+      glVertexPointer(array.getComponentCount(), array.getComponentType(), array.getStride(), array.getVBOOffset());
+  } else {
+      glVertexPointer(array.getComponentCount(), array.getComponentType(), array.getStride(), array.getBuffer());
+  }
 }
+ at Override
+public final void glColorPointer(GLArrayData array) {
+  if(array.getComponentCount()==0) return;
+  if(array.isVBO()) {
+      glColorPointer(array.getComponentCount(), array.getComponentType(), array.getStride(), array.getVBOOffset());
+  } else {
+      glColorPointer(array.getComponentCount(), array.getComponentType(), array.getStride(), array.getBuffer());
+  }
 
-/** Entry point to C language function: <code> void *  {@native glMapBufferRange}(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); </code> <br>Part of <code>GL_ES_VERSION_3_0</code>, <code>GL_VERSION_3_0</code>; <code>GL_EXT_map_buffer_range</code>   */
-public final ByteBuffer glMapBufferRange(int target, long offset, long length, int access)  {
-  return glMapBufferImpl(target, true, offset, length, access, ((GL4bcProcAddressTable)_context.getGLProcAddressTable())._addressof_glMapBufferRange);
 }
-
-/** Entry point to C language function: <code> GLvoid *  {@native glMapNamedBufferEXT}(GLuint buffer, GLenum access); </code> <br>Part of <code>GL_EXT_direct_state_access</code>   */
-public final java.nio.ByteBuffer glMapNamedBufferEXT(int bufferName, int access)  {
-  return glMapNamedBufferImpl(bufferName, access, ((GL4bcProcAddressTable)_context.getGLProcAddressTable())._addressof_glMapNamedBufferEXT);
+ at Override
+public final void glNormalPointer(GLArrayData array) {
+  if(array.getComponentCount()==0) return;
+  if(array.getComponentCount()!=3) {
+    throw new GLException("Only 3 components per normal allowed");
+  }
+  if(array.isVBO()) {
+      glNormalPointer(array.getComponentType(), array.getStride(), array.getVBOOffset());
+  } else {
+      glNormalPointer(array.getComponentType(), array.getStride(), array.getBuffer());
+  }
+}
+ at Override
+public final void glTexCoordPointer(GLArrayData array) {
+  if(array.getComponentCount()==0) return;
+  if(array.isVBO()) {
+      glTexCoordPointer(array.getComponentCount(), array.getComponentType(), array.getStride(), array.getVBOOffset());
+  } else {
+      glTexCoordPointer(array.getComponentCount(), array.getComponentType(), array.getStride(), array.getBuffer());
+  }
 }
 
-    @Override
-    public final void glVertexPointer(GLArrayData array) {
-      if(array.getComponentCount()==0) return;
-      if(array.isVBO()) {
-          glVertexPointer(array.getComponentCount(), array.getComponentType(), array.getStride(), array.getVBOOffset());
-      } else {
-          glVertexPointer(array.getComponentCount(), array.getComponentType(), array.getStride(), array.getBuffer());
-      }
+//
+// GLBufferObjectTracker Redirects
+//
+
+ at Override
+public final void glBufferData(int target, long size, Buffer data, int usage)  {
+    final long glProcAddress = ((GL4bcProcAddressTable)_context.getGLProcAddressTable())._addressof_glBufferData;
+    if ( 0 == glProcAddress ) {
+      throw new GLException(String.format("Method \"%s\" not available", "glBufferData"));
+    }
+    bufferObjectTracker.createBufferStorage(bufferStateTracker, this, 
+                                            target, size, data, usage, 0 /* immutableFlags */, 
+                                            createBoundMutableStorageDispatch, glProcAddress);
+}
+/** FIXME Add for OpenGL 4.4
+ at Override
+public final void glBufferStorage(int target, long size, Buffer data, int flags)  {
+    final long glProcAddress = ((GL4bcProcAddressTable)_context.getGLProcAddressTable())._addressof_glBufferStorage;
+    if ( 0 == glProcAddress ) {
+      throw new GLException(String.format("Method \"%s\" not available", "glBufferStorage"));
     }
-    @Override
-    public final void glColorPointer(GLArrayData array) {
-      if(array.getComponentCount()==0) return;
-      if(array.isVBO()) {
-          glColorPointer(array.getComponentCount(), array.getComponentType(), array.getStride(), array.getVBOOffset());
-      } else {
-          glColorPointer(array.getComponentCount(), array.getComponentType(), array.getStride(), array.getBuffer());
-      }
+    bufferObjectTracker.createBufferStorage(bufferStateTracker, this, 
+                                            target, size, data, 0 * mutableUsage *, flags, 
+                                            createBoundImmutableStorageDispatch, glProcAddress);
+}
+private final jogamp.opengl.GLBufferObjectTracker.CreateStorageDispatch createBoundImmutableStorageDispatch = 
+    new jogamp.opengl.GLBufferObjectTracker.CreateStorageDispatch() {
+        public final void create(final int target, final long size, final Buffer data, final int immutableFlags, final long glProcAddress) {
+            final boolean data_is_direct = Buffers.isDirect(data);
+            dispatch_glBufferStorage(target, size, 
+                                  data_is_direct ? data : Buffers.getArray(data), 
+                                  data_is_direct ? Buffers.getDirectBufferByteOffset(data) : Buffers.getIndirectBufferByteOffset(data), 
+                                  data_is_direct, immutableFlags, glProcAddress);
+        }
+    };
+private native void dispatch_glBufferStorage(int target, long size, Object data, int data_byte_offset, boolean data_is_direct, int flags, long procAddress);
+ */
 
+ at Override
+public final void glNamedBufferDataEXT(int buffer, long size, Buffer data, int usage)  {
+    final long glProcAddress = ((GL4bcProcAddressTable)_context.getGLProcAddressTable())._addressof_glNamedBufferDataEXT;
+    if ( 0 == glProcAddress ) {
+      throw new GLException(String.format("Method \"%s\" not available", "glNamedBufferDataEXT"));
     }
-    @Override
-    public final void glNormalPointer(GLArrayData array) {
-      if(array.getComponentCount()==0) return;
-      if(array.getComponentCount()!=3) {
-        throw new GLException("Only 3 components per normal allowed");
-      }
-      if(array.isVBO()) {
-          glNormalPointer(array.getComponentType(), array.getStride(), array.getVBOOffset());
-      } else {
-          glNormalPointer(array.getComponentType(), array.getStride(), array.getBuffer());
-      }
+    bufferObjectTracker.createBufferStorage(this, 
+                                            buffer, size, data, usage, 0 /* immutableFlags */,
+                                            createNamedStorageDispatch, glProcAddress);
+}
+private final jogamp.opengl.GLBufferObjectTracker.CreateStorageDispatch createNamedStorageDispatch = 
+    new jogamp.opengl.GLBufferObjectTracker.CreateStorageDispatch() {
+        public final void create(final int buffer, final long size, final Buffer data, final int mutableUsage, final long glProcAddress) {
+            final boolean data_is_direct = Buffers.isDirect(data);
+            dispatch_glNamedBufferDataEXT(buffer, size,
+                                          data_is_direct ? data : Buffers.getArray(data), 
+                                          data_is_direct ? Buffers.getDirectBufferByteOffset(data) : Buffers.getIndirectBufferByteOffset(data), 
+                                          data_is_direct, mutableUsage, glProcAddress);
+        }
+    };
+private native void dispatch_glNamedBufferDataEXT(int buffer, long size, Object data, int data_byte_offset, boolean data_is_direct, int usage, long procAddress);
+
+ at Override
+public boolean glUnmapBuffer(int target)  {
+    final long glProcAddress = ((GL4bcProcAddressTable)_context.getGLProcAddressTable())._addressof_glUnmapBuffer;
+    if ( 0 == glProcAddress ) {
+      throw new GLException(String.format("Method \"%s\" not available", "glUnmapBuffer"));
     }
-    @Override
-    public final void glTexCoordPointer(GLArrayData array) {
-      if(array.getComponentCount()==0) return;
-      if(array.isVBO()) {
-          glTexCoordPointer(array.getComponentCount(), array.getComponentType(), array.getStride(), array.getVBOOffset());
-      } else {
-          glTexCoordPointer(array.getComponentCount(), array.getComponentType(), array.getStride(), array.getBuffer());
-      }
+    return bufferObjectTracker.unmapBuffer(bufferStateTracker, this, target, unmapBoundBufferDispatch, glProcAddress);
+}
+
+ at Override
+public boolean glUnmapNamedBufferEXT(int buffer)  {
+    final long glProcAddress = ((GL4bcProcAddressTable)_context.getGLProcAddressTable())._addressof_glUnmapNamedBufferEXT;
+    if ( 0 == glProcAddress ) {
+      throw new GLException(String.format("Method \"%s\" not available", "glUnmapNamedBufferEXT"));
     }
+    return bufferObjectTracker.unmapBuffer(buffer, unmapNamedBufferDispatch, glProcAddress);
+}
+private final jogamp.opengl.GLBufferObjectTracker.UnmapBufferDispatch unmapNamedBufferDispatch = 
+    new jogamp.opengl.GLBufferObjectTracker.UnmapBufferDispatch() {
+        public final boolean unmap(final int buffer, final long glProcAddress) {
+            return dispatch_glUnmapNamedBufferEXT(buffer, glProcAddress);
+        }
+    };
+private native boolean dispatch_glUnmapNamedBufferEXT(int buffer, long procAddress);
+
+ at Override
+public final GLBufferStorage mapBuffer(final int target, final int access) {
+  final long glProcAddress = ((GL4bcProcAddressTable)_context.getGLProcAddressTable())._addressof_glMapBuffer;
+  if ( 0 == glProcAddress ) {
+    throw new GLException("Method \"glMapBuffer\" not available");
+  }
+  return bufferObjectTracker.mapBuffer(bufferStateTracker, this, target, access, mapBoundBufferAllDispatch, glProcAddress);
+}
+ at Override
+public final GLBufferStorage mapBufferRange(final int target, final long offset, final long length, final int access) {
+  final long glProcAddress = ((GL4bcProcAddressTable)_context.getGLProcAddressTable())._addressof_glMapBufferRange;
+  if ( 0 == glProcAddress ) {
+    throw new GLException("Method \"glMapBufferRange\" not available");
+  }
+  return bufferObjectTracker.mapBuffer(bufferStateTracker, this, target, offset, length, access, mapBoundBufferRangeDispatch, glProcAddress);
+}
+
+ at Override
+public final GLBufferStorage mapNamedBuffer(final int bufferName, final int access) {
+  final long glProcAddress = ((GL4bcProcAddressTable)_context.getGLProcAddressTable())._addressof_glMapNamedBufferEXT;
+  if ( 0 == glProcAddress ) {
+    throw new GLException("Method \"glMapNamedBufferEXT\" not available");
+  }
+  return bufferObjectTracker.mapBuffer(bufferName, access, mapNamedBufferAllDispatch, glProcAddress);
+}
+private final jogamp.opengl.GLBufferObjectTracker.MapBufferAllDispatch mapNamedBufferAllDispatch = 
+    new jogamp.opengl.GLBufferObjectTracker.MapBufferAllDispatch() {
+        public final ByteBuffer allocNioByteBuffer(final long addr, final long length) { return newDirectByteBuffer(addr, length); }
+        public final long mapBuffer(final int bufferName, final int access, final long glProcAddress) {
+            return dispatch_glMapNamedBufferEXT(bufferName, access, glProcAddress);
+        }
+    };
+private native long dispatch_glMapNamedBufferEXT(int buffer, int access, long glProcAddress);
+
+ at Override
+public final GLBufferStorage mapNamedBufferRange(final int bufferName, final long offset, final long length, final int access) {
+  final long glProcAddress = ((GL4bcProcAddressTable)_context.getGLProcAddressTable())._addressof_glMapNamedBufferRangeEXT;
+  if ( 0 == glProcAddress ) {
+    throw new GLException("Method \"glMapNamedBufferRangeEXT\" not available");
+  }
+  return bufferObjectTracker.mapBuffer(bufferName, offset, length, access, mapNamedBufferRangeDispatch, glProcAddress);
+}
+private final jogamp.opengl.GLBufferObjectTracker.MapBufferRangeDispatch mapNamedBufferRangeDispatch = 
+    new jogamp.opengl.GLBufferObjectTracker.MapBufferRangeDispatch() {
+        public final ByteBuffer allocNioByteBuffer(final long addr, final long length) { return newDirectByteBuffer(addr, length); }
+        public final long mapBuffer(final int bufferName, final long offset, final long length, final int access, final long glProcAddress) {
+            return dispatch_glMapNamedBufferRangeEXT(bufferName, offset, length, access, glProcAddress);
+        }
+    };
+private native long dispatch_glMapNamedBufferRangeEXT(int buffer, long offset, long length, int access, long procAddress);
+
+ at Override
+public final java.nio.ByteBuffer glMapNamedBufferEXT(int bufferName, int access)  {
+  return mapNamedBuffer(bufferName, access).getMappedBuffer();
+}
+
+ at Override
+public final ByteBuffer glMapNamedBufferRangeEXT(int bufferName, long offset, long length, int access)  {
+  return mapNamedBufferRange(bufferName, offset, length, access).getMappedBuffer();
+}
+
 
diff --git a/make/config/jogl/gl-impl-CustomJavaCode-gles1.java b/make/config/jogl/gl-impl-CustomJavaCode-gles1.java
index 8d5dcc7..6a7e12c 100644
--- a/make/config/jogl/gl-impl-CustomJavaCode-gles1.java
+++ b/make/config/jogl/gl-impl-CustomJavaCode-gles1.java
@@ -1,11 +1,11 @@
 public GLES1Impl(GLProfile glp, GLContextImpl context) {
   this._context = context; 
   if(null != context) {
-      this.bufferSizeTracker  = context.getBufferSizeTracker();
+      this.bufferObjectTracker  = context.getBufferObjectTracker();
       this.bufferStateTracker = context.getBufferStateTracker();
       this.glStateTracker     = context.getGLStateTracker();
   } else {
-      this.bufferSizeTracker  = null;
+      this.bufferObjectTracker  = null;
       this.bufferStateTracker = null;
       this.glStateTracker     = null;
   }
@@ -199,10 +199,6 @@ public final GL2GL3 getGL2GL3() throws GLException {
 // Helpers for ensuring the correct amount of texture data
 //
 
-private final GLBufferSizeTracker  bufferSizeTracker;
-private final GLBufferStateTracker bufferStateTracker;
-private final GLStateTracker       glStateTracker;
-
 private final boolean checkBufferObject(boolean bound,
                                         int state,
                                         String kind, boolean throwException) {
@@ -269,16 +265,6 @@ private final boolean checkPackPBOBound(boolean throwException) {
     return false;
 }
 
-/** Entry point to C language function: <code> void *  {@native glMapBuffer}(GLenum target, GLenum access); </code> <br>Part of <code>GL_VERSION_1_5</code>; <code>GL_OES_mapbuffer</code>   */
-public final java.nio.ByteBuffer glMapBuffer(int target, int access) {
-  return glMapBufferImpl(target, false, 0, 0, access, ((GLES1ProcAddressTable)_context.getGLProcAddressTable())._addressof_glMapBuffer);
-}
-
-/** Entry point to C language function: <code> void *  {@native glMapBufferRange}(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); </code> <br>Part of <code>GL_ES_VERSION_3_0</code>, <code>GL_VERSION_3_0</code>; <code>GL_EXT_map_buffer_range</code>   */
-public final ByteBuffer glMapBufferRange(int target, long offset, long length, int access)  {
-  return glMapBufferImpl(target, true, offset, length, access, ((GLES1ProcAddressTable)_context.getGLProcAddressTable())._addressof_glMapBufferRange);
-}
-
 @Override
 public final void glVertexPointer(GLArrayData array) {
   if(array.getComponentCount()==0) return;
@@ -320,3 +306,44 @@ public final void glTexCoordPointer(GLArrayData array) {
   }
 }
 
+//
+// GLBufferObjectTracker Redirects
+//
+
+ at Override
+public final void glBufferData(int target, long size, Buffer data, int usage)  {
+    final long glProcAddress = ((GLES1ProcAddressTable)_context.getGLProcAddressTable())._addressof_glBufferData;
+    if ( 0 == glProcAddress ) {
+      throw new GLException(String.format("Method \"%s\" not available", "glBufferData"));
+    }
+    bufferObjectTracker.createBufferStorage(bufferStateTracker, this, 
+                                            target, size, data, usage, 0 /* immutableFlags */,
+                                            createBoundMutableStorageDispatch, glProcAddress);
+}
+
+ at Override
+public boolean glUnmapBuffer(int target)  {
+    final long glProcAddress = ((GLES1ProcAddressTable)_context.getGLProcAddressTable())._addressof_glUnmapBuffer;
+    if ( 0 == glProcAddress ) {
+      throw new GLException(String.format("Method \"%s\" not available", "glUnmapBuffer"));
+    }
+    return bufferObjectTracker.unmapBuffer(bufferStateTracker, this, target, unmapBoundBufferDispatch, glProcAddress);
+}
+
+ at Override
+public final GLBufferStorage mapBuffer(final int target, final int access) {
+  final long glProcAddress = ((GLES1ProcAddressTable)_context.getGLProcAddressTable())._addressof_glMapBuffer;
+  if ( 0 == glProcAddress ) {
+    throw new GLException("Method \"glMapBuffer\" not available");
+  }
+  return bufferObjectTracker.mapBuffer(bufferStateTracker, this, target, access, mapBoundBufferAllDispatch, glProcAddress);
+}
+ at Override
+public final GLBufferStorage mapBufferRange(final int target, final long offset, final long length, final int access) {
+  final long glProcAddress = ((GLES1ProcAddressTable)_context.getGLProcAddressTable())._addressof_glMapBufferRange;
+  if ( 0 == glProcAddress ) {
+    throw new GLException("Method \"glMapBufferRange\" not available");
+  }
+  return bufferObjectTracker.mapBuffer(bufferStateTracker, this, target, offset, length, access, mapBoundBufferRangeDispatch, glProcAddress);
+}
+
diff --git a/make/config/jogl/gl-impl-CustomJavaCode-gles3.java b/make/config/jogl/gl-impl-CustomJavaCode-gles3.java
index 1a1d7ab..a5c0d19 100644
--- a/make/config/jogl/gl-impl-CustomJavaCode-gles3.java
+++ b/make/config/jogl/gl-impl-CustomJavaCode-gles3.java
@@ -2,11 +2,11 @@
 public GLES3Impl(GLProfile glp, GLContextImpl context) {
   this._context = context; 
   if(null != context) {
-      this.bufferSizeTracker  = context.getBufferSizeTracker();
+      this.bufferObjectTracker  = context.getBufferObjectTracker();
       this.bufferStateTracker = context.getBufferStateTracker();
       this.glStateTracker     = context.getGLStateTracker();
   } else {
-      this.bufferSizeTracker  = null;
+      this.bufferObjectTracker  = null;
       this.bufferStateTracker = null;
       this.glStateTracker     = null;
   }
@@ -48,7 +48,7 @@ public final boolean isGLES1() {
 
 @Override
 public final boolean isGLES2() {
-    return !_isES3;
+    return true;
 }
 
 @Override
@@ -211,9 +211,6 @@ public final GL2GL3 getGL2GL3() throws GLException {
 //
 
 private final boolean _isES3;
-private final GLBufferSizeTracker  bufferSizeTracker;
-private final GLBufferStateTracker bufferStateTracker;
-private final GLStateTracker       glStateTracker;
 
 private final boolean checkBufferObject(boolean extensionAvail,
                                         boolean allowVAO,
@@ -333,22 +330,20 @@ private final boolean checkPackPBOBound(boolean throwException) {
 
 @Override
 public final boolean glIsPBOPackBound() {
+    return isPBOPackBound();
+}
+ at Override
+public final boolean isPBOPackBound() {
     return checkPackPBOBound(false);
 }
 
 @Override
 public final boolean glIsPBOUnpackBound() {
-    return checkUnpackPBOBound(false);
+    return isPBOUnpackBound();
 }
-
-/** Entry point to C language function: <code> void *  {@native glMapBuffer}(GLenum target, GLenum access); </code> <br>Part of <code>GL_VERSION_1_5</code>; <code>GL_OES_mapbuffer</code>   */
-public final java.nio.ByteBuffer glMapBuffer(int target, int access) {
-  return glMapBufferImpl(target, false, 0, 0, access, ((GLES3ProcAddressTable)_context.getGLProcAddressTable())._addressof_glMapBuffer);
-}
-
-/** Entry point to C language function: <code> void *  {@native glMapBufferRange}(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); </code> <br>Part of <code>GL_ES_VERSION_3_0</code>, <code>GL_VERSION_3_0</code>; <code>GL_EXT_map_buffer_range</code>   */
-public final ByteBuffer glMapBufferRange(int target, long offset, long length, int access)  {
-  return glMapBufferImpl(target, true, offset, length, access, ((GLES3ProcAddressTable)_context.getGLProcAddressTable())._addressof_glMapBufferRange);
+ at Override
+public final boolean isPBOUnpackBound() {
+    return checkUnpackPBOBound(false);
 }
 
 @Override
@@ -361,3 +356,45 @@ public final void glDepthRange(double zNear, double zFar) {
     glDepthRangef((float)zNear, (float)zFar); 
 }
 
+//
+// GLBufferObjectTracker Redirects
+//
+
+ at Override
+public final void glBufferData(int target, long size, Buffer data, int usage)  {
+    final long glProcAddress = ((GLES3ProcAddressTable)_context.getGLProcAddressTable())._addressof_glBufferData;
+    if ( 0 == glProcAddress ) {
+      throw new GLException(String.format("Method \"%s\" not available", "glBufferData"));
+    }
+    bufferObjectTracker.createBufferStorage(bufferStateTracker, this, 
+                                            target, size, data, usage, 0 /* immutableFlags */,
+                                            createBoundMutableStorageDispatch, glProcAddress);
+}
+
+ at Override
+public boolean glUnmapBuffer(int target)  {
+    final long glProcAddress = ((GLES3ProcAddressTable)_context.getGLProcAddressTable())._addressof_glUnmapBuffer;
+    if ( 0 == glProcAddress ) {
+      throw new GLException(String.format("Method \"%s\" not available", "glUnmapBuffer"));
+    }
+    return bufferObjectTracker.unmapBuffer(bufferStateTracker, this, target, unmapBoundBufferDispatch, glProcAddress);
+}
+
+ at Override
+public final GLBufferStorage mapBuffer(final int target, final int access) {
+  final long glProcAddress = ((GLES3ProcAddressTable)_context.getGLProcAddressTable())._addressof_glMapBuffer;
+  if ( 0 == glProcAddress ) {
+    throw new GLException("Method \"glMapBuffer\" not available");
+  }
+  return bufferObjectTracker.mapBuffer(bufferStateTracker, this, target, access, mapBoundBufferAllDispatch, glProcAddress);
+}
+ at Override
+public final GLBufferStorage mapBufferRange(final int target, final long offset, final long length, final int access) {
+  final long glProcAddress = ((GLES3ProcAddressTable)_context.getGLProcAddressTable())._addressof_glMapBufferRange;
+  if ( 0 == glProcAddress ) {
+    throw new GLException("Method \"glMapBufferRange\" not available");
+  }
+  return bufferObjectTracker.mapBuffer(bufferStateTracker, this, target, offset, length, access, mapBoundBufferRangeDispatch, glProcAddress);
+}
+
+
diff --git a/make/joglversion b/make/joglversion
index 079f9de..4e53b8d 100644
--- a/make/joglversion
+++ b/make/joglversion
@@ -14,4 +14,6 @@ Extension-Name: javax.media.opengl
 Implementation-Vendor-Id: com.jogamp
 Trusted-Library: true
 Permissions: all-permissions
+Application-Library-Allowable-Codebase: *
 @JAR_CODEBASE_TAG@
+
diff --git a/make/joglversion-all b/make/joglversion-all
index 079f9de..4e53b8d 100644
--- a/make/joglversion-all
+++ b/make/joglversion-all
@@ -14,4 +14,6 @@ Extension-Name: javax.media.opengl
 Implementation-Vendor-Id: com.jogamp
 Trusted-Library: true
 Permissions: all-permissions
+Application-Library-Allowable-Codebase: *
 @JAR_CODEBASE_TAG@
+
diff --git a/make/joglversion-test b/make/joglversion-test
index c449303..5c4bdb9 100644
--- a/make/joglversion-test
+++ b/make/joglversion-test
@@ -12,3 +12,7 @@ Implementation-Vendor: JogAmp Community
 Implementation-URL: http://jogamp.org/
 Extension-Name: com.jogamp.opengl.test
 Implementation-Vendor-Id: com.jogamp
+Permissions: sandbox
+Application-Library-Allowable-Codebase: *
+ at JAR_CODEBASE_TAG@
+
diff --git a/make/joglversion-test-android b/make/joglversion-test-android
index db757c3..18568fb 100644
--- a/make/joglversion-test-android
+++ b/make/joglversion-test-android
@@ -12,3 +12,4 @@ Implementation-Vendor: JogAmp Community
 Implementation-URL: http://jogamp.org/
 Extension-Name: com.jogamp.opengl.test
 Implementation-Vendor-Id: com.jogamp
+
diff --git a/make/nativewindowversion b/make/nativewindowversion
index 9a26432..f31c7f2 100644
--- a/make/nativewindowversion
+++ b/make/nativewindowversion
@@ -14,4 +14,6 @@ Extension-Name: javax.media.nativewindow
 Implementation-Vendor-Id: com.jogamp
 Trusted-Library: true
 Permissions: all-permissions
+Application-Library-Allowable-Codebase: *
 @JAR_CODEBASE_TAG@
+
diff --git a/make/newtversion b/make/newtversion
index 6f7047a..4d2004d 100644
--- a/make/newtversion
+++ b/make/newtversion
@@ -14,4 +14,6 @@ Extension-Name: com.jogamp.newt
 Implementation-Vendor-Id: com.jogamp
 Trusted-Library: true
 Permissions: all-permissions
+Application-Library-Allowable-Codebase: *
 @JAR_CODEBASE_TAG@
+
diff --git a/make/resources/android/AndroidManifest-jogl.xml b/make/resources/android/AndroidManifest-jogl.xml
index d9a9ac8..1b6c463 100644
--- a/make/resources/android/AndroidManifest-jogl.xml
+++ b/make/resources/android/AndroidManifest-jogl.xml
@@ -28,18 +28,6 @@
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
-        <activity android:name="jogamp.newt.driver.android.NewtDebugActivityLauncher"
-                  android:finishOnTaskLaunch="true"
-                  android:launchMode="singleTop"
-                  android:configChanges="keyboardHidden|orientation"
-                  android:label="@string/activity_debug_name"
-                  android:description="@string/activity_debug_descr"
-                  >
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
     </application>
 
 </manifest>
diff --git a/make/resources/android/res-jogl/values/strings.xml b/make/resources/android/res-jogl/values/strings.xml
index ae48166..e88a0a4 100644
--- a/make/resources/android/res-jogl/values/strings.xml
+++ b/make/resources/android/res-jogl/values/strings.xml
@@ -5,6 +5,4 @@
     <string name="app_descr">Contains Dalvik and native code, supporting native bindings.</string>
     <string name="activity_version_name">Jogl\'s Version</string>
     <string name="activity_version_descr">Shows the version of the JOGL Library and runtime GL infos.</string>
-    <string name="activity_debug_name">Jogl Debug</string>
-    <string name="activity_debug_descr">Debug output of JOGL\'s initialization.</string>
 </resources>
diff --git a/make/resources/assets-test/crosshair-grey-alpha-64x64.png b/make/resources/assets-test/crosshair-grey-alpha-64x64.png
new file mode 100644
index 0000000..9be2853
Binary files /dev/null and b/make/resources/assets-test/crosshair-grey-alpha-64x64.png differ
diff --git a/make/resources/assets-test/jogamp-pointer-64x64.png b/make/resources/assets-test/jogamp-pointer-64x64.png
new file mode 100644
index 0000000..a965dca
Binary files /dev/null and b/make/resources/assets-test/jogamp-pointer-64x64.png differ
diff --git a/make/resources/assets/jogl/util/data/av/test-ntsc01-57x32.png b/make/resources/assets/jogl/util/data/av/test-ntsc01-57x32.png
new file mode 100644
index 0000000..0a1488c
Binary files /dev/null and b/make/resources/assets/jogl/util/data/av/test-ntsc01-57x32.png differ
diff --git a/make/resources/assets/newt/data/cross-grey-alpha-16x16.png b/make/resources/assets/newt/data/cross-grey-alpha-16x16.png
new file mode 100644
index 0000000..303c454
Binary files /dev/null and b/make/resources/assets/newt/data/cross-grey-alpha-16x16.png differ
diff --git a/make/resources/assets/newt/data/jogamp-16x16.png b/make/resources/assets/newt/data/jogamp-16x16.png
new file mode 100644
index 0000000..02df899
Binary files /dev/null and b/make/resources/assets/newt/data/jogamp-16x16.png differ
diff --git a/make/resources/assets/newt/data/jogamp-32x32.png b/make/resources/assets/newt/data/jogamp-32x32.png
new file mode 100644
index 0000000..ab21c6e
Binary files /dev/null and b/make/resources/assets/newt/data/jogamp-32x32.png differ
diff --git a/make/resources/assets/newt/data/pointer-grey-alpha-16x24.png b/make/resources/assets/newt/data/pointer-grey-alpha-16x24.png
new file mode 100644
index 0000000..98b2c86
Binary files /dev/null and b/make/resources/assets/newt/data/pointer-grey-alpha-16x24.png differ
diff --git a/make/resources/misc/jogamp-48x48.png b/make/resources/misc/jogamp-48x48.png
new file mode 100644
index 0000000..216f8c0
Binary files /dev/null and b/make/resources/misc/jogamp-48x48.png differ
diff --git a/make/resources/misc/jogamp-64x64.png b/make/resources/misc/jogamp-64x64.png
new file mode 100644
index 0000000..9936616
Binary files /dev/null and b/make/resources/misc/jogamp-64x64.png differ
diff --git a/make/resources/assets/jogl/util/data/av/test-ntsc01-160x90.png b/make/resources/misc/test-ntsc01-160x90.png
similarity index 100%
rename from make/resources/assets/jogl/util/data/av/test-ntsc01-160x90.png
rename to make/resources/misc/test-ntsc01-160x90.png
diff --git a/make/scripts/create-i386-libs-symlinks.sh b/make/scripts/create-i386-libs-symlinks.sh
new file mode 100644
index 0000000..0eb5a14
--- /dev/null
+++ b/make/scripts/create-i386-libs-symlinks.sh
@@ -0,0 +1,10 @@
+ls -la libX11.so* libXxf86vm.so* libXrender.so* libXrandr.so* libXinerama.so* libXcursor.so*
+
+ln -s libX11.so.6 libX11.so
+ln -s libXxf86vm.so.1 libXxf86vm.so
+ln -s libXrender.so.1 libXrender.so
+ln -s libXrandr.so.2 libXrandr.so
+ln -s libXinerama.so.1 libXinerama.so
+ln -s libXcursor.so.1 libXcursor.so
+
+ls -la libX11.so* libXxf86vm.so* libXrender.so* libXrandr.so* libXinerama.so* libXcursor.so*
diff --git a/make/scripts/make.jogl.all.android-armv6-cross.sh b/make/scripts/make.jogl.all.android-armv6-cross.sh
index 2b8f9a3..1b5f5bf 100755
--- a/make/scripts/make.jogl.all.android-armv6-cross.sh
+++ b/make/scripts/make.jogl.all.android-armv6-cross.sh
@@ -1,5 +1,7 @@
 #! /bin/sh
 
+SDIR=`dirname $0` 
+
 if [ -e $SDIR/../../../gluegen/make/scripts/setenv-build-jogl-x86_64.sh ] ; then
     . $SDIR/../../../gluegen/make/scripts/setenv-build-jogl-x86_64.sh
 fi
diff --git a/make/scripts/setenv-jogl.sh b/make/scripts/setenv-jogl.sh
index 186da55..dc121a5 100755
--- a/make/scripts/setenv-jogl.sh
+++ b/make/scripts/setenv-jogl.sh
@@ -73,7 +73,7 @@ if [ ! -e "$JOAL_BUILDDIR" ] ; then
     print_usage
     exit
 fi
-JOAL_JAR="$JOAL_BUILDDIR"/joal.jar
+JOAL_JAR="$JOAL_BUILDDIR"/jar/joal.jar
 
 if [ -z "$ANT_PATH" ] ; then
     ANT_PATH=$(dirname $(dirname $(which ant)))
diff --git a/make/scripts/test-win32-smb_share.bat b/make/scripts/test-win32-smb_share.bat
new file mode 100755
index 0000000..d016676
--- /dev/null
+++ b/make/scripts/test-win32-smb_share.bat
@@ -0,0 +1,33 @@
+
+set SMB_ROOT=\\risa.goethel.localnet\deployment\test\jogamp
+
+set BLD_SUB=build-win32
+set J2RE_HOME=c:\jre1.7.0_45_x32
+set JAVA_HOME=c:\jdk1.7.0_45_x32
+set ANT_PATH=C:\apache-ant-1.8.2
+
+set PROJECT_ROOT=%SMB_ROOT%\jogl
+set BLD_DIR=%PROJECT_ROOT%\%BLD_SUB%
+
+REM set FFMPEG_LIB=C:\ffmpeg_libav\lavc53_lavf53_lavu51-ffmpeg\x32
+set FFMPEG_LIB=C:\ffmpeg_libav\lavc55_lavf55_lavu52-ffmpeg\x32
+REM set FFMPEG_LIB=C:\ffmpeg_libav\lavc54_lavf54_lavu52_lavr01-libav\x32
+
+REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PATH%
+REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PROJECT_ROOT%\make\lib\external\angle\win32\20120127;%PATH%
+REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PROJECT_ROOT%\make\lib\external\angle\win32\20121010-chrome;%PATH%
+REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PROJECT_ROOT%\make\lib\external\PVRVFrame\OGLES-2.0\Windows_x86_32;%PATH%
+set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%FFMPEG_LIB%;%PATH%
+
+set D_ARGS="-Djogamp.debug=all"
+
+REM set LIB_DIR=..\..\gluegen\%BLD_SUB%\obj;%BLD_DIR%\lib
+set LIB_DIR=
+
+set CP_ALL=.;%BLD_DIR%\jar\jogl-all.jar;%BLD_DIR%\jar\jogl-test.jar;%SMB_ROOT%\gluegen\%BLD_SUB%\gluegen-rt.jar;%SMB_ROOT%\gluegen\make\lib\junit.jar;%ANT_PATH%\lib\ant.jar;%ANT_PATH%\lib\ant-junit.jar;%BLD_DIR%\..\make\lib\swt\win32-win32-x86\swt-debug.jar
+
+echo CP_ALL %CP_ALL%
+
+%J2RE_HOME%\bin\java -classpath %CP_ALL% %D_ARGS% %X_ARGS% com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT -time 3000 > java-win.log 2>&1
+tail java-win.log
+
diff --git a/make/scripts/tests-osx-x64-custom.sh b/make/scripts/tests-osx-x64-custom.sh
index 88587f0..16a5628 100755
--- a/make/scripts/tests-osx-x64-custom.sh
+++ b/make/scripts/tests-osx-x64-custom.sh
@@ -1,6 +1,6 @@
 #! /bin/bash
 
-export DYLD_LIBRARY_PATH=/usr/local/lib:$DYLD_LIBRARY_PATH
+export DYLD_LIBRARY_PATH=/usr/local/libav:$DYLD_LIBRARY_PATH
 
 spath=`dirname $0`
 
diff --git a/make/scripts/tests-osx-x64-java6.sh b/make/scripts/tests-osx-x64-java6.sh
index fe2d2c4..b8190f0 100755
--- a/make/scripts/tests-osx-x64-java6.sh
+++ b/make/scripts/tests-osx-x64-java6.sh
@@ -1,6 +1,6 @@
 #! /bin/bash
 
-export DYLD_LIBRARY_PATH=/usr/local/lib:$DYLD_LIBRARY_PATH
+export DYLD_LIBRARY_PATH=/usr/local/libav:$DYLD_LIBRARY_PATH
 
 JAVA_HOME=`/usr/libexec/java_home -version 1.6`
 PATH=$JAVA_HOME/bin:$PATH
diff --git a/make/scripts/tests-osx-x64.sh b/make/scripts/tests-osx-x64.sh
index 1204b8a..5d9cd6f 100755
--- a/make/scripts/tests-osx-x64.sh
+++ b/make/scripts/tests-osx-x64.sh
@@ -1,6 +1,6 @@
 #! /bin/bash
 
-export DYLD_LIBRARY_PATH=/usr/local/lib:$DYLD_LIBRARY_PATH
+export DYLD_LIBRARY_PATH=/usr/local/libav:$DYLD_LIBRARY_PATH
 
 JAVA_HOME=`/usr/libexec/java_home -version 1.7`
 #JAVA_HOME=`/usr/libexec/java_home -version 1.7.0_25`
diff --git a/make/scripts/tests-win.bat b/make/scripts/tests-win.bat
index f5417bf..5642cca 100755
--- a/make/scripts/tests-win.bat
+++ b/make/scripts/tests-win.bat
@@ -39,16 +39,18 @@ REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.tile.TestTiledPrintin
 
 REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLCapabilities01NEWT %*
 REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteNEWT %*
-scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteAWT %*
+REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteAWT %*
 REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.offscreen.TestOffscreen01GLPBufferNEWT -time 5000
 
 REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextListNEWT %*
 REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextListNEWT2 %*
+
+REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestMapBufferRead01NEWT %*
 REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES1NEWT %*
 REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2NEWT0 %*
 REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2NEWT1 %*
 REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2NEWT2 %*
-REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2NEWT3 %*
+scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2NEWT3 %*
 REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2AWT3 %*
 REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2AWT3b %*
 REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextWithJTabbedPaneAWT %*
diff --git a/make/scripts/tests-x64-dbg.bat b/make/scripts/tests-x64-dbg.bat
index 6e8407f..ce2df92 100755
--- a/make/scripts/tests-x64-dbg.bat
+++ b/make/scripts/tests-x64-dbg.bat
@@ -55,9 +55,10 @@ REM set D_ARGS="-Djogl.debug.GLCanvas" "-Djogl.debug.Animator" "-Djogl.debug.GLC
 REM set D_ARGS="-Djogl.debug.GLCanvas" "-Djogl.debug.GLJPanel" "-Djogl.debug.TileRenderer" "-Djogl.debug.TileRenderer.PNG"
 REM set D_ARGS="-Djogl.debug.GLCanvas" "-Djogl.debug.GLJPanel" "-Djogl.debug.TileRenderer"
 REM set D_ARGS="-Djogl.gljpanel.noverticalflip"
+set D_ARGS="-Dnewt.debug=all"
 REM set D_ARGS="-Dnewt.debug.Window"
 REM set D_ARGS="-Dnewt.debug.Window.KeyEvent"
-set D_ARGS="-Dnewt.debug.Window" "-Dnewt.debug.Window.KeyEvent" "-Dnewt.debug.EDT"
+REM set D_ARGS="-Dnewt.debug.Window" "-Dnewt.debug.Window.KeyEvent" "-Dnewt.debug.EDT"
 REM set D_ARGS="-Dnewt.debug.Window.MouseEvent"
 REM set D_ARGS="-Dnewt.debug.Window.MouseEvent" "-Dnewt.debug.Window.KeyEvent"
 REM set D_ARGS="-Dnewt.debug.Window" "-Dnewt.debug.Display"
diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh
index cb60028..85eb142 100644
--- a/make/scripts/tests.sh
+++ b/make/scripts/tests.sh
@@ -93,6 +93,7 @@ function jrun() {
     #D_ARGS="-Djogl.debug=all -Dnativewindow.debug=all"
     #D_ARGS="-Djogamp.debug=all -Dnativewindow.debug=all -Djogl.debug=all -Dnewt.debug=all"
     #D_ARGS="-Dnativewindow.debug=all -Djogl.debug=all -Dnewt.debug=all"
+    #D_ARGS="-Dnativewindow.debug=all -Dnewt.debug.Window"
     #D_ARGS="-Djogl.debug=all -Dnativewindow.debug=all -Dnewt.debug=all -Djogamp.debug.Lock"
 
     #D_ARGS="-Dnativewindow.debug.X11Util.ATI_HAS_NO_XCLOSEDISPLAY_BUG"
@@ -102,11 +103,16 @@ function jrun() {
     #D_ARGS="-Djogl.debug.DebugGL -Djogl.debug.FBObject"
     #D_ARGS="-Djogl.debug.FBObject -Djogl.debug.TraceGL -Djogl.debug.GLBufferStateTracker"
     #D_ARGS="-Djogl.debug.FBObject"
+    #D_ARGS="-Djogl.debug.GLBufferStateTracker -Djogl.debug.GLBufferObjectTracker -Djogamp.debug.Lock -Djogamp.common.utils.locks.Lock.timeout=600000 -Dnewt.debug.EDT"
+    #D_ARGS="-Djogl.debug.GLBufferStateTracker -Djogl.debug.GLBufferObjectTracker"
+    #D_ARGS="-Djogl.debug.GLBufferObjectTracker"
+    #D_ARGS="-Djogl.debug.GLBufferObjectTracker -Djogl.debug.GLArrayData -Djogl.debug.TraceGL -Djogl.debug.DebugGL"
     #D_ARGS="-Djogl.debug.GLSLCode"
     #D_ARGS="-Djogl.debug.GLSLCode -Djogl.debug.DebugGL"
-    #D_ARGS="-Dnativewindow.debug.X11Util -Dnativewindow.debug.X11Util.TraceDisplayLifecycle -Djogl.debug.EGLDisplayUtil -Djogl.debug.GLDrawable"
     #D_ARGS="-Djogl.debug.GLContext -Dnativewindow.debug.JAWT -Dnewt.debug.Window"
+    #D_ARGS="-Dnativewindow.debug.JAWT -Djogl.debug.GLCanvas"
     #D_ARGS="-Dnativewindow.debug.JAWT -Djogamp.debug.TaskBase.TraceSource"
+    #D_ARGS="-Dnativewindow.debug.JAWT"
     #D_ARGS="-Djogl.debug.GLContext.TraceSwitch"
     #D_ARGS="-Djogl.debug.GLContext -Djogl.debug.GLContext.TraceSwitch"
     #D_ARGS="-Djogl.debug.FixedFuncPipeline -Djogl.debug.GLSLCode"
@@ -119,18 +125,15 @@ function jrun() {
     #D_ARGS="-Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.GLDrawable -Djogl.debug.GLContext -Djogl.debug.FBObject"
     #D_ARGS="-Djogl.debug.GLContext -Djogl.debug.GLDrawable -Dnativewindow.debug.GraphicsConfiguration"
     #D_ARGS="-Dnativewindow.debug.GraphicsConfiguration"
-    #D_ARGS="-Djogl.debug.GLContext"
+    #D_ARGS="-Djogl.debug.GLContext -Djogl.debug.GLDrawable"
     #D_ARGS="-Djogl.debug.GLContext.NoProfileAliasing"
     #D_ARGS="-Djogl.debug.GLDrawable -Dnativewindow.debug.X11Util -Dnativewindow.debug.NativeWindow -Dnewt.debug.Display -Dnewt.debug.Screen -Dnewt.debug.Window"
     #D_ARGS="-Djogl.debug.Animator -Djogl.debug.GLDrawable -Dnativewindow.debug.NativeWindow"
     #D_ARGS="-Djogl.debug=all -Dnewt.debug=all"
-    #D_ARGS="-Djogl.debug.EGLDisplayUtil -Djogl.debug.GLDrawable"
     #D_ARGS="-Djogl.debug.GLDrawable -Djogl.debug.GLContext -Djogl.debug.GLCanvas"
     #D_ARGS="-Djogl.debug.GLDrawable"
     #D_ARGS="-Djogl.debug.GLEventListenerState"
     #D_ARGS="-Djogl.fbo.force.none"
-    #D_ARGS="-Djogl.debug.EGLDrawableFactory.DontQuery -Djogl.debug.GLDrawable"
-    #D_ARGS="-Djogl.debug.EGLDrawableFactory.QueryNativeTK -Djogl.debug.GLDrawable"
     #D_ARGS="-Djogl.debug.GLDebugMessageHandler"
     #D_ARGS="-Djogl.debug.GLDebugMessageHandler -Djogl.debug.DebugGL"
     #D_ARGS="-Djogl.debug.GLDebugMessageHandler -Djogl.debug.TraceGL -Djogl.debug.DebugGL -Djogl.debug.GLSLCode -Djogl.debug.GLSLState"
@@ -139,30 +142,29 @@ function jrun() {
     #D_ARGS="-Djogl.1thread=false -Djogl.debug.Threading"
     #D_ARGS="-Djogl.1thread=true -Djogl.debug.Threading"
     #D_ARGS="-Djogl.debug.DebugGL -Djogl.debug.TraceGL -Djogl.debug.GLContext.TraceSwitch -Djogl.debug=all"
-    #D_ARGS="-Djogamp.debug.IOUtil -Djogl.debug.GLSLCode -Djogl.debug.GLMediaPlayer"
-    #D_ARGS="-Djogl.debug.GLMediaPlayer -Djogl.debug.AudioSink"
-    #D_ARGS="-Djogl.debug.GLMediaPlayer -Djogl.debug.GLMediaPlayer.Native"
-    #D_ARGS="-Djogl.debug.GLMediaPlayer"
-    #D_ARGS="-Djogl.debug.GLMediaPlayer.StreamWorker.delay=25 -Djogl.debug.GLMediaPlayer"
-    #D_ARGS="-Djogl.debug.GLMediaPlayer.Native"
     #D_ARGS="-Djogl.debug.AudioSink"
     #D_ARGS="-Djogl.debug.GLArrayData"
-    #D_ARGS="-Djogl.debug.EGLDisplayUtil -Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.GLDrawable"
-    #D_ARGS="-Djogl.debug.EGLDisplayUtil -Dnativewindow.debug.X11Util"
     #D_ARGS="-Dnewt.debug.Screen -Dnewt.debug.Window"
     #D_ARGS="-Dnewt.debug.Screen"
     #D_ARGS="-Dnewt.test.Screen.disableRandR13"
     #D_ARGS="-Dnewt.test.Screen.disableScreenMode -Dnewt.debug.Screen"
     #D_ARGS="-Dnewt.debug.Screen -Djogl.debug.Animator"
     #D_ARGS="-Djogamp.debug.ProcAddressHelper -Djogamp.debug.NativeLibrary -Djogamp.debug.NativeLibrary.Lookup -Djogamp.debug.JNILibLoader -Djogamp.debug.TempJarCache -Djogamp.debug.JarUtil"
+    #D_ARGS="-Djogl.debug.GLContext -Djogl.debug.GLProfile"
+    #D_ARGS="-Djogl.debug.GLProfile"
     #D_ARGS="-Djogl.debug.GLContext -Djogamp.debug.NativeLibrary -Djogamp.debug.JNILibLoader -Djogl.debug.DebugGL -Djogl.debug.GLDebugMessageHandler"
     #D_ARGS="-Dnewt.debug.MainThread"
     #D_ARGS="-Dnativewindow.debug.GraphicsConfiguration -Dnativewindow.debug.NativeWindow"
     #D_ARGS="-Djogl.debug.GLCanvas -Djogl.debug.Animator -Djogl.debug.GLDrawable -Djogl.debug.GLContext -Djogl.debug.GLContext.TraceSwitch"
     #D_ARGS="-Djogl.debug.GLContext -Djogl.debug.ExtensionAvailabilityCache"
-    #D_ARGS="-Djogl.debug.GLContext -Djogl.debug.GLProfile -Djogl.debug.GLDrawable -Djogl.debug.EGLDisplayUtil"
-    #D_ARGS="-Djogl.debug.GLContext -Djogl.debug.GLProfile"
-    #D_ARGS="-Djogl.debug.GLProfile"
+    #D_ARGS="-Djogl.debug.EGLDrawableFactory.QueryNativeTK -Djogl.debug.GLDrawable"
+    #D_ARGS="-Djogamp.debug.ProcAddressHelper -Djogamp.debug.NativeLibrary -Djogamp.debug.NativeLibrary.Lookup -Djogamp.debug.JNILibLoader -Djogamp.debug.TempJarCache -Djogamp.debug.JarUtil"
+    #D_ARGS="-Djogl.debug.GLContext -Djogl.debug.GLProfile -Djogl.debug.GLDrawable -Djogl.debug.EGLDisplayUtil -Dnativewindow.debug.GraphicsDevice"
+    #D_ARGS="-Djogl.debug.GLContext -Djogl.debug.GLProfile -Djogl.debug.GLDrawable -Djogl.debug.EGLDisplayUtil -Djogl.debug.EGLDrawableFactory.QueryNativeTK"
+    #D_ARGS="-Djogl.debug.EGLDisplayUtil -Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.GLDrawable"
+    #D_ARGS="-Djogl.debug.EGLDisplayUtil -Dnativewindow.debug.X11Util"
+    #D_ARGS="-Dnativewindow.debug.X11Util -Dnativewindow.debug.X11Util.TraceDisplayLifecycle -Djogl.debug.EGLDisplayUtil -Djogl.debug.GLDrawable"
+    #D_ARGS="-Djogl.debug.EGLDisplayUtil -Djogl.debug.GLDrawable"
     #D_ARGS="-Dnativewindow.debug.NativeWindow -Dnewt.debug.Window -Dnewt.debug.Screen -Dnewt.debug.Display"
     #D_ARGS="-Djogl.debug.GLCanvas -Dnewt.debug.Window -Dnewt.debug.Display -Dnewt.debug.EDT -Djogl.debug.Animator"
     #D_ARGS="-Dnewt.debug.Display -Dnewt.debug.EDT -Dnewt.debug.Window"
@@ -205,6 +207,7 @@ function jrun() {
     #D_ARGS="-Xprof"
     #D_ARGS="-Djogl.debug.GLCanvas -Djogl.debug.Java2D -Djogl.debug.GLJPanel"
     #D_ARGS="-Djogl.debug.GLCanvas -Djogl.debug.Java2D -Djogl.debug.GLJPanel -Djogl.gljpanel.noglsl"
+    #D_ARGS="-Djogl.debug.GLCanvas -Djogl.debug.Java2D -Djogl.debug.GLJPanel -Djogl.gljpanel.noglsl -Djogl.gljpanel.awtverticalflip"
     #D_ARGS="-Djogl.debug.GLJPanel -Djogl.debug.DebugGL"
     #D_ARGS="-Djogl.gljpanel.noverticalflip"
     #D_ARGS="-Djogl.debug.GLCanvas -Djogl.debug.Animator"
@@ -228,7 +231,7 @@ function jrun() {
     #D_ARGS="-Djogl.debug.GLContext -Dnewt.debug=all"
     #D_ARGS="-Djogl.debug.GLCanvas -Djogl.debug.GLJPanel -Djogl.debug.TileRenderer -Djogl.debug.TileRenderer.PNG"
     #D_ARGS="-Djogl.debug.GLCanvas -Djogl.debug.GLJPanel -Djogl.debug.TileRenderer"
-    #D_ARGS="-Djogl.debug.PNGImage"
+    #D_ARGS="-Djogl.debug.PNG -Dnewt.debug.Display.PointerIcon"
     #D_ARGS="-Djogl.debug.JPEGImage"
     #D_ARGS="-Djogl.debug.GLDrawable -Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.CapabilitiesChooser"
     #X_ARGS="-Dsun.java2d.noddraw=True -Dsun.java2d.opengl=True -Dsun.java2d.xrender=false"
@@ -236,6 +239,12 @@ function jrun() {
     #X_ARGS="-verbose:jni"
     #X_ARGS="-Xrs"
     #X_ARGS="-Dsun.awt.disableMixing=true"
+    #D_ARGS="-Djogamp.debug.IOUtil -Djogl.debug.GLSLCode -Djogl.debug.GLMediaPlayer"
+    #D_ARGS="-Djogl.debug.GLMediaPlayer -Djogl.debug.AudioSink"
+    #D_ARGS="-Djogl.debug.GLMediaPlayer -Djogl.debug.GLMediaPlayer.Native"
+    D_ARGS="-Djogl.debug.GLMediaPlayer"
+    #D_ARGS="-Djogl.debug.GLMediaPlayer.StreamWorker.delay=25 -Djogl.debug.GLMediaPlayer"
+    #D_ARGS="-Djogl.debug.GLMediaPlayer.Native"
 
     if [ $awton -eq 1 ] ; then
         export CLASSPATH=$JOGAMP_ALL_AWT_CLASSPATH
@@ -310,6 +319,8 @@ function testawtswt() {
 #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLVersionParsing00NEWT $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestMainVersionGLWindowNEWT $*
 #testawt com.jogamp.opengl.test.junit.jogl.acore.TestMainVersionGLCanvasAWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLProfile00NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLProfile01NEWT $*
 
 #
 # demos (any TK, more user driven tests)
@@ -323,7 +334,6 @@ function testawtswt() {
 #testawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NewtCanvasAWT $*
 #testawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestLandscapeES2NewtCanvasAWT $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLProfile00NEWT $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestLandscapeES2NEWT $*
 #testawtswt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NewtCanvasSWT $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestElektronenMultipliziererNEWT $*
@@ -379,8 +389,6 @@ testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieSimple $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.math.TestFloatUtil01MatrixMatrixMultNOUI $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.math.TestBinary16NOUI $*
 
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLProfile00NEWT $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLProfile01NEWT $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteNEWT $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestInitConcurrent01NEWT $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestInitConcurrent02NEWT $*
@@ -388,7 +396,13 @@ testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieSimple $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLDebug00NEWT $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLDebug01NEWT $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGPUMemSec01NEWT $*
+
 #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestMapBufferRead01NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestRedSquareES2NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2NEWT0 $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2NEWT3 $*
+
 #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestBug669RecursiveGLContext01NEWT $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestBug669RecursiveGLContext02NEWT $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestBug692GL3VAONEWT $*
@@ -466,7 +480,6 @@ testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieSimple $*
 
 #testnoawt com.jogamp.opengl.test.junit.jogl.acore.anim.TestAnimatorGLWindow01NEWT $*
 #testawt com.jogamp.opengl.test.junit.jogl.acore.anim.TestAnimatorGLJPanel01AWT $*
-#testawt com.jogamp.opengl.test.junit.jogl.acore.anim.TestAWTCardLayoutAnimatorStartStopBug532 $*
 #testawt com.jogamp.opengl.test.junit.jogl.acore.anim.Bug898AnimatorFromEDTAWT $*
 
 #
@@ -500,15 +513,52 @@ testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieSimple $*
 #
 # AWT
 #
-#testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug816OSXCALayerPos01AWT $*
-#testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug816OSXCALayerPos02AWT $*
+
+#
+# OSX CALayer Position and Visibility (OSX CALayer, ..)
+# <BEGIN>
+#
+
+#
+# Simple GLCanvas setVisible on/off
+#   OK (X11, OSX)
+#testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug664GLCanvasSetVisibleSwingAWT $*
+
+#
+# GLCanvas moving between CardLayout's JPanels
+#   OK (X11, OSX)
+#testawt com.jogamp.opengl.test.junit.jogl.acore.anim.TestAWTCardLayoutAnimatorStartStopBug532 $*
+
+#
+# GLCanvas moving between JTabbedPanel's tabs
+#   OK (X11, OSX)
+#testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug816JTabbedPanelVisibilityB849B878AWT $*
+
+#
+# GLCanvas/AWT Checkbox Visibility
+#   OK (X11, OSX)
 #testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug816OSXCALayerPos03aB729AWT $*
+
+#
+# GLCanvas/AWT Checkbox Visibility (on parent's Panel)
+#   OK (X11, OSX)
 #testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug816OSXCALayerPos03bB849AWT $*
+#
+# GLCanvas/Swing Checkbox Visibility (on parent's JPanel)
+#   OK (X11, OSX)
 #testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug816OSXCALayerPos03cB849AWT $*
-#testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug816JTabbedPanelVisibilityB849B878AWT $*
+
+#testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug816OSXCALayerPos01AWT $*
+#testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug816OSXCALayerPos02AWT $*
 #testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug816GLCanvasFrameHoppingB849B889AWT $*
 #testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug816OSXCALayerPos04aAWT $*
 #testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug816OSXCALayerPos04bAWT $*
+
+#
+# OSX CALayer Position and Visibility (OSX CALayer, ..)
+# <END>
+#
+
 #testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug675BeansInDesignTimeAWT $*
 #testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug551AWT $*
 #testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug572AWT $*
@@ -519,7 +569,6 @@ testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieSimple $*
 #testawt com.jogamp.opengl.test.junit.jogl.awt.TestAWT02WindowClosing
 #testawt com.jogamp.opengl.test.junit.jogl.awt.TestJScrollPaneMixHwLw01AWT $*
 #testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug642JSplitPaneMixHwLw01AWT $*
-#testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug664GLCanvasSetVisibleSwingAWT $*
 #testawt com.jogamp.opengl.test.junit.jogl.awt.TestIsRealizedConcurrency01AWT $*
 #testawt com.jogamp.opengl.test.junit.jogl.awt.text.TestAWTTextRendererUseVertexArrayBug464
 #testawt com.jogamp.opengl.test.junit.jogl.glu.TestBug463ScaleImageMemoryAWT $*
@@ -634,8 +683,10 @@ testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieSimple $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.util.texture.TestJPEGJoglAWTCompareNewtAWT $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.util.texture.TestJPEGJoglAWTBenchmarkNewtAWT $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.util.texture.TestJPEGTextureFromFileNEWT $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.util.texture.TestPNGImage00NEWT $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.util.texture.TestPNGImage01NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.util.texture.TestPNGPixelRect00NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.util.texture.TestPNGPixelRect01NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.util.texture.TestPixelFormatUtil00NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.util.texture.TestPixelFormatUtil01NEWT $*
 #testawt com.jogamp.opengl.test.junit.jogl.util.texture.TestPNGTextureFromFileAWT $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.util.texture.TestPNGTextureFromFileNEWT $*
 #testawt com.jogamp.opengl.test.junit.jogl.util.texture.TestGLReadBufferUtilTextureIOWrite01AWT $*
diff --git a/src/jogl/classes/com/jogamp/gluegen/opengl/BuildComposablePipeline.java b/src/jogl/classes/com/jogamp/gluegen/opengl/BuildComposablePipeline.java
index df60d2f..023913d 100644
--- a/src/jogl/classes/com/jogamp/gluegen/opengl/BuildComposablePipeline.java
+++ b/src/jogl/classes/com/jogamp/gluegen/opengl/BuildComposablePipeline.java
@@ -41,6 +41,7 @@ package com.jogamp.gluegen.opengl;
 
 import com.jogamp.gluegen.CodeGenUtils;
 import com.jogamp.gluegen.JavaType;
+
 import java.io.BufferedWriter;
 import java.io.File;
 import java.io.FileWriter;
@@ -50,6 +51,7 @@ import java.lang.reflect.Method;
 import java.nio.Buffer;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
@@ -82,6 +84,16 @@ public class BuildComposablePipeline {
      */
     public static final int GEN_GL_IDENTITY_BY_ASSIGNABLE_CLASS = 1 << 4;
 
+    private static final HashMap<String, String> addedGLHooks = new HashMap<String, String>();
+    private static final String[] addedGLHookMethodNames = new String[] {
+            "mapBuffer", "mapBufferRange",
+            "mapNamedBuffer", "mapNamedBufferRange" };
+    static {
+        for(int i=0; i<addedGLHookMethodNames.length; i++) {
+            addedGLHooks.put(addedGLHookMethodNames[i], addedGLHookMethodNames[i]);
+        }
+    }
+
     int mode;
     private final String outputDir;
     private final String outputPackage;
@@ -200,8 +212,11 @@ public class BuildComposablePipeline {
             // Don't hook methods which aren't real GL methods,
             // such as the synthetic "isGL2ES2" "getGL2ES2"
             final String name = method.getName();
-            boolean runHooks = name.startsWith("gl");
-            if ( !name.startsWith("getGL") && !name.startsWith("isGL") && !name.equals("getDownstreamGL") && !name.equals("toString") ) {
+            if ( !name.startsWith("getGL") &&
+                 !name.startsWith("isGL") &&
+                 !name.equals("getDownstreamGL") &&
+                 !name.equals("toString") ) {
+                final boolean runHooks = name.startsWith("gl") || addedGLHooks.containsKey(name);
                 publicMethodsPlain.add(new PlainMethod(method, runHooks));
             }
         }
diff --git a/src/jogl/classes/com/jogamp/opengl/FBObject.java b/src/jogl/classes/com/jogamp/opengl/FBObject.java
index 72041a3..90a8dc0 100644
--- a/src/jogl/classes/com/jogamp/opengl/FBObject.java
+++ b/src/jogl/classes/com/jogamp/opengl/FBObject.java
@@ -32,6 +32,7 @@ import java.util.Arrays;
 
 import javax.media.opengl.GL;
 import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GL2ES3;
 import javax.media.opengl.GL2GL3;
 import javax.media.opengl.GL3;
 import javax.media.opengl.GLBase;
@@ -386,7 +387,7 @@ public class FBObject {
 
                 gl.glBindRenderbuffer(GL.GL_RENDERBUFFER, getName());
                 if( samples > 0 ) {
-                    ((GL2GL3)gl).glRenderbufferStorageMultisample(GL.GL_RENDERBUFFER, samples, format, getWidth(), getHeight());
+                    ((GL2ES3)gl).glRenderbufferStorageMultisample(GL.GL_RENDERBUFFER, samples, format, getWidth(), getHeight());
                 } else {
                     gl.glRenderbufferStorage(GL.GL_RENDERBUFFER, format, getWidth(), getHeight());
                 }
@@ -793,7 +794,7 @@ public class FBObject {
         }
         fullFBOSupport = gl.hasFullFBOSupport();
 
-        rgba8Avail = gl.isGL2GL3() || gl.isExtensionAvailable(GLExtensions.OES_rgb8_rgba8);
+        rgba8Avail = gl.isGL2ES3() || gl.isExtensionAvailable(GLExtensions.OES_rgb8_rgba8);
         depth24Avail = fullFBOSupport || gl.isExtensionAvailable(GLExtensions.OES_depth24);
         depth32Avail = fullFBOSupport || gl.isExtensionAvailable(GLExtensions.OES_depth32);
         stencil01Avail = fullFBOSupport || gl.isExtensionAvailable(GLExtensions.OES_stencil1);
@@ -1044,14 +1045,14 @@ public class FBObject {
                 return("FBO missing draw buffer");
             case GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
                 return("FBO missing read buffer");
-            case GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
+            case GL2ES3.GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
                 return("FBO missing multisample buffer");
             case GL3.GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:
                 return("FBO missing layer targets");
 
             case GL.GL_FRAMEBUFFER_UNSUPPORTED:
                 return("Unsupported FBO format");
-            case GL2GL3.GL_FRAMEBUFFER_UNDEFINED:
+            case GL2ES3.GL_FRAMEBUFFER_UNDEFINED:
                  return("FBO undefined");
 
             case 0:
@@ -1084,7 +1085,7 @@ public class FBObject {
                 }
 
             case GL.GL_FRAMEBUFFER_UNSUPPORTED:
-            case GL2GL3.GL_FRAMEBUFFER_UNDEFINED:
+            case GL2ES3.GL_FRAMEBUFFER_UNDEFINED:
 
             case 0:
             default:
@@ -2068,7 +2069,7 @@ public class FBObject {
      *
      * <p>
      * In case you have attached more than one color buffer,
-     * you may want to setup {@link GL2GL3#glDrawBuffers(int, int[], int)}.
+     * you may want to setup {@link GL2ES3#glDrawBuffers(int, int[], int)}.
      * </p>
      * @param gl the current GL context
      * @throws GLException
@@ -2078,8 +2079,8 @@ public class FBObject {
             checkInitialized();
             if(samples > 0 && fullFBOSupport) {
                 // draw to multisampling - read from samplesSink
-                gl.glBindFramebuffer(GL2GL3.GL_DRAW_FRAMEBUFFER, getWriteFramebuffer());
-                gl.glBindFramebuffer(GL2GL3.GL_READ_FRAMEBUFFER, getReadFramebuffer());
+                gl.glBindFramebuffer(GL2ES3.GL_DRAW_FRAMEBUFFER, getWriteFramebuffer());
+                gl.glBindFramebuffer(GL2ES3.GL_READ_FRAMEBUFFER, getReadFramebuffer());
             } else {
                 // one for all
                 gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, getWriteFramebuffer());
@@ -2104,8 +2105,8 @@ public class FBObject {
             if(fullFBOSupport) {
                 // default read/draw buffers, may utilize GLContext/GLDrawable override of
                 // GLContext.getDefaultDrawFramebuffer() and GLContext.getDefaultReadFramebuffer()
-                gl.glBindFramebuffer(GL2GL3.GL_DRAW_FRAMEBUFFER, 0);
-                gl.glBindFramebuffer(GL2GL3.GL_READ_FRAMEBUFFER, 0);
+                gl.glBindFramebuffer(GL2ES3.GL_DRAW_FRAMEBUFFER, 0);
+                gl.glBindFramebuffer(GL2ES3.GL_READ_FRAMEBUFFER, 0);
             } else {
                 gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0); // default draw buffer
             }
@@ -2155,7 +2156,7 @@ public class FBObject {
      * </p>
      * <p>
      * In case you use this FBO w/o the {@link GLFBODrawable} and intend to employ {@link GL#glReadPixels(int, int, int, int, int, int, java.nio.Buffer) glReadPixels(..)}
-     * you may want to call {@link GL#glBindFramebuffer(int, int) glBindFramebuffer}({@link GL2GL3#GL_READ_FRAMEBUFFER}, {@link #getReadFramebuffer()});
+     * you may want to call {@link GL#glBindFramebuffer(int, int) glBindFramebuffer}({@link GL2ES3#GL_READ_FRAMEBUFFER}, {@link #getReadFramebuffer()});
      * </p>
      * <p>Leaves the FBO unbound.</p>
      *
@@ -2169,17 +2170,17 @@ public class FBObject {
             samplingSinkDirty = false;
             resetSamplingSink(gl);
             checkPreGLError(gl);
-            gl.glBindFramebuffer(GL2GL3.GL_READ_FRAMEBUFFER, fbName);
-            gl.glBindFramebuffer(GL2GL3.GL_DRAW_FRAMEBUFFER, samplingSink.getWriteFramebuffer());
-            ((GL2GL3)gl).glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, // since MSAA is supported, casting to GL2GL3 is OK
+            gl.glBindFramebuffer(GL2ES3.GL_READ_FRAMEBUFFER, fbName);
+            gl.glBindFramebuffer(GL2ES3.GL_DRAW_FRAMEBUFFER, samplingSink.getWriteFramebuffer());
+            ((GL2ES3)gl).glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, // since MSAA is supported, casting to GL2ES3 is OK
                                            GL.GL_COLOR_BUFFER_BIT, GL.GL_NEAREST);
             checkNoError(null, gl.glGetError(), "FBObject syncSampleSink"); // throws GLException if error
         }
         if(fullFBOSupport) {
             // default read/draw buffers, may utilize GLContext/GLDrawable override of
             // GLContext.getDefaultDrawFramebuffer() and GLContext.getDefaultReadFramebuffer()
-            gl.glBindFramebuffer(GL2GL3.GL_DRAW_FRAMEBUFFER, 0);
-            gl.glBindFramebuffer(GL2GL3.GL_READ_FRAMEBUFFER, 0);
+            gl.glBindFramebuffer(GL2ES3.GL_DRAW_FRAMEBUFFER, 0);
+            gl.glBindFramebuffer(GL2ES3.GL_READ_FRAMEBUFFER, 0);
         } else {
             gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0); // default draw buffer
         }
diff --git a/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java b/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java
index 95f87be..a643d81 100644
--- a/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java
+++ b/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java
@@ -31,6 +31,11 @@ import java.util.IdentityHashMap;
 
 import javax.media.nativewindow.AbstractGraphicsDevice;
 
+import com.jogamp.common.os.Platform;
+
+import jogamp.opengl.egl.EGL;
+import jogamp.opengl.egl.EGLExt;
+
 /**
  * GLRendererQuirks contains information of known bugs of various GL renderer.
  * This information allows us to workaround them.
@@ -67,7 +72,13 @@ public class GLRendererQuirks {
     /** SIGSEGV on setSwapInterval() after changing the context's drawable w/ 'Mesa 8.0.4' dri2SetSwapInterval/DRI2 (soft & intel) */
     public static final int NoSetSwapIntervalPostRetarget = 4;
 
-    /** GLSL <code>discard</code> command leads to undefined behavior or won't get compiled if being used. Appears to <i>have</i> happened on Nvidia Tegra2, but seems to be fine now. FIXME: Constrain version. */
+    /**
+     * GLSL <code>discard</code> command leads to undefined behavior or won't get compiled if being used.
+     * <p>
+     * Appears to <i>have</i> happened on Nvidia Tegra2, but seems to be fine now.<br/>
+     * FIXME: Constrain version.
+     * </p>
+     */
     public static final int GLSLBuggyDiscard = 5;
 
     /**
@@ -235,15 +246,58 @@ public class GLRendererQuirks {
      */
     public static final int GLSharedContextBuggy = 14;
 
+    /**
+     * Bug 925 - Accept an ES3 Context, if reported via GL-Version-String w/o {@link EGLExt#EGL_OPENGL_ES3_BIT_KHR}.
+     * <p>
+     * The ES3 Context can be used via {@link EGL#EGL_OPENGL_ES2_BIT}.
+     * </p>
+     * <p>
+     * The ES3 Context {@link EGL#eglCreateContext(long, long, long, java.nio.IntBuffer) must be created} with version attributes:
+     * <pre>
+     *  EGL.EGL_CONTEXT_CLIENT_VERSION, 2, ..
+     * </pre>
+     * </p>
+     * <ul>
+     *   <li>Mesa/AMD >= 9.2.1</li>
+     *   <li>Some Android ES3 drivers ..</li>
+     * </ul>
+     */
+    public static final int GLES3ViaEGLES2Config = 15;
+
+    /**
+     * Bug 948 - NVIDIA 331.38 (Linux X11) EGL impl. only supports _one_ EGL Device via {@link EGL#eglGetDisplay(long)}.
+     * <p>
+     * Subsequent calls to {@link EGL#eglGetDisplay(long)} fail.
+     * </p>
+     * <p>
+     * Reusing global EGL display works.
+     * </p>
+     * <p>
+     * The quirk is autodetected within EGLDrawableFactory's initial default device setup!
+     * </p>
+     * <p>
+     * Appears on:
+     * <ul>
+     *   <li>EGL_VENDOR      NVIDIA</li>
+     *   <li>EGL_VERSION     1.4</li>
+     *   <li>GL_VENDOR       NVIDIA Corporation</li>
+     *   <li>GL_VERSION      OpenGL ES 3.0 331.38 (probably w/ 1st NV EGL lib on x86)</li>
+     *   <li>Platform        X11</li>
+     *   <li>CPU Family      {@link Platform.CPUFamily#X86}</li>
+     * </ul>
+     * </p>
+     */
+    public static final int SingletonEGLDisplayOnly = 16;
+
     /** Number of quirks known. */
-    public static final int COUNT = 15;
+    public static final int COUNT = 17;
 
     private static final String[] _names = new String[] { "NoDoubleBufferedPBuffer", "NoDoubleBufferedBitmap", "NoSetSwapInterval",
                                                           "NoOffscreenBitmap", "NoSetSwapIntervalPostRetarget", "GLSLBuggyDiscard",
                                                           "GLNonCompliant", "GLFlushBeforeRelease", "DontCloseX11Display",
                                                           "NeedCurrCtx4ARBPixFmtQueries", "NeedCurrCtx4ARBCreateContext",
                                                           "NoFullFBOSupport", "GLSLNonCompliant", "GL4NeedsGL3Request",
-                                                          "GLSharedContextBuggy"
+                                                          "GLSharedContextBuggy", "GLES3ViaEGLES2Config", "SingletonEGLDisplayOnly"
                                                         };
 
     private static final IdentityHashMap<String, GLRendererQuirks> stickyDeviceQuirks = new IdentityHashMap<String, GLRendererQuirks>();
@@ -251,8 +305,12 @@ public class GLRendererQuirks {
     /**
      * Retrieval of sticky {@link AbstractGraphicsDevice}'s {@link GLRendererQuirks}.
      * <p>
+     * The {@link AbstractGraphicsDevice}s are mapped via their {@link AbstractGraphicsDevice#getUniqueID()}.
+     * </p>
+     * <p>
      * Not thread safe.
      * </p>
+     * @see #areSameStickyDevice(AbstractGraphicsDevice, AbstractGraphicsDevice)
      */
     public static GLRendererQuirks getStickyDeviceQuirks(AbstractGraphicsDevice device) {
         final String key = device.getUniqueID();
@@ -268,20 +326,41 @@ public class GLRendererQuirks {
     }
 
     /**
+     * Returns true if both devices have the same {@link AbstractGraphicsDevice#getUniqueID()},
+     * otherwise false.
+     */
+    public static boolean areSameStickyDevice(AbstractGraphicsDevice device1, AbstractGraphicsDevice device2) {
+        return device1.getUniqueID() == device2.getUniqueID();
+    }
+
+    /**
      * {@link #addQuirks(int[], int, int) Adding given quirks} of sticky {@link AbstractGraphicsDevice}'s {@link GLRendererQuirks}.
      * <p>
      * Not thread safe.
      * </p>
+     * @see #getStickyDeviceQuirks(AbstractGraphicsDevice)
      */
     public static void addStickyDeviceQuirks(AbstractGraphicsDevice device, int[] quirks, int offset, int len) throws IllegalArgumentException {
         final GLRendererQuirks sq = getStickyDeviceQuirks(device);
         sq.addQuirks(quirks, offset, len);
     }
     /**
+     * {@link #addQuirks(GLRendererQuirks) Adding given quirks} of sticky {@link AbstractGraphicsDevice}'s {@link GLRendererQuirks}.
+     * <p>
+     * Not thread safe.
+     * </p>
+     * @see #getStickyDeviceQuirks(AbstractGraphicsDevice)
+     */
+    public static void addStickyDeviceQuirks(AbstractGraphicsDevice device, GLRendererQuirks quirks) throws IllegalArgumentException {
+        final GLRendererQuirks sq = getStickyDeviceQuirks(device);
+        sq.addQuirks(quirks);
+    }
+    /**
      * {@link #exist(int) Query} of sticky {@link AbstractGraphicsDevice}'s {@link GLRendererQuirks}.
      * <p>
      * Not thread safe. However, use after changing the sticky quirks is safe.
      * </p>
+     * @see #getStickyDeviceQuirks(AbstractGraphicsDevice)
      */
     public static boolean existStickyDeviceQuirk(AbstractGraphicsDevice device, int quirk) {
         return getStickyDeviceQuirks(device).exist(quirk);
@@ -292,6 +371,7 @@ public class GLRendererQuirks {
      * <p>
      * Not thread safe. However, use after changing the sticky quirks is safe.
      * </p>
+     * @see #getStickyDeviceQuirks(AbstractGraphicsDevice)
      */
     public static void pushStickyDeviceQuirks(AbstractGraphicsDevice device, GLRendererQuirks dest) {
         dest.addQuirks(getStickyDeviceQuirks(device));
@@ -322,7 +402,7 @@ public class GLRendererQuirks {
      */
     public final void addQuirks(int[] quirks, int offset, int len) throws IllegalArgumentException {
         int bitmask = 0;
-        if( !( 0 <= offset + len && offset + len < quirks.length ) ) {
+        if( !( 0 <= offset + len && offset + len <= quirks.length ) ) {
             throw new IllegalArgumentException("offset and len out of bounds: offset "+offset+", len "+len+", array-len "+quirks.length);
         }
         for(int i=offset; i<offset+len; i++) {
diff --git a/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java b/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
index cad780a..cd5aa33 100644
--- a/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
+++ b/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
@@ -725,6 +725,11 @@ public class GLCanvas extends Canvas implements GLAutoDrawable, GLSharedContextS
    }
 
    @Override
+   public boolean areAllGLEventListenerInitialized() {
+      return helper.areAllGLEventListenerInitialized();
+   }
+
+   @Override
    public boolean getGLEventListenerInitState(GLEventListener listener) {
        return helper.getGLEventListenerInitState(listener);
    }
diff --git a/src/jogl/classes/com/jogamp/opengl/util/FPSAnimator.java b/src/jogl/classes/com/jogamp/opengl/util/FPSAnimator.java
index 65fed17..5bd8035 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/FPSAnimator.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/FPSAnimator.java
@@ -163,13 +163,17 @@ public class FPSAnimator extends AnimatorBase {
                         setDrawablesExclCtxState(exclusiveContext);
                         FPSAnimator.this.notifyAll();
                     }
-                    System.err.println("FPSAnimator P1:" + Thread.currentThread() + ": " + toString());
+                    if(DEBUG) {
+                        System.err.println("FPSAnimator P1:" + Thread.currentThread() + ": " + toString());
+                    }
                 }
             }
             if( shouldRun ) {
                 display();
             } else if( shouldStop ) { // STOP
-                System.err.println("FPSAnimator P4: "+alreadyStopped+", "+ Thread.currentThread() + ": " + toString());
+                if(DEBUG) {
+                    System.err.println("FPSAnimator P4: "+alreadyStopped+", "+ Thread.currentThread() + ": " + toString());
+                }
                 this.cancel();
 
                 if( !alreadyStopped ) {
@@ -188,7 +192,9 @@ public class FPSAnimator extends AnimatorBase {
                     }
                 }
             } else {
-                System.err.println("FPSAnimator P5: "+alreadyPaused+", "+ Thread.currentThread() + ": " + toString());
+                if(DEBUG) {
+                    System.err.println("FPSAnimator P5: "+alreadyPaused+", "+ Thread.currentThread() + ": " + toString());
+                }
                 this.cancel();
 
                 if( !alreadyPaused ) { // PAUSE
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java
index f84342e..a58eb82 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java
@@ -74,7 +74,7 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
   {
       GLArrayDataClient adc = new GLArrayDataClient();
       GLArrayHandler glArrayHandler = new GLFixedArrayHandler(adc);
-      adc.init(null, index, comps, dataType, normalized, 0, null, initialElementCount, false, glArrayHandler, 0, 0, 0, 0, false);
+      adc.init(null, index, comps, dataType, normalized, 0, null, initialElementCount, 0 /* mappedElementCount */, false, glArrayHandler, 0, 0, 0, 0, false);
       return adc;
   }
 
@@ -105,7 +105,7 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
   {
       GLArrayDataClient adc = new GLArrayDataClient();
       GLArrayHandler glArrayHandler = new GLFixedArrayHandler(adc);
-      adc.init(null, index, comps, dataType, normalized, stride, buffer, comps*comps, false, glArrayHandler, 0, 0, 0, 0, false);
+      adc.init(null, index, comps, dataType, normalized, stride, buffer, comps*comps, 0 /* mappedElementCount */, false, glArrayHandler, 0, 0, 0, 0, false);
       return adc;
   }
 
@@ -124,7 +124,7 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
   {
       GLArrayDataClient adc = new GLArrayDataClient();
       GLArrayHandler glArrayHandler = new GLSLArrayHandler(adc);
-      adc.init(name, -1, comps, dataType, normalized, 0, null, initialElementCount, true, glArrayHandler, 0, 0, 0, 0, true);
+      adc.init(name, -1, comps, dataType, normalized, 0, null, initialElementCount, 0 /* mappedElementCount */, true, glArrayHandler, 0, 0, 0, 0, true);
       return adc;
   }
 
@@ -144,7 +144,7 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
   {
       GLArrayDataClient adc = new GLArrayDataClient();
       GLArrayHandler glArrayHandler = new GLSLArrayHandler(adc);
-      adc.init(name, -1, comps, dataType, normalized, stride, buffer, comps*comps, true, glArrayHandler, 0, 0, 0, 0, true);
+      adc.init(name, -1, comps, dataType, normalized, stride, buffer, comps*comps, 0 /* mappedElementCount */, true, glArrayHandler, 0, 0, 0, 0, true);
       return adc;
   }
 
@@ -177,7 +177,9 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
   //
 
   @Override
-  public final void setVBOWritten(boolean written) { bufferWritten=written; }
+  public final void setVBOWritten(boolean written) {
+      bufferWritten = ( 0 == mappedElementCount ) ? written : true;
+  }
 
   @Override
   public void destroy(GL gl) {
@@ -231,25 +233,25 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
 
   @Override
   public void reset() {
-    if(buffer!=null) {
+    if( buffer != null ) {
         buffer.clear();
     }
-    this.sealed=false;
-    this.bufferEnabled=false;
-    this.bufferWritten=false;
+    sealed = false;
+    bufferEnabled = false;
+    bufferWritten = ( 0 == mappedElementCount ) ? false : true;
   }
 
   @Override
   public void seal(boolean seal)
   {
-    if(sealed==seal) return;
+    if( sealed == seal ) return;
     sealed = seal;
-    bufferWritten=false;
-    if(seal) {
-        if (null!=buffer) {
+    bufferWritten = ( 0 == mappedElementCount ) ? false : true;
+    if( seal ) {
+        if ( null != buffer ) {
             buffer.flip();
         }
-    } else if (null!=buffer) {
+    } else if ( null != buffer ) {
         buffer.position(buffer.limit());
         buffer.limit(buffer.capacity());
     }
@@ -333,8 +335,9 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
                        ", dataType 0x"+Integer.toHexString(componentType)+
                        ", bufferClazz "+componentClazz+
                        ", elements "+getElementCount()+
-                       ", components "+components+
+                       ", components "+componentsPerElement+
                        ", stride "+strideB+"b "+strideL+"c"+
+                       ", mappedElementCount "+mappedElementCount+
                        ", initialElementCount "+initialElementCount+
                        ", sealed "+sealed+
                        ", bufferEnabled "+bufferEnabled+
@@ -346,9 +349,14 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
 
   // non public matters
 
-  protected final boolean growBufferIfNecessary(int spare) {
-    if(buffer==null || buffer.remaining()<spare) {
-        growBuffer(Math.max(initialElementCount, spare));
+  protected final boolean growBufferIfNecessary(int spareComponents) {
+    if( buffer==null || buffer.remaining()<spareComponents ) {
+        if( 0 != mappedElementCount ) {
+            throw new GLException("Mapped buffer can't grow. Insufficient storage size: Needed "+spareComponents+" components, "+
+                                  "mappedElementCount "+mappedElementCount+
+                                  ", has mapped buffer "+buffer+"; "+this);
+        }
+        growBuffer(Math.max(initialElementCount, (spareComponents+componentsPerElement-1)/componentsPerElement));
         return true;
     }
     return false;
@@ -360,34 +368,35 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
     }
 
     // add the stride delta
-    additionalElements += (additionalElements/components)*(strideL-components);
+    additionalElements += (additionalElements/componentsPerElement)*(strideL-componentsPerElement);
 
     final int osize = (buffer!=null) ? buffer.capacity() : 0;
-    final int nsize = osize + ( additionalElements * components );
+    final int nsize = osize + ( additionalElements * componentsPerElement );
+    final Buffer oldBuffer = buffer;
 
     if(componentClazz==ByteBuffer.class) {
-        ByteBuffer newBBuffer = Buffers.newDirectByteBuffer( nsize );
+        final ByteBuffer newBBuffer = Buffers.newDirectByteBuffer( nsize );
         if(buffer!=null) {
             buffer.flip();
             newBBuffer.put((ByteBuffer)buffer);
         }
         buffer = newBBuffer;
     } else if(componentClazz==ShortBuffer.class) {
-        ShortBuffer newSBuffer = Buffers.newDirectShortBuffer( nsize );
+        final ShortBuffer newSBuffer = Buffers.newDirectShortBuffer( nsize );
         if(buffer!=null) {
             buffer.flip();
             newSBuffer.put((ShortBuffer)buffer);
         }
         buffer = newSBuffer;
     } else if(componentClazz==IntBuffer.class) {
-        IntBuffer newIBuffer = Buffers.newDirectIntBuffer( nsize );
+        final IntBuffer newIBuffer = Buffers.newDirectIntBuffer( nsize );
         if(buffer!=null) {
             buffer.flip();
             newIBuffer.put((IntBuffer)buffer);
         }
         buffer = newIBuffer;
     } else if(componentClazz==FloatBuffer.class) {
-        FloatBuffer newFBuffer = Buffers.newDirectFloatBuffer( nsize );
+        final FloatBuffer newFBuffer = Buffers.newDirectFloatBuffer( nsize );
         if(buffer!=null) {
             buffer.flip();
             newFBuffer.put((FloatBuffer)buffer);
@@ -397,7 +406,8 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
         throw new GLException("Given Buffer Class not supported: "+componentClazz+":\n\t"+this);
     }
     if(DEBUG) {
-        System.err.println("*** Grow: comps: "+components+", "+(osize/components)+"/"+osize+" -> "+(nsize/components)+"/"+nsize+", "+this);
+        System.err.println("*** Grow: comps: "+componentsPerElement+", "+(osize/componentsPerElement)+"/"+osize+" -> "+(nsize/componentsPerElement)+"/"+nsize+
+                           "; "+oldBuffer+" -> "+buffer+"; "+this);
     }
   }
 
@@ -415,20 +425,24 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
   }
 
   protected void init(String name, int index, int comps, int dataType, boolean normalized, int stride, Buffer data,
-                      int initialElementCount, boolean isVertexAttribute, GLArrayHandler handler,
-                      int vboName, long vboOffset, int vboUsage, int vboTarget, boolean usesGLSL)
+                      int initialElementCount, int mappedElementCount, boolean isVertexAttribute,
+                      GLArrayHandler handler, int vboName, long vboOffset, int vboUsage, int vboTarget, boolean usesGLSL)
     throws GLException
   {
-    super.init(name, index, comps, dataType, normalized, stride, data, isVertexAttribute,
-               vboName, vboOffset, vboUsage, vboTarget);
+    super.init(name, index, comps, dataType, normalized, stride, data, mappedElementCount,
+               isVertexAttribute, vboName, vboOffset, vboUsage, vboTarget);
 
+    if( 0<mappedElementCount && 0<initialElementCount ) { // null!=buffer case validated in super.init(..)
+        throw new IllegalArgumentException("mappedElementCount:="+mappedElementCount+" specified, but passing non zero initialElementSize");
+    }
     this.initialElementCount = initialElementCount;
     this.glArrayHandler = handler;
     this.usesGLSL = usesGLSL;
     this.sealed=false;
     this.bufferEnabled=false;
     this.enableBufferAlways=false;
-    this.bufferWritten=false;
+    this.bufferWritten = ( 0 == mappedElementCount ) ? false : true;
+
     if(null==buffer && initialElementCount>0) {
         growBuffer(initialElementCount);
     }
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataServer.java b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataServer.java
index 4a12ff1..833f1cc 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataServer.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataServer.java
@@ -29,11 +29,15 @@
 package com.jogamp.opengl.util;
 
 import java.nio.Buffer;
+import java.nio.ByteBuffer;
 import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+import java.nio.ShortBuffer;
 
 import javax.media.opengl.GL;
 import javax.media.opengl.GL2ES2;
 import javax.media.opengl.GLArrayData;
+import javax.media.opengl.GLBufferStorage;
 import javax.media.opengl.GLException;
 import javax.media.opengl.fixedfunc.GLPointerFuncUtil;
 
@@ -68,23 +72,23 @@ public class GLArrayDataServer extends GLArrayDataClient implements GLArrayDataE
    * see {@link GLPointerFuncUtil#getPredefinedArrayIndexName(int)}.
    *
    * @param index The GL array index
-   * @param comps The array component number
-   * @param dataType The array index GL data type
+   * @param compsPerElement component count per element
+   * @param dataType The component's OpenGL data type
    * @param normalized Whether the data shall be normalized
-   * @param stride
+   * @param stride in bytes from one element to the other. If zero, compsPerElement * compSizeInBytes
    * @param buffer the user define data
    * @param vboUsage {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW}
    *
    * @see javax.media.opengl.GLContext#getPredefinedArrayIndexName(int)
    */
-  public static GLArrayDataServer createFixed(int index, int comps, int dataType, boolean normalized, int stride,
+  public static GLArrayDataServer createFixed(int index, int compsPerElement, int dataType, boolean normalized, int stride,
                                               Buffer buffer, int vboUsage)
     throws GLException
   {
     GLArrayDataServer ads = new GLArrayDataServer();
     GLArrayHandler glArrayHandler = new GLFixedArrayHandler(ads);
-    ads.init(null, index, comps, dataType, normalized, stride, buffer, buffer.limit(), false, glArrayHandler,
-             0, 0, vboUsage, GL.GL_ARRAY_BUFFER, false);
+    ads.init(null, index, compsPerElement, dataType, normalized, stride, buffer, buffer.limit(), 0 /* mappedElementCount */, false,
+             glArrayHandler, 0, 0, vboUsage, GL.GL_ARRAY_BUFFER, false);
     return ads;
   }
 
@@ -101,22 +105,22 @@ public class GLArrayDataServer extends GLArrayDataClient implements GLArrayDataE
    * see {@link GLPointerFuncUtil#getPredefinedArrayIndexName(int)}.
    *
    * @param index The GL array index
-   * @param comps The array component number
-   * @param dataType The array index GL data type
+   * @param compsPerElement component count per element
+   * @param dataType The component's OpenGL data type
    * @param normalized Whether the data shall be normalized
    * @param initialElementCount
    * @param vboUsage {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW}
    *
    * @see javax.media.opengl.GLContext#getPredefinedArrayIndexName(int)
    */
-  public static GLArrayDataServer createFixed(int index, int comps, int dataType, boolean normalized, int initialElementCount,
+  public static GLArrayDataServer createFixed(int index, int compsPerElement, int dataType, boolean normalized, int initialElementCount,
                                               int vboUsage)
     throws GLException
   {
     GLArrayDataServer ads = new GLArrayDataServer();
     GLArrayHandler glArrayHandler = new GLFixedArrayHandler(ads);
-    ads.init(null, index, comps, dataType, normalized, 0, null, initialElementCount, false, glArrayHandler,
-             0, 0, vboUsage, GL.GL_ARRAY_BUFFER, false);
+    ads.init(null, index, compsPerElement, dataType, normalized, 0, null, initialElementCount, 0 /* mappedElementCount */, false,
+             glArrayHandler, 0, 0, vboUsage, GL.GL_ARRAY_BUFFER, false);
     return ads;
   }
 
@@ -124,20 +128,42 @@ public class GLArrayDataServer extends GLArrayDataClient implements GLArrayDataE
    * Create a VBO, using a custom GLSL array attribute name
    * and starting with a new created Buffer object with initialElementCount size
    * @param name  The custom name for the GL attribute
-   * @param comps The array component number
-   * @param dataType The array index GL data type
+   * @param compsPerElement component count per element
+   * @param dataType The component's OpenGL data type
    * @param normalized Whether the data shall be normalized
    * @param initialElementCount
    * @param vboUsage {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW}
    */
-  public static GLArrayDataServer createGLSL(String name, int comps,
+  public static GLArrayDataServer createGLSL(String name, int compsPerElement,
                                              int dataType, boolean normalized, int initialElementCount, int vboUsage)
     throws GLException
   {
     GLArrayDataServer ads = new GLArrayDataServer();
     GLArrayHandler glArrayHandler = new GLSLArrayHandler(ads);
-    ads.init(name, -1, comps, dataType, normalized, 0, null, initialElementCount,
-             true, glArrayHandler, 0, 0, vboUsage, GL.GL_ARRAY_BUFFER, true);
+    ads.init(name, -1, compsPerElement, dataType, normalized, 0, null, initialElementCount,
+             0 /* mappedElementCount */, true, glArrayHandler, 0, 0, vboUsage, GL.GL_ARRAY_BUFFER, true);
+    return ads;
+  }
+
+  /**
+   * Create a VBO, using a custom GLSL array attribute name
+   * intended for GPU buffer storage mapping, see {@link GLBufferStorage}, via {@link #mapStorage(GL, int)} and {@link #mapStorage(GL, long, long, int)}.
+   * @param name  The custom name for the GL attribute
+   * @param compsPerElement component count per element
+   * @param dataType The component's OpenGL data type
+   * @param normalized Whether the data shall be normalized
+   * @param mappedElementCount
+   * @param vboUsage {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW}
+   */
+  public static GLArrayDataServer createGLSLMapped(String name, int compsPerElement,
+                                                   int dataType, boolean normalized, int mappedElementCount, int vboUsage)
+    throws GLException
+  {
+    GLArrayDataServer ads = new GLArrayDataServer();
+    GLArrayHandler glArrayHandler = new GLSLArrayHandler(ads);
+    ads.init(name, -1, compsPerElement, dataType, normalized, 0, null, 0 /* initialElementCount */,
+             mappedElementCount, true, glArrayHandler, 0, 0, vboUsage, GL.GL_ARRAY_BUFFER, true);
+    ads.seal(true);
     return ads;
   }
 
@@ -145,22 +171,22 @@ public class GLArrayDataServer extends GLArrayDataClient implements GLArrayDataE
    * Create a VBO, using a custom GLSL array attribute name
    * and starting with a given Buffer object incl it's stride
    * @param name  The custom name for the GL attribute
-   * @param comps The array component number
-   * @param dataType The array index GL data type
+   * @param compsPerElement component count per element
+   * @param dataType The component's OpenGL data type
    * @param normalized Whether the data shall be normalized
-   * @param stride
+   * @param stride in bytes from one element to the other. If zero, compsPerElement * compSizeInBytes
    * @param buffer the user define data
    * @param vboUsage {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW}
    */
-  public static GLArrayDataServer createGLSL(String name, int comps,
+  public static GLArrayDataServer createGLSL(String name, int compsPerElement,
                                              int dataType, boolean normalized, int stride, Buffer buffer,
                                              int vboUsage)
     throws GLException
   {
     GLArrayDataServer ads = new GLArrayDataServer();
     GLArrayHandler glArrayHandler = new GLSLArrayHandler(ads);
-    ads.init(name, -1, comps, dataType, normalized, stride, buffer, buffer.limit(), true, glArrayHandler,
-             0, 0, vboUsage, GL.GL_ARRAY_BUFFER, true);
+    ads.init(name, -1, compsPerElement, dataType, normalized, stride, buffer, buffer.limit(), 0 /* mappedElementCount */, true,
+             glArrayHandler, 0, 0, vboUsage, GL.GL_ARRAY_BUFFER, true);
     return ads;
   }
 
@@ -169,22 +195,22 @@ public class GLArrayDataServer extends GLArrayDataClient implements GLArrayDataE
    *
    * Hence no index, name for a fixed function pipeline nor vertex attribute is given.
    *
-   * @param comps The array component number
-   * @param dataType The array index GL data type
-   * @param stride
+   * @param compsPerElement component count per element
+   * @param dataType The component's OpenGL data type
+   * @param stride in bytes from one element to the other. If zero, compsPerElement * compSizeInBytes
    * @param buffer the user define data
    * @param vboUsage {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW}
    * @param vboTarget {@link GL#GL_ELEMENT_ARRAY_BUFFER}, ..
    * {@link GL#glGenBuffers(int, int[], int)
    */
-  public static GLArrayDataServer createData(int comps, int dataType, int stride,
+  public static GLArrayDataServer createData(int compsPerElement, int dataType, int stride,
                                              Buffer buffer, int vboUsage, int vboTarget)
     throws GLException
   {
     GLArrayDataServer ads = new GLArrayDataServer();
     GLArrayHandler glArrayHandler = new GLDataArrayHandler(ads);
-    ads.init(null, -1, comps, dataType, false, stride, buffer, buffer.limit(), false, glArrayHandler,
-             0, 0, vboUsage, vboTarget, false);
+    ads.init(null, -1, compsPerElement, dataType, false, stride, buffer, buffer.limit(), 0 /* mappedElementCount */, false,
+             glArrayHandler, 0, 0, vboUsage, vboTarget, false);
     return ads;
   }
 
@@ -193,43 +219,89 @@ public class GLArrayDataServer extends GLArrayDataClient implements GLArrayDataE
    *
    * Hence no index, name for a fixed function pipeline nor vertex attribute is given.
    *
-   * @param comps The array component number
-   * @param dataType The array index GL data type
+   * @param compsPerElement component count per element
+   * @param dataType The component's OpenGL data type
    * @param initialElementCount
    * @param vboUsage {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW}
    * @param vboTarget {@link GL#GL_ELEMENT_ARRAY_BUFFER}, ..
    */
-  public static GLArrayDataServer createData(int comps, int dataType, int initialElementCount,
+  public static GLArrayDataServer createData(int compsPerElement, int dataType, int initialElementCount,
                                              int vboUsage, int vboTarget)
     throws GLException
   {
     GLArrayDataServer ads = new GLArrayDataServer();
     GLArrayHandler glArrayHandler = new GLDataArrayHandler(ads);
-    ads.init(null, -1, comps, dataType, false, 0, null, initialElementCount, false, glArrayHandler,
-             0, 0, vboUsage, vboTarget, false);
+    ads.init(null, -1, compsPerElement, dataType, false, 0, null, initialElementCount, 0 /* mappedElementCount */, false,
+             glArrayHandler, 0, 0, vboUsage, vboTarget, false);
     return ads;
   }
 
+  /**
+   * Create a VBO data object for any target w/o render pipeline association, i.e. {@link GL#GL_ELEMENT_ARRAY_BUFFER},
+   * intended for GPU buffer storage mapping, see {@link GLBufferStorage}, via {@link #mapStorage(GL, int)} and {@link #mapStorage(GL, long, long, int)}.
+   * <p>
+   * No index, name for a fixed function pipeline nor vertex attribute is given.
+   * </p>
+   *
+   * @param compsPerElement component count per element
+   * @param dataType The component's OpenGL data type
+   * @param initialElementCount
+   * @param vboUsage {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW}
+   * @param vboTarget {@link GL#GL_ELEMENT_ARRAY_BUFFER}, ..
+   */
+  public static GLArrayDataServer createDataMapped(int compsPerElement, int dataType, int mappedElementCount,
+                                                   int vboUsage, int vboTarget)
+    throws GLException
+  {
+    GLArrayDataServer ads = new GLArrayDataServer();
+    GLArrayHandler glArrayHandler = new GLDataArrayHandler(ads);
+    ads.init(null, -1, compsPerElement, dataType, false, 0, null, 0 /* initialElementCount */, mappedElementCount, false,
+             glArrayHandler, 0, 0, vboUsage, vboTarget, false);
+    return ads;
+  }
 
   /**
    * Create a VBO for fixed function interleaved array data
    * starting with a new created Buffer object with initialElementCount size.
    * <p>User needs to <i>configure</i> the interleaved segments via {@link #addFixedSubArray(int, int, int)}.</p>
    *
-   * @param comps The total number of all interleaved components.
-   * @param dataType The array index GL data type
+   * @param compsPerElement The total number of all interleaved components per element.
+   * @param dataType The component's OpenGL data type
    * @param normalized Whether the data shall be normalized
-   * @param initialElementCount
+   * @param initialElementCount The initial number of all interleaved elements
    * @param vboUsage {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW}
    */
-  public static GLArrayDataServer createFixedInterleaved(int comps, int dataType, boolean normalized, int initialElementCount,
+  public static GLArrayDataServer createFixedInterleaved(int compsPerElement, int dataType, boolean normalized, int initialElementCount,
                                               int vboUsage)
     throws GLException
   {
     GLArrayDataServer ads = new GLArrayDataServer();
     GLArrayHandler glArrayHandler = new GLArrayHandlerInterleaved(ads);
-    ads.init(GLPointerFuncUtil.mgl_InterleaveArray, -1, comps, dataType, false, 0, null, initialElementCount, false, glArrayHandler,
-             0, 0, vboUsage, GL.GL_ARRAY_BUFFER, false);
+    ads.init(GLPointerFuncUtil.mgl_InterleaveArray, -1, compsPerElement, dataType, false, 0, null, initialElementCount, 0 /* mappedElementCount */, false,
+             glArrayHandler, 0, 0, vboUsage, GL.GL_ARRAY_BUFFER, false);
+    return ads;
+  }
+
+  /**
+   * Create a VBO for fixed function interleaved array data
+   * intended for GPU buffer storage mapping, see {@link GLBufferStorage}, via {@link #mapStorage(GL, int)} and {@link #mapStorage(GL, long, long, int)}.
+   * <p>User needs to <i>configure</i> the interleaved segments via {@link #addFixedSubArray(int, int, int)}.</p>
+   *
+   * @param compsPerElement The total number of all interleaved components per element.
+   * @param dataType The component's OpenGL data type
+   * @param normalized Whether the data shall be normalized
+   * @param mappedElementCount The total number of all interleaved elements
+   * @param vboUsage {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW}
+   */
+  public static GLArrayDataServer createFixedInterleavedMapped(int compsPerElement, int dataType, boolean normalized, int mappedElementCount,
+                                                               int vboUsage)
+    throws GLException
+  {
+    GLArrayDataServer ads = new GLArrayDataServer();
+    GLArrayHandler glArrayHandler = new GLArrayHandlerInterleaved(ads);
+    ads.init(GLPointerFuncUtil.mgl_InterleaveArray, -1, compsPerElement, dataType, false, 0, null, 0 /* initialElementCount */, mappedElementCount, false,
+             glArrayHandler, 0, 0, vboUsage, GL.GL_ARRAY_BUFFER, false);
+    ads.seal(true);
     return ads;
   }
 
@@ -238,20 +310,21 @@ public class GLArrayDataServer extends GLArrayDataClient implements GLArrayDataE
    * starting with a given Buffer object incl it's stride
    * <p>User needs to <i>configure</i> the interleaved segments via {@link #addFixedSubArray(int, int, int)}.</p>
    *
-   * @param comps The total number of all interleaved components.
-   * @param dataType The array index GL data type
+   * @param compsPerElement The total number of all interleaved components per element.
+   * @param dataType The component's OpenGL data type
    * @param normalized Whether the data shall be normalized
-   * @param initialElementCount
+   * @param stride in bytes from one element of a sub-array to the other. If zero, compsPerElement * compSizeInBytes
+   * @param buffer The user define data of all interleaved elements
    * @param vboUsage {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW}
    */
-  public static GLArrayDataServer createFixedInterleaved(int comps, int dataType, boolean normalized, int stride, Buffer buffer,
+  public static GLArrayDataServer createFixedInterleaved(int compsPerElement, int dataType, boolean normalized, int stride, Buffer buffer,
                                               int vboUsage)
     throws GLException
   {
     GLArrayDataServer ads = new GLArrayDataServer();
     GLArrayHandler glArrayHandler = new GLArrayHandlerInterleaved(ads);
-    ads.init(GLPointerFuncUtil.mgl_InterleaveArray, -1, comps, dataType, normalized, stride, buffer, buffer.limit(), false, glArrayHandler,
-             0, 0, vboUsage, GL.GL_ARRAY_BUFFER, false);
+    ads.init(GLPointerFuncUtil.mgl_InterleaveArray, -1, compsPerElement, dataType, normalized, stride, buffer, buffer.limit(), 0 /* mappedElementCount */, false,
+             glArrayHandler, 0, 0, vboUsage, GL.GL_ARRAY_BUFFER, false);
     return ads;
   }
 
@@ -259,14 +332,14 @@ public class GLArrayDataServer extends GLArrayDataClient implements GLArrayDataE
    * Configure a segment of this fixed function interleaved array (see {@link #createFixedInterleaved(int, int, boolean, int, int)}).
    * <p>
    * This method may be called several times as long the sum of interleaved components does not
-   * exceed the total number of components of the created interleaved array.</p>
+   * exceed the total component count of the created interleaved array.</p>
    * <p>
    * The memory of the the interleaved array is being used.</p>
    * <p>
    * Must be called before using the array, eg: {@link #seal(boolean)}, {@link #putf(float)}, .. </p>
    *
    * @param index The GL array index, maybe -1 if vboTarget is {@link GL#GL_ELEMENT_ARRAY_BUFFER}
-   * @param comps This interleaved array segment's component number
+   * @param comps This interleaved array segment's component count per element
    * @param vboTarget {@link GL#GL_ARRAY_BUFFER} or {@link GL#GL_ELEMENT_ARRAY_BUFFER}
    */
   public GLArrayData addFixedSubArray(int index, int comps, int vboTarget) {
@@ -277,10 +350,19 @@ public class GLArrayDataServer extends GLArrayDataClient implements GLArrayDataE
       if(usesGLSL) {
           throw new GLException("buffer uses GLSL");
       }
-      final GLArrayDataWrapper ad = GLArrayDataWrapper.createFixed(
-              index, comps, getComponentType(),
-              getNormalized(), getStride(), getBuffer(),
-              getVBOName(), interleavedOffset, getVBOUsage(), vboTarget);
+      final int subStrideB = ( 0 == getStride() ) ? getComponentCount() * getComponentSizeInBytes() : getStride();
+      final GLArrayDataWrapper ad;
+      if( 0 < mappedElementCount ) {
+          ad = GLArrayDataWrapper.createFixed(
+                  index, comps, getComponentType(),
+                  getNormalized(), subStrideB, mappedElementCount,
+                  getVBOName(), interleavedOffset, getVBOUsage(), vboTarget);
+      } else {
+          ad = GLArrayDataWrapper.createFixed(
+                  index, comps, getComponentType(),
+                  getNormalized(), subStrideB, getBuffer(),
+                  getVBOName(), interleavedOffset, getVBOUsage(), vboTarget);
+      }
       ad.setVBOEnabled(isVBO());
       interleavedOffset += comps * getComponentSizeInBytes();
       if(GL.GL_ARRAY_BUFFER == vboTarget) {
@@ -294,20 +376,42 @@ public class GLArrayDataServer extends GLArrayDataClient implements GLArrayDataE
    * starting with a new created Buffer object with initialElementCount size.
    * <p>User needs to <i>configure</i> the interleaved segments via {@link #addGLSLSubArray(int, int, int)}.</p>
    *
-   * @param comps The total number of all interleaved components.
-   * @param dataType The array index GL data type
+   * @param compsPerElement The total number of all interleaved components per element.
+   * @param dataType The component's OpenGL data type
    * @param normalized Whether the data shall be normalized
-   * @param initialElementCount
+   * @param initialElementCount The initial number of all interleaved elements
    * @param vboUsage {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW}
    */
-  public static GLArrayDataServer createGLSLInterleaved(int comps, int dataType, boolean normalized, int initialElementCount,
-                                              int vboUsage)
+  public static GLArrayDataServer createGLSLInterleaved(int compsPerElement, int dataType, boolean normalized, int initialElementCount,
+                                                        int vboUsage)
     throws GLException
   {
     GLArrayDataServer ads = new GLArrayDataServer();
     GLArrayHandler glArrayHandler = new GLSLArrayHandlerInterleaved(ads);
-    ads.init(GLPointerFuncUtil.mgl_InterleaveArray, -1, comps, dataType, false, 0, null, initialElementCount, false, glArrayHandler,
-             0, 0, vboUsage, GL.GL_ARRAY_BUFFER, true);
+    ads.init(GLPointerFuncUtil.mgl_InterleaveArray, -1, compsPerElement, dataType, normalized, 0, null, initialElementCount, 0 /* mappedElementCount */, false,
+             glArrayHandler, 0, 0, vboUsage, GL.GL_ARRAY_BUFFER, true);
+    return ads;
+  }
+
+  /**
+   * Create a VBO for GLSL interleaved array data
+   * intended for GPU buffer storage mapping, see {@link GLBufferStorage}, via {@link #mapStorage(GL, int)} and {@link #mapStorage(GL, long, long, int)}.
+   * <p>User needs to <i>configure</i> the interleaved segments via {@link #addGLSLSubArray(int, int, int)}.</p>
+   *
+   * @param compsPerElement The total number of all interleaved components per element.
+   * @param dataType The component's OpenGL data type
+   * @param normalized Whether the data shall be normalized
+   * @param mappedElementCount The total number of all interleaved elements
+   * @param vboUsage {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW}
+   */
+  public static GLArrayDataServer createGLSLInterleavedMapped(int compsPerElement, int dataType, boolean normalized, int mappedElementCount, int vboUsage)
+    throws GLException
+  {
+    GLArrayDataServer ads = new GLArrayDataServer();
+    GLArrayHandler glArrayHandler = new GLSLArrayHandlerInterleaved(ads);
+    ads.init(GLPointerFuncUtil.mgl_InterleaveArray, -1, compsPerElement, dataType, normalized, 0, null, 0 /* initialElementCount */, mappedElementCount, false,
+             glArrayHandler, 0, 0, vboUsage, GL.GL_ARRAY_BUFFER, true);
+    ads.seal(true);
     return ads;
   }
 
@@ -316,21 +420,21 @@ public class GLArrayDataServer extends GLArrayDataClient implements GLArrayDataE
    * starting with a given Buffer object incl it's stride
    * <p>User needs to <i>configure</i> the interleaved segments via {@link #addGLSLSubArray(int, int, int)}.</p>
    *
-   * @param comps The total number of all interleaved components.
-   * @param dataType The array index GL data type
+   * @param compsPerElement The total number of all interleaved components per element.
+   * @param dataType The component's OpenGL data type
    * @param normalized Whether the data shall be normalized
-   * @param stride
-   * @param buffer the user define data
+   * @param stride in bytes from one element of a sub-array to the other. If zero, compsPerElement * compSizeInBytes
+   * @param buffer The user define data of all interleaved elements
    * @param vboUsage {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW}
    */
-  public static GLArrayDataServer createGLSLInterleaved(int comps, int dataType, boolean normalized, int stride, Buffer buffer,
-                                              int vboUsage)
+  public static GLArrayDataServer createGLSLInterleaved(int compsPerElement, int dataType, boolean normalized, int stride, Buffer buffer,
+                                                        int vboUsage)
     throws GLException
   {
     GLArrayDataServer ads = new GLArrayDataServer();
     GLArrayHandler glArrayHandler = new GLSLArrayHandlerInterleaved(ads);
-    ads.init(GLPointerFuncUtil.mgl_InterleaveArray, -1, comps, dataType, normalized, stride, buffer, buffer.limit(), false, glArrayHandler,
-             0, 0, vboUsage, GL.GL_ARRAY_BUFFER, true);
+    ads.init(GLPointerFuncUtil.mgl_InterleaveArray, -1, compsPerElement, dataType, normalized, stride, buffer, buffer.limit(), 0 /* mappedElementCount */, false,
+             glArrayHandler, 0, 0, vboUsage, GL.GL_ARRAY_BUFFER, true);
     return ads;
   }
 
@@ -338,13 +442,13 @@ public class GLArrayDataServer extends GLArrayDataClient implements GLArrayDataE
    * Configure a segment of this GLSL interleaved array (see {@link #createGLSLInterleaved(int, int, boolean, int, int)}).
    * <p>
    * This method may be called several times as long the sum of interleaved components does not
-   * exceed the total number of components of the created interleaved array.</p>
+   * exceed the total component count of the created interleaved array.</p>
    * <p>
    * The memory of the the interleaved array is being used.</p>
    * <p>
    * Must be called before using the array, eg: {@link #seal(boolean)}, {@link #putf(float)}, .. </p>
    * @param name  The custom name for the GL attribute, maybe null if vboTarget is {@link GL#GL_ELEMENT_ARRAY_BUFFER}
-   * @param comps This interleaved array segment's component number
+   * @param comps This interleaved array segment's component count per element
    * @param vboTarget {@link GL#GL_ARRAY_BUFFER} or {@link GL#GL_ELEMENT_ARRAY_BUFFER}
    */
   public GLArrayData addGLSLSubArray(String name, int comps, int vboTarget) {
@@ -355,10 +459,19 @@ public class GLArrayDataServer extends GLArrayDataClient implements GLArrayDataE
       if(!usesGLSL) {
           throw new GLException("buffer uses fixed function");
       }
-      final GLArrayDataWrapper ad = GLArrayDataWrapper.createGLSL(
-              name, comps, getComponentType(),
-              getNormalized(), getStride(), getBuffer(),
-              getVBOName(), interleavedOffset, getVBOUsage(), vboTarget);
+      final int subStrideB = ( 0 == getStride() ) ? getComponentCount() * getComponentSizeInBytes() : getStride();
+      final GLArrayDataWrapper ad;
+      if( 0 < mappedElementCount ) {
+          ad = GLArrayDataWrapper.createGLSL(
+                  name, comps, getComponentType(),
+                  getNormalized(), subStrideB, mappedElementCount,
+                  getVBOName(), interleavedOffset, getVBOUsage(), vboTarget);
+      } else {
+          ad = GLArrayDataWrapper.createGLSL(
+                  name, comps, getComponentType(),
+                  getNormalized(), subStrideB, getBuffer(),
+                  getVBOName(), interleavedOffset, getVBOUsage(), vboTarget);
+      }
       ad.setVBOEnabled(isVBO());
       interleavedOffset += comps * getComponentSizeInBytes();
       if(GL.GL_ARRAY_BUFFER == vboTarget) {
@@ -407,11 +520,73 @@ public class GLArrayDataServer extends GLArrayDataClient implements GLArrayDataE
    * Only possible if buffer is defined.
    */
   @Override
-  public void    setVBOEnabled(boolean vboUsage) {
+  public void setVBOEnabled(boolean vboUsage) {
     checkSeal(false);
     super.setVBOEnabled(vboUsage);
   }
 
+  public GLBufferStorage mapStorage(GL gl, int access) {
+      if( null != this.getBuffer() ) {
+          throw new IllegalStateException("user buffer not null");
+      }
+      if( null != mappedStorage ) {
+          throw new IllegalStateException("already mapped: "+mappedStorage);
+      }
+      checkSeal(true);
+      bindBuffer(gl, true);
+      gl.glBufferData(getVBOTarget(), getSizeInBytes(), null, getVBOUsage());
+      final GLBufferStorage storage = gl.mapBuffer(getVBOTarget(), access);
+      setMappedBuffer(storage);
+      bindBuffer(gl, false);
+      seal(false);
+      rewind();
+      return storage;
+  }
+  public GLBufferStorage mapStorage(GL gl, long offset, long length, int access) {
+      if( null != this.getBuffer() ) {
+          throw new IllegalStateException("user buffer not null");
+      }
+      if( null != mappedStorage ) {
+          throw new IllegalStateException("already mapped: "+mappedStorage);
+      }
+      checkSeal(true);
+      bindBuffer(gl, true);
+      gl.glBufferData(getVBOTarget(), getSizeInBytes(), null, getVBOUsage());
+      final GLBufferStorage storage = gl.mapBufferRange(getVBOTarget(), offset, length, access);
+      setMappedBuffer(storage);
+      bindBuffer(gl, false);
+      seal(false);
+      rewind();
+      return storage;
+  }
+  private final void setMappedBuffer(GLBufferStorage storage) {
+      mappedStorage = storage;
+      final ByteBuffer bb = storage.getMappedBuffer();
+      if(componentClazz==ByteBuffer.class) {
+          buffer = bb;
+      } else if(componentClazz==ShortBuffer.class) {
+          buffer = bb.asShortBuffer();
+      } else if(componentClazz==IntBuffer.class) {
+          buffer = bb.asIntBuffer();
+      } else if(componentClazz==FloatBuffer.class) {
+          buffer = bb.asFloatBuffer();
+      } else {
+          throw new GLException("Given Buffer Class not supported: "+componentClazz+":\n\t"+this);
+      }
+  }
+
+  public void unmapStorage(GL gl) {
+      if( null == mappedStorage ) {
+          throw new IllegalStateException("not mapped");
+      }
+      mappedStorage = null;
+      buffer = null;
+      seal(true);
+      bindBuffer(gl, true);
+      gl.glUnmapBuffer(getVBOTarget());
+      bindBuffer(gl, false);
+  }
+
   @Override
   public String toString() {
     return "GLArrayDataServer["+name+
@@ -423,9 +598,11 @@ public class GLArrayDataServer extends GLArrayDataClient implements GLArrayDataE
                        ", dataType 0x"+Integer.toHexString(componentType)+
                        ", bufferClazz "+componentClazz+
                        ", elements "+getElementCount()+
-                       ", components "+components+
+                       ", components "+componentsPerElement+
                        ", stride "+strideB+"b "+strideL+"c"+
                        ", initialElementCount "+initialElementCount+
+                       ", mappedElementCount "+mappedElementCount+
+                       ", mappedStorage "+mappedStorage+
                        ", vboEnabled "+vboEnabled+
                        ", vboName "+vboName+
                        ", vboUsage 0x"+Integer.toHexString(vboUsage)+
@@ -445,13 +622,13 @@ public class GLArrayDataServer extends GLArrayDataClient implements GLArrayDataE
 
   @Override
   protected void init(String name, int index, int comps, int dataType, boolean normalized,
-                      int stride, Buffer data, int initialElementCount, boolean isVertexAttribute,
-                      GLArrayHandler glArrayHandler,
-                      int vboName, long vboOffset, int vboUsage, int vboTarget, boolean usesGLSL)
+                      int stride, Buffer data, int initialElementCount, int mappedElementCount,
+                      boolean isVertexAttribute,
+                      GLArrayHandler glArrayHandler, int vboName, long vboOffset, int vboUsage, int vboTarget, boolean usesGLSL)
     throws GLException
   {
-    super.init(name, index, comps, dataType, normalized, stride, data, initialElementCount, isVertexAttribute, glArrayHandler,
-               vboName, vboOffset, vboUsage, vboTarget, usesGLSL);
+    super.init(name, index, comps, dataType, normalized, stride, data, initialElementCount, mappedElementCount, isVertexAttribute,
+               glArrayHandler, vboName, vboOffset, vboUsage, vboTarget, usesGLSL);
 
     vboEnabled=true;
   }
@@ -483,8 +660,10 @@ public class GLArrayDataServer extends GLArrayDataClient implements GLArrayDataE
   public GLArrayDataServer(GLArrayDataServer src) {
     super(src);
     this.interleavedOffset = src.interleavedOffset;
+    this.mappedStorage = src.mappedStorage;
   }
 
   private int interleavedOffset = 0;
+  private GLBufferStorage mappedStorage = null;
 }
 
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java
index 068ab52..f617fed 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java
@@ -71,8 +71,35 @@ public class GLArrayDataWrapper implements GLArrayData {
     throws GLException
   {
       GLArrayDataWrapper adc = new GLArrayDataWrapper();
-      adc.init(null, index, comps, dataType, normalized, stride, buffer, false,
-               vboName, vboOffset, vboUsage, vboTarget);
+      adc.init(null, index, comps, dataType, normalized, stride, buffer, 0 /* mappedElementCount */,
+               false, vboName, vboOffset, vboUsage, vboTarget);
+      return adc;
+  }
+
+  /**
+   * Create a VBO, using a predefined fixed function array index, wrapping the mapped data characteristics.
+   *
+   * @param index The GL array index
+   * @param comps The array component number
+   * @param dataType The array index GL data type
+   * @param normalized Whether the data shall be normalized
+   * @param stride
+   * @param mappedElementCount
+   * @param vboName
+   * @param vboOffset
+   * @param vboUsage {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW}
+   * @param vboTarget {@link GL#GL_ARRAY_BUFFER} or {@link GL#GL_ELEMENT_ARRAY_BUFFER}
+   * @return the new create instance
+   *
+   * @throws GLException
+   */
+  public static GLArrayDataWrapper createFixed(int index, int comps, int dataType, boolean normalized, int stride,
+                                               int mappedElementCount, int vboName, long vboOffset, int vboUsage, int vboTarget)
+    throws GLException
+  {
+      GLArrayDataWrapper adc = new GLArrayDataWrapper();
+      adc.init(null, index, comps, dataType, normalized, stride, null, mappedElementCount,
+               false, vboName, vboOffset, vboUsage, vboTarget);
       return adc;
   }
 
@@ -97,8 +124,34 @@ public class GLArrayDataWrapper implements GLArrayData {
     throws GLException
   {
       GLArrayDataWrapper adc = new GLArrayDataWrapper();
-      adc.init(name, -1, comps, dataType, normalized, stride, buffer, true,
-              vboName, vboOffset, vboUsage, vboTarget);
+      adc.init(name, -1, comps, dataType, normalized, stride, buffer, 0  /* mappedElementCount */,
+              true, vboName, vboOffset, vboUsage, vboTarget);
+      return adc;
+  }
+
+  /**
+   * Create a VBO, using a custom GLSL array attribute name, wrapping the mapped data characteristics.
+   *
+   * @param name  The custom name for the GL attribute, maybe null if gpuBufferTarget is {@link GL#GL_ELEMENT_ARRAY_BUFFER}
+   * @param comps The array component number
+   * @param dataType The array index GL data type
+   * @param normalized Whether the data shall be normalized
+   * @param stride
+   * @param mappedElementCount
+   * @param vboName
+   * @param vboOffset
+   * @param vboUsage {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW}
+   * @param vboTarget {@link GL#GL_ARRAY_BUFFER} or {@link GL#GL_ELEMENT_ARRAY_BUFFER}
+   * @return the new create instance
+   * @throws GLException
+   */
+  public static GLArrayDataWrapper createGLSL(String name, int comps, int dataType, boolean normalized, int stride,
+                                              int mappedElementCount, int vboName, long vboOffset, int vboUsage, int vboTarget)
+    throws GLException
+  {
+      GLArrayDataWrapper adc = new GLArrayDataWrapper();
+      adc.init(name, -1, comps, dataType, normalized, stride, null, mappedElementCount,
+              true, vboName, vboOffset, vboUsage, vboTarget);
       return adc;
   }
 
@@ -179,10 +232,10 @@ public class GLArrayDataWrapper implements GLArrayData {
   public final int getVBOTarget() { return vboEnabled?vboTarget:0; }
 
   @Override
-  public final Buffer getBuffer() { return buffer; }
+  public Buffer getBuffer() { return buffer; }
 
   @Override
-  public final int getComponentCount() { return components; }
+  public final int getComponentCount() { return componentsPerElement; }
 
   @Override
   public final int getComponentType() { return componentType; }
@@ -192,14 +245,25 @@ public class GLArrayDataWrapper implements GLArrayData {
 
   @Override
   public final int getElementCount() {
-    if(null==buffer) return 0;
-    return ( buffer.position()==0 ) ? ( buffer.limit() / components ) : ( buffer.position() / components ) ;
+    if( 0 != mappedElementCount ) {
+        return mappedElementCount;
+    } else if( null != buffer ) {
+        final int remainingComponents = ( 0 == buffer.position() ) ? buffer.limit() : buffer.position();
+        return ( remainingComponents * componentByteSize ) / strideB ;
+    } else {
+        return 0;
+    }
   }
 
   @Override
   public final int getSizeInBytes() {
-    if(null==buffer) return 0;
-    return ( buffer.position()==0 ) ? ( buffer.limit() * componentByteSize ) : ( buffer.position() * componentByteSize ) ;
+    if( 0 != mappedElementCount ) {
+        return mappedElementCount * componentsPerElement * componentByteSize ;
+    } else if( null != buffer ) {
+        return ( buffer.position()==0 ) ? ( buffer.limit() * componentByteSize ) : ( buffer.position() * componentByteSize ) ;
+    } else {
+        return 0;
+    }
   }
 
   @Override
@@ -228,8 +292,9 @@ public class GLArrayDataWrapper implements GLArrayData {
                        ", dataType 0x"+Integer.toHexString(componentType)+
                        ", bufferClazz "+componentClazz+
                        ", elements "+getElementCount()+
-                       ", components "+components+
+                       ", components "+componentsPerElement+
                        ", stride "+strideB+"b "+strideL+"c"+
+                       ", mappedElementCount "+mappedElementCount+
                        ", buffer "+buffer+
                        ", vboEnabled "+vboEnabled+
                        ", vboName "+vboName+
@@ -299,12 +364,14 @@ public class GLArrayDataWrapper implements GLArrayData {
       this.vboTarget = vboTarget;
   }
 
-  protected void init(String name, int index, int components, int componentType,
-                      boolean normalized, int stride, Buffer data,
-                      boolean isVertexAttribute,
-                      int vboName, long vboOffset, int vboUsage, int vboTarget)
+  protected void init(String name, int index, int componentsPerElement, int componentType,
+                      boolean normalized, int stride, Buffer data, int mappedElementCount,
+                      boolean isVertexAttribute, int vboName, long vboOffset, int vboUsage, int vboTarget)
     throws GLException
   {
+    if( 0<mappedElementCount && null != data ) {
+        throw new IllegalArgumentException("mappedElementCount:="+mappedElementCount+" specified, but passing non null buffer");
+    }
     this.isVertexAttribute = isVertexAttribute;
     this.index = index;
     this.location = -1;
@@ -333,19 +400,20 @@ public class GLArrayDataWrapper implements GLArrayData {
     if(0 > componentByteSize) {
         throw new GLException("Given componentType not supported: "+componentType+":\n\t"+this);
     }
-    if(0 >= components) {
-        throw new GLException("Invalid number of components: " + components);
+    if(0 >= componentsPerElement) {
+        throw new GLException("Invalid number of components: " + componentsPerElement);
     }
-    this.components = components;
+    this.componentsPerElement = componentsPerElement;
 
-    if(0<stride && stride<components*componentByteSize) {
-        throw new GLException("stride ("+stride+") lower than component bytes, "+components+" * "+componentByteSize);
+    if(0<stride && stride<componentsPerElement*componentByteSize) {
+        throw new GLException("stride ("+stride+") lower than component bytes, "+componentsPerElement+" * "+componentByteSize);
     }
     if(0<stride && stride%componentByteSize!=0) {
         throw new GLException("stride ("+stride+") not a multiple of bpc "+componentByteSize);
     }
     this.buffer = data;
-    this.strideB=(0==stride)?components*componentByteSize:stride;
+    this.mappedElementCount = mappedElementCount;
+    this.strideB=(0==stride)?componentsPerElement*componentByteSize:stride;
     this.strideL=strideB/componentByteSize;
     this.vboName= vboName;
     this.vboEnabled= 0 != vboName ;
@@ -389,7 +457,7 @@ public class GLArrayDataWrapper implements GLArrayData {
     this.index = src.index;
     this.location = src.location;
     this.name = src.name;
-    this.components = src.components;
+    this.componentsPerElement = src.componentsPerElement;
     this.componentType = src.componentType;
     this.componentClazz = src.componentClazz;
     this.componentByteSize = src.componentByteSize;
@@ -405,6 +473,7 @@ public class GLArrayDataWrapper implements GLArrayData {
     } else {
         this.buffer = null;
     }
+    this.mappedElementCount = src.mappedElementCount;
     this.isVertexAttribute = src.isVertexAttribute;
     this.vboOffset = src.vboOffset;
     this.vboName = src.vboName;
@@ -417,14 +486,17 @@ public class GLArrayDataWrapper implements GLArrayData {
   protected int index;
   protected int location;
   protected String name;
-  protected int components;
+  protected int componentsPerElement;
   protected int componentType;
   protected Class<?> componentClazz;
   protected int componentByteSize;
   protected boolean normalized;
-  protected int strideB; // stride in bytes
-  protected int strideL; // stride in logical components
+  /** stride in bytes; strideB >= componentsPerElement * componentByteSize */
+  protected int strideB;
+  /** stride in logical components */
+  protected int strideL;
   protected Buffer buffer;
+  protected int mappedElementCount;
   protected boolean isVertexAttribute;
   protected long vboOffset;
   protected int vboName;
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLPixelBuffer.java b/src/jogl/classes/com/jogamp/opengl/util/GLPixelBuffer.java
index 50124c3..a921a28 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLPixelBuffer.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLPixelBuffer.java
@@ -30,11 +30,15 @@ package com.jogamp.opengl.util;
 import java.nio.Buffer;
 import java.nio.ByteBuffer;
 
+import javax.media.nativewindow.util.PixelFormat;
 import javax.media.opengl.GL;
+import javax.media.opengl.GL2;
 import javax.media.opengl.GL2ES2;
 import javax.media.opengl.GL2ES3;
+import javax.media.opengl.GL2GL3;
 import javax.media.opengl.GLContext;
 import javax.media.opengl.GLException;
+import javax.media.opengl.GLProfile;
 
 import com.jogamp.common.nio.Buffers;
 import com.jogamp.opengl.util.texture.TextureData;
@@ -202,6 +206,56 @@ public class GLPixelBuffer {
         public GLPixelAttributes(int componentCount, int dataFormat, int dataType) {
             this(componentCount, dataFormat, dataType, true);
         }
+
+        /**
+         * Returns the matching {@link GLPixelAttributes} for the given {@link PixelFormat} and {@link GLProfile} if exists,
+         * otherwise returns <code>null</code>.
+         */
+        public static final GLPixelAttributes convert(PixelFormat pixFmt, GLProfile glp) {
+            int df = 0; // format
+            int dt = GL.GL_UNSIGNED_BYTE; // data type
+            switch(pixFmt) {
+                case LUMINANCE:
+                    if( glp.isGL3ES3() ) {
+                        // RED is supported on ES3 and >= GL3 [core]; ALPHA/LUMINANCE is deprecated on core
+                        df = GL2ES2.GL_RED;
+                    } else {
+                        // ALPHA/LUMINANCE is supported on ES2 and GL2, i.e. <= GL3 [core] or compatibility
+                        df = GL2ES2.GL_LUMINANCE;
+                    }
+                    break;
+                case BGR888:
+                    if( glp.isGL2GL3() ) {
+                        df = GL2GL3.GL_BGR;
+                    }
+                    break;
+                case RGB888:
+                    df = GL.GL_RGB;
+                    break;
+                case RGBA8888:
+                    df = GL.GL_RGBA;
+                    break;
+                case ABGR8888:
+                    if( glp.isGL2GL3() ) {
+                        df = GL.GL_RGBA; dt = GL2GL3.GL_UNSIGNED_INT_8_8_8_8;
+                    }
+                    break;
+                case BGRA8888:
+                    df = GL.GL_BGRA;
+                    break;
+                case ARGB8888:
+                    if( glp.isGL2GL3() ) {
+                        df = GL.GL_BGRA; dt = GL2GL3.GL_UNSIGNED_INT_8_8_8_8;
+                    }
+                    break;
+                default:
+                    break;
+            }
+            if( 0 != df ) {
+                return new GLPixelAttributes(pixFmt.componentCount, df, dt, true);
+            }
+            return null;
+        }
         private GLPixelAttributes(int componentCount, int dataFormat, int dataType, boolean checkArgs) {
             this.componentCount = componentCount;
             this.format = dataFormat;
@@ -216,6 +270,52 @@ public class GLPixelBuffer {
                 }
             }
         }
+
+        /**
+         * Returns the matching {@link PixelFormat} of this {@link GLPixelAttributes} if exists,
+         * otherwise returns <code>null</code>.
+         */
+        public final PixelFormat getPixelFormat() {
+            final PixelFormat pixFmt;
+            // FIXME: Take 'type' into consideration and complete mapping!
+            switch(format) {
+                case GL.GL_ALPHA:
+                case GL.GL_LUMINANCE:
+                case GL2ES2.GL_RED:
+                    pixFmt = PixelFormat.LUMINANCE;
+                    break;
+                case GL.GL_RGB:
+                    pixFmt = PixelFormat.RGB888;
+                    break;
+                case GL.GL_RGBA:
+                    pixFmt = PixelFormat.RGBA8888;
+                    break;
+                case GL2.GL_BGR:
+                    pixFmt = PixelFormat.BGR888;
+                    break;
+                case GL.GL_BGRA:
+                    pixFmt = PixelFormat.BGRA8888;
+                    break;
+                default:
+                    switch( bytesPerPixel ) {
+                        case 1:
+                            pixFmt = PixelFormat.LUMINANCE;
+                            break;
+                        case 3:
+                            pixFmt = PixelFormat.RGB888;
+                            break;
+                        case 4:
+                            pixFmt = PixelFormat.RGBA8888;
+                            break;
+                        default:
+                            pixFmt = null;
+                            break;
+                    }
+                    break;
+            }
+            return pixFmt;
+        }
+
         @Override
         public String toString() {
             return "PixelAttributes[comp "+componentCount+", fmt 0x"+Integer.toHexString(format)+", type 0x"+Integer.toHexString(type)+", bytesPerPixel "+bytesPerPixel+"]";
diff --git a/src/jogl/classes/com/jogamp/opengl/util/PNGPixelRect.java b/src/jogl/classes/com/jogamp/opengl/util/PNGPixelRect.java
new file mode 100644
index 0000000..1bbc12f
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/PNGPixelRect.java
@@ -0,0 +1,335 @@
+/**
+ * Copyright 2012 JogAmp Community. 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 JogAmp Community ``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 JogAmp Community OR
+ * 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package com.jogamp.opengl.util;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+
+import javax.media.nativewindow.util.Dimension;
+import javax.media.nativewindow.util.DimensionImmutable;
+import javax.media.nativewindow.util.PixelFormat;
+import javax.media.nativewindow.util.PixelRectangle;
+import javax.media.nativewindow.util.PixelFormatUtil;
+
+import jogamp.opengl.Debug;
+import jogamp.opengl.util.pngj.ImageInfo;
+import jogamp.opengl.util.pngj.ImageLine;
+import jogamp.opengl.util.pngj.ImageLineHelper;
+import jogamp.opengl.util.pngj.PngReader;
+import jogamp.opengl.util.pngj.PngWriter;
+import jogamp.opengl.util.pngj.chunks.PngChunkPLTE;
+import jogamp.opengl.util.pngj.chunks.PngChunkTRNS;
+import jogamp.opengl.util.pngj.chunks.PngChunkTextVar;
+
+import com.jogamp.common.nio.Buffers;
+import com.jogamp.common.util.IOUtil;
+
+public class PNGPixelRect extends PixelRectangle.GenericPixelRect {
+    private static final boolean DEBUG = Debug.debug("PNG");
+
+    /**
+     * Reads a PNG image from the specified InputStream.
+     * <p>
+     * Implicitly converts the image to match the desired:
+     * <ul>
+     *   <li>{@link PixelFormat}, see {@link #getPixelformat()}</li>
+     *   <li><code>destStrideInBytes</code>, see {@link #getStride()}</li>
+     *   <li><code>destIsGLOriented</code>, see {@link #isGLOriented()}</li>
+     * </ul>
+     * </p>
+     *
+     * @param in input stream
+     * @param destFmt desired destination {@link PixelFormat} incl. conversion, maybe <code>null</code> to use source {@link PixelFormat}
+     * @param destDirectBuffer if true, using a direct NIO buffer, otherwise an array backed buffer
+     * @param destMinStrideInBytes used if greater than PNG's stride, otherwise using PNG's stride. Stride is width * bytes-per-pixel.
+     * @param destIsGLOriented
+     * @return the newly created PNGPixelRect instance
+     * @throws IOException
+     */
+    public static PNGPixelRect read(final InputStream in,
+                                    final PixelFormat ddestFmt, final boolean destDirectBuffer, final int destMinStrideInBytes,
+                                    final boolean destIsGLOriented) throws IOException {
+        final PngReader pngr = new PngReader(new BufferedInputStream(in), null);
+        final ImageInfo imgInfo = pngr.imgInfo;
+        final PngChunkPLTE plte = pngr.getMetadata().getPLTE();
+        final PngChunkTRNS trns = pngr.getMetadata().getTRNS();
+        final boolean indexed = imgInfo.indexed;
+        final boolean hasAlpha = indexed ? ( trns != null ) : imgInfo.alpha ;
+
+        if(DEBUG) {
+            System.err.println("PNGPixelRect: "+imgInfo);
+        }
+        final int channels = indexed ? ( hasAlpha ? 4 : 3 ) : imgInfo.channels ;
+        final boolean isGrayAlpha = 2 == channels && imgInfo.greyscale && imgInfo.alpha;
+        if ( ! ( 1 == channels || 3 == channels || 4 == channels || isGrayAlpha ) ) {
+            throw new RuntimeException("PNGPixelRect can only handle Lum/RGB/RGBA [1/3/4 channels] or Lum+A (GA) images for now. Channels "+channels + " Paletted: " + indexed);
+        }
+        final int bytesPerPixel = indexed ? channels : imgInfo.bytesPixel ;
+        if ( ! ( 1 == bytesPerPixel || 3 == bytesPerPixel || 4 == bytesPerPixel || isGrayAlpha ) ) {
+            throw new RuntimeException("PNGPixelRect can only handle Lum/RGB/RGBA [1/3/4 bpp] images for now. BytesPerPixel "+bytesPerPixel);
+        }
+        if( channels != bytesPerPixel ) {
+            throw new RuntimeException("PNGPixelRect currently only handles Channels [1/3/4] == BytePerPixel [1/3/4], channels: "+channels+", bytesPerPixel "+bytesPerPixel);
+        }
+        final int width = imgInfo.cols;
+        final int height = imgInfo.rows;
+        final double dpiX, dpiY;
+        {
+            final double[] dpi = pngr.getMetadata().getDpi();
+            dpiX = dpi[0];
+            dpiY = dpi[1];
+        }
+        final PixelFormat srcFmt;
+        if ( indexed ) {
+            if ( hasAlpha ) {
+                srcFmt = PixelFormat.RGBA8888;
+            } else {
+                srcFmt = PixelFormat.RGB888;
+            }
+        } else {
+            switch( channels ) {
+                case 1: srcFmt = PixelFormat.LUMINANCE; break;
+                case 2: srcFmt = isGrayAlpha ? PixelFormat.LUMINANCE : null; break;
+                case 3: srcFmt = PixelFormat.RGB888; break;
+                case 4: srcFmt = PixelFormat.RGBA8888; break;
+                default: srcFmt = null;
+            }
+            if( null == srcFmt ) {
+                throw new InternalError("XXX: channels: "+channels+", bytesPerPixel "+bytesPerPixel);
+            }
+        }
+        final PixelFormat destFmt;
+        if( null == ddestFmt ) {
+            if( isGrayAlpha ) {
+                destFmt = PixelFormat.BGRA8888; // save alpha value on gray-alpha
+            } else {
+                destFmt = srcFmt; // 1:1
+            }
+        } else {
+            destFmt = ddestFmt; // user choice
+        }
+        final int destStrideInBytes = Math.max(destMinStrideInBytes, destFmt.bytesPerPixel() * width);
+        final ByteBuffer destPixels = destDirectBuffer ? Buffers.newDirectByteBuffer(destStrideInBytes * height) :
+                                                         ByteBuffer.allocate(destStrideInBytes * height);
+        {
+            final int reqBytes = destStrideInBytes * height;
+            if( destPixels.limit() < reqBytes ) {
+                throw new IndexOutOfBoundsException("Dest buffer has insufficient bytes left, needs "+reqBytes+": "+destPixels);
+            }
+        }
+        final boolean vert_flip = destIsGLOriented;
+
+        int[] rgbaScanline = indexed ? new int[width * channels] : null;
+        if(DEBUG) {
+            System.err.println("PNGPixelRect: indexed "+indexed+", alpha "+hasAlpha+", grayscale "+imgInfo.greyscale+", channels "+channels+"/"+imgInfo.channels+
+                               ", bytesPerPixel "+bytesPerPixel+"/"+imgInfo.bytesPixel+
+                               ", grayAlpha "+isGrayAlpha+", pixels "+width+"x"+height+", dpi "+dpiX+"x"+dpiY+", format "+srcFmt);
+            System.err.println("PNGPixelRect: destFormat "+destFmt+" ("+ddestFmt+", bytesPerPixel "+destFmt.bytesPerPixel()+", fast-path "+(destFmt==srcFmt)+"), destDirectBuffer "+destDirectBuffer+", destIsGLOriented (flip) "+destIsGLOriented);
+            System.err.println("PNGPixelRect: destStrideInBytes "+destStrideInBytes+" (destMinStrideInBytes "+destMinStrideInBytes+")");
+        }
+
+        for (int row = 0; row < height; row++) {
+            final ImageLine l1 = pngr.readRow(row);
+            int lineOff = 0;
+            int dataOff = vert_flip ? ( height - 1 - row ) * destStrideInBytes : row * destStrideInBytes;
+            if( indexed ) {
+                for (int j = width - 1; j >= 0; j--) {
+                    rgbaScanline = ImageLineHelper.palette2rgb(l1, plte, trns, rgbaScanline); // reuse rgbaScanline and update if resized
+                    dataOff = getPixelRGBA8ToAny(destFmt, destPixels, dataOff, rgbaScanline, lineOff, hasAlpha);
+                    lineOff += bytesPerPixel;
+                }
+            } else if( 1 == channels ) {
+                for (int j = width - 1; j >= 0; j--) {
+                    dataOff = getPixelLUMToAny(destFmt, destPixels, dataOff, (byte)l1.scanline[lineOff++], (byte)0xff); // Luminance, 1 bytesPerPixel
+                }
+            } else if( isGrayAlpha ) {
+                for (int j = width - 1; j >= 0; j--) {
+                    dataOff = getPixelLUMToAny(destFmt, destPixels, dataOff, (byte)l1.scanline[lineOff++], (byte)l1.scanline[lineOff++]); // Luminance+Alpha, 2 bytesPerPixel
+                }
+            } else if( srcFmt == destFmt ) { // fast-path
+                for (int j = width - 1; j >= 0; j--) {
+                    dataOff = getPixelRGBSame(destPixels, dataOff, l1.scanline, lineOff, bytesPerPixel);
+                    lineOff += bytesPerPixel;
+                }
+            } else {
+                for (int j = width - 1; j >= 0; j--) {
+                    dataOff = getPixelRGBA8ToAny(destFmt, destPixels, dataOff, l1.scanline, lineOff, hasAlpha);
+                    lineOff += bytesPerPixel;
+                }
+            }
+        }
+        pngr.end();
+
+        return new PNGPixelRect(destFmt, new Dimension(width, height), destStrideInBytes, destIsGLOriented, destPixels, dpiX, dpiY);
+    }
+
+    private static final int getPixelLUMToAny(PixelFormat dest_fmt, ByteBuffer d, int dOff, byte lum, byte alpha) {
+        switch(dest_fmt) {
+            case LUMINANCE:
+                d.put(dOff++, lum);
+                break;
+            case BGR888:
+            case RGB888:
+                d.put(dOff++, lum);
+                d.put(dOff++, lum);
+                d.put(dOff++, lum);
+                break;
+            case ABGR8888:
+            case ARGB8888:
+                d.put(dOff++, alpha); // A
+                d.put(dOff++, lum);
+                d.put(dOff++, lum);
+                d.put(dOff++, lum);
+                break;
+            case BGRA8888:
+            case RGBA8888:
+                d.put(dOff++, lum);
+                d.put(dOff++, lum);
+                d.put(dOff++, lum);
+                d.put(dOff++, alpha); // A
+                break;
+            default:
+                throw new InternalError("Unhandled format "+dest_fmt);
+        }
+        return dOff;
+    }
+    private static final int getPixelRGBA8ToAny(final PixelFormat dest_fmt, final ByteBuffer d, int dOff, final int[] scanline, final int lineOff, final boolean srcHasAlpha) {
+        final int p = PixelFormatUtil.convertToInt32(dest_fmt, (byte)scanline[lineOff],   // R
+                                                               (byte)scanline[lineOff+1], // G
+                                                               (byte)scanline[lineOff+2], // B
+                                                               srcHasAlpha ? (byte)scanline[lineOff+3] : (byte)0xff); // A
+        final int dbpp = dest_fmt.bytesPerPixel();
+        d.put(dOff++, (byte) ( p ));                // 1
+        if( 1 < dbpp ) {
+            d.put(dOff++, (byte) ( p >>>  8 ));     // 2
+            d.put(dOff++, (byte) ( p >>> 16 ));     // 3
+            if( 4 == dbpp ) {
+                d.put(dOff++, (byte) ( p >>> 24 )); // 4
+            }
+        }
+        return dOff;
+    }
+    private static final int getPixelRGBSame(final ByteBuffer d, int dOff, final int[] scanline, final int lineOff, final int bpp) {
+        d.put(dOff++, (byte)scanline[lineOff]);             // R
+        if( 1 < bpp ) {
+            d.put(dOff++, (byte)scanline[lineOff + 1]);     // G
+            d.put(dOff++, (byte)scanline[lineOff + 2]);     // B
+            if( 4 == bpp ) {
+                d.put(dOff++, (byte)scanline[lineOff + 3]); // A
+            }
+        }
+        return dOff;
+    }
+    private int setPixelRGBA8(final ImageLine line, final int lineOff, final ByteBuffer d, final int dOff, final int bytesPerPixel, final boolean hasAlpha) {
+        final int b = hasAlpha ? 4-1 : 3-1;
+        if( d.limit() <= dOff + b ) {
+            throw new IndexOutOfBoundsException("Buffer has unsufficient bytes left, needs ["+dOff+".."+(dOff+b)+"]: "+d);
+        }
+        final int p = PixelFormatUtil.convertToInt32(hasAlpha ? PixelFormat.RGBA8888 : PixelFormat.RGB888, pixelformat, d, dOff);
+        line.scanline[lineOff    ] = 0xff &   p;              // R
+        line.scanline[lineOff + 1] = 0xff & ( p >>> 8 );      // G
+        line.scanline[lineOff + 2] = 0xff & ( p >>> 16 );     // B
+        if(hasAlpha) {
+            line.scanline[lineOff + 3] = 0xff & ( p >>> 24 ); // A
+        }
+        return dOff + pixelformat.bytesPerPixel();
+    }
+
+    /**
+     * Creates a PNGPixelRect from data supplied by the end user. Shares
+     * data with the passed ByteBuffer.
+     *
+     * @param pixelformat
+     * @param size
+     * @param strideInBytes
+     * @param isGLOriented see {@link #isGLOriented()}.
+     * @param pixels
+     * @param dpiX
+     * @param dpiY
+     */
+    public PNGPixelRect(final PixelFormat pixelformat, final DimensionImmutable size,
+                        final int strideInBytes, final boolean isGLOriented, final ByteBuffer pixels,
+                        final double dpiX, final double dpiY) {
+        super(pixelformat, size, strideInBytes, isGLOriented, pixels);
+        this.dpi = new double[] { dpiX, dpiY };
+    }
+    public PNGPixelRect(final PixelRectangle src, final double dpiX, final double dpiY) {
+        super(src);
+        this.dpi = new double[] { dpiX, dpiY };
+    }
+    private final double[] dpi;
+
+    /** Returns the dpi of the image. */
+    public double[] getDpi() { return dpi; }
+
+    public void write(final OutputStream outstream, final boolean closeOutstream) throws IOException {
+        final int width = size.getWidth();
+        final int height = size.getHeight();
+        final int bytesPerPixel = pixelformat.bytesPerPixel();
+        final ImageInfo imi = new ImageInfo(width, height, 8 /* bitdepth */,
+                                            (4 == bytesPerPixel) ? true : false /* alpha */,
+                                            (1 == bytesPerPixel) ? true : false /* grayscale */,
+                                            false /* indexed */);
+
+        // open image for writing to a output stream
+        try {
+            final PngWriter png = new PngWriter(outstream, imi);
+            // add some optional metadata (chunks)
+            png.getMetadata().setDpi(dpi[0], dpi[1]);
+            png.getMetadata().setTimeNow(0); // 0 seconds fron now = now
+            png.getMetadata().setText(PngChunkTextVar.KEY_Title, "JogAmp PNGPixelRect");
+            // png.getMetadata().setText("my key", "my text");
+            final boolean hasAlpha = 4 == bytesPerPixel;
+
+            final ImageLine l1 = new ImageLine(imi);
+            for (int row = 0; row < height; row++) {
+                int dataOff = isGLOriented ? ( height - 1 - row ) * strideInBytes : row * strideInBytes;
+                int lineOff = 0;
+                if(1 == bytesPerPixel) {
+                    for (int j = width - 1; j >= 0; j--) {
+                        l1.scanline[lineOff++] = pixels.get(dataOff++); // // Luminance, 1 bytesPerPixel
+                    }
+                } else {
+                    for (int j = width - 1; j >= 0; j--) {
+                        dataOff = setPixelRGBA8(l1, lineOff, pixels, dataOff, bytesPerPixel, hasAlpha);
+                        lineOff += bytesPerPixel;
+                    }
+                }
+                png.writeRow(l1, row);
+            }
+            png.end();
+        } finally {
+            if( closeOutstream ) {
+                IOUtil.close(outstream, false);
+            }
+        }
+    }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java b/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java
index 22a5cfb..9957f20 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java
@@ -391,7 +391,7 @@ public interface GLMediaPlayer extends TextureSequence {
     public AudioSink getAudioSink();
 
     /**
-     * Releases the GL and stream resources.
+     * Releases the GL, stream and other resources, including {@link #attachObject(String, Object) attached user objects}.
      * <p>
      * <a href="#lifecycle">Lifecycle</a>: <code>ANY</code> -> {@link State#Uninitialized}
      * </p>
@@ -626,4 +626,22 @@ public interface GLMediaPlayer extends TextureSequence {
 
     /** Return all {@link GLMediaEventListener} of this player. */
     public GLMediaEventListener[] getEventListeners();
+
+    /**
+     * Returns the attached user object for the given name.
+     */
+    public Object getAttachedObject(String name);
+
+    /**
+     * Attaches the user object for the given name.
+     * Returns the previously set object, may be null.
+     */
+    public Object attachObject(String name, Object obj);
+
+    /**
+     * Detaches the user object for the given name.
+     * Returns the previously set object, may be null.
+     */
+    public Object detachObject(String name);
+
 }
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java
index 67ab517..0cde24d 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java
@@ -41,10 +41,12 @@
 package com.jogamp.opengl.util.texture;
 
 import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.OutputStream;
 import java.net.URL;
 import java.nio.Buffer;
 import java.nio.ByteBuffer;
@@ -52,9 +54,10 @@ import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 
+import javax.media.nativewindow.util.Dimension;
+import javax.media.nativewindow.util.PixelFormat;
 import javax.media.opengl.GL;
 import javax.media.opengl.GL2;
-import javax.media.opengl.GL2ES2;
 import javax.media.opengl.GL2GL3;
 import javax.media.opengl.GLContext;
 import javax.media.opengl.GLException;
@@ -63,11 +66,11 @@ import javax.media.opengl.GLProfile;
 import jogamp.opengl.Debug;
 
 import com.jogamp.common.util.IOUtil;
+import com.jogamp.opengl.util.PNGPixelRect;
 import com.jogamp.opengl.util.GLPixelBuffer.GLPixelAttributes;
 import com.jogamp.opengl.util.texture.spi.DDSImage;
 import com.jogamp.opengl.util.texture.spi.JPEGImage;
 import com.jogamp.opengl.util.texture.spi.NetPbmTextureWriter;
-import com.jogamp.opengl.util.texture.spi.PNGImage;
 import com.jogamp.opengl.util.texture.spi.SGIImage;
 import com.jogamp.opengl.util.texture.spi.TGAImage;
 import com.jogamp.opengl.util.texture.spi.TextureProvider;
@@ -1166,27 +1169,29 @@ public class TextureIO {
                                           boolean mipmap,
                                           String fileSuffix) throws IOException {
             if (PNG.equals(fileSuffix)) {
-                PNGImage image = PNGImage.read(/*glp, */ stream);
-                if (pixelFormat == 0) {
-                    pixelFormat = image.getGLFormat();
-                }
-                if (internalFormat == 0) {
+                final PNGPixelRect image = PNGPixelRect.read(stream, null, true /* directBuffer */, 0 /* destMinStrideInBytes */, true /* destIsGLOriented */);
+                final GLPixelAttributes glpa = GLPixelAttributes.convert(image.getPixelformat(), glp);
+                if ( 0 == pixelFormat ) {
+                    pixelFormat = glpa.format;
+                }  // else FIXME: Actually not supported w/ preset pixelFormat!
+                if ( 0 == internalFormat ) {
+                    final boolean hasAlpha = 4 == glpa.bytesPerPixel;
                     if(glp.isGL2ES3()) {
-                        internalFormat = (image.getBytesPerPixel()==4)?GL.GL_RGBA8:GL.GL_RGB8;
+                        internalFormat = hasAlpha ? GL.GL_RGBA8 : GL.GL_RGB8;
                     } else {
-                        internalFormat = (image.getBytesPerPixel()==4)?GL.GL_RGBA:GL.GL_RGB;
+                        internalFormat = hasAlpha ? GL.GL_RGBA : GL.GL_RGB;
                     }
                 }
                 return new TextureData(glp, internalFormat,
-                                       image.getWidth(),
-                                       image.getHeight(),
+                                       image.getSize().getWidth(),
+                                       image.getSize().getHeight(),
                                        0,
                                        pixelFormat,
-                                       image.getGLType(),
+                                       glpa.type,
                                        mipmap,
                                        false,
                                        false,
-                                       image.getData(),
+                                       image.getPixels(),
                                        null);
             }
 
@@ -1392,29 +1397,7 @@ public class TextureIO {
                 final int pixelFormat = pixelAttribs.format;
                 final int pixelType   = pixelAttribs.type;
                 final int bytesPerPixel = pixelAttribs.bytesPerPixel;
-                final boolean reversedChannels;
-                switch(pixelFormat) {
-                    case GL.GL_ALPHA:
-                    case GL.GL_LUMINANCE:
-                    case GL2ES2.GL_RED:
-                        reversedChannels=false;
-                        break;
-                    case GL.GL_RGB:
-                        reversedChannels=false;
-                        break;
-                    case GL.GL_RGBA:
-                        reversedChannels=false;
-                        break;
-                    case GL2.GL_BGR:
-                        reversedChannels=true;
-                        break;
-                    case GL.GL_BGRA:
-                        reversedChannels=true;
-                        break;
-                    default:
-                        reversedChannels=false;
-                        break;
-                }
+                final PixelFormat pixFmt = pixelAttribs.getPixelFormat();
                 if ( ( 1 == bytesPerPixel || 3 == bytesPerPixel || 4 == bytesPerPixel) &&
                      ( pixelType == GL.GL_BYTE || pixelType == GL.GL_UNSIGNED_BYTE)) {
                     ByteBuffer buf = (ByteBuffer) data.getBuffer();
@@ -1423,9 +1406,11 @@ public class TextureIO {
                     }
                     buf.rewind();
 
-                    PNGImage image = PNGImage.createFromData(data.getWidth(), data.getHeight(), -1f, -1f,
-                                                             bytesPerPixel, reversedChannels, !data.getMustFlipVertically(), buf);
-                    image.write(file, true);
+                    final PNGPixelRect image = new PNGPixelRect(pixFmt, new Dimension(data.getWidth(), data.getHeight()),
+                                                                0 /* stride */, true /* isGLOriented */, buf /* pixels */,
+                                                                -1f, -1f);
+                    final OutputStream outs = new BufferedOutputStream(IOUtil.getFileOutputStream(file, true /* allowOverwrite */));
+                    image.write(outs, true /* close */);
                     return true;
                 }
                 throw new IOException("PNG writer doesn't support this pixel format 0x"+Integer.toHexString(pixelFormat)+
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/DDSImage.java b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/DDSImage.java
index d75bb37..7311f20 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/DDSImage.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/DDSImage.java
@@ -766,6 +766,8 @@ public class DDSImage {
 
         // Now check the mipmaps against this size
         int curSize = topmostMipmapSize;
+        int mipmapWidth = width;
+        int mipmapHeight = height;
         int totalSize = 0;
         for (int i = 0; i < mipmapData.length; i++) {
             if (mipmapData[i].remaining() != curSize) {
@@ -773,7 +775,10 @@ public class DDSImage {
                                                    " didn't match expected data size (expected " + curSize + ", got " +
                                                    mipmapData[i].remaining() + ")");
             }
-            curSize /= 4;
+            // Compute next mipmap size
+            if (mipmapWidth > 1) mipmapWidth /= 2;
+            if (mipmapHeight > 1) mipmapHeight /= 2;
+            curSize = computeBlockSize(mipmapWidth, mipmapHeight, 1, d3dFormat);
             totalSize += mipmapData[i].remaining();
         }
 
@@ -852,6 +857,32 @@ public class DDSImage {
         return blockSize;
     }
 
+    private static int computeBlockSize(int width,
+                                        int height,
+                                        int depth,
+                                        int pixelFormat) {
+        int blocksize;
+        switch (pixelFormat) {
+        case D3DFMT_R8G8B8:
+            blocksize = width*height*3;
+            break;
+        case D3DFMT_A8R8G8B8:
+        case D3DFMT_X8R8G8B8:
+            blocksize = width*height*4;
+            break;
+        case D3DFMT_DXT1:
+        case D3DFMT_DXT2:
+        case D3DFMT_DXT3:
+        case D3DFMT_DXT4:
+        case D3DFMT_DXT5:
+            blocksize = computeCompressedBlockSize(width, height, 1, pixelFormat);
+            break;
+        default:
+            throw new IllegalArgumentException("d3dFormat must be one of the known formats");
+        }
+        return blocksize;
+    }
+
     private int mipMapWidth(int map) {
         int width = getWidth();
         for (int i = 0; i < map; i++) {
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/PNGImage.java b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/PNGImage.java
deleted file mode 100644
index 71cbbf9..0000000
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/PNGImage.java
+++ /dev/null
@@ -1,319 +0,0 @@
-/**
- * Copyright 2012 JogAmp Community. 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 JogAmp Community ``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 JogAmp Community OR
- * 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.
- *
- * The views and conclusions contained in the software and documentation are those of the
- * authors and should not be interpreted as representing official policies, either expressed
- * or implied, of JogAmp Community.
- */
-package com.jogamp.opengl.util.texture.spi;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.ByteBuffer;
-
-import javax.media.opengl.GL;
-
-import jogamp.opengl.Debug;
-import jogamp.opengl.util.pngj.ImageInfo;
-import jogamp.opengl.util.pngj.ImageLine;
-import jogamp.opengl.util.pngj.ImageLineHelper;
-import jogamp.opengl.util.pngj.PngReader;
-import jogamp.opengl.util.pngj.PngWriter;
-import jogamp.opengl.util.pngj.chunks.PngChunkPLTE;
-import jogamp.opengl.util.pngj.chunks.PngChunkTRNS;
-import jogamp.opengl.util.pngj.chunks.PngChunkTextVar;
-
-import com.jogamp.common.nio.Buffers;
-import com.jogamp.common.util.IOUtil;
-
-public class PNGImage {
-    private static final boolean DEBUG = Debug.debug("PNGImage");
-
-    /**
-     * Creates a PNGImage from data supplied by the end user. Shares
-     * data with the passed ByteBuffer. Assumes the data is already in
-     * the correct byte order for writing to disk, i.e., LUMINANCE, RGB or RGBA.
-     * Orientation is <i>bottom-to-top</i> (OpenGL coord. default)
-     * or <i>top-to-bottom</i> depending on <code>isGLOriented</code>.
-     *
-     * @param width
-     * @param height
-     * @param dpiX
-     * @param dpiY
-     * @param bytesPerPixel
-     * @param reversedChannels
-     * @param isGLOriented see {@link #isGLOriented()}.
-     * @param data
-     * @return
-     */
-    public static PNGImage createFromData(int width, int height, double dpiX, double dpiY,
-                                          int bytesPerPixel, boolean reversedChannels, boolean isGLOriented, ByteBuffer data) {
-        return new PNGImage(width, height, dpiX, dpiY, bytesPerPixel, reversedChannels, isGLOriented, data);
-    }
-
-    /**
-     * Reads a PNG image from the specified InputStream.
-     * <p>
-     * Implicitly flip image to GL orientation, see {@link #isGLOriented()}.
-     * </p>
-     */
-    public static PNGImage read(InputStream in) throws IOException {
-        return new PNGImage(in);
-    }
-
-    /** Reverse read and store, implicitly flip image to GL orientation, see {@link #isGLOriented()}. */
-    private static final int getPixelRGBA8(ByteBuffer d, int dOff, int[] scanline, int lineOff, boolean hasAlpha) {
-        final int b = hasAlpha ? 4-1 : 3-1;
-        if( d.limit() <= dOff || dOff - b < 0 ) {
-            throw new IndexOutOfBoundsException("Buffer has unsufficient bytes left, needs ["+(dOff-b)+".."+dOff+"]: "+d);
-        }
-    	if(hasAlpha) {
-            d.put(dOff--, (byte)scanline[lineOff + 3]); // A
-        }
-        d.put(dOff--, (byte)scanline[lineOff + 2]); // B
-        d.put(dOff--, (byte)scanline[lineOff + 1]); // G
-        d.put(dOff--, (byte)scanline[lineOff    ]); // R
-        return dOff;
-    }
-
-    /** Reverse write and store, implicitly flip image from current orientation, see {@link #isGLOriented()}. Handle reversed channels (BGR[A]). */
-    private int setPixelRGBA8(ImageLine line, int lineOff, ByteBuffer d, int dOff, boolean hasAlpha) {
-        final int b = hasAlpha ? 4-1 : 3-1;
-        if( d.limit() <= dOff + b ) {
-            throw new IndexOutOfBoundsException("Buffer has unsufficient bytes left, needs ["+dOff+".."+(dOff+b)+"]: "+d);
-        }
-        if( reversedChannels ) {
-            if(hasAlpha) {
-                line.scanline[lineOff + 3] = d.get(dOff++); // A
-            }
-            line.scanline[lineOff + 2] = d.get(dOff++); // R
-            line.scanline[lineOff + 1] = d.get(dOff++); // G
-            line.scanline[lineOff    ] = d.get(dOff++); // B
-        } else {
-            line.scanline[lineOff    ] = d.get(dOff++); // R
-            line.scanline[lineOff + 1] = d.get(dOff++); // G
-            line.scanline[lineOff + 2] = d.get(dOff++); // B
-            if(hasAlpha) {
-                line.scanline[lineOff + 3] = d.get(dOff++); // A
-            }
-        }
-        return isGLOriented ? dOff - bytesPerPixel - bytesPerPixel : dOff;
-    }
-
-    private PNGImage(int width, int height, double dpiX, double dpiY, int bytesPerPixel, boolean reversedChannels, boolean isGLOriented, ByteBuffer data) {
-        pixelWidth=width;
-        pixelHeight=height;
-        dpi = new double[] { dpiX, dpiY };
-        if(4 == bytesPerPixel) {
-            glFormat = GL.GL_RGBA;
-        } else if (3 == bytesPerPixel) {
-            glFormat = GL.GL_RGB;
-        } else {
-            throw new InternalError("XXX: bytesPerPixel "+bytesPerPixel);
-        }
-        this.bytesPerPixel = bytesPerPixel;
-        this.reversedChannels = reversedChannels;
-        this.isGLOriented = isGLOriented;
-        this.data = data;
-    }
-
-    private PNGImage(InputStream in) {
-        final PngReader pngr = new PngReader(new BufferedInputStream(in), null);
-        final ImageInfo imgInfo = pngr.imgInfo;
-        final PngChunkPLTE plte = pngr.getMetadata().getPLTE();
-        final PngChunkTRNS trns = pngr.getMetadata().getTRNS();
-        final boolean indexed = imgInfo.indexed;
-        final boolean hasAlpha = indexed ? ( trns != null ) : imgInfo.alpha ;
-
-        final int channels = indexed ? ( hasAlpha ? 4 : 3 ) : imgInfo.channels ;
-        if ( ! ( 1 == channels || 3 == channels || 4 == channels ) ) {
-            throw new RuntimeException("PNGImage can only handle Lum/RGB/RGBA [1/3/4 channels] images for now. Channels "+channels + " Paletted: " + indexed);
-        }
-
-        bytesPerPixel = indexed ? channels : imgInfo.bytesPixel ;
-        if ( ! ( 1 == bytesPerPixel || 3 == bytesPerPixel || 4 == bytesPerPixel ) ) {
-            throw new RuntimeException("PNGImage can only handle Lum/RGB/RGBA [1/3/4 bpp] images for now. BytesPerPixel "+bytesPerPixel);
-        }
-        if( channels != bytesPerPixel ) {
-            throw new RuntimeException("PNGImage currently only handles Channels [1/3/4] == BytePerPixel [1/3/4], channels: "+channels+", bytesPerPixel "+bytesPerPixel);
-        }
-        pixelWidth = imgInfo.cols;
-        pixelHeight = imgInfo.rows;
-        dpi = new double[2];
-        {
-            final double[] dpi2 = pngr.getMetadata().getDpi();
-            dpi[0]=dpi2[0];
-            dpi[1]=dpi2[1];
-        }
-        if ( indexed ) {
-        	if ( hasAlpha ) {
-        		glFormat = GL.GL_RGBA;
-        	} else {
-        		glFormat = GL.GL_RGB;
-        	}
-        } else {
-        	switch( channels ) {
-                case 1: glFormat = GL.GL_LUMINANCE; break;
-                case 3: glFormat = GL.GL_RGB; break;
-                case 4: glFormat = GL.GL_RGBA; break;
-                default: throw new InternalError("XXX: channels: "+channels+", bytesPerPixel "+bytesPerPixel);
-            }
-        }
-        if(DEBUG) {
-            System.err.println("PNGImage: "+imgInfo);
-            System.err.println("PNGImage: indexed "+indexed+", alpha "+hasAlpha+", channels "+channels+"/"+imgInfo.channels+
-                               ", bytesPerPixel "+bytesPerPixel+"/"+imgInfo.bytesPixel+
-                               ", pixels "+pixelWidth+"x"+pixelHeight+", dpi "+dpi[0]+"x"+dpi[1]+", glFormat 0x"+Integer.toHexString(glFormat));
-        }
-
-        data = Buffers.newDirectByteBuffer(bytesPerPixel * pixelWidth * pixelHeight);
-        reversedChannels = false; // RGB[A]
-        isGLOriented = true;
-        int dataOff = bytesPerPixel * pixelWidth * pixelHeight - 1; // start at end-of-buffer, reverse store
-
-        int[] rgbaScanline = indexed ? new int[imgInfo.cols * channels] : null;
-
-        for (int row = 0; row < pixelHeight; row++) {
-            final ImageLine l1 = pngr.readRow(row);
-            int lineOff = ( pixelWidth - 1 ) * bytesPerPixel ; // start w/ last pixel in line, reverse read (PNG top-left -> OpenGL bottom-left origin)
-            if( indexed ) {
-                for (int j = pixelWidth - 1; j >= 0; j--) {
-                    rgbaScanline = ImageLineHelper.palette2rgb(l1, plte, trns, rgbaScanline); // reuse rgbaScanline and update if resized
-                    dataOff = getPixelRGBA8(data, dataOff, rgbaScanline, lineOff, hasAlpha);
-                    lineOff -= bytesPerPixel;
-                }
-            } else if( 1 == channels ) {
-                for (int j = pixelWidth - 1; j >= 0; j--) {
-                    data.put(dataOff--, (byte)l1.scanline[lineOff--]); // Luminance, 1 bytesPerPixel
-                }
-            } else {
-                for (int j = pixelWidth - 1; j >= 0; j--) {
-            		dataOff = getPixelRGBA8(data, dataOff, l1.scanline, lineOff, hasAlpha);
-                    lineOff -= bytesPerPixel;
-                }
-            }
-        }
-        pngr.end();
-    }
-    private final int pixelWidth, pixelHeight, glFormat, bytesPerPixel;
-    private final boolean reversedChannels;
-    private final boolean isGLOriented;
-    private final double[] dpi;
-    private final ByteBuffer data;
-
-    /** Returns the width of the image. */
-    public int getWidth()    { return pixelWidth; }
-
-    /** Returns the height of the image. */
-    public int getHeight()   { return pixelHeight; }
-
-    /** Returns true if data has the channels reversed to BGR or BGRA, otherwise RGB or RGBA is expected. */
-    public boolean getHasReversedChannels() { return reversedChannels; }
-
-    /**
-     * Returns <code>true</code> if the drawable is rendered in
-     * OpenGL's coordinate system, <i>origin at bottom left</i>.
-     * Otherwise returns <code>false</code>, i.e. <i>origin at top left</i>.
-     * <p>
-     * Default impl. is <code>true</code>, i.e. OpenGL coordinate system.
-     * </p>
-     */
-    public boolean isGLOriented() { return isGLOriented; }
-
-    /** Returns the dpi of the image. */
-    public double[] getDpi() { return dpi; }
-
-    /** Returns the OpenGL format for this texture; e.g. GL.GL_LUMINANCE, GL.GL_RGB or GL.GL_RGBA. */
-    public int getGLFormat() { return glFormat; }
-
-    /** Returns the OpenGL data type: GL.GL_UNSIGNED_BYTE. */
-    public int getGLType() { return GL.GL_UNSIGNED_BYTE; }
-
-    /** Returns the bytes per pixel */
-    public int getBytesPerPixel() { return bytesPerPixel; }
-
-    /** Returns the raw data for this texture in the correct
-        (bottom-to-top) order for calls to glTexImage2D. */
-    public ByteBuffer getData()  { return data; }
-
-    public void write(File out, boolean allowOverwrite) throws IOException {
-        final ImageInfo imi = new ImageInfo(pixelWidth, pixelHeight, 8, (4 == bytesPerPixel) ? true : false); // 8 bits per channel, no alpha
-        // open image for writing to a output stream
-        final OutputStream outs = new BufferedOutputStream(IOUtil.getFileOutputStream(out, allowOverwrite));
-        try {
-            final PngWriter png = new PngWriter(outs, imi);
-            // add some optional metadata (chunks)
-            png.getMetadata().setDpi(dpi[0], dpi[1]);
-            png.getMetadata().setTimeNow(0); // 0 seconds fron now = now
-            png.getMetadata().setText(PngChunkTextVar.KEY_Title, "JogAmp PNGImage");
-            // png.getMetadata().setText("my key", "my text");
-            final boolean hasAlpha = 4 == bytesPerPixel;
-            final ImageLine l1 = new ImageLine(imi);
-            if( isGLOriented ) {
-                // start at last pixel at end-of-buffer, reverse read (OpenGL bottom-left -> PNG top-left origin)
-                int dataOff = ( pixelWidth * bytesPerPixel * ( pixelHeight - 1 ) ) + // full lines - 1 line
-                              ( ( pixelWidth - 1 ) * bytesPerPixel );                // one line - 1 pixel
-                for (int row = 0; row < pixelHeight; row++) {
-                    int lineOff = ( pixelWidth - 1 ) * bytesPerPixel ; // start w/ last pixel in line, reverse store (OpenGL bottom-left -> PNG top-left origin)
-                    if(1 == bytesPerPixel) {
-                        for (int j = pixelWidth - 1; j >= 0; j--) {
-                            l1.scanline[lineOff--] = data.get(dataOff--); // // Luminance, 1 bytesPerPixel
-                        }
-                    } else {
-                        for (int j = pixelWidth - 1; j >= 0; j--) {
-                            dataOff = setPixelRGBA8(l1, lineOff, data, dataOff, hasAlpha);
-                            lineOff -= bytesPerPixel;
-                        }
-                    }
-                    png.writeRow(l1, row);
-                }
-            } else {
-                int dataOff = 0; // start at first pixel at start-of-buffer, normal read (same origin: top-left)
-                for (int row = 0; row < pixelHeight; row++) {
-                    int lineOff = 0; // start w/ first pixel in line, normal store (same origin: top-left)
-                    if(1 == bytesPerPixel) {
-                        for (int j = pixelWidth - 1; j >= 0; j--) {
-                            l1.scanline[lineOff++] = data.get(dataOff++); // // Luminance, 1 bytesPerPixel
-                        }
-                    } else {
-                        for (int j = pixelWidth - 1; j >= 0; j--) {
-                            dataOff = setPixelRGBA8(l1, lineOff, data, dataOff, hasAlpha);
-                            lineOff += bytesPerPixel;
-                        }
-                    }
-                    png.writeRow(l1, row);
-                }
-            }
-            png.end();
-        } finally {
-            IOUtil.close(outs, false);
-        }
-    }
-
-    @Override
-    public String toString() { return "PNGImage["+pixelWidth+"x"+pixelHeight+", dpi "+dpi[0]+" x "+dpi[1]+", bytesPerPixel "+bytesPerPixel+", reversedChannels "+reversedChannels+", "+data+"]"; }
-}
diff --git a/src/jogl/classes/javax/media/opengl/GLBase.java b/src/jogl/classes/javax/media/opengl/GLBase.java
index a19a991..2d6aed1 100644
--- a/src/jogl/classes/javax/media/opengl/GLBase.java
+++ b/src/jogl/classes/javax/media/opengl/GLBase.java
@@ -396,7 +396,7 @@ public interface GLBase {
    /**
     * Returns <code>true</code> if basic FBO support is available, otherwise <code>false</code>.
     * <p>
-    * Basic FBO is supported if the context is either GL-ES >= 2.0, GL >= core 3.0 or implements the extensions
+    * Basic FBO is supported if the context is either GL-ES >= 2.0, GL >= 3.0 [core, compat] or implements the extensions
     * <code>GL_ARB_ES2_compatibility</code>, <code>GL_ARB_framebuffer_object</code>, <code>GL_EXT_framebuffer_object</code> or <code>GL_OES_framebuffer_object</code>.
     * </p>
     * <p>
@@ -410,7 +410,7 @@ public interface GLBase {
    /**
     * Returns <code>true</code> if full FBO support is available, otherwise <code>false</code>.
     * <p>
-    * Full FBO is supported if the context is either GL >= core 3.0 or implements the extensions
+    * Full FBO is supported if the context is either GL >= core 3.0 [ES, core, compat] or implements the extensions
     * <code>ARB_framebuffer_object</code>, or all of
     * <code>EXT_framebuffer_object</code>, <code>EXT_framebuffer_multisample</code>,
     * <code>EXT_framebuffer_blit</code>, <code>GL_EXT_packed_depth_stencil</code>.
@@ -505,26 +505,97 @@ public interface GLBase {
    public void glDepthRange(double zNear, double zFar);
 
    /**
-    * @param target a GL buffer (VBO) target as used in {@link GL#glBindBuffer(int, int)}, ie {@link GL#GL_ELEMENT_ARRAY_BUFFER}, {@link GL#GL_ARRAY_BUFFER}, ..
-    * @return the GL buffer (VBO) name bound to a target via {@link GL#glBindBuffer(int, int)} or 0 if unbound.
+    * @deprecated Avoid original GL API namespace conflict. Use {@link #getBoundBuffer(int)}
     */
    public int glGetBoundBuffer(int target);
+   /**
+    * @param target a GL buffer (VBO) target as used in {@link GL#glBindBuffer(int, int)}, ie {@link GL#GL_ELEMENT_ARRAY_BUFFER}, {@link GL#GL_ARRAY_BUFFER}, ..
+    * @return the GL buffer name bound to a target via {@link GL#glBindBuffer(int, int)} or 0 if unbound.
+    * @see #getBufferStorage(int)
+    */
+   public int getBoundBuffer(int target);
 
    /**
-    * @param buffer a GL buffer name, generated with {@link GL#glGenBuffers(int, int[], int)} and used in {@link GL#glBindBuffer(int, int)}, {@link GL#glBufferData(int, long, java.nio.Buffer, int)} or {@link GL2#glNamedBufferDataEXT(int, long, java.nio.Buffer, int)} for example.
-    * @return the size of the given GL buffer
+    * @deprecated Use {@link #getBufferStorage(int)}.
     */
-   public long glGetBufferSize(int buffer);
+   public long glGetBufferSize(int bufferName);
+   /**
+    * @param bufferName a GL buffer name, generated with e.g. {@link GL#glGenBuffers(int, int[], int)} and used in {@link GL#glBindBuffer(int, int)}, {@link GL#glBufferData(int, long, java.nio.Buffer, int)} or {@link GL2#glNamedBufferDataEXT(int, long, java.nio.Buffer, int)}.
+    * @return the size of the given GL buffer storage, see {@link GLBufferStorage}
+    * @see #getBoundBuffer(int)
+    */
+   public GLBufferStorage getBufferStorage(int bufferName);
 
    /**
-    * @return true if a VBO is bound to {@link GL#GL_ARRAY_BUFFER} via {@link GL#glBindBuffer(int, int)}, otherwise false
+    * Returns the {@link GLBufferStorage} instance as mapped via OpenGL's native {@link GL#glMapBuffer(int, int) glMapBuffer(..)} implementation.
+    * <p>
+    * Throws a {@link GLException} if GL-function constraints are not met.
+    * </p>
+    * <p>
+    * {@link GL#glMapBuffer(int, int)} wrapper calls this method and returns {@link GLBufferStorage#getMappedBuffer()}.
+    * </p>
+    * <p>
+    * A zero {@link GLBufferStorage#getSize()} will avoid a native call and returns the unmapped {@link GLBufferStorage}.
+    * </p>
+    * <p>
+    * A null native mapping result indicating an error will
+    * not cause a GLException but returns the unmapped {@link GLBufferStorage}.
+    * This allows the user to handle this case.
+    * </p>
+    * @param target denotes the buffer via it's bound target
+    * @param access the mapping access mode
+    * @throws GLException if buffer is not bound to target
+    * @throws GLException if buffer is not tracked
+    * @throws GLException if buffer is already mapped
+    * @throws GLException if buffer has invalid store size, i.e. less-than zero
+    */
+   public GLBufferStorage mapBuffer(int target, int access) throws GLException;
+
+   /**
+    * Returns the {@link GLBufferStorage} instance as mapped via OpenGL's native {@link GL#glMapBufferRange(int, long, long, int) glMapBufferRange(..)} implementation.
+    * <p>
+    * Throws a {@link GLException} if GL-function constraints are not met.
+    * </p>
+    * <p>
+    * {@link GL#glMapBufferRange(int, long, long, int)} wrapper calls this method and returns {@link GLBufferStorage#getMappedBuffer()}.
+    * </p>
+    * <p>
+    * A zero {@link GLBufferStorage#getSize()} will avoid a native call and returns the unmapped {@link GLBufferStorage}.
+    * </p>
+    * <p>
+    * A null native mapping result indicating an error will
+    * not cause a GLException but returns the unmapped {@link GLBufferStorage}.
+    * This allows the user to handle this case.
+    * </p>
+    * @param target denotes the buffer via it's bound target
+    * @param offset offset of the mapped buffer's storage
+    * @param length length of the mapped buffer's storage
+    * @param access the mapping access mode
+    * @throws GLException if buffer is not bound to target
+    * @throws GLException if buffer is not tracked
+    * @throws GLException if buffer is already mapped
+    * @throws GLException if buffer has invalid store size, i.e. less-than zero
+    * @throws GLException if buffer mapping range does not fit, incl. offset
+    */
+   public GLBufferStorage mapBufferRange(final int target, final long offset, final long length, final int access) throws GLException;
+
+   /**
+    * @deprecated Avoid original GL API namespace conflict. Use {@link #isVBOArrayBound()}
     */
    public boolean glIsVBOArrayBound();
+   /**
+    * @return true if a VBO is bound to {@link GL#GL_ARRAY_BUFFER} via {@link GL#glBindBuffer(int, int)}, otherwise false
+    */
+   public boolean isVBOArrayBound();
 
    /**
-    * @return true if a VBO is bound to {@link GL#GL_ELEMENT_ARRAY_BUFFER} via {@link GL#glBindBuffer(int, int)}, otherwise false
+    * @deprecated Avoid original GL API namespace conflict. Use {@link #isVBOElementArrayBound()}
     */
    public boolean glIsVBOElementArrayBound();
+   /**
+    * @return true if a VBO is bound to {@link GL#GL_ELEMENT_ARRAY_BUFFER} via {@link GL#glBindBuffer(int, int)}, otherwise false
+    */
+   public boolean isVBOElementArrayBound();
 
    /**
     * Return the framebuffer name bound to this context,
diff --git a/src/jogl/classes/javax/media/opengl/GLBufferStorage.java b/src/jogl/classes/javax/media/opengl/GLBufferStorage.java
new file mode 100644
index 0000000..929ecf6
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLBufferStorage.java
@@ -0,0 +1,150 @@
+/**
+ * Copyright 2014 JogAmp Community. 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 JogAmp Community ``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 JogAmp Community OR
+ * 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package javax.media.opengl;
+
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
+
+/**
+ * OpenGL buffer storage object reflecting it's
+ * <ul>
+ *   <li>storage size</li>
+ *   <li>storage memory if mapped</li>
+ *   <li>mutable usage or immutable flags</li>
+ * </ul>
+ * <p>
+ * Buffer storage is created via:
+ * <ul>
+ *   <li><code>glBufferStorage</code> - storage creation with target</li>
+ *   <li>{@link GL#glBufferData(int, long, java.nio.Buffer, int)} - storage recreation with target</li>
+ *   <li>{@link GL2#glNamedBufferDataEXT(int, long, java.nio.Buffer, int)} - storage recreation, direct</li>
+ * </ul>
+ * Note that storage <i>recreation</i> as mentioned above also invalidate a previous storage instance,
+ * i.e. disposed the buffer's current storage if exist and attaches a new storage instance.
+ * </p>
+ * <p>
+ * Buffer storage is disposed via:
+ * <ul>
+ *   <li>{@link GL#glDeleteBuffers(int, IntBuffer)} - explicit, direct, via {@link #notifyBuffersDeleted(int, IntBuffer)} or {@link #notifyBuffersDeleted(int, int[], int)}</li>
+ *   <li>{@link GL#glBufferData(int, long, java.nio.Buffer, int)} - storage recreation via target</li>
+ *   <li>{@link GL2#glNamedBufferDataEXT(int, long, java.nio.Buffer, int)} - storage recreation, direct</li>
+ * </ul>
+ * </p>
+ * <p>
+ * GL buffer storage is mapped via
+ * <ul>
+ *
+ *   <li>{@link GL#mapBuffer(int, int)}</li>
+ *   <li>{@link GL#mapBufferRange(int, long, long, int)}</li>
+ *   <li>{@link GL2#mapNamedBuffer(int, int)}</li>
+ *   <li>{@link GL2#mapNamedBufferRange(int, long, long, int)}</li>
+ * </ul>
+ * </p>
+ * <p>
+ * GL buffer storage is unmapped via
+ * <ul>
+ *   <li>{@link GL#glUnmapBuffer(int)} - explicit via target</li>
+ *   <li>{@link GL2#glUnmapNamedBufferEXT(int)} - explicit direct</li>
+ *   <li>{@link GL#glBufferData(int, long, java.nio.Buffer, int)} - storage recreation via target</li>
+ *   <li>{@link GL2#glNamedBufferDataEXT(int, long, java.nio.Buffer, int)} - storage recreation, direct</li>
+ *   <li>{@link GL#glDeleteBuffers(int, IntBuffer)} - buffer deletion</li>
+ * </ul>
+ * </p>
+ */
+public abstract class GLBufferStorage {
+        private final int name;
+        private final long size;
+        private final int mutableUsage;
+        private final int immutableFlags;
+        protected ByteBuffer mappedBuffer;
+
+        protected GLBufferStorage(final int name, final long size, final int mutableUsage, final int immutableFlags) {
+            this.name = name;
+            this.size = size;
+            this.mutableUsage = mutableUsage;
+            this.immutableFlags = immutableFlags;
+            this.mappedBuffer = null;
+        }
+
+        /** Return the buffer name */
+        public final int getName() { return name; }
+
+        /** Return the buffer's storage size. */
+        public final long getSize() { return size; }
+
+        /**
+         * Returns <code>true</code> if buffer's storage is mutable, i.e.
+         * created via {@link GL#glBufferData(int, long, java.nio.Buffer, int)}.
+         * <p>
+         * Returns <code>false</code> if buffer's storage is immutable, i.e.
+         * created via <code>glBufferStorage</code>. FIXME: Add GL 4.4 support!
+         * </p>
+         * @return
+         */
+        public final boolean isMutableStorage() { return 0 != mutableUsage; }
+
+        /**
+         * Returns the mutable storage usage or 0 if storage is not {@link #isMutableStorage() mutable}.
+         */
+        public final int getMutableUsage() { return mutableUsage; }
+
+        /**
+         * Returns the immutable storage flags, invalid if storage is {@link #isMutableStorage() mutable}.
+         */
+        public final int getImmutableFlags() { return immutableFlags; }
+
+        /**
+         * Returns the mapped ByteBuffer, or null if not mapped.
+         * Mapping may occur via:
+         * <ul>
+         *   <li>{@link GL#glMapBuffer(int, int)}</li>
+         *   <li>{@link GL#glMapBufferRange(int, long, long, int)}</li>
+         *   <li>{@link GL2#glMapNamedBufferEXT(int, int)}</li>
+         *   <li>{@link GL2#glMapNamedBufferRangeEXT(int, long, long, int)}
+         * </ul>
+         */
+        public final ByteBuffer getMappedBuffer() { return mappedBuffer; }
+
+        public final String toString() {
+            return toString(false);
+        }
+        public final String toString(final boolean skipMappedBuffer) {
+            final String s0;
+            if( isMutableStorage() ) {
+                s0 = String.format("%s[name %s, size %d, mutable usage 0x%X", msgClazzName, name, size, mutableUsage);
+            } else {
+                s0 = String.format("%s[name %s, size %d, immutable flags 0x%X", msgClazzName, name, size, immutableFlags);
+            }
+            if(skipMappedBuffer) {
+                return s0+"]";
+            } else {
+                return s0+", mapped "+mappedBuffer+"]";
+            }
+        }
+        private final String msgClazzName = "GLBufferStorage";
+}
diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java
index deb1d75..9245d10 100644
--- a/src/jogl/classes/javax/media/opengl/GLContext.java
+++ b/src/jogl/classes/javax/media/opengl/GLContext.java
@@ -883,7 +883,7 @@ public abstract class GLContext {
   /**
    * Returns <code>true</code> if basic FBO support is available, otherwise <code>false</code>.
    * <p>
-   * Basic FBO is supported if the context is either GL-ES >= 2.0, GL >= core 3.0 or implements the extensions
+   * Basic FBO is supported if the context is either GL-ES >= 2.0, GL >= 3.0 [core, compat] or implements the extensions
    * <code>GL_ARB_ES2_compatibility</code>, <code>GL_ARB_framebuffer_object</code>, <code>GL_EXT_framebuffer_object</code> or <code>GL_OES_framebuffer_object</code>.
    * </p>
    * <p>
@@ -897,18 +897,9 @@ public abstract class GLContext {
   }
 
   /**
-   * Returns <code>true</code> if <code>OES_single_precision</code>, fp32, fixed function point (FFP) compatibility entry points available,
-   * otherwise <code>false</code>.
-   * @see #CTX_IMPL_FP32_COMPAT_API
-   */
-  public final boolean hasFP32CompatAPI() {
-      return 0 != ( ctxOptions & CTX_IMPL_FP32_COMPAT_API ) ;
-  }
-
-  /**
    * Returns <code>true</code> if full FBO support is available, otherwise <code>false</code>.
    * <p>
-   * Full FBO is supported if the context is either GL >= core 3.0 or implements the extensions
+   * Full FBO is supported if the context is either GL >= 3.0 [ES, core, compat] or implements the extensions
    * <code>ARB_framebuffer_object</code>, or all of
    * <code>EXT_framebuffer_object</code>, <code>EXT_framebuffer_multisample</code>,
    * <code>EXT_framebuffer_blit</code>, <code>GL_EXT_packed_depth_stencil</code>.
@@ -919,7 +910,7 @@ public abstract class GLContext {
    */
   public final boolean hasFullFBOSupport() {
       return hasBasicFBOSupport() && !hasRendererQuirk(GLRendererQuirks.NoFullFBOSupport) &&
-             ( isGL3() ||                                                         // GL >= 3.0
+             ( isGL3ES3() ||                                                      // GL >= 3.0 [ES, core, compat]
                isExtensionAvailable(GLExtensions.ARB_framebuffer_object) ||       // ARB_framebuffer_object
                ( isExtensionAvailable(GLExtensions.EXT_framebuffer_object) &&     // All EXT_framebuffer_object*
                  isExtensionAvailable(GLExtensions.EXT_framebuffer_multisample) &&
@@ -930,6 +921,15 @@ public abstract class GLContext {
   }
 
   /**
+   * Returns <code>true</code> if <code>OES_single_precision</code>, fp32, fixed function point (FFP) compatibility entry points available,
+   * otherwise <code>false</code>.
+   * @see #CTX_IMPL_FP32_COMPAT_API
+   */
+  public final boolean hasFP32CompatAPI() {
+      return 0 != ( ctxOptions & CTX_IMPL_FP32_COMPAT_API ) ;
+  }
+
+  /**
    * Returns the maximum number of FBO RENDERBUFFER samples
    * if {@link #hasFullFBOSupport() full FBO is supported}, otherwise false.
    */
@@ -1109,11 +1109,15 @@ public abstract class GLContext {
   }
 
   /**
-   * Indicates whether this GLContext is capable of GLES2.  <p>Includes [ GLES2 ].</p>
+   * Indicates whether this GLContext is capable of GLES2.  <p>Includes [ GLES2, GLES3 ].</p>
    * @see GLProfile#isGLES2()
    */
   public final boolean isGLES2() {
-      return 0 != ( ctxOptions & CTX_PROFILE_ES ) && ctxVersion.getMajor() == 2 ;
+      if( 0 != ( ctxOptions & CTX_PROFILE_ES ) ) {
+          final int major = ctxVersion.getMajor();
+          return 2 == major || 3 == major;
+      }
+      return false;
   }
 
   /**
@@ -1121,7 +1125,7 @@ public abstract class GLContext {
    * @see GLProfile#isGLES3()
    */
   public final boolean isGLES3() {
-      return 0 != ( ctxOptions & CTX_PROFILE_ES ) && ctxVersion.getMajor() >= 3 ;
+      return 0 != ( ctxOptions & CTX_PROFILE_ES ) && ctxVersion.getMajor() == 3 ;
   }
 
   /**
@@ -1618,8 +1622,8 @@ public abstract class GLContext {
             final Integer valI = deviceVersionAvailable.get(key);
             if(null != valI) {
                 final int bits32 = valI.intValue();
-                final int major = ( bits32 & 0xFF000000 ) >> 24 ;
-                final int minor = ( bits32 & 0x00FF0000 ) >> 16 ;
+                final int major = ( bits32 & 0xFF000000 ) >>> 24 ;
+                final int minor = ( bits32 & 0x00FF0000 ) >>> 16 ;
                 final int ctp   = ( bits32 & 0x0000FFFF )       ;
                 sb.append(GLContext.getGLVersion(major, minor, ctp, null));
             } else {
@@ -1664,10 +1668,10 @@ public abstract class GLContext {
     final int bits32 = valI.intValue();
 
     if(null!=major) {
-        major[0] = ( bits32 & 0xFF000000 ) >> 24 ;
+        major[0] = ( bits32 & 0xFF000000 ) >>> 24 ;
     }
     if(null!=minor) {
-        minor[0] = ( bits32 & 0x00FF0000 ) >> 16 ;
+        minor[0] = ( bits32 & 0x00FF0000 ) >>> 16 ;
     }
     if(null!=ctp) {
         ctp[0]   = ( bits32 & 0x0000FFFF )       ;
diff --git a/src/jogl/classes/javax/media/opengl/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java
index 64c8a62..a43ddee 100644
--- a/src/jogl/classes/javax/media/opengl/GLProfile.java
+++ b/src/jogl/classes/javax/media/opengl/GLProfile.java
@@ -510,7 +510,7 @@ public class GLProfile {
     /** The intersection of the desktop GL3 and GL2 profile */
     public static final String GL2GL3 = "GL2GL3";
 
-    /** The intersection of the desktop GL4 and ES3 profile */
+    /** The intersection of the desktop GL4 and ES3 profile, available only if either ES3 or GL4 w/ <code>GL_ARB_ES3_compatibility</code> is available. */
     public static final String GL4ES3 = "GL4ES3";
 
     /** The default profile, used for the device default profile map  */
@@ -1147,9 +1147,9 @@ public class GLProfile {
         return GLES1 == profile;
     }
 
-    /** Indicates whether this profile is capable of GLES2.  <p>Includes [ GLES2 ].</p> */
+    /** Indicates whether this profile is capable of GLES2.  <p>Includes [ GLES2, GLES3 ].</p> */
     public final boolean isGLES2() {
-        return GLES2 == profile;
+        return isGLES3() || GLES2 == profile;
     }
 
     /** Indicates whether this profile is capable of GLES3.  <p>Includes [ GLES3 ].</p> */
@@ -1157,7 +1157,7 @@ public class GLProfile {
         return GLES3 == profile;
     }
 
-    /** Indicates whether this profile is capable of GLES.  <p>Includes [ GLES3, GLES1, GLES2 ].</p> */
+    /** Indicates whether this profile is capable of GLES.  <p>Includes [ GLES1, GLES2, GLES3 ].</p> */
     public final boolean isGLES() {
         return GLES3 == profile || GLES2 == profile || GLES1 == profile;
     }
diff --git a/src/jogl/classes/javax/media/opengl/GLSharedContextSetter.java b/src/jogl/classes/javax/media/opengl/GLSharedContextSetter.java
index 69ee035..2ea4e4c 100644
--- a/src/jogl/classes/javax/media/opengl/GLSharedContextSetter.java
+++ b/src/jogl/classes/javax/media/opengl/GLSharedContextSetter.java
@@ -99,6 +99,12 @@ package javax.media.opengl;
  */
 public interface GLSharedContextSetter extends GLAutoDrawable {
     /**
+     * Returns true if all {@link GLEventListener} are initialized, otherwise false.
+     * @deprecated Promote method to {@link GLAutoDrawable}
+     */
+    boolean areAllGLEventListenerInitialized();
+
+    /**
      * Specifies an {@link GLContext OpenGL context}, which shall be shared by this {@link GLAutoDrawable}'s {@link GLContext}.
      * <p>
      * Since the {@link GLDrawable drawable} and {@link GLContext context} is created
@@ -130,8 +136,12 @@ public interface GLSharedContextSetter extends GLAutoDrawable {
      * </p>
      * <p>
      * A set <i>sharedAutoDrawable</i> will block context creation, i.e. {@link GLAutoDrawable#initialization GLAutoDrawable initialization},
-     * as long it's {@link GLContext} is <code>null</code>
-     * or has not been {@link GLContext#isCreated() created natively}.
+     * as long it's
+     * <ul>
+     *   <li>{@link GLContext} is <code>null</code>, or</li>
+     *   <li>{@link GLContext} has not been {@link GLContext#isCreated() created natively}, or</li>
+     *   <li>{@link GLEventListener} are <i>not</i> {@link GLSharedContextSetter#areAllGLEventListenerInitialized() completely initialized}</li>
+     * </ul>
      * </p>
      * <p>
      * See <a href="#lifecycle">Lifecycle Considerations</a>.
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
index 0bc002f..abf670c 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
@@ -52,6 +52,8 @@ import java.awt.Graphics;
 import java.awt.Graphics2D;
 import java.awt.GraphicsConfiguration;
 import java.awt.GraphicsDevice;
+import java.awt.event.HierarchyEvent;
+import java.awt.event.HierarchyListener;
 import java.awt.geom.NoninvertibleTransformException;
 import java.awt.geom.Rectangle2D;
 import java.awt.EventQueue;
@@ -173,6 +175,14 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
   private final GraphicsDevice device;
   private boolean shallUseOffscreenLayer = false;
 
+  private volatile boolean isShowing;
+  private final HierarchyListener hierarchyListener = new HierarchyListener() {
+      @Override
+      public void hierarchyChanged(HierarchyEvent e) {
+          isShowing = GLCanvas.this.isShowing();
+      }
+  };
+
   private final AWTWindowClosingProtocol awtWindowClosingProtocol =
           new AWTWindowClosingProtocol(this, new Runnable() {
                 @Override
@@ -294,6 +304,9 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
         helper.setSharedContext(null, shareWith);
     }
     this.device = device;
+
+    this.addHierarchyListener(hierarchyListener);
+    this.isShowing = isShowing();
   }
 
   @Override
@@ -524,7 +537,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
         }
         return; // not yet available ..
     }
-    if( isVisible() && !printActive ) {
+    if( isShowing && !printActive ) {
         Threading.invoke(true, displayOnEDTAction, getTreeLock());
     }
   }
@@ -583,15 +596,6 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
     }
   }
 
-  @Override
-  public void setVisible(boolean b) {
-      if(DEBUG) {
-          System.err.println(getThreadName()+": Info: setVisible("+b+")");
-          Thread.dumpStack();
-      }
-      super.setVisible(b);
-  }
-
   /** Overridden to track when this component is added to a container.
       Subclasses which override this method must call
       super.addNotify() in their addNotify() method in order to
@@ -814,9 +818,9 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
               printActive = false;
               return; // not yet available ..
           }
-          if( !isVisible() ) {
+          if( !isShowing ) {
               if(DEBUG) {
-                  System.err.println(getThreadName()+": Info: GLCanvas setupPrint - skipped GL render, drawable visible");
+                  System.err.println(getThreadName()+": Info: GLCanvas setupPrint - skipped GL render, drawable valid, canvas not showing");
               }
               printActive = false;
               return; // not yet available ..
@@ -966,6 +970,11 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
   }
 
   @Override
+  public boolean areAllGLEventListenerInitialized() {
+     return helper.areAllGLEventListenerInitialized();
+  }
+
+  @Override
   public boolean getGLEventListenerInitState(GLEventListener listener) {
       return helper.getGLEventListenerInitState(listener);
   }
@@ -1148,7 +1157,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
                           ",\n\thandle    0x"+Long.toHexString(getHandle())+
                           ",\n\tDrawable size "+dw+"x"+dh+
                           ",\n\tAWT pos "+getX()+"/"+getY()+", size "+getWidth()+"x"+getHeight()+
-                          ",\n\tvisible "+isVisible()+", displayable "+isDisplayable()+
+                          ",\n\tvisible "+isVisible()+", displayable "+isDisplayable()+", showing "+isShowing+
                           ",\n\t"+awtConfig+"]";
   }
 
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
index a71b47c..522585f 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
@@ -48,6 +48,8 @@ import java.awt.Graphics2D;
 import java.awt.GraphicsConfiguration;
 import java.awt.GraphicsEnvironment;
 import java.awt.Rectangle;
+import java.awt.event.HierarchyEvent;
+import java.awt.event.HierarchyListener;
 import java.awt.geom.NoninvertibleTransformException;
 import java.awt.geom.Rectangle2D;
 import java.awt.image.BufferedImage;
@@ -265,6 +267,14 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
       return null == customPixelBufferProvider &&  useJava2DGLPipeline && java2DGLPipelineOK;
   }
 
+  private volatile boolean isShowing;
+  private final HierarchyListener hierarchyListener = new HierarchyListener() {
+      @Override
+      public void hierarchyChanged(HierarchyEvent e) {
+          isShowing = GLJPanel.this.isShowing();
+      }
+  };
+
   private final AWTWindowClosingProtocol awtWindowClosingProtocol =
           new AWTWindowClosingProtocol(this, new Runnable() {
                 @Override
@@ -346,6 +356,8 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
         helper.setSharedContext(null, shareWith);
     }
     this.setFocusable(true); // allow keyboard input!
+    this.addHierarchyListener(hierarchyListener);
+    this.isShowing = isShowing();
   }
 
   /**
@@ -418,7 +430,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
 
   @Override
   public void display() {
-    if( isVisible() ) {
+    if( isShowing ) {
         if (EventQueue.isDispatchThread()) {
           // Want display() to be synchronous, so call paintImmediately()
           paintImmediately(0, 0, getWidth(), getHeight());
@@ -521,7 +533,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
           sendReshape = handleReshape();
         }
 
-        if( isVisible() ) {
+        if( isShowing ) {
           updater.setGraphics(g);
           backend.doPaintComponent(g);
         }
@@ -608,9 +620,9 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
               printActive = false;
               return; // not yet available ..
           }
-          if( !isVisible() ) {
+          if( !isShowing ) {
               if(DEBUG) {
-                  System.err.println(getThreadName()+": Info: GLJPanel setupPrint - skipped GL render, drawable visible");
+                  System.err.println(getThreadName()+": Info: GLJPanel setupPrint - skipped GL render, drawable valid, panel not showing");
               }
               printActive = false;
               return; // not yet available ..
@@ -793,6 +805,11 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
   }
 
   @Override
+  public boolean areAllGLEventListenerInitialized() {
+     return helper.areAllGLEventListenerInitialized();
+  }
+
+  @Override
   public boolean getGLEventListenerInitState(GLEventListener listener) {
       return helper.getGLEventListenerInitState(listener);
   }
diff --git a/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java b/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java
index 42d0a2e..7cd685d 100644
--- a/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java
+++ b/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java
@@ -510,6 +510,11 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, GLStateKeepe
     }
 
     @Override
+    public boolean areAllGLEventListenerInitialized() {
+        return helper.areAllGLEventListenerInitialized();
+    }
+
+    @Override
     public boolean getGLEventListenerInitState(GLEventListener listener) {
         return helper.getGLEventListenerInitState(listener);
     }
diff --git a/src/jogl/classes/jogamp/opengl/GLBufferObjectTracker.java b/src/jogl/classes/jogamp/opengl/GLBufferObjectTracker.java
new file mode 100644
index 0000000..472bfbd
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/GLBufferObjectTracker.java
@@ -0,0 +1,520 @@
+/**
+ * Copyright 2014 JogAmp Community. 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 JogAmp Community ``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 JogAmp Community OR
+ * 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package jogamp.opengl;
+
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
+
+import javax.media.opengl.*;
+
+import com.jogamp.common.nio.Buffers;
+import com.jogamp.common.util.IntObjectHashMap;
+
+/**
+ * Tracking of {@link GLBufferStorage} instances via GL API callbacks.
+ * <p>
+ * See {@link GLBufferStorage} for generic details.
+ * </p>
+ * <p>
+ * Buffer storage is created via
+ * <ul>
+ *   <li><code>glBufferStorage</code> - storage creation with target via {@link #createBufferStorage(GLBufferStateTracker, GL, int, long, Buffer, int, int, CreateStorageDispatch, long)}</li>
+ *   <li>{@link GL#glBufferData(int, long, java.nio.Buffer, int)} - storage recreation with target via {@link #createBufferStorage(GLBufferStateTracker, GL, int, long, Buffer, int, int, CreateStorageDispatch, long)}</li>
+ *   <li>{@link GL2#glNamedBufferDataEXT(int, long, java.nio.Buffer, int)} - storage recreation, direct, via {@link #createBufferStorage(GL, int, long, Buffer, int, CreateStorageDispatch, long)}</li>
+ * </ul>
+ * Note that storage <i>recreation</i> as mentioned above also invalidate a previous storage instance,
+ * i.e. disposed the buffer's current storage if exist and attaches a new storage instance.
+ * </p>
+ * <p>
+ * Buffers storage is disposed via
+ * <ul>
+ *   <li>{@link GL#glDeleteBuffers(int, IntBuffer)} - explicit, direct, via {@link #notifyBuffersDeleted(int, IntBuffer)} or {@link #notifyBuffersDeleted(int, int[], int)}</li>
+ *   <li>{@link GL#glBufferData(int, long, java.nio.Buffer, int)} - storage recreation via target</li>
+ *   <li>{@link GL2#glNamedBufferDataEXT(int, long, java.nio.Buffer, int)} - storage recreation, direct</li>
+ * </ul>
+ * </p>
+ *
+ * <p>
+ * Implementation throws a {@link GLException} in all <i>construction</i> methods as listed below,
+ * if GL-function constraints are not met. <code>createBufferStorage</code> also throws an exception
+ * if the native GL-function fails.
+ * <ul>
+ *   <li>{@link #createBufferStorage(GLBufferStateTracker, GL, int, long, Buffer, int, int, CreateStorageDispatch, long)}, etc ..</li>
+ *   <li>{@link #mapBuffer(GLBufferStateTracker, GL, int, int, MapBufferAllDispatch, long)}, etc ..</li>
+ * </ul>
+ * In <i>destruction</i> and informal methods, i.e. all others, implementation only issues a WARNING debug message, if enabled.
+ * </p>
+ *
+ * <p>
+ * Buffer mapping methods like {@link GL#mapBuffer(int, int)} ...,
+ * require knowledge of the buffer's storage size as determined via it's creation with
+ * {@link GL#glBufferData(int, long, java.nio.Buffer, int)} ....
+ * </p>
+ * <p>
+ * Hence we track the OpenGL buffer's {@link GLBufferStorage} to be able to
+ * access the buffer's storage size. The tracked {@link GLBufferStorage} instances
+ * also allow users to conveniently access details of their created and maybe mapped buffer storage.
+ * </p>
+ * <p>
+ * The {@link GLBufferObjectTracker} and it's tracked {@link GLBufferStorage} instances
+ * maybe shared across multiple OpenGL context, hence this class is thread safe and employs synchronization.
+ * </p>
+ * <p>
+ * Implementation requires and utilizes a local {@link GLBufferStateTracker}
+ * to resolve the actual buffer-name bound to the given target.
+ * </p>
+ * <p>
+ * Note: This tracker requires to be notified about all OpenGL buffer storage operations,
+ * as well as the local {@link GLBufferStateTracker} to be notified about all
+ * OpenGL buffer binding operations.
+ * Hence buffer storage cannot be accessed properly if managed via native code.
+ * </p>
+ */
+public class GLBufferObjectTracker {
+    protected static final boolean DEBUG;
+
+    static {
+        Debug.initSingleton();
+        DEBUG = Debug.isPropertyDefined("jogl.debug.GLBufferObjectTracker", true);
+    }
+
+    static final class GLBufferStorageImpl extends GLBufferStorage {
+        GLBufferStorageImpl(final int name, final long size, final int mutableUsage, final int immutableFlags) {
+            super(name, size, mutableUsage, immutableFlags);
+        }
+        final void setMappedBuffer(final ByteBuffer bb) {
+            if (DEBUG) {
+                System.err.printf("%s.GLBufferStorage.setMappedBuffer: %s: %s -> %s%n", msgClazzName, toString(true), mappedBuffer, bb);
+            }
+            mappedBuffer = bb;
+        }
+    }
+
+    /**
+     * Map from buffer names to GLBufferObject.
+     */
+    private final IntObjectHashMap bufferName2StorageMap;
+
+    public GLBufferObjectTracker() {
+        bufferName2StorageMap = new IntObjectHashMap();
+        bufferName2StorageMap.setKeyNotFoundValue(null);
+    }
+
+    public static interface CreateStorageDispatch {
+        void create(final int targetOrBufferName, final long size, final Buffer data, final int mutableUsageOrImmutableFlags, final long glProcAddress);
+    }
+
+    /**
+     * Must be called when [re]creating the GL buffer object via <code>glBufferStorage</code> and {@link GL#glBufferData(int, long, java.nio.Buffer, int)},
+     * i.e. implies destruction of the buffer.
+     *
+     * @param bufferStateTracker
+     * @param caller
+     * @param target
+     * @param size
+     * @param mutableUsage <code>glBufferData</code>, <code>glNamedBufferDataEXT</code> usage
+     * @param immutableFlags <code>glBufferStorage</code> flags
+     * @throws GLException if buffer is not bound to target
+     * @throws GLException if size is less-or-eqaul zero for <code>glBufferStorage</code>, or size is less-than zero otherwise
+     * @throws GLException if a native GL-Error occurs
+     */
+    public synchronized final void createBufferStorage(final GLBufferStateTracker bufferStateTracker, final GL caller,
+                                                       final int target, final long size, final Buffer data, int mutableUsage, int immutableFlags,
+                                                       final CreateStorageDispatch dispatch, final long glProcAddress) throws GLException {
+        final int glerrPre = caller.glGetError(); // clear
+        if (DEBUG && GL.GL_NO_ERROR != glerrPre) {
+            System.err.printf("%s.%s glerr-pre 0x%X%n", msgClazzName, msgCreateBound, glerrPre);
+        }
+        final int bufferName = bufferStateTracker.getBoundBufferObject(target, caller);
+        if ( 0 == bufferName ) {
+            throw new GLException(String.format("%s: Buffer for target 0x%X not bound", GL_INVALID_OPERATION, target));
+        }
+        final boolean mutableBuffer = 0 != mutableUsage;
+        final boolean invalidSize = (  mutableBuffer && 0 > size )   // glBufferData, glNamedBufferDataEXT
+                                 || ( !mutableBuffer && 0 >= size ); // glBufferStorage
+        if( invalidSize ) {
+            throw new GLException(String.format("%s: Invalid size %d for buffer %d on target 0x%X", GL_INVALID_VALUE, size, bufferName, target));
+        }
+
+        dispatch.create(target, size, data, mutableBuffer ? mutableUsage : immutableFlags, glProcAddress);
+        final int glerrPost = caller.glGetError(); // be safe, catch failure!
+        if(GL.GL_NO_ERROR != glerrPost) {
+            throw new GLException(String.format("GL-Error 0x%X while creating %s storage for target 0x%X -> buffer %d of size %d with data %s",
+                    glerrPost, mutableBuffer ? "mutable" : "immutable", target, bufferName, size, data));
+        }
+        final GLBufferStorageImpl objNew = new GLBufferStorageImpl(bufferName, size, mutableUsage, immutableFlags);
+        final GLBufferStorageImpl objOld = (GLBufferStorageImpl) bufferName2StorageMap.put(bufferName, objNew);
+        if (DEBUG) {
+            System.err.printf("%s.%s target: 0x%X -> %d: %s -> %s%n", msgClazzName, msgCreateBound, target, bufferName, objOld, objNew);
+        }
+        if( null != objOld ) {
+            objOld.setMappedBuffer(null);
+        }
+    }
+
+    /**
+     * Must be called when [re]creating the GL buffer object via {@link GL2#glNamedBufferDataEXT(int, long, java.nio.Buffer, int)},
+     * i.e. implies destruction of the buffer.
+     *
+     * @param bufferName
+     * @param size
+     * @param mutableUsage
+     * @throws GLException if size is less-than zero
+     * @throws GLException if a native GL-Error occurs
+     */
+    public synchronized final void createBufferStorage(final GL caller,
+                                                       final int bufferName, final long size, final Buffer data, final int mutableUsage, int immutableFlags,
+                                                       final CreateStorageDispatch dispatch, final long glProcAddress) throws GLException {
+        final int glerrPre = caller.glGetError(); // clear
+        if (DEBUG && GL.GL_NO_ERROR != glerrPre) {
+            System.err.printf("%s.%s glerr-pre 0x%X%n", msgClazzName, msgCreateNamed, glerrPre);
+        }
+        if ( 0 > size ) { // glBufferData, glNamedBufferDataEXT
+            throw new GLException(String.format("%s: Invalid size %d for buffer %d", GL_INVALID_VALUE, size, bufferName));
+        }
+        final boolean mutableBuffer = 0 != mutableUsage;
+        if( !mutableBuffer ) {
+            throw new InternalError("Immutable glNamedBufferStorageEXT not supported yet");
+        }
+        dispatch.create(bufferName, size, data, mutableUsage, glProcAddress);
+        final int glerrPost = caller.glGetError(); // be safe, catch failure!
+        if(GL.GL_NO_ERROR != glerrPost) {
+            throw new GLException(String.format("GL-Error 0x%X while creating %s storage for buffer %d of size %d with data %s",
+                                                glerrPost, "mutable", bufferName, size, data));
+        }
+        final GLBufferStorageImpl objNew = new GLBufferStorageImpl(bufferName, size, mutableUsage, 0 /* immutableFlags */);
+        final GLBufferStorageImpl objOld = (GLBufferStorageImpl) bufferName2StorageMap.put(bufferName, objNew);
+        if (DEBUG) {
+            System.err.printf("%s.%s direct: %d: %s -> %s%n", msgClazzName, msgCreateNamed, bufferName, objOld, objNew);
+        }
+        if( null != objOld ) {
+            objOld.setMappedBuffer(null);
+        }
+    }
+
+    /**
+     * Must be called when deleting GL buffer objects vis <code>glDeleteBuffers</code>.
+     * @param count
+     * @param bufferNames
+     * @param offset
+     */
+    public synchronized final void notifyBuffersDeleted(final int count, final int[] bufferNames, final int offset) {
+        for(int i=0; i<count; i++) {
+            notifyBufferDeleted(bufferNames[i+offset], i, count);
+        }
+    }
+    /**
+     * Must be called when deleting GL buffer objects vis <code>glDeleteBuffers</code>.
+     * @param n
+     * @param bufferNames
+     */
+    public synchronized final void notifyBuffersDeleted(final int n, final IntBuffer bufferNames) {
+        final int offset = bufferNames.position();
+        for(int i=0; i<n; i++) {
+            notifyBufferDeleted(bufferNames.get(i+offset), i, n);
+        }
+    }
+    /**
+     * Must be called when deleting GL buffer objects vis {@link GL#glDeleteBuffers(int, IntBuffer)}.
+     * @param bufferName
+     * @param i
+     * @param count
+     */
+    private synchronized final void notifyBufferDeleted(final int bufferName, final int i, final int count) {
+        final GLBufferStorageImpl objOld = (GLBufferStorageImpl) bufferName2StorageMap.put(bufferName, null);
+        if (DEBUG) {
+            System.err.printf("%s.notifyBuffersDeleted()[%d/%d]: %d: %s -> null%n", msgClazzName, i+1, count, bufferName, objOld);
+        }
+        if( null == objOld ) {
+            if (DEBUG) {
+                System.err.printf("%s: %s.notifyBuffersDeleted()[%d/%d]: Buffer %d not tracked%n", warning, msgClazzName, i+1, count, bufferName);
+                Thread.dumpStack();
+            }
+            return;
+        }
+        objOld.setMappedBuffer(null);
+    }
+
+    public static interface MapBufferDispatch {
+        ByteBuffer allocNioByteBuffer(final long addr, final long length);
+    }
+    public static interface MapBufferRangeDispatch extends MapBufferDispatch {
+        long mapBuffer(final int targetOrBufferName, final long offset, final long length, final int access, final long glProcAddress);
+    }
+    public static interface MapBufferAllDispatch extends MapBufferDispatch {
+        long mapBuffer(final int targetOrBufferName, final int access, final long glProcAddress);
+    }
+
+    private static final String GL_INVALID_OPERATION = "GL_INVALID_OPERATION";
+    private static final String GL_INVALID_VALUE = "GL_INVALID_VALUE";
+
+    /**
+     * Must be called when mapping GL buffer objects via {@link GL#mapBuffer(int, int)}.
+     * @throws GLException if buffer is not bound to target
+     * @throws GLException if buffer is not tracked
+     * @throws GLException if buffer is already mapped
+     * @throws GLException if buffer has invalid store size, i.e. less-than zero
+     */
+    public synchronized final GLBufferStorage mapBuffer(final GLBufferStateTracker bufferStateTracker,
+                                                        final GL caller, final int target, final int access,
+                                                        final MapBufferAllDispatch dispatch, final long glProcAddress) throws GLException {
+        return this.mapBufferImpl(bufferStateTracker, caller, target, false /* useRange */, 0 /* offset */, 0 /* length */, access, dispatch, glProcAddress);
+    }
+    /**
+     * Must be called when mapping GL buffer objects via {@link GL#mapBufferRange(int, long, long, int)}.
+     * @throws GLException if buffer is not bound to target
+     * @throws GLException if buffer is not tracked
+     * @throws GLException if buffer is already mapped
+     * @throws GLException if buffer has invalid store size, i.e. less-than zero
+     * @throws GLException if buffer mapping range does not fit, incl. offset
+     */
+    public synchronized final GLBufferStorage mapBuffer(final GLBufferStateTracker bufferStateTracker,
+                                                        final GL caller, final int target, final long offset, final long length, final int access,
+                                                        final MapBufferRangeDispatch dispatch, final long glProcAddress) throws GLException {
+        return this.mapBufferImpl(bufferStateTracker, caller, target, true /* useRange */, length, access, access, dispatch, glProcAddress);
+    }
+    /**
+     * Must be called when mapping GL buffer objects via {@link GL2#mapNamedBuffer(int, int)}.
+     * @throws GLException if buffer is not tracked
+     * @throws GLException if buffer is already mapped
+     * @throws GLException if buffer has invalid store size, i.e. less-than zero
+     */
+    public synchronized final GLBufferStorage mapBuffer(final int bufferName, final int access, final MapBufferAllDispatch dispatch,
+                                                        final long glProcAddress) throws GLException {
+        return this.mapBufferImpl(0 /* target */, bufferName, true /* isNamedBuffer */, false /* useRange */, 0 /* offset */, 0 /* length */, access, dispatch, glProcAddress);
+    }
+    /**
+     * Must be called when mapping GL buffer objects via {@link GL2#mapNamedBufferRange(int, long, long, int)}.
+     * @throws GLException if buffer is not tracked
+     * @throws GLException if buffer is already mapped
+     * @throws GLException if buffer has invalid store size, i.e. less-than zero
+     * @throws GLException if buffer mapping range does not fit, incl. offset
+     */
+    public synchronized final GLBufferStorage mapBuffer(final int bufferName, final long offset, final long length, final int access, final MapBufferRangeDispatch dispatch,
+                                                        final long glProcAddress) throws GLException {
+        return this.mapBufferImpl(0 /* target */, bufferName, true /* isNamedBuffer */, false /* useRange */, 0 /* offset */, 0 /* length */, access, dispatch, glProcAddress);
+    }
+    /**
+     * @throws GLException if buffer is not bound to target
+     * @throws GLException if buffer is not tracked
+     * @throws GLException if buffer is already mapped
+     * @throws GLException if buffer has invalid store size, i.e. less-than zero
+     * @throws GLException if buffer mapping range does not fit, incl. optional offset
+     */
+    private synchronized final GLBufferStorage mapBufferImpl(final GLBufferStateTracker bufferStateTracker,
+                                                             final GL caller, final int target, final boolean useRange,
+                                                             long offset, long length, final int access,
+                                                             final MapBufferDispatch dispatch, final long glProcAddress) throws GLException {
+        final int bufferName = bufferStateTracker.getBoundBufferObject(target, caller);
+        if( 0 == bufferName ) {
+            throw new GLException(String.format("%s.%s: %s Buffer for target 0x%X not bound", msgClazzName, msgMapBuffer, GL_INVALID_OPERATION, target));
+        }
+        return this.mapBufferImpl(target, bufferName, false /* isNamedBuffer */, useRange, offset, length, access, dispatch, glProcAddress);
+    }
+    /**
+     * <p>
+     * A zero store size will avoid a native call and returns the unmapped {@link GLBufferStorage}.
+     * </p>
+     * <p>
+     * A null native mapping result indicating an error will
+     * not cause a GLException but returns the unmapped {@link GLBufferStorage}.
+     * This allows the user to handle this case.
+     * </p>
+     * @throws GLException if buffer is not tracked
+     * @throws GLException if buffer is already mapped
+     * @throws GLException if buffer has invalid store size, i.e. less-than zero
+     * @throws GLException if buffer mapping range does not fit, incl. optional offset
+     */
+    private synchronized final GLBufferStorage mapBufferImpl(final int target, final int bufferName, final boolean isNamedBuffer, final boolean useRange, long offset,
+                                                             long length, final int access, final MapBufferDispatch dispatch,
+                                                             final long glProcAddress) throws GLException {
+        final GLBufferStorageImpl store = (GLBufferStorageImpl)bufferName2StorageMap.get(bufferName);
+        if ( null == store ) {
+            throw new GLException("Buffer with name "+bufferName+" not tracked");
+        }
+        if( null != store.getMappedBuffer() ) {
+            throw new GLException(String.format("%s.%s: %s Buffer storage of target 0x%X -> %d: %s is already mapped", msgClazzName, msgMapBuffer, GL_INVALID_OPERATION, target, bufferName, store));
+        }
+        final long storeSize = store.getSize();
+        if ( 0 > storeSize ) {
+            throw new GLException(String.format("%s.%s: %s Buffer storage of target 0x%X -> %d: %s is of less-than zero", msgClazzName, msgMapBuffer, GL_INVALID_OPERATION, target, bufferName, store));
+        }
+        if( !useRange ) {
+            length = storeSize;
+            offset = 0;
+        }
+        if( length + offset > storeSize ) {
+            throw new GLException(String.format("%s.%s: %s Out of range: offset %d, length %d, buffer storage of target 0x%X -> %d: %s", msgClazzName, msgMapBuffer, GL_INVALID_VALUE, offset, length, target, bufferName, store));
+        }
+        if( 0 >= length || 0 > offset ) {
+            throw new GLException(String.format("%s.%s: %s Invalid values: offset %d, length %d, buffer storage of target 0x%X -> %d: %s", msgClazzName, msgMapBuffer, GL_INVALID_VALUE, offset, length, target, bufferName, store));
+        }
+        if( 0 == storeSize ) {
+            return store;
+        }
+        final long addr;
+        if( isNamedBuffer ) {
+            if( useRange ) {
+                addr = ((MapBufferRangeDispatch)dispatch).mapBuffer(bufferName, offset, length, access, glProcAddress);
+            } else {
+                addr = ((MapBufferAllDispatch)dispatch).mapBuffer(bufferName, access, glProcAddress);
+            }
+        } else {
+            if( useRange ) {
+                addr = ((MapBufferRangeDispatch)dispatch).mapBuffer(target, offset, length, access, glProcAddress);
+            } else {
+                addr = ((MapBufferAllDispatch)dispatch).mapBuffer(target, access, glProcAddress);
+            }
+        }
+        // GL's map-buffer implementation always returns NULL on error,
+        // user shall validate the result and the corresponding getGLError() value!
+        if ( 0 == addr ) {
+            if( DEBUG ) {
+                System.err.printf("%s.%s: %s MapBuffer null result for target 0x%X -> %d: %s, off %d, len %d, acc 0x%X%n", msgClazzName, msgMapBuffer, warning, target, bufferName, store, offset, length, access);
+                Thread.dumpStack();
+            }
+            // User shall handle the glError !
+        } else {
+            final ByteBuffer buffer = dispatch.allocNioByteBuffer(addr, length);
+            Buffers.nativeOrder(buffer);
+            if( DEBUG ) {
+                System.err.printf("%s.%s: Target 0x%X -> %d: %s, off %d, len %d, acc 0x%X%n", msgClazzName, msgClazzName, target, bufferName, store.toString(false), offset, length, access);
+            }
+            store.setMappedBuffer(buffer);
+        }
+        return store;
+    }
+
+    public static interface UnmapBufferDispatch {
+        boolean unmap(final int targetOrBufferName, final long glProcAddress);
+    }
+
+    /**
+     * Must be called when unmapping GL buffer objects via {@link GL#glUnmapBuffer(int)}.
+     * <p>
+     * Only clear mapped buffer reference of {@link GLBufferStorage}
+     * if native unmapping was successful.
+     * </p>
+     */
+    public synchronized final boolean unmapBuffer(final GLBufferStateTracker bufferStateTracker, final GL caller,
+                                                  final int target,
+                                                  final UnmapBufferDispatch dispatch, final long glProcAddress) {
+        final int bufferName = bufferStateTracker.getBoundBufferObject(target, caller);
+        final GLBufferStorageImpl store;
+        if( 0 == bufferName ) {
+            if (DEBUG) {
+                System.err.printf("%s: %s.%s: Buffer for target 0x%X not bound%n", warning, msgClazzName, msgUnmapped, target);
+                Thread.dumpStack();
+            }
+            store = null;
+        } else {
+            store = (GLBufferStorageImpl) bufferName2StorageMap.get(bufferName);
+            if( DEBUG && null == store ) {
+                System.err.printf("%s: %s.%s: Buffer %d not tracked%n", warning, msgClazzName, msgUnmapped, bufferName);
+                Thread.dumpStack();
+            }
+        }
+        final boolean res = dispatch.unmap(target, glProcAddress);
+        if( res && null != store ) {
+            store.setMappedBuffer(null);
+        }
+        if( DEBUG ) {
+            System.err.printf("%s.%s %s target: 0x%X -> %d: %s%n", msgClazzName, msgUnmapped, res ? "OK" : "Failed", target, bufferName, store.toString(false));
+            if(!res) {
+                Thread.dumpStack();
+            }
+        }
+        return res;
+    }
+    /**
+     * Must be called when unmapping GL buffer objects via {@link GL2#glUnmapNamedBufferEXT(int)}.
+     * <p>
+     * Only clear mapped buffer reference of {@link GLBufferStorage}
+     * if native unmapping was successful.
+     * </p>
+     */
+    public synchronized final boolean unmapBuffer(final int bufferName,
+                                                  final UnmapBufferDispatch dispatch, final long glProcAddress) {
+        final GLBufferStorageImpl store = (GLBufferStorageImpl) bufferName2StorageMap.get(bufferName);
+        if (DEBUG && null == store ) {
+            System.err.printf("%s: %s.%s: Buffer %d not tracked%n", warning, msgClazzName, msgUnmapped, bufferName);
+            Thread.dumpStack();
+        }
+        final boolean res = dispatch.unmap(bufferName, glProcAddress);
+        if( res && null != store ) {
+            store.setMappedBuffer(null);
+        }
+        if (DEBUG) {
+            System.err.printf("%s.%s %s %d: %s%n", msgClazzName, msgUnmapped, res ? "OK" : "Failed", bufferName, store.toString(false));
+            if(!res) {
+                Thread.dumpStack();
+            }
+        }
+        return res;
+    }
+
+    public synchronized final long getBufferSize(final int bufferName) {
+        final GLBufferStorageImpl store = (GLBufferStorageImpl)bufferName2StorageMap.get(bufferName);
+        if ( null == store ) {
+            if (DEBUG) {
+                System.err.printf("%s: %s.getBufferSize(): Buffer %d not tracked%n", warning, msgClazzName, bufferName);
+                Thread.dumpStack();
+            }
+            return 0;
+        }
+        return store.getSize();
+    }
+
+    public synchronized final GLBufferStorage getBufferStorage(final int bufferName) {
+        return (GLBufferStorageImpl)bufferName2StorageMap.get(bufferName);
+    }
+
+    /**
+     * Clear all tracked buffer object knowledge.
+     * <p>
+     * Shall only be called at GLContext destruction <i>iff</i>
+     * there are no other shared GLContext instances left.
+     * </p>
+     */
+    public synchronized final void clear() {
+        if (DEBUG) {
+          System.err.printf("%s.clear() - Thread %s%n", msgClazzName, Thread.currentThread().getName());
+          // Thread.dumpStack();
+        }
+        bufferName2StorageMap.clear();
+    }
+
+    private static final String warning  = "WARNING";
+    private static final String msgClazzName = "GLBufferObjectTracker";
+    private static final String msgUnmapped = "notifyBufferUnmapped()";
+    private static final String msgCreateBound = "createBoundBufferStorage()";
+    private static final String msgCreateNamed = "createNamedBufferStorage()";
+    private static final String msgMapBuffer = "mapBuffer()";
+}
diff --git a/src/jogl/classes/jogamp/opengl/GLBufferSizeTracker.java b/src/jogl/classes/jogamp/opengl/GLBufferSizeTracker.java
deleted file mode 100644
index fa05902..0000000
--- a/src/jogl/classes/jogamp/opengl/GLBufferSizeTracker.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
- * Copyright (c) 2010 JogAmp Community. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * - Redistribution of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- *
- * - Redistribution 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.
- *
- * Neither the name of Sun Microsystems, Inc. or the names of
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * This software is provided "AS IS," without a warranty of any kind. ALL
- * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
- * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
- * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
- * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
- * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
- * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
- * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
- * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
- * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
- * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
- * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
- *
- * You acknowledge that this software is not designed or intended for use
- * in the design, construction, operation or maintenance of any nuclear
- * facility.
- *
- * Sun gratefully acknowledges that this software was originally authored
- * and developed by Kenneth Bradley Russell and Christopher John Kline.
- */
-
-package jogamp.opengl;
-
-import javax.media.opengl.*;
-import com.jogamp.common.util.IntLongHashMap;
-
-/**
- * Tracks as closely as possible the sizes of allocated OpenGL buffer
- * objects. When glMapBuffer or glMapBufferARB is called, in order to
- * turn the resulting base address into a java.nio.ByteBuffer, we need
- * to know the size in bytes of the allocated OpenGL buffer object.
- * Previously we would compute this size by using
- * glGetBufferParameterivARB with a pname of GL_BUFFER_SIZE, but
- * it appears doing so each time glMapBuffer is called is too costly
- * on at least Apple's new multithreaded OpenGL implementation. <P>
- *
- * Instead we now try to track the sizes of allocated buffer objects.
- * We watch calls to glBindBuffer to see which buffer is bound to
- * which target and to glBufferData to see how large the buffer's
- * allocated size is. When glMapBuffer is called, we consult our table
- * of buffer sizes to see if we can return an answer without a glGet
- * call. <P>
- *
- * We share the GLBufferSizeTracker objects among all GLContexts for
- * which sharing is enabled, because the namespace for buffer objects
- * is the same for these contexts. <P>
- *
- * Tracking the state of which buffer objects are bound is done in the
- * GLBufferStateTracker and is not completely trivial. In the face of
- * calls to glPushClientAttrib / glPopClientAttrib we currently punt
- * and re-fetch the bound buffer object for the state in question;
- * see, for example, glVertexPointer and the calls down to
- * GLBufferStateTracker.getBoundBufferObject(). Note that we currently
- * ignore new binding targets such as GL_TRANSFORM_FEEDBACK_BUFFER_NV;
- * the fact that new binding targets may be added in the future makes
- * it impossible to cache state for these new targets. <P>
- *
- * Ignoring new binding targets, the primary situation in which we may
- * not be able to return a cached answer is in the case of an error,
- * where glBindBuffer may not have been called before trying to call
- * glBufferData. Also, if external native code modifies a buffer
- * object, we may return an incorrect answer. (FIXME: this case
- * requires more thought, and perhaps stochastic and
- * exponential-fallback checking. However, note that it can only occur
- * in the face of external native code which requires that the
- * application be signed anyway, so there is no security risk in this
- * area.)
- */
-
-public class GLBufferSizeTracker {
-  protected static final boolean DEBUG;
-
-  static {
-      Debug.initSingleton();
-      DEBUG = Debug.isPropertyDefined("jogl.debug.GLBufferSizeTracker", true);
-  }
-
-  // Map from buffer names to sizes.
-  // Note: should probably have some way of shrinking this map, but
-  // can't just make it a WeakHashMap because nobody holds on to the
-  // keys; would have to always track creation and deletion of buffer
-  // objects, which is probably sub-optimal. The expected usage
-  // pattern of buffer objects indicates that the fact that this map
-  // never shrinks is probably not that bad.
-  private final IntLongHashMap bufferSizeMap;
-  private final long keyNotFount = 0xFFFFFFFFFFFFFFFFL;
-
-  public GLBufferSizeTracker() {
-      bufferSizeMap = new IntLongHashMap();
-      bufferSizeMap.setKeyNotFoundValue(keyNotFount);
-  }
-
-  public final void setBufferSize(GLBufferStateTracker bufferStateTracker,
-                                  int target, GL caller, long size) {
-    // Need to do some similar queries to getBufferSize below
-    int buffer = bufferStateTracker.getBoundBufferObject(target, caller);
-    if (buffer != 0) {
-      setDirectStateBufferSize(buffer, caller, size);
-    }
-    // We don't know the current buffer state. Note that the buffer
-    // state tracker will have made the appropriate OpenGL query if it
-    // didn't know what was going on, so at this point we have nothing
-    // left to do except drop this piece of information on the floor.
-  }
-
-  public final void setDirectStateBufferSize(int buffer, GL caller, long size) {
-      bufferSizeMap.put(buffer, size);
-  }
-
-  public final long getBufferSize(GLBufferStateTracker bufferStateTracker,
-                           int target,
-                           GL caller) {
-    // See whether we know what buffer is currently bound to the given
-    // state
-    final int buffer = bufferStateTracker.getBoundBufferObject(target, caller);
-    if (0 != buffer) {
-      return getBufferSizeImpl(target, buffer, caller);
-    }
-    // We don't know what's going on in this case; query the GL for an answer
-    // FIXME: both functions return 'int' types, which is not suitable,
-    // since buffer lenght is 64bit ?
-    int[] tmp = new int[1];
-    caller.glGetBufferParameteriv(target, GL.GL_BUFFER_SIZE, tmp, 0);
-    if (DEBUG) {
-      System.err.println("GLBufferSizeTracker.getBufferSize(): no cached buffer information");
-    }
-    return tmp[0];
-  }
-
-  public final long getDirectStateBufferSize(int buffer, GL caller) {
-      return getBufferSizeImpl(0, buffer, caller);
-  }
-
-  private final long getBufferSizeImpl(int target, int buffer, GL caller) {
-      // See whether we know the size of this buffer object; at this
-      // point we almost certainly should if the application is
-      // written correctly
-      long sz = bufferSizeMap.get(buffer);
-      if (keyNotFount == sz) {
-        // For robustness, try to query this value from the GL as we used to
-        // FIXME: both functions return 'int' types, which is not suitable,
-        // since buffer lenght is 64bit ?
-        int[] tmp = new int[1];
-        if(0==target) {
-            // DirectState ..
-            if(caller.isFunctionAvailable("glGetNamedBufferParameterivEXT")) {
-                caller.getGL2().glGetNamedBufferParameterivEXT(buffer, GL.GL_BUFFER_SIZE, tmp, 0);
-            } else {
-                throw new GLException("Error: getDirectStateBufferSize called with unknown state and GL function 'glGetNamedBufferParameterivEXT' n/a to query size");
-            }
-        } else {
-            caller.glGetBufferParameteriv(target, GL.GL_BUFFER_SIZE, tmp, 0);
-        }
-        if (tmp[0] == 0) {
-          // Assume something is wrong rather than silently going along
-          throw new GLException("Error: buffer size returned by "+
-                                ((0==target)?"glGetNamedBufferParameterivEXT":"glGetBufferParameteriv")+
-                                " was zero; probably application error");
-        }
-        // Assume we just don't know what's happening
-        sz = tmp[0];
-        bufferSizeMap.put(buffer, sz);
-        if (DEBUG) {
-          System.err.println("GLBufferSizeTracker.getBufferSize(): made slow query to cache size " +
-                             sz +
-                             " for buffer " +
-                             buffer);
-        }
-      }
-      return sz;
-  }
-
-  // This should be called on any major event where we might start
-  // producing wrong answers, such as OpenGL context creation and
-  // destruction if we don't know whether there are other currently-
-  // created contexts that might be keeping the buffer objects alive
-  // that we're dealing with
-  public final void clearCachedBufferSizes() {
-    bufferSizeMap.clear();
-  }
-}
diff --git a/src/jogl/classes/jogamp/opengl/GLBufferStateTracker.java b/src/jogl/classes/jogamp/opengl/GLBufferStateTracker.java
index 16b7edc..511c1b9 100644
--- a/src/jogl/classes/jogamp/opengl/GLBufferStateTracker.java
+++ b/src/jogl/classes/jogamp/opengl/GLBufferStateTracker.java
@@ -50,8 +50,13 @@ import com.jogamp.common.util.IntIntHashMap;
  * GLBufferStateTracker objects are allocated on a per-OpenGL-context basis.
  * This class is used to verify that e.g. the vertex
  * buffer object extension is in use when the glVertexPointer variant
- * taking a long as argument is called. <P>
- *
+ * taking a long as argument is called.
+ * <p>
+ * The buffer binding state is local to it's OpenGL context,
+ * i.e. not shared across multiple OpenGL context.
+ * Hence this code is thread safe due to no multithreading usage.
+ * </p>
+ * <p>
  * Note that because the enumerated value used for the binding of a
  * buffer object (e.g. GL_ARRAY_BUFFER) is different than that used to
  * query the binding using glGetIntegerv (e.g.
@@ -61,19 +66,15 @@ import com.jogamp.common.util.IntIntHashMap;
  * to a particular state. It turns out that for some uses, such as
  * finding the size of the currently bound buffer, this doesn't
  * matter, though of course without knowing the buffer object we can't
- * re-associate the queried size with the buffer object ID. <P>
- *
- * Because the namespace of buffer objects is the unsigned integers
- * with 0 reserved by the GL, and because we have to be able to return
- * both 0 and other integers as valid answers from
- * getBoundBufferObject(), we need a second query, which is to ask
- * whether we know the state of the binding for a given target. For
- * "unknown" targets such as GL_TRANSFORM_FEEDBACK_BUFFER_NV we return
+ * re-associate the queried size with the buffer object ID.
+ * </p>
+ * <p>
+ * For <i>unknown</i> targets such as GL_TRANSFORM_FEEDBACK_BUFFER_NV we return
  * false from this, but we also clear the valid bit and later refresh
  * the binding state if glPushClientAttrib / glPopClientAttrib are
  * called, since we don't want the complexity of tracking stacks of
  * these attributes.
- *
+ * </p>
  */
 
 public class GLBufferStateTracker {
@@ -90,25 +91,103 @@ public class GLBufferStateTracker {
   // OpenGL specifications.
   // http://www.opengl.org/sdk/docs/man/xhtml/glBindBuffer.xml
   private final IntIntHashMap bindingMap;
-  private final int keyNotFound = 0xFFFFFFFF;
+  private final int bindingNotFound = 0xFFFFFFFF;
 
   private final int[] bufTmp = new int[1];
 
   public GLBufferStateTracker() {
     bindingMap = new IntIntHashMap();
-    bindingMap.setKeyNotFoundValue(keyNotFound);
+    bindingMap.setKeyNotFoundValue(bindingNotFound);
 
     // Start with known unbound targets for known keys
     // setBoundBufferObject(GL2ES3.GL_VERTEX_ARRAY_BINDING, 0); // not using default VAO (removed in GL3 core) - only explicit
     setBoundBufferObject(GL.GL_ARRAY_BUFFER,         0);
+    setBoundBufferObject(GL4.GL_DRAW_INDIRECT_BUFFER, 0);
     setBoundBufferObject(GL.GL_ELEMENT_ARRAY_BUFFER, 0);
     setBoundBufferObject(GL2.GL_PIXEL_PACK_BUFFER,   0);
     setBoundBufferObject(GL2.GL_PIXEL_UNPACK_BUFFER, 0);
-    setBoundBufferObject(GL4.GL_DRAW_INDIRECT_BUFFER, 0);
   }
 
-  public final void setBoundBufferObject(int target, int value) {
-    bindingMap.put(target, value);
+
+  /**
+   *  GL_ARRAY_BUFFER​,
+   *  GL_ATOMIC_COUNTER_BUFFER​,
+   *  GL_COPY_READ_BUFFER​,
+   *  GL_COPY_WRITE_BUFFER​,
+   *  GL_DRAW_INDIRECT_BUFFER​,
+   *  GL_DISPATCH_INDIRECT_BUFFER​,
+   *  GL_ELEMENT_ARRAY_BUFFER​,
+   *  GL_PIXEL_PACK_BUFFER​,
+   *  GL_PIXEL_UNPACK_BUFFER​,
+   *  GL_SHADER_STORAGE_BUFFER​,
+   *  GL_TEXTURE_BUFFER​,
+   *  GL_TRANSFORM_FEEDBACK_BUFFER​ or
+   *  GL_UNIFORM_BUFFER​.
+   *
+   *  GL_VERTEX_ARRAY_BINDING
+   *
+   */
+  private static final int getQueryName(final int target) {
+      switch (target) {
+        case GL.GL_ARRAY_BUFFER:                  return GL.GL_ARRAY_BUFFER_BINDING;
+        case GL4.GL_ATOMIC_COUNTER_BUFFER:        return GL4.GL_ATOMIC_COUNTER_BUFFER_BINDING;
+        case GL2ES3.GL_COPY_READ_BUFFER:          return GL2ES3.GL_COPY_READ_BUFFER_BINDING;
+        case GL2ES3.GL_COPY_WRITE_BUFFER:         return GL2ES3.GL_COPY_WRITE_BUFFER_BINDING;
+        case GL4.GL_DRAW_INDIRECT_BUFFER:         return GL4.GL_DRAW_INDIRECT_BUFFER_BINDING;
+        case GL4.GL_DISPATCH_INDIRECT_BUFFER:     return GL4.GL_DISPATCH_INDIRECT_BUFFER_BINDING;
+        case GL.GL_ELEMENT_ARRAY_BUFFER:          return GL.GL_ELEMENT_ARRAY_BUFFER_BINDING;
+        case GL2.GL_PIXEL_PACK_BUFFER:            return GL2.GL_PIXEL_PACK_BUFFER_BINDING;
+        case GL2.GL_PIXEL_UNPACK_BUFFER:          return GL2.GL_PIXEL_UNPACK_BUFFER_BINDING;
+        // FIXME case GL4.GL_QUERY_BUFFER:              return GL4.GL_QUERY_BUFFER_BINDING;
+        case GL4.GL_SHADER_STORAGE_BUFFER:        return GL4.GL_SHADER_STORAGE_BUFFER_BINDING;
+        case GL2GL3.GL_TEXTURE_BUFFER:            return GL2GL3.GL_TEXTURE_BINDING_BUFFER;
+        case GL2ES3.GL_TRANSFORM_FEEDBACK_BUFFER: return GL2ES3.GL_TRANSFORM_FEEDBACK_BUFFER_BINDING;
+        case GL2ES3.GL_UNIFORM_BUFFER:            return GL2ES3.GL_UNIFORM_BUFFER_BINDING;
+
+        case GL2ES3.GL_VERTEX_ARRAY_BINDING:      return GL2ES3.GL_VERTEX_ARRAY_BINDING;
+
+        default:
+            throw new GLException(String.format("GL_INVALID_ENUM​: Invalid binding target 0x%X", target));
+      }
+  }
+  private static final void checkTargetName(final int target) {
+      switch (target) {
+        case GL.GL_ARRAY_BUFFER:
+        case GL4.GL_ATOMIC_COUNTER_BUFFER:
+        case GL2ES3.GL_COPY_READ_BUFFER:
+        case GL2ES3.GL_COPY_WRITE_BUFFER:
+        case GL4.GL_DRAW_INDIRECT_BUFFER:
+        case GL4.GL_DISPATCH_INDIRECT_BUFFER:
+        case GL.GL_ELEMENT_ARRAY_BUFFER:
+        case GL2.GL_PIXEL_PACK_BUFFER:
+        case GL2.GL_PIXEL_UNPACK_BUFFER:
+        // FIXME case GL4.GL_QUERY_BUFFER:
+        case GL4.GL_SHADER_STORAGE_BUFFER:
+        case GL2GL3.GL_TEXTURE_BUFFER:
+        case GL2ES3.GL_TRANSFORM_FEEDBACK_BUFFER:
+        case GL2ES3.GL_UNIFORM_BUFFER:
+
+        case GL2ES3.GL_VERTEX_ARRAY_BINDING:
+            return;
+
+        default:
+            throw new GLException(String.format("GL_INVALID_ENUM​: Invalid binding target 0x%X", target));
+      }
+  }
+
+  /**
+   * Must be called when binding a buffer, e.g.:
+   * <ul>
+   *   <li><code>glBindBuffer</code></li>
+   *   <li><code>glBindBufferBase</code></li>
+   *   <li><code>glBindBufferRange</code></li>
+   * </ul>
+   * @param target
+   * @param bufferName
+   */
+  public final void setBoundBufferObject(int target, int bufferName) {
+    checkTargetName(target);
+    final int oldBufferName = bindingMap.put(target, bufferName);
     /***
      * Test for clearing bound buffer states when unbinding VAO,
      * Bug 692 Comment 5 is invalid, i.e. <https://jogamp.org/bugzilla/show_bug.cgi?id=692#c5>.
@@ -116,8 +195,8 @@ public class GLBufferStateTracker {
      * after unbinding a VAO w/o unbinding the VBOs resulted to no visible image.
      * Leaving code in here for discussion - in case I am wrong.
      *
-    final int pre = bindingMap.put(target, value);
-    if( GL2ES3.GL_VERTEX_ARRAY_BINDING == target && keyNotFound != pre && 0 == value ) {
+    final int pre = bindingMap.put(target, bufferName);
+    if( GL2ES3.GL_VERTEX_ARRAY_BINDING == target && keyNotFound != pre && 0 == bufferName ) {
         // Unbinding a previous bound VAO leads to unbinding of all buffers!
         bindingMap.put(GL.GL_ARRAY_BUFFER,         0);
         bindingMap.put(GL.GL_ELEMENT_ARRAY_BUFFER, 0);
@@ -126,9 +205,8 @@ public class GLBufferStateTracker {
         bindingMap.put(GL4.GL_DRAW_INDIRECT_BUFFER, 0);
     } */
     if (DEBUG) {
-      System.err.println("GLBufferStateTracker.setBoundBufferObject() target 0x" +
-                         Integer.toHexString(target) + " -> mapped bound buffer 0x" +
-                         Integer.toHexString(value));
+      System.err.println("GLBufferStateTracker.setBoundBufferObject() target " +
+                         toHexString(target) + ": " + toHexString(oldBufferName) + " -> " + toHexString(bufferName));
       // Thread.dumpStack();
     }
   }
@@ -139,22 +217,12 @@ public class GLBufferStateTracker {
       return value is valid. */
   public final int getBoundBufferObject(int target, GL caller) {
     int value = bindingMap.get(target);
-    if (keyNotFound == value) {
+    if (bindingNotFound == value) {
       // User probably either called glPushClientAttrib /
       // glPopClientAttrib or is querying an unknown target. See
       // whether we know how to fetch this state.
-      boolean gotQueryTarget = true;
-      int queryTarget = 0;
-      switch (target) {
-        case GL2ES3.GL_VERTEX_ARRAY_BINDING: queryTarget = GL2ES3.GL_VERTEX_ARRAY_BINDING;  break;
-        case GL.GL_ARRAY_BUFFER:          queryTarget = GL.GL_ARRAY_BUFFER_BINDING;         break;
-        case GL.GL_ELEMENT_ARRAY_BUFFER:  queryTarget = GL.GL_ELEMENT_ARRAY_BUFFER_BINDING; break;
-        case GL2.GL_PIXEL_PACK_BUFFER:    queryTarget = GL2.GL_PIXEL_PACK_BUFFER_BINDING;    break;
-        case GL2.GL_PIXEL_UNPACK_BUFFER:  queryTarget = GL2.GL_PIXEL_UNPACK_BUFFER_BINDING;  break;
-        case GL4.GL_DRAW_INDIRECT_BUFFER: queryTarget = GL4.GL_DRAW_INDIRECT_BUFFER_BINDING;  break;
-        default:                          gotQueryTarget = false; break;
-      }
-      if (gotQueryTarget) {
+      final int queryTarget = getQueryName(target);
+      if ( 0 != queryTarget ) {
         final int glerrPre = caller.glGetError(); // clear
         caller.glGetIntegerv(queryTarget, bufTmp, 0);
         final int glerrPost = caller.glGetError(); // be safe, e.g. GL '3.0 Mesa 8.0.4' may produce an error querying GL_PIXEL_UNPACK_BUFFER_BINDING, ignore value
@@ -164,9 +232,9 @@ public class GLBufferStateTracker {
             value = 0;
         }
         if (DEBUG) {
-          System.err.println("GLBufferStateTracker.getBoundBufferObject() glerr[pre 0x"+Integer.toHexString(glerrPre)+", post 0x"+Integer.toHexString(glerrPost)+"], [queried value]: target 0x" +
-                             Integer.toHexString(target) + " / query 0x"+Integer.toHexString(queryTarget)+
-                             " -> mapped bound buffer 0x" + Integer.toHexString(value));
+          System.err.println("GLBufferStateTracker.getBoundBufferObject() glerr[pre "+toHexString(glerrPre)+", post "+toHexString(glerrPost)+"], [queried value]: target " +
+                             toHexString(target) + " / query "+toHexString(queryTarget)+
+                             " -> mapped bound buffer " + toHexString(value));
         }
         setBoundBufferObject(target, value);
         return value;
@@ -188,11 +256,12 @@ public class GLBufferStateTracker {
       from GLContext.makeCurrent() in the future to possibly increase
       the robustness of these caches in the face of external native
       code manipulating OpenGL state. */
-  public final void clearBufferObjectState() {
+  public final void clear() {
+    if (DEBUG) {
+      System.err.println("GLBufferStateTracker.clear() - Thread "+Thread.currentThread().getName());
+      // Thread.dumpStack();
+    }
     bindingMap.clear();
-        if (DEBUG) {
-          System.err.println("GLBufferStateTracker.clearBufferObjectState()");
-          //Thread.dumpStack();
-        }
   }
+  private final String toHexString(int i) { return Integer.toHexString(i); }
 }
diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
index 8885c32..431bba6 100644
--- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
@@ -67,13 +67,14 @@ import javax.media.nativewindow.NativeSurface;
 import javax.media.nativewindow.NativeWindowFactory;
 import javax.media.opengl.GL;
 import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GL2ES3;
 import javax.media.opengl.GL2GL3;
-import javax.media.opengl.GL3ES3;
 import javax.media.opengl.GLCapabilitiesImmutable;
 import javax.media.opengl.GLContext;
 import javax.media.opengl.GLDebugListener;
 import javax.media.opengl.GLDebugMessage;
 import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLDrawableFactory;
 import javax.media.opengl.GLException;
 import javax.media.opengl.GLPipelineFactory;
 import javax.media.opengl.GLProfile;
@@ -99,10 +100,10 @@ public abstract class GLContextImpl extends GLContext {
   private String glRendererLowerCase;
   private String glVersion;
 
-  // Tracks creation and initialization of buffer objects to avoid
+  // Tracks lifecycle of buffer objects to avoid
   // repeated glGet calls upon glMapBuffer operations
-  private GLBufferSizeTracker bufferSizeTracker; // Singleton - Set by GLContextShareSet
-  private final GLBufferStateTracker bufferStateTracker = new GLBufferStateTracker();
+  private final GLBufferObjectTracker bufferObjectTracker;
+  private final GLBufferStateTracker bufferStateTracker;
   private final GLStateTracker glStateTracker = new GLStateTracker();
   private GLDebugMessageHandler glDebugHandler = null;
   private final int[] boundFBOTarget = new int[] { 0, 0 }; // { draw, read }
@@ -137,10 +138,14 @@ public abstract class GLContextImpl extends GLContext {
   public GLContextImpl(GLDrawableImpl drawable, GLContext shareWith) {
     super();
 
-    if (shareWith != null) {
+    bufferStateTracker = new GLBufferStateTracker();
+    if ( null != shareWith ) {
       GLContextShareSet.registerSharing(this, shareWith);
+      bufferObjectTracker = ((GLContextImpl)shareWith).getBufferObjectTracker();
+      assert (bufferObjectTracker != null) : "shared context hash null GLBufferObjectTracker: "+shareWith;
+    } else {
+      bufferObjectTracker = new GLBufferObjectTracker();
     }
-    GLContextShareSet.synchronizeBufferObjectSharing(shareWith, this);
 
     this.drawable = drawable;
     this.drawableRead = drawable;
@@ -149,15 +154,10 @@ public abstract class GLContextImpl extends GLContext {
   }
 
   private final void clearStates() {
-      // Because we don't know how many other contexts we might be
-      // sharing with (and it seems too complicated to implement the
-      // GLObjectTracker's ref/unref scheme for the buffer-related
-      // optimizations), simply clear the cache of known buffers' sizes
-      // when we destroy contexts
-      if (bufferSizeTracker != null) {
-          bufferSizeTracker.clearCachedBufferSizes();
+      if( !GLContextShareSet.hasCreatedSharedLeft(this) ) {
+        bufferObjectTracker.clear();
       }
-      bufferStateTracker.clearBufferObjectState();
+      bufferStateTracker.clear();
       glStateTracker.setEnabled(false);
       glStateTracker.clearStates();
   }
@@ -415,9 +415,9 @@ public abstract class GLContextImpl extends GLContext {
                   }
                   if ( 0 != defaultVAO ) {
                       final int[] tmp = new int[] { defaultVAO };
-                      final GL3ES3 gl3es3 = gl.getRootGL().getGL3ES3();
-                      gl3es3.glBindVertexArray(0);
-                      gl3es3.glDeleteVertexArrays(1, tmp, 0);
+                      final GL2ES3 gl2es3 = gl.getRootGL().getGL2ES3();
+                      gl2es3.glBindVertexArray(0);
+                      gl2es3.glDeleteVertexArrays(1, tmp, 0);
                       defaultVAO = 0;
                   }
                   glDebugHandler.enable(false);
@@ -663,10 +663,13 @@ public abstract class GLContextImpl extends GLContext {
             created = createImpl(shareWithHandle); // may throws exception if fails
             if( created && hasNoDefaultVAO() ) {
                 final int[] tmp = new int[1];
-                final GL3ES3 gl3es3 = gl.getRootGL().getGL3ES3();
-                gl3es3.glGenVertexArrays(1, tmp, 0);
-                defaultVAO = tmp[0];
-                gl3es3.glBindVertexArray(defaultVAO);
+                final GL rootGL = gl.getRootGL();
+                if( rootGL.isGL2ES3() ) { // FIXME remove if ES2 == ES3 later
+                    final GL2ES3 gl2es3 = rootGL.getGL2ES3();
+                    gl2es3.glGenVertexArrays(1, tmp, 0);
+                    defaultVAO = tmp[0];
+                    gl2es3.glBindVertexArray(defaultVAO);
+                }
             }
         } finally {
             if (null != shareWith) {
@@ -1449,12 +1452,20 @@ public abstract class GLContextImpl extends GLContext {
             // Strict Match (GLVersionMapping):
             //   Relaxed match for versions ( !isES && major < 3 ) requests, last resort!
             //   Otherwise:
-            //     - fail if hasVersion < reqVersion
-            //     - fail if ES major-version mismatch
+            //     - fail if hasVersion < reqVersion (desktop and ES)
+            //     - fail if ES major-version mismatch:
+            //       - request 1, >= 3 must be equal
+            //       - request 2 must be [2..3]
             //
+            final int hasMajor = hasGLVersionByInt.getMajor();
             if( strictMatch &&
                 ( ( ( isES || major >= 3 ) && hasGLVersionByInt.compareTo(reqGLVersion) < 0 ) ||
-                  ( isES && major != hasGLVersionByInt.getMajor() )
+                  ( isES &&
+                    (
+                      ( 2 == major && ( 2 > hasMajor || hasMajor > 3 ) ) ||  // 2      -> [2..3]
+                      ( ( 1 == major || 3 <= major ) && major != hasMajor )  // 1,3,.. -> equal
+                    )
+                  )
                 ) ) {
                 if(DEBUG) {
                     System.err.println(getThreadName() + ": GLContext.setGLFuncAvail.X: FAIL, GL version mismatch (Int): "+GLContext.getGLVersion(major, minor, ctxProfileBits, null)+" -> "+glVersion+", "+hasGLVersionByInt);
@@ -1484,12 +1495,20 @@ public abstract class GLContextImpl extends GLContext {
             // Strict Match (GLVersionMapping):
             //   Relaxed match for versions ( !isES && major < 3 ) requests, last resort!
             //   Otherwise:
-            //     - fail if hasVersion < reqVersion
-            //     - fail if ES major-version mismatch
+            //     - fail if hasVersion < reqVersion (desktop and ES)
+            //     - fail if ES major-version mismatch:
+            //       - request 1, >= 3 must be equal
+            //       - request 2 must be [2..3]
             //
+            final int hasMajor = hasGLVersionByString.getMajor();
             if( strictMatch &&
                 ( ( ( isES || major >= 3 ) && hasGLVersionByString.compareTo(reqGLVersion) < 0 ) ||
-                  ( isES && major != hasGLVersionByString.getMajor() )
+                  ( isES &&
+                    (
+                      ( 2 == major && ( 2 > hasMajor || hasMajor > 3 ) ) ||  // 2      -> [2..3]
+                      ( ( 1 == major || 3 <= major ) && major != hasMajor )  // 1,3,.. -> equal
+                    )
+                  )
                 ) ) {
                 if(DEBUG) {
                     System.err.println(getThreadName() + ": GLContext.setGLFuncAvail.X: FAIL, GL version mismatch (String): "+GLContext.getGLVersion(major, minor, ctxProfileBits, null)+" -> "+glVersion+", "+hasGLVersionByString);
@@ -1529,7 +1548,9 @@ public abstract class GLContextImpl extends GLContext {
 
     final VersionNumberString vendorVersion = GLVersionNumber.createVendorVersion(glVersion);
 
-    setRendererQuirks(adevice, reqGLVersion.getMajor(), reqGLVersion.getMinor(), reqCtxProfileBits, major, minor, ctxProfileBits, vendorVersion, withinGLVersionsMapping);
+    setRendererQuirks(adevice, getDrawableImpl().getFactoryImpl(),
+                      reqGLVersion.getMajor(), reqGLVersion.getMinor(), reqCtxProfileBits,
+                      major, minor, ctxProfileBits, vendorVersion, withinGLVersionsMapping);
 
     if( strictMatch && glRendererQuirks.exist(GLRendererQuirks.GLNonCompliant) ) {
         if(DEBUG) {
@@ -1646,7 +1667,7 @@ public abstract class GLContextImpl extends GLContext {
     return true;
   }
 
-  private final void setRendererQuirks(final AbstractGraphicsDevice adevice,
+  private final void setRendererQuirks(final AbstractGraphicsDevice adevice, final GLDrawableFactoryImpl factory,
                                        int reqMajor, int reqMinor, int reqCTP,
                                        int major, int minor, int ctp, final VersionNumberString vendorVersion,
                                        boolean withinGLVersionsMapping) {
@@ -1658,6 +1679,7 @@ public abstract class GLContextImpl extends GLContext {
     final String MesaRendererIntelsp = "Intel(R)";
     final boolean hwAccel = 0 == ( ctp & GLContext.CTX_IMPL_ACCEL_SOFT );
     final boolean compatCtx = 0 != ( ctp & GLContext.CTX_PROFILE_COMPAT );
+    final boolean esCtx = 0 != ( ctp & GLContext.CTX_PROFILE_ES );
     final boolean isX11 = NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(true);
     final boolean isWindows = Platform.getOSType() == Platform.OSType.WINDOWS;
     final boolean isDriverMesa = glRenderer.contains(MesaSP) || glRenderer.contains("Gallium ");
@@ -1665,6 +1687,28 @@ public abstract class GLContextImpl extends GLContext {
     final boolean isDriverNVIDIAGeForce = !isDriverMesa && ( glVendor.contains("NVIDIA Corporation") || glRenderer.contains("NVIDIA ") );
 
     //
+    // General Quirks
+    //
+    if( esCtx ) {
+        if( 2 == reqMajor && 2 < major ) {
+            final int quirk = GLRendererQuirks.GLES3ViaEGLES2Config;
+            if(DEBUG) {
+                System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: ES req "+reqMajor+" and 2 < "+major);
+            }
+            quirks[i++] = quirk;
+            if( withinGLVersionsMapping ) {
+                // Thread safe due to single threaded initialization!
+                GLRendererQuirks.addStickyDeviceQuirks(adevice, quirks, i-1, 1);
+            } else {
+                // FIXME: Remove when moving EGL/ES to ARB ctx creation
+                synchronized(GLContextImpl.class) {
+                    GLRendererQuirks.addStickyDeviceQuirks(adevice, quirks, i-1, 1);
+                }
+            }
+        }
+    }
+
+    //
     // OS related quirks
     //
     if( Platform.getOSType() == Platform.OSType.MACOS ) {
@@ -1746,14 +1790,14 @@ public abstract class GLContextImpl extends GLContext {
         if( glRenderer.contains("PowerVR") ) {
             final int quirk = GLRendererQuirks.NoSetSwapInterval;
             if(DEBUG) {
-                System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: OS "+Platform.getOSType() + " / Renderer " + glRenderer);
+                System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: OS "+Platform.getOSType() + ", Renderer " + glRenderer);
             }
             quirks[i++] = quirk;
         }
         if( glRenderer.contains("Immersion.16") ) {
           final int quirk = GLRendererQuirks.GLSharedContextBuggy;
           if(DEBUG) {
-              System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: OS "+Platform.getOSType() + " / Renderer " + glRenderer);
+              System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: OS "+Platform.getOSType() + ", Renderer " + glRenderer);
           }
           quirks[i++] = quirk;
         }
@@ -1858,9 +1902,27 @@ public abstract class GLContextImpl extends GLContext {
     }
 
     glRendererQuirks = new GLRendererQuirks(quirks, 0, i);
-    GLRendererQuirks.pushStickyDeviceQuirks(adevice, glRendererQuirks); // Thread safe due to single threaded initialization!
     if(DEBUG) {
-        System.err.println("Quirks local: "+glRendererQuirks);
+        System.err.println("Quirks local.0: "+glRendererQuirks);
+    }
+    {
+        // Merge sticky quirks, thread safe due to single threaded initialization!
+        GLRendererQuirks.pushStickyDeviceQuirks(adevice, glRendererQuirks);
+
+        final AbstractGraphicsDevice factoryDefaultDevice = factory.getDefaultDevice();
+        if( !GLRendererQuirks.areSameStickyDevice(factoryDefaultDevice, adevice) ) {
+            GLRendererQuirks.pushStickyDeviceQuirks(factoryDefaultDevice, glRendererQuirks);
+        }
+        if( esCtx ) {
+            final AbstractGraphicsDevice eglFactoryDefaultDevice = GLDrawableFactory.getEGLFactory().getDefaultDevice();
+            if( !GLRendererQuirks.areSameStickyDevice(eglFactoryDefaultDevice, adevice) &&
+                !GLRendererQuirks.areSameStickyDevice(eglFactoryDefaultDevice, factoryDefaultDevice) ) {
+                GLRendererQuirks.pushStickyDeviceQuirks(eglFactoryDefaultDevice, glRendererQuirks);
+            }
+        }
+    }
+    if(DEBUG) {
+        System.err.println("Quirks local.X: "+glRendererQuirks);
         System.err.println("Quirks sticky on "+adevice+": "+GLRendererQuirks.getStickyDeviceQuirks(adevice));
     }
   }
@@ -1868,7 +1930,7 @@ public abstract class GLContextImpl extends GLContext {
   private static final boolean hasFBOImpl(int major, int ctp, ExtensionAvailabilityCache extCache) {
     return ( 0 != (ctp & CTX_PROFILE_ES) && major >= 2 ) ||   // ES >= 2.0
 
-           major >= 3 ||                                                 // any >= 3.0 GL ctx
+           major >= 3 ||                                                 // any >= 3.0 GL ctx (core, compat and ES)
 
            ( null != extCache &&
 
@@ -2074,12 +2136,8 @@ public abstract class GLContextImpl extends GLContext {
   //----------------------------------------------------------------------
   // Helpers for buffer object optimizations
 
-  public final void setBufferSizeTracker(GLBufferSizeTracker bufferSizeTracker) {
-    this.bufferSizeTracker = bufferSizeTracker;
-  }
-
-  public final GLBufferSizeTracker getBufferSizeTracker() {
-    return bufferSizeTracker;
+  public final GLBufferObjectTracker getBufferObjectTracker() {
+    return bufferObjectTracker;
   }
 
   public final GLBufferStateTracker getBufferStateTracker() {
diff --git a/src/jogl/classes/jogamp/opengl/GLContextShareSet.java b/src/jogl/classes/jogamp/opengl/GLContextShareSet.java
index 483767b..c057c90 100644
--- a/src/jogl/classes/jogamp/opengl/GLContextShareSet.java
+++ b/src/jogl/classes/jogamp/opengl/GLContextShareSet.java
@@ -262,30 +262,6 @@ public class GLContextShareSet {
     return false;
   }
 
-  /** In order to avoid glGet calls for buffer object checks related
-      to glVertexPointer, etc. calls as well as glMapBuffer calls, we
-      need to share the same GLBufferSizeTracker object between
-      contexts sharing textures and display lists. For now we keep
-      this mechanism orthogonal to the GLObjectTracker to hopefully
-      keep things easier to understand. (The GLObjectTracker is
-      currently only needed in a fairly esoteric case, when the
-      Java2D/JOGL bridge is active, but the GLBufferSizeTracker
-      mechanism is now always required.) */
-  public static void synchronizeBufferObjectSharing(final GLContext olderContextOrNull, final GLContext newContext) {
-    final GLContextImpl older = (GLContextImpl) olderContextOrNull;
-    final GLContextImpl newer = (GLContextImpl) newContext;
-    GLBufferSizeTracker tracker = null;
-    if (older != null) {
-      tracker = older.getBufferSizeTracker();
-      assert (tracker != null)
-        : "registerForBufferObjectSharing was not called properly for the older context, or has a bug in it";
-    }
-    if (tracker == null) {
-      tracker = new GLBufferSizeTracker();
-    }
-    newer.setBufferSizeTracker(tracker);
-  }
-
   //----------------------------------------------------------------------
   // Internals only below this point
 
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java
index 61735c4..0e135d5 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java
@@ -58,6 +58,7 @@ import javax.media.opengl.GLEventListener;
 import javax.media.opengl.GLException;
 import javax.media.opengl.GLFBODrawable;
 import javax.media.opengl.GLRunnable;
+import javax.media.opengl.GLSharedContextSetter;
 
 /** Encapsulates the implementation of most of the GLAutoDrawable's
     methods to be able to share it between GLAutoDrawable implementations like GLAutoDrawableBase, GLCanvas and GLJPanel. */
@@ -149,8 +150,14 @@ public class GLDrawableHelper {
       final GLContext shareWith;
       final boolean pending;
       if ( null != sharedAutoDrawable ) {
+          final boolean allGLELInitialized;
+          if( sharedAutoDrawable instanceof GLSharedContextSetter ) {
+              allGLELInitialized = ((GLSharedContextSetter)sharedAutoDrawable).areAllGLEventListenerInitialized();
+          } else {
+              allGLELInitialized = true; // we have to assume 'yes'
+          }
           shareWith = sharedAutoDrawable.getContext();
-          pending = null == shareWith || !shareWith.isCreated();
+          pending = null == shareWith || !shareWith.isCreated() || !allGLELInitialized;
       } else {
           shareWith = sharedContext;
           pending = null != shareWith && !shareWith.isCreated();
@@ -331,24 +338,27 @@ public class GLDrawableHelper {
   public static final GLDrawableImpl resizeOffscreenDrawable(GLDrawableImpl drawable, GLContext context, int newWidth, int newHeight)
           throws NativeWindowException, GLException
   {
-      if(drawable.getChosenGLCapabilities().isOnscreen()) {
-          throw new NativeWindowException("Drawable is not offscreen: "+drawable);
-      }
       final NativeSurface ns = drawable.getNativeSurface();
       final int lockRes = ns.lockSurface();
-      if (NativeSurface.LOCK_SURFACE_NOT_READY >= lockRes) {
+      if ( NativeSurface.LOCK_SURFACE_NOT_READY >= lockRes ) {
           throw new NativeWindowException("Could not lock surface of drawable: "+drawable);
       }
       boolean validateSize = true;
       try {
-          if(DEBUG && ( 0>=newWidth || 0>=newHeight) ) {
+          if( ! drawable.isRealized() ) {
+              return drawable;
+          }
+          if( drawable.getChosenGLCapabilities().isOnscreen() ) {
+              throw new NativeWindowException("Drawable is not offscreen: "+drawable);
+          }
+          if( DEBUG && ( 0>=newWidth || 0>=newHeight) ) {
               System.err.println("WARNING: Odd size detected: "+newWidth+"x"+newHeight+", using safe size 1x1. Drawable "+drawable);
               Thread.dumpStack();
           }
-          if(0>=newWidth)  { newWidth = 1; validateSize=false; }
-          if(0>=newHeight) { newHeight = 1; validateSize=false; }
+          if( 0 >= newWidth )  { newWidth = 1; validateSize=false; }
+          if( 0 >= newHeight ) { newHeight = 1; validateSize=false; }
           // propagate new size
-          if(ns instanceof ProxySurface) {
+          if( ns instanceof ProxySurface ) {
               final ProxySurface ps = (ProxySurface) ns;
               final UpstreamSurfaceHook ush = ps.getUpstreamSurfaceHook();
               if(ush instanceof UpstreamSurfaceHook.MutableSize) {
@@ -359,7 +369,7 @@ public class GLDrawableHelper {
           } else if(DEBUG) { // we have to assume surface contains the new size already, hence size check @ bottom
               System.err.println("GLDrawableHelper.resizeOffscreenDrawable: Drawable's offscreen surface n.a. ProxySurface, but "+ns.getClass().getName()+": "+ns);
           }
-          if(drawable instanceof GLFBODrawable) {
+          if( drawable instanceof GLFBODrawable ) {
               if( null != context && context.isCreated() ) {
                   ((GLFBODrawable) drawable).resetSize(context.getGL());
               }
@@ -431,6 +441,12 @@ public class GLDrawableHelper {
     }
   }
 
+  public final boolean areAllGLEventListenerInitialized() {
+    synchronized(listenersLock) {
+        return 0 == listenersToBeInit.size();
+    }
+  }
+
   public final boolean getGLEventListenerInitState(GLEventListener listener) {
     synchronized(listenersLock) {
         return !listenersToBeInit.contains(listener);
diff --git a/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java
index ab31892..0e9d142 100644
--- a/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java
@@ -90,7 +90,7 @@ public class GLFBODrawableImpl extends GLDrawableImpl implements GLFBODrawable {
         this.initialized = false;
 
         this.parent = parent;
-        this.origParentChosenCaps = (GLCapabilitiesImmutable) getChosenGLCapabilities(); // just to avoid null, will be reset at initialize(..)
+        this.origParentChosenCaps = getChosenGLCapabilities(); // just to avoid null, will be reset at initialize(..)
         this.texUnit = textureUnit;
         this.samples = fboCaps.getNumSamples();
         fboResetQuirk = false;
@@ -552,7 +552,7 @@ public class GLFBODrawableImpl extends GLDrawableImpl implements GLFBODrawable {
                 ",\n\tfboI back "+fboIBack+", front "+fboIFront+", num "+(initialized ? fbos.length : 0)+
                 ",\n\tFBO front read "+getDefaultReadFramebuffer()+", "+getFBObject(GL.GL_FRONT)+
                 ",\n\tFBO back  write "+getDefaultDrawFramebuffer()+", "+getFBObject(GL.GL_BACK)+
-                ",\n\tSurface   "+getNativeSurface()+
+                ",\n\tSurface   "+surface+
                 "]";
     }
 
diff --git a/src/jogl/classes/jogamp/opengl/MemoryObject.java b/src/jogl/classes/jogamp/opengl/MemoryObject.java
index d107476..6ebefc5 100644
--- a/src/jogl/classes/jogamp/opengl/MemoryObject.java
+++ b/src/jogl/classes/jogamp/opengl/MemoryObject.java
@@ -31,17 +31,18 @@ package jogamp.opengl;
 import java.nio.ByteBuffer;
 import java.util.HashMap;
 
+import javax.media.opengl.GLBufferStorage;
+
 import com.jogamp.common.util.HashUtil;
 
 /**
- *
+ * @deprecated No more used for GL buffer storage tracking, see {@link GLBufferStorage} and {@link GLBufferObjectTracker}.
  */
 public class MemoryObject {
-    private long addr;
-    private long size;
-    private int  hash;
+    private final long addr;
+    private final long size;
+    private final int  hash;
     private ByteBuffer buffer=null;
-
     public MemoryObject(long addr, long size) {
         this.addr = addr;
         this.size = size;
@@ -70,17 +71,33 @@ public class MemoryObject {
     }
 
     /**
+     * Ignores the optional attached <code>ByteBuffer</code> intentionally.<br>
+     *
+     * @return true of reference is equal or <code>obj</code> is of type <code>MemoryObject</code>
+     *         and <code>addr</code> and <code>size</code> is equal.<br>
+     */
+    public boolean equals(Object obj) {
+        if(this == obj) { return true; }
+        if(obj instanceof MemoryObject) {
+            final MemoryObject m = (MemoryObject) obj;
+            return addr == m.addr && size == m.size ;
+        }
+        return false;
+    }
+
+    /**
      * @param map the identity HashMap, MemoryObject to MemoryObject
      * @param obj0 the MemoryObject
      * @return either the already mapped MemoryObject - not changing the map, or the newly mapped one.
      */
     public static MemoryObject getOrAddSafe(HashMap<MemoryObject,MemoryObject> map, MemoryObject obj0) {
-        MemoryObject obj1 = map.get(obj0); // get identity (fast)
+        final MemoryObject obj1 = map.get(obj0); // get identity (fast)
         if(null == obj1) {
             map.put(obj0, obj0);
-            obj1 = obj0;
+            return obj0;
+        } else {
+            return obj1;
         }
-        return obj1;
     }
 
 }
\ No newline at end of file
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
index b2f06dc..f89ded4 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
@@ -44,6 +44,7 @@ import javax.media.nativewindow.AbstractGraphicsConfiguration;
 import javax.media.nativewindow.AbstractGraphicsDevice;
 import javax.media.opengl.GLCapabilitiesImmutable;
 import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawableFactory;
 import javax.media.opengl.GLException;
 import javax.media.opengl.GLProfile;
 
@@ -187,7 +188,11 @@ public class EGLContext extends GLContextImpl {
         {
             if ( glProfile.usesNativeGLES3() ) {
                 contextVersionReq = 3;
-                contextVersionAttr = 3;
+                if( GLRendererQuirks.existStickyDeviceQuirk( GLDrawableFactory.getEGLFactory().getDefaultDevice(), GLRendererQuirks.GLES3ViaEGLES2Config) ) {
+                    contextVersionAttr = 2;
+                } else {
+                    contextVersionAttr = 3;
+                }
             } else if ( glProfile.usesNativeGLES2() ) {
                 contextVersionReq = 2;
                 contextVersionAttr = 2;
@@ -314,27 +319,23 @@ public class EGLContext extends GLContextImpl {
         }
         mapStaticGLVersion(device, reqMajorCTP[0], 0, reqMajorCTP[1]);
     }
-    /* pp */ static void mapStaticGLESVersion(AbstractGraphicsDevice device, final int major) {
-        int ctp = GLContext.CTX_PROFILE_ES;
-        if( major >= 3 ) {
-            ctp |= GLContext.CTX_IMPL_ES3_COMPAT | GLContext.CTX_IMPL_ES2_COMPAT | GLContext.CTX_IMPL_FBO ;
-        } else if( major >= 2 ) {
-            ctp |= GLContext.CTX_IMPL_ES2_COMPAT | GLContext.CTX_IMPL_FBO ;
-        }
-        mapStaticGLVersion(device, major, 0, ctp);
-    }
     /* pp */ static void mapStaticGLVersion(AbstractGraphicsDevice device, int major, int minor, int ctp) {
         if( 0 != ( ctp & GLContext.CTX_PROFILE_ES) ) {
-            // ES1 or ES2
-            final int reqMajor = major;
-            final int reqProfile = GLContext.CTX_PROFILE_ES;
-            GLContext.mapAvailableGLVersion(device, reqMajor, reqProfile, major, minor, ctp);
-            if(! ( device instanceof EGLGraphicsDevice ) ) {
-                final EGLGraphicsDevice eglDevice = new EGLGraphicsDevice(device.getHandle(), EGL.EGL_NO_DISPLAY, device.getConnection(), device.getUnitID(), null);
-                GLContext.mapAvailableGLVersion(eglDevice, reqMajor, reqProfile, major, minor, ctp);
+            // ES1, ES2, ES3, ..
+            mapStaticGLVersion(device, major /* reqMajor */, major, minor, ctp);
+            if( 3 == major ) {
+                // map ES2 -> ES3
+                mapStaticGLVersion(device, 2 /* reqMajor */, major, minor, ctp);
             }
         }
     }
+    private static void mapStaticGLVersion(AbstractGraphicsDevice device, int reqMajor, int major, int minor, int ctp) {
+        GLContext.mapAvailableGLVersion(device, reqMajor, GLContext.CTX_PROFILE_ES, major, minor, ctp);
+        if(! ( device instanceof EGLGraphicsDevice ) ) {
+            final EGLGraphicsDevice eglDevice = new EGLGraphicsDevice(device.getHandle(), EGL.EGL_NO_DISPLAY, device.getConnection(), device.getUnitID(), null);
+            GLContext.mapAvailableGLVersion(eglDevice, reqMajor, GLContext.CTX_PROFILE_ES, major, minor, ctp);
+        }
+    }
     protected static String getGLVersion(int major, int minor, int ctp, String gl_version) {
         return GLContext.getGLVersion(major, minor, ctp, gl_version);
     }
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java b/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
index 0577124..c5f76f6 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
@@ -49,57 +49,120 @@ import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
  * and <code>eglTerminate(..)</code> is issued only for the last call.
  * <p>
  * This class is required, due to implementation bugs within EGL where {@link EGL#eglTerminate(long)}
- * does not mark the resource for deletion when still in use, bug releases them immediatly.
+ * does not mark the resource for deletion when still in use, bug releases them immediately.
  * </p>
  */
 public class EGLDisplayUtil {
-    protected static final boolean DEBUG = Debug.debug("EGLDisplayUtil");
+    private static final boolean DEBUG = Debug.debug("EGLDisplayUtil");
+    private static boolean useSingletonEGLDisplay = false;
+    private static EGLDisplayRef singletonEGLDisplay = null;
 
-    private static class DpyCounter {
+    private static class EGLDisplayRef {
         final long eglDisplay;
         final Throwable createdStack;
-        int refCount;
+        int initRefCount;
 
-        private DpyCounter(long eglDisplay) {
+        /**
+         * Returns an already opened {@link EGLDisplayRef} or opens a new {@link EGLDisplayRef}.
+         * <p>
+         * Opened {@link EGLDisplayRef}s are mapped against their <code>eglDisplay</code> handle.
+         * </p>
+         * <p>
+         * Method utilizes {@link EGLDisplayRef}'s reference counter, i.e. increases it.
+         * </p>
+         * <p>
+         * An {@link EGLDisplayRef} is <i>opened</i> via {@link EGL#eglInitialize(long, IntBuffer, IntBuffer)}.
+         * </p>
+         */
+        static EGLDisplayRef getOrCreateOpened(final long eglDisplay, final IntBuffer major, final IntBuffer minor) {
+            EGLDisplayRef o = (EGLDisplayRef) openEGLDisplays.get(eglDisplay);
+            if( null == o ) {
+                if( EGL.eglInitialize(eglDisplay, major, minor) ) {
+                    final EGLDisplayRef n = new EGLDisplayRef(eglDisplay);
+                    openEGLDisplays.put(eglDisplay, n);
+                    n.initRefCount++;
+                    if( null == singletonEGLDisplay ) {
+                        singletonEGLDisplay = n;
+                    }
+                    return n;
+                } else {
+                    return null;
+                }
+            } else {
+                o.initRefCount++;
+                return o;
+            }
+        }
+
+        /**
+         * Closes an already opened {@link EGLDisplayRef}.
+         * <p>
+         * Method decreases a reference counter and closes the {@link EGLDisplayRef} if it reaches zero.
+         * </p>
+         * <p>
+         * An {@link EGLDisplayRef} is <i>closed</i> via {@link EGL#eglTerminate(long)}.
+         * </p>
+         */
+        static EGLDisplayRef closeOpened(final long eglDisplay, final boolean[] res) {
+            final EGLDisplayRef o = (EGLDisplayRef) openEGLDisplays.get(eglDisplay);
+            res[0] = true;
+            if( null != o ) {
+                if( 0 < o.initRefCount ) { // no negative refCount
+                    o.initRefCount--;
+                    if( 0 == o.initRefCount ) {
+                        res[0] = EGL.eglTerminate(eglDisplay);
+                        if( o == singletonEGLDisplay ) {
+                            singletonEGLDisplay = null;
+                        }
+                    }
+                }
+                if( 0 >= o.initRefCount ) {
+                    openEGLDisplays.remove(eglDisplay);
+                }
+            }
+            return o;
+        }
+
+        private EGLDisplayRef(long eglDisplay) {
             this.eglDisplay = eglDisplay;
-            this.refCount = 0;
+            this.initRefCount = 0;
             this.createdStack = DEBUG ? new Throwable() : null;
         }
 
         @Override
         public String toString() {
-            return "EGLDisplay[0x"+Long.toHexString(eglDisplay)+": refCnt "+refCount+"]";
+            return "EGLDisplayRef[0x"+Long.toHexString(eglDisplay)+": refCnt "+initRefCount+"]";
         }
     }
-    static final LongObjectHashMap eglDisplayCounter;
+    private static final LongObjectHashMap openEGLDisplays;
 
     static {
-        eglDisplayCounter = new LongObjectHashMap();
-        eglDisplayCounter.setKeyNotFoundValue(null);
+        openEGLDisplays = new LongObjectHashMap();
+        openEGLDisplays.setKeyNotFoundValue(null);
     }
 
     /**
      * @return number of unclosed EGL Displays.<br>
      */
     public static int shutdown(boolean verbose) {
-        if(DEBUG || verbose || eglDisplayCounter.size() > 0 ) {
-            System.err.println("EGLDisplayUtil.EGLDisplays: Shutdown (open: "+eglDisplayCounter.size()+")");
+        if(DEBUG || verbose || openEGLDisplays.size() > 0 ) {
+            System.err.println("EGLDisplayUtil.EGLDisplays: Shutdown (open: "+openEGLDisplays.size()+")");
             if(DEBUG) {
                 Thread.dumpStack();
             }
-            if( eglDisplayCounter.size() > 0) {
+            if( openEGLDisplays.size() > 0) {
                 dumpOpenDisplayConnections();
             }
         }
-        return eglDisplayCounter.size();
+        return openEGLDisplays.size();
     }
 
     public static void dumpOpenDisplayConnections() {
-        System.err.println("EGLDisplayUtil: Open EGL Display Connections: "+eglDisplayCounter.size());
+        System.err.println("EGLDisplayUtil: Open EGL Display Connections: "+openEGLDisplays.size());
         int i=0;
-        for(Iterator<LongObjectHashMap.Entry> iter = eglDisplayCounter.iterator(); iter.hasNext(); i++) {
+        for(Iterator<LongObjectHashMap.Entry> iter = openEGLDisplays.iterator(); iter.hasNext(); i++) {
             final LongObjectHashMap.Entry e = iter.next();
-            final DpyCounter v = (DpyCounter) e.value;
+            final EGLDisplayRef v = (EGLDisplayRef) e.value;
             System.err.println("EGLDisplayUtil: Open["+i+"]: 0x"+Long.toHexString(e.key)+": "+v);
             if(null != v.createdStack) {
                 v.createdStack.printStackTrace();
@@ -107,12 +170,22 @@ public class EGLDisplayUtil {
         }
     }
 
-    public static long eglGetDisplay(long nativeDisplay_id)  {
+    /* pp */ static synchronized void setSingletonEGLDisplayOnly(boolean v) { useSingletonEGLDisplay = v; }
+
+    private static synchronized long eglGetDisplay(long nativeDisplay_id)  {
+        if( useSingletonEGLDisplay && null != singletonEGLDisplay ) {
+            if(DEBUG) {
+                System.err.println("EGLDisplayUtil.eglGetDisplay.s: eglDisplay("+EGLContext.toHexString(nativeDisplay_id)+"): "+
+                                   EGLContext.toHexString(singletonEGLDisplay.eglDisplay)+
+                                   ", "+((EGL.EGL_NO_DISPLAY != singletonEGLDisplay.eglDisplay)?"OK":"Failed")+", singletonEGLDisplay "+singletonEGLDisplay+" (use "+useSingletonEGLDisplay+")");
+            }
+            return singletonEGLDisplay.eglDisplay;
+        }
         final long eglDisplay = EGL.eglGetDisplay(nativeDisplay_id);
         if(DEBUG) {
-            System.err.println("EGLDisplayUtil.eglGetDisplay(): eglDisplay("+EGLContext.toHexString(nativeDisplay_id)+"): "+
+            System.err.println("EGLDisplayUtil.eglGetDisplay.X: eglDisplay("+EGLContext.toHexString(nativeDisplay_id)+"): "+
                                EGLContext.toHexString(eglDisplay)+
-                               ", "+((EGL.EGL_NO_DISPLAY != eglDisplay)?"OK":"Failed"));
+                               ", "+((EGL.EGL_NO_DISPLAY != eglDisplay)?"OK":"Failed")+", singletonEGLDisplay "+singletonEGLDisplay+" (use "+useSingletonEGLDisplay+")");
         }
         return eglDisplay;
     }
@@ -125,39 +198,16 @@ public class EGLDisplayUtil {
      *
      * @see EGL#eglInitialize(long, IntBuffer, IntBuffer)
      */
-    public static synchronized boolean eglInitialize(long eglDisplay, IntBuffer major, IntBuffer minor)  {
+    private static synchronized boolean eglInitialize(long eglDisplay, IntBuffer major, IntBuffer minor)  {
         if( EGL.EGL_NO_DISPLAY == eglDisplay) {
             return false;
         }
-        final int refCnt;
-        final DpyCounter d;
-        {
-            DpyCounter _d = (DpyCounter) eglDisplayCounter.get(eglDisplay);
-            if(null == _d) {
-                _d = new DpyCounter(eglDisplay);
-                refCnt = 1; // 1st init
-            } else {
-                refCnt = _d.refCount + 1;
-            }
-            d = _d;
-        }
-        final boolean res;
-        if(1==refCnt) { // only initialize once
-            res = EGL.eglInitialize(eglDisplay, major, minor);
-        } else {
-            res = true;
-        }
-        if(res) { // update refCount and map if successfully initialized, only
-            d.refCount = refCnt;
-            if(1 == refCnt) {
-                eglDisplayCounter.put(eglDisplay, d);
-            }
-        }
+        final EGLDisplayRef d = EGLDisplayRef.getOrCreateOpened(eglDisplay, major, minor);
         if(DEBUG) {
-            System.err.println("EGLDisplayUtil.eglInitialize("+EGLContext.toHexString(eglDisplay)+" ...): #"+refCnt+", "+d+" = "+res);
+            System.err.println("EGLDisplayUtil.eglInitialize("+EGLContext.toHexString(eglDisplay)+" ...): "+d+" = "+(null != d)+", singletonEGLDisplay "+singletonEGLDisplay+" (use "+useSingletonEGLDisplay+")");
             // Thread.dumpStack();
         }
-        return res;
+        return null != d;
     }
 
     /**
@@ -172,14 +222,14 @@ public class EGLDisplayUtil {
      * @see #eglGetDisplay(long)
      * @see #eglInitialize(long, IntBuffer, IntBuffer)
      */
-    public static synchronized int eglGetDisplayAndInitialize(long nativeDisplayID, long[] eglDisplay, int[] eglErr, IntBuffer major, IntBuffer minor) {
+    private static synchronized int eglGetDisplayAndInitialize(long nativeDisplayID, long[] eglDisplay, int[] eglErr, IntBuffer major, IntBuffer minor) {
         eglDisplay[0] = EGL.EGL_NO_DISPLAY;
-        final long _eglDisplay = EGLDisplayUtil.eglGetDisplay( nativeDisplayID );
+        final long _eglDisplay = eglGetDisplay( nativeDisplayID );
         if ( EGL.EGL_NO_DISPLAY == _eglDisplay ) {
             eglErr[0] = EGL.eglGetError();
             return EGL.EGL_BAD_DISPLAY;
         }
-        if ( !EGLDisplayUtil.eglInitialize( _eglDisplay, major, minor) ) {
+        if ( !eglInitialize( _eglDisplay, major, minor) ) {
             eglErr[0] = EGL.eglGetError();
             return EGL.EGL_NOT_INITIALIZED;
         }
@@ -188,11 +238,16 @@ public class EGLDisplayUtil {
     }
 
     /**
+     * Attempts to {@link #eglGetDisplayAndInitialize(long, long[], int[], IntBuffer, IntBuffer)} with given <code>nativeDisplayID</code>.
+     * If this fails, method retries with <code>nativeDisplayID</code> {@link EGL#EGL_DEFAULT_DISPLAY} - the fallback mechanism.
+     * The actual used <code>nativeDisplayID</code> is returned in it's in/out array.
+     *
+     * @throws GLException if {@link EGL#eglGetDisplay(long)} or {@link EGL#eglInitialize(long, int[], int, int[], int)} fails incl fallback
      * @param nativeDisplayID in/out array of size 1, passing the requested nativeVisualID, may return a different revised nativeVisualID handle
      * @return the initialized EGL display ID
      * @throws GLException if not successful
      */
-    public static synchronized long eglGetDisplayAndInitialize(long[] nativeDisplayID) {
+    private static synchronized long eglGetDisplayAndInitialize(long[] nativeDisplayID) {
         final long[] eglDisplay = new long[1];
         final int[] eglError = new int[1];
         int eglRes = EGLDisplayUtil.eglGetDisplayAndInitialize(nativeDisplayID[0], eglDisplay, eglError, null, null);
@@ -216,40 +271,20 @@ public class EGLDisplayUtil {
      * @param eglDisplay the EGL display handle
      * @return true if the eglDisplay is valid and it's reference counter becomes zero and {@link EGL#eglTerminate(long)} was successful, otherwise false
      */
-    public static synchronized boolean eglTerminate(long eglDisplay)  {
+    private static synchronized boolean eglTerminate(long eglDisplay)  {
         if( EGL.EGL_NO_DISPLAY == eglDisplay) {
             return false;
         }
-        final boolean res;
-        final int refCnt;
-        final DpyCounter d;
-        {
-            DpyCounter _d = (DpyCounter) eglDisplayCounter.get(eglDisplay);
-            if(null == _d) {
-                _d = null;
-                refCnt = -1; // n/a
-            } else {
-                refCnt = _d.refCount - 1; // 1 - 1 = 0 -> final terminate
-            }
-            d = _d;
-        }
-        if( 0 == refCnt ) { // no terminate if still in use or already terminated
-            res = EGL.eglTerminate(eglDisplay);
-            eglDisplayCounter.remove(eglDisplay);
-        } else {
-            if(0 < refCnt) { // no negative refCount
-                d.refCount = refCnt;
-            }
-            res = true;
-        }
+        final boolean[] res = new boolean[1];
+        final EGLDisplayRef d = EGLDisplayRef.closeOpened(eglDisplay, res);
         if(DEBUG) {
-            System.err.println("EGLDisplayUtil.eglTerminate("+EGLContext.toHexString(eglDisplay)+" ...): #"+refCnt+" = "+res);
+            System.err.println("EGLDisplayUtil.eglTerminate.X("+EGLContext.toHexString(eglDisplay)+" ...): "+d+" = "+res[0]+", singletonEGLDisplay "+singletonEGLDisplay+" (use "+useSingletonEGLDisplay+")");
             // Thread.dumpStack();
         }
-        return res;
+        return res[0];
     }
 
-    public static final EGLGraphicsDevice.EGLDisplayLifecycleCallback eglLifecycleCallback = new EGLGraphicsDevice.EGLDisplayLifecycleCallback() {
+    private static final EGLGraphicsDevice.EGLDisplayLifecycleCallback eglLifecycleCallback = new EGLGraphicsDevice.EGLDisplayLifecycleCallback() {
         @Override
         public long eglGetAndInitDisplay(long[] nativeDisplayID) {
             return eglGetDisplayAndInitialize(nativeDisplayID);
@@ -261,24 +296,34 @@ public class EGLDisplayUtil {
     };
 
     /**
+     * Returns an uninitialized {@link EGLGraphicsDevice}. User needs to issue {@link EGLGraphicsDevice#open()} before usage.
+     * <p>
+     * Using {@link #eglGetDisplayAndInitialize(long[])} for the {@link EGLGraphicsDevice#open()} implementation
+     * and {@link #eglTerminate(long)} for {@link EGLGraphicsDevice#close()}.
+     * </p>
+     * <p>
      * Using the default {@link ToolkitLock}, via {@link NativeWindowFactory#getDefaultToolkitLock(String, long)}.
+     * </p>
      * @param nativeDisplayID
      * @param connection
      * @param unitID
-     * @return an initialized EGLGraphicsDevice
-     * @throws GLException if {@link EGL#eglGetDisplay(long)} or {@link EGL#eglInitialize(long, int[], int, int[], int)} fails
-     * @see EGLGraphicsDevice#EGLGraphicsDevice(long, long, String, int, com.jogamp.nativewindow.egl.EGLGraphicsDevice.EGLDisplayLifecycleCallback)
+     * @return an uninitialized {@link EGLGraphicsDevice}
      */
     public static EGLGraphicsDevice eglCreateEGLGraphicsDevice(long nativeDisplayID, String connection, int unitID)  {
-        final EGLGraphicsDevice eglDisplay = new EGLGraphicsDevice(nativeDisplayID, EGL.EGL_NO_DISPLAY, connection, unitID, eglLifecycleCallback);
-        eglDisplay.open();
-        return eglDisplay;
+        return new EGLGraphicsDevice(nativeDisplayID, EGL.EGL_NO_DISPLAY, connection, unitID, eglLifecycleCallback);
     }
 
     /**
+     * Returns an uninitialized {@link EGLGraphicsDevice}. User needs to issue {@link EGLGraphicsDevice#open()} before usage.
+     * <p>
+     * Using {@link #eglGetDisplayAndInitialize(long[])} for the {@link EGLGraphicsDevice#open()} implementation
+     * and {@link #eglTerminate(long)} for {@link EGLGraphicsDevice#close()}.
+     * </p>
+     * <p>
+     * Using the default {@link ToolkitLock}, via {@link NativeWindowFactory#getDefaultToolkitLock(String, long)}.
+     * </p>
      * @param surface
-     * @return an initialized EGLGraphicsDevice
-     * @throws GLException if {@link EGL#eglGetDisplay(long)} or {@link EGL#eglInitialize(long, int[], int, int[], int)} fails incl fallback
+     * @return an uninitialized EGLGraphicsDevice
      */
     public static EGLGraphicsDevice eglCreateEGLGraphicsDevice(NativeSurface surface)  {
         final long nativeDisplayID;
@@ -288,8 +333,6 @@ public class EGLDisplayUtil {
             nativeDisplayID = surface.getDisplayHandle(); // 0 == EGL.EGL_DEFAULT_DISPLAY
         }
         final AbstractGraphicsDevice adevice = surface.getGraphicsConfiguration().getScreen().getDevice();
-        final EGLGraphicsDevice eglDevice = new EGLGraphicsDevice(nativeDisplayID, EGL.EGL_NO_DISPLAY, adevice.getConnection(), adevice.getUnitID(), eglLifecycleCallback);
-        eglDevice.open();
-        return eglDevice;
+        return new EGLGraphicsDevice(nativeDisplayID, EGL.EGL_NO_DISPLAY, adevice.getConnection(), adevice.getUnitID(), eglLifecycleCallback);
     }
 }
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
index f7799f1..9ee0134 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
@@ -192,8 +192,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
                     }
                     sharedMap = new HashMap<String /*uniqueKey*/, SharedResource>();
                     sharedMapCreateAttempt = new HashSet<String>();
-
-                    // FIXME: Following triggers eglInitialize(..) which crashed on Windows w/ Chrome/Angle, FF/Angle!
+                    // FIXME: defaultDevice.open() triggers eglInitialize(..) which crashed on Windows w/ Chrome/ANGLE, FF/ANGLE!
                     defaultDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
                 }
             }
@@ -362,10 +361,17 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
         return new ArrayList<GLCapabilitiesImmutable>(0);
     }
 
-    private boolean mapAvailableEGLESConfig(AbstractGraphicsDevice adevice, int esProfile,
+    private static void dumpEGLInfo(final String prefix, final long eglDisplay) {
+        final String eglVendor = EGL.eglQueryString(eglDisplay, EGL.EGL_VENDOR);
+        final String eglClientAPIs = EGL.eglQueryString(eglDisplay, EGL.EGL_CLIENT_APIS);
+        final String eglVersion = EGL.eglQueryString(eglDisplay, EGL.EGL_VERSION);
+        System.err.println(prefix+"EGL vendor "+eglVendor+", version "+eglVersion+", clientAPIs "+eglClientAPIs);
+    }
+
+    private boolean mapAvailableEGLESConfig(AbstractGraphicsDevice adevice, int[] esProfile,
                                             boolean[] hasPBuffer, GLRendererQuirks[] rendererQuirks, int[] ctp) {
         final String profileString;
-        switch( esProfile ) {
+        switch( esProfile[0] ) {
             case 3:
                 profileString = GLProfile.GLES3; break;
             case 2:
@@ -383,7 +389,9 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
         }
         final GLProfile glp = GLProfile.get(adevice, profileString) ;
         final GLDrawableFactoryImpl desktopFactory = (GLDrawableFactoryImpl) GLDrawableFactory.getDesktopFactory();
-        final boolean mapsADeviceToDefaultDevice = !QUERY_EGL_ES_NATIVE_TK || null == desktopFactory || adevice instanceof EGLGraphicsDevice ;
+        final boolean initDefaultDevice = 0 == defaultDevice.getHandle(); // Note: GLProfile always triggers EGL device initialization first!
+        final boolean mapsADeviceToDefaultDevice = !QUERY_EGL_ES_NATIVE_TK || initDefaultDevice ||
+                                                   null == desktopFactory || adevice instanceof EGLGraphicsDevice ;
         if( DEBUG ) {
             System.err.println("EGLDrawableFactory.mapAvailableEGLESConfig: "+profileString+" ( "+esProfile+" ), "+
                                "defaultSharedResourceSet "+(null!=defaultSharedResource)+", mapsADeviceToDefaultDevice "+mapsADeviceToDefaultDevice+
@@ -394,8 +402,8 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
         EGLGraphicsDevice eglDevice = null;
         NativeSurface surface = null;
         ProxySurface upstreamSurface = null; // X11, GLX, ..
+        ProxySurface downstreamSurface = null; // EGL
         boolean success = false;
-        boolean deviceFromUpstreamSurface = false;
         try {
             final GLCapabilities reqCapsAny = new GLCapabilities(glp);
             reqCapsAny.setRedBits(5); reqCapsAny.setGreenBits(5); reqCapsAny.setBlueBits(5); reqCapsAny.setAlphaBits(0);
@@ -404,6 +412,24 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
             if( mapsADeviceToDefaultDevice ) {
                 // In this branch, any non EGL device is mapped to EGL default shared resources (default behavior).
                 // Only one default shared resource instance is ever be created.
+                if( initDefaultDevice ) {
+                    defaultDevice.open();
+
+                    // Probe for GLRendererQuirks.SingletonEGLDisplayOnly
+                    final long secondEGLDisplay = EGL.eglGetDisplay(EGL.EGL_DEFAULT_DISPLAY);
+                    if ( EGL.EGL_NO_DISPLAY == secondEGLDisplay ) {
+                        final int[] quirks = { GLRendererQuirks.SingletonEGLDisplayOnly };
+                        GLRendererQuirks.addStickyDeviceQuirks(adevice, quirks, 0, 1);
+                        EGLDisplayUtil.setSingletonEGLDisplayOnly(true);
+                        if(DEBUG) {
+                            System.err.println("Quirk: "+GLRendererQuirks.toString(quirks[0])+": cause: Second eglGetDisplay(EGL_DEFAULT_DISPLAY) failed");
+                        }
+                    }
+                }
+                if( DEBUG ) {
+                    dumpEGLInfo("EGLDrawableFactory.mapAvailableEGLESConfig: ", defaultDevice.getHandle());
+                }
+
                 final GLCapabilitiesImmutable reqCapsPBuffer = GLGraphicsConfigurationUtil.fixGLPBufferGLCapabilities(reqCapsAny);
                 final List<GLCapabilitiesImmutable> availablePBufferCapsL = getAvailableEGLConfigs(defaultDevice, reqCapsPBuffer);
                 hasPBuffer[0] = availablePBufferCapsL.size() > 0;
@@ -413,7 +439,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
                     if(null == defaultSharedResource) {
                         return false;
                     }
-                    switch(esProfile) {
+                    switch(esProfile[0]) {
                         case 3:
                             if( !defaultSharedResource.wasES3ContextCreated ) {
                                 return false;
@@ -436,26 +462,28 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
                             ctp[0] = defaultSharedResource.ctpES1;
                             break;
                     }
-                    EGLContext.mapStaticGLVersion(adevice, esProfile, 0, ctp[0]);
+                    if( null != rendererQuirks[0] ) {
+                        GLRendererQuirks.addStickyDeviceQuirks(adevice, rendererQuirks[0]);
+                    }
+                    EGLContext.mapStaticGLVersion(adevice, esProfile[0], 0, ctp[0]);
                     return true;
                 }
 
                 // attempt to created the default shared resources ..
 
-                eglDevice = defaultDevice; // reuse
-
                 if( hasPBuffer[0] ) {
                     // 2nd case create defaultDevice shared resource using pbuffer surface
-                    surface = createDummySurfaceImpl(eglDevice, false, reqCapsPBuffer, reqCapsPBuffer, null, 64, 64); // egl pbuffer offscreen
-                    upstreamSurface = (ProxySurface)surface;
-                    upstreamSurface.createNotify();
-                    deviceFromUpstreamSurface = false;
+                    downstreamSurface = createDummySurfaceImpl(defaultDevice, false, reqCapsPBuffer, reqCapsPBuffer, null, 64, 64); // egl pbuffer offscreen
+                    if( null != downstreamSurface ) {
+                        downstreamSurface.createNotify();
+                    }
+                    surface = downstreamSurface;
                 } else {
                     // 3rd case fake creation of defaultDevice shared resource, no pbuffer available
-                    final List<GLCapabilitiesImmutable> capsAnyL = getAvailableEGLConfigs(eglDevice, reqCapsAny);
+                    final List<GLCapabilitiesImmutable> capsAnyL = getAvailableEGLConfigs(defaultDevice, reqCapsAny);
                     if(capsAnyL.size() > 0) {
                         final GLCapabilitiesImmutable chosenCaps = capsAnyL.get(0);
-                        EGLContext.mapStaticGLESVersion(eglDevice, chosenCaps);
+                        EGLContext.mapStaticGLESVersion(defaultDevice, chosenCaps);
                         success = true;
                     }
                     if(DEBUG) {
@@ -463,15 +491,19 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
                         EGLGraphicsConfigurationFactory.printCaps("!PBufferCaps", capsAnyL, System.err);
                     }
                 }
+                eglDevice = defaultDevice; // reuse
             } else {
                 // 4th case always creates a true mapping of given device to EGL
-                surface = desktopFactory.createDummySurface(adevice, reqCapsAny, null, 64, 64); // X11, WGL, .. dummy window
-                upstreamSurface = ( surface instanceof ProxySurface ) ? (ProxySurface)surface : null ;
+                upstreamSurface = desktopFactory.createDummySurface(adevice, reqCapsAny, null, 64, 64); // X11, WGL, .. dummy window
                 if(null != upstreamSurface) {
                     upstreamSurface.createNotify();
                 }
+                surface = upstreamSurface;
                 eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(surface);
-                deviceFromUpstreamSurface = true;
+                eglDevice.open();
+                if( DEBUG ) {
+                    dumpEGLInfo("EGLDrawableFactory.mapAvailableEGLESConfig: ", eglDevice.getHandle());
+                }
                 hasPBuffer[0] = true;
             }
 
@@ -491,6 +523,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
                                 }
                                 rendererQuirks[0] = context.getRendererQuirks();
                                 ctp[0] = context.getContextOptions();
+                                esProfile[0] = context.getGLVersionNumber().getMajor();
                                 success = true;
                             } else {
                                 // Oops .. something is wrong
@@ -499,10 +532,10 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
                                 }
                             }
                         }
-                    } catch (GLException gle) {
+                    } catch (Throwable t) {
                         if (DEBUG) {
                             System.err.println("EGLDrawableFactory.mapAvailableEGLESConfig: INFO: context create/makeCurrent failed");
-                            gle.printStackTrace();
+                            t.printStackTrace();
                         }
                     } finally {
                         context.destroy();
@@ -517,24 +550,16 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
             }
             success = false;
         } finally {
-            if(eglDevice == defaultDevice) {
-                if(null != upstreamSurface) {
-                    upstreamSurface.destroyNotify();
-                }
-            } else if( deviceFromUpstreamSurface ) {
+            if(null != downstreamSurface) {
+                downstreamSurface.destroyNotify();
+            }
+            if( defaultDevice != eglDevice ) { // don't close default device
                 if(null != eglDevice) {
                     eglDevice.close();
                 }
                 if(null != upstreamSurface) {
                     upstreamSurface.destroyNotify();
                 }
-            } else {
-                if(null != upstreamSurface) {
-                    upstreamSurface.destroyNotify();
-                }
-                if(null != eglDevice) {
-                    eglDevice.close();
-                }
             }
         }
         return success;
@@ -594,8 +619,6 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
 
     private SharedResource createEGLSharedResourceImpl(AbstractGraphicsDevice adevice) {
         final boolean madeCurrentES1;
-        final boolean madeCurrentES2;
-        final boolean madeCurrentES3;
         boolean[] hasPBufferES1 = new boolean[] { false };
         boolean[] hasPBufferES3ES2 = new boolean[] { false };
         // EGLContext[] eglCtxES1 = new EGLContext[] { null };
@@ -611,18 +634,29 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
         }
 
         if( null != eglES1DynamicLookupHelper ) {
-            madeCurrentES1 = mapAvailableEGLESConfig(adevice, 1, hasPBufferES1, rendererQuirksES1, ctpES1);
+            final int[] esProfile = { 1 };
+            madeCurrentES1 = mapAvailableEGLESConfig(adevice, esProfile, hasPBufferES1, rendererQuirksES1, ctpES1) && 1 == esProfile[0];
         } else {
             madeCurrentES1 = false;
         }
+        boolean madeCurrentES2 = false;
+        boolean madeCurrentES3 = false;
         if( null != eglES2DynamicLookupHelper ) {
-            madeCurrentES3 = mapAvailableEGLESConfig(adevice, 3, hasPBufferES3ES2, rendererQuirksES3ES2, ctpES3ES2);
-            madeCurrentES2 = mapAvailableEGLESConfig(adevice, 2, hasPBufferES3ES2, rendererQuirksES3ES2, ctpES3ES2);
-        } else {
-            madeCurrentES2 = false;
-            madeCurrentES3 = false;
+            // ES3 Query
+            final int[] esProfile = { 3 };
+            madeCurrentES3 = mapAvailableEGLESConfig(adevice, esProfile, hasPBufferES3ES2, rendererQuirksES3ES2, ctpES3ES2) && 3 == esProfile[0];
+            if( !madeCurrentES3 ) {
+                // ES2 Query, may result in ES3
+                esProfile[0] = 2;
+                if( mapAvailableEGLESConfig(adevice, esProfile, hasPBufferES3ES2, rendererQuirksES3ES2, ctpES3ES2) ) {
+                    switch( esProfile[0] ) {
+                        case 2: madeCurrentES2 = true; break;
+                        case 3: madeCurrentES3 = true; break;
+                        default: throw new InternalError("XXXX Got "+esProfile[0]);
+                    }
+                }
+            }
         }
-
         if( !EGLContext.getAvailableGLVersionsSet(adevice) ) {
             // Even though we override the non EGL native mapping intentionally,
             // avoid exception due to double 'set' - carefull exception of the rule.
@@ -640,9 +674,9 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
         }
         if (DEBUG) {
             System.err.println("EGLDrawableFactory.createShared: devices: queried nativeTK "+QUERY_EGL_ES_NATIVE_TK+", adevice " + adevice + ", defaultDevice " + defaultDevice);
-            System.err.println("EGLDrawableFactory.createShared: context ES1: " + madeCurrentES1 + ", hasPBuffer "+hasPBufferES1[0]);
-            System.err.println("EGLDrawableFactory.createShared: context ES2: " + madeCurrentES2 + ", hasPBuffer "+hasPBufferES3ES2[0]);
-            System.err.println("EGLDrawableFactory.createShared: context ES3: " + madeCurrentES3 + ", hasPBuffer "+hasPBufferES3ES2[0]);
+            System.err.println("EGLDrawableFactory.createShared: context ES1: " + madeCurrentES1 + ", hasPBuffer "+hasPBufferES1[0]+", quirks "+rendererQuirksES1[0]);
+            System.err.println("EGLDrawableFactory.createShared: context ES2: " + madeCurrentES2 + ", hasPBuffer "+hasPBufferES3ES2[0]+", quirks "+rendererQuirksES3ES2[0]);
+            System.err.println("EGLDrawableFactory.createShared: context ES3: " + madeCurrentES3 + ", hasPBuffer "+hasPBufferES3ES2[0]+", quirks "+rendererQuirksES3ES2[0]);
             dumpMap();
         }
         return sr;
@@ -721,6 +755,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
             final long nativeDisplayID = ( deviceReq instanceof EGLGraphicsDevice) ?
                     ( (EGLGraphicsDevice) deviceReq ).getNativeDisplayID() : deviceReq.getHandle() ;
             device = EGLDisplayUtil.eglCreateEGLGraphicsDevice(nativeDisplayID, deviceReq.getConnection(), deviceReq.getUnitID());
+            device.open();
             ownDevice = true;
         } else {
             device = (EGLGraphicsDevice) deviceReq;
@@ -779,6 +814,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
     protected ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice deviceReq, int screenIdx, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream) {
         final EGLGraphicsDevice eglDeviceReq = (EGLGraphicsDevice) deviceReq;
         final EGLGraphicsDevice device = EGLDisplayUtil.eglCreateEGLGraphicsDevice(eglDeviceReq.getNativeDisplayID(), deviceReq.getConnection(), deviceReq.getUnitID());
+        device.open();
         final DefaultGraphicsScreen screen = new DefaultGraphicsScreen(device, screenIdx);
         final EGLGraphicsConfiguration cfg = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsRequested, capsRequested, chooser, screen, VisualIDHolder.VID_UNDEFINED, false);
         return new WrappedSurface(cfg, windowHandle, upstream, true);
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/egl/EGLDynamicLibraryBundleInfo.java
index ac880eb..ebe8f49 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDynamicLibraryBundleInfo.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDynamicLibraryBundleInfo.java
@@ -55,6 +55,9 @@ public abstract class EGLDynamicLibraryBundleInfo extends GLDynamicLibraryBundle
     /**
      * Returns <code>true</code> on <code>Android</code>,
      * and <code>false</code> otherwise.
+     * <p>
+     * {@inheritDoc}
+     * </p>
      */
     @Override
     public final boolean shallLookupGlobal() {
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
index 0e5551b..88ed0be 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
@@ -46,6 +46,7 @@ import javax.media.nativewindow.VisualIDHolder;
 import javax.media.opengl.DefaultGLCapabilitiesChooser;
 import javax.media.opengl.GLCapabilitiesChooser;
 import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLDrawableFactory;
 import javax.media.opengl.GLException;
 import javax.media.opengl.GLProfile;
 
@@ -55,6 +56,7 @@ import com.jogamp.common.nio.Buffers;
 import com.jogamp.common.nio.PointerBuffer;
 import com.jogamp.nativewindow.MutableGraphicsConfiguration;
 import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
+import com.jogamp.opengl.GLRendererQuirks;
 
 public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration implements Cloneable {
 
@@ -94,8 +96,9 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
         }
         final long cfg = EGLConfigId2EGLConfig(dpy, eglConfigID);
         if(0 < cfg) {
+            final GLRendererQuirks defaultQuirks = GLRendererQuirks.getStickyDeviceQuirks( GLDrawableFactory.getEGLFactory().getDefaultDevice() );
             final int winattrmask = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(capsRequested);
-            final EGLGLCapabilities caps = EGLConfig2Capabilities((EGLGraphicsDevice)absDevice, capsRequested.getGLProfile(), cfg, winattrmask, false);
+            final EGLGLCapabilities caps = EGLConfig2Capabilities(defaultQuirks, (EGLGraphicsDevice)absDevice, capsRequested.getGLProfile(), cfg, winattrmask, false);
             return new EGLGraphicsConfiguration(absScreen, caps, capsRequested, new DefaultGLCapabilitiesChooser());
         }
         return null;
@@ -179,6 +182,7 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
     }
 
     /**
+     * @param defaultQuirks GLRendererQuirks of the EGLDrawableFactory's defaultDevice
      * @param device
      * @param glp desired GLProfile, may be null
      * @param config
@@ -186,8 +190,8 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
      * @param forceTransparentFlag
      * @return
      */
-    public static EGLGLCapabilities EGLConfig2Capabilities(EGLGraphicsDevice device, GLProfile glp, long config,
-                                                           int winattrmask, boolean forceTransparentFlag) {
+    public static EGLGLCapabilities EGLConfig2Capabilities(GLRendererQuirks defaultQuirks, EGLGraphicsDevice device, GLProfile glp,
+                                                           long config, int winattrmask, boolean forceTransparentFlag) {
         final long display = device.getHandle();
         final int cfgID;
         final int rType;
@@ -232,7 +236,14 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
             }
             return null;
         }
-        rType = values.get(1);
+        {
+            final int rTypeOrig = values.get(1);
+            if( defaultQuirks.exist(GLRendererQuirks.GLES3ViaEGLES2Config) && 0 != ( EGL.EGL_OPENGL_ES2_BIT & rTypeOrig ) ) {
+                rType = rTypeOrig | EGLExt.EGL_OPENGL_ES3_BIT_KHR;
+            } else {
+                rType = rTypeOrig;
+            }
+        }
 
         if( EGL.EGL_NATIVE_VISUAL_ID == attributes.get(2) ) {
             visualID = values.get(2);
@@ -251,7 +262,7 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
             if(!EGLGLCapabilities.isCompatible(glp, rType)) {
                 if(DEBUG) {
                     System.err.println("config "+toHexString(config)+": Requested GLProfile "+glp+
-                                " not compatible with EGL-RenderableType["+EGLGLCapabilities.renderableTypeToString(null, rType)+"]");
+                                " with quirks "+defaultQuirks+" not compatible with EGL-RenderableType["+EGLGLCapabilities.renderableTypeToString(null, rType)+"]");
                 }
                 return null;
             }
@@ -453,7 +464,11 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
         } else if(caps.getGLProfile().usesNativeGLES2()) {
             attrs.put(idx++, EGL.EGL_OPENGL_ES2_BIT);
         } else if(caps.getGLProfile().usesNativeGLES3()) {
-            attrs.put(idx++, EGLExt.EGL_OPENGL_ES3_BIT_KHR);
+            if( GLRendererQuirks.existStickyDeviceQuirk(GLDrawableFactory.getEGLFactory().getDefaultDevice(), GLRendererQuirks.GLES3ViaEGLES2Config) ) {
+                attrs.put(idx++, EGL.EGL_OPENGL_ES2_BIT);
+            } else {
+                attrs.put(idx++, EGLExt.EGL_OPENGL_ES3_BIT_KHR);
+            }
         } else {
             attrs.put(idx++, EGL.EGL_OPENGL_BIT);
         }
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
index 568fede..5cfa378 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
@@ -53,6 +53,7 @@ import javax.media.opengl.GLDrawableFactory;
 import com.jogamp.common.nio.Buffers;
 import com.jogamp.common.nio.PointerBuffer;
 import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
+import com.jogamp.opengl.GLRendererQuirks;
 
 import jogamp.opengl.GLGraphicsConfigurationFactory;
 import jogamp.opengl.GLGraphicsConfigurationUtil;
@@ -181,16 +182,15 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
     }
 
     protected static List<GLCapabilitiesImmutable> getAvailableCapabilities(EGLDrawableFactory factory, AbstractGraphicsDevice device) {
-        EGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateSharedResourceImpl(device);
+        final EGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateSharedResourceImpl(device);
         if(null == sharedResource) {
             throw new GLException("Shared resource for device n/a: "+device);
         }
-        EGLGraphicsDevice eglDevice = sharedResource.getDevice();
-        long eglDisplay = eglDevice.getHandle();
+        final EGLGraphicsDevice eglDevice = sharedResource.getDevice();
+        final long eglDisplay = eglDevice.getHandle();
         if(0 == eglDisplay) {
             throw new GLException("null eglDisplay");
         }
-
         List<GLCapabilitiesImmutable> availableCaps = null;
         IntBuffer numConfigs = Buffers.newDirectIntBuffer(1);
 
@@ -212,7 +212,6 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
                 Collections.sort(availableCaps, EglCfgIDComparator);
             }
         }
-
         return availableCaps;
     }
 
@@ -243,6 +242,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
             ownEGLDisplay = false;
         } else {
             eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(absDevice.getHandle(), absDevice.getConnection(), absDevice.getUnitID());
+            eglDevice.open();
             ownEGLDisplay = true;
         }
 
@@ -476,9 +476,10 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
     }
 
     static List<GLCapabilitiesImmutable> eglConfigs2GLCaps(EGLGraphicsDevice device, GLProfile glp, PointerBuffer configs, int num, int winattrmask, boolean forceTransparentFlag, boolean onlyFirstValid) {
+        final GLRendererQuirks defaultQuirks = GLRendererQuirks.getStickyDeviceQuirks( GLDrawableFactory.getEGLFactory().getDefaultDevice() );
         List<GLCapabilitiesImmutable> bucket = new ArrayList<GLCapabilitiesImmutable>(num);
         for(int i=0; i<num; i++) {
-            final GLCapabilitiesImmutable caps = EGLGraphicsConfiguration.EGLConfig2Capabilities(device, glp, configs.get(i), winattrmask, forceTransparentFlag);
+            final GLCapabilitiesImmutable caps = EGLGraphicsConfiguration.EGLConfig2Capabilities(defaultQuirks, device, glp, configs.get(i), winattrmask, forceTransparentFlag);
             if(null != caps) {
                 bucket.add(caps);
                 if(onlyFirstValid) {
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java b/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java
index dac85e7..5b91157 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java
@@ -125,6 +125,7 @@ public class EGLUpstreamSurfaceHook implements UpstreamSurfaceHook.MutableSize {
                 }
             } else {
                 eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(upstreamSurface);
+                eglDevice.open();
                 aConfig = upstreamConfig;
                 isEGLSurfaceValid = false;
                 surface.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE );
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
index 0d231b8..259c706 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
@@ -291,7 +291,7 @@ public class MacOSXCGLContext extends GLContextImpl
     final MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration();
     final GLCapabilitiesImmutable capabilitiesChosen = (GLCapabilitiesImmutable) config.getChosenCapabilities();
     final GLProfile glp = capabilitiesChosen.getGLProfile();
-    if( glp.isGLES1() || glp.isGLES2() || glp.isGLES3() ||
+    if( glp.isGLES() ||
         ( glp.isGL3() && !isLionOrLater ) || ( glp.isGL4() && !isMavericksOrLater ) ) {
         throw new GLException("OpenGL profile not supported on MacOSX "+Platform.getOSVersionNumber()+": "+glp);
     }
diff --git a/src/jogl/classes/jogamp/opengl/openal/av/ALAudioSink.java b/src/jogl/classes/jogamp/opengl/openal/av/ALAudioSink.java
index 1229eb7..8b12f8a 100644
--- a/src/jogl/classes/jogamp/opengl/openal/av/ALAudioSink.java
+++ b/src/jogl/classes/jogamp/opengl/openal/av/ALAudioSink.java
@@ -487,7 +487,7 @@ public class ALAudioSink implements AudioSink {
                     // clip wait at [2 .. 100] ms
                     final int avgBufferDura = chosenFormat.getBytesDuration( alBufferBytesQueued / alFramesPlaying.size() );
                     final int sleep = Math.max(2, Math.min(100, releaseBufferLimes * avgBufferDura));
-                    if( DEBUG || true ) {
+                    if( DEBUG ) {
                         System.err.println(getThreadName()+": ALAudioSink: Dequeue.wait["+i+"]: avgBufferDura "+avgBufferDura+", releaseBufferLimes "+releaseBufferLimes+", sleep "+sleep+" ms, playImpl "+(AL.AL_PLAYING == getSourceState())+", processed "+val[0]+", "+this);
                     }
                     unlockContext();
diff --git a/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java b/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java
index 0de308c..7cea51d 100644
--- a/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java
+++ b/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java
@@ -30,6 +30,7 @@ package jogamp.opengl.util.av;
 import java.io.IOException;
 import java.net.URI;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 
@@ -374,6 +375,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
             removeAllTextureFrames(gl);
             textureCount=0;
             changeState(event_mask, State.Uninitialized);
+            attachedObjects.clear();
             return state;
         }
     }
@@ -757,7 +759,9 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
                     }
                     texFrames[i] = null;
                 }
-                System.err.println(Thread.currentThread().getName()+"> Clear TexFrame["+i+"]: "+frame+" -> null");
+                if( DEBUG ) {
+                    System.err.println(Thread.currentThread().getName()+"> Clear TexFrame["+i+"]: "+frame+" -> null");
+                }
             }
         }
     }
@@ -1592,6 +1596,23 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
 
     private final Object eventListenersLock = new Object();
 
+    @Override
+    public final Object getAttachedObject(String name) {
+        return attachedObjects.get(name);
+    }
+
+    @Override
+    public final Object attachObject(String name, Object obj) {
+        return attachedObjects.put(name, obj);
+    }
+
+    @Override
+    public final Object detachObject(String name) {
+        return attachedObjects.remove(name);
+    }
+
+    private final HashMap<String, Object> attachedObjects = new HashMap<String, Object>();
+
     protected static final String toHexString(long v) {
         return "0x"+Long.toHexString(v);
     }
@@ -1609,4 +1630,4 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
         }
         return 0;
     }
-}
\ No newline at end of file
+}
diff --git a/src/jogl/classes/jogamp/opengl/util/av/NullGLMediaPlayer.java b/src/jogl/classes/jogamp/opengl/util/av/NullGLMediaPlayer.java
index fc621a1..79129e5 100644
--- a/src/jogl/classes/jogamp/opengl/util/av/NullGLMediaPlayer.java
+++ b/src/jogl/classes/jogamp/opengl/util/av/NullGLMediaPlayer.java
@@ -108,7 +108,7 @@ public class NullGLMediaPlayer extends GLMediaPlayerImpl {
     public final static TextureData createTestTextureData() {
         TextureData res = null;
         try {
-            URLConnection urlConn = IOUtil.getResource("jogl/util/data/av/test-ntsc01-160x90.png", NullGLMediaPlayer.class.getClassLoader());
+            URLConnection urlConn = IOUtil.getResource("jogl/util/data/av/test-ntsc01-57x32.png", NullGLMediaPlayer.class.getClassLoader());
             if(null != urlConn) {
                 res = TextureIO.newTextureData(GLProfile.getGL2ES2(), urlConn.getInputStream(), false, TextureIO.PNG);
             }
diff --git a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java
index 034b945..344ba48 100644
--- a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java
+++ b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java
@@ -185,13 +185,15 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl {
             final boolean avResampleLoaded = FFMPEGDynamicLibraryBundleInfo.avResampleLoaded();
             final VersionNumber swResampleVersion = FFMPEGDynamicLibraryBundleInfo.swResampleVersion;
             final boolean swResampleLoaded = FFMPEGDynamicLibraryBundleInfo.swResampleLoaded();
-            System.err.println("LIB_AV Codec   : "+avCodecVersion+" [cc "+avCodecMajorVersionCC+"]");
-            System.err.println("LIB_AV Format  : "+avFormatVersion+" [cc "+avFormatMajorVersionCC+"]");
-            System.err.println("LIB_AV Util    : "+avUtilVersion+" [cc "+avUtilMajorVersionCC+"]");
-            System.err.println("LIB_AV Resample: "+avResampleVersion+" [cc "+avResampleMajorVersionCC+", loaded "+avResampleLoaded+"]");
-            System.err.println("LIB_SW Resample: "+swResampleVersion+" [cc "+swResampleMajorVersionCC+", loaded "+swResampleLoaded+"]");
-            System.err.println("LIB_AV Device  : [loaded "+FFMPEGDynamicLibraryBundleInfo.avDeviceLoaded()+"]");
-            System.err.println("LIB_AV Class   : "+(null!= natives ? natives.getClass().getSimpleName() : "n/a"));
+            if( DEBUG ) {
+                System.err.println("LIB_AV Codec   : "+avCodecVersion+" [cc "+avCodecMajorVersionCC+"]");
+                System.err.println("LIB_AV Format  : "+avFormatVersion+" [cc "+avFormatMajorVersionCC+"]");
+                System.err.println("LIB_AV Util    : "+avUtilVersion+" [cc "+avUtilMajorVersionCC+"]");
+                System.err.println("LIB_AV Resample: "+avResampleVersion+" [cc "+avResampleMajorVersionCC+", loaded "+avResampleLoaded+"]");
+                System.err.println("LIB_SW Resample: "+swResampleVersion+" [cc "+swResampleMajorVersionCC+", loaded "+swResampleLoaded+"]");
+                System.err.println("LIB_AV Device  : [loaded "+FFMPEGDynamicLibraryBundleInfo.avDeviceLoaded()+"]");
+                System.err.println("LIB_AV Class   : "+(null!= natives ? natives.getClass().getSimpleName() : "n/a"));
+            }
             libAVVersionGood = avCodecMajorVersionCC  == avCodecVersion.getMajor() &&
                                avFormatMajorVersionCC == avFormatVersion.getMajor() &&
                                avUtilMajorVersionCC   == avUtilVersion.getMajor() &&
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/FixedFuncHook.java b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/FixedFuncHook.java
index c329945..458a9c9 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/FixedFuncHook.java
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/FixedFuncHook.java
@@ -352,11 +352,11 @@ public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFun
     @Override
     public void glVertexPointer(GLArrayData array) {
       if(array.isVBO()) {
-          if(!gl.glIsVBOArrayBound()) {
+          if(!gl.isVBOArrayBound()) {
             throw new GLException("VBO array is not enabled: "+array);
           }
       } else {
-          if(gl.glIsVBOArrayBound()) {
+          if(gl.isVBOArrayBound()) {
             throw new GLException("VBO array is not disabled: "+array);
           }
           Buffers.rangeCheck(array.getBuffer(), 1);
@@ -373,7 +373,7 @@ public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFun
     }
     @Override
     public void glVertexPointer(int size, int type, int stride, long pointer_buffer_offset) {
-      int vboName = gl.glGetBoundBuffer(GL.GL_ARRAY_BUFFER);
+      int vboName = gl.getBoundBuffer(GL.GL_ARRAY_BUFFER);
       if(vboName==0) {
         throw new GLException("no GL_ARRAY_BUFFER VBO bound");
       }
@@ -384,11 +384,11 @@ public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFun
     @Override
     public void glColorPointer(GLArrayData array) {
       if(array.isVBO()) {
-          if(!gl.glIsVBOArrayBound()) {
+          if(!gl.isVBOArrayBound()) {
             throw new GLException("VBO array is not enabled: "+array);
           }
       } else {
-          if(gl.glIsVBOArrayBound()) {
+          if(gl.isVBOArrayBound()) {
             throw new GLException("VBO array is not disabled: "+array);
           }
           Buffers.rangeCheck(array.getBuffer(), 1);
@@ -404,7 +404,7 @@ public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFun
     }
     @Override
     public void glColorPointer(int size, int type, int stride, long pointer_buffer_offset) {
-      int vboName = gl.glGetBoundBuffer(GL.GL_ARRAY_BUFFER);
+      int vboName = gl.getBoundBuffer(GL.GL_ARRAY_BUFFER);
       if(vboName==0) {
         throw new GLException("no GL_ARRAY_BUFFER VBO bound");
       }
@@ -418,11 +418,11 @@ public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFun
         throw new GLException("Only 3 components per normal allowed");
       }
       if(array.isVBO()) {
-          if(!gl.glIsVBOArrayBound()) {
+          if(!gl.isVBOArrayBound()) {
             throw new GLException("VBO array is not enabled: "+array);
           }
       } else {
-          if(gl.glIsVBOArrayBound()) {
+          if(gl.isVBOArrayBound()) {
             throw new GLException("VBO array is not disabled: "+array);
           }
           Buffers.rangeCheck(array.getBuffer(), 1);
@@ -438,7 +438,7 @@ public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFun
     }
     @Override
     public void glNormalPointer(int type, int stride, long pointer_buffer_offset) {
-      int vboName = gl.glGetBoundBuffer(GL.GL_ARRAY_BUFFER);
+      int vboName = gl.getBoundBuffer(GL.GL_ARRAY_BUFFER);
       if(vboName==0) {
         throw new GLException("no GL_ARRAY_BUFFER VBO bound");
       }
@@ -449,11 +449,11 @@ public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFun
     @Override
     public void glTexCoordPointer(GLArrayData array) {
       if(array.isVBO()) {
-          if(!gl.glIsVBOArrayBound()) {
+          if(!gl.isVBOArrayBound()) {
             throw new GLException("VBO array is not enabled: "+array);
           }
       } else {
-          if(gl.glIsVBOArrayBound()) {
+          if(gl.isVBOArrayBound()) {
             throw new GLException("VBO array is not disabled: "+array);
           }
           Buffers.rangeCheck(array.getBuffer(), 1);
@@ -470,7 +470,7 @@ public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFun
     }
     @Override
     public void glTexCoordPointer(int size, int type, int stride, long pointer_buffer_offset) {
-      int vboName = gl.glGetBoundBuffer(GL.GL_ARRAY_BUFFER);
+      int vboName = gl.getBoundBuffer(GL.GL_ARRAY_BUFFER);
       if(vboName==0) {
         throw new GLException("no GL_ARRAY_BUFFER VBO bound");
       }
diff --git a/src/jogl/native/GLContext.c b/src/jogl/native/GLContext.c
index f10d0e4..9be9f82 100644
--- a/src/jogl/native/GLContext.c
+++ b/src/jogl/native/GLContext.c
@@ -19,7 +19,7 @@ Java_jogamp_opengl_GLContextImpl_glGetStringInt(JNIEnv *env, jclass _unused, jin
   assert(ptr_glGetString != NULL);
   _res = (* ptr_glGetString) ((unsigned int) name);
   if (NULL == _res) return NULL;
-  return (*env)->NewStringUTF(env, _res);
+  return (*env)->NewStringUTF(env, (const char *)_res);
 }
 
 /*
diff --git a/src/jogl/native/GLDebugMessageHandler.c b/src/jogl/native/GLDebugMessageHandler.c
index 2e9d603..0aa7a01 100644
--- a/src/jogl/native/GLDebugMessageHandler.c
+++ b/src/jogl/native/GLDebugMessageHandler.c
@@ -49,8 +49,6 @@ JNIEXPORT jboolean JNICALL Java_jogamp_opengl_GLDebugMessageHandler_initIDs0
 }
 
 typedef struct {
-    JavaVM *vm;
-    int version;
     jobject obj;
     int extType;
 } DebugHandlerType;
@@ -60,39 +58,21 @@ typedef struct {
 static void GLDebugMessageARBCallback(GLenum source, GLenum type, GLuint id, GLenum severity, 
                                       GLsizei length, const GLchar *message, GLvoid *userParam) {
     DebugHandlerType * handle = (DebugHandlerType*) (intptr_t) userParam;
-    JavaVM *vm = handle->vm;
-    int version = handle->version;
     jobject obj = handle->obj;
-    JNIEnv *curEnv = NULL;
-    JNIEnv *newEnv = NULL;
-    int envRes ;
-    DBG_PRINT("GLDebugMessageARBCallback: 00 - %s, vm %p, version 0x%X, jobject %p, extType %d\n", 
-        message, handle->vm, handle->version, (void*)handle->obj, handle->extType);
-
-    // retrieve this thread's JNIEnv curEnv - or detect it's detached
-    envRes = (*vm)->GetEnv(vm, (void **) &curEnv, version) ;
-    DBG_PRINT("GLDebugMessageARBCallback: 01 - JVM Env: curEnv %p, res 0x%X\n", curEnv, envRes);
-    if( JNI_EDETACHED == envRes ) {
-        // detached thread - attach to JVM
-        if( JNI_OK != ( envRes = (*vm)->AttachCurrentThread(vm, (void**) &newEnv, NULL) ) ) {
-            fprintf(stderr, "GLDebugMessageARBCallback: can't attach thread: %d\n", envRes);
-            return;
-        }
-        curEnv = newEnv;
-        DBG_PRINT("GLDebugMessageARBCallback: 02 - attached .. \n");
-    } else if( JNI_OK != envRes ) {
-        // oops ..
-        fprintf(stderr, "GLDebugMessageARBCallback: can't GetEnv: %d\n", envRes);
+    JNIEnv *env = NULL;
+    int shallBeDetached ;
+    DBG_PRINT("GLDebugMessageARBCallback: 00 - %s, jobject %p, extType %d\n", message, (void*)handle->obj, handle->extType);
+
+    env = JoglCommon_GetJNIEnv (1 /* asDaemon */, &shallBeDetached);
+    if( NULL == env ) {
+        DBG_PRINT("GLDebugMessageARBCallback: Null JNIEnv\n");
         return;
     }
-    (*curEnv)->CallVoidMethod(curEnv, obj, glDebugMessageARB, 
+    (*env)->CallVoidMethod(env, obj, glDebugMessageARB, 
                               (jint) source, (jint) type, (jint) id, (jint) severity, 
-                              (*curEnv)->NewStringUTF(curEnv, message));
-    if( NULL != newEnv ) {
-        // detached attached thread
-        (*vm)->DetachCurrentThread(vm);
-        DBG_PRINT("GLDebugMessageARBCallback: 04 - detached .. \n");
-    }
+                              (*env)->NewStringUTF(env, message));
+    // detaching thread not required - daemon
+    // JoglCommon_ReleaseJNIEnv(shallBeDetached);
     DBG_PRINT("GLDebugMessageARBCallback: 0X\n");
     /**
      * On Java 32bit on 64bit Windows and w/ GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB disables,
@@ -104,39 +84,21 @@ static void GLDebugMessageARBCallback(GLenum source, GLenum type, GLuint id, GLe
 static void GLDebugMessageAMDCallback(GLuint id, GLenum category, GLenum severity, 
                                       GLsizei length, const GLchar *message, GLvoid *userParam) {
     DebugHandlerType * handle = (DebugHandlerType*) (intptr_t) userParam;
-    JavaVM *vm = handle->vm;
-    int version = handle->version;
     jobject obj = handle->obj;
-    JNIEnv *curEnv = NULL;
-    JNIEnv *newEnv = NULL;
-    int envRes ;
-    DBG_PRINT("GLDebugMessageAMDCallback: 00 - %s, vm %p, version 0x%X, jobject %p, extType %d\n", 
-        message, handle->vm, handle->version, (void*)handle->obj, handle->extType);
-
-    // retrieve this thread's JNIEnv curEnv - or detect it's detached
-    envRes = (*vm)->GetEnv(vm, (void **) &curEnv, version) ;
-    DBG_PRINT("GLDebugMessageAMDCallback: 01 - JVM Env: curEnv %p, res 0x%X\n", curEnv, envRes);
-    if( JNI_EDETACHED == envRes ) {
-        // detached thread - attach to JVM
-        if( JNI_OK != ( envRes = (*vm)->AttachCurrentThread(vm, (void**) &newEnv, NULL) ) ) {
-            fprintf(stderr, "GLDebugMessageAMDCallback: can't attach thread: %d\n", envRes);
-            return;
-        }
-        curEnv = newEnv;
-        DBG_PRINT("GLDebugMessageAMDCallback: 02 - attached .. \n");
-    } else if( JNI_OK != envRes ) {
-        // oops ..
-        fprintf(stderr, "GLDebugMessageAMDCallback: can't GetEnv: %d\n", envRes);
+    JNIEnv *env = NULL;
+    int shallBeDetached ;
+    DBG_PRINT("GLDebugMessageAMDCallback: 00 - %s, jobject %p, extType %d\n", message, (void*)handle->obj, handle->extType);
+
+    env = JoglCommon_GetJNIEnv (1 /* asDaemon */, &shallBeDetached);
+    if( NULL == env ) {
+        DBG_PRINT("GLDebugMessageARBCallback: Null JNIEnv\n");
         return;
     }
-    (*curEnv)->CallVoidMethod(curEnv, obj, glDebugMessageAMD, 
+    (*env)->CallVoidMethod(env, obj, glDebugMessageAMD, 
                               (jint) id, (jint) category, (jint) severity, 
-                              (*curEnv)->NewStringUTF(curEnv, message));
-    if( NULL != newEnv ) {
-        // detached attached thread
-        (*vm)->DetachCurrentThread(vm);
-        DBG_PRINT("GLDebugMessageAMDCallback: 04 - detached .. \n");
-    }
+                              (*env)->NewStringUTF(env, message));
+    // detached attached thread not required - daemon
+    // JoglCommon_ReleaseJNIEnv(shallBeDetached);
     DBG_PRINT("GLDebugMessageAMDCallback: 0X\n");
     /**
      * On Java 32bit on 64bit Windows,
@@ -153,18 +115,10 @@ static void GLDebugMessageAMDCallback(GLuint id, GLenum category, GLenum severit
 JNIEXPORT jlong JNICALL Java_jogamp_opengl_GLDebugMessageHandler_register0
   (JNIEnv *env, jobject obj, jlong procAddress, jint extType)
 {
-    JavaVM *vm;
     DebugHandlerType * handle = malloc(sizeof(DebugHandlerType));
-    if(0 != (*env)->GetJavaVM(env, &vm)) {
-        vm = NULL;
-        JoglCommon_throwNewRuntimeException(env, "GetJavaVM failed");
-    }
-    handle->vm = vm;
-    handle->version = (*env)->GetVersion(env);
     handle->obj = (*env)->NewGlobalRef(env, obj);
     handle->extType = extType;
-    DBG_PRINT("GLDebugMessageHandler.register0: vm %p, version 0x%X, jobject %p, extType %d\n", 
-        handle->vm, handle->version, (void*)handle->obj, handle->extType);
+    DBG_PRINT("GLDebugMessageHandler.register0: jobject %p, extType %d\n", (void*)handle->obj, handle->extType);
 
     if(jogamp_opengl_GLDebugMessageHandler_EXT_ARB == extType) {
         _local_PFNGLDEBUGMESSAGECALLBACKARBPROC ptr_glDebugMessageCallbackARB;
@@ -191,8 +145,7 @@ JNIEXPORT void JNICALL Java_jogamp_opengl_GLDebugMessageHandler_unregister0
 {
     DebugHandlerType * handle = (DebugHandlerType*) (intptr_t) jhandle;
 
-    DBG_PRINT("GLDebugMessageHandler.unregister0: vm %p, version 0x%X, jobject %p, extType %d\n", 
-        handle->vm, handle->version, (void*)handle->obj, handle->extType);
+    DBG_PRINT("GLDebugMessageHandler.unregister0: jobject %p, extType %d\n", (void*)handle->obj, handle->extType);
 
     if(JNI_FALSE == (*env)->IsSameObject(env, obj, handle->obj)) {
         JoglCommon_throwNewRuntimeException(env, "wrong handle (obj doesn't match)");
diff --git a/src/jogl/native/JoglCommon.c b/src/jogl/native/JoglCommon.c
index 4170b13..e9984ad 100644
--- a/src/jogl/native/JoglCommon.c
+++ b/src/jogl/native/JoglCommon.c
@@ -11,42 +11,38 @@ static JavaVM *_jvmHandle = NULL;
 static int _jvmVersion = 0;
 
 void JoglCommon_init(JNIEnv *env) {
-    if(NULL==runtimeExceptionClz) {
+    if(NULL==_jvmHandle) {
+        if(0 != (*env)->GetJavaVM(env, &_jvmHandle)) {
+            JoglCommon_FatalError(env, "JOGL: Can't fetch JavaVM handle");
+        } else {
+            _jvmVersion = (*env)->GetVersion(env);
+        }
         jclass c = (*env)->FindClass(env, ClazzNameRuntimeException);
         if(NULL==c) {
-            JoglCommon_FatalError(env, "JOGL: can't find %s", ClazzNameRuntimeException);
+            JoglCommon_FatalError(env, "JOGL: Can't find %s", ClazzNameRuntimeException);
         }
         runtimeExceptionClz = (jclass)(*env)->NewGlobalRef(env, c);
         (*env)->DeleteLocalRef(env, c);
         if(NULL==runtimeExceptionClz) {
-            JoglCommon_FatalError(env, "JOGL: can't use %s", ClazzNameRuntimeException);
+            JoglCommon_FatalError(env, "JOGL: Can't use %s", ClazzNameRuntimeException);
         }
     }
-    if(0 != (*env)->GetJavaVM(env, &_jvmHandle)) {
-        JoglCommon_FatalError(env, "JOGL: can't fetch JavaVM handle");
-    } else {
-        _jvmVersion = (*env)->GetVersion(env);
-    }
 }
 
 void JoglCommon_FatalError(JNIEnv *env, const char* msg, ...)
 {
     char buffer[512];
     va_list ap;
-    int shallBeDetached = 0;
-
-    if(NULL == env) {
-        env = JoglCommon_GetJNIEnv (&shallBeDetached);
-    }
 
-    va_start(ap, msg);
-    vsnprintf(buffer, sizeof(buffer), msg, ap);
-    va_end(ap);
+    if( NULL != msg ) {
+        va_start(ap, msg);
+        vsnprintf(buffer, sizeof(buffer), msg, ap);
+        va_end(ap);
 
-    fprintf(stderr, "%s\n", buffer);
-    if(NULL != env) {
-        (*env)->FatalError(env, buffer);
-        JoglCommon_ReleaseJNIEnv (shallBeDetached);
+        fprintf(stderr, "%s\n", buffer);
+        if(NULL != env) {
+            (*env)->FatalError(env, buffer);
+        }
     }
 }
 
@@ -54,48 +50,42 @@ void JoglCommon_throwNewRuntimeException(JNIEnv *env, const char* msg, ...)
 {
     char buffer[512];
     va_list ap;
-    int shallBeDetached = 0;
 
-    if(NULL == env) {
-        env = JoglCommon_GetJNIEnv (&shallBeDetached);
+    if(NULL==_jvmHandle) {
+        JoglCommon_FatalError(env, "JOGL: NULL JVM handle, call JoglCommon_init 1st\n");
+        return;
     }
 
-    va_start(ap, msg);
-    vsnprintf(buffer, sizeof(buffer), msg, ap);
-    va_end(ap);
+    if( NULL != msg ) {
+        va_start(ap, msg);
+        vsnprintf(buffer, sizeof(buffer), msg, ap);
+        va_end(ap);
 
-    if(NULL != env) {
-        (*env)->ThrowNew(env, runtimeExceptionClz, buffer);
-        JoglCommon_ReleaseJNIEnv (shallBeDetached);
+        if(NULL != env) {
+            (*env)->ThrowNew(env, runtimeExceptionClz, buffer);
+        }
     }
 }
 
-JavaVM *JoglCommon_GetJVMHandle() {
-    return _jvmHandle;
-}
-
-int JoglCommon_GetJVMVersion() {
-    return _jvmVersion;
-}
-
 jchar* JoglCommon_GetNullTerminatedStringChars(JNIEnv* env, jstring str)
 {
     jchar* strChars = NULL;
-    strChars = calloc((*env)->GetStringLength(env, str) + 1, sizeof(jchar));
-    if (strChars != NULL) {
-        (*env)->GetStringRegion(env, str, 0, (*env)->GetStringLength(env, str), strChars);
+    if( NULL != env && 0 != str ) {
+        strChars = calloc((*env)->GetStringLength(env, str) + 1, sizeof(jchar));
+        if (strChars != NULL) {
+            (*env)->GetStringRegion(env, str, 0, (*env)->GetStringLength(env, str), strChars);
+        }
     }
     return strChars;
 }
 
-JNIEnv* JoglCommon_GetJNIEnv (int * shallBeDetached)
-{
+JNIEnv* JoglCommon_GetJNIEnv (int asDaemon, int * shallBeDetached) {
     JNIEnv* curEnv = NULL;
     JNIEnv* newEnv = NULL;
     int envRes;
 
-    if(NULL == _jvmHandle) {
-        fprintf(stderr, "JOGL: No JavaVM handle registered, call JoglCommon_init(..) 1st");
+    if(NULL==_jvmHandle) {
+        fprintf(stderr, "JOGL GetJNIEnv: NULL JVM handle, call JoglCommon_init 1st\n");
         return NULL;
     }
 
@@ -103,18 +93,23 @@ JNIEnv* JoglCommon_GetJNIEnv (int * shallBeDetached)
     envRes = (*_jvmHandle)->GetEnv(_jvmHandle, (void **) &curEnv, _jvmVersion) ;
     if( JNI_EDETACHED == envRes ) {
         // detached thread - attach to JVM
-        if( JNI_OK != ( envRes = (*_jvmHandle)->AttachCurrentThread(_jvmHandle, (void**) &newEnv, NULL) ) ) {
-            fprintf(stderr, "JNIEnv: can't attach thread: %d\n", envRes);
+        if( asDaemon ) {
+            envRes = (*_jvmHandle)->AttachCurrentThreadAsDaemon(_jvmHandle, (void**) &newEnv, NULL);
+        } else {
+            envRes = (*_jvmHandle)->AttachCurrentThread(_jvmHandle, (void**) &newEnv, NULL);
+        }
+        if( JNI_OK != envRes ) {
+            fprintf(stderr, "JOGL GetJNIEnv: Can't attach thread: %d\n", envRes);
             return NULL;
         }
         curEnv = newEnv;
     } else if( JNI_OK != envRes ) {
         // oops ..
-        fprintf(stderr, "can't GetEnv: %d\n", envRes);
+        fprintf(stderr, "JOGL GetJNIEnv: Can't GetEnv: %d\n", envRes);
         return NULL;
     }
     if (curEnv==NULL) {
-        fprintf(stderr, "env is NULL\n");
+        fprintf(stderr, "JOGL GetJNIEnv: env is NULL\n");
         return NULL;
     }
     *shallBeDetached = NULL != newEnv;
@@ -123,10 +118,8 @@ JNIEnv* JoglCommon_GetJNIEnv (int * shallBeDetached)
 
 void JoglCommon_ReleaseJNIEnv (int shallBeDetached) {
     if(NULL == _jvmHandle) {
-        fprintf(stderr, "JOGL: No JavaVM handle registered, call JoglCommon_init(..) 1st");
-    }
-
-    if(shallBeDetached) {
+        fprintf(stderr, "JOGL ReleaseJNIEnv: No JavaVM handle registered, call JoglCommon_init(..) 1st");
+    } else if(shallBeDetached) {
         (*_jvmHandle)->DetachCurrentThread(_jvmHandle);
     }
 }
diff --git a/src/jogl/native/JoglCommon.h b/src/jogl/native/JoglCommon.h
index 023b4be..2aeaf7d 100644
--- a/src/jogl/native/JoglCommon.h
+++ b/src/jogl/native/JoglCommon.h
@@ -1,3 +1,30 @@
+/**
+ * Copyright 2011 JogAmp Community. 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 JogAmp Community ``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 JogAmp Community OR
+ * 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.
+ * 
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
 
 #ifndef JOGL_COMMON_H
 #define JOGL_COMMON_H 1
@@ -7,29 +34,25 @@
 
 void JoglCommon_init(JNIEnv *env);
 
-/** Set by JoglCommon_init */
-JavaVM *JoglCommon_GetJVMHandle();
-
-/** Set by JoglCommon_init */
-int JoglCommon_GetJVMVersion();
-
 jchar* JoglCommon_GetNullTerminatedStringChars(JNIEnv* env, jstring str);
 
-/** env may be NULL, in which case JoglCommon_GetJNIEnv() is being used. */
 void JoglCommon_FatalError(JNIEnv *env, const char* msg, ...);
-
-/** env may be NULL, in which case JoglCommon_GetJNIEnv() is being used. */
 void JoglCommon_throwNewRuntimeException(JNIEnv *env, const char* msg, ...);
 
 /**
  *
- * 1) Store jvmHandle and jvmVersion is done by 'JoglCommon_init(JNIEnv*)'
- *    and internally used by 'JoglCommon_GetJNIEnv(..)' and 'JoglCommon_ReleaseJNIEnv(..)'.
+ * 1) Init static jvmHandle, jvmVersion and clazz references
+ *    from an early initialization call w/ valid 'JNIEnv * env'
+
+    JoglCommon_init(env);
+
  *
  * 2) Use current thread JNIEnv or attach current thread to JVM, generating new JNIEnv
  *
+
+    int asDaemon = 0;
     int shallBeDetached = 0;
-    JNIEnv* env = NewtCommon_GetJNIEnv(&shallBeDetached);
+    JNIEnv* env = JoglCommon_GetJNIEnv(asDaemon, &shallBeDetached);
     if(NULL==env) {
         DBG_PRINT("drawRect: null JNIEnv\n");
         return;
@@ -41,11 +64,13 @@ void JoglCommon_throwNewRuntimeException(JNIEnv *env, const char* msg, ...);
     .. your JNIEnv code here ..
 
  *
- * 4) Detach thread from JVM, if required
+ * 4) Detach thread from JVM if required, i.e. not attached as daemon!
+ *    Not recommended for recurring _daemon_ threads (performance)
  *
-    JoglCommon_ReleaseJNIEnv (shallBeDetached);
+    JoglCommon_ReleaseJNIEnv(shallBeDetached);
  */
-JNIEnv* JoglCommon_GetJNIEnv (int * shallBeDetached);
+JNIEnv* JoglCommon_GetJNIEnv (int asDaemon, int * shallBeDetached);
+
 void JoglCommon_ReleaseJNIEnv (int shallBeDetached);
 
 #endif
diff --git a/src/jogl/native/libav/ffmpeg_impl_template.c b/src/jogl/native/libav/ffmpeg_impl_template.c
index 44acfe4..e86b2a5 100644
--- a/src/jogl/native/libav/ffmpeg_impl_template.c
+++ b/src/jogl/native/libav/ffmpeg_impl_template.c
@@ -1499,7 +1499,7 @@ JNIEXPORT jint JNICALL FF_FUNC(seek0)
     int64_t pts1 = (int64_t) (pos1 * (int64_t) time_base.den)
                            / (1000 * (int64_t) time_base.num);
     if(pAV->verbose) {
-        fprintf(stderr, "SEEK: vid %d, aid %d, pos0 %d, pos1 %d, pts: %"PRId64" -> %"PRId64"\n", pAV->vid, pAV->aid, pos0, pos1, pts0, pts1);
+        fprintf(stderr, "SEEK: vid %d, aid %d, pos0 %"PRId64", pos1 %d, pts: %"PRId64" -> %"PRId64"\n", pAV->vid, pAV->aid, pos0, pos1, pts0, pts1);
     }
     int flags = 0;
     if(pos1 < pos0) {
@@ -1508,7 +1508,7 @@ JNIEXPORT jint JNICALL FF_FUNC(seek0)
     int res = -2;
     if(HAS_FUNC(sp_av_seek_frame)) {
         if(pAV->verbose) {
-            fprintf(stderr, "SEEK.0: pre  : s %d / %"PRId64" -> t %d / %"PRId64"\n", pos0, pts0, pos1, pts1);
+            fprintf(stderr, "SEEK.0: pre  : s %"PRId64" / %"PRId64" -> t %d / %"PRId64"\n", pos0, pts0, pos1, pts1);
         }
         sp_av_seek_frame(pAV->pFormatCtx, streamID, pts1, flags);
     } else if(HAS_FUNC(sp_avformat_seek_file)) {
diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m b/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m
index 75917d2..7ce8c58 100644
--- a/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m
+++ b/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m
@@ -578,6 +578,7 @@ static const GLfloat gl_verts[] = {
         quirks, dedicatedFramePosSet, dedicatedFrameSizeSet, dedicatedLayoutSet, self, texWidth, texHeight,
         lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height,
         dFrame.origin.x, dFrame.origin.y, dFrame.size.width, dFrame.size.height);
+    (void)lRect; // silence
     
     if( dedicatedFrameSet ) {
         [super setFrame: dedicatedFrame];
diff --git a/src/jogl/native/openmax/jogamp_opengl_util_av_impl_OMXGLMediaPlayer.c b/src/jogl/native/openmax/jogamp_opengl_util_av_impl_OMXGLMediaPlayer.c
index ec68a24..3166306 100644
--- a/src/jogl/native/openmax/jogamp_opengl_util_av_impl_OMXGLMediaPlayer.c
+++ b/src/jogl/native/openmax/jogamp_opengl_util_av_impl_OMXGLMediaPlayer.c
@@ -67,7 +67,7 @@ void OMXInstance_UpdateJavaAttributes(OMXToolBasicAV_t *pAV)
         return;
     }
     int shallBeDetached = 0;
-    JNIEnv  * env = JoglCommon_GetJNIEnv (&shallBeDetached); 
+    JNIEnv  * env = JoglCommon_GetJNIEnv (1 /* daemon */, &shallBeDetached); 
     if(NULL!=env) {
         (*env)->CallVoidMethod(env, (jobject)pAV->jni_instance, jni_mid_updateAttributes,
                                pAV->width, pAV->height, 
@@ -75,7 +75,8 @@ void OMXInstance_UpdateJavaAttributes(OMXToolBasicAV_t *pAV)
                                pAV->framerate, (uint32_t)(pAV->length*pAV->framerate), pAV->length,
                                (*env)->NewStringUTF(env, pAV->videoCodec),
                                (*env)->NewStringUTF(env, pAV->audioCodec) );
-        JoglCommon_ReleaseJNIEnv (shallBeDetached);
+        // detaching thread not required - daemon
+        // JoglCommon_ReleaseJNIEnv(shallBeDetached);
     }
 }
 
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/UpstreamSurfaceHookMutableSizePos.java b/src/nativewindow/classes/com/jogamp/nativewindow/UpstreamSurfaceHookMutableSizePos.java
new file mode 100644
index 0000000..e6fcc04
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/UpstreamSurfaceHookMutableSizePos.java
@@ -0,0 +1,36 @@
+package com.jogamp.nativewindow;
+
+public class UpstreamSurfaceHookMutableSizePos extends UpstreamSurfaceHookMutableSize {
+    int x, y;
+
+    /**
+     * @param width initial width
+     * @param height initial height
+     */
+    public UpstreamSurfaceHookMutableSizePos(int x, int y, int width, int height) {
+        super(width, height);
+        this.x= x;
+        this.y= y;
+    }
+
+    // @Override
+    public final void setPos(int x, int y) {
+        this.x= x;
+        this.y= y;
+    }
+
+    public final int getX() {
+        return x;
+    }
+
+    public final int getY() {
+        return y;
+    }
+
+    @Override
+    public String toString() {
+        return getClass().getSimpleName()+"[ "+ x + "/" + y + " " + width + "x" + height + "]";
+    }
+
+}
+
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java b/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java
index 9a19a7f..a57dafc 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java
@@ -38,12 +38,14 @@
 package com.jogamp.nativewindow.awt;
 
 import com.jogamp.common.os.Platform;
+import com.jogamp.common.util.awt.AWTEDTExecutor;
 import com.jogamp.common.util.locks.LockFactory;
 import com.jogamp.common.util.locks.RecursiveLock;
 import com.jogamp.nativewindow.MutableGraphicsConfiguration;
 
 import java.awt.Component;
 import java.awt.Container;
+import java.awt.Cursor;
 import java.awt.Window;
 import java.awt.event.ComponentEvent;
 import java.awt.event.ComponentListener;
@@ -62,7 +64,9 @@ import javax.media.nativewindow.OffscreenLayerSurface;
 import javax.media.nativewindow.SurfaceUpdatedListener;
 import javax.media.nativewindow.util.Insets;
 import javax.media.nativewindow.util.InsetsImmutable;
+import javax.media.nativewindow.util.PixelRectangle;
 import javax.media.nativewindow.util.Point;
+import javax.media.nativewindow.util.PointImmutable;
 import javax.media.nativewindow.util.Rectangle;
 import javax.media.nativewindow.util.RectangleImmutable;
 
@@ -121,11 +125,9 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
   private String jawtStr() { return "JAWTWindow["+id(JAWTWindow.this)+"]"; }
 
   private class JAWTComponentListener implements ComponentListener, HierarchyListener {
-        private boolean localVisibility = component.isVisible();
-        private boolean globalVisibility = localVisibility;
-        private boolean visibilityPropagation = false;
+        private boolean isShowing;
 
-        private String str(Object obj) {
+        private String str(final Object obj) {
             if( null == obj ) {
                 return "0xnil: null";
             } else if( obj instanceof Component ) {
@@ -136,15 +138,15 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
                 return id(obj)+": "+obj.getClass().getSimpleName()+"[..]";
             }
         }
-        private String s(ComponentEvent e) {
-            return "visible[local "+localVisibility+", global "+globalVisibility+", propag. "+visibilityPropagation+"],"+Platform.getNewline()+
+        private String s(final ComponentEvent e) {
+            return "visible[isShowing "+isShowing+"],"+Platform.getNewline()+
                    "    ** COMP "+str(e.getComponent())+Platform.getNewline()+
                    "    ** SOURCE "+str(e.getSource())+Platform.getNewline()+
                    "    ** THIS "+str(component)+Platform.getNewline()+
                    "    ** THREAD "+getThreadName();
         }
-        private String s(HierarchyEvent e) {
-            return "visible[local "+localVisibility+", global "+globalVisibility+", propag. "+visibilityPropagation+"], changeBits 0x"+Long.toHexString(e.getChangeFlags())+Platform.getNewline()+
+        private String s(final HierarchyEvent e) {
+            return "visible[isShowing "+isShowing+"], changeBits 0x"+Long.toHexString(e.getChangeFlags())+Platform.getNewline()+
                    "    ** COMP "+str(e.getComponent())+Platform.getNewline()+
                    "    ** SOURCE "+str(e.getSource())+Platform.getNewline()+
                    "    ** CHANGED "+str(e.getChanged())+Platform.getNewline()+
@@ -154,25 +156,34 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
         }
         @Override
         public final String toString() {
-            return "visible[local "+localVisibility+", global "+globalVisibility+", propag. "+visibilityPropagation+"],"+Platform.getNewline()+
+            return "visible[isShowing "+isShowing+"],"+Platform.getNewline()+
                    "    ** THIS "+str(component)+Platform.getNewline()+
                    "    ** THREAD "+getThreadName();
         }
 
-        public JAWTComponentListener() {
-            if(DEBUG) {
-                System.err.println(jawtStr()+".attach: "+toString());
-            }
-            component.addComponentListener(jawtComponentListener);
-            component.addHierarchyListener(jawtComponentListener);
+        private JAWTComponentListener() {
+            isShowing = component.isShowing();
+            AWTEDTExecutor.singleton.invoke(false, new Runnable() { // Bug 952: Avoid deadlock via AWTTreeLock acquisition ..
+                @Override
+                public void run() {
+                    if(DEBUG) {
+                        System.err.println(jawtStr()+".attach @ Thread "+getThreadName()+": "+JAWTComponentListener.this.toString());
+                    }
+                    component.addComponentListener(JAWTComponentListener.this);
+                    component.addHierarchyListener(JAWTComponentListener.this);
+                } } );
         }
 
-        public final void detach() {
-            if(DEBUG) {
-                System.err.println(jawtStr()+".detach: "+toString());
-            }
-            component.removeComponentListener(jawtComponentListener);
-            component.removeHierarchyListener(jawtComponentListener);
+        private final void detach() {
+            AWTEDTExecutor.singleton.invoke(false, new Runnable() { // Bug 952: Avoid deadlock via AWTTreeLock acquisition ..
+                @Override
+                public void run() {
+                    if(DEBUG) {
+                        System.err.println(jawtStr()+".detach @ Thread "+getThreadName()+": "+JAWTComponentListener.this.toString());
+                    }
+                    component.removeComponentListener(JAWTComponentListener.this);
+                    component.removeHierarchyListener(JAWTComponentListener.this);
+                } } );
         }
 
         @Override
@@ -180,7 +191,7 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
             if(DEBUG) {
                 System.err.println(jawtStr()+".componentResized: "+s(e));
             }
-            layoutSurfaceLayerIfEnabled(globalVisibility && localVisibility);
+            layoutSurfaceLayerIfEnabled(isShowing);
         }
 
         @Override
@@ -188,7 +199,7 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
             if(DEBUG) {
                 System.err.println(jawtStr()+".componentMoved: "+s(e));
             }
-            layoutSurfaceLayerIfEnabled(globalVisibility && localVisibility);
+            layoutSurfaceLayerIfEnabled(isShowing);
         }
 
         @Override
@@ -196,7 +207,7 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
             if(DEBUG) {
                 System.err.println(jawtStr()+".componentShown: "+s(e));
             }
-            layoutSurfaceLayerIfEnabled(globalVisibility && localVisibility);
+            layoutSurfaceLayerIfEnabled(isShowing);
         }
 
         @Override
@@ -204,53 +215,27 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
             if(DEBUG) {
                 System.err.println(jawtStr()+".componentHidden: "+s(e));
             }
-            layoutSurfaceLayerIfEnabled(globalVisibility && localVisibility);
+            layoutSurfaceLayerIfEnabled(isShowing);
         }
 
         @Override
         public final void hierarchyChanged(HierarchyEvent e) {
-            final long bits = e.getChangeFlags();
-            final java.awt.Component changed = e.getChanged();
-            final boolean compIsVisible = component.isVisible();
-            if( 0 != ( java.awt.event.HierarchyEvent.DISPLAYABILITY_CHANGED & bits ) ) {
-                final boolean displayable = changed.isDisplayable();
-                final boolean propagateDisplayability = changed == component && ( displayable && localVisibility ) != compIsVisible;
-                if( propagateDisplayability ) {
-                    // Propagate parent's displayability, i.e. 'removeNotify()' and 'addNotify()'
-                    final boolean _visible = displayable && localVisibility;
-                    visibilityPropagation = true;
-                    globalVisibility = displayable;
-                    if(DEBUG) {
-                        System.err.println(jawtStr()+".hierarchyChanged DISPLAYABILITY_CHANGED (1): displayable "+displayable+" -> visible "+_visible+", "+s(e));
-                    }
-                    component.setVisible(_visible);
-                } else if(DEBUG) {
-                    System.err.println(jawtStr()+".hierarchyChanged DISPLAYABILITY_CHANGED (x): displayable "+displayable+", "+s(e));
+            final boolean wasShowing = isShowing;
+            isShowing = component.isShowing();
+            int action = 0;
+            if( 0 != ( java.awt.event.HierarchyEvent.SHOWING_CHANGED & e.getChangeFlags() ) ) {
+                if( e.getChanged() != component && wasShowing != isShowing ) {
+                    // A parent component changed and caused a 'showing' state change,
+                    // propagate to offscreen-layer!
+                    layoutSurfaceLayerIfEnabled(isShowing);
+                    action = 1;
                 }
-            } else if( 0 != ( java.awt.event.HierarchyEvent.SHOWING_CHANGED & bits ) ) {
+            }
+            if(DEBUG) {
+                final java.awt.Component changed = e.getChanged();
+                final boolean displayable = changed.isDisplayable();
                 final boolean showing = changed.isShowing();
-                final boolean propagateVisibility = changed != component && ( showing && localVisibility ) != compIsVisible;
-                if( propagateVisibility ) {
-                    // Propagate parent's visibility
-                    final boolean _visible = showing && localVisibility;
-                    visibilityPropagation = true;
-                    globalVisibility = showing;
-                    if(DEBUG) {
-                        System.err.println(jawtStr()+".hierarchyChanged SHOWING_CHANGED (1): showing "+showing+" -> visible "+_visible+", "+s(e));
-                    }
-                    component.setVisible(_visible);
-                } else if( changed == component ) {
-                    // Update component's local visibility state
-                    if(!visibilityPropagation) {
-                        localVisibility = compIsVisible;
-                    }
-                    visibilityPropagation = false;
-                    if(DEBUG) {
-                        System.err.println(jawtStr()+".hierarchyChanged SHOWING_CHANGED (0): showing "+showing+" -> visible "+(showing && localVisibility)+", "+s(e));
-                    }
-                } else if(DEBUG) {
-                    System.err.println(jawtStr()+".hierarchyChanged SHOWING_CHANGED (x): showing "+showing+" -> visible "+(showing && localVisibility)+", "+s(e));
-                }
+                System.err.println(jawtStr()+".hierarchyChanged: action "+action+", displayable "+displayable+", showing [changed "+showing+", comp "+isShowing+"], "+s(e));
             }
         }
   }
@@ -413,7 +398,7 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
   @Override
   public final void setChosenCapabilities(CapabilitiesImmutable caps) {
       ((MutableGraphicsConfiguration)getGraphicsConfiguration()).setChosenCapabilities(caps);
-      getPrivateGraphicsConfiguration().setChosenCapabilities(caps);
+      config.setChosenCapabilities(caps);
   }
 
   @Override
@@ -421,6 +406,37 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
       return surfaceLock;
   }
 
+  @Override
+  public final boolean setCursor(final PixelRectangle pixelrect, final PointImmutable hotSpot) {
+      AWTEDTExecutor.singleton.invoke(false, new Runnable() {
+          public void run() {
+              Cursor c = null;
+              if( null == pixelrect || null == hotSpot ) {
+                  c = Cursor.getDefaultCursor();
+              } else {
+                  final java.awt.Point awtHotspot = new java.awt.Point(hotSpot.getX(), hotSpot.getY());
+                  try {
+                      c = AWTMisc.getCursor(pixelrect, awtHotspot);
+                  } catch (Exception e) {
+                      e.printStackTrace();
+                  }
+              }
+              if( null != c ) {
+                  component.setCursor(c);
+              }
+          } } );
+      return true;
+  }
+
+  @Override
+  public final boolean hideCursor() {
+      AWTEDTExecutor.singleton.invoke(false, new Runnable() {
+          public void run() {
+              component.setCursor(AWTMisc.getNullCursor());
+          } } );
+      return true;
+  }
+
   //
   // SurfaceUpdateListener
   //
@@ -560,10 +576,6 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
     return drawable;
   }
 
-  public final AWTGraphicsConfiguration getPrivateGraphicsConfiguration() {
-    return config;
-  }
-
   @Override
   public final AbstractGraphicsConfiguration getGraphicsConfiguration() {
     return config.getNativeGraphicsConfiguration();
@@ -597,6 +609,9 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
   public void destroy() {
     surfaceLock.lock();
     try {
+        if(DEBUG) {
+            System.err.println(jawtStr()+".destroy @ Thread "+getThreadName());
+        }
         jawtComponentListener.detach();
         invalidate();
     } finally {
@@ -726,6 +741,9 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
       if( null == sb ) {
           sb = new StringBuilder();
       }
+      sb.append("JVM version: ").append(Platform.JAVA_VERSION).append(" (").
+      append(Platform.JAVA_VERSION_NUMBER).
+      append(" update ").append(Platform.JAVA_VERSION_UPDATE).append(")").append(Platform.getNewline());
       if(null != jawt) {
           sb.append("JAWT version: 0x").append(Integer.toHexString(jawt.getCachedVersion())).
           append(", CA_LAYER: ").append(JAWTUtil.isJAWTUsingOffscreenLayer(jawt)).
@@ -751,7 +769,7 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
     sb.append(", pos "+getX()+"/"+getY()+", size "+getWidth()+"x"+getHeight()+
               ", visible "+component.isVisible());
     sb.append(", lockedExt "+isSurfaceLockedByOtherThread()+
-              ",\n\tconfig "+getPrivateGraphicsConfiguration()+
+              ",\n\tconfig "+config+
               ",\n\tawtComponent "+getAWTComponent()+
               ",\n\tsurfaceLock "+surfaceLock+"]");
 
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java b/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java
index c838149..6dc52a7 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java
@@ -86,6 +86,12 @@ public class EGLGraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
       return super.clone();
     }
 
+    /**
+     * Opens the EGL device if handle is null and it's {@link EGLDisplayLifecycleCallback} is valid.
+     * <p>
+     * {@inheritDoc}
+     * </p>
+     */
     @Override
     public boolean open() {
         if(null != eglLifecycleCallback && 0 == handle) {
@@ -101,6 +107,12 @@ public class EGLGraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
         return false;
     }
 
+    /**
+     * Closes the EGL device if handle is not null and it's {@link EGLDisplayLifecycleCallback} is valid.
+     * <p>
+     * {@inheritDoc}
+     * </p>
+     */
     @Override
     public boolean close() {
         if(null != eglLifecycleCallback && 0 != handle) {
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java
index 10e3f78..863e53b 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java
@@ -82,6 +82,21 @@ public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
         isXineramaEnabled = X11Util.XineramaIsEnabled(this);
     }
 
+    /**
+     * Constructs a new X11GraphicsDevice corresponding to the given display connection.
+     * <p>
+     * The constructor opens the native connection and takes ownership.
+     * </p>
+     * @param displayConnection the semantic display connection name
+     * @param locker custom {@link javax.media.nativewindow.ToolkitLock}, eg to force null locking w/ private connection
+     * @see DefaultGraphicsDevice#DefaultGraphicsDevice(String, String, int, long, ToolkitLock)
+     */
+    public X11GraphicsDevice(String displayConnection, int unitID, ToolkitLock locker) {
+        super(NativeWindowFactory.TYPE_X11, displayConnection, unitID, 0, locker);
+        handleOwner = true;
+        open();
+        isXineramaEnabled = X11Util.XineramaIsEnabled(this);
+    }
 
     private static int getDefaultScreenImpl(long dpy) {
         return X11Lib.DefaultScreen(dpy);
diff --git a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
index f916a8e..15ff2b1 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
@@ -247,7 +247,7 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
     * Returns a unique String object using {@link String#intern()} for the given arguments,
     * which object reference itself can be used as a key.
     */
-    protected static String getUniqueID(String type, String connection, int unitID) {
+    private static String getUniqueID(String type, String connection, int unitID) {
       final String r = (type + separator + connection + separator + unitID).intern();
       return r.intern();
     }
diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
index 6962ce5..15a43cf 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
@@ -43,15 +43,25 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import javax.media.nativewindow.util.Point;
+import javax.media.nativewindow.util.PointImmutable;
+
 import jogamp.nativewindow.Debug;
 import jogamp.nativewindow.NativeWindowFactoryImpl;
 import jogamp.nativewindow.ToolkitProperties;
 import jogamp.nativewindow.ResourceToolkitLock;
+import jogamp.nativewindow.WrappedWindow;
+import jogamp.nativewindow.macosx.OSXUtil;
+import jogamp.nativewindow.windows.GDIUtil;
+import jogamp.nativewindow.x11.X11Lib;
 
 import com.jogamp.common.os.Platform;
 import com.jogamp.common.util.ReflectionUtil;
+import com.jogamp.nativewindow.UpstreamSurfaceHookMutableSizePos;
 import com.jogamp.nativewindow.awt.AWTGraphicsDevice;
 import com.jogamp.nativewindow.awt.AWTGraphicsScreen;
+import com.jogamp.nativewindow.macosx.MacOSXGraphicsDevice;
+import com.jogamp.nativewindow.windows.WindowsGraphicsDevice;
 import com.jogamp.nativewindow.x11.X11GraphicsDevice;
 import com.jogamp.nativewindow.x11.X11GraphicsScreen;
 
@@ -627,4 +637,59 @@ public abstract class NativeWindowFactory {
                VisualIDHolder.VID_UNDEFINED != visualID ;
     }
 
+    /**
+     * Creates a native device type, following {@link #getNativeWindowType(boolean) getNativeWindowType(true)}.
+     * <p>
+     * The device will be opened if <code>own</code> is true, otherwise no native handle will ever be acquired.
+     * </p>
+     */
+    public static AbstractGraphicsDevice createDevice(String displayConnection, boolean own) {
+        final String nwt = NativeWindowFactory.getNativeWindowType(true);
+        if( NativeWindowFactory.TYPE_X11 == nwt ) {
+            if( own ) {
+                return new X11GraphicsDevice(displayConnection, AbstractGraphicsDevice.DEFAULT_UNIT, null /* ToolkitLock */);
+            } else {
+                return new X11GraphicsDevice(displayConnection, AbstractGraphicsDevice.DEFAULT_UNIT);
+            }
+        } else if( NativeWindowFactory.TYPE_WINDOWS == nwt ) {
+            return new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
+        } else if( NativeWindowFactory.TYPE_MACOSX == nwt ) {
+            return new MacOSXGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT);
+        }
+        throw new UnsupportedOperationException("n/a for this windowing system: "+nwt);
+    }
+
+    /**
+     * Creates a wrapped {@link NativeWindow} with given native handles and {@link AbstractGraphicsScreen}.
+     * <p>
+     * The given {@link UpstreamSurfaceHookMutableSizePos} maybe used to reflect resizes and repositioning of the native window.
+     * </p>
+     * <p>
+     * The {@link AbstractGraphicsScreen} may be created via {@link #createScreen(AbstractGraphicsDevice, int)}.
+     * </p>
+     * <p>
+     * The {@link AbstractGraphicsScreen} may have an underlying open {@link AbstractGraphicsDevice}
+     * or a simple <i>dummy</i> instance, see {@link #createDevice(String, boolean)}.
+     * </p>
+     */
+    public static NativeWindow createWrappedWindow(AbstractGraphicsScreen aScreen, long surfaceHandle, long windowHandle,
+                                                   UpstreamSurfaceHookMutableSizePos hook) {
+        final CapabilitiesImmutable caps = new Capabilities();
+        final AbstractGraphicsConfiguration config = new DefaultGraphicsConfiguration(aScreen, caps, caps);
+        return new WrappedWindow(config, surfaceHandle, hook, true, windowHandle);
+    }
+
+    public static PointImmutable getLocationOnScreen(NativeWindow nw) {
+        final String nwt = NativeWindowFactory.getNativeWindowType(true);
+        if( NativeWindowFactory.TYPE_X11 == nwt ) {
+            return X11Lib.GetRelativeLocation(nw.getDisplayHandle(), nw.getScreenIndex(), nw.getWindowHandle(), 0, 0, 0);
+        } else if( NativeWindowFactory.TYPE_WINDOWS == nwt ) {
+            return GDIUtil.GetRelativeLocation(nw.getWindowHandle(), 0, 0, 0);
+        } else if( NativeWindowFactory.TYPE_MACOSX == nwt ) {
+            return OSXUtil.GetLocationOnScreen(nw.getWindowHandle(), null == nw.getParent(), 0, 0);
+        }
+        throw new UnsupportedOperationException("n/a for this windowing system: "+nwt);
+    }
+
+
 }
diff --git a/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java b/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java
index 8681422..cf8cf89 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java
@@ -27,6 +27,9 @@
  */
 package javax.media.nativewindow;
 
+import javax.media.nativewindow.util.PixelRectangle;
+import javax.media.nativewindow.util.PointImmutable;
+
 import com.jogamp.common.util.locks.RecursiveLock;
 
 /**
@@ -65,4 +68,19 @@ public interface OffscreenLayerSurface {
   /** Returns the recursive lock object of this surface, which synchronizes multithreaded access. */
   public RecursiveLock getLock();
 
+  /**
+   * Optional method setting cursor in the corresponding on-screen surface/window, if exists.
+   *
+   * @param pixelrect cursor pixels, maybe null for default cursor
+   * @param hotSpot maybe null for default cursor
+   * @return true if successful, i.e. on-screen surface/window w/ cursor capabilities exists. Otherwise false.
+   */
+  public boolean setCursor(PixelRectangle pixelrect, PointImmutable hotSpot);
+
+  /**
+   * Optional method hiding the cursor in the corresponding on-screen surface/window, if exists.
+   *
+   * @return true if successful, i.e. on-screen surface/window w/ cursor capabilities exists. Otherwise false.
+   */
+  public boolean hideCursor();
 }
diff --git a/src/nativewindow/classes/javax/media/nativewindow/util/PixelFormat.java b/src/nativewindow/classes/javax/media/nativewindow/util/PixelFormat.java
new file mode 100644
index 0000000..823496a
--- /dev/null
+++ b/src/nativewindow/classes/javax/media/nativewindow/util/PixelFormat.java
@@ -0,0 +1,196 @@
+/**
+ * Copyright (c) 2014 JogAmp Community. 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 JogAmp Community ``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 JogAmp Community OR
+ * 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package javax.media.nativewindow.util;
+
+/**
+ * Basic pixel formats
+ * <p>
+ * Notation follows OpenGL notation, i.e.
+ * name consist of all it's component names
+ * followed by their bit size.
+ * </p>
+ * <p>
+ * Order of component names is from lowest-bit to highest-bit.
+ * </p>
+ * <p>
+ * In case component-size is 1 byte (e.g. OpenGL data-type GL_UNSIGNED_BYTE),
+ * component names are ordered from lowest-byte to highest-byte.
+ * Note that OpenGL applies special interpretation if
+ * data-type is e.g. GL_UNSIGNED_8_8_8_8_REV or GL_UNSIGNED_8_8_8_8_REV.
+ * </p>
+ * <p>
+ * PixelFormat can be converted to OpenGL GLPixelAttributes
+ * via
+ * <pre>
+ *  GLPixelAttributes glpa = GLPixelAttributes.convert(PixelFormat pixFmt, GLProfile glp);
+ * </pre>
+ * </p>
+ * <p>
+ * See OpenGL Specification 4.3 - February 14, 2013, Core Profile,
+ * Section 8.4.4 Transfer of Pixel Rectangles, p. 161-174.
+ * </ul>
+ *
+ * </p>
+ */
+public enum PixelFormat {
+    /**
+     * Pixel size is 1 bytes (8 bits) with one component of size 1 byte (8 bits).
+     * Compatible with:
+     * <ul>
+     *   <li>OpenGL: data-format GL_ALPHA (< GL3), GL_RED (>= GL3), data-type GL_UNSIGNED_BYTE</li>
+     *   <li>AWT: <i>none</i></li>
+     * </ul>
+     * </p>
+     */
+    LUMINANCE(1, 8),
+
+    /**
+     * Pixel size is 3 bytes (24 bits) with each component of size 1 byte (8 bits).
+     * <p>
+     * The components are interleaved in the order:
+     * <ul>
+     *   <li>Low to High: R, G, B</li>
+     * </ul>
+     * </p>
+     * <p>
+     * Compatible with:
+     * <ul>
+     *   <li>OpenGL: data-format GL_RGB, data-type GL_UNSIGNED_BYTE</li>
+     *   <li>AWT: <i>None</i></li>
+     * </ul>
+     * </p>
+     */
+    RGB888(3, 24),
+
+    /**
+     * Pixel size is 3 bytes (24 bits) with each component of size 1 byte (8 bits).
+     * <p>
+     * The components are interleaved in the order:
+     * <ul>
+     *   <li>Low to High: B, G, R</li>
+     * </ul>
+     * </p>
+     * <p>
+     * Compatible with:
+     * <ul>
+     *   <li>OpenGL: data-format GL_BGR (>= GL2), data-type GL_UNSIGNED_BYTE</li>
+     *   <li>AWT: {@link java.awt.image.BufferedImage#TYPE_3BYTE_BGR TYPE_3BYTE_BGR}</li>
+     * </ul>
+     * </p>
+     */
+    BGR888(3, 24),
+
+    /**
+     * Pixel size is 4 bytes (32 bits) with each component of size 1 byte (8 bits).
+     * <p>
+     * The components are interleaved in the order:
+     * <ul>
+     *   <li>Low to High: R, G, B, A</li>
+     * </ul>
+     * </p>
+     * <p>
+     * Compatible with:
+     * <ul>
+     *   <li>OpenGL: data-format GL_RGBA, data-type GL_UNSIGNED_BYTE</li>
+     *   <li>AWT: <i>None</i></li>
+     *   <li>PointerIcon: X11 (XCURSOR)</li>
+     *   <li>PNGJ: Scanlines</li>
+     * </ul>
+     * </p>
+     */
+    RGBA8888(4, 32),
+
+    /**
+     * Pixel size is 4 bytes (32 bits) with each component of size 1 byte (8 bits).
+     * <p>
+     * The components are interleaved in the order:
+     * <ul>
+     *   <li>Low to High: A, B, G, R</li>
+     * </ul>
+     * </p>
+     * <p>
+     * Compatible with:
+     * <ul>
+     *   <li>OpenGL: data-format GL_RGBA, data-type GL_UNSIGNED_8_8_8_8</li>
+     *   <li>AWT: {@link java.awt.image.BufferedImage#TYPE_4BYTE_ABGR TYPE_4BYTE_ABGR}</li>
+     * </ul>
+     * </p>
+     */
+    ABGR8888(4, 32),
+
+    /**
+     * Pixel size is 4 bytes (32 bits) with each component of size 1 byte (8 bits).
+     * <p>
+     * The components are interleaved in the order:
+     * <ul>
+     *   <li>Low to High: A, R, G, B</li>
+     * </ul>
+     * </p>
+     * <p>
+     * Compatible with:
+     * <ul>
+     *   <li>OpenGL: data-format GL_BGRA, data-type GL_UNSIGNED_INT_8_8_8_8</li>
+     *   <li>AWT: <i>None</i></li>
+     * </ul>
+     * </p>
+     */
+    ARGB8888(4, 32),
+
+    /**
+     * Pixel size is 4 bytes (32 bits) with each component of size 1 byte (8 bits).
+     * <p>
+     * The components are interleaved in the order:
+     * <ul>
+     *   <li>Low to High: B, G, R, A</li>
+     * </ul>
+     * </p>
+     * <p>
+     * Compatible with:
+     * <ul>
+     *   <li>OpenGL: data-format GL_BGRA, data-type GL_UNSIGNED_BYTE</li>
+     *   <li>AWT: {@link java.awt.image.BufferedImage#TYPE_INT_ARGB TYPE_INT_ARGB}</li>
+     *   <li>PointerIcon: Win32, OSX (NSBitmapImageRep), AWT</li>
+     *   <li>Window Icon: X11, Win32, OSX (NSBitmapImageRep)</li>
+     * </ul>
+     * </p>
+     */
+    BGRA8888(4, 32);
+
+    /** Number of components per pixel, e.g. 4 for RGBA. */
+    public final int componentCount;
+    /** Number of bits per pixel, e.g. 32 for RGBA. */
+    public final int bitsPerPixel;
+    /** Number of bytes per pixel, e.g. 4 for RGBA. */
+    public final int bytesPerPixel() { return (7+bitsPerPixel)/8; }
+
+    private PixelFormat(int componentCount, int bpp) {
+        this.componentCount = componentCount;
+        this.bitsPerPixel = bpp;
+    }
+}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/util/PixelFormatUtil.java b/src/nativewindow/classes/javax/media/nativewindow/util/PixelFormatUtil.java
new file mode 100644
index 0000000..361d034
--- /dev/null
+++ b/src/nativewindow/classes/javax/media/nativewindow/util/PixelFormatUtil.java
@@ -0,0 +1,374 @@
+/**
+ * Copyright (c) 2014 JogAmp Community. 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 JogAmp Community ``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 JogAmp Community OR
+ * 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package javax.media.nativewindow.util;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+import com.jogamp.common.nio.Buffers;
+
+/**
+ * Pixel Rectangle Utilities.
+ * <p>
+ * All conversion methods are endian independent.
+ * </p>
+ */
+public class PixelFormatUtil {
+    public static interface PixelSink {
+        /** Return the sink's destination pixelformat. */
+        PixelFormat getPixelformat();
+
+        /**
+         * Returns stride in byte-size, i.e. byte count from one line to the next.
+         * <p>
+         * Must be >= {@link #getPixelformat()}.{@link PixelFormat#bytesPerPixel() bytesPerPixel()} * {@link #getSize()}.{@link DimensionImmutable#getWidth() getWidth()}.
+         * </p>
+         */
+        int getStride();
+
+        /**
+         * Returns <code>true</code> if the sink's memory is laid out in
+         * OpenGL's coordinate system, <i>origin at bottom left</i>.
+         * Otherwise returns <code>false</code>, i.e. <i>origin at top left</i>.
+         */
+        boolean isGLOriented();
+    }
+    /**
+     * Pixel sink for up-to 32bit.
+     */
+    public static interface PixelSink32 extends PixelSink {
+        /**
+         * Will be invoked over all rows top-to down
+         * and all columns left-to-right.
+         * <p>
+         * Shall consider dest pixelformat and only store as much components
+         * as defined, up to 32bit.
+         * </p>
+         * <p>
+         * Implementation may better write single bytes from low-to-high bits,
+         * e.g. {@link ByteOrder#LITTLE_ENDIAN} order.
+         * Otherwise a possible endian conversion must be taken into consideration.
+         * </p>
+         * @param x
+         * @param y
+         * @param pixel
+         */
+        void store(int x, int y, int pixel);
+    }
+
+    /**
+     * Returns the {@link PixelFormat} with reversed components of <code>fmt</code>.
+     * If no reversed  {@link PixelFormat} is available, returns <code>fmt</code>.
+     */
+    public static PixelFormat getReversed(PixelFormat fmt) {
+        switch(fmt) {
+            case LUMINANCE:
+                return PixelFormat.LUMINANCE;
+            case RGB888:
+                return PixelFormat.BGR888;
+            case BGR888:
+                return PixelFormat.RGB888;
+            case RGBA8888:
+                return PixelFormat.ABGR8888;
+            case ABGR8888:
+                return PixelFormat.RGBA8888;
+            case ARGB8888:
+                return PixelFormat.BGRA8888;
+            case BGRA8888:
+                return PixelFormat.ABGR8888;
+            default:
+                throw new InternalError("Unhandled format "+fmt);
+        }
+    }
+
+    public static int getValue32(PixelFormat src_fmt, ByteBuffer src, int srcOff) {
+        switch(src_fmt) {
+            case LUMINANCE: {
+                    final byte c1 = src.get(srcOff++);
+                    return ( 0xff      ) << 24 | ( 0xff & c1 ) << 16 | ( 0xff & c1 ) << 8 | ( 0xff & c1 );
+                }
+            case RGB888:
+            case BGR888: {
+                    final byte c1  = src.get(srcOff++);
+                    final byte c2  = src.get(srcOff++);
+                    final byte c3  = src.get(srcOff++);
+                    return ( 0xff      ) << 24 | ( 0xff & c3 ) << 16 | ( 0xff & c2 ) << 8 | ( 0xff & c1 );
+                }
+            case RGBA8888:
+            case ABGR8888:
+            case ARGB8888:
+            case BGRA8888: {
+                    final byte c1  = src.get(srcOff++);
+                    final byte c2  = src.get(srcOff++);
+                    final byte c3  = src.get(srcOff++);
+                    final byte c4  = src.get(srcOff++);
+                    return ( 0xff & c4 ) << 24 | ( 0xff & c3 ) << 16 | ( 0xff & c2 ) << 8 | ( 0xff & c1 );
+                }
+            default:
+                throw new InternalError("Unhandled format "+src_fmt);
+        }
+    }
+
+    public static int convertToInt32(PixelFormat dest_fmt, final byte r, final byte g, final byte b, final byte a) {
+        switch(dest_fmt) {
+            case LUMINANCE: {
+                final byte l = ( byte) ( ( ( ( 0xff & r ) + ( 0xff & g ) + ( 0xff & b ) ) / 3 ) );
+                return ( 0xff     ) << 24 | ( 0xff & l ) << 16 | ( 0xff & l ) << 8 | ( 0xff & l );
+            }
+            case RGB888:
+                return ( 0xff     ) << 24 | ( 0xff & b ) << 16 | ( 0xff & g ) << 8 | ( 0xff & r );
+            case BGR888:
+                return ( 0xff     ) << 24 | ( 0xff & r ) << 16 | ( 0xff & g ) << 8 | ( 0xff & b );
+            case RGBA8888:
+                return ( 0xff & a ) << 24 | ( 0xff & b ) << 16 | ( 0xff & g ) << 8 | ( 0xff & r );
+            case ABGR8888:
+                return ( 0xff & r ) << 24 | ( 0xff & g ) << 16 | ( 0xff & b ) << 8 | ( 0xff & a );
+            case ARGB8888:
+                return ( 0xff & b ) << 24 | ( 0xff & g ) << 16 | ( 0xff & r ) << 8 | ( 0xff & a );
+            case BGRA8888:
+                return ( 0xff & a ) << 24 | ( 0xff & r ) << 16 | ( 0xff & g ) << 8 | ( 0xff & b );
+            default:
+                throw new InternalError("Unhandled format "+dest_fmt);
+        }
+    }
+
+    public static int convertToInt32(PixelFormat dest_fmt, PixelFormat src_fmt, ByteBuffer src, int srcOff) {
+        final byte r, g, b, a;
+        switch(src_fmt) {
+            case LUMINANCE:
+                r  = src.get(srcOff++); // R
+                g  = r;                 // G
+                b  = r;                 // B
+                a  = (byte) 0xff;       // A
+                break;
+            case RGB888:
+                r  = src.get(srcOff++); // R
+                g  = src.get(srcOff++); // G
+                b  = src.get(srcOff++); // B
+                a  = (byte) 0xff;       // A
+                break;
+            case BGR888:
+                b  = src.get(srcOff++); // B
+                g  = src.get(srcOff++); // G
+                r  = src.get(srcOff++); // R
+                a  = (byte) 0xff;       // A
+                break;
+            case RGBA8888:
+                r  = src.get(srcOff++); // R
+                g  = src.get(srcOff++); // G
+                b  = src.get(srcOff++); // B
+                a  = src.get(srcOff++); // A
+                break;
+            case ABGR8888:
+                a  = src.get(srcOff++); // A
+                b  = src.get(srcOff++); // B
+                g  = src.get(srcOff++); // G
+                r  = src.get(srcOff++); // R
+                break;
+            case ARGB8888:
+                a  = src.get(srcOff++); // A
+                r  = src.get(srcOff++); // R
+                g  = src.get(srcOff++); // G
+                b  = src.get(srcOff++); // B
+                break;
+            case BGRA8888:
+                b  = src.get(srcOff++); // B
+                g  = src.get(srcOff++); // G
+                r  = src.get(srcOff++); // R
+                a  = src.get(srcOff++); // A
+                break;
+            default:
+                throw new InternalError("Unhandled format "+src_fmt);
+        }
+        return convertToInt32(dest_fmt, r, g, b, a);
+    }
+
+    /**
+    public static int convertToInt32(PixelFormat dest_fmt, PixelFormat src_fmt, final int src_pixel) {
+        final byte r, g, b, a;
+        switch(src_fmt) {
+            case LUMINANCE:
+                r  = (byte) ( src_pixel       );  // R
+                g  = r;                           // G
+                b  = r;                           // B
+                a  = (byte) 0xff;                 // A
+                break;
+            case RGB888:
+                r  = (byte) ( src_pixel        ); // R
+                g  = (byte) ( src_pixel >>>  8 ); // G
+                b  = (byte) ( src_pixel >>> 16 ); // B
+                a  = (byte) 0xff;                 // A
+                break;
+            case BGR888:
+                b  = (byte) ( src_pixel        ); // B
+                g  = (byte) ( src_pixel >>>  8 ); // G
+                r  = (byte) ( src_pixel >>> 16 ); // R
+                a  = (byte) 0xff;                 // A
+                break;
+            case RGBA8888:
+                r  = (byte) ( src_pixel        ); // R
+                g  = (byte) ( src_pixel >>>  8 ); // G
+                b  = (byte) ( src_pixel >>> 16 ); // B
+                a  = (byte) ( src_pixel >>> 24 ); // A
+                break;
+            case ABGR8888:
+                a  = (byte) ( src_pixel        ); // A
+                b  = (byte) ( src_pixel >>>  8 ); // B
+                g  = (byte) ( src_pixel >>> 16 ); // G
+                r  = (byte) ( src_pixel >>> 24 ); // R
+                break;
+            case ARGB8888:
+                a  = (byte) ( src_pixel        ); // A
+                r  = (byte) ( src_pixel >>>  8 ); // R
+                g  = (byte) ( src_pixel >>> 16 ); // G
+                b  = (byte) ( src_pixel >>> 24 ); // B
+                break;
+            case BGRA8888:
+                b  = (byte) ( src_pixel        ); // B
+                g  = (byte) ( src_pixel >>>  8 ); // G
+                r  = (byte) ( src_pixel >>> 16 ); // R
+                a  = (byte) ( src_pixel >>> 24 ); // A
+                break;
+            default:
+                throw new InternalError("Unhandled format "+src_fmt);
+        }
+        return convertToInt32(dest_fmt, r, g, b, a);
+    } */
+
+    public static PixelRectangle convert32(final PixelRectangle src,
+                                           final PixelFormat destFmt, int ddestStride, final boolean isGLOriented,
+                                           final boolean destIsDirect) {
+        final int width = src.getSize().getWidth();
+        final int height = src.getSize().getHeight();
+        final int bpp = destFmt.bytesPerPixel();
+        final int destStride;
+        if( 0 != ddestStride ) {
+            destStride = ddestStride;
+            if( destStride < bpp * width ) {
+                throw new IllegalArgumentException("Invalid stride "+destStride+", must be greater than bytesPerPixel "+bpp+" * width "+width);
+            }
+        } else {
+            destStride = bpp * width;
+        }
+        final int capacity = destStride*height;
+        final ByteBuffer bb = destIsDirect ? Buffers.newDirectByteBuffer(capacity) : ByteBuffer.allocate(capacity).order(src.getPixels().order());
+
+        // System.err.println("XXX: SOURCE "+src);
+        // System.err.println("XXX: DEST fmt "+destFmt+", stride "+destStride+" ("+ddestStride+"), isGL "+isGLOriented+", "+width+"x"+height+", capacity "+capacity+", "+bb);
+
+        final PixelFormatUtil.PixelSink32 imgSink = new PixelFormatUtil.PixelSink32() {
+            public void store(int x, int y, int pixel) {
+                int o = destStride*y+x*bpp;
+                bb.put(o++, (byte) ( pixel        )); // 1
+                if( 3 <= bpp ) {
+                    bb.put(o++, (byte) ( pixel >>>  8 )); // 2
+                    bb.put(o++, (byte) ( pixel >>> 16 )); // 3
+                    if( 4 <= bpp ) {
+                        bb.put(o++, (byte) ( pixel >>> 24 )); // 4
+                    }
+                }
+            }
+            @Override
+            public final PixelFormat getPixelformat() {
+                return destFmt;
+            }
+            @Override
+            public final int getStride() {
+                return destStride;
+            }
+            @Override
+            public final boolean isGLOriented() {
+                return isGLOriented;
+            }
+        };
+        convert32(imgSink, src);
+        return new PixelRectangle.GenericPixelRect(destFmt, src.getSize(), destStride, isGLOriented, bb);
+    }
+
+    public static void convert32(PixelSink32 destInt32, final PixelRectangle src) {
+        convert32(destInt32,
+                  src.getPixels(), src.getPixelformat(),
+                  src.isGLOriented(),
+                  src.getSize().getWidth(), src.getSize().getHeight(),
+                  src.getStride());
+    }
+
+    /**
+     *
+     * @param dest32 32bit pixel sink
+     * @param src_bb
+     * @param src_fmt
+     * @param src_glOriented if true, the source memory is laid out in OpenGL's coordinate system, <i>origin at bottom left</i>,
+     *                       otherwise <i>origin at top left</i>.
+     * @param width
+     * @param height
+     * @param strideInBytes stride in byte-size, i.e. byte count from one line to the next.
+     *                      If zero, stride is set to <code>width * bytes-per-pixel</code>.
+     *                      If not zero, value must be >= <code>width * bytes-per-pixel</code>.
+     * @param stride_bytes stride in byte-size, i.e. byte count from one line to the next.
+     *                     Must be >= {@link PixelFormat#bytesPerPixel() src_fmt.bytesPerPixel()} * width.
+     * @throws IllegalArgumentException if <code>strideInBytes</code> is invalid
+     */
+    public static void convert32(PixelSink32 dest32,
+                                 final ByteBuffer src_bb, final PixelFormat src_fmt, final boolean src_glOriented, final int width, final int height, int stride_bytes) {
+        final int src_bpp = src_fmt.bytesPerPixel();
+        if( 0 != stride_bytes ) {
+            if( stride_bytes < src_bpp * width ) {
+                throw new IllegalArgumentException("Invalid stride "+stride_bytes+", must be greater than bytesPerPixel "+src_bpp+" * width "+width);
+            }
+        } else {
+            stride_bytes = src_bpp * width;
+        }
+        final PixelFormat dest_fmt = dest32.getPixelformat();
+        final boolean vert_flip = src_glOriented != dest32.isGLOriented();
+        final boolean fast_copy = src_fmt == dest_fmt && dest_fmt.bytesPerPixel() == 4 ;
+        // System.err.println("XXX: SRC fmt "+src_fmt+", stride "+stride_bytes+", isGL "+src_glOriented+", "+width+"x"+height);
+        // System.err.println("XXX: DST fmt "+dest_fmt+", fast_copy "+fast_copy);
+
+        if( fast_copy ) {
+            // Fast copy
+            for(int y=0; y<height; y++) {
+                int o = vert_flip ? ( height - 1 - y ) * stride_bytes : y * stride_bytes;
+                for(int x=0; x<width; x++) {
+                    dest32.store(x, y, getValue32(src_fmt, src_bb, o));
+                    o += src_bpp;
+                }
+            }
+        } else {
+            // Conversion
+            for(int y=0; y<height; y++) {
+                int o = vert_flip ? ( height - 1 - y ) * stride_bytes : y * stride_bytes;
+                for(int x=0; x<width; x++) {
+                    dest32.store( x, y, convertToInt32( dest_fmt, src_fmt, src_bb, o));
+                    o += src_bpp;
+                }
+            }
+        }
+    }
+}
+
diff --git a/src/nativewindow/classes/javax/media/nativewindow/util/PixelRectangle.java b/src/nativewindow/classes/javax/media/nativewindow/util/PixelRectangle.java
new file mode 100644
index 0000000..96c1f7b
--- /dev/null
+++ b/src/nativewindow/classes/javax/media/nativewindow/util/PixelRectangle.java
@@ -0,0 +1,194 @@
+/**
+ * Copyright (c) 2014 JogAmp Community. 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 JogAmp Community ``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 JogAmp Community OR
+ * 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package javax.media.nativewindow.util;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Pixel Rectangle identified by it's {@link #hashCode()}.
+ * <p>
+ * The {@link #getPixels()} are assumed to be immutable.
+ * </p>
+ */
+public interface PixelRectangle {
+    /**
+     * <p>
+     * Computes a hash code over:
+     * <ul>
+     *   <li>pixelformat</li>
+     *   <li>size</li>
+     *   <li>stride</li>
+     *   <li>isGLOriented</li>
+     *   <li>pixels</li>
+     * </ul>
+     * </p>
+     * <p>
+     * The hashCode shall be computed only once with first call
+     * and stored for later retrieval to enhance performance.
+     * </p>
+     * <p>
+     * {@inheritDoc}
+     * </p>
+     */
+    @Override
+    int hashCode();
+
+    /** Returns the {@link PixelFormat}. */
+    PixelFormat getPixelformat();
+
+    /** Returns the size, i.e. width and height. */
+    DimensionImmutable getSize();
+
+    /**
+     * Returns stride in byte-size, i.e. byte count from one line to the next.
+     * <p>
+     * Must be >= {@link #getPixelformat()}.{@link PixelFormat#bytesPerPixel() bytesPerPixel()} * {@link #getSize()}.{@link DimensionImmutable#getWidth() getWidth()}.
+     * </p>
+     */
+    int getStride();
+
+    /**
+     * Returns <code>true</code> if the memory is laid out in
+     * OpenGL's coordinate system, <i>origin at bottom left</i>.
+     * Otherwise returns <code>false</code>, i.e. <i>origin at top left</i>.
+     */
+    public boolean isGLOriented();
+
+    /** Returns the pixels. */
+    ByteBuffer getPixels();
+
+    @Override
+    String toString();
+
+    /**
+     * Generic PixelRectangle implementation
+     */
+    public static class GenericPixelRect implements PixelRectangle {
+        protected final PixelFormat pixelformat;
+        protected final DimensionImmutable size;
+        protected final int strideInBytes;
+        protected final boolean isGLOriented;
+        protected final ByteBuffer pixels;
+        private int hashCode = 0;
+        private volatile boolean hashCodeComputed = false;
+
+        /**
+         *
+         * @param pixelformat
+         * @param size
+         * @param strideInBytes stride in byte-size, i.e. byte count from one line to the next.
+         *                      If not zero, value must be >= <code>width * bytes-per-pixel</code>.
+         *                      If zero, stride is set to <code>width * bytes-per-pixel</code>.
+         * @param isGLOriented
+         * @param pixels
+         * @throws IllegalArgumentException if <code>strideInBytes</code> is invalid.
+         * @throws IndexOutOfBoundsException if <code>pixels</code> has insufficient bytes left
+         */
+        public GenericPixelRect(final PixelFormat pixelformat, final DimensionImmutable size, int strideInBytes, final boolean isGLOriented, final ByteBuffer pixels)
+                throws IllegalArgumentException, IndexOutOfBoundsException
+        {
+            if( 0 != strideInBytes ) {
+                if( strideInBytes < pixelformat.bytesPerPixel() * size.getWidth()) {
+                    throw new IllegalArgumentException("Invalid stride "+strideInBytes+", must be greater than bytesPerPixel "+pixelformat.bytesPerPixel()+" * width "+size.getWidth());
+                }
+            } else {
+                strideInBytes = pixelformat.bytesPerPixel() * size.getWidth();
+            }
+            final int reqBytes = strideInBytes * size.getHeight();
+            if( pixels.limit() < reqBytes ) {
+                throw new IndexOutOfBoundsException("Dest buffer has insufficient bytes left, needs "+reqBytes+": "+pixels);
+            }
+            this.pixelformat = pixelformat;
+            this.size = size;
+            this.strideInBytes = strideInBytes;
+            this.isGLOriented = isGLOriented;
+            this.pixels = pixels;
+        }
+
+        /**
+         * Copy ctor validating src.
+         * @param src
+         * @throws IllegalArgumentException if <code>strideInBytes</code> is invalid.
+         * @throws IndexOutOfBoundsException if <code>pixels</code> has insufficient bytes left
+         */
+        public GenericPixelRect(final PixelRectangle src)
+                throws IllegalArgumentException, IndexOutOfBoundsException
+        {
+            this(src.getPixelformat(), src.getSize(), src.getStride(), src.isGLOriented(), src.getPixels());
+        }
+
+        @Override
+        public int hashCode() {
+            if( !hashCodeComputed ) { // DBL CHECKED OK VOLATILE
+                synchronized (this) {
+                    if( !hashCodeComputed ) {
+                        // 31 * x == (x << 5) - x
+                        int hash = 31 + pixelformat.hashCode();
+                        hash = ((hash << 5) - hash) + size.hashCode();
+                        hash = ((hash << 5) - hash) + strideInBytes;
+                        hash = ((hash << 5) - hash) + ( isGLOriented ? 1 : 0);
+                        hashCode = ((hash << 5) - hash) + pixels.hashCode();
+                        hashCodeComputed = true;
+                    }
+                }
+            }
+            return hashCode;
+        }
+
+        @Override
+        public PixelFormat getPixelformat() {
+            return pixelformat;
+        }
+
+        @Override
+        public DimensionImmutable getSize() {
+            return size;
+        }
+
+        @Override
+        public int getStride() {
+            return strideInBytes;
+        }
+
+        @Override
+        public boolean isGLOriented() {
+            return isGLOriented;
+        }
+
+        @Override
+        public ByteBuffer getPixels() {
+            return pixels;
+        }
+
+        @Override
+        public final String toString() {
+            return "PixelRect[obj 0x"+Integer.toHexString(super.hashCode())+", "+pixelformat+", "+size+", stride "+strideInBytes+", isGLOrient "+isGLOriented+", pixels "+pixels+"]";
+        }
+    }
+}
+
diff --git a/src/nativewindow/classes/jogamp/nativewindow/ProxySurfaceImpl.java b/src/nativewindow/classes/jogamp/nativewindow/ProxySurfaceImpl.java
index 097fffe..fbff712 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/ProxySurfaceImpl.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/ProxySurfaceImpl.java
@@ -45,7 +45,7 @@ public abstract class ProxySurfaceImpl implements ProxySurface {
     private AbstractGraphicsConfiguration config; // control access due to delegation
     private UpstreamSurfaceHook upstream;
     private long surfaceHandle_old;
-    private RecursiveLock surfaceLock = LockFactory.createRecursiveLock();
+    private final RecursiveLock surfaceLock = LockFactory.createRecursiveLock();
     private int implBitfield;
     private boolean upstreamSurfaceHookLifecycleEnabled;
 
@@ -122,10 +122,6 @@ public abstract class ProxySurfaceImpl implements ProxySurface {
         throw new InternalError("UpstreamSurfaceHook given, but required method not implemented.");
     }
 
-    protected final AbstractGraphicsConfiguration getPrivateGraphicsConfiguration() {
-        return config;
-    }
-
     @Override
     public final AbstractGraphicsConfiguration getGraphicsConfiguration() {
         return config.getNativeGraphicsConfiguration();
diff --git a/src/nativewindow/classes/jogamp/nativewindow/WrappedWindow.java b/src/nativewindow/classes/jogamp/nativewindow/WrappedWindow.java
new file mode 100644
index 0000000..edb65eb
--- /dev/null
+++ b/src/nativewindow/classes/jogamp/nativewindow/WrappedWindow.java
@@ -0,0 +1,98 @@
+package jogamp.nativewindow;
+
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.NativeWindow;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
+import javax.media.nativewindow.util.Insets;
+import javax.media.nativewindow.util.InsetsImmutable;
+import javax.media.nativewindow.util.Point;
+
+import com.jogamp.nativewindow.UpstreamSurfaceHookMutableSizePos;
+
+public class WrappedWindow extends WrappedSurface implements NativeWindow {
+    private final InsetsImmutable insets = new Insets(0, 0, 0, 0);
+    private long windowHandle;
+
+    /**
+     * Utilizes a {@link UpstreamSurfaceHookMutableSizePos} to hold the size and postion information,
+     * which is being passed to the {@link ProxySurface} instance.
+     *
+     * @param cfg the {@link AbstractGraphicsConfiguration} to be used
+     * @param surfaceHandle the wrapped pre-existing native surface handle, maybe 0 if not yet determined
+     * @param initialX
+     * @param initialY
+     * @param initialWidth
+     * @param initialHeight
+     * @param ownsDevice <code>true</code> if this {@link ProxySurface} instance
+     *                  owns the {@link AbstractGraphicsConfiguration}'s {@link AbstractGraphicsDevice},
+     *                  otherwise <code>false</code>. Owning the device implies closing it at {@link #destroyNotify()}.
+     */
+    public WrappedWindow(AbstractGraphicsConfiguration cfg, long surfaceHandle, int initialX, int initialY, int initialWidth, int initialHeight, boolean ownsDevice, long windowHandle) {
+        this(cfg, surfaceHandle, new UpstreamSurfaceHookMutableSizePos(initialX, initialY, initialWidth, initialHeight), ownsDevice, windowHandle);
+    }
+
+    /**
+     * @param cfg the {@link AbstractGraphicsConfiguration} to be used
+     * @param surfaceHandle the wrapped pre-existing native surface handle, maybe 0 if not yet determined
+     * @param upstream the {@link UpstreamSurfaceHook} to be used
+     * @param ownsDevice <code>true</code> if this {@link ProxySurface} instance
+     *                  owns the {@link AbstractGraphicsConfiguration}'s {@link AbstractGraphicsDevice},
+     *                  otherwise <code>false</code>.
+     */
+    public WrappedWindow(AbstractGraphicsConfiguration cfg, long surfaceHandle, UpstreamSurfaceHookMutableSizePos upstream, boolean ownsDevice, long windowHandle) {
+        super(cfg, surfaceHandle, upstream, ownsDevice);
+        this.windowHandle = windowHandle;
+    }
+
+    @Override
+    protected void invalidateImpl() {
+      super.invalidateImpl();
+      windowHandle = 0;
+    }
+
+    @Override
+    public void destroy() {
+        destroyNotify();
+    }
+
+    @Override
+    public NativeWindow getParent() {
+        return null;
+    }
+
+    @Override
+    public long getWindowHandle() {
+        return windowHandle;
+    }
+
+    @Override
+    public InsetsImmutable getInsets() {
+        return insets;
+    }
+
+    @Override
+    public int getX() {
+        return ((UpstreamSurfaceHookMutableSizePos)getUpstreamSurfaceHook()).getX();
+    }
+
+    @Override
+    public int getY() {
+        return ((UpstreamSurfaceHookMutableSizePos)getUpstreamSurfaceHook()).getY();
+    }
+
+    @Override
+    public Point getLocationOnScreen(Point point) {
+        if(null!=point) {
+          return point;
+        } else {
+          return new Point(0, 0);
+        }
+    }
+
+    @Override
+    public boolean hasFocus() {
+        return false;
+    }
+}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/awt/AWTMisc.java b/src/nativewindow/classes/jogamp/nativewindow/awt/AWTMisc.java
index 0fa5006..069cffe 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/awt/AWTMisc.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/awt/AWTMisc.java
@@ -27,12 +27,17 @@
  */
 package jogamp.nativewindow.awt;
 
+import java.awt.Cursor;
 import java.awt.FocusTraversalPolicy;
 import java.awt.Insets;
+import java.awt.Point;
+import java.awt.Toolkit;
 import java.awt.Window;
 import java.awt.Component;
 import java.awt.Container;
 import java.awt.Frame;
+import java.awt.image.BufferedImage;
+import java.util.HashMap;
 
 import javax.swing.JComponent;
 import javax.swing.JFrame;
@@ -40,6 +45,9 @@ import javax.swing.JRootPane;
 import javax.swing.WindowConstants;
 import javax.media.nativewindow.NativeWindowException;
 import javax.media.nativewindow.WindowClosingProtocol;
+import javax.media.nativewindow.util.PixelRectangle;
+import javax.media.nativewindow.util.PixelFormat;
+import javax.media.nativewindow.util.PixelFormatUtil;
 import javax.swing.MenuSelectionManager;
 
 public class AWTMisc {
@@ -163,6 +171,55 @@ public class AWTMisc {
         MenuSelectionManager.defaultManager().clearSelectedPath();
     }
 
+    static final HashMap<Integer, Cursor> cursorMap = new HashMap<Integer, Cursor>();
+    static final Cursor nulCursor;
+    static {
+        final Toolkit toolkit = Toolkit.getDefaultToolkit();
+        final BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_4BYTE_ABGR);
+        nulCursor = toolkit.createCustomCursor(img, new Point(0,0), "nullCursor");
+    }
+
+    public static synchronized Cursor getNullCursor() { return nulCursor; }
+
+    public static synchronized Cursor getCursor(PixelRectangle pixelrect, Point hotSpot) {
+        // 31 * x == (x << 5) - x
+        int hash = 31 + pixelrect.hashCode();
+        hash = ((hash << 5) - hash) + hotSpot.hashCode();
+        final Integer key = Integer.valueOf(hash);
+
+        Cursor cursor = cursorMap.get(key);
+        if( null == cursor ) {
+            cursor = createCursor(pixelrect, hotSpot);
+            cursorMap.put(key, cursor);
+        }
+        return cursor;
+    }
+    private static synchronized Cursor createCursor(PixelRectangle pixelrect, Point hotSpot) {
+        final int width = pixelrect.getSize().getWidth();
+        final int height = pixelrect.getSize().getHeight();
+        final BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); // PixelFormat.BGRA8888
+        final PixelFormatUtil.PixelSink32 imgSink = new PixelFormatUtil.PixelSink32() {
+            public void store(int x, int y, int pixel) {
+                img.setRGB(x, y, pixel);
+            }
+            @Override
+            public final PixelFormat getPixelformat() {
+                return PixelFormat.BGRA8888;
+            }
+            @Override
+            public int getStride() {
+                return width*4;
+            }
+            @Override
+            public final boolean isGLOriented() {
+                return false;
+            }
+        };
+        PixelFormatUtil.convert32(imgSink, pixelrect);
+        final Toolkit toolkit = Toolkit.getDefaultToolkit();
+        return toolkit.createCustomCursor(img, hotSpot, pixelrect.toString());
+    }
+
     public static WindowClosingProtocol.WindowClosingMode AWT2NWClosingOperation(int awtClosingOperation) {
         switch (awtClosingOperation) {
             case WindowConstants.DISPOSE_ON_CLOSE:
diff --git a/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java b/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java
index a872e63..720ff9b 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java
@@ -59,7 +59,9 @@ public class GDIUtil implements ToolkitProperties {
                     if( !initIDs0() ) {
                         throw new NativeWindowException("GDI: Could not initialized native stub");
                     }
-                    dummyWindowClassFactory = new RegisteredClassFactory(dummyWindowClassNameBase, getDummyWndProc0(), true /* useDummyDispatchThread */);
+                    dummyWindowClassFactory = new RegisteredClassFactory(dummyWindowClassNameBase, getDummyWndProc0(),
+                                                                         true /* useDummyDispatchThread */,
+                                                                         0 /* iconSmallHandle */, 0 /* iconBigHandle */);
                     if(DEBUG) {
                         System.out.println("GDI.initSingleton() dummyWindowClassFactory "+dummyWindowClassFactory);
                     }
@@ -128,7 +130,9 @@ public class GDIUtil implements ToolkitProperties {
 
     private static final void dumpStack() { Thread.dumpStack(); } // Callback for JNI
 
-    static native boolean CreateWindowClass0(long hInstance, String clazzName, long wndProc);
+    /** Creates WNDCLASSEX instance */
+    static native boolean CreateWindowClass0(long hInstance, String clazzName, long wndProc, long iconSmallHandle, long iconBigHandle);
+    /** Destroys WNDCLASSEX instance */
     static native boolean DestroyWindowClass0(long hInstance, String className, long dispThreadCtx);
     static native long CreateDummyDispatchThread0();
 
diff --git a/src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClassFactory.java b/src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClassFactory.java
index ee41fe1..c4b4d14 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClassFactory.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClassFactory.java
@@ -50,6 +50,7 @@ public class RegisteredClassFactory {
     private final String classBaseName;
     private final long wndProc;
     private final boolean useDummyDispatchThread;
+    private final long iconSmallHandle, iconBigHandle;
 
     private RegisteredClass sharedClass = null;
     private int classIter = 0;
@@ -92,10 +93,12 @@ public class RegisteredClassFactory {
     /** Application handle. */
     public static long getHInstance() { return hInstance; }
 
-    public RegisteredClassFactory(String classBaseName, long wndProc, boolean useDummyDispatchThread) {
+    public RegisteredClassFactory(String classBaseName, long wndProc, boolean useDummyDispatchThread, long iconSmallHandle, long iconBigHandle) {
         this.classBaseName = classBaseName;
         this.wndProc = wndProc;
         this.useDummyDispatchThread = useDummyDispatchThread;
+        this.iconSmallHandle = iconSmallHandle;
+        this.iconBigHandle = iconBigHandle;
         synchronized(registeredFactories) {
             registeredFactories.add(this);
         }
@@ -114,7 +117,7 @@ public class RegisteredClassFactory {
                   // Retry with next clazz name, this could happen if more than one JVM is running
                   clazzName = classBaseName + classIter;
                   classIter++;
-                  registered = GDIUtil.CreateWindowClass0(hInstance, clazzName, wndProc);
+                  registered = GDIUtil.CreateWindowClass0(hInstance, clazzName, wndProc, iconSmallHandle, iconBigHandle);
               }
               if( !registered ) {
                   throw new NativeWindowException("Error: Could not create WindowClass: "+clazzName);
diff --git a/src/nativewindow/native/NativewindowCommon.c b/src/nativewindow/native/NativewindowCommon.c
index 212bdf8..e65f872 100644
--- a/src/nativewindow/native/NativewindowCommon.c
+++ b/src/nativewindow/native/NativewindowCommon.c
@@ -3,20 +3,55 @@
 #include <string.h>
 #include <sys/time.h>
 
+// #define STDERR_TO_FILE 1
+
 static const char * const ClazzNameRuntimeException = "java/lang/RuntimeException";
 static jclass    runtimeExceptionClz=NULL;
 
+static JavaVM *_jvmHandle = NULL;
+static int _jvmVersion = 0;
+
+int NativewindowCommon_init(JNIEnv *env) {
+    if(NULL==_jvmHandle) {
+        if(0 != (*env)->GetJavaVM(env, &_jvmHandle)) {
+            NativewindowCommon_FatalError(env, "Nativewindow: Can't fetch JavaVM handle");
+        } else {
+            _jvmVersion = (*env)->GetVersion(env);
+        }
+        jclass c = (*env)->FindClass(env, ClazzNameRuntimeException);
+        if(NULL==c) {
+            NativewindowCommon_FatalError(env, "Nativewindow: Can't find %s", ClazzNameRuntimeException);
+        }
+        runtimeExceptionClz = (jclass)(*env)->NewGlobalRef(env, c);
+        (*env)->DeleteLocalRef(env, c);
+        if(NULL==runtimeExceptionClz) {
+            NativewindowCommon_FatalError(env, "Nativewindow: Can't use %s", ClazzNameRuntimeException);
+        }
+        #ifdef STDERR_TO_FILE
+            FILE * old_stderr = stderr; 
+            FILE * new_stderr = freopen("jogamp_stderr.log", "w", stderr);
+            fprintf(stderr, "STDERR_TO_FILE: %p -> %p\n", old_stderr, new_stderr);
+        #endif
+        return 1;
+    }
+    return 0;
+}
+
 void NativewindowCommon_FatalError(JNIEnv *env, const char* msg, ...)
 {
     char buffer[512];
     va_list ap;
 
-    va_start(ap, msg);
-    vsnprintf(buffer, sizeof(buffer), msg, ap);
-    va_end(ap);
+    if( NULL != msg ) {
+        va_start(ap, msg);
+        vsnprintf(buffer, sizeof(buffer), msg, ap);
+        va_end(ap);
 
-    fprintf(stderr, "%s\n", buffer);
-    (*env)->FatalError(env, buffer);
+        fprintf(stderr, "%s\n", buffer);
+        if(NULL != env) {
+            (*env)->FatalError(env, buffer);
+        }
+    }
 }
 
 void NativewindowCommon_throwNewRuntimeException(JNIEnv *env, const char* msg, ...)
@@ -24,27 +59,20 @@ void NativewindowCommon_throwNewRuntimeException(JNIEnv *env, const char* msg, .
     char buffer[512];
     va_list ap;
 
-    va_start(ap, msg);
-    vsnprintf(buffer, sizeof(buffer), msg, ap);
-    va_end(ap);
+    if(NULL==_jvmHandle) {
+        NativewindowCommon_FatalError(env, "Nativewindow: NULL JVM handle, call NativewindowCommon_init 1st\n");
+        return;
+    }
 
-    (*env)->ThrowNew(env, runtimeExceptionClz, buffer);
-}
+    if( NULL != msg ) {
+        va_start(ap, msg);
+        vsnprintf(buffer, sizeof(buffer), msg, ap);
+        va_end(ap);
 
-int NativewindowCommon_init(JNIEnv *env) {
-    if(NULL==runtimeExceptionClz) {
-        jclass c = (*env)->FindClass(env, ClazzNameRuntimeException);
-        if(NULL==c) {
-            NativewindowCommon_FatalError(env, "Nativewindow: can't find %s", ClazzNameRuntimeException);
-        }
-        runtimeExceptionClz = (jclass)(*env)->NewGlobalRef(env, c);
-        (*env)->DeleteLocalRef(env, c);
-        if(NULL==runtimeExceptionClz) {
-            NativewindowCommon_FatalError(env, "Nativewindow: can't use %s", ClazzNameRuntimeException);
+        if(NULL != env) {
+            (*env)->ThrowNew(env, runtimeExceptionClz, buffer);
         }
-        return 1;
     }
-    return 0;
 }
 
 const char * NativewindowCommon_GetStaticStringMethod(JNIEnv *jniEnv, jclass clazz, jmethodID jGetStrID, char *dest, int destSize, const char *altText) {
@@ -68,45 +96,60 @@ const char * NativewindowCommon_GetStaticStringMethod(JNIEnv *jniEnv, jclass cla
 jchar* NativewindowCommon_GetNullTerminatedStringChars(JNIEnv* env, jstring str)
 {
     jchar* strChars = NULL;
-    strChars = calloc((*env)->GetStringLength(env, str) + 1, sizeof(jchar));
-    if (strChars != NULL) {
-        (*env)->GetStringRegion(env, str, 0, (*env)->GetStringLength(env, str), strChars);
+    if( NULL != env && 0 != str ) {
+        strChars = calloc((*env)->GetStringLength(env, str) + 1, sizeof(jchar));
+        if (strChars != NULL) {
+            (*env)->GetStringRegion(env, str, 0, (*env)->GetStringLength(env, str), strChars);
+        }
     }
     return strChars;
 }
 
-JNIEnv* NativewindowCommon_GetJNIEnv (JavaVM * jvmHandle, int jvmVersion, int asDaemon, int * shallBeDetached) {
+JNIEnv* NativewindowCommon_GetJNIEnv (int asDaemon, int * shallBeDetached) {
     JNIEnv* curEnv = NULL;
     JNIEnv* newEnv = NULL;
     int envRes;
 
+    if(NULL==_jvmHandle) {
+        fprintf(stderr, "Nativewindow GetJNIEnv: NULL JVM handle, call NativewindowCommon_init 1st\n");
+        return NULL;
+    }
+
     // retrieve this thread's JNIEnv curEnv - or detect it's detached
-    envRes = (*jvmHandle)->GetEnv(jvmHandle, (void **) &curEnv, jvmVersion) ;
+    envRes = (*_jvmHandle)->GetEnv(_jvmHandle, (void **) &curEnv, _jvmVersion) ;
     if( JNI_EDETACHED == envRes ) {
         // detached thread - attach to JVM
         if( asDaemon ) {
-            envRes = (*jvmHandle)->AttachCurrentThreadAsDaemon(jvmHandle, (void**) &newEnv, NULL);
+            envRes = (*_jvmHandle)->AttachCurrentThreadAsDaemon(_jvmHandle, (void**) &newEnv, NULL);
         } else {
-            envRes = (*jvmHandle)->AttachCurrentThread(jvmHandle, (void**) &newEnv, NULL);
+            envRes = (*_jvmHandle)->AttachCurrentThread(_jvmHandle, (void**) &newEnv, NULL);
         }
         if( JNI_OK != envRes ) {
-            fprintf(stderr, "JNIEnv: can't attach thread: %d\n", envRes);
+            fprintf(stderr, "Nativewindow GetJNIEnv: Can't attach thread: %d\n", envRes);
             return NULL;
         }
         curEnv = newEnv;
     } else if( JNI_OK != envRes ) {
         // oops ..
-        fprintf(stderr, "can't GetEnv: %d\n", envRes);
+        fprintf(stderr, "Nativewindow GetJNIEnv: Can't GetEnv: %d\n", envRes);
         return NULL;
     }
     if (curEnv==NULL) {
-        fprintf(stderr, "env is NULL\n");
+        fprintf(stderr, "Nativewindow GetJNIEnv: env is NULL\n");
         return NULL;
     }
     *shallBeDetached = NULL != newEnv;
     return curEnv;
 }
 
+void NativewindowCommon_ReleaseJNIEnv (int shallBeDetached) {
+    if(NULL == _jvmHandle) {
+        fprintf(stderr, "Nativewindow ReleaseJNIEnv: No JavaVM handle registered, call NativewindowCommon_init(..) 1st");
+    } else if(shallBeDetached) {
+        (*_jvmHandle)->DetachCurrentThread(_jvmHandle);
+    }
+}
+
 int64_t NativewindowCommon_CurrentTimeMillis() {
     struct timeval tv;
     gettimeofday(&tv,NULL);
diff --git a/src/nativewindow/native/NativewindowCommon.h b/src/nativewindow/native/NativewindowCommon.h
index a23fad9..f19552e 100644
--- a/src/nativewindow/native/NativewindowCommon.h
+++ b/src/nativewindow/native/NativewindowCommon.h
@@ -1,3 +1,30 @@
+/**
+ * Copyright 2011 JogAmp Community. 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 JogAmp Community ``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 JogAmp Community OR
+ * 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.
+ * 
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
 
 #ifndef NATIVEWINDOW_COMMON_H
 #define NATIVEWINDOW_COMMON_H 1
@@ -14,7 +41,39 @@ jchar* NativewindowCommon_GetNullTerminatedStringChars(JNIEnv* env, jstring str)
 void NativewindowCommon_FatalError(JNIEnv *env, const char* msg, ...);
 void NativewindowCommon_throwNewRuntimeException(JNIEnv *env, const char* msg, ...);
 
-JNIEnv* NativewindowCommon_GetJNIEnv (JavaVM * jvmHandle, int jvmVersion, int asDaemon, int * shallBeDetached);
+/**
+ *
+ * 1) Init static jvmHandle, jvmVersion and clazz references
+ *    from an early initialization call w/ valid 'JNIEnv * env'
+
+    NativewindowCommon_init(env);
+
+ *
+ * 2) Use current thread JNIEnv or attach current thread to JVM, generating new JNIEnv
+ *
+
+    int asDaemon = 0;
+    int shallBeDetached = 0;
+    JNIEnv* env = NewtCommon_GetJNIEnv(asDaemon, &shallBeDetached);
+    if(NULL==env) {
+        DBG_PRINT("drawRect: null JNIEnv\n");
+        return;
+    }
+    
+ *
+ * 3) Use JNIEnv ..
+ *
+    .. your JNIEnv code here ..
+
+ *
+ * 4) Detach thread from JVM if required, i.e. not attached as daemon!
+ *    Not recommended for recurring _daemon_ threads (performance)
+ *
+    NewtCommon_ReleaseJNIEnv(shallBeDetached);
+ */
+JNIEnv* NativewindowCommon_GetJNIEnv (int asDaemon, int * shallBeDetached);
+
+void NativewindowCommon_ReleaseJNIEnv (int shallBeDetached);
 
 int64_t NativewindowCommon_CurrentTimeMillis();
 
diff --git a/src/nativewindow/native/macosx/OSXmisc.m b/src/nativewindow/native/macosx/OSXmisc.m
index 6a7952e..d95d1cd 100644
--- a/src/nativewindow/native/macosx/OSXmisc.m
+++ b/src/nativewindow/native/macosx/OSXmisc.m
@@ -75,11 +75,9 @@ static const char * const ClazzNameInsetsCstrSignature = "(IIII)V";
 static jclass insetsClz = NULL;
 static jmethodID insetsCstr = NULL;
 
-static int _initialized=0;
-
 JNIEXPORT jboolean JNICALL 
 Java_jogamp_nativewindow_macosx_OSXUtil_initIDs0(JNIEnv *env, jclass _unused) {
-    if(0==_initialized) {
+    if( NativewindowCommon_init(env) ) {
         jclass c;
         c = (*env)->FindClass(env, ClazzNamePoint);
         if(NULL==c) {
@@ -119,7 +117,6 @@ Java_jogamp_nativewindow_macosx_OSXUtil_initIDs0(JNIEnv *env, jclass _unused) {
         if(NULL==runnableRunID) {
             NativewindowCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_macosx_MacWindow_initIDs0: can't fetch %s.run()V", ClazzNameRunnable);
         }
-        _initialized=1;
     }
     return JNI_TRUE;
 }
@@ -337,6 +334,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetNSWindow0
   BOOL fixedFrameSet;
   CGRect fixedFrame;
   float visibleOpacity;
+  BOOL visibleOpacityZeroed;
 }
 - (id)init;
 #ifdef DBG_LIFECYCLE
@@ -360,6 +358,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetNSWindow0
     o->fixedFrameSet = 0;
     o->fixedFrame = CGRectMake(0, 0, 0, 0);
     o->visibleOpacity = 1.0;
+    o->visibleOpacityZeroed = 0;
     DBG_PRINT("MyCALayer::init.X: new %p\n", o);
     return o;
 }
@@ -464,12 +463,16 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetNSWindow0
             [self setOpacity: visibleOpacity];
             [self setHidden: NO];
             [subLayer setHidden: NO];
+            visibleOpacityZeroed = 0;
         } else {
             [subLayer setHidden: YES];
             [self setHidden: YES];
-            visibleOpacity = [self opacity];
+            if( !visibleOpacityZeroed ) {
+                visibleOpacity = [self opacity];
+            }
             [subLayer setOpacity: 0.0];
             [self setOpacity: 0.0];
+            visibleOpacityZeroed = 1;
         }
         int posQuirk  = 0 != ( NW_DEDICATEDFRAME_QUIRK_POSITION & caLayerQuirks ) && ( lFrame.origin.x!=0 || lFrame.origin.y!=0 );
         int sizeQuirk = 0 != ( NW_DEDICATEDFRAME_QUIRK_SIZE & caLayerQuirks ) && ( lFrame.size.width!=width || lFrame.size.height!=height );
@@ -491,8 +494,8 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetNSWindow0
             fixedFrame.size.width = width;
             fixedFrame.size.height = height;
         }
-        DBG_PRINT("CALayer::FixCALayerLayout0.0: Quirks [%d, pos %d, size %d, lout %d], Super %p frame %lf/%lf %lfx%lf, Root %p frame %lf/%lf %lfx%lf, usr %d/%d %dx%d -> %lf/%lf %lfx%lf\n",
-            caLayerQuirks, posQuirk, sizeQuirk, loutQuirk,
+        DBG_PRINT("CALayer::FixCALayerLayout0.0: Visible %d, Quirks [%d, pos %d, size %d, lout %d, force %d], Super %p frame %lf/%lf %lfx%lf, Root %p frame %lf/%lf %lfx%lf, usr %d/%d %dx%d -> %lf/%lf %lfx%lf\n",
+            (int)visible, caLayerQuirks, posQuirk, sizeQuirk, loutQuirk, (int)force,
             superLayer, superFrame.origin.x, superFrame.origin.y, superFrame.size.width, superFrame.size.height, 
             self, lFrame.origin.x, lFrame.origin.y, lFrame.size.width, lFrame.size.height, 
             x, y, width, height, fixedFrame.origin.x, fixedFrame.origin.y, fixedFrame.size.width, fixedFrame.size.height);
@@ -517,8 +520,9 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetNSWindow0
             _w = width;
             _h = height;
         }
-        DBG_PRINT("CALayer::FixCALayerLayout1.0: Quirks [%d, pos %d, size %d, lout %d], SubL %p frame %lf/%lf %lfx%lf, usr %dx%d -> %lf/%lf %lfx%lf\n",
-            caLayerQuirks, posQuirk, sizeQuirk, loutQuirk, subLayer, lFrame.origin.x, lFrame.origin.y, lFrame.size.width, lFrame.size.height,
+        DBG_PRINT("CALayer::FixCALayerLayout1.0: Visible %d, Quirks [%d, pos %d, size %d, lout %d, force %d], SubL %p frame %lf/%lf %lfx%lf, usr %dx%d -> %lf/%lf %lfx%lf\n",
+            (int)visible, caLayerQuirks, posQuirk, sizeQuirk, loutQuirk, (int)force,
+            subLayer, lFrame.origin.x, lFrame.origin.y, lFrame.size.width, lFrame.size.height,
             width, height, _x, _y, _w, _h);
         if( force || posQuirk || sizeQuirk || loutQuirk ) {
             lFrame.origin.x = _x;
@@ -775,12 +779,10 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow_Uns
 @interface MainRunnable : NSObject
 
 {
-    JavaVM *jvmHandle;
-    int jvmVersion;
     jobject runnableObj;
 }
 
-- (id) initWithRunnable: (jobject)runnable jvmHandle: (JavaVM*)jvm jvmVersion: (int)jvmVers;
+- (id) initWithRunnable: (jobject)runnable;
 - (void) jRun;
 
 #ifdef DBG_LIFECYCLE
@@ -794,10 +796,8 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow_Uns
 
 @implementation MainRunnable
 
-- (id) initWithRunnable: (jobject)runnable jvmHandle: (JavaVM*)jvm jvmVersion: (int)jvmVers
+- (id) initWithRunnable: (jobject)runnable
 {
-    jvmHandle = jvm;
-    jvmVersion = jvmVers;
     runnableObj = runnable;
     return [super init];
 }
@@ -805,7 +805,7 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow_Uns
 - (void) jRun
 {
     int shallBeDetached = 0;
-    JNIEnv* env = NativewindowCommon_GetJNIEnv(jvmHandle, jvmVersion, 1 /* asDaemon */, &shallBeDetached);
+    JNIEnv* env = NativewindowCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached);
     DBG_PRINT2("MainRunnable.1 env: %d\n", (int)(NULL!=env));
     if(NULL!=env) {
         DBG_PRINT2("MainRunnable.1.0\n");
@@ -813,11 +813,9 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow_Uns
         DBG_PRINT2("MainRunnable.1.1\n");
         (*env)->DeleteGlobalRef(env, runnableObj);
 
-        if (shallBeDetached) {
-            DBG_PRINT2("MainRunnable.1.3\n");
-            // Keep attached on main thread !
-            // (*jvmHandle)->DetachCurrentThread(jvmHandle);
-        }
+        DBG_PRINT2("MainRunnable.1.3\n");
+        // detaching thread not required - daemon
+        // NativewindowCommon_ReleaseJNIEnv(shallBeDetached);
     }
     DBG_PRINT2("MainRunnable.X\n");
 }
@@ -861,17 +859,8 @@ static void RunOnThread (JNIEnv *env, jobject runnable, BOOL onMain, jint delayI
     if ( forkOnMain ) {
         jobject runnableObj = (*env)->NewGlobalRef(env, runnable);
 
-        JavaVM *jvmHandle = NULL;
-        int jvmVersion = 0;
-
-        if(0 != (*env)->GetJavaVM(env, &jvmHandle)) {
-            jvmHandle = NULL;
-        } else {
-            jvmVersion = (*env)->GetVersion(env);
-        }
-
         DBG_PRINT2( "RunOnThread.1.0\n");
-        MainRunnable * mr = [[MainRunnable alloc] initWithRunnable: runnableObj jvmHandle: jvmHandle jvmVersion: jvmVersion];
+        MainRunnable * mr = [[MainRunnable alloc] initWithRunnable: runnableObj];
 
         if( onMain ) {
             [mr performSelectorOnMainThread:@selector(jRun) withObject:nil waitUntilDone:NO];
diff --git a/src/nativewindow/native/win32/GDImisc.c b/src/nativewindow/native/win32/GDImisc.c
index b55988c..bec1d49 100644
--- a/src/nativewindow/native/win32/GDImisc.c
+++ b/src/nativewindow/native/win32/GDImisc.c
@@ -237,11 +237,12 @@ Java_jogamp_nativewindow_windows_GDIUtil_CreateDummyDispatchThread0
  */
 JNIEXPORT jboolean JNICALL
 Java_jogamp_nativewindow_windows_GDIUtil_CreateWindowClass0
-    (JNIEnv *env, jclass _unused, jlong jHInstance, jstring jClazzName, jlong wndProc)
+    (JNIEnv *env, jclass _unused, jlong jHInstance, jstring jClazzName, jlong wndProc,
+     jlong iconSmallHandle, jlong iconBigHandle)
 {
     HINSTANCE hInstance = (HINSTANCE) (intptr_t) jHInstance;
     const TCHAR* clazzName = NULL;
-    WNDCLASS  wc;
+    WNDCLASSEX wc;
     jboolean res;
 
 #ifdef UNICODE
@@ -251,23 +252,25 @@ Java_jogamp_nativewindow_windows_GDIUtil_CreateWindowClass0
 #endif
 
     ZeroMemory( &wc, sizeof( wc ) );
-    if( GetClassInfo( hInstance,  clazzName, &wc ) ) {
+    if( GetClassInfoEx( hInstance,  clazzName, &wc ) ) {
         // registered already
         res = JNI_TRUE;
     } else {
         // register now
         ZeroMemory( &wc, sizeof( wc ) );
+        wc.cbSize = sizeof(WNDCLASSEX);
         wc.style = CS_HREDRAW | CS_VREDRAW ;
         wc.lpfnWndProc = (WNDPROC) (intptr_t) wndProc;
         wc.cbClsExtra = 0;
         wc.cbWndExtra = 0;
         wc.hInstance = hInstance;
-        wc.hIcon = NULL;
-        wc.hCursor = LoadCursor( NULL, IDC_ARROW);
+        wc.hIcon = (HICON) (intptr_t) iconBigHandle;
+        wc.hCursor = NULL;
         wc.hbrBackground = NULL; // no background paint - GetStockObject(BLACK_BRUSH);
         wc.lpszMenuName = NULL;
         wc.lpszClassName = clazzName;
-        res = ( 0 != RegisterClass( &wc ) ) ? JNI_TRUE : JNI_FALSE ;
+        wc.hIconSm = (HICON) (intptr_t) iconSmallHandle;
+        res = ( 0 != RegisterClassEx( &wc ) ) ? JNI_TRUE : JNI_FALSE ;
     }
 
 #ifdef UNICODE
@@ -484,7 +487,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_windows_GDIUtil_DestroyWindo
 JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_windows_GDIUtil_initIDs0
   (JNIEnv *env, jclass gdiClazz)
 {
-    if(NativewindowCommon_init(env)) {
+    if( NativewindowCommon_init(env) ) {
         jclass c = (*env)->FindClass(env, ClazzNamePoint);
         if(NULL==c) {
             NativewindowCommon_FatalError(env, "FatalError jogamp_nativewindow_windows_GDIUtil: can't find %s", ClazzNamePoint);
diff --git a/src/nativewindow/native/x11/Xmisc.c b/src/nativewindow/native/x11/Xmisc.c
index 7b9dc34..247dc13 100644
--- a/src/nativewindow/native/x11/Xmisc.c
+++ b/src/nativewindow/native/x11/Xmisc.c
@@ -113,68 +113,56 @@ static jmethodID pointCstr = NULL;
 static void _initClazzAccess(JNIEnv *env) {
     jclass c;
 
-    if(!NativewindowCommon_init(env)) return;
-
-    getCurrentThreadNameID = (*env)->GetStaticMethodID(env, X11UtilClazz, "getCurrentThreadName", "()Ljava/lang/String;");
-    if(NULL==getCurrentThreadNameID) {
-        NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't get method getCurrentThreadName");
-    }
-    dumpStackID = (*env)->GetStaticMethodID(env, X11UtilClazz, "dumpStack", "()V");
-    if(NULL==dumpStackID) {
-        NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't get method dumpStack");
-    }
-
-    c = (*env)->FindClass(env, ClazzNameBuffers);
-    if(NULL==c) {
-        NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't find %s", ClazzNameBuffers);
-    }
-    clazzBuffers = (jclass)(*env)->NewGlobalRef(env, c);
-    (*env)->DeleteLocalRef(env, c);
-    if(NULL==clazzBuffers) {
-        NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't use %s", ClazzNameBuffers);
-    }
-    c = (*env)->FindClass(env, ClazzNameByteBuffer);
-    if(NULL==c) {
-        NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't find %s", ClazzNameByteBuffer);
-    }
-    clazzByteBuffer = (jclass)(*env)->NewGlobalRef(env, c);
-    (*env)->DeleteLocalRef(env, c);
-    if(NULL==c) {
-        NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't use %s", ClazzNameByteBuffer);
-    }
-
-    cstrBuffers = (*env)->GetStaticMethodID(env, clazzBuffers, 
-                            ClazzNameBuffersStaticCstrName, ClazzNameBuffersStaticCstrSignature);
-    if(NULL==cstrBuffers) {
-        NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't create %s.%s %s",
-            ClazzNameBuffers, ClazzNameBuffersStaticCstrName, ClazzNameBuffersStaticCstrSignature);
-    }
+    if( NativewindowCommon_init(env) ) {
+        getCurrentThreadNameID = (*env)->GetStaticMethodID(env, X11UtilClazz, "getCurrentThreadName", "()Ljava/lang/String;");
+        if(NULL==getCurrentThreadNameID) {
+            NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't get method getCurrentThreadName");
+        }
+        dumpStackID = (*env)->GetStaticMethodID(env, X11UtilClazz, "dumpStack", "()V");
+        if(NULL==dumpStackID) {
+            NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't get method dumpStack");
+        }
 
-    c = (*env)->FindClass(env, ClazzNamePoint);
-    if(NULL==c) {
-        NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't find %s", ClazzNamePoint);
-    }
-    pointClz = (jclass)(*env)->NewGlobalRef(env, c);
-    (*env)->DeleteLocalRef(env, c);
-    if(NULL==pointClz) {
-        NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't use %s", ClazzNamePoint);
-    }
-    pointCstr = (*env)->GetMethodID(env, pointClz, ClazzAnyCstrName, ClazzNamePointCstrSignature);
-    if(NULL==pointCstr) {
-        NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't fetch %s.%s %s",
-            ClazzNamePoint, ClazzAnyCstrName, ClazzNamePointCstrSignature);
-    }
-}
+        c = (*env)->FindClass(env, ClazzNameBuffers);
+        if(NULL==c) {
+            NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't find %s", ClazzNameBuffers);
+        }
+        clazzBuffers = (jclass)(*env)->NewGlobalRef(env, c);
+        (*env)->DeleteLocalRef(env, c);
+        if(NULL==clazzBuffers) {
+            NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't use %s", ClazzNameBuffers);
+        }
+        c = (*env)->FindClass(env, ClazzNameByteBuffer);
+        if(NULL==c) {
+            NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't find %s", ClazzNameByteBuffer);
+        }
+        clazzByteBuffer = (jclass)(*env)->NewGlobalRef(env, c);
+        (*env)->DeleteLocalRef(env, c);
+        if(NULL==c) {
+            NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't use %s", ClazzNameByteBuffer);
+        }
 
-static JavaVM *jvmHandle = NULL;
-static int jvmVersion = 0;
+        cstrBuffers = (*env)->GetStaticMethodID(env, clazzBuffers, 
+                                ClazzNameBuffersStaticCstrName, ClazzNameBuffersStaticCstrSignature);
+        if(NULL==cstrBuffers) {
+            NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't create %s.%s %s",
+                ClazzNameBuffers, ClazzNameBuffersStaticCstrName, ClazzNameBuffersStaticCstrSignature);
+        }
 
-static void setupJVMVars(JNIEnv * env) {
-    if( NULL != env && NULL == jvmHandle ) {
-        if(0 != (*env)->GetJavaVM(env, &jvmHandle)) {
-            jvmHandle = NULL;
+        c = (*env)->FindClass(env, ClazzNamePoint);
+        if(NULL==c) {
+            NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't find %s", ClazzNamePoint);
+        }
+        pointClz = (jclass)(*env)->NewGlobalRef(env, c);
+        (*env)->DeleteLocalRef(env, c);
+        if(NULL==pointClz) {
+            NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't use %s", ClazzNamePoint);
+        }
+        pointCstr = (*env)->GetMethodID(env, pointClz, ClazzAnyCstrName, ClazzNamePointCstrSignature);
+        if(NULL==pointCstr) {
+            NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't fetch %s.%s %s",
+                ClazzNamePoint, ClazzAnyCstrName, ClazzNamePointCstrSignature);
         }
-        jvmVersion = (*env)->GetVersion(env);
     }
 }
 
@@ -201,8 +189,8 @@ static int x11ErrorHandler(Display *dpy, XErrorEvent *e)
             (int)e->request_code, (int)e->minor_code, reqCodeStr);
         fflush(stderr);
 
-        if( NULL != jvmHandle && ( errorHandlerDebug || errorHandlerThrowException ) ) {
-            jniEnv = NativewindowCommon_GetJNIEnv(jvmHandle, jvmVersion, 0 /* asDaemon */, &shallBeDetached);
+        if( errorHandlerDebug || errorHandlerThrowException ) {
+            jniEnv = NativewindowCommon_GetJNIEnv(0 /* asDaemon */, &shallBeDetached);
             if(NULL == jniEnv) {
                 fprintf(stderr, "Nativewindow X11 Error: null JNIEnv");
                 fflush(stderr);
@@ -219,10 +207,7 @@ static int x11ErrorHandler(Display *dpy, XErrorEvent *e)
                                                             e->error_code, errCodeStr, e->display, (int)e->resourceid, (int)e->serial,
                                                             (int)e->request_code, (int)e->minor_code, reqCodeStr);
             }
-
-            if (shallBeDetached) {
-                (*jvmHandle)->DetachCurrentThread(jvmHandle);
-            }
+            NativewindowCommon_ReleaseJNIEnv(shallBeDetached);
         }
     }
 
@@ -234,7 +219,6 @@ static void NativewindowCommon_x11ErrorHandlerEnable(JNIEnv * env, Display *dpy,
     if(onoff) {
         if(force || NULL==origErrorHandler) {
             XErrorHandler prevErrorHandler;
-            setupJVMVars(env);
             prevErrorHandler = XSetErrorHandler(x11ErrorHandler);
             if(x11ErrorHandler != prevErrorHandler) { // if forced don't overwrite w/ orig w/ our handler
                 origErrorHandler = prevErrorHandler;
@@ -266,14 +250,10 @@ static int x11IOErrorHandler(Display *dpy)
     fprintf(stderr, "Nativewindow X11 IOError: Display %p (%s): %s\n", dpy, dpyName, errnoStr);
     fflush(stderr);
 
-    if( NULL != jvmHandle ) {
-        jniEnv = NativewindowCommon_GetJNIEnv(jvmHandle, jvmVersion, 0 /* asDaemon */, &shallBeDetached);
-        if (NULL != jniEnv) {
-            NativewindowCommon_FatalError(jniEnv, "Nativewindow X11 IOError: Display %p (%s): %s", dpy, dpyName, errnoStr);
-            if (shallBeDetached) {
-                (*jvmHandle)->DetachCurrentThread(jvmHandle);
-            }
-        }
+    jniEnv = NativewindowCommon_GetJNIEnv(0 /* asDaemon */, &shallBeDetached);
+    if (NULL != jniEnv) {
+        NativewindowCommon_FatalError(jniEnv, "Nativewindow X11 IOError: Display %p (%s): %s", dpy, dpyName, errnoStr);
+        NativewindowCommon_ReleaseJNIEnv(shallBeDetached);
     }
     if(NULL!=origIOErrorHandler) {
         origIOErrorHandler(dpy);
@@ -284,7 +264,6 @@ static int x11IOErrorHandler(Display *dpy)
 static void x11IOErrorHandlerEnable(int onoff, JNIEnv * env) {
     if(onoff) {
         if(NULL==origIOErrorHandler) {
-            setupJVMVars(env);
             origIOErrorHandler = XSetIOErrorHandler(x11IOErrorHandler);
         }
     } else {
@@ -347,25 +326,24 @@ JNIEXPORT jobject JNICALL
 Java_jogamp_nativewindow_x11_X11Lib_XGetVisualInfo1__JJLjava_nio_ByteBuffer_2Ljava_lang_Object_2I(JNIEnv *env, jclass _unused, jlong arg0, jlong arg1, jobject arg2, jobject arg3, jint arg3_byte_offset) {
   XVisualInfo * _ptr2 = NULL;
   int * _ptr3 = NULL;
-  XVisualInfo *  _res;
-  int count;
-  jobject jbyteSource;
-  jobject jbyteCopy;
-    if(0==arg0) {
-        NativewindowCommon_FatalError(env, "invalid display connection..");
-    }
-    if (arg2 != NULL) {
-        _ptr2 = (XVisualInfo *) (((char*) (*env)->GetDirectBufferAddress(env, arg2)) + 0);
-    }
-  if (arg3 != NULL) {
-    _ptr3 = (int *) (((char*) (*env)->GetPrimitiveArrayCritical(env, arg3, NULL)) + arg3_byte_offset);
+  XVisualInfo *  _res = NULL;
+  int count = 0;
+  jobject jbyteSource = NULL;
+  jobject jbyteCopy = NULL;
+  if( 0 == arg0 || 0 == arg2 || 0 == arg3 ) {
+    NativewindowCommon_FatalError(env, "invalid display connection, vinfo_template or nitems_return");
+    return NULL;
   }
-  NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) arg0, 0, 1, errorHandlerQuiet, 0);
-  _res = XGetVisualInfo((Display *) (intptr_t) arg0, (long) arg1, (XVisualInfo *) _ptr2, (int *) _ptr3);
-  // NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) arg0, 0, 0, errorHandlerQuiet, 0);
-  count = _ptr3[0];
-  if (arg3 != NULL) {
-    (*env)->ReleasePrimitiveArrayCritical(env, arg3, _ptr3, 0);
+  _ptr2 = (XVisualInfo *) (((char*) (*env)->GetDirectBufferAddress(env, arg2)) + 0);
+  if( NULL != _ptr2 ) {
+      _ptr3 = (int *) (((char*) (*env)->GetPrimitiveArrayCritical(env, arg3, NULL)) + arg3_byte_offset);
+      if( NULL != _ptr3 ) {
+          NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) arg0, 0, 1, errorHandlerQuiet, 0);
+          _res = XGetVisualInfo((Display *) (intptr_t) arg0, (long) arg1, (XVisualInfo *) _ptr2, (int *) _ptr3);
+          // NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) arg0, 0, 0, errorHandlerQuiet, 0);
+          count = _ptr3[0];
+          (*env)->ReleasePrimitiveArrayCritical(env, arg3, _ptr3, 0);
+      }
   }
   if (_res == NULL) return NULL;
 
diff --git a/src/newt/classes/com/jogamp/newt/Display.java b/src/newt/classes/com/jogamp/newt/Display.java
index a0a0984..4b38fcc 100644
--- a/src/newt/classes/com/jogamp/newt/Display.java
+++ b/src/newt/classes/com/jogamp/newt/Display.java
@@ -28,17 +28,26 @@
 
 package com.jogamp.newt;
 
-import com.jogamp.newt.util.EDTUtil;
-import jogamp.newt.Debug;
-
+import java.io.IOException;
 import java.lang.ref.WeakReference;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
 
 import javax.media.nativewindow.AbstractGraphicsDevice;
 import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.util.PixelRectangle;
+import javax.media.nativewindow.util.PixelFormat;
+import javax.media.nativewindow.util.PointImmutable;
+
+import jogamp.newt.Debug;
+
+import com.jogamp.common.util.IOUtil;
+import com.jogamp.newt.util.EDTUtil;
 
 public abstract class Display {
     public static final boolean DEBUG = Debug.debug("Display");
+    protected static final boolean DEBUG_POINTER_ICON = Debug.debug("Display.PointerIcon");
 
     /** return precomputed hashCode from FQN {@link #getFQName()} */
     @Override
@@ -56,6 +65,167 @@ public abstract class Display {
     }
 
     /**
+     * Native PointerIcon handle.
+     * <p>
+     * Instances can be created via {@link Display}'s
+     * {@link Display#createPointerIcon(com.jogamp.common.util.IOUtil.ClassResources, int, int) createPointerIcon(pngResource, ..)}
+     * or {@link Display#createPointerIcon(PixelRectangle, int, int) createPointerIcon(pixelrect, ..)}.
+     * </p>
+     * <p>
+     * Instance is {@link #destroy()}'ed automatically if it's {@link #getDisplay() associated Display} is destroyed.
+     * </p>
+     * <p>
+     * Instance can be re-validated after destruction via {@link #validate()}.
+     * </p>
+     * <p>
+     * {@link PointerIcon} must not be {@link #destroy() destroyed} while in use!
+     * </p>
+     * <p>
+     * {@link PointerIcon} may be {@link #destroy() destroyed} manually after use,
+     * i.e. when no {@link Window} {@link Window#setPointerIcon(PointerIcon) uses them} anymore.
+     * However, this is not required.
+     * </p>
+     * <p>
+     * PointerIcons can be used via {@link Window#setPointerIcon(PointerIcon)}.
+     * </p>
+     */
+    public static interface PointerIcon extends PixelRectangle {
+        /**
+         * Always neatly packed, i.e. width * bytes_per_pixel.
+         * <p>
+         * {@inheritDoc}
+         * </p>
+         */
+        @Override
+        int getStride();
+
+        /**
+         * Always false, i.e. origin is TOP-LEFT.
+         * <p>
+         * {@inheritDoc}
+         * </p>
+         */
+        boolean isGLOriented();
+
+        /**
+         * Computes a hash code over:
+         * <ul>
+         *   <li>display</li>
+         *   <li>pixelformat</li>
+         *   <li>size</li>
+         *   <li>stride</li>
+         *   <li>isGLOriented</li>
+         *   <li>pixels</li>
+         *   <li>hotspot</li>
+         * </ul>
+         * Dismissing the native handle!
+         * <p>
+         * The hashCode shall be computed only once with first call
+         * and stored for later retrieval to enhance performance.
+         * </p>
+         * <p>
+         * {@inheritDoc}
+         * </p>
+         */
+        @Override
+        int hashCode();
+
+        /**
+         * @return the associated Display
+         */
+        Display getDisplay();
+
+        /** Returns the hotspot. */
+        PointImmutable getHotspot();
+
+        /**
+         * Returns true if valid, otherwise false.
+         * <p>
+         * A PointerIcon instance becomes invalid if it's {@link #getDisplay() associated Display} is destroyed.
+         * </p>
+         */
+        boolean isValid();
+
+        /**
+         * Returns true if instance {@link #isValid()} or validation was successful, otherwise false.
+         * <p>
+         * Validation, i.e. recreation, is required if instance became invalid, see {@link #isValid()}.
+         * </p>
+         */
+        boolean validate();
+
+        /**
+         * Destroys this instance.
+         * <p>
+         * Will be called automatically if it's {@link #getDisplay() associated Display} is destroyed.
+         * </p>
+         */
+        void destroy();
+    }
+
+    /**
+     * Returns the native platform's {@link PointerIcon.PixelFormat} for pointer-icon pixel data.
+     * <p>
+     * Using this value will avoid conversion within {@link #createPointerIcon(PixelRectangle, int, int)}.
+     * </p>
+     */
+    public abstract PixelFormat getNativePointerIconPixelFormat();
+
+    /**
+     * Returns the native platform's direct NIO buffer requirement pointer-icon pixel data.
+     * <p>
+     * Using this value will avoid conversion within {@link #createPointerIcon(PixelRectangle, int, int)}.
+     * </p>
+     */
+    public abstract boolean getNativePointerIconForceDirectNIO();
+
+    /**
+     * Returns the newly created {@link PointerIcon} or <code>null</code> if not implemented on platform.
+     * <p>
+     * See {@link PointerIcon} for lifecycle semantics.
+     * </p>
+     *
+     * @param pngResource single PNG resource for the {@link PointerIcon}. Only the first entry of {@link IOUtil.ClassResources#resourcePaths} is used.
+     * @param hotX pointer hotspot x-coord, origin is upper-left corner
+     * @param hotY pointer hotspot y-coord, origin is upper-left corner
+     *
+     * @throws IllegalArgumentException if pngResource is null or invalid
+     * @throws IllegalStateException if this Display instance is not {@link #isNativeValid() valid yet}.
+     * @throws IOException if the <code>pngResource</code> could not be {@link IOUtil.ClassResources#resolve(int) resolved}
+     *                     or via the PNG parser processing the input stream.
+     *
+     * @see PointerIcon
+     * @see Window#setPointerIcon(PointerIcon)
+     */
+    public abstract PointerIcon createPointerIcon(final IOUtil.ClassResources pngResource, final int hotX, final int hotY)
+            throws IllegalArgumentException, IllegalStateException, IOException;
+
+    /**
+     * Returns the newly created {@link PointerIcon} or <code>null</code> if not implemented on platform.
+     * <p>
+     * See {@link PointerIcon} for lifecycle semantics.
+     * </p>
+     * <p>
+     * In case {@link #getNativePointerIconPixelFormat()} or {@link #getNativePointerIconForceDirectNIO()}
+     * is not matched by the given <code>pixelrect</code>, the <code>pixelrect</code> is converted
+     * into the required {@link PixelFormat} and NIO type.
+     * </p>
+     *
+     * @param pixelrect {@link PixelRectangle} source for the {@link PointerIcon}
+     * @param hotX pointer hotspot x-coord, origin is upper-left corner
+     * @param hotY pointer hotspot y-coord, origin is upper-left corner
+     *
+     * @throws IllegalArgumentException if pixelrect is null.
+     * @throws IllegalStateException if this Display instance is not {@link #isNativeValid() valid yet}.
+     *
+     * @see PointerIcon
+     * @see Window#setPointerIcon(PointerIcon)
+     * @see #getNativePointerIconPixelFormat()
+     * @see #getNativePointerIconForceDirectNIO()
+     */
+    public abstract PointerIcon createPointerIcon(final PixelRectangle pixelrect, final int hotX, final int hotY) throws IllegalArgumentException, IllegalStateException;
+
+    /**
      * Manual trigger the native creation, if it is not done yet.<br>
      * This is useful to be able to request the {@link javax.media.nativewindow.AbstractGraphicsDevice}, via
      * {@link #getGraphicsDevice()}.<br>
@@ -222,7 +392,7 @@ public abstract class Display {
         synchronized(displayList) {
             int i = fromIndex >= 0 ? fromIndex : displayList.size() - 1 ;
             while( ( incr > 0 ) ? i < displayList.size() : i >= 0 ) {
-                final Display display = (Display) displayList.get(i).get();
+                final Display display = displayList.get(i).get();
                 if( null == display ) {
                     // Clear GC'ed dead reference entry!
                     displayList.remove(i);
diff --git a/src/newt/classes/com/jogamp/newt/NewtFactory.java b/src/newt/classes/com/jogamp/newt/NewtFactory.java
index 5ae3f36..9685200 100644
--- a/src/newt/classes/com/jogamp/newt/NewtFactory.java
+++ b/src/newt/classes/com/jogamp/newt/NewtFactory.java
@@ -36,6 +36,7 @@ package com.jogamp.newt;
 
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import java.util.Arrays;
 
 import javax.media.nativewindow.AbstractGraphicsConfiguration;
 import javax.media.nativewindow.AbstractGraphicsDevice;
@@ -44,6 +45,8 @@ import javax.media.nativewindow.CapabilitiesImmutable;
 import javax.media.nativewindow.NativeWindow;
 import javax.media.nativewindow.NativeWindowFactory;
 
+import com.jogamp.common.util.IOUtil;
+
 import jogamp.newt.Debug;
 import jogamp.newt.DisplayImpl;
 import jogamp.newt.ScreenImpl;
@@ -54,20 +57,46 @@ public class NewtFactory {
 
     public static final String DRIVER_DEFAULT_ROOT_PACKAGE = "jogamp.newt.driver";
 
+    private static IOUtil.ClassResources defaultWindowIcons;
+
     static {
         AccessController.doPrivileged(new PrivilegedAction<Object>() {
             @Override
             public Object run() {
                 NativeWindowFactory.initSingleton(); // last resort ..
-
-                // Work-around for initialization order problems on Mac OS X
-                // between native Newt and (apparently) Fmod
-                WindowImpl.init(NativeWindowFactory.getNativeWindowType(true));
-
+                {
+                    /** See API Doc in {@link Window} ! */
+                    final String[] paths = Debug.getProperty("newt.window.icons", true, "newt/data/jogamp-16x16.png newt/data/jogamp-32x32.png").split("\\s");
+                    if( paths.length < 2 ) {
+                        throw new IllegalArgumentException("Property 'newt.window.icons' did not specify at least two PNG icons, but "+Arrays.toString(paths));
+                    }
+                    final Class<?> clazz = NewtFactory.class;
+                    defaultWindowIcons = new IOUtil.ClassResources(clazz, paths);
+                }
                 return null;
             } } );
     }
 
+    /**
+     * Returns the application window icon resources to be used.
+     * <p>
+     * Property <code>newt.window.icons</code> may define a list of PNG icons separated by a whitespace character.
+     * Shall reference at least two PNG icons, from lower (16x16) to higher (>= 32x32) resolution.
+     * </p>
+     * <p>
+     * Users may also specify application window icons using {@link #setWindowIcons(com.jogamp.common.util.IOUtil.ClassResources)}.
+     * </p>
+     */
+    public static IOUtil.ClassResources getWindowIcons() { return defaultWindowIcons; }
+
+    /**
+     * Allow user to set custom window icons, only applicable at application start before creating any NEWT instance.
+     * <p>
+     * Shall reference at least two PNG icons, from lower (16x16) to higher (>= 32x32) resolution.
+     * </p>
+     */
+    public static void setWindowIcons(IOUtil.ClassResources cres) { defaultWindowIcons = cres; }
+
     public static Class<?> getCustomClass(String packageName, String classBaseName) {
         Class<?> clazz = null;
         if(packageName!=null && classBaseName!=null) {
@@ -215,7 +244,7 @@ public class NewtFactory {
      * </p>
      */
     public static Window createWindow(Screen screen, CapabilitiesImmutable caps) {
-        return createWindowImpl(screen, caps);
+        return WindowImpl.create(null, 0, screen, caps);
     }
 
     /**
@@ -242,6 +271,9 @@ public class NewtFactory {
      */
     public static Window createWindow(NativeWindow parentWindow, CapabilitiesImmutable caps) {
         final String type = NativeWindowFactory.getNativeWindowType(true);
+        if( null == parentWindow ) {
+            return createWindowImpl(type, caps);
+        }
         Screen screen  = null;
         Window newtParentWindow = null;
 
@@ -262,7 +294,7 @@ public class NewtFactory {
                 screen  = NewtFactory.createScreen(display, 0); // screen 0
             }
         }
-        final Window win = createWindowImpl(parentWindow, screen, caps);
+        final Window win = WindowImpl.create(parentWindow, 0, screen, caps);
 
         win.setSize(parentWindow.getWidth(), parentWindow.getHeight());
         if ( null != newtParentWindow ) {
@@ -272,19 +304,7 @@ public class NewtFactory {
         return win;
     }
 
-    protected static Window createWindowImpl(NativeWindow parentNativeWindow, Screen screen, CapabilitiesImmutable caps) {
-        return WindowImpl.create(parentNativeWindow, 0, screen, caps);
-    }
-
-    protected static Window createWindowImpl(long parentWindowHandle, Screen screen, CapabilitiesImmutable caps) {
-        return WindowImpl.create(null, parentWindowHandle, screen, caps);
-    }
-
-    protected static Window createWindowImpl(Screen screen, CapabilitiesImmutable caps) {
-        return WindowImpl.create(null, 0, screen, caps);
-    }
-
-    protected static Window createWindowImpl(String type, CapabilitiesImmutable caps) {
+    private static Window createWindowImpl(String type, CapabilitiesImmutable caps) {
         Display display = NewtFactory.createDisplay(type, null, true); // local display
         Screen screen  = NewtFactory.createScreen(display, 0); // screen 0
         return WindowImpl.create(null, 0, screen, caps);
@@ -293,11 +313,17 @@ public class NewtFactory {
     /**
      * Create a child Window entity attached to the given parent, incl native creation<br>
      *
-     * @param parentWindowObject the native parent window handle
-     * @param undecorated only impacts if the window is in top-level state, while attached to a parent window it's rendered undecorated always
+     * @param displayConnection the parent window's display connection
+     * @param screenIdx the desired screen index
+     * @param parentWindowHandle the native parent window handle
+     * @param caps the desired capabilities
+     * @return
      */
-    public static Window createWindow(long parentWindowHandle, Screen screen, CapabilitiesImmutable caps) {
-        return createWindowImpl(parentWindowHandle, screen, caps);
+    public static Window createWindow(String displayConnection, int screenIdx, long parentWindowHandle, CapabilitiesImmutable caps) {
+        final String type = NativeWindowFactory.getNativeWindowType(true);
+        Display display = NewtFactory.createDisplay(type, displayConnection, true);
+        Screen screen  = NewtFactory.createScreen(display, screenIdx);
+        return WindowImpl.create(null, parentWindowHandle, screen, caps);
     }
 
     /**
@@ -320,9 +346,9 @@ public class NewtFactory {
 
     public static boolean isScreenCompatible(NativeWindow parent, Screen childScreen) {
       // Get parent's NativeWindow details
-      AbstractGraphicsConfiguration parentConfig = (AbstractGraphicsConfiguration) parent.getGraphicsConfiguration();
-      AbstractGraphicsScreen parentScreen = (AbstractGraphicsScreen) parentConfig.getScreen();
-      AbstractGraphicsDevice parentDevice = (AbstractGraphicsDevice) parentScreen.getDevice();
+      AbstractGraphicsConfiguration parentConfig = parent.getGraphicsConfiguration();
+      AbstractGraphicsScreen parentScreen = parentConfig.getScreen();
+      AbstractGraphicsDevice parentDevice = parentScreen.getDevice();
 
       DisplayImpl childDisplay = (DisplayImpl) childScreen.getDisplay();
       String parentDisplayName = childDisplay.validateDisplayName(null, parentDevice.getHandle());
@@ -343,9 +369,9 @@ public class NewtFactory {
 
     public static Screen createCompatibleScreen(NativeWindow parent, Screen childScreen) {
       // Get parent's NativeWindow details
-      AbstractGraphicsConfiguration parentConfig = (AbstractGraphicsConfiguration) parent.getGraphicsConfiguration();
-      AbstractGraphicsScreen parentScreen = (AbstractGraphicsScreen) parentConfig.getScreen();
-      AbstractGraphicsDevice parentDevice = (AbstractGraphicsDevice) parentScreen.getDevice();
+      AbstractGraphicsConfiguration parentConfig = parent.getGraphicsConfiguration();
+      AbstractGraphicsScreen parentScreen = parentConfig.getScreen();
+      AbstractGraphicsDevice parentDevice = parentScreen.getDevice();
 
       if(null != childScreen) {
         // check if child Display/Screen is compatible already
diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java
index 5c3bb78..4816e62 100644
--- a/src/newt/classes/com/jogamp/newt/Window.java
+++ b/src/newt/classes/com/jogamp/newt/Window.java
@@ -30,6 +30,7 @@ package com.jogamp.newt;
 
 import java.util.List;
 
+import com.jogamp.newt.Display.PointerIcon;
 import com.jogamp.newt.event.GestureHandler;
 import com.jogamp.newt.event.WindowEvent;
 import com.jogamp.newt.event.WindowListener;
@@ -62,6 +63,21 @@ import javax.media.nativewindow.util.RectangleImmutable;
  * window operation to an instance of this interface while providing OpenGL
  * functionality.
  * </p>
+ * <a name="customwindowicons"><h5>Custom Window Icons</h5></a>
+ * <p>
+ * Custom window icons can be defined via system property <code>newt.window.icons</code>,
+ * which shall contain a space separated list of PNG icon locations from low- to high-resolution.
+ * The location must be resolvable via classpath, i.e. shall reference a location within the jar file.
+ * Example (our default):
+ * <pre>
+ *   -Dnewt.window.icons="newt/data/jogamp-16x16.png newt/data/jogamp-32x32.png"
+ *   -Djnlp.newt.window.icons="newt/data/jogamp-16x16.png newt/data/jogamp-32x32.png"
+ * </pre>
+ * The property can also be set programmatically, which must happen before any NEWT classes are <i>touched</i>:
+ * <pre>
+ *   System.setProperty("newt.window.icons", "newt/data/jogamp-16x16.png newt/data/jogamp-32x32.png");
+ * </pre>
+ * </p>
  */
 public interface Window extends NativeWindow, WindowClosingProtocol {
     public static final boolean DEBUG_MOUSE_EVENT = Debug.debug("Window.MouseEvent");
@@ -307,6 +323,20 @@ public interface Window extends NativeWindow, WindowClosingProtocol {
      */
     void setPointerVisible(boolean pointerVisible);
 
+    /**
+     * Returns the current {@link PointerIcon}, which maybe <code>null</code> for the default.
+     * @see #setPointerIcon(PointerIcon)
+     */
+    PointerIcon getPointerIcon();
+
+    /**
+     * @param pi Valid {@link PointerIcon} reference or <code>null</code> to reset the pointer icon to default.
+     *
+     * @see PointerIcon
+     * @see Display#createPointerIcon(com.jogamp.common.util.IOUtil.ClassResources, int, int)
+     */
+    void setPointerIcon(final PointerIcon pi);
+
     /** @see #confinePointer(boolean) */
     boolean isPointerConfined();
 
diff --git a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
index 00c3f1e..1ed6284 100644
--- a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
+++ b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
@@ -621,9 +621,9 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
                     printActive = false;
                     return; // not yet available ..
                 }
-                if( !isVisible() ) {
+                if( !isShowing() ) {
                     if(DEBUG) {
-                        System.err.println(currentThreadName()+": Info: NewtCanvasAWT setupPrint - skipped GL render, drawable visible");
+                        System.err.println(currentThreadName()+": Info: NewtCanvasAWT setupPrint - skipped GL render, drawable valid, canvas not showing");
                     }
                     printActive = false;
                     return; // not yet available ..
diff --git a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtApplet1Run.java b/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtApplet1Run.java
index 74d4d83..9cecca9 100644
--- a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtApplet1Run.java
+++ b/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtApplet1Run.java
@@ -48,6 +48,7 @@ import jogamp.nativewindow.jawt.JAWTUtil;
 import com.jogamp.common.util.awt.AWTEDTExecutor;
 import com.jogamp.newt.awt.NewtCanvasAWT;
 import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.newt.util.applet.JOGLNewtAppletBase;
 
 /**
  * Simple GLEventListener deployment as an applet using JOGL. This demo must be
diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
index 208602a..ca8ab67 100644
--- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
+++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
@@ -77,6 +77,7 @@ import com.jogamp.newt.MonitorDevice;
 import com.jogamp.newt.NewtFactory;
 import com.jogamp.newt.Screen;
 import com.jogamp.newt.Window;
+import com.jogamp.newt.Display.PointerIcon;
 import com.jogamp.newt.event.GestureHandler;
 import com.jogamp.newt.event.KeyListener;
 import com.jogamp.newt.event.MouseListener;
@@ -268,6 +269,16 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
     }
 
     @Override
+    public final PointerIcon getPointerIcon() {
+        return window.getPointerIcon();
+    }
+
+    @Override
+    public final void setPointerIcon(final PointerIcon pi) {
+        window.setPointerIcon(pi);
+    }
+
+    @Override
     public final boolean isPointerConfined() {
         return window.isPointerConfined();
     }
diff --git a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtApplet1Run.java b/src/newt/classes/com/jogamp/newt/util/applet/JOGLNewtApplet3Run.java
similarity index 65%
copy from src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtApplet1Run.java
copy to src/newt/classes/com/jogamp/newt/util/applet/JOGLNewtApplet3Run.java
index 74d4d83..8123126 100644
--- a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtApplet1Run.java
+++ b/src/newt/classes/com/jogamp/newt/util/applet/JOGLNewtApplet3Run.java
@@ -25,28 +25,28 @@
  * authors and should not be interpreted as representing official policies, either expressed
  * or implied, of JogAmp Community.
  */
-package com.jogamp.newt.awt.applet;
-
-import java.applet.Applet;
-import java.awt.BorderLayout;
-import java.awt.Button;
-import java.awt.Component;
-import java.awt.Container;
-import java.awt.EventQueue;
-import java.awt.event.KeyListener;
-import java.awt.event.MouseListener;
-import java.awt.event.MouseMotionListener;
+package com.jogamp.newt.util.applet;
 
+import java.util.Locale;
+
+import com.jogamp.plugin.applet.Applet3;
+import com.jogamp.plugin.applet.Applet3Context;
+import com.jogamp.plugin.ui.NativeWindowDownstream;
+import com.jogamp.plugin.ui.NativeWindowUpstream;
+
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.NativeWindow;
+import javax.media.nativewindow.NativeWindowFactory;
 import javax.media.nativewindow.WindowClosingProtocol.WindowClosingMode;
+import javax.media.nativewindow.util.PointImmutable;
 import javax.media.opengl.FPSCounter;
 import javax.media.opengl.GLCapabilities;
-import javax.media.opengl.GLEventListener;
 import javax.media.opengl.GLProfile;
 
-import jogamp.nativewindow.jawt.JAWTUtil;
-
-import com.jogamp.common.util.awt.AWTEDTExecutor;
-import com.jogamp.newt.awt.NewtCanvasAWT;
+import com.jogamp.nativewindow.UpstreamSurfaceHookMutableSizePos;
+import com.jogamp.newt.NewtFactory;
+import com.jogamp.newt.Window;
 import com.jogamp.newt.opengl.GLWindow;
 
 /**
@@ -94,48 +94,35 @@ import com.jogamp.newt.opengl.GLWindow;
  *  </pre>
  *  </p>
  */
- at SuppressWarnings("serial")
-public class JOGLNewtApplet1Run extends Applet {
+public class JOGLNewtApplet3Run implements Applet3 {
     public static final boolean DEBUG = JOGLNewtAppletBase.DEBUG;
 
     GLWindow glWindow = null;
-    NewtCanvasAWT newtCanvasAWT = null;
     JOGLNewtAppletBase base = null;
     /** if valid glStandalone:=true (own window) ! */
     int glXd=Integer.MAX_VALUE, glYd=Integer.MAX_VALUE, glWidth=Integer.MAX_VALUE, glHeight=Integer.MAX_VALUE;
+    Applet3Context ctx;
+    boolean glStandalone = false;
+    UpstreamSurfaceHookMutableSizePos upstreamSizePosHook;
+    PointImmutable upstreamLocOnScreen;
+    NativeWindow browserWin;
+
+    final String getParameter(String name) {
+        return ctx.getParameter(name);
+    }
 
     @Override
-    public void init() {
-        if(DEBUG) {
-            System.err.println("JOGLNewtApplet1Run.init() START - "+currentThreadName());
-        }
-        if(!(this instanceof Container)) {
-            throw new RuntimeException("This Applet is not a AWT Container");
-        }
-        final Container container = this;
+    public NativeWindowDownstream createNativeWindow(final Applet3Context ctx, final NativeWindowUpstream upstreamWin) {
+        this.ctx = ctx;
 
-        String glEventListenerClazzName=null;
         String glProfileName=null;
-        int glSwapInterval=0;
-        boolean glDebug=false;
-        boolean glTrace=false;
-        boolean glUndecorated=false;
-        boolean glAlwaysOnTop=false;
-        boolean glCloseable=false;
         boolean glOpaque=true;
         int glAlphaBits=0;
         int glNumMultisampleBuffer=0;
-        boolean glNoDefaultKeyListener = false;
-        boolean appletDebugTestBorder = false;
+        boolean glUndecorated=false;
+        boolean glAlwaysOnTop=false;
         try {
-            glEventListenerClazzName = getParameter("gl_event_listener_class");
             glProfileName = getParameter("gl_profile");
-            glSwapInterval = JOGLNewtAppletBase.str2Int(getParameter("gl_swap_interval"), glSwapInterval);
-            glDebug = JOGLNewtAppletBase.str2Bool(getParameter("gl_debug"), glDebug);
-            glTrace = JOGLNewtAppletBase.str2Bool(getParameter("gl_trace"), glTrace);
-            glUndecorated = JOGLNewtAppletBase.str2Bool(getParameter("gl_undecorated"), glUndecorated);
-            glAlwaysOnTop = JOGLNewtAppletBase.str2Bool(getParameter("gl_alwaysontop"), glAlwaysOnTop);
-            glCloseable = JOGLNewtAppletBase.str2Bool(getParameter("gl_closeable"), glCloseable);
             glOpaque = JOGLNewtAppletBase.str2Bool(getParameter("gl_opaque"), glOpaque);
             glAlphaBits = JOGLNewtAppletBase.str2Int(getParameter("gl_alpha"), glAlphaBits);
             glNumMultisampleBuffer = JOGLNewtAppletBase.str2Int(getParameter("gl_multisamplebuffer"), glNumMultisampleBuffer);
@@ -143,33 +130,144 @@ public class JOGLNewtApplet1Run extends Applet {
             glYd = JOGLNewtAppletBase.str2Int(getParameter("gl_dy"), glYd);
             glWidth = JOGLNewtAppletBase.str2Int(getParameter("gl_width"), glWidth);
             glHeight = JOGLNewtAppletBase.str2Int(getParameter("gl_height"), glHeight);
-            glNoDefaultKeyListener = JOGLNewtAppletBase.str2Bool(getParameter("gl_nodefaultkeyListener"), glNoDefaultKeyListener);
-            appletDebugTestBorder = JOGLNewtAppletBase.str2Bool(getParameter("appletDebugTestBorder"), appletDebugTestBorder);
+            glUndecorated = JOGLNewtAppletBase.str2Bool(getParameter("gl_undecorated"), glUndecorated);
+            glAlwaysOnTop = JOGLNewtAppletBase.str2Bool(getParameter("gl_alwaysontop"), glAlwaysOnTop);
         } catch (Exception e) {
             e.printStackTrace();
         }
-        if(null==glEventListenerClazzName) {
-            throw new RuntimeException("No applet parameter 'gl_event_listener_class'");
+        glStandalone = Integer.MAX_VALUE>glXd && Integer.MAX_VALUE>glYd && Integer.MAX_VALUE>glWidth && Integer.MAX_VALUE>glHeight;
+        final GLCapabilities caps = new GLCapabilities(GLProfile.get(glProfileName));
+        caps.setAlphaBits(glAlphaBits);
+        if(0<glNumMultisampleBuffer) {
+            caps.setSampleBuffers(true);
+            caps.setNumSamples(glNumMultisampleBuffer);
         }
-        final boolean glStandalone = Integer.MAX_VALUE>glXd && Integer.MAX_VALUE>glYd && Integer.MAX_VALUE>glWidth && Integer.MAX_VALUE>glHeight;
+        caps.setBackgroundOpaque(glOpaque);
+
+        final AbstractGraphicsDevice aDevice = NativeWindowFactory.createDevice(upstreamWin.getDisplayConnection(),
+                                                                                true /* own */); // open and own! (for upstreamLocOnScreen)
+        final AbstractGraphicsScreen aScreen = NativeWindowFactory.createScreen(aDevice, upstreamWin.getScreenIndex());
+        upstreamSizePosHook = new UpstreamSurfaceHookMutableSizePos(upstreamWin.getX(), upstreamWin.getY(),
+                                                                    upstreamWin.getWidth(), upstreamWin.getHeight());
+        browserWin = NativeWindowFactory.createWrappedWindow(aScreen, 0 /* surfaceHandle */, upstreamWin.getWindowHandle(),
+                                                            upstreamSizePosHook);
+        upstreamLocOnScreen = NativeWindowFactory.getLocationOnScreen(browserWin);
         if(DEBUG) {
-            System.err.println("JOGLNewtApplet1Run Configuration:");
+            System.err.println("JOGLNewtApplet3Run Configuration:");
             System.err.println("glStandalone: "+glStandalone);
+            System.err.println("glProfileName: "+glProfileName);
+            System.err.println("glOpaque: "+glOpaque);
+            System.err.println("glAlphaBits: "+glAlphaBits);
+            System.err.println("glNumMultisampleBuffer: "+glNumMultisampleBuffer);
+            System.err.println("glUndecorated: "+glUndecorated);
+            System.err.println("glAlwaysOnTop: "+glAlwaysOnTop);
+            System.err.println("UpstreamWin: "+upstreamWin+", LOS "+upstreamLocOnScreen);
             if(glStandalone) {
                 System.err.println("pos-size: "+glXd+"/"+glYd+" "+glWidth+"x"+glHeight);
             }
+        }
+
+        final Window w = NewtFactory.createWindow(glStandalone ? null : browserWin, caps);
+        glWindow = GLWindow.create(w);
+        glWindow.setUndecorated(glUndecorated);
+        glWindow.setAlwaysOnTop(glAlwaysOnTop);
+        glWindow.setSize(browserWin.getWidth(), browserWin.getHeight());
+
+        return new NativeWindowDownstream() {
+            @Override
+            public void setVisible(boolean v) {
+                if( null != glWindow ) {
+                    glWindow.setVisible(v);
+                }
+            }
+
+            @Override
+            public void setSize(int width, int height) {
+                upstreamSizePosHook.setSize(width, height);
+                if( null != glWindow ) {
+                    glWindow.setSize(width, height);
+                }
+            }
+
+            @Override
+            public void requestFocus() {
+                if( null != glWindow ) {
+                    glWindow.requestFocus();
+                }
+            }
+
+            @Override
+            public void destroy() {
+                if( null != glWindow ) {
+                    glWindow.destroy();
+                }
+            }
+
+            @Override
+            public NativeWindowUpstream getParent() {
+                return upstreamWin;
+            }
+
+            @Override
+            public long getWindowHandle() {
+                if( null != glWindow ) {
+                    return glWindow.getWindowHandle();
+                } else {
+                    return 0;
+                }
+            }
+
+            @Override
+            public void display() {
+                if( null != glWindow ) {
+                    glWindow.display();
+                }
+            }
+
+            @Override
+            public void notifyPositionChanged(NativeWindowUpstream nw) {
+                upstreamSizePosHook.setPos(nw.getX(), nw.getY());
+                if( null != glWindow ) {
+                    glWindow.setPosition(nw.getX(), nw.getY());
+                }
+            }
+        };
+    }
+
+    @Override
+    public void init(Applet3Context ctx) {
+        if(DEBUG) {
+            System.err.println("JOGLNewtApplet1Run.init() START - "+currentThreadName());
+        }
+        this.ctx = ctx;
+        String glEventListenerClazzName=null;
+        int glSwapInterval=0;
+        boolean glDebug=false;
+        boolean glTrace=false;
+        boolean glNoDefaultKeyListener = false;
+        boolean glCloseable=false;
+
+        try {
+            glEventListenerClazzName = getParameter("gl_event_listener_class");
+            glSwapInterval = JOGLNewtAppletBase.str2Int(getParameter("gl_swap_interval"), glSwapInterval);
+            glDebug = JOGLNewtAppletBase.str2Bool(getParameter("gl_debug"), glDebug);
+            glTrace = JOGLNewtAppletBase.str2Bool(getParameter("gl_trace"), glTrace);
+            glNoDefaultKeyListener = JOGLNewtAppletBase.str2Bool(getParameter("gl_nodefaultkeyListener"), glNoDefaultKeyListener);
+            glCloseable = JOGLNewtAppletBase.str2Bool(getParameter("gl_closeable"), glCloseable);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        if(null==glEventListenerClazzName) {
+            throw new RuntimeException("No applet parameter 'gl_event_listener_class'");
+        }
+        if(DEBUG) {
+            System.err.println("JOGLNewtApplet1Run Configuration:");
             System.err.println("glEventListenerClazzName: "+glEventListenerClazzName);
-            System.err.println("glProfileName: "+glProfileName);
             System.err.println("glSwapInterval: "+glSwapInterval);
             System.err.println("glDebug: "+glDebug);
             System.err.println("glTrace: "+glTrace);
-            System.err.println("glUndecorated: "+glUndecorated);
-            System.err.println("glAlwaysOnTop: "+glAlwaysOnTop);
-            System.err.println("glCloseable: "+glCloseable);
-            System.err.println("glOpaque: "+glOpaque);
-            System.err.println("glAlphaBits: "+glAlphaBits);
-            System.err.println("glNumMultisampleBuffer: "+glNumMultisampleBuffer);
             System.err.println("glNoDefaultKeyListener: "+glNoDefaultKeyListener);
+            System.err.println("glCloseable: "+glCloseable);
         }
 
         base = new JOGLNewtAppletBase(glEventListenerClazzName,
@@ -180,51 +278,9 @@ public class JOGLNewtApplet1Run extends Applet {
                                       glTrace);
 
         try {
-            GLCapabilities caps = new GLCapabilities(GLProfile.get(glProfileName));
-            caps.setAlphaBits(glAlphaBits);
-            if(0<glNumMultisampleBuffer) {
-                caps.setSampleBuffers(true);
-                caps.setNumSamples(glNumMultisampleBuffer);
-            }
-            caps.setBackgroundOpaque(glOpaque);
-            glWindow = GLWindow.create(caps);
             glWindow.setUpdateFPSFrames(FPSCounter.DEFAULT_FRAMES_PER_INTERVAL, System.err);
-            glWindow.setUndecorated(glUndecorated);
-            glWindow.setAlwaysOnTop(glAlwaysOnTop);
             glWindow.setDefaultCloseOperation(glCloseable ? WindowClosingMode.DISPOSE_ON_CLOSE : WindowClosingMode.DO_NOTHING_ON_CLOSE);
-            container.setLayout(new BorderLayout());
-            if(appletDebugTestBorder) {
-                AWTEDTExecutor.singleton.invoke(true, new Runnable() {
-                    public void run() {
-                        container.add(new Button("North"), BorderLayout.NORTH);
-                        container.add(new Button("South"), BorderLayout.SOUTH);
-                        container.add(new Button("East"), BorderLayout.EAST);
-                        container.add(new Button("West"), BorderLayout.WEST);
-                    } } );
-            }
             base.init(glWindow);
-            if(base.isValid()) {
-                GLEventListener glEventListener = base.getGLEventListener();
-
-                if(glEventListener instanceof MouseListener) {
-                    addMouseListener((MouseListener)glEventListener);
-                }
-                if(glEventListener instanceof MouseMotionListener) {
-                    addMouseMotionListener((MouseMotionListener)glEventListener);
-                }
-                if(glEventListener instanceof KeyListener) {
-                    addKeyListener((KeyListener)glEventListener);
-                }
-            }
-            if( !glStandalone ) {
-                AWTEDTExecutor.singleton.invoke(true, new Runnable() {
-                    public void run() {
-                        newtCanvasAWT = new NewtCanvasAWT(glWindow);
-                        newtCanvasAWT.setSkipJAWTDestroy(true); // Bug 910
-                        container.add(newtCanvasAWT, BorderLayout.CENTER);
-                        container.validate();
-                    } } );
-            }
         } catch (Throwable t) {
             throw new RuntimeException(t);
         }
@@ -233,56 +289,25 @@ public class JOGLNewtApplet1Run extends Applet {
         }
     }
 
-    private static String currentThreadName() { return "["+Thread.currentThread().getName()+", isAWT-EDT "+EventQueue.isDispatchThread()+"]"; }
+    private static String currentThreadName() { return "["+Thread.currentThread().getName()+"]"; }
 
     @Override
     public void start() {
         if(DEBUG) {
-            System.err.println("JOGLNewtApplet1Run.start() START (isVisible "+isVisible()+", isDisplayable "+isDisplayable()+") - "+currentThreadName());
+            System.err.println("JOGLNewtApplet1Run.start() START (isVisible "+glWindow.isVisible()+") - "+currentThreadName());
         }
-        final java.awt.Point[] p0 = { null };
-        AWTEDTExecutor.singleton.invoke(true, new Runnable() {
-            public void run() {
-                setVisible(true);
-                p0[0] = getLocationOnScreen();
-                if( null != newtCanvasAWT ) {
-                    newtCanvasAWT.setFocusable(true);
-                    newtCanvasAWT.requestFocus();
-                }
-            }
-        });
-        if( null == newtCanvasAWT ) {
-            glWindow.requestFocus();
+        if( glStandalone ) {
             glWindow.setSize(glWidth, glHeight);
-            glWindow.setPosition(p0[0].x+glXd, p0[0].y+glYd);
+            glWindow.setPosition(upstreamLocOnScreen.getX()+glXd, upstreamLocOnScreen.getY()+glYd);
+            glWindow.setVisible(true);
+            glWindow.requestFocus();
         }
         if(DEBUG) {
-            Component topC = this;
-            while (null != topC.getParent()) {
-                topC = topC.getParent();
-            }
             System.err.println("JOGLNewtApplet1Run start:");
-            System.err.println("TopComponent: "+topC.getLocation()+" rel, "+topC.getLocationOnScreen()+" screen, visible "+topC.isVisible()+", "+topC);
-            System.err.println("Applet Pos: "+this.getLocation()+" rel, "+p0+" screen, visible "+this.isVisible()+", "+this);
-            if(null != newtCanvasAWT) {
-                System.err.println("NewtCanvasAWT Pos: "+newtCanvasAWT.getLocation()+" rel, "+newtCanvasAWT.getLocationOnScreen()+" screen, visible "+newtCanvasAWT.isVisible()+", "+newtCanvasAWT);
-            }
             System.err.println("GLWindow Pos: "+glWindow.getX()+"/"+glWindow.getY()+" rel, "+glWindow.getLocationOnScreen(null)+" screen");
             System.err.println("GLWindow: "+glWindow);
         }
         base.start();
-        if( null != newtCanvasAWT &&
-            newtCanvasAWT.isOffscreenLayerSurfaceEnabled() &&
-            0 != ( JAWTUtil.JAWT_OSX_CALAYER_QUIRK_POSITION & JAWTUtil.getOSXCALayerQuirks() ) ) {
-            // force relayout
-            AWTEDTExecutor.singleton.invoke(true, new Runnable() {
-                public void run() {
-                    final int cW = newtCanvasAWT.getWidth();
-                    final int cH = newtCanvasAWT.getHeight();
-                    newtCanvasAWT.setSize(cW+1, cH+1);
-                    newtCanvasAWT.setSize(cW, cH);
-                } } );
-        }
         if(DEBUG) {
             System.err.println("JOGLNewtApplet1Run.start() END - "+currentThreadName());
         }
@@ -304,22 +329,31 @@ public class JOGLNewtApplet1Run extends Applet {
         if(DEBUG) {
             System.err.println("JOGLNewtApplet1Run.destroy() START - "+currentThreadName());
         }
-        AWTEDTExecutor.singleton.invoke(true, new Runnable() {
-            public void run() {
-                glWindow.setVisible(false); // hide 1st
-                if( null != newtCanvasAWT ) {
-                    newtCanvasAWT.setSkipJAWTDestroy(false); // Bug 910
-                    remove(newtCanvasAWT); // remove newtCanvasAWT incl. glWindow.reparentWindow(null) if not done yet!
-                    newtCanvasAWT.destroy();
-                }
-            } } );
+        glWindow.setVisible(false); // hide 1st
         base.destroy(); // destroy glWindow unrecoverable
         base=null;
         glWindow=null;
-        newtCanvasAWT=null;
+        browserWin.destroy(); // make sure the open display connection gets closed!
+        browserWin = null;
         if(DEBUG) {
             System.err.println("JOGLNewtApplet1Run.destroy() END - "+currentThreadName());
         }
     }
+
+    @Override
+    public String getAppletInfo() {
+        return null;
+    }
+
+    @Override
+    public Locale getLocale() {
+        return null;
+    }
+
+    @Override
+    public String[][] getParameterInfo() {
+        return null;
+    }
+
 }
 
diff --git a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java b/src/newt/classes/com/jogamp/newt/util/applet/JOGLNewtAppletBase.java
similarity index 72%
rename from src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java
rename to src/newt/classes/com/jogamp/newt/util/applet/JOGLNewtAppletBase.java
index e6571d2..bbe6b85 100644
--- a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java
+++ b/src/newt/classes/com/jogamp/newt/util/applet/JOGLNewtAppletBase.java
@@ -25,7 +25,7 @@
  * authors and should not be interpreted as representing official policies, either expressed
  * or implied, of JogAmp Community.
  */
-package com.jogamp.newt.awt.applet;
+package com.jogamp.newt.util.applet;
 
 import java.lang.reflect.Field;
 import java.security.AccessController;
@@ -42,7 +42,10 @@ import javax.media.opengl.GLPipelineFactory;
 
 import jogamp.newt.Debug;
 
+import com.jogamp.common.util.IOUtil;
+import com.jogamp.newt.Display;
 import com.jogamp.newt.Window;
+import com.jogamp.newt.Display.PointerIcon;
 import com.jogamp.newt.event.KeyEvent;
 import com.jogamp.newt.event.KeyListener;
 import com.jogamp.newt.event.MouseListener;
@@ -65,12 +68,13 @@ public class JOGLNewtAppletBase implements KeyListener, GLEventListener {
     boolean glClosable;
     boolean glDebug;
     boolean glTrace;
+    PointerIcon pointerIconTest = null;
 
     GLEventListener glEventListener = null;
     GLWindow glWindow = null;
     Animator glAnimator=null;
     boolean isValid = false;
-    NativeWindow awtParent;
+    NativeWindow parentWin;
 
     public JOGLNewtAppletBase(String glEventListenerClazzName,
                               int glSwapInterval,
@@ -212,14 +216,14 @@ public class JOGLNewtAppletBase implements KeyListener, GLEventListener {
         @Override
         public void windowDestroyNotify(WindowEvent e) {
             if( isValid() && WindowClosingMode.DO_NOTHING_ON_CLOSE == glWindow.getDefaultCloseOperation() &&
-                null == glWindow.getParent() && null != awtParent && 0 != awtParent.getWindowHandle() )
+                null == glWindow.getParent() && null != parentWin && 0 != parentWin.getWindowHandle() )
             {
                 // we may be called directly by the native EDT
                 new Thread(new Runnable() {
                    @Override
                    public void run() {
-                    if( glWindow.isNativeValid() && null != awtParent && 0 != awtParent.getWindowHandle() ) {
-                        glWindow.reparentWindow(awtParent, -1, -1, Window.REPARENT_HINT_BECOMES_VISIBLE);
+                    if( glWindow.isNativeValid() && null != parentWin && 0 != parentWin.getWindowHandle() ) {
+                        glWindow.reparentWindow(parentWin, -1, -1, Window.REPARENT_HINT_BECOMES_VISIBLE);
                     }
                    }
                 }).start();
@@ -230,8 +234,17 @@ public class JOGLNewtAppletBase implements KeyListener, GLEventListener {
         if(isValid) {
             glWindow.setVisible(true);
             glWindow.sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED);
+            if( null == pointerIconTest ) {
+                final IOUtil.ClassResources res = new IOUtil.ClassResources(glWindow.getClass(), new String[] { "newt/data/cross-grey-alpha-16x16.png" } );
+                final Display disp = glWindow.getScreen().getDisplay();
+                try {
+                    pointerIconTest = disp.createPointerIcon(res, 8, 8);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
             glAnimator.start();
-            awtParent = glWindow.getParent();
+            parentWin = glWindow.getParent();
             glWindow.addWindowListener(reparentHomeListener);
         }
     }
@@ -302,28 +315,71 @@ public class JOGLNewtAppletBase implements KeyListener, GLEventListener {
            return;
        }
        if(e.getKeyChar()=='d') {
-            glWindow.setUndecorated(!glWindow.isUndecorated());
+           new Thread() {
+               public void run() {
+                   glWindow.setUndecorated(!glWindow.isUndecorated());
+               } }.start();
        } if(e.getKeyChar()=='f') {
-            glWindow.setFullscreen(!glWindow.isFullscreen());
+           new Thread() {
+               public void run() {
+                   glWindow.setFullscreen(!glWindow.isFullscreen());
+               } }.start();
        } else if(e.getKeyChar()=='a') {
-            glWindow.setAlwaysOnTop(!glWindow.isAlwaysOnTop());
-       } else if(e.getKeyChar()=='r' && null!=awtParent) {
-            if(null == glWindow.getParent()) {
-                glWindow.reparentWindow(awtParent, -1, -1, 0 /* hints */);
-            } else {
-                final InsetsImmutable insets = glWindow.getInsets();
-                final int x, y;
-                if ( 0 >= insets.getTopHeight() ) {
-                    // fail safe ..
-                    x = 32;
-                    y = 32;
-                } else {
-                    x = insets.getLeftWidth();
-                    y = insets.getTopHeight();
-                }
-                glWindow.reparentWindow(null, x, y, 0 /* hints */);
-                glWindow.setDefaultCloseOperation( glClosable ? WindowClosingMode.DISPOSE_ON_CLOSE : WindowClosingMode.DO_NOTHING_ON_CLOSE );
-            }
+           new Thread() {
+               public void run() {
+                   glWindow.setAlwaysOnTop(!glWindow.isAlwaysOnTop());
+               } }.start();
+       } else if(e.getKeyChar()=='r' && null!=parentWin) {
+           new Thread() {
+               public void run() {
+                   if(null == glWindow.getParent()) {
+                       glWindow.reparentWindow(parentWin, -1, -1, 0 /* hints */);
+                   } else {
+                       final InsetsImmutable insets = glWindow.getInsets();
+                       final int x, y;
+                       if ( 0 >= insets.getTopHeight() ) {
+                           // fail safe ..
+                           x = 32;
+                           y = 32;
+                       } else {
+                           x = insets.getLeftWidth();
+                           y = insets.getTopHeight();
+                       }
+                       glWindow.reparentWindow(null, x, y, 0 /* hints */);
+                       glWindow.setDefaultCloseOperation( glClosable ? WindowClosingMode.DISPOSE_ON_CLOSE : WindowClosingMode.DO_NOTHING_ON_CLOSE );
+                   }
+               } }.start();
+       } else if(e.getKeyChar()=='c') {
+           new Thread() {
+               public void run() {
+                   System.err.println("[set pointer-icon pre]");
+                   final PointerIcon currentPI = glWindow.getPointerIcon();
+                   glWindow.setPointerIcon( currentPI == pointerIconTest ? null : pointerIconTest);
+                   System.err.println("[set pointer-icon post] "+currentPI+" -> "+glWindow.getPointerIcon());
+               } }.start();
+       } else if(e.getKeyChar()=='i') {
+           new Thread() {
+               public void run() {
+                   System.err.println("[set mouse visible pre]: "+glWindow.isPointerVisible());
+                   glWindow.setPointerVisible(!glWindow.isPointerVisible());
+                   System.err.println("[set mouse visible post]: "+glWindow.isPointerVisible());
+               } }.start();
+       } else if(e.getKeyChar()=='j') {
+           new Thread() {
+               public void run() {
+                    final Thread t = glWindow.setExclusiveContextThread(null);
+                    System.err.println("[set mouse confined pre]: "+glWindow.isPointerConfined());
+                    glWindow.confinePointer(!glWindow.isPointerConfined());
+                    System.err.println("[set mouse confined post]: "+glWindow.isPointerConfined());
+                    glWindow.setExclusiveContextThread(t);
+               } }.start();
+       } else if(e.getKeyChar()=='w') {
+           new Thread() {
+               public void run() {
+                   System.err.println("[set mouse pos pre]");
+                   glWindow.warpPointer(glWindow.getWidth()/2, glWindow.getHeight()/2);
+                   System.err.println("[set mouse pos post]");
+               } }.start();
        }
     }
 
diff --git a/src/newt/classes/com/jogamp/newt/util/applet/VersionApplet3.java b/src/newt/classes/com/jogamp/newt/util/applet/VersionApplet3.java
new file mode 100644
index 0000000..db0e8fc
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/util/applet/VersionApplet3.java
@@ -0,0 +1,226 @@
+package com.jogamp.newt.util.applet;
+
+import com.jogamp.plugin.applet.Applet3;
+import com.jogamp.plugin.applet.Applet3Context;
+import com.jogamp.plugin.ui.NativeWindowDownstream;
+import com.jogamp.plugin.ui.NativeWindowUpstream;
+
+import java.util.List;
+import java.util.Locale;
+
+import javax.media.opengl.GLProfile;
+import javax.media.opengl.GL;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLEventListener;
+
+import com.jogamp.common.GlueGenVersion;
+import com.jogamp.common.util.VersionUtil;
+import com.jogamp.newt.NewtFactory;
+import com.jogamp.newt.Window;
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.JoglVersion;
+
+public class VersionApplet3 implements Applet3 {
+
+    public static void main(String[] args) {
+        VersionApplet3 va = new VersionApplet3();
+
+        final NativeWindowDownstream nwc = va.createNativeWindow(null, new NativeWindowUpstream() {
+            @Override
+            public long getWindowHandle() {
+                return 0;
+            }
+            @Override
+            public int getWidth() {
+                return 64;
+            }
+            @Override
+            public int getHeight() {
+                return 64;
+            }
+            @Override
+            public String getDisplayConnection() {
+                return null; // default
+            }
+            @Override
+            public int getScreenIndex() {
+                return 0; // default
+            }
+            @Override
+            public void notifySurfaceUpdated(NativeWindowDownstream swappedWin) {
+                // NOP
+            }
+            @Override
+            public int getX() {
+                return 0;
+            }
+            @Override
+            public int getY() {
+                return 0;
+            }
+        });
+        va.init(null);
+        va.start();
+        va.stop();
+        va.destroy();
+        nwc.destroy();
+    }
+
+    GLWindow canvas;
+
+    @Override
+    public NativeWindowDownstream createNativeWindow(final Applet3Context ctx, final NativeWindowUpstream parentWin) {
+        final GLCapabilities caps = new GLCapabilities(GLProfile.getDefault());
+        final Window w = NewtFactory.createWindow(parentWin.getDisplayConnection(), parentWin.getScreenIndex(), parentWin.getWindowHandle(), caps);
+        canvas = GLWindow.create(w);
+        canvas.setSize(parentWin.getWidth(), parentWin.getHeight());
+
+        return new NativeWindowDownstream() {
+            @Override
+            public void setVisible(boolean v) {
+                if( null != canvas ) {
+                    canvas.setVisible(v);
+                }
+            }
+
+            @Override
+            public void setSize(int width, int height) {
+                if( null != canvas ) {
+                    canvas.setSize(width, height);
+                }
+            }
+
+            @Override
+            public void requestFocus() {
+                if( null != canvas ) {
+                    canvas.requestFocus();
+                }
+            }
+
+            @Override
+            public void destroy() {
+                if( null != canvas ) {
+                    canvas.destroy();
+                }
+            }
+
+            @Override
+            public NativeWindowUpstream getParent() {
+                return parentWin;
+            }
+
+            @Override
+            public long getWindowHandle() {
+                if( null != canvas ) {
+                    return canvas.getWindowHandle();
+                } else {
+                    return 0;
+                }
+            }
+
+            @Override
+            public void display() {
+                if( null != canvas ) {
+                    canvas.display();
+                }
+            }
+
+            @Override
+            public void notifyPositionChanged(NativeWindowUpstream nw) {
+                if( null != canvas ) {
+                    canvas.setPosition(nw.getX(), nw.getY());
+                }
+            }
+        };
+    }
+
+    @Override
+    public void init(Applet3Context ctx) {
+        System.err.println("VersionApplet: init() - begin");
+        canvas.addGLEventListener(new GLInfo());
+        System.err.println("VersionApplet: init() - end");
+    }
+
+    @Override
+    public void start() {
+        System.err.println("VersionApplet: start() - begin");
+
+        String s;
+
+        s = VersionUtil.getPlatformInfo().toString();
+        System.err.println(s);
+
+        s = GlueGenVersion.getInstance().toString();
+        System.err.println(s);
+
+        /*
+            s = NativeWindowVersion.getInstance().toString();
+            System.err.println(s);
+        */
+
+        s = JoglVersion.getInstance().toString();
+        System.err.println(s);
+
+        GLDrawableFactory factory = GLDrawableFactory.getFactory(canvas.getGLProfile());
+        List<GLCapabilitiesImmutable> availCaps = factory.getAvailableCapabilities(null);
+        for(int i=0; i<availCaps.size(); i++) {
+            s = availCaps.get(i).toString();
+            System.err.println(s);
+        }
+        canvas.display();
+        System.err.println("VersionApplet: start() - end");
+    }
+
+    @Override
+    public void stop() {
+        System.err.println("VersionApplet: stop() - begin");
+        canvas.setVisible(false);
+        System.err.println("VersionApplet: stop() - end");
+    }
+
+    @Override
+    public void destroy() {
+        System.err.println("VersionApplet: destroy() - start");
+        if(null!=canvas) {
+            canvas.destroy();
+            canvas = null;
+        }
+        System.err.println("VersionApplet: destroy() - end");
+    }
+
+    @Override
+    public String getAppletInfo() {
+        return null;
+    }
+
+    @Override
+    public Locale getLocale() {
+        return null;
+    }
+
+    @Override
+    public String[][] getParameterInfo() {
+        return null;
+    }
+
+    class GLInfo implements GLEventListener {
+        @Override
+        public void init(GLAutoDrawable drawable) {
+            GL gl = drawable.getGL();
+            String s = JoglVersion.getGLInfo(gl, null).toString();
+            System.err.println(s);
+        }
+        @Override
+        public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
+        }
+        @Override
+        public void display(GLAutoDrawable drawable) {
+        }
+        @Override
+        public void dispose(GLAutoDrawable drawable) {
+        }
+    }
+}
diff --git a/src/newt/classes/jogamp/newt/DefaultEDTUtil.java b/src/newt/classes/jogamp/newt/DefaultEDTUtil.java
index f33b474..d481ce8 100644
--- a/src/newt/classes/jogamp/newt/DefaultEDTUtil.java
+++ b/src/newt/classes/jogamp/newt/DefaultEDTUtil.java
@@ -50,6 +50,11 @@ import com.jogamp.newt.util.EDTUtil;
 public class DefaultEDTUtil implements EDTUtil {
     public static final boolean DEBUG = Debug.debug("EDT");
 
+    /** Used to implement {@link #invokeStop(boolean, Runnable)}. */
+    private static final Object TASK_ATTACHMENT_STOP = new Object();
+    /** Used to provoke an exception on the EDT while waiting / blocking. Merely exists to test code.*/
+    private static final Object TASK_ATTACHMENT_TEST_ERROR = new Object();
+
     private final Object edtLock = new Object(); // locking the EDT start/stop state
     private /* final */ ThreadGroup threadGroup;
     private final String name;
@@ -139,12 +144,20 @@ public class DefaultEDTUtil implements EDTUtil {
             System.err.println(Thread.currentThread()+": Default-EDT.invokeStop wait "+wait);
             Thread.dumpStack();
         }
-        return invokeImpl(wait, task, true);
+        return invokeImpl(wait, task, true /* stop */, false /* provokeError */);
+    }
+
+    public final boolean invokeAndWaitError(Runnable task) {
+        if(DEBUG) {
+            System.err.println(Thread.currentThread()+": Default-EDT.invokeAndWaitError");
+            Thread.dumpStack();
+        }
+        return invokeImpl(true /* wait */, task, false /* stop */, true /* provokeError */);
     }
 
     @Override
     public final boolean invoke(boolean wait, Runnable task) {
-        return invokeImpl(wait, task, false);
+        return invokeImpl(wait, task, false /* stop */, false /* provokeError */);
     }
 
     private static Runnable nullTask = new Runnable() {
@@ -152,7 +165,7 @@ public class DefaultEDTUtil implements EDTUtil {
         public void run() { }
     };
 
-    private final boolean invokeImpl(boolean wait, Runnable task, boolean stop) {
+    private final boolean invokeImpl(boolean wait, Runnable task, boolean stop, boolean provokeError) {
         Throwable throwable = null;
         RunnableTask rTask = null;
         final Object rTaskLock = new Object();
@@ -204,7 +217,9 @@ public class DefaultEDTUtil implements EDTUtil {
                                                      true /* always catch and report Exceptions, don't disturb EDT */,
                                                      wait ? null : System.err);
                             if(stop) {
-                                rTask.setAttachment(new Boolean(true)); // mark final task, will imply shouldStop:=true
+                                rTask.setAttachment(TASK_ATTACHMENT_STOP); // mark final task, will imply shouldStop:=true
+                            } else if(provokeError) {
+                                rTask.setAttachment(TASK_ATTACHMENT_TEST_ERROR);
                             }
                             // append task ..
                             edt.tasks.add(rTask);
@@ -283,7 +298,7 @@ public class DefaultEDTUtil implements EDTUtil {
     class NEDT extends Thread {
         volatile boolean shouldStop = false;
         volatile boolean isRunning = false;
-        ArrayList<RunnableTask> tasks = new ArrayList<RunnableTask>(); // one shot tasks
+        final ArrayList<RunnableTask> tasks = new ArrayList<RunnableTask>(); // one shot tasks
 
         public NEDT(ThreadGroup tg, String name) {
             super(tg, name);
@@ -340,8 +355,13 @@ public class DefaultEDTUtil implements EDTUtil {
                         if(tasks.size()>0) {
                             task = tasks.remove(0);
                             tasks.notifyAll();
-                            if( null != task.getAttachment() ) {
+                            final Object attachment = task.getAttachment();
+                            if( TASK_ATTACHMENT_STOP == attachment ) {
                                 shouldStop = true;
+                            } else if( TASK_ATTACHMENT_TEST_ERROR == attachment ) {
+                                tasks.add(0, task);
+                                task = null;
+                                throw new RuntimeException("TASK_ATTACHMENT_TEST_ERROR");
                             }
                         }
                     }
@@ -366,16 +386,27 @@ public class DefaultEDTUtil implements EDTUtil {
                     error = new RuntimeException("Within Default-EDT", t);
                 }
             } finally {
+                final String msg = getName()+": Default-EDT finished w/ "+tasks.size()+" left";
                 if(DEBUG) {
-                    RunnableTask rt = ( tasks.size() > 0 ) ? tasks.get(0) : null ;
-                    System.err.println(getName()+": Default-EDT run() END "+ getName()+", tasks: "+tasks.size()+", "+rt+", "+error);
+                    System.err.println(msg+", "+error);
                 }
                 synchronized(edtLock) {
+                    int i = 0;
+                    while( tasks.size() > 0 ) {
+                        // notify all waiter
+                        final String msg2 = msg+", task #"+i;
+                        final Throwable t = null != error ? new Throwable(msg2, error) : new Throwable(msg2);
+                        final RunnableTask rt = tasks.remove(0);
+                        if( null != rt ) {
+                            rt.flush(t);
+                            i++;
+                        }
+                    }
                     isRunning = false;
                     edtLock.notifyAll();
                 }
                 if(DEBUG) {
-                    System.err.println(getName()+": Default-EDT run() EXIT "+ getName()+", exception: "+error);
+                    System.err.println(msg+" EXIT, exception: "+error);
                 }
                 if(null!=error) {
                     throw error;
diff --git a/src/newt/classes/jogamp/newt/DisplayImpl.java b/src/newt/classes/jogamp/newt/DisplayImpl.java
index 0c29d77..b485a47 100644
--- a/src/newt/classes/jogamp/newt/DisplayImpl.java
+++ b/src/newt/classes/jogamp/newt/DisplayImpl.java
@@ -34,22 +34,36 @@
 
 package jogamp.newt;
 
+import com.jogamp.common.nio.Buffers;
+import com.jogamp.common.util.IOUtil;
+import com.jogamp.common.util.ReflectionUtil;
 import com.jogamp.newt.Display;
 import com.jogamp.newt.NewtFactory;
 import com.jogamp.newt.event.NEWTEvent;
 import com.jogamp.newt.event.NEWTEventConsumer;
 
 import jogamp.newt.event.NEWTEventTask;
+
 import com.jogamp.newt.util.EDTUtil;
+import com.jogamp.opengl.util.PNGPixelRect;
 
+import java.io.IOException;
+import java.net.URLConnection;
+import java.nio.ByteBuffer;
 import java.util.ArrayList;
 
 import javax.media.nativewindow.AbstractGraphicsDevice;
 import javax.media.nativewindow.NativeWindowException;
 import javax.media.nativewindow.NativeWindowFactory;
+import javax.media.nativewindow.util.PixelFormatUtil;
+import javax.media.nativewindow.util.PixelRectangle;
+import javax.media.nativewindow.util.PixelFormat;
+import javax.media.nativewindow.util.Point;
+import javax.media.nativewindow.util.PointImmutable;
 
 public abstract class DisplayImpl extends Display {
     private static int serialno = 1;
+    private static final boolean pngUtilAvail;
 
     static {
         NativeWindowFactory.addCustomShutdownHook(true /* head */, new Runnable() {
@@ -60,8 +74,183 @@ public abstract class DisplayImpl extends Display {
                DisplayImpl.shutdownAll();
            }
         });
+
+        final ClassLoader cl = DisplayImpl.class.getClassLoader();
+        pngUtilAvail = ReflectionUtil.isClassAvailable("jogamp.opengl.util.pngj.PngReader", cl) &&
+                       ReflectionUtil.isClassAvailable("com.jogamp.opengl.util.PNGPixelRect", cl);
     }
 
+    public static final boolean isPNGUtilAvailable() { return pngUtilAvail; }
+
+    final ArrayList<PointerIconImpl> pointerIconList = new ArrayList<PointerIconImpl>();
+
+    /** Executed from EDT! */
+    private void destroyAllPointerIconFromList(final long dpy) {
+        synchronized(pointerIconList) {
+            final int count = pointerIconList.size();
+            for( int i=0; i < count; i++ ) {
+                final PointerIconImpl item = pointerIconList.get(i);
+                if(DEBUG) {
+                    System.err.println("destroyAllPointerIconFromList: dpy "+toHexString(dpy)+", # "+i+"/"+count+": "+item+" @ "+getThreadName());
+                }
+                if( null != item && item.isValid() ) {
+                    item.destroyOnEDT(dpy);
+                }
+            }
+            pointerIconList.clear();
+        }
+    }
+
+    @Override
+    public PixelFormat getNativePointerIconPixelFormat() { return PixelFormat.BGRA8888; }
+    @Override
+    public boolean getNativePointerIconForceDirectNIO() { return false; }
+
+    @Override
+    public final PointerIcon createPointerIcon(final IOUtil.ClassResources pngResource, final int hotX, final int hotY)
+            throws IllegalArgumentException, IllegalStateException, IOException
+    {
+        if( null == pngResource || 0 >= pngResource.resourceCount() ) {
+            throw new IllegalArgumentException("Null or invalid pngResource "+pngResource);
+        }
+        if( !pngUtilAvail ) {
+            return null;
+        }
+        final PointerIconImpl[] res = { null };
+        runOnEDTIfAvail(true, new Runnable() {
+            public void run() {
+                try {
+                    if( !DisplayImpl.this.isNativeValidAsync() ) {
+                        throw new IllegalStateException("Display.createPointerIcon: Display invalid "+DisplayImpl.this);
+                    }
+                    final URLConnection urlConn = pngResource.resolve(0);
+                    if( null == urlConn ) {
+                        throw new IOException("Could not resolve "+pngResource.resourcePaths[0]);
+                    }
+                    final PNGPixelRect image = PNGPixelRect.read(urlConn.getInputStream(),
+                                                                 getNativePointerIconPixelFormat(),
+                                                                 getNativePointerIconForceDirectNIO(),
+                                                                 0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+                    final long handle = createPointerIconImplChecked(image.getPixelformat(), image.getSize().getWidth(), image.getSize().getHeight(),
+                                                                     image.getPixels(), hotX, hotY);
+                    final PointImmutable hotspot = new Point(hotX, hotY);
+                    if( DEBUG_POINTER_ICON ) {
+                        System.err.println("createPointerIconPNG.0: "+image+", handle: "+toHexString(handle)+", hot "+hotspot);
+                    }
+                    if( 0 != handle ) {
+                        res[0] = new PointerIconImpl(DisplayImpl.this, image, hotspot, handle);
+                        if( DEBUG_POINTER_ICON ) {
+                            System.err.println("createPointerIconPNG.0: "+res[0]);
+                        }
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            } } );
+        if( null != res[0] ) {
+            synchronized(pointerIconList) {
+                pointerIconList.add(res[0]);
+            }
+        }
+        return res[0];
+    }
+
+    @Override
+    public final PointerIcon createPointerIcon(final PixelRectangle pixelrect, final int hotX, final int hotY)
+            throws IllegalArgumentException, IllegalStateException
+    {
+        if( null == pixelrect ) {
+            throw new IllegalArgumentException("Null or pixelrect");
+        }
+        final PixelRectangle fpixelrect;
+        if( getNativePointerIconPixelFormat() != pixelrect.getPixelformat() || pixelrect.isGLOriented() ) {
+            // conversion !
+            fpixelrect = PixelFormatUtil.convert32(pixelrect, getNativePointerIconPixelFormat(),
+                                                      0 /* ddestStride */, false /* isGLOriented */, getNativePointerIconForceDirectNIO() );
+            if( DEBUG_POINTER_ICON ) {
+                System.err.println("createPointerIconRES.0: Conversion-FMT "+pixelrect+" -> "+fpixelrect);
+            }
+        } else if( getNativePointerIconForceDirectNIO() && !Buffers.isDirect(pixelrect.getPixels()) ) {
+            // transfer to direct NIO
+            final ByteBuffer sBB = pixelrect.getPixels();
+            final ByteBuffer dBB = Buffers.newDirectByteBuffer(sBB.array(), sBB.arrayOffset());
+            fpixelrect = new PixelRectangle.GenericPixelRect(pixelrect.getPixelformat(), pixelrect.getSize(), pixelrect.getStride(), pixelrect.isGLOriented(), dBB);
+            if( DEBUG_POINTER_ICON ) {
+                System.err.println("createPointerIconRES.0: Conversion-NIO "+pixelrect+" -> "+fpixelrect);
+            }
+        } else {
+            fpixelrect = pixelrect;
+            if( DEBUG_POINTER_ICON ) {
+                System.err.println("createPointerIconRES.0: No conversion "+fpixelrect);
+            }
+        }
+        final PointerIconImpl[] res = { null };
+        runOnEDTIfAvail(true, new Runnable() {
+            public void run() {
+                try {
+                    if( !DisplayImpl.this.isNativeValidAsync() ) {
+                        throw new IllegalStateException("Display.createPointerIcon: Display invalid "+DisplayImpl.this);
+                    }
+                    if( null != fpixelrect ) {
+                        final long handle = createPointerIconImplChecked(fpixelrect.getPixelformat(),
+                                                                         fpixelrect.getSize().getWidth(),
+                                                                         fpixelrect.getSize().getHeight(),
+                                                                         fpixelrect.getPixels(), hotX, hotY);
+                        if( 0 != handle ) {
+                            res[0] = new PointerIconImpl(DisplayImpl.this, fpixelrect, new Point(hotX, hotY), handle);
+                        }
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            } } );
+        if( null != res[0] ) {
+            synchronized(pointerIconList) {
+                pointerIconList.add(res[0]);
+            }
+        }
+        return res[0];
+    }
+
+    /**
+     * Executed from EDT!
+     *
+     * @param pixelformat the <code>pixels</code>'s format
+     * @param width the <code>pixels</code>'s width
+     * @param height the <code>pixels</code>'s height
+     * @param pixels the <code>pixels</code>
+     * @param hotX the PointerIcon's hot-spot x-coord
+     * @param hotY the PointerIcon's hot-spot x-coord
+     * @return if successful a valid handle (not null), otherwise null.
+     */
+    protected final long createPointerIconImplChecked(PixelFormat pixelformat, int width, int height, final ByteBuffer pixels, final int hotX, final int hotY) {
+        if( getNativePointerIconPixelFormat() != pixelformat ) {
+            throw new IllegalArgumentException("Pixelformat no "+getNativePointerIconPixelFormat()+", but "+pixelformat);
+        }
+        if( getNativePointerIconForceDirectNIO() && !Buffers.isDirect(pixels) ) {
+            throw new IllegalArgumentException("pixel buffer is not direct "+pixels);
+        }
+        return createPointerIconImpl(pixelformat, width, height, pixels, hotX, hotY);
+    }
+
+    /**
+     * Executed from EDT!
+     *
+     * @param pixelformat the <code>pixels</code>'s format
+     * @param width the <code>pixels</code>'s width
+     * @param height the <code>pixels</code>'s height
+     * @param pixels the <code>pixels</code>
+     * @param hotX the PointerIcon's hot-spot x-coord
+     * @param hotY the PointerIcon's hot-spot x-coord
+     * @return if successful a valid handle (not null), otherwise null.
+     */
+    protected long createPointerIconImpl(PixelFormat pixelformat, int width, int height, final ByteBuffer pixels, final int hotX, final int hotY) {
+        return 0;
+    }
+
+    /** Executed from EDT! */
+    protected void destroyPointerIconImpl(final long displayHandle, long piHandle) { }
+
     /** Ensure static init has been run. */
     /* pp */static void initSingleton() { }
 
@@ -283,6 +472,7 @@ public abstract class DisplayImpl extends Display {
             @Override
             public void run() {
                 if ( null != f_aDevice ) {
+                    f_dpy.destroyAllPointerIconFromList(f_aDevice.getHandle());
                     f_dpy.closeNativeImpl(f_aDevice);
                 }
             }
@@ -315,6 +505,7 @@ public abstract class DisplayImpl extends Display {
                     @Override
                     public void run() {
                         if ( null != d.getGraphicsDevice() ) {
+                            d.destroyAllPointerIconFromList(f_aDevice.getHandle());
                             d.closeNativeImpl(f_aDevice);
                         }
                     }
@@ -433,6 +624,9 @@ public abstract class DisplayImpl extends Display {
     public synchronized final boolean isNativeValid() {
         return null != aDevice;
     }
+    protected final boolean isNativeValidAsync() {
+        return null != aDevice;
+    }
 
     @Override
     public boolean isEDTRunning() {
@@ -453,7 +647,7 @@ public abstract class DisplayImpl extends Display {
     /** Dispatch native Toolkit messageges */
     protected abstract void dispatchMessagesNative();
 
-    private Object eventsLock = new Object();
+    private final Object eventsLock = new Object();
     private ArrayList<NEWTEventTask> events = new ArrayList<NEWTEventTask>();
     private volatile boolean haveEvents = false;
 
diff --git a/src/newt/classes/jogamp/newt/PointerIconImpl.java b/src/newt/classes/jogamp/newt/PointerIconImpl.java
new file mode 100644
index 0000000..840799d
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/PointerIconImpl.java
@@ -0,0 +1,171 @@
+/**
+ * Copyright 2013 JogAmp Community. 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 JogAmp Community ``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 JogAmp Community OR
+ * 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package jogamp.newt;
+
+import java.nio.ByteBuffer;
+
+import javax.media.nativewindow.util.DimensionImmutable;
+import javax.media.nativewindow.util.PixelFormat;
+import javax.media.nativewindow.util.PixelRectangle;
+import javax.media.nativewindow.util.PointImmutable;
+
+import com.jogamp.newt.Display;
+import com.jogamp.newt.Display.PointerIcon;
+
+public class PointerIconImpl implements PointerIcon {
+    private final DisplayImpl display;
+    private final PixelFormat pixelformat;
+    private final DimensionImmutable size;
+    private final ByteBuffer pixels;
+    private final PointImmutable hotspot;
+    private long handle;
+    private int hashCode = 0;
+    private volatile boolean hashCodeComputed = false;
+
+    public PointerIconImpl(final DisplayImpl display, final PixelFormat pixelformat, final DimensionImmutable size, final ByteBuffer pixels, final PointImmutable hotspot, final long handle) {
+        this.display = display;
+        this.pixelformat = pixelformat;
+        this.size = size;
+        this.pixels = pixels;
+        this.hotspot = hotspot;
+
+        this.handle=handle;
+    }
+    public PointerIconImpl(final DisplayImpl display, final PixelRectangle pixelrect, final PointImmutable hotspot, final long handle) {
+        this.display = display;
+        this.pixelformat = pixelrect.getPixelformat();
+        this.size = pixelrect.getSize();
+        this.pixels = pixelrect.getPixels();
+        this.hotspot = hotspot;
+        this.handle=handle;
+    }
+
+    @Override
+    public int hashCode() {
+        if( !hashCodeComputed ) { // DBL CHECKED OK VOLATILE
+            synchronized (this) {
+                if( !hashCodeComputed ) {
+                    // 31 * x == (x << 5) - x
+                    int hash = 31 + display.getFQName().hashCode();
+                    hash = ((hash << 5) - hash) + pixelformat.hashCode();
+                    hash = ((hash << 5) - hash) + size.hashCode();
+                    hash = ((hash << 5) - hash) + getStride();
+                    hash = ((hash << 5) - hash) + ( isGLOriented() ? 1 : 0);
+                    hash = ((hash << 5) - hash) + pixels.hashCode();
+                    hashCode = ((hash << 5) - hash) + hotspot.hashCode();
+                }
+            }
+        }
+        return hashCode;
+    }
+
+    public synchronized final long getHandle() { return handle; }
+    public synchronized final long validatedHandle() {
+        synchronized(display.pointerIconList) {
+            if( !display.pointerIconList.contains(this) ) {
+                display.pointerIconList.add(this);
+            }
+        }
+        if( 0 == handle ) {
+            try {
+                handle = display.createPointerIconImpl(pixelformat, size.getWidth(), size.getHeight(), pixels, hotspot.getX(), hotspot.getY());
+                return handle;
+            } catch (Exception e) {
+                e.printStackTrace();
+                return 0;
+            }
+        } else {
+            return handle;
+        }
+    }
+    @Override
+    public final Display getDisplay() { return display; }
+    @Override
+    public final PixelFormat getPixelformat() { return pixelformat; }
+    @Override
+    public final ByteBuffer getPixels() { return pixels; }
+    @Override
+    public synchronized final boolean isValid() { return 0 != handle; }
+    @Override
+    public synchronized final boolean validate() {
+        if( 0 == handle ) {
+            return 0 != validatedHandle();
+        }
+        return true;
+    }
+
+    @Override
+    public synchronized void destroy() {
+        if(DisplayImpl.DEBUG) {
+            System.err.println("PointerIcon.destroy: "+this+", "+display+", "+DisplayImpl.getThreadName());
+        }
+        if( 0 != handle ) {
+            synchronized(display.pointerIconList) {
+                display.pointerIconList.remove(this);
+            }
+            display.runOnEDTIfAvail(false, new Runnable() {
+                public void run() {
+                    if( !display.isNativeValidAsync() ) {
+                        destroyOnEDT(display.getHandle());
+                    }
+                } } );
+        }
+    }
+
+    /** No checks, assume execution on EDT */
+    synchronized void destroyOnEDT(final long dpy) {
+        final long h = handle;
+        handle = 0;
+        try {
+            display.destroyPointerIconImpl(dpy, h);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public final DimensionImmutable getSize() {
+        return size;
+    }
+    @Override
+    public final int getStride() {
+        return size.getWidth() * pixelformat.bytesPerPixel();
+    }
+    @Override
+    public final boolean isGLOriented() {
+        return false;
+    }
+    @Override
+    public final PointImmutable getHotspot() {
+        return hotspot;
+    }
+    @Override
+    public final String toString() {
+        return "PointerIcon[obj 0x"+Integer.toHexString(super.hashCode())+", "+display.getFQName()+", 0x"+Long.toHexString(handle)+", "+pixelformat+", "+size+", "+hotspot+", pixels "+pixels+"]";
+    }
+}
\ No newline at end of file
diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java
index ed7dd56..1e2291c 100644
--- a/src/newt/classes/jogamp/newt/WindowImpl.java
+++ b/src/newt/classes/jogamp/newt/WindowImpl.java
@@ -34,55 +34,59 @@
 
 package jogamp.newt;
 
-import java.util.ArrayList;
-import java.util.List;
 import java.lang.ref.WeakReference;
 import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.CapabilitiesChooser;
+import javax.media.nativewindow.CapabilitiesImmutable;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindow;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.NativeWindowFactory;
+import javax.media.nativewindow.OffscreenLayerSurface;
+import javax.media.nativewindow.SurfaceUpdatedListener;
+import javax.media.nativewindow.WindowClosingProtocol;
+import javax.media.nativewindow.util.DimensionImmutable;
+import javax.media.nativewindow.util.Insets;
+import javax.media.nativewindow.util.InsetsImmutable;
+import javax.media.nativewindow.util.PixelRectangle;
+import javax.media.nativewindow.util.Point;
+import javax.media.nativewindow.util.PointImmutable;
+import javax.media.nativewindow.util.Rectangle;
+import javax.media.nativewindow.util.RectangleImmutable;
+
+import jogamp.nativewindow.SurfaceUpdatedHelper;
 
 import com.jogamp.common.util.ArrayHashSet;
 import com.jogamp.common.util.IntBitfield;
 import com.jogamp.common.util.ReflectionUtil;
+import com.jogamp.common.util.locks.LockFactory;
+import com.jogamp.common.util.locks.RecursiveLock;
+import com.jogamp.newt.Display;
+import com.jogamp.newt.Display.PointerIcon;
 import com.jogamp.newt.MonitorDevice;
 import com.jogamp.newt.NewtFactory;
-import com.jogamp.newt.Display;
 import com.jogamp.newt.Screen;
 import com.jogamp.newt.Window;
-import com.jogamp.common.util.locks.LockFactory;
-import com.jogamp.common.util.locks.RecursiveLock;
 import com.jogamp.newt.event.DoubleTapScrollGesture;
 import com.jogamp.newt.event.GestureHandler;
 import com.jogamp.newt.event.InputEvent;
 import com.jogamp.newt.event.KeyEvent;
 import com.jogamp.newt.event.KeyListener;
 import com.jogamp.newt.event.MonitorEvent;
+import com.jogamp.newt.event.MonitorModeListener;
 import com.jogamp.newt.event.MouseEvent;
+import com.jogamp.newt.event.MouseEvent.PointerType;
 import com.jogamp.newt.event.MouseListener;
 import com.jogamp.newt.event.NEWTEvent;
 import com.jogamp.newt.event.NEWTEventConsumer;
-import com.jogamp.newt.event.MonitorModeListener;
 import com.jogamp.newt.event.WindowEvent;
 import com.jogamp.newt.event.WindowListener;
 import com.jogamp.newt.event.WindowUpdateEvent;
-import com.jogamp.newt.event.MouseEvent.PointerType;
-
-import javax.media.nativewindow.AbstractGraphicsConfiguration;
-import javax.media.nativewindow.AbstractGraphicsDevice;
-import javax.media.nativewindow.CapabilitiesChooser;
-import javax.media.nativewindow.CapabilitiesImmutable;
-import javax.media.nativewindow.NativeSurface;
-import javax.media.nativewindow.NativeWindow;
-import javax.media.nativewindow.NativeWindowException;
-import javax.media.nativewindow.NativeWindowFactory;
-import javax.media.nativewindow.SurfaceUpdatedListener;
-import javax.media.nativewindow.WindowClosingProtocol;
-import javax.media.nativewindow.util.DimensionImmutable;
-import javax.media.nativewindow.util.Insets;
-import javax.media.nativewindow.util.InsetsImmutable;
-import javax.media.nativewindow.util.Point;
-import javax.media.nativewindow.util.Rectangle;
-import javax.media.nativewindow.util.RectangleImmutable;
-
-import jogamp.nativewindow.SurfaceUpdatedHelper;
 
 public abstract class WindowImpl implements Window, NEWTEventConsumer
 {
@@ -147,6 +151,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
     private volatile int width = 128, height = 128; // client-area size w/o insets, default: may be overwritten by user
     private volatile int x = 64, y = 64; // client-area pos w/o insets
     private volatile Insets insets = new Insets(); // insets of decoration (if top-level && decorated)
+    private boolean blockInsetsChange = false; // block insets change (from same thread)
 
     private final RecursiveLock windowLock = LockFactory.createRecursiveLock();  // Window instance wide lock
     private int surfaceLockCount = 0; // surface lock recursion count
@@ -169,6 +174,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
     private String title = "Newt Window";
     private boolean undecorated = false;
     private boolean alwaysOnTop = false;
+    private PointerIconImpl pointerIcon = null;
     private boolean pointerVisible = true;
     private boolean pointerConfined = false;
     private LifecycleHook lifecycleHook = null;
@@ -254,22 +260,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
     private ArrayList<WindowListener> windowListeners  = new ArrayList<WindowListener>();
     private boolean repaintQueued = false;
 
-    /**
-     * Workaround for initialization order problems on Mac OS X
-     * between native Newt and (apparently) Fmod -- if Fmod is
-     * initialized first then the connection to the window server
-     * breaks, leading to errors from deep within the AppKit
-     */
-    public static void init(String type) {
-        if (NativeWindowFactory.TYPE_MACOSX.equals(type)) {
-            try {
-                getWindowClass(type);
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-        }
-    }
-
     //
     // Construction Methods
     //
@@ -424,8 +414,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
             throw new NativeWindowException("Parent surface lock: not ready: "+parentWindow);
         }
 
+        final boolean hasParent = null != parentWindow || 0 != this.parentWindowHandle;
+
         // child window: position defaults to 0/0, no auto position, no negative position
-        if( null != parentWindow && ( autoPosition || 0>getX() || 0>getY() ) ) {
+        if( hasParent && ( autoPosition || 0>getX() || 0>getY() ) ) {
             definePosition(0, 0);
         }
         boolean postParentlockFocus = false;
@@ -451,7 +443,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
                     createNativeImpl();
                     screen.addMonitorModeListener(monitorModeListenerImpl);
                     setTitleImpl(title);
-                    setPointerVisibleImpl(pointerVisible);
+                    setPointerIconIntern(pointerIcon);
+                    setPointerVisibleIntern(pointerVisible);
                     confinePointerImpl(pointerConfined);
                     setKeyboardVisible(keyboardVisible);
                     final long remainingV = waitForVisible(true, false);
@@ -462,7 +455,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
                                 fullScreenAction.init(true);
                                 fullScreenAction.run();
                             }
-                        } else {
+                        } else if ( !hasParent ) {
                             // Wait until position is reached within tolerances, either auto-position or custom position.
                             waitForPosition(usePosition, wX, wY, Window.TIMEOUT_NATIVEWINDOW);
                         }
@@ -549,14 +542,14 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
     private WindowClosingMode defaultCloseOperation = WindowClosingMode.DISPOSE_ON_CLOSE;
 
     @Override
-    public WindowClosingMode getDefaultCloseOperation() {
+    public final WindowClosingMode getDefaultCloseOperation() {
         synchronized (closingListenerLock) {
             return defaultCloseOperation;
         }
     }
 
     @Override
-    public WindowClosingMode setDefaultCloseOperation(WindowClosingMode op) {
+    public final WindowClosingMode setDefaultCloseOperation(WindowClosingMode op) {
         synchronized (closingListenerLock) {
             WindowClosingMode _op = defaultCloseOperation;
             defaultCloseOperation = op;
@@ -740,6 +733,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
     protected boolean setPointerVisibleImpl(boolean pointerVisible) { return false; }
     protected boolean confinePointerImpl(boolean confine) { return false; }
     protected void warpPointerImpl(int x, int y) { }
+    protected void setPointerIconImpl(final PointerIconImpl pi) { }
 
     //----------------------------------------------------------------------
     // NativeSurface
@@ -977,7 +971,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
     }
 
     @Override
-    public void setVisible(boolean wait, boolean visible) {
+    public final void setVisible(boolean wait, boolean visible) {
         if(DEBUG_IMPLEMENTATION) {
             System.err.println("Window setVisible: START ("+getThreadName()+") "+getX()+"/"+getY()+" "+getWidth()+"x"+getHeight()+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible: "+this.visible+" -> "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentWindow "+(null!=parentWindow));
         }
@@ -985,7 +979,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
     }
 
     @Override
-    public void setVisible(boolean visible) {
+    public final void setVisible(boolean visible) {
         setVisible(true, visible);
     }
 
@@ -1043,11 +1037,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
         runOnEDTIfAvail(true, new SetSizeAction(width, height, true));
     }
     @Override
-    public void setSize(int width, int height) {
+    public final void setSize(int width, int height) {
         runOnEDTIfAvail(true, new SetSizeAction(width, height, false));
     }
     @Override
-    public void setTopLevelSize(int width, int height) {
+    public final void setTopLevelSize(int width, int height) {
         setSize(width - getInsets().getTotalWidth(), height - getInsets().getTotalHeight());
     }
 
@@ -1211,6 +1205,14 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
 
         @Override
         public final void run() {
+            if( WindowImpl.this.isFullscreen() ) {
+                // Bug 924: Ignore reparent when in fullscreen - otherwise may confuse WM
+                if( DEBUG_IMPLEMENTATION) {
+                    System.err.println("Window.reparent: NOP (in fullscreen, "+getThreadName()+") valid "+isNativeValid()+
+                                       ", windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle));
+                }
+                return;
+            }
             boolean animatorPaused = false;
             if(null!=lifecycleHook) {
                 animatorPaused = lifecycleHook.pauseRenderingAction();
@@ -1262,6 +1264,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
                                        ", windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle)+
                                        ", visible "+wasVisible+", becomesVisible "+becomesVisible+
                                        ", forceDestroyCreate "+forceDestroyCreate+
+                                       ", DEBUG_TEST_REPARENT_INCOMPATIBLE "+DEBUG_TEST_REPARENT_INCOMPATIBLE+
                                        ", HINT_FORCE_RECREATION "+( 0 != ( REPARENT_HINT_FORCE_RECREATION & hints ) )+
                                        ", HINT_BECOMES_VISIBLE "+( 0 != ( REPARENT_HINT_BECOMES_VISIBLE & hints ) ) +
                                        ", old parentWindow: "+Display.hashCodeNullSafe(parentWindow)+
@@ -1379,6 +1382,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
                     return;
                 }
 
+                if( null == newParentWindow ) {
+                    // CLIENT -> TOP: Reset Parent's Pointer State
+                    setOffscreenPointerIcon(null);
+                    setOffscreenPointerVisible(true, null);
+                }
+
                 // rearrange window tree
                 if(null!=parentWindow && parentWindow instanceof Window) {
                     ((Window)parentWindow).removeChild(WindowImpl.this);
@@ -1431,12 +1440,18 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
                             setVisibleImpl(true, x, y, width, height);
                             ok = 0 <= WindowImpl.this.waitForVisible(true, false);
                             if(ok) {
+                                if( isAlwaysOnTop() && 0 == parentWindowHandle && NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(true) ) {
+                                    // Reinforce ALWAYSONTOP when CHILD -> TOP reparenting, since reparenting itself cause X11 WM to loose it's state.
+                                    reconfigureWindowImpl(x, y, width, height, getReconfigureFlags(FLAG_CHANGE_ALWAYSONTOP, isVisible()));
+                                }
                                 ok = WindowImpl.this.waitForSize(width, height, false, TIMEOUT_NATIVEWINDOW);
                             }
                             if(ok) {
-                                ok = WindowImpl.this.waitForPosition(true, x, y, TIMEOUT_NATIVEWINDOW);
-                            }
-                            if(ok) {
+                                if( 0 == parentWindowHandle ) {
+                                    // Position mismatch shall not lead to reparent failure
+                                    WindowImpl.this.waitForPosition(true, x, y, TIMEOUT_NATIVEWINDOW);
+                                }
+
                                 requestFocusInt( 0 == parentWindowHandle /* skipFocusAction if top-level */);
                                 display.dispatchMessagesNative(); // status up2date
                             }
@@ -1457,6 +1472,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
                         }
                         destroy( becomesVisible );
                         operation = ReparentOperation.ACTION_NATIVE_CREATION ;
+                    } else {
+                        if( null != parentWindow ) {
+                            // TOP -> CLIENT: Setup Parent's Pointer State
+                            setOffscreenPointerIcon(pointerIcon);
+                            setOffscreenPointerVisible(pointerVisible, pointerIcon);
+                        }
                     }
                 } else {
                     // Case
@@ -1522,19 +1543,19 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
     }
 
     @Override
-    public ReparentOperation reparentWindow(NativeWindow newParent, int x, int y, boolean forceDestroyCreate) {
+    public final ReparentOperation reparentWindow(NativeWindow newParent, int x, int y, boolean forceDestroyCreate) {
         return reparentWindow(newParent, x, y, forceDestroyCreate ? REPARENT_HINT_FORCE_RECREATION : 0);
     }
 
     @Override
-    public ReparentOperation reparentWindow(NativeWindow newParent, int x, int y, int hints) {
+    public final ReparentOperation reparentWindow(NativeWindow newParent, int x, int y, int hints) {
         final ReparentAction reparentAction = new ReparentAction(newParent, x, y, hints);
         runOnEDTIfAvail(true, reparentAction);
         return reparentAction.getOp();
     }
 
     @Override
-    public CapabilitiesChooser setCapabilitiesChooser(CapabilitiesChooser chooser) {
+    public final CapabilitiesChooser setCapabilitiesChooser(CapabilitiesChooser chooser) {
         CapabilitiesChooser old = this.capabilitiesChooser;
         this.capabilitiesChooser = chooser;
         return old;
@@ -1587,7 +1608,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
     }
 
     @Override
-    public void setUndecorated(boolean value) {
+    public final void setUndecorated(boolean value) {
         runOnEDTIfAvail(true, new DecorationAction(value));
     }
 
@@ -1647,11 +1668,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
     }
 
     @Override
-    public String getTitle() {
+    public final String getTitle() {
         return title;
     }
     @Override
-    public void setTitle(String title) {
+    public final void setTitle(String title) {
         if (title == null) {
             title = "";
         }
@@ -1662,28 +1683,121 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
     }
 
     @Override
-    public boolean isPointerVisible() {
+    public final boolean isPointerVisible() {
         return pointerVisible;
     }
     @Override
-    public void setPointerVisible(boolean pointerVisible) {
+    public final void setPointerVisible(final boolean pointerVisible) {
         if(this.pointerVisible != pointerVisible) {
             boolean setVal = 0 == getWindowHandle();
             if(!setVal) {
-                setVal = setPointerVisibleImpl(pointerVisible);
+                setVal = setPointerVisibleIntern(pointerVisible);
             }
             if(setVal) {
                 this.pointerVisible = pointerVisible;
             }
         }
     }
+    private boolean setPointerVisibleIntern(final boolean pointerVisible) {
+        boolean res = setOffscreenPointerVisible(pointerVisible, pointerIcon);
+        return setPointerVisibleImpl(pointerVisible) || res; // accept onscreen or offscreen positive result!
+    }
+    /**
+     * Helper method to delegate {@link #setPointerVisibleImpl(boolean)} to
+     * {@link OffscreenLayerSurface#hideCursor()} or {@link OffscreenLayerSurface#setCursor(PixelRectangle, PointImmutable)}.
+     * <p>
+     * Note: JAWTWindow is an OffscreenLayerSurface.
+     * </p>
+     * <p>
+     * Performing OffscreenLayerSurface's setCursor(..)/hideCursor(), if available,
+     * gives same behavior on all platforms.
+     * </p>
+     * <p>
+     * If visible, implementation invokes {@link #setOffscreenPointerIcon(OffscreenLayerSurface, PointerIconImpl)} using the
+     * given <code>defaultPointerIcon</code>, otherwise {@link OffscreenLayerSurface#hideCursor()} is invoked.
+     * </p>
+     * @param pointerVisible true for visible, otherwise invisible.
+     * @param defaultPointerIcon default PointerIcon for visibility
+     * @param ols the {@link OffscreenLayerSurface} instance, if null method does nothing.
+     */
+    private boolean setOffscreenPointerVisible(final boolean pointerVisible, final PointerIconImpl defaultPointerIcon) {
+        if( pointerVisible ) {
+            return setOffscreenPointerIcon(defaultPointerIcon);
+        } else {
+            final NativeWindow parent = getParent();
+            if( parent instanceof OffscreenLayerSurface ) {
+                final OffscreenLayerSurface ols = (OffscreenLayerSurface) parent;
+                try {
+                    return ols.hideCursor();
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return false;
+    }
+
     @Override
-    public boolean isPointerConfined() {
-        return pointerConfined;
+    public final PointerIcon getPointerIcon() { return pointerIcon; }
+
+    @Override
+    public final void setPointerIcon(final PointerIcon pi) {
+        final PointerIconImpl piImpl = (PointerIconImpl)pi;
+        if( this.pointerIcon != piImpl ) {
+            if( isNativeValid() ) {
+                runOnEDTIfAvail(true, new Runnable() {
+                    public void run() {
+                        setPointerIconIntern(piImpl);
+                    } } );
+            }
+            this.pointerIcon = piImpl;
+        }
+    }
+    private void setPointerIconIntern(final PointerIconImpl pi) {
+        setOffscreenPointerIcon(pi);
+        setPointerIconImpl(pi);
+    }
+    /**
+     * Helper method to delegate {@link #setPointerIconIntern(PointerIconImpl)} to
+     * {@link OffscreenLayerSurface#setCursor(PixelRectangle, PointImmutable)}
+     * <p>
+     * Note: JAWTWindow is an OffscreenLayerSurface.
+     * </p>
+     * <p>
+     * Performing OffscreenLayerSurface's setCursor(..), if available,
+     * gives same behavior on all platforms.
+     * </p>
+     * <p>
+     * Workaround for AWT/Windows bug within browser,
+     * where the PointerIcon gets periodically overridden
+     * by the AWT Component's icon.
+     * </p>
+     * @param ols the {@link OffscreenLayerSurface} instance, if null method does nothing.
+     * @param pi the {@link PointerIconImpl} instance, if null PointerIcon gets reset.
+     */
+    private boolean setOffscreenPointerIcon(final PointerIconImpl pi) {
+        final NativeWindow parent = getParent();
+        if( parent instanceof OffscreenLayerSurface ) {
+            final OffscreenLayerSurface ols = (OffscreenLayerSurface) parent;
+            try {
+                if( null != pi ) {
+                    return ols.setCursor(pi, pi.getHotspot());
+                } else {
+                    return ols.setCursor(null, null); // default
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        return false;
     }
 
     @Override
-    public void confinePointer(boolean confine) {
+    public final boolean isPointerConfined() {
+        return pointerConfined;
+    }
+    @Override
+    public final void confinePointer(boolean confine) {
         if(this.pointerConfined != confine) {
             boolean setVal = 0 == getWindowHandle();
             if(!setVal) {
@@ -1707,7 +1821,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
     }
 
     @Override
-    public void warpPointer(int x, int y) {
+    public final void warpPointer(int x, int y) {
         if(0 != getWindowHandle()) {
             warpPointerImpl(x, y);
         }
@@ -1794,11 +1908,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
         return false;
     }
 
-    public LifecycleHook getLifecycleHook() {
+    public final LifecycleHook getLifecycleHook() {
         return lifecycleHook;
     }
 
-    public LifecycleHook setLifecycleHook(LifecycleHook hook) {
+    public final LifecycleHook setLifecycleHook(LifecycleHook hook) {
         LifecycleHook old = lifecycleHook;
         lifecycleHook = hook;
         return old;
@@ -1813,23 +1927,16 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
     }
 
     @Override
-    public void setWindowDestroyNotifyAction(Runnable r) {
+    public final void setWindowDestroyNotifyAction(Runnable r) {
         windowDestroyNotifyAction = r;
     }
 
-    /**
-     * Returns the non delegated {@link AbstractGraphicsConfiguration},
-     * see {@link #getGraphicsConfiguration()}. */
-    public final AbstractGraphicsConfiguration getPrivateGraphicsConfiguration() {
-        return config;
-    }
-
     protected final long getParentWindowHandle() {
         return isFullscreen() ? 0 : parentWindowHandle;
     }
 
     @Override
-    public String toString() {
+    public final String toString() {
         StringBuilder sb = new StringBuilder();
 
         sb.append(getClass().getName()+"[Config "+config+
@@ -1874,7 +1981,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
     }
 
     @Override
-    public void runOnEDTIfAvail(boolean wait, final Runnable task) {
+    public final void runOnEDTIfAvail(boolean wait, final Runnable task) {
         if( windowLock.isOwner( Thread.currentThread() ) ) {
             task.run();
         } else {
@@ -1907,12 +2014,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
     }
 
     @Override
-    public void requestFocus() {
+    public final void requestFocus() {
         requestFocus(true);
     }
 
     @Override
-    public void requestFocus(boolean wait) {
+    public final void requestFocus(boolean wait) {
         requestFocus(wait /* wait */, false /* skipFocusAction */, brokenFocusChange /* force */);
     }
 
@@ -1935,7 +2042,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
     }
 
     @Override
-    public void setFocusAction(FocusRunnable focusAction) {
+    public final void setFocusAction(FocusRunnable focusAction) {
         this.focusAction = focusAction;
     }
 
@@ -1955,12 +2062,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
         return res;
     }
 
-    protected void setBrokenFocusChange(boolean v) {
+    protected final void setBrokenFocusChange(boolean v) {
         brokenFocusChange = v;
     }
 
     @Override
-    public void setKeyboardFocusHandler(KeyListener l) {
+    public final void setKeyboardFocusHandler(KeyListener l) {
         keyboardFocusHandler = l;
     }
 
@@ -1984,9 +2091,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
                     if(isNativeValid()) {
                         // this.x/this.y will be set by sizeChanged, triggered by windowing event system
                         reconfigureWindowImpl(x, y, getWidth(), getHeight(), getReconfigureFlags(0, isVisible()));
-
-                        // Wait until custom position is reached within tolerances
-                        waitForPosition(true, x, y, Window.TIMEOUT_NATIVEWINDOW);
+                        if( null == parentWindow ) {
+                            // Wait until custom position is reached within tolerances
+                            waitForPosition(true, x, y, Window.TIMEOUT_NATIVEWINDOW);
+                        }
                     } else {
                         definePosition(x, y); // set pos for createNative(..)
                     }
@@ -2004,32 +2112,30 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
     }
 
     @Override
-    public void setTopLevelPosition(int x, int y) {
+    public final void setTopLevelPosition(int x, int y) {
         setPosition(x + getInsets().getLeftWidth(), y + getInsets().getTopHeight());
     }
 
     private class FullScreenAction implements Runnable {
-        boolean fullscreen;
+        boolean _fullscreen;
 
         private boolean init(boolean fullscreen) {
             if(isNativeValid()) {
-                this.fullscreen = fullscreen;
+                this._fullscreen = fullscreen;
                 return isFullscreen() != fullscreen;
             } else {
                 WindowImpl.this.fullscreen = fullscreen; // set current state for createNative(..)
                 return false;
             }
         }
-        public boolean fsOn() { return fullscreen; }
+        public boolean fsOn() { return _fullscreen; }
 
         @Override
         public final void run() {
             final RecursiveLock _lock = windowLock;
             _lock.lock();
+            blockInsetsChange = true;
             try {
-                // set current state
-                WindowImpl.this.fullscreen = fullscreen;
-
                 final int oldX = getX();
                 final int oldY = getY();
                 final int oldWidth = getWidth();
@@ -2041,7 +2147,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
                 final RectangleImmutable viewport;
                 final int fs_span_flag;
                 final boolean alwaysOnTopChange;
-                if(fullscreen) {
+                if(_fullscreen) {
                     if( null == fullscreenMonitors ) {
                         if( fullscreenUseMainMonitor ) {
                             fullscreenMonitors = new ArrayList<MonitorDevice>();
@@ -2094,30 +2200,33 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
                         }
                     }
                 }
+
+                final DisplayImpl display = (DisplayImpl) screen.getDisplay();
+                display.dispatchMessagesNative(); // status up2date
+                final boolean wasVisible = isVisible();
+                final boolean tempInvisible = !_fullscreen && wasVisible && NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(true);
+
                 if(DEBUG_IMPLEMENTATION) {
-                    System.err.println("Window fs: "+fullscreen+" "+x+"/"+y+" "+w+"x"+h+", "+isUndecorated()+
+                    System.err.println("Window fs: "+_fullscreen+" "+x+"/"+y+" "+w+"x"+h+", "+isUndecorated()+
                                        ", virtl-screenSize: "+sviewport+", monitorsViewport "+viewport+
                                        ", spanning "+(0!=fs_span_flag)+
                                        ", alwaysOnTop "+alwaysOnTop+(alwaysOnTopChange?"*":"")+
+                                       ", wasVisible "+wasVisible+", tempInvisible "+tempInvisible+
+                                       ", hasParent "+(null!=parentWindow)+
                                        " @ "+Thread.currentThread().getName());
                 }
 
-                final DisplayImpl display = (DisplayImpl) screen.getDisplay();
-                display.dispatchMessagesNative(); // status up2date
-                final boolean wasVisible = isVisible();
+                // fullscreen off: !visible first (fixes X11 unsuccessful return to parent window _and_ wrong window size propagation)
+                if( tempInvisible ) {
+                    setVisibleImpl(false, oldX, oldY, oldWidth, oldHeight);
+                    WindowImpl.this.waitForVisible(false, false);
+                    try { Thread.sleep(100); } catch (InterruptedException e) { }
+                    display.dispatchMessagesNative(); // status up2date
+                }
 
                 // Lock parentWindow only during reparenting (attempt)
                 final NativeWindow parentWindowLocked;
                 if( null != parentWindow ) {
-                    // fullscreen off: !visible first (fixes X11 unsuccessful return to parent window)
-                    if( !fullscreen && wasVisible && NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(true) ) {
-                        setVisibleImpl(false, oldX, oldY, oldWidth, oldHeight);
-                        WindowImpl.this.waitForVisible(false, false);
-                        // FIXME: Some composite WM behave slacky .. give 'em chance to change state -> invisible,
-                        // even though we do exactly that (KDE+Composite)
-                        try { Thread.sleep(100); } catch (InterruptedException e) { }
-                        display.dispatchMessagesNative(); // status up2date
-                    }
                     parentWindowLocked = parentWindow;
                     if( NativeSurface.LOCK_SURFACE_NOT_READY >= parentWindowLocked.lockSurface() ) {
                         throw new NativeWindowException("Parent surface lock: not ready: "+parentWindow);
@@ -2126,14 +2235,16 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
                     parentWindowLocked = null;
                 }
                 try {
-                    if(alwaysOnTopChange && fullscreen) {
+                    if(alwaysOnTopChange && _fullscreen) {
                         // Enter fullscreen - Disable alwaysOnTop
-                        reconfigureWindowImpl(nfs_x, nfs_y, nfs_width, nfs_height, getReconfigureFlags(FLAG_CHANGE_ALWAYSONTOP, isVisible()));
+                        reconfigureWindowImpl(oldX, oldY, oldWidth, oldHeight, getReconfigureFlags(FLAG_CHANGE_ALWAYSONTOP, isVisible()));
                     }
+
+                    WindowImpl.this.fullscreen = _fullscreen;
                     reconfigureWindowImpl(x, y, w, h,
                                           getReconfigureFlags( ( ( null != parentWindowLocked ) ? FLAG_CHANGE_PARENTING : 0 ) |
                                                                fs_span_flag | FLAG_CHANGE_FULLSCREEN | FLAG_CHANGE_DECORATION, isVisible()) );
-                    if(alwaysOnTopChange && !fullscreen) {
+                    if(alwaysOnTopChange && !_fullscreen) {
                         // Leave fullscreen - Restore alwaysOnTop
                         reconfigureWindowImpl(x, y, w, h, getReconfigureFlags(FLAG_CHANGE_ALWAYSONTOP, isVisible()));
                     }
@@ -2145,16 +2256,22 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
                 display.dispatchMessagesNative(); // status up2date
 
                 if(wasVisible) {
+                    if( NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(true) ) {
+                        // Give sluggy WM's (e.g. Unity) a chance to properly restore window ..
+                        try { Thread.sleep(100); } catch (InterruptedException e) { }
+                        display.dispatchMessagesNative(); // status up2date
+                    }
                     setVisibleImpl(true, x, y, w, h);
                     boolean ok = 0 <= WindowImpl.this.waitForVisible(true, false);
                     if(ok) {
                         ok = WindowImpl.this.waitForSize(w, h, false, TIMEOUT_NATIVEWINDOW);
                     }
-                    if(ok && !fullscreen) {
-                        ok = WindowImpl.this.waitForPosition(true, x, y, TIMEOUT_NATIVEWINDOW);
+                    if(ok && !_fullscreen && null == parentWindow) {
+                        // Position mismatch shall not lead to fullscreen failure
+                        WindowImpl.this.waitForPosition(true, x, y, TIMEOUT_NATIVEWINDOW);
                     }
                     if(ok) {
-                        requestFocusInt(fullscreen /* skipFocusAction if fullscreen */);
+                        requestFocusInt(_fullscreen /* skipFocusAction if fullscreen */);
                         display.dispatchMessagesNative(); // status up2date
                     }
                     if(DEBUG_IMPLEMENTATION) {
@@ -2162,6 +2279,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
                     }
                 }
             } finally {
+                blockInsetsChange = false;
                 _lock.unlock();
             }
             sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener
@@ -2333,7 +2451,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
     }
 
     @Override
-    public void enqueueEvent(boolean wait, com.jogamp.newt.event.NEWTEvent event) {
+    public final void enqueueEvent(boolean wait, com.jogamp.newt.event.NEWTEvent event) {
         if(isNativeValid()) {
             ((DisplayImpl)screen.getDisplay()).enqueueEvent(wait, event);
         }
@@ -2392,22 +2510,22 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
     // SurfaceUpdatedListener Support
     //
     @Override
-    public void addSurfaceUpdatedListener(SurfaceUpdatedListener l) {
+    public final void addSurfaceUpdatedListener(SurfaceUpdatedListener l) {
         surfaceUpdatedHelper.addSurfaceUpdatedListener(l);
     }
 
     @Override
-    public void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l) throws IndexOutOfBoundsException {
+    public final void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l) throws IndexOutOfBoundsException {
         surfaceUpdatedHelper.addSurfaceUpdatedListener(index, l);
     }
 
     @Override
-    public void removeSurfaceUpdatedListener(SurfaceUpdatedListener l) {
+    public final void removeSurfaceUpdatedListener(SurfaceUpdatedListener l) {
         surfaceUpdatedHelper.removeSurfaceUpdatedListener(l);
     }
 
     @Override
-    public void surfaceUpdated(Object updater, NativeSurface ns, long when) {
+    public final void surfaceUpdated(Object updater, NativeSurface ns, long when) {
         surfaceUpdatedHelper.surfaceUpdated(updater, ns, when);
     }
 
@@ -2419,8 +2537,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
     // Native MouseEvents pre-processed to be enqueued or consumed directly
     //
 
-    public final void sendMouseEvent(final short eventType, final int modifiers,
-                                     final int x, final int y, final short button, final float rotation) {
+    public void sendMouseEvent(final short eventType, final int modifiers,
+                               final int x, final int y, final short button, final float rotation) {
         doMouseEvent(false, false, eventType, modifiers, x, y, button, MouseEvent.getRotationXYZ(rotation, modifiers), 1f);
     }
     public final void enqueueMouseEvent(final boolean wait, final short eventType, final int modifiers,
@@ -3250,12 +3368,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
     protected boolean keyboardVisible = false;
 
     @Override
-    public void addKeyListener(KeyListener l) {
+    public final void addKeyListener(KeyListener l) {
         addKeyListener(-1, l);
     }
 
     @Override
-    public void addKeyListener(int index, KeyListener l) {
+    public final void addKeyListener(int index, KeyListener l) {
         if(l == null) {
             return;
         }
@@ -3269,7 +3387,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
     }
 
     @Override
-    public void removeKeyListener(KeyListener l) {
+    public final void removeKeyListener(KeyListener l) {
         if (l == null) {
             return;
         }
@@ -3280,7 +3398,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
     }
 
     @Override
-    public KeyListener getKeyListener(int index) {
+    public final KeyListener getKeyListener(int index) {
         @SuppressWarnings("unchecked")
         ArrayList<KeyListener> clonedListeners = (ArrayList<KeyListener>) keyListeners.clone();
         if(0>index) {
@@ -3290,7 +3408,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
     }
 
     @Override
-    public KeyListener[] getKeyListeners() {
+    public final KeyListener[] getKeyListeners() {
         return keyListeners.toArray(new KeyListener[keyListeners.size()]);
     }
 
@@ -3332,21 +3450,21 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
     // WindowListener/Event Support
     //
     @Override
-    public void sendWindowEvent(int eventType) {
+    public final void sendWindowEvent(int eventType) {
         consumeWindowEvent( new WindowEvent((short)eventType, this, System.currentTimeMillis()) );
     }
 
-    public void enqueueWindowEvent(boolean wait, int eventType) {
+    public final void enqueueWindowEvent(boolean wait, int eventType) {
         enqueueEvent( wait, new WindowEvent((short)eventType, this, System.currentTimeMillis()) );
     }
 
     @Override
-    public void addWindowListener(WindowListener l) {
+    public final void addWindowListener(WindowListener l) {
         addWindowListener(-1, l);
     }
 
     @Override
-    public void addWindowListener(int index, WindowListener l)
+    public final void addWindowListener(int index, WindowListener l)
         throws IndexOutOfBoundsException
     {
         if(l == null) {
@@ -3373,7 +3491,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
     }
 
     @Override
-    public WindowListener getWindowListener(int index) {
+    public final WindowListener getWindowListener(int index) {
         @SuppressWarnings("unchecked")
         ArrayList<WindowListener> clonedListeners = (ArrayList<WindowListener>) windowListeners.clone();
         if(0>index) {
@@ -3383,7 +3501,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
     }
 
     @Override
-    public WindowListener[] getWindowListeners() {
+    public final WindowListener[] getWindowListeners() {
         return windowListeners.toArray(new WindowListener[windowListeners.size()]);
     }
 
@@ -3440,7 +3558,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
     }
 
     /** Triggered by implementation's WM events to update the visibility state. */
-    protected void visibleChanged(boolean defer, boolean visible) {
+    protected final void visibleChanged(boolean defer, boolean visible) {
         if(this.visible != visible) {
             if(DEBUG_IMPLEMENTATION) {
                 System.err.println("Window.visibleChanged ("+getThreadName()+"): (defer: "+defer+") "+this.visible+" -> "+visible+" - windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle));
@@ -3522,7 +3640,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
     }
 
     /** Triggered by implementation's WM events to update the position. */
-    protected void positionChanged(boolean defer, int newX, int newY) {
+    protected final void positionChanged(boolean defer, int newX, int newY) {
         if ( getX() != newX || getY() != newY ) {
             if(DEBUG_IMPLEMENTATION) {
                 System.err.println("Window.positionChanged: ("+getThreadName()+"): (defer: "+defer+") "+getX()+"/"+getY()+" -> "+newX+"/"+newY+" - windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle));
@@ -3587,17 +3705,17 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
      */
     protected void insetsChanged(boolean defer, int left, int right, int top, int bottom) {
         if ( left >= 0 && right >= 0 && top >= 0 && bottom >= 0 ) {
-            if(isUndecorated()) {
+            if( blockInsetsChange || isUndecorated() ) {
                 if(DEBUG_IMPLEMENTATION) {
-                    System.err.println("Window.insetsChanged: skip insets change for undecoration mode");
+                    System.err.println("Window.insetsChanged (defer: "+defer+"): Skip insets change "+insets+" -> "+new Insets(left, right, top, bottom)+" (blocked "+blockInsetsChange+", undecoration "+isUndecorated()+")");
                 }
             } else if ( (left != insets.getLeftWidth() || right != insets.getRightWidth() ||
                          top != insets.getTopHeight() || bottom != insets.getBottomHeight() )
                        ) {
-                insets.set(left, right, top, bottom);
                 if(DEBUG_IMPLEMENTATION) {
-                    System.err.println("Window.insetsChanged: (defer: "+defer+") "+insets);
+                    System.err.println("Window.insetsChanged (defer: "+defer+"): Changed "+insets+" -> "+new Insets(left, right, top, bottom));
                 }
+                insets.set(left, right, top, bottom);
             }
         }
     }
@@ -3609,7 +3727,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
      *              and hence force destruction. Otherwise is follows the user settings.
      * @return true if this window is no more valid and hence has been destroyed, otherwise false.
      */
-    public boolean windowDestroyNotify(boolean force) {
+    public final boolean windowDestroyNotify(boolean force) {
         final WindowClosingMode defMode = getDefaultCloseOperation();
         final WindowClosingMode mode = force ? WindowClosingMode.DISPOSE_ON_CLOSE : defMode;
         if(DEBUG_IMPLEMENTATION) {
@@ -3653,14 +3771,14 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
     }
 
     @Override
-    public void windowRepaint(int x, int y, int width, int height) {
+    public final void windowRepaint(int x, int y, int width, int height) {
         windowRepaint(false, x, y, width, height);
     }
 
     /**
      * Triggered by implementation's WM events to update the content
      */
-    protected void windowRepaint(boolean defer, int x, int y, int width, int height) {
+    protected final void windowRepaint(boolean defer, int x, int y, int width, int height) {
         width = ( 0 >= width ) ? getWidth() : width;
         height = ( 0 >= height ) ? getHeight() : height;
         if(DEBUG_IMPLEMENTATION) {
@@ -3721,10 +3839,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
         return sb.toString();
     }
 
-    protected final void shouldNotCallThis() {
-        throw new NativeWindowException("Should not call this");
-    }
-
     public static String getThreadName() {
         return Display.getThreadName();
     }
diff --git a/src/newt/classes/jogamp/newt/awt/event/AWTParentWindowAdapter.java b/src/newt/classes/jogamp/newt/awt/event/AWTParentWindowAdapter.java
index e152d96..7705023 100644
--- a/src/newt/classes/jogamp/newt/awt/event/AWTParentWindowAdapter.java
+++ b/src/newt/classes/jogamp/newt/awt/event/AWTParentWindowAdapter.java
@@ -121,13 +121,14 @@ public class AWTParentWindowAdapter extends AWTWindowAdapter implements java.awt
             newtChild.runOnEDTIfAvail(false, new Runnable() {
                 @Override
                 public void run() {
-                    int cw = comp.getWidth();
-                    int ch = comp.getHeight();
+                    final int cw = comp.getWidth();
+                    final int ch = comp.getHeight();
                     if( 0 < cw && 0 < ch ) {
                         if( newtChild.getWidth() != cw || newtChild.getHeight() != ch ) {
                             newtChild.setSize(cw, ch);
-                            if(comp.isVisible() != newtChild.isVisible()) {
-                                newtChild.setVisible(comp.isVisible());
+                            final boolean v = comp.isShowing(); // compute showing-state throughout hierarchy
+                            if(v != newtChild.isVisible()) {
+                                newtChild.setVisible(v);
                             }
                         }
                     } else if(newtChild.isVisible()) {
@@ -164,12 +165,12 @@ public class AWTParentWindowAdapter extends AWTWindowAdapter implements java.awt
         if( !isSetup ) { return; }
         final Window newtChild = getNewtWindow();
         if( null != newtChild && null == getNewtEventListener() ) {
-            long bits = e.getChangeFlags();
-            final java.awt.Component changed = e.getChanged();
+            final long bits = e.getChangeFlags();
+            final java.awt.Component comp = e.getComponent();
             if( 0 != ( java.awt.event.HierarchyEvent.SHOWING_CHANGED & bits ) ) {
-                final boolean showing = changed.isShowing();
+                final boolean showing = comp.isShowing(); // compute showing-state throughout hierarchy
                 if(DEBUG_IMPLEMENTATION) {
-                    System.err.println("AWT: hierarchyChanged SHOWING_CHANGED: showing "+showing+", "+changed+", source "+e.getComponent());
+                    System.err.println("AWT: hierarchyChanged SHOWING_CHANGED: showing "+showing+", comp "+comp+", changed "+e.getChanged());
                 }
                 newtChild.runOnEDTIfAvail(false, new Runnable() {
                     @Override
@@ -181,8 +182,7 @@ public class AWTParentWindowAdapter extends AWTWindowAdapter implements java.awt
             }
             if(DEBUG_IMPLEMENTATION) {
                 if( 0 != ( java.awt.event.HierarchyEvent.DISPLAYABILITY_CHANGED & bits ) ) {
-                    final boolean displayability = changed.isDisplayable();
-                    System.err.println("AWT: hierarchyChanged DISPLAYABILITY_CHANGED: displayability "+displayability+", "+changed);
+                    System.err.println("AWT: hierarchyChanged DISPLAYABILITY_CHANGED: "+e.getChanged());
                 }
             }
         }
diff --git a/src/newt/classes/jogamp/newt/driver/PNGIcon.java b/src/newt/classes/jogamp/newt/driver/PNGIcon.java
new file mode 100644
index 0000000..967acd4
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/driver/PNGIcon.java
@@ -0,0 +1,80 @@
+/**
+ * Copyright 2013 JogAmp Community. 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 JogAmp Community ``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 JogAmp Community OR
+ * 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package jogamp.newt.driver;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.nio.ByteBuffer;
+
+import jogamp.newt.Debug;
+import jogamp.newt.DisplayImpl;
+
+import com.jogamp.common.util.IOUtil;
+import com.jogamp.common.util.ReflectionUtil;
+
+public class PNGIcon {
+    private static final String err0 = "PNG decoder not implemented.";
+
+    private static final boolean avail;
+
+    static {
+        Debug.initSingleton();
+
+        final ClassLoader cl = PNGIcon.class.getClassLoader();
+        avail = DisplayImpl.isPNGUtilAvailable() && ReflectionUtil.isClassAvailable("jogamp.newt.driver.opengl.JoglUtilPNGIcon", cl);
+    }
+
+    /** Returns true if PNG decoder is available. */
+    public static boolean isAvailable() {
+        return avail;
+    }
+
+    /**
+     * Special implementation for X11 Window Icons
+     * <p>
+     * The returned byte buffer is a direct buffer!
+     * </p>
+     *
+     * @param resources
+     * @param data_size
+     * @param elem_bytesize
+     *
+     * @return BGRA8888 bytes with origin at upper-left corner where component B is located on the lowest 8-bit and component A is located on the highest 8-bit.
+     *
+     * @throws UnsupportedOperationException if not implemented
+     * @throws InterruptedException
+     * @throws IOException
+     * @throws MalformedURLException
+     */
+    public static ByteBuffer arrayToX11BGRAImages(IOUtil.ClassResources resources, int[] data_size, int[] elem_bytesize) throws UnsupportedOperationException, InterruptedException, IOException, MalformedURLException {
+        if( avail ) {
+            return jogamp.newt.driver.opengl.JoglUtilPNGIcon.arrayToX11BGRAImages(resources, data_size, elem_bytesize);
+        }
+        throw new UnsupportedOperationException(err0);
+    }
+}
diff --git a/src/newt/classes/jogamp/newt/driver/android/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/android/DisplayDriver.java
index a2877db..32bd970 100644
--- a/src/newt/classes/jogamp/newt/driver/android/DisplayDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/android/DisplayDriver.java
@@ -3,14 +3,14 @@
  *
  * 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 JogAmp Community ``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 JogAmp Community OR
@@ -20,7 +20,7 @@
  * 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.
- * 
+ *
  * The views and conclusions contained in the software and documentation are those of the
  * authors and should not be interpreted as representing official policies, either expressed
  * or implied, of JogAmp Community.
@@ -53,6 +53,7 @@ public class DisplayDriver extends jogamp.newt.DisplayImpl {
     protected void createNativeImpl() {
         // EGL Device
         aDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
+        aDevice.open();
     }
 
     protected void closeNativeImpl(AbstractGraphicsDevice aDevice) {
@@ -61,6 +62,6 @@ public class DisplayDriver extends jogamp.newt.DisplayImpl {
 
     protected void dispatchMessagesNative() {
         // n/a .. DispatchMessages();
-    }    
+    }
 }
 
diff --git a/src/newt/classes/jogamp/newt/driver/android/NewtDebugActivityLauncher.java b/src/newt/classes/jogamp/newt/driver/android/NewtDebugActivityLauncher.java
deleted file mode 100644
index 9d16fde..0000000
--- a/src/newt/classes/jogamp/newt/driver/android/NewtDebugActivityLauncher.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package jogamp.newt.driver.android;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.util.Log;
-
-public class NewtDebugActivityLauncher extends Activity {
-       @Override
-       public void onCreate(Bundle savedInstanceState) {
-           super.onCreate(savedInstanceState);
-
-           final Uri uri = Uri.parse("launch://jogamp.org/jogamp.newt.driver.android.NewtDebugActivity?sys=com.jogamp.common&sys=javax.media.opengl&pkg=com.jogamp.opengl.test&jogamp.debug=all&nativewindow.debug=all&jogl.debug=all&newt.debug=all");
-           final Intent intent = new Intent("org.jogamp.launcher.action.LAUNCH_ACTIVITY_NORMAL", uri);
-           Log.d(getClass().getSimpleName(), "Launching Activity: "+intent);
-           startActivity (intent);
-
-           finish(); // done
-       }
-}
diff --git a/src/newt/classes/jogamp/newt/driver/android/NewtVersionActivity.java b/src/newt/classes/jogamp/newt/driver/android/NewtVersionActivity.java
index 8a7f3af..259acb8 100644
--- a/src/newt/classes/jogamp/newt/driver/android/NewtVersionActivity.java
+++ b/src/newt/classes/jogamp/newt/driver/android/NewtVersionActivity.java
@@ -27,11 +27,95 @@
  */
 package jogamp.newt.driver.android;
 
+import javax.media.opengl.GL;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLProfile;
+
+import com.jogamp.common.GlueGenVersion;
+import com.jogamp.common.os.Platform;
+import com.jogamp.common.util.VersionUtil;
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.JoglVersion;
+
 import android.os.Bundle;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.ViewGroup.LayoutParams;
+import android.widget.ScrollView;
+import android.widget.TextView;
+
+public class NewtVersionActivity extends NewtBaseActivity {
 
-public class NewtVersionActivity extends NewtVersionBaseActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
-       super.onCreate("NewtVersionActivity - NORMAL MODE", savedInstanceState);
+       super.onCreate(savedInstanceState);
+
+       setFullscreenFeature(getWindow(), true);
+
+       final android.view.ViewGroup viewGroup = new android.widget.FrameLayout(getActivity().getApplicationContext());
+       getWindow().setContentView(viewGroup);
+
+       final TextView tv = new TextView(getActivity());
+       final ScrollView scroller = new ScrollView(getActivity());
+       scroller.addView(tv);
+       viewGroup.addView(scroller, new android.widget.FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, Gravity.TOP|Gravity.LEFT));
+
+       final String info1 = "JOGL Version Info"+Platform.NEWLINE+VersionUtil.getPlatformInfo()+Platform.NEWLINE+GlueGenVersion.getInstance()+Platform.NEWLINE+JoglVersion.getInstance()+Platform.NEWLINE;
+       Log.d(MD.TAG, info1);
+       tv.setText(info1);
+
+       final GLProfile glp;
+       if( GLProfile.isAvailable(GLProfile.GL2ES2) ) {
+           glp = GLProfile.get(GLProfile.GL2ES2);
+       } else if( GLProfile.isAvailable(GLProfile.GL2ES1) ) {
+           glp = GLProfile.get(GLProfile.GL2ES1);
+       } else {
+           glp = null;
+           tv.append("No GLProfile GL2ES2 nor GL2ES1 available!");
+       }
+       if( null != glp ) {
+           // create GLWindow (-> incl. underlying NEWT Display, Screen & Window)
+           GLCapabilities caps = new GLCapabilities(glp);
+           GLWindow glWindow = GLWindow.create(caps);
+           glWindow.setUndecorated(true);
+           glWindow.setSize(32, 32);
+           glWindow.setPosition(0, 0);
+           final android.view.View androidGLView = ((WindowDriver)glWindow.getDelegatedWindow()).getAndroidView();
+           viewGroup.addView(androidGLView, new android.widget.FrameLayout.LayoutParams(glWindow.getWidth(), glWindow.getHeight(), Gravity.BOTTOM|Gravity.RIGHT));
+           registerNEWTWindow(glWindow);
+
+           glWindow.addGLEventListener(new GLEventListener() {
+                public void init(GLAutoDrawable drawable) {
+                    GL gl = drawable.getGL();
+                    final StringBuilder sb = new StringBuilder();
+                    sb.append(JoglVersion.getGLInfo(gl, null, true)).append(Platform.NEWLINE);
+                    sb.append("Requested: ").append(Platform.NEWLINE);
+                    sb.append(drawable.getNativeSurface().getGraphicsConfiguration().getRequestedCapabilities()).append(Platform.NEWLINE).append(Platform.NEWLINE);
+                    sb.append("Chosen: ").append(Platform.NEWLINE);
+                    sb.append(drawable.getChosenGLCapabilities()).append(Platform.NEWLINE).append(Platform.NEWLINE);
+                    final String info2 = sb.toString();
+                    // Log.d(MD.TAG, info2); // too big!
+                    System.err.println(info2);
+                    viewGroup.post(new Runnable() {
+                        public void run() {
+                            tv.append(info2);
+                            viewGroup.removeView(androidGLView);
+                        } } );
+                }
+
+                public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
+                }
+
+                public void display(GLAutoDrawable drawable) {
+                }
+
+                public void dispose(GLAutoDrawable drawable) {
+                }
+            });
+           glWindow.setVisible(true);
+       }
+       Log.d(MD.TAG, "onCreate - X");
    }
 }
diff --git a/src/newt/classes/jogamp/newt/driver/android/NewtVersionActivityLauncher.java b/src/newt/classes/jogamp/newt/driver/android/NewtVersionActivityLauncher.java
index 3374e41..553900f 100644
--- a/src/newt/classes/jogamp/newt/driver/android/NewtVersionActivityLauncher.java
+++ b/src/newt/classes/jogamp/newt/driver/android/NewtVersionActivityLauncher.java
@@ -11,7 +11,7 @@ public class NewtVersionActivityLauncher extends Activity {
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
 
-           final Uri uri = Uri.parse("launch://jogamp.org/jogamp.newt.driver.android.NewtVersionActivity?sys=com.jogamp.common&sys=javax.media.opengl&pkg=com.jogamp.opengl.test");
+           final Uri uri = Uri.parse("launch://jogamp.org/jogamp.newt.driver.android.NewtVersionActivity?sys=com.jogamp.common&sys=javax.media.opengl&pkg=com.jogamp.opengl.test&jogamp.debug=all&nativewindow.debug=all&jogl.debug=all&newt.debug=all");
            final Intent intent = new Intent("org.jogamp.launcher.action.LAUNCH_ACTIVITY_NORMAL", uri);
            Log.d(getClass().getSimpleName(), "Launching Activity: "+intent);
            startActivity (intent);
diff --git a/src/newt/classes/jogamp/newt/driver/android/NewtVersionBaseActivity.java b/src/newt/classes/jogamp/newt/driver/android/NewtVersionBaseActivity.java
deleted file mode 100644
index f24fb20..0000000
--- a/src/newt/classes/jogamp/newt/driver/android/NewtVersionBaseActivity.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/**
- * Copyright 2011 JogAmp Community. 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 JogAmp Community ``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 JogAmp Community OR
- * 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.
- *
- * The views and conclusions contained in the software and documentation are those of the
- * authors and should not be interpreted as representing official policies, either expressed
- * or implied, of JogAmp Community.
- */
-package jogamp.newt.driver.android;
-
-import javax.media.opengl.GL;
-import javax.media.opengl.GLAutoDrawable;
-import javax.media.opengl.GLCapabilities;
-import javax.media.opengl.GLEventListener;
-import javax.media.opengl.GLProfile;
-
-import com.jogamp.common.GlueGenVersion;
-import com.jogamp.common.os.Platform;
-import com.jogamp.common.util.VersionUtil;
-import com.jogamp.newt.opengl.GLWindow;
-import com.jogamp.opengl.JoglVersion;
-
-import android.os.Bundle;
-import android.util.Log;
-import android.view.Gravity;
-import android.view.ViewGroup.LayoutParams;
-import android.widget.ScrollView;
-import android.widget.TextView;
-
-public class NewtVersionBaseActivity extends NewtBaseActivity {
-
-   public void onCreate(String prefix, Bundle savedInstanceState) {
-       super.onCreate(savedInstanceState);
-
-       setFullscreenFeature(getWindow(), true);
-
-       final android.view.ViewGroup viewGroup = new android.widget.FrameLayout(getActivity().getApplicationContext());
-       getWindow().setContentView(viewGroup);
-
-       final TextView tv = new TextView(getActivity());
-       final ScrollView scroller = new ScrollView(getActivity());
-       scroller.addView(tv);
-       viewGroup.addView(scroller, new android.widget.FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, Gravity.TOP|Gravity.LEFT));
-
-       final String info1 = prefix+Platform.NEWLINE+VersionUtil.getPlatformInfo()+Platform.NEWLINE+GlueGenVersion.getInstance()+Platform.NEWLINE+JoglVersion.getInstance()+Platform.NEWLINE;
-       Log.d(MD.TAG, info1);
-       tv.setText(info1);
-
-       final GLProfile glp;
-       if( GLProfile.isAvailable(GLProfile.GL2ES2) ) {
-           glp = GLProfile.get(GLProfile.GL2ES2);
-       } else if( GLProfile.isAvailable(GLProfile.GL2ES1) ) {
-           glp = GLProfile.get(GLProfile.GL2ES1);
-       } else {
-           glp = null;
-           tv.append("No GLProfile GL2ES2 nor GL2ES1 available!");
-       }
-       if( null != glp ) {
-           // create GLWindow (-> incl. underlying NEWT Display, Screen & Window)
-           GLCapabilities caps = new GLCapabilities(glp);
-           GLWindow glWindow = GLWindow.create(caps);
-           glWindow.setUndecorated(true);
-           glWindow.setSize(32, 32);
-           glWindow.setPosition(0, 0);
-           final android.view.View androidGLView = ((WindowDriver)glWindow.getDelegatedWindow()).getAndroidView();
-           viewGroup.addView(androidGLView, new android.widget.FrameLayout.LayoutParams(glWindow.getWidth(), glWindow.getHeight(), Gravity.BOTTOM|Gravity.RIGHT));
-           registerNEWTWindow(glWindow);
-
-           glWindow.addGLEventListener(new GLEventListener() {
-                public void init(GLAutoDrawable drawable) {
-                    GL gl = drawable.getGL();
-                    final StringBuilder sb = new StringBuilder();
-                    sb.append(JoglVersion.getGLInfo(gl, null, true)).append(Platform.NEWLINE);
-                    sb.append("Requested: ").append(Platform.NEWLINE);
-                    sb.append(drawable.getNativeSurface().getGraphicsConfiguration().getRequestedCapabilities()).append(Platform.NEWLINE).append(Platform.NEWLINE);
-                    sb.append("Chosen: ").append(Platform.NEWLINE);
-                    sb.append(drawable.getChosenGLCapabilities()).append(Platform.NEWLINE).append(Platform.NEWLINE);
-                    final String info2 = sb.toString();
-                    // Log.d(MD.TAG, info2); // too big!
-                    System.err.println(info2);
-                    viewGroup.post(new Runnable() {
-                        public void run() {
-                            tv.append(info2);
-                            viewGroup.removeView(androidGLView);
-                        } } );
-                }
-
-                public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
-                }
-
-                public void display(GLAutoDrawable drawable) {
-                }
-
-                public void dispose(GLAutoDrawable drawable) {
-                }
-            });
-           glWindow.setVisible(true);
-       }
-       Log.d(MD.TAG, "onCreate - X");
-   }
-}
diff --git a/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java
index 653cbf9..9af4554 100644
--- a/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java
@@ -3,14 +3,14 @@
  *
  * 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 JogAmp Community ``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 JogAmp Community OR
@@ -20,7 +20,7 @@
  * 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.
- * 
+ *
  * The views and conclusions contained in the software and documentation are those of the
  * authors and should not be interpreted as representing official policies, either expressed
  * or implied, of JogAmp Community.
@@ -74,50 +74,50 @@ import android.view.SurfaceView;
 import android.view.KeyEvent;
 
 
-public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {    
+public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
     static {
         DisplayDriver.initSingleton();
     }
 
     /**
-     * First stage of selecting an Android PixelFormat, 
-     * at construction via {@link SurfaceHolder#setFormat(int)} 
+     * First stage of selecting an Android PixelFormat,
+     * at construction via {@link SurfaceHolder#setFormat(int)}
      * before native realization!
-     * 
+     *
      * @param rCaps requested Capabilities
      * @return An Android PixelFormat number suitable for {@link SurfaceHolder#setFormat(int)}.
      */
     public static final int getSurfaceHolderFormat(CapabilitiesImmutable rCaps) {
         int fmt = PixelFormat.UNKNOWN;
-        
+
         if( !rCaps.isBackgroundOpaque() ) {
             fmt = PixelFormat.TRANSLUCENT;
         } else if( rCaps.getRedBits()<=5 &&
                    rCaps.getGreenBits()<=6 &&
                    rCaps.getBlueBits()<=5 &&
                    rCaps.getAlphaBits()==0 ) {
-            fmt = PixelFormat.RGB_565;            
+            fmt = PixelFormat.RGB_565;
         } else if( rCaps.getAlphaBits()==0 ) {
             fmt = PixelFormat.RGB_888;
-        } else {        
+        } else {
             fmt = PixelFormat.RGBA_8888;
         }
         Log.d(MD.TAG, "getSurfaceHolderFormat: requested: "+rCaps);
         Log.d(MD.TAG, "getSurfaceHolderFormat:  returned: "+fmt);
-        
+
         return fmt;
     }
-    
-    
+
+
     public static final int NATIVE_WINDOW_FORMAT_RGBA_8888          = 1;
     public static final int NATIVE_WINDOW_FORMAT_RGBX_8888          = 2;
     public static final int NATIVE_WINDOW_FORMAT_RGB_565            = 4;
 
     /**
-     * Second stage of selecting an Android PixelFormat, 
+     * Second stage of selecting an Android PixelFormat,
      * at right after native (surface) realization at {@link Callback2#surfaceChanged(SurfaceHolder, int, int, int)}.
      * Selection happens via {@link #setSurfaceVisualID0(long, int)} before native EGL creation.
-     * 
+     *
      * @param androidPixelFormat An Android PixelFormat delivered via {@link Callback2#surfaceChanged(SurfaceHolder, int, int, int)} params.
      * @return A native Android PixelFormat number suitable for {@link #setSurfaceVisualID0(long, int)}.
      */
@@ -127,40 +127,40 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
             case PixelFormat.RGBA_8888:
             case PixelFormat.RGBA_5551:
             case PixelFormat.RGBA_4444:
-                nativePixelFormat = NATIVE_WINDOW_FORMAT_RGBA_8888; 
+                nativePixelFormat = NATIVE_WINDOW_FORMAT_RGBA_8888;
                 break;
-            
+
             case PixelFormat.RGBX_8888:
-            case PixelFormat.RGB_888:   
-                nativePixelFormat = NATIVE_WINDOW_FORMAT_RGBX_8888; 
+            case PixelFormat.RGB_888:
+                nativePixelFormat = NATIVE_WINDOW_FORMAT_RGBX_8888;
                 break;
-                
-            case PixelFormat.RGB_565:   
-            case PixelFormat.RGB_332:   
-                nativePixelFormat = NATIVE_WINDOW_FORMAT_RGB_565; 
+
+            case PixelFormat.RGB_565:
+            case PixelFormat.RGB_332:
+                nativePixelFormat = NATIVE_WINDOW_FORMAT_RGB_565;
                 break;
             default: nativePixelFormat = NATIVE_WINDOW_FORMAT_RGBA_8888;
         }
         Log.d(MD.TAG, "getANativeWindowFormat: android: "+androidPixelFormat+" -> native "+nativePixelFormat);
         return nativePixelFormat;
     }
-    
+
     /**
-     * Final stage of Android PixelFormat operation, 
-     * match the requested Capabilities w/ Android PixelFormat number. 
+     * Final stage of Android PixelFormat operation,
+     * match the requested Capabilities w/ Android PixelFormat number.
      * This is done at native realization @ {@link Callback2#surfaceChanged(SurfaceHolder, int, int, int)}.
-     * 
+     *
      * @param matchFormatPrecise
      * @param format
      * @param rCaps requested Capabilities
      * @return The fixed Capabilities
-     */    
+     */
     public static final CapabilitiesImmutable fixCaps(boolean matchFormatPrecise, int format, CapabilitiesImmutable rCaps) {
-        PixelFormat pf = new PixelFormat(); 
+        PixelFormat pf = new PixelFormat();
         PixelFormat.getPixelFormatInfo(format, pf);
-        final CapabilitiesImmutable res;        
+        final CapabilitiesImmutable res;
         int r, g, b, a;
-        
+
         switch(format) {
             case PixelFormat.RGBA_8888: r=8; g=8; b=8; a=8; break; // NATIVE_WINDOW_FORMAT_RGBA_8888
             case PixelFormat.RGBX_8888: r=8; g=8; b=8; a=0; break; // NATIVE_WINDOW_FORMAT_RGBX_8888
@@ -176,24 +176,24 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
                                rCaps.getGreenBits() > g &&
                                rCaps.getBlueBits()  > b &&
                                rCaps.getAlphaBits() > a ;
-        
+
         if(change) {
             Capabilities nCaps = (Capabilities) rCaps.cloneMutable();
             nCaps.setRedBits(r);
             nCaps.setGreenBits(g);
             nCaps.setBlueBits(b);
             nCaps.setAlphaBits(a);
-            res = nCaps;        
+            res = nCaps;
         } else {
             res = rCaps;
         }
         Log.d(MD.TAG, "fixCaps:    format: "+format);
         Log.d(MD.TAG, "fixCaps: requested: "+rCaps);
         Log.d(MD.TAG, "fixCaps:    chosen: "+res);
-        
+
         return res;
     }
-    
+
     public static final boolean isAndroidFormatTransparent(int aFormat) {
         switch (aFormat) {
             case PixelFormat.TRANSLUCENT:
@@ -202,15 +202,15 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
         }
         return false;
     }
-    
+
     public static Class<?>[] getCustomConstructorArgumentTypes() {
         return new Class<?>[] { Context.class } ;
     }
-    
+
     public WindowDriver() {
         reset();
     }
-    
+
     public void registerActivity(Activity activity) {
         this.activity = activity;
     }
@@ -227,15 +227,15 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
         eglSurface = 0;
         definePosition(0, 0); // default to 0/0
         defineSize(0, 0); // default size -> TBD !
-        
+
         setBrokenFocusChange(true);
     }
-    
+
     private final void setupInputListener(final boolean enable) {
         Log.d(MD.TAG, "setupInputListener(enable "+enable+") - "+Thread.currentThread().getName());
-        
-        final AndroidNewtEventTranslator eventTranslator = 
-                enable ? new AndroidNewtEventTranslator(this, androidView.getContext(), androidView.getHandler()) : null; 
+
+        final AndroidNewtEventTranslator eventTranslator =
+                enable ? new AndroidNewtEventTranslator(this, androidView.getContext(), androidView.getHandler()) : null;
         androidView.setOnTouchListener(eventTranslator);
         androidView.setOnKeyListener(eventTranslator);
         androidView.setOnFocusChangeListener(eventTranslator);
@@ -252,47 +252,47 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
                 } } );
         }
     }
-    
+
     private final void setupAndroidView(Context ctx) {
         androidView = new MSurfaceView(ctx);
-                
+
         final SurfaceHolder sh = androidView.getHolder();
-        sh.addCallback(WindowDriver.this); 
-        sh.setFormat(getSurfaceHolderFormat(getRequestedCapabilities()));        
+        sh.addCallback(WindowDriver.this);
+        sh.setFormat(getSurfaceHolderFormat(getRequestedCapabilities()));
     }
-    
+
     public final SurfaceView getAndroidView() { return androidView; }
-    
+
     @Override
     protected final void instantiationFinished() {
         Log.d(MD.TAG, "instantiationFinished() - "+Thread.currentThread().getName());
-                
-        final Context ctx = StaticContext.getContext();        
+
+        final Context ctx = StaticContext.getContext();
         if(null == ctx) {
             throw new NativeWindowException("No static [Application] Context has been set. Call StaticContext.setContext(Context) first.");
         }
-        
+
         if( null != Looper.myLooper() ) {
             setupAndroidView(ctx);
         }
     }
-    
+
     @Override
     protected final boolean canCreateNativeImpl() {
         Log.d(MD.TAG, "canCreateNativeImpl.0: surfaceHandle ready "+(0!=surfaceHandle)+" - on thread "+Thread.currentThread().getName());
         if(WindowImpl.DEBUG_IMPLEMENTATION) {
             Thread.dumpStack();
         }
-        
+
         if( isFullscreen() ) {
             final MonitorDevice mainMonitor = getMainMonitor();
             final RectangleImmutable viewport = mainMonitor.getViewport();
             definePosition(viewport.getX(), viewport.getY());
             defineSize(viewport.getWidth(), viewport.getHeight());
         }
-        
+
         final boolean b;
-        
+
         if( 0 == surfaceHandle ) {
             // Static ViewGroup, i.e. self contained main code
             final ViewGroup viewGroup = StaticContext.getContentViewGroup();
@@ -305,20 +305,20 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
                             setupAndroidView( StaticContext.getContext() );
                         }
                         viewGroup.addView(androidView, new android.widget.FrameLayout.LayoutParams(getWidth(), getHeight(), Gravity.BOTTOM|Gravity.RIGHT));
-                        Log.d(MD.TAG, "canCreateNativeImpl: added to static ViewGroup - on thread "+Thread.currentThread().getName());                        
+                        Log.d(MD.TAG, "canCreateNativeImpl: added to static ViewGroup - on thread "+Thread.currentThread().getName());
                     } });
                 for(long sleep = TIMEOUT_NATIVEWINDOW; 0<sleep && 0 == surfaceHandle; sleep-=10 ) {
                     try { Thread.sleep(10); } catch (InterruptedException ie) {}
                 }
                 b = 0 != surfaceHandle;
-                Log.d(MD.TAG, "canCreateNativeImpl: surfaceHandle ready(2) "+b+" - on thread "+Thread.currentThread().getName());                
+                Log.d(MD.TAG, "canCreateNativeImpl: surfaceHandle ready(2) "+b+" - on thread "+Thread.currentThread().getName());
             } else {
                 // No surfaceHandle defined, No static ViewGroup to add ourselves
                 b = false;
             }
         } else {
             // surfaceHandle already defined
-            b = true; 
+            b = true;
         }
         return b;
     }
@@ -330,8 +330,9 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
         final AbstractGraphicsScreen aScreen = getScreen().getGraphicsScreen();
         final EGLGraphicsDevice aDevice = (EGLGraphicsDevice) aScreen.getDevice();
         final EGLGraphicsDevice eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(aDevice.getNativeDisplayID(), aDevice.getConnection(), aDevice.getUnitID());
+        eglDevice.open();
         final DefaultGraphicsScreen eglScreen = new DefaultGraphicsScreen(eglDevice, aScreen.getIndex());
-        
+
         Log.d(MD.TAG, "createNativeImpl 0 - eglDevice 0x"+Integer.toHexString(eglDevice.hashCode())+", "+eglDevice+", surfaceHandle 0x"+Long.toHexString(surfaceHandle)+
                     ", format [a "+androidFormat+", n "+nativeFormat+"], "+getX()+"/"+getY()+" "+getWidth()+"x"+getHeight()+" - on thread "+Thread.currentThread().getName());
 
@@ -341,9 +342,9 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
         if(0==surfaceHandle) {
             throw new InternalError("surfaceHandle null");
         }
-       
+
         final EGLGraphicsConfiguration eglConfig = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(
-                capsByFormat, (GLCapabilitiesImmutable) getRequestedCapabilities(), 
+                capsByFormat, (GLCapabilitiesImmutable) getRequestedCapabilities(),
                 (GLCapabilitiesChooser)capabilitiesChooser, eglScreen, nativeFormat, isAndroidFormatTransparent(androidFormat));
         if (eglConfig == null) {
             throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
@@ -355,36 +356,36 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
         if(VisualIDHolder.VID_UNDEFINED != nativeVisualID) {
             setSurfaceVisualID0(surfaceHandle, nativeVisualID);
         }
-        
+
         eglSurface = EGL.eglCreateWindowSurface(eglDevice.getHandle(), eglConfig.getNativeConfig(), surfaceHandle, null);
         if (EGL.EGL_NO_SURFACE==eglSurface) {
             throw new NativeWindowException("Creation of window surface failed: "+eglConfig+", surfaceHandle 0x"+Long.toHexString(surfaceHandle)+", error "+toHexString(EGL.eglGetError()));
         }
-                
+
         // propagate data ..
         setGraphicsConfiguration(eglConfig);
         setWindowHandle(surfaceHandle);
         visibleChanged(false, true);
         focusChanged(false, true);
-        
+
         setupInputListener(true);
-        
+
         Log.d(MD.TAG, "createNativeImpl X: eglDevice 0x"+Integer.toHexString(eglDevice.hashCode())+", "+eglDevice+", eglSurfaceHandle 0x"+Long.toHexString(eglSurface));
     }
 
     @Override
     protected final void closeNativeImpl() {
         final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) getGraphicsConfiguration().getScreen().getDevice();
-        
+
         Log.d(MD.TAG, "closeNativeImpl 0 - eglDevice 0x"+Integer.toHexString(eglDevice.hashCode())+", "+eglDevice+", surfaceHandle 0x"+Long.toHexString(surfaceHandle)+
                     ", eglSurfaceHandle 0x"+Long.toHexString(eglSurface)+
                     ", format [a "+androidFormat+", n "+nativeFormat+"], "+getX()+"/"+getY()+" "+getWidth()+"x"+getHeight()+" - on thread "+Thread.currentThread().getName());
         if(WindowImpl.DEBUG_IMPLEMENTATION) {
             Thread.dumpStack();
         }
-        
+
         setupInputListener(false);
-        
+
         if(0 != eglSurface) {
             try {
                 if (!EGL.eglDestroySurface(eglDevice.getHandle(), eglSurface)) {
@@ -396,9 +397,9 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
             } finally {
                 eglSurface = 0;
             }
-        }        
+        }
         release0(surfaceHandle);
-        
+
         eglDevice.close();
 
         if( null != androidView ) {
@@ -414,7 +415,7 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
                 }
             }
         }
-        
+
         surface = null;
         surfaceHandle = 0;
     }
@@ -423,21 +424,21 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
     public final long getSurfaceHandle() {
         return eglSurface;
     }
-    
+
     /**
      * <p>
      * Accessible protected method!
      * </p>
-     * 
+     *
      * {@inheritDoc}
      */
     @Override
     public final void focusChanged(boolean defer, boolean focusGained) {
         super.focusChanged(defer, focusGained);
     }
-    
+
     @Override
-    protected final void requestFocusImpl(boolean reparented) { 
+    protected final void requestFocusImpl(boolean reparented) {
         if(null != androidView) {
             Log.d(MD.TAG, "requestFocusImpl: reparented "+reparented);
             androidView.post(new Runnable() {
@@ -450,9 +451,9 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
     }
 
     @Override
-    protected final boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) {        
+    protected final boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) {
         boolean res = true;
-        
+
         if( 0 != ( FLAG_CHANGE_FULLSCREEN & flags) ) {
             Log.d(MD.TAG, "reconfigureWindowImpl.setFullscreen post creation (setContentView()) n/a");
             return false;
@@ -474,7 +475,7 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
             }
         }
         if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) {
-            visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags));            
+            visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags));
         }
         return res;
     }
@@ -486,22 +487,22 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
 
     @Override
     protected final void updateInsetsImpl(Insets insets) {
-        // nop ..        
+        // nop ..
     }
-    
+
     //----------------------------------------------------------------------
-    // Virtual On-Screen Keyboard / SoftInput 
+    // Virtual On-Screen Keyboard / SoftInput
     //
-    
+
     private class KeyboardVisibleReceiver extends ResultReceiver {
         public KeyboardVisibleReceiver() {
             super(null);
         }
-        
-        @Override 
+
+        @Override
         public void onReceiveResult(int r, Bundle data) {
             boolean v = false;
-        
+
             switch(r) {
                 case InputMethodManager.RESULT_UNCHANGED_SHOWN:
                 case InputMethodManager.RESULT_SHOWN:
@@ -510,14 +511,14 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
                 case InputMethodManager.RESULT_HIDDEN:
                 case InputMethodManager.RESULT_UNCHANGED_HIDDEN:
                     v = false;
-                    break;            
+                    break;
             }
             Log.d(MD.TAG, "keyboardVisible: "+v);
             keyboardVisibilityChanged(v);
         }
     }
-    private KeyboardVisibleReceiver keyboardVisibleReceiver = new KeyboardVisibleReceiver();
-    
+    private final KeyboardVisibleReceiver keyboardVisibleReceiver = new KeyboardVisibleReceiver();
+
     @Override
     protected final boolean setKeyboardVisibleImpl(boolean visible) {
         if(null != androidView) {
@@ -536,13 +537,13 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
             return false; // nop
         }
     }
-    
+
     //----------------------------------------------------------------------
-    // Surface Callbacks 
+    // Surface Callbacks
     //
-    
+
     @Override
-    public final void surfaceCreated(SurfaceHolder holder) {    
+    public final void surfaceCreated(SurfaceHolder holder) {
         Log.d(MD.TAG, "surfaceCreated: "+getX()+"/"+getY()+" "+getWidth()+"x"+getHeight()+" - on thread "+Thread.currentThread().getName());
     }
 
@@ -570,14 +571,14 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
         if(0>getX() || 0>getY()) {
             positionChanged(false, 0, 0);
         }
-        
+
         if(0 == surfaceHandle) {
             androidFormat = aFormat;
             surface = aHolder.getSurface();
             surfaceHandle = getSurfaceHandle0(surface);
             acquire0(surfaceHandle);
             final int aNativeWindowFormat = getANativeWindowFormat(androidFormat);
-            setSurfaceVisualID0(surfaceHandle, aNativeWindowFormat);            
+            setSurfaceVisualID0(surfaceHandle, aNativeWindowFormat);
             nativeFormat = getSurfaceVisualID0(surfaceHandle);
             Log.d(MD.TAG, "surfaceChanged: androidFormat "+androidFormat+" -- (set-native "+aNativeWindowFormat+") --> nativeFormat "+nativeFormat);
 
@@ -585,12 +586,12 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
             final int nHeight = getHeight0(surfaceHandle);
             capsByFormat = (GLCapabilitiesImmutable) fixCaps(true /* matchFormatPrecise */, nativeFormat, getRequestedCapabilities());
             sizeChanged(false, nWidth, nHeight, false);
-    
+
             Log.d(MD.TAG, "surfaceRealized: isValid: "+surface.isValid()+
                           ", new surfaceHandle 0x"+Long.toHexString(surfaceHandle)+
                           ", format [a "+androidFormat+"/n "+nativeFormat+"], "+
                           getX()+"/"+getY()+" "+nWidth+"x"+nHeight+", visible: "+isVisible());
-    
+
             if(isVisible()) {
                setVisible(false, true);
             }
@@ -599,7 +600,7 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
         windowRepaint(0, 0, aWidth, aHeight);
         Log.d(MD.TAG, "surfaceChanged: X");
     }
-    
+
     @Override
     public final void surfaceDestroyed(SurfaceHolder holder) {
         Log.d(MD.TAG, "surfaceDestroyed - on thread "+Thread.currentThread().getName());
@@ -612,14 +613,14 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
         Log.d(MD.TAG, "surfaceRedrawNeeded  - on thread "+Thread.currentThread().getName());
         windowRepaint(0, 0, getWidth(), getHeight());
     }
-        
+
     protected boolean handleKeyCodeBack(KeyEvent.DispatcherState state, android.view.KeyEvent event) {
         if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
             Log.d(MD.TAG, "handleKeyCodeBack.0 : "+event);
             state.startTracking(event, this);
         } else if (event.getAction() == KeyEvent.ACTION_UP && !event.isCanceled() && state.isTracking(event)) {
-            // Since we cannot trust the visibility state 'completly', 
-            // assume an already invisible state if the invisible operation fails. 
+            // Since we cannot trust the visibility state 'completly',
+            // assume an already invisible state if the invisible operation fails.
             final boolean wasVisible = setKeyboardVisibleImpl(false);
             Log.d(MD.TAG, "handleKeyCodeBack.1 : wasVisible "+wasVisible+": "+event);
             keyboardVisibilityChanged(false);
@@ -635,7 +636,7 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
             } else {
                 Log.d(MD.TAG, "handleKeyCodeBack.X1 : "+event);
                 windowDestroyNotify(true);
-                // -> default BACK action, usually activity.finish() 
+                // -> default BACK action, usually activity.finish()
             }
         }
         return false; // continue w/ further processing
@@ -646,7 +647,7 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
         enqueueEvent(false, eDown);
         enqueueEvent(false, eUp);
     }
-    
+
     @Override
     protected void consumeKeyEvent(com.jogamp.newt.event.KeyEvent e) {
         super.consumeKeyEvent(e); // consume event, i.e. call all KeyListener
@@ -659,7 +660,7 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
                 triggerHome();
             }
         }
-    }    
+    }
     private void triggerHome() {
        Context ctx = StaticContext.getContext();
        if(null == ctx) {
@@ -669,7 +670,7 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
        showOptions.addCategory(Intent.CATEGORY_HOME);
        ctx.startActivity(showOptions);
     }
-    
+
     private boolean added2StaticViewGroup;
     private MSurfaceView androidView;
     private int nativeFormat; // chosen current native PixelFormat (suitable for EGL)
@@ -678,7 +679,7 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
     private Surface surface;
     private volatile long surfaceHandle;
     private long eglSurface;
-    
+
     class MSurfaceView extends SurfaceView {
         public MSurfaceView (Context ctx) {
             super(ctx);
@@ -696,7 +697,7 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
                 }
             }
             return false; // cont. processing
-        }        
+        }
     }
     //----------------------------------------------------------------------
     // Internals only
diff --git a/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/DisplayDriver.java
index d8d93f1..178bb70 100644
--- a/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/DisplayDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/DisplayDriver.java
@@ -28,15 +28,28 @@
 
 package jogamp.newt.driver.bcm.vc.iv;
 
+import java.net.URLConnection;
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+
 import javax.media.nativewindow.AbstractGraphicsDevice;
 import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.util.PixelFormat;
+
+import com.jogamp.common.nio.Buffers;
+import com.jogamp.common.util.IOUtil;
+import com.jogamp.opengl.util.PNGPixelRect;
 
 import jogamp.newt.DisplayImpl;
 import jogamp.newt.NEWTJNILibLoader;
+import jogamp.newt.PointerIconImpl;
+import jogamp.newt.driver.linux.LinuxMouseTracker;
 import jogamp.opengl.egl.EGL;
 import jogamp.opengl.egl.EGLDisplayUtil;
 
 public class DisplayDriver extends DisplayImpl {
+    static final PNGPixelRect defaultPointerIconImage;
+
     static {
         NEWTJNILibLoader.loadNEWT();
 
@@ -49,6 +62,18 @@ public class DisplayDriver extends DisplayImpl {
         if (!WindowDriver.initIDs()) {
             throw new NativeWindowException("Failed to initialize bcm.vc.iv Window jmethodIDs");
         }
+
+        PNGPixelRect image = null;
+        if( DisplayImpl.isPNGUtilAvailable() ) {
+            final IOUtil.ClassResources res = new IOUtil.ClassResources(DisplayDriver.class, new String[] { "newt/data/pointer-grey-alpha-16x24.png" } );
+            try {
+                final URLConnection urlConn = res.resolve(0);
+                image = PNGPixelRect.read(urlConn.getInputStream(), PixelFormat.BGRA8888, false /* directBuffer */, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        defaultPointerIconImage = image;
     }
 
     public static void initSingleton() {
@@ -57,25 +82,128 @@ public class DisplayDriver extends DisplayImpl {
 
 
     public DisplayDriver() {
+        bcmHandle = 0;
+        activePointerIcon = 0;
+        activePointerIconVisible = false;
     }
 
     @Override
     protected void createNativeImpl() {
         // FIXME: map name to EGL_*_DISPLAY
+        bcmHandle = OpenBCMDisplay0();
         aDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
+        aDevice.open();
+
+        defaultPointerIcon = (PointerIconImpl) createPointerIcon(defaultPointerIconImage, 0, 0);
+        if( DEBUG_POINTER_ICON ) {
+            System.err.println("Display.PointerIcon.createDefault: "+defaultPointerIcon);
+        }
+        if( null != defaultPointerIcon ) {
+            final LinuxMouseTracker lmt = LinuxMouseTracker.getSingleton();
+            setPointerIconActive(defaultPointerIcon.getHandle(), lmt.getLastX(), lmt.getLastY());
+        }
     }
+    private PointerIconImpl defaultPointerIcon = null;
 
     @Override
     protected void closeNativeImpl(AbstractGraphicsDevice aDevice) {
         aDevice.close();
+        CloseBCMDisplay0(bcmHandle);
+        bcmHandle = 0;
     }
 
+    /* pp */ final long getBCMHandle() { return bcmHandle; }
+
     @Override
     protected void dispatchMessagesNative() {
-        DispatchMessages();
+        DispatchMessages0();
+    }
+
+    // @Override
+    // public final PixelFormat getNativePointerIconPixelFormat() { return PixelFormat.BGRA8888; }
+
+    @Override
+    protected final long createPointerIconImpl(PixelFormat pixelformat, int width, int height, final ByteBuffer pixels, final int hotX, final int hotY) {
+        return CreatePointerIcon(bcmHandle, pixels, width, height, hotX, hotY);
+    }
+
+    @Override
+    protected final void destroyPointerIconImpl(final long displayHandle, long piHandle) {
+        DestroyPointerIcon0(piHandle);
+    }
+
+    /* pp */ void setPointerIconActive(long piHandle, final int x, final int y) {
+        synchronized(pointerIconSync) {
+            if( DEBUG_POINTER_ICON ) {
+                System.err.println("Display.PointerIcon.set.0: active ["+toHexString(activePointerIcon)+", visible "+activePointerIconVisible+"] -> "+toHexString(piHandle));
+            }
+            if( 0 != activePointerIcon && activePointerIconVisible ) {
+                SetPointerIcon0(bcmHandle, activePointerIcon, false, x, y);
+            }
+            if( 0 == piHandle && null != defaultPointerIcon ) {
+                piHandle = defaultPointerIcon.getHandle();
+            }
+            if( 0 != piHandle ) {
+                SetPointerIcon0(bcmHandle, piHandle, true, x, y);
+                activePointerIconVisible = true;
+            } else {
+                activePointerIconVisible = false;
+            }
+            activePointerIcon = piHandle;
+            if( DEBUG_POINTER_ICON ) {
+                System.err.println("Display.PointerIcon.set.X: active ["+toHexString(activePointerIcon)+", visible "+activePointerIconVisible+"]");
+            }
+        }
+    }
+    /* pp */ void setActivePointerIconVisible(final boolean visible, final int x, final int y) {
+        synchronized(pointerIconSync) {
+            if( DEBUG_POINTER_ICON ) {
+                System.err.println("Display.PointerIcon.visible: active ["+toHexString(activePointerIcon)+", visible "+activePointerIconVisible+"] -> visible "+visible);
+            }
+            if( activePointerIconVisible != visible ) {
+                if( 0 != activePointerIcon ) {
+                    SetPointerIcon0(bcmHandle, activePointerIcon, visible, x, y);
+                }
+                activePointerIconVisible = visible;
+            }
+        }
+    }
+    /* pp */ void moveActivePointerIcon(final int x, final int y) {
+        synchronized(pointerIconSync) {
+            if( DEBUG_POINTER_ICON ) {
+                System.err.println("Display.PointerIcon.move: active ["+toHexString(activePointerIcon)+", visible "+activePointerIconVisible+"], "+x+"/"+y);
+            }
+            if( 0 != activePointerIcon && activePointerIconVisible ) {
+                MovePointerIcon0(activePointerIcon, x, y);
+            }
+        }
     }
 
+    //----------------------------------------------------------------------
+    // Internals only
+    //
+
     protected static native boolean initIDs();
-    private native void DispatchMessages();
+    private static native long OpenBCMDisplay0();
+    private static native void CloseBCMDisplay0(long handle);
+
+    private static long CreatePointerIcon(long bcmHandle, Buffer pixels, int width, int height, int hotX, int hotY) {
+        final boolean pixels_is_direct = Buffers.isDirect(pixels);
+        return CreatePointerIcon0(pixels_is_direct ? pixels : Buffers.getArray(pixels),
+                                  pixels_is_direct ? Buffers.getDirectBufferByteOffset(pixels) : Buffers.getIndirectBufferByteOffset(pixels),
+                                  pixels_is_direct,
+                                  width, height, hotX, hotY);
+    }
+    private static native long CreatePointerIcon0(Object pixels, int pixels_byte_offset, boolean pixels_is_direct, int width, int height, int hotX, int hotY);
+    private static native void DestroyPointerIcon0(long handle);
+    private static native void SetPointerIcon0(long bcmHandle, long handle, boolean enable, int x, int y);
+    private static native void MovePointerIcon0(long handle, int x, int y);
+
+    private static native void DispatchMessages0();
+
+    private long bcmHandle;
+    private long activePointerIcon;
+    private boolean activePointerIconVisible;
+    private final Object pointerIconSync = new Object();
 }
 
diff --git a/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/WindowDriver.java
index 4d49777..c3cb8a8 100644
--- a/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/WindowDriver.java
@@ -38,8 +38,11 @@ import javax.media.nativewindow.VisualIDHolder;
 import javax.media.nativewindow.util.Insets;
 import javax.media.nativewindow.util.Point;
 
+import com.jogamp.common.util.IntBitfield;
 import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
+import com.jogamp.newt.event.MouseEvent;
 
+import jogamp.newt.PointerIconImpl;
 import jogamp.newt.WindowImpl;
 import jogamp.newt.driver.linux.LinuxEventDeviceTracker;
 import jogamp.newt.driver.linux.LinuxMouseTracker;
@@ -53,6 +56,11 @@ public class WindowDriver extends WindowImpl {
     }
 
     public WindowDriver() {
+        linuxMouseTracker = LinuxMouseTracker.getSingleton();
+        linuxEventDeviceTracker = LinuxEventDeviceTracker.getSingleton();
+        layer = -1;
+        nativeWindowHandle = 0;
+        windowHandleClose = 0;
     }
 
     @Override
@@ -60,11 +68,35 @@ public class WindowDriver extends WindowImpl {
         if(0!=getParentWindowHandle()) {
             throw new RuntimeException("Window parenting not supported (yet)");
         }
+        synchronized( layerSync ) {
+            if( layerCount >= MAX_LAYERS ) {
+                throw new RuntimeException("Max windows reached: "+layerCount+" ( "+MAX_LAYERS+" )");
+            }
+            for(int i=0; 0 > layer && i<MAX_LAYERS; i++) {
+                if( !usedLayers.get(nextLayer) ) {
+                    layer = nextLayer;
+                    usedLayers.put(layer, true);
+                    layerCount++;
+                }
+                nextLayer++;
+                if( MAX_LAYERS == nextLayer ) {
+                    nextLayer=0;
+                }
+            }
+            // System.err.println("XXX.Open capacity "+usedLayers.capacity()+", count "+usedLayers.getBitCount());
+        }
+        if( 0 > layer ) {
+            throw new InternalError("Could not find a free layer: count "+layerCount+", max "+MAX_LAYERS);
+        }
+        final ScreenDriver screen = (ScreenDriver) getScreen();
+        final DisplayDriver display = (DisplayDriver) screen.getDisplay();
+
         // Create own screen/device resource instance allowing independent ownership,
         // while still utilizing shared EGL resources.
-        final AbstractGraphicsScreen aScreen = getScreen().getGraphicsScreen();
+        final AbstractGraphicsScreen aScreen = screen.getGraphicsScreen();
         final EGLGraphicsDevice aDevice = (EGLGraphicsDevice) aScreen.getDevice();
         final EGLGraphicsDevice eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(aDevice.getNativeDisplayID(), aDevice.getConnection(), aDevice.getUnitID());
+        eglDevice.open();
         final DefaultGraphicsScreen eglScreen = new DefaultGraphicsScreen(eglDevice, aScreen.getIndex());
 
         final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice(), capsRequested).chooseGraphicsConfiguration(
@@ -78,34 +110,42 @@ public class WindowDriver extends WindowImpl {
             chosenCaps.setBackgroundOpaque(capsRequested.isBackgroundOpaque());
         }
         setGraphicsConfiguration(cfg);
-        nativeWindowHandle = CreateWindow(getWidth(), getHeight(), chosenCaps.isBackgroundOpaque(), chosenCaps.getAlphaBits());
+        nativeWindowHandle = CreateWindow0(display.getBCMHandle(), layer, getX(), getY(), getWidth(), getHeight(),
+                                           chosenCaps.isBackgroundOpaque(), chosenCaps.getAlphaBits());
         if (nativeWindowHandle == 0) {
             throw new NativeWindowException("Error creating egl window: "+cfg);
         }
-        setVisible0(nativeWindowHandle, false);
         setWindowHandle(nativeWindowHandle);
         if (0 == getWindowHandle()) {
             throw new NativeWindowException("Error native Window Handle is null");
         }
         windowHandleClose = nativeWindowHandle;
-        addWindowListener(LinuxMouseTracker.getSingleton());
-        addWindowListener(LinuxEventDeviceTracker.getSingleton());
+
+        addWindowListener(linuxEventDeviceTracker);
+        addWindowListener(linuxMouseTracker);
         focusChanged(false, true);
     }
 
     @Override
     protected void closeNativeImpl() {
+        final DisplayDriver display = (DisplayDriver) getScreen().getDisplay();
         final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) getGraphicsConfiguration().getScreen().getDevice();
 
-        removeWindowListener(LinuxMouseTracker.getSingleton());
-        removeWindowListener(LinuxEventDeviceTracker.getSingleton());
+        removeWindowListener(linuxMouseTracker);
+        removeWindowListener(linuxEventDeviceTracker);
 
         if(0!=windowHandleClose) {
-            CloseWindow(windowHandleClose, windowUserData);
-            windowUserData=0;
+            CloseWindow0(display.getBCMHandle(), windowHandleClose);
         }
 
         eglDevice.close();
+
+        synchronized( layerSync ) {
+            usedLayers.put(layer, false);
+            layerCount--;
+            layer = -1;
+            // System.err.println("XXX.Close capacity "+usedLayers.capacity()+", count "+usedLayers.getBitCount());
+        }
     }
 
     @Override
@@ -115,35 +155,7 @@ public class WindowDriver extends WindowImpl {
 
     @Override
     protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) {
-        if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) {
-            setVisible0(nativeWindowHandle, 0 != ( FLAG_IS_VISIBLE & flags));
-            visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags));
-        }
-
-        if(0!=nativeWindowHandle) {
-            if(0 != ( FLAG_CHANGE_FULLSCREEN & flags)) {
-                final boolean fs = 0 != ( FLAG_IS_FULLSCREEN & flags) ;
-                setFullScreen0(nativeWindowHandle, fs);
-                if(fs) {
-                    return true;
-                }
-            }
-            // int _x=(x>=0)?x:this.x;
-            // int _y=(x>=0)?y:this.y;
-            width=(width>0)?width:getWidth();
-            height=(height>0)?height:getHeight();
-            if(width>0 || height>0) {
-                setSize0(nativeWindowHandle, width, height);
-            }
-            if(x>=0 || y>=0) {
-                System.err.println("setPosition n/a in KD");
-            }
-        }
-
-        if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) {
-            visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags));
-        }
-
+        reconfigure0(nativeWindowHandle, x, y, width, height, flags);
         return true;
     }
 
@@ -157,23 +169,47 @@ public class WindowDriver extends WindowImpl {
         // nop ..
     }
 
+    @Override
+    public final void sendMouseEvent(final short eventType, final int modifiers,
+                                     final int x, final int y, final short button, final float rotation) {
+        if( MouseEvent.EVENT_MOUSE_MOVED == eventType ) {
+            final DisplayDriver display = (DisplayDriver) getScreen().getDisplay();
+            display.moveActivePointerIcon(x, y);
+        }
+        super.sendMouseEvent(eventType, modifiers, x, y, button, rotation);
+    }
+
+    @Override
+    protected void setPointerIconImpl(final PointerIconImpl pi) {
+        final DisplayDriver display = (DisplayDriver) getScreen().getDisplay();
+        display.setPointerIconActive(null != pi ? pi.validatedHandle() : 0, linuxMouseTracker.getLastX(), linuxMouseTracker.getLastY());
+    }
+
+    @Override
+    protected boolean setPointerVisibleImpl(final boolean pointerVisible) {
+        final DisplayDriver display = (DisplayDriver) getScreen().getDisplay();
+        display.setActivePointerIconVisible(pointerVisible, linuxMouseTracker.getLastX(), linuxMouseTracker.getLastY());
+        return true;
+    }
+
     //----------------------------------------------------------------------
     // Internals only
     //
+    private final LinuxMouseTracker linuxMouseTracker;
+    private final LinuxEventDeviceTracker linuxEventDeviceTracker;
 
     protected static native boolean initIDs();
-    private        native long CreateWindow(int width, int height, boolean opaque, int alphaBits);
-    private        native long RealizeWindow(long eglWindowHandle);
-    private        native int  CloseWindow(long eglWindowHandle, long userData);
-    private        native void setVisible0(long eglWindowHandle, boolean visible);
-    private        native void setSize0(long eglWindowHandle, int width, int height);
-    private        native void setFullScreen0(long eglWindowHandle, boolean fullscreen);
-
-    private void windowCreated(long userData) {
-        windowUserData=userData;
-    }
+    private        native long CreateWindow0(long bcmDisplay, int layer, int x, int y, int width, int height, boolean opaque, int alphaBits);
+    private        native void CloseWindow0(long bcmDisplay, long eglWindowHandle);
+    private        native void reconfigure0(long eglWindowHandle, int x, int y, int width, int height, int flags);
 
+    private int    layer;
     private long   nativeWindowHandle;
     private long   windowHandleClose;
-    private long   windowUserData;
+
+    private static int nextLayer = 0;
+    private static int layerCount = 0;
+    private static final int MAX_LAYERS = 32;
+    private static final IntBitfield usedLayers = new IntBitfield(MAX_LAYERS);
+    private static final Object layerSync = new Object();
 }
diff --git a/src/newt/classes/jogamp/newt/driver/kd/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/kd/DisplayDriver.java
index 929688b..6c70614 100644
--- a/src/newt/classes/jogamp/newt/driver/kd/DisplayDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/kd/DisplayDriver.java
@@ -63,6 +63,7 @@ public class DisplayDriver extends DisplayImpl {
     protected void createNativeImpl() {
         // FIXME: map name to EGL_*_DISPLAY
         aDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
+        aDevice.open();
     }
 
     @Override
diff --git a/src/newt/classes/jogamp/newt/driver/linux/LinuxMouseTracker.java b/src/newt/classes/jogamp/newt/driver/linux/LinuxMouseTracker.java
index 1e314b7..9d7b893 100644
--- a/src/newt/classes/jogamp/newt/driver/linux/LinuxMouseTracker.java
+++ b/src/newt/classes/jogamp/newt/driver/linux/LinuxMouseTracker.java
@@ -68,9 +68,14 @@ public class LinuxMouseTracker implements WindowListener {
     private short buttonDown = 0;
     private int old_x = 0;
     private int old_y = 0;
+    private volatile int lastFocusedX = 0;
+    private volatile int lastFocusedY = 0;
     private short old_buttonDown = 0;
     private WindowImpl focusedWindow = null;
-    private MouseDevicePoller mouseDevicePoller = new MouseDevicePoller();
+    private final MouseDevicePoller mouseDevicePoller = new MouseDevicePoller();
+
+    public final int getLastX() { return lastFocusedX; }
+    public final int getLastY() { return lastFocusedY; }
 
     @Override
     public void windowResized(WindowEvent e) { }
@@ -179,10 +184,11 @@ public class LinuxMouseTracker implements WindowListener {
                     if( y >= focusedWindow.getScreen().getHeight() ) {
                         y = focusedWindow.getScreen().getHeight() - 1;
                     }
-                    int wx = x - focusedWindow.getX(), wy = y - focusedWindow.getY();
-
+                    final int wx = x - focusedWindow.getX(), wy = y - focusedWindow.getY();
                     if(old_x != x || old_y != y) {
                         // mouse moved
+                        lastFocusedX = wx;
+                        lastFocusedY = wy;
                         focusedWindow.sendMouseEvent(MouseEvent.EVENT_MOUSE_MOVED, 0, wx, wy, (short)0, 0 );
                     }
 
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java
index c44685d..d850a18 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java
@@ -34,15 +34,26 @@
 
 package jogamp.newt.driver.macosx;
 
+import java.net.URLConnection;
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+
 import javax.media.nativewindow.AbstractGraphicsDevice;
 import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.util.PixelFormat;
 
+import com.jogamp.common.nio.Buffers;
+import com.jogamp.common.util.IOUtil;
 import com.jogamp.nativewindow.macosx.MacOSXGraphicsDevice;
+import com.jogamp.newt.NewtFactory;
+import com.jogamp.opengl.util.PNGPixelRect;
 
 import jogamp.newt.DisplayImpl;
 import jogamp.newt.NEWTJNILibLoader;
 
 public class DisplayDriver extends DisplayImpl {
+    private static final PNGPixelRect defaultIconData;
+
     static {
         NEWTJNILibLoader.loadNEWT();
 
@@ -52,6 +63,27 @@ public class DisplayDriver extends DisplayImpl {
         if(!WindowDriver.initIDs0()) {
             throw new NativeWindowException("Failed to initialize jmethodIDs");
         }
+        {
+            PNGPixelRect image=null;
+            if( DisplayImpl.isPNGUtilAvailable() ) {
+                try {
+                    // NOTE: MUST BE DIRECT BUFFER, since NSBitmapImageRep uses buffer directly!
+                    final IOUtil.ClassResources iconRes = NewtFactory.getWindowIcons();
+                    final URLConnection urlConn = iconRes.resolve(iconRes.resourceCount()-1);
+                    image = PNGPixelRect.read(urlConn.getInputStream(), PixelFormat.BGRA8888, true /* directBuffer */, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+            defaultIconData = image;
+            if( null != defaultIconData ) {
+                final Buffer pixels = defaultIconData.getPixels();
+                DisplayDriver.setAppIcon0(
+                      pixels, Buffers.getDirectBufferByteOffset(pixels), true /* pixels_is_direct */,
+                      defaultIconData.getSize().getWidth(), defaultIconData.getSize().getHeight());
+            }
+        }
+
         if(DEBUG) {
             System.err.println("MacDisplay.init App and IDs OK "+Thread.currentThread().getName());
         }
@@ -79,6 +111,27 @@ public class DisplayDriver extends DisplayImpl {
         aDevice.close();
     }
 
+    /**
+     * {@inheritDoc}
+     * <p>
+     * NOTE: MUST BE DIRECT BUFFER, since NSBitmapImageRep uses buffer directly!
+     * </p>
+     */
+    @Override
+    public final boolean getNativePointerIconForceDirectNIO() { return true; }
+
+    @Override
+    protected final long createPointerIconImpl(PixelFormat pixelformat, int width, int height, final ByteBuffer pixels, final int hotX, final int hotY) {
+        return createPointerIcon0(
+              pixels, Buffers.getDirectBufferByteOffset(pixels), true /* pixels_is_direct */,
+              width, height, hotX, hotY);
+    }
+
+    @Override
+    protected final void destroyPointerIconImpl(final long displayHandle, long piHandle) {
+        destroyPointerIcon0(piHandle);
+    }
+
     public static void runNSApplication() {
         runNSApplication0();
     }
@@ -89,5 +142,9 @@ public class DisplayDriver extends DisplayImpl {
     private static native boolean initNSApplication0();
     private static native void runNSApplication0();
     private static native void stopNSApplication0();
+    /* pp */ static native void setAppIcon0(Object pixels, int pixels_byte_offset, boolean pixels_is_direct, int width, int height);
+    private static native long createPointerIcon0(Object pixels, int pixels_byte_offset, boolean pixels_is_direct, int width, int height, int hotX, int hotY);
+    private static native long destroyPointerIcon0(long handle);
+
 }
 
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java
index 641d743..e2a57de 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java
@@ -45,6 +45,7 @@ import javax.media.nativewindow.util.Point;
 import javax.media.nativewindow.util.PointImmutable;
 
 import jogamp.nativewindow.macosx.OSXUtil;
+import jogamp.newt.PointerIconImpl;
 import jogamp.newt.WindowImpl;
 import jogamp.newt.driver.DriverClearFocus;
 import jogamp.newt.driver.DriverUpdatePosition;
@@ -392,17 +393,35 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
     }
 
     @Override
+    protected void setPointerIconImpl(final PointerIconImpl pi) {
+        if( !isOffscreenInstance ) {
+            final long piHandle = null != pi ? pi.validatedHandle() : 0;
+            OSXUtil.RunOnMainThread(true, new Runnable() { // waitUntildone due to PointerIconImpl's Lifecycle !
+                @Override
+                public void run() {
+                    setPointerIcon0(getWindowHandle(), piHandle);
+                } } );
+        }
+    }
+
+    @Override
     protected boolean setPointerVisibleImpl(final boolean pointerVisible) {
         if( !isOffscreenInstance ) {
-            return setPointerVisible0(getWindowHandle(), hasFocus(), pointerVisible);
-        } // else may need offscreen solution ? FIXME
+            OSXUtil.RunOnMainThread(false, new Runnable() {
+                @Override
+                public void run() {
+                    setPointerVisible0(getWindowHandle(), hasFocus(), pointerVisible);
+                } } );
+            return true;
+        }
         return false;
     }
 
     @Override
     protected boolean confinePointerImpl(final boolean confine) {
         if( !isOffscreenInstance ) {
-            return confinePointer0(getWindowHandle(), confine);
+            confinePointer0(getWindowHandle(), confine);
+            return true;
         } // else may need offscreen solution ? FIXME
         return false;
     }
@@ -565,8 +584,9 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
     /** Must be called on Main-Thread */
     private native void setAlwaysOnTop0(long window, boolean atop);
     private static native Object getLocationOnScreen0(long windowHandle, int src_x, int src_y);
-    private static native boolean setPointerVisible0(long windowHandle, boolean hasFocus, boolean visible);
-    private static native boolean confinePointer0(long windowHandle, boolean confine);
+    private static native void setPointerIcon0(long windowHandle, long handle);
+    private static native void setPointerVisible0(long windowHandle, boolean hasFocus, boolean visible);
+    private static native void confinePointer0(long windowHandle, boolean confine);
     private static native void warpPointer0(long windowHandle, int x, int y);
 
     // Window styles
diff --git a/src/newt/classes/jogamp/newt/driver/opengl/JoglUtilPNGIcon.java b/src/newt/classes/jogamp/newt/driver/opengl/JoglUtilPNGIcon.java
new file mode 100644
index 0000000..551929b
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/driver/opengl/JoglUtilPNGIcon.java
@@ -0,0 +1,89 @@
+/**
+ * Copyright 2013 JogAmp Community. 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 JogAmp Community ``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 JogAmp Community OR
+ * 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package jogamp.newt.driver.opengl;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URLConnection;
+import java.nio.ByteBuffer;
+
+import javax.media.nativewindow.util.PixelFormat;
+
+import com.jogamp.common.nio.Buffers;
+import com.jogamp.common.os.Platform;
+import com.jogamp.common.util.IOUtil;
+import com.jogamp.opengl.util.PNGPixelRect;
+
+public class JoglUtilPNGIcon {
+
+    public static ByteBuffer arrayToX11BGRAImages(IOUtil.ClassResources resources, int[] data_size, int[] elem_bytesize) throws UnsupportedOperationException, InterruptedException, IOException, MalformedURLException {
+        final PNGPixelRect[] images = new PNGPixelRect[resources.resourceCount()];
+        data_size[0] = 0;
+        for(int i=0; i<resources.resourceCount(); i++) {
+            final URLConnection urlConn = resources.resolve(i);
+            final PNGPixelRect image = PNGPixelRect.read(urlConn.getInputStream(), PixelFormat.BGRA8888, false /* directBuffer */, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+            data_size[0] += 2 + image.getSize().getWidth() * image.getSize().getHeight();
+            images[i] = image;
+        }
+        final boolean is64Bit = Platform.is64Bit();
+        elem_bytesize[0] =  is64Bit ? Buffers.SIZEOF_LONG : Buffers.SIZEOF_INT;
+        final ByteBuffer buffer = Buffers.newDirectByteBuffer( data_size[0] * elem_bytesize[0] );
+
+        for(int i=0; i<images.length; i++) {
+            final PNGPixelRect image1 = images[i];
+            final int width = image1.getSize().getWidth();
+            final int height = image1.getSize().getHeight();
+            if( is64Bit ) {
+                buffer.putLong(width);
+                buffer.putLong(height);
+            } else {
+                buffer.putInt(width);
+                buffer.putInt(height);
+            }
+            final ByteBuffer bb = image1.getPixels();
+            final int stride = image1.getStride();
+            for(int y=0; y<height; y++) {
+                int bbOff = y * stride;
+                for(int x=0; x<width; x++) {
+                    long pixel;
+                    pixel  = ( 0xffL & bb.get(bbOff++) );       // B
+                    pixel |= ( 0xffL & bb.get(bbOff++) ) <<  8; // G
+                    pixel |= ( 0xffL & bb.get(bbOff++) ) << 16; // R
+                    pixel |= ( 0xffL & bb.get(bbOff++) ) << 24; // A
+                    if( is64Bit ) {
+                        buffer.putLong(pixel);
+                    } else {
+                        buffer.putInt((int)pixel);
+                    }
+                }
+            }
+        }
+        buffer.rewind();
+        return buffer;
+    }
+}
diff --git a/src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java
index c4cfd98..a304317 100644
--- a/src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java
@@ -34,24 +34,56 @@
 
 package jogamp.newt.driver.windows;
 
+import java.net.URLConnection;
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+
 import jogamp.nativewindow.windows.RegisteredClass;
 import jogamp.nativewindow.windows.RegisteredClassFactory;
 import jogamp.newt.DisplayImpl;
 import jogamp.newt.NEWTJNILibLoader;
+
 import javax.media.nativewindow.AbstractGraphicsDevice;
 import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.util.PixelFormat;
 
+import com.jogamp.common.nio.Buffers;
+import com.jogamp.common.util.IOUtil;
 import com.jogamp.nativewindow.windows.WindowsGraphicsDevice;
+import com.jogamp.newt.NewtFactory;
+import com.jogamp.opengl.util.PNGPixelRect;
 
 public class DisplayDriver extends DisplayImpl {
 
     private static final String newtClassBaseName = "_newt_clazz" ;
+    private static final long[] defaultIconHandles;
     private static RegisteredClassFactory sharedClassFactory;
 
     static {
         NEWTJNILibLoader.loadNEWT();
-
-        sharedClassFactory = new RegisteredClassFactory(newtClassBaseName, WindowDriver.getNewtWndProc0(), false /* useDummyDispatchThread */);
+        {
+            long[] _defaultIconHandle = { 0, 0 };
+            if( DisplayImpl.isPNGUtilAvailable() ) {
+                try {
+                    final IOUtil.ClassResources iconRes = NewtFactory.getWindowIcons();
+                    {
+                        final URLConnection urlConn = iconRes.resolve(0);
+                        final PNGPixelRect image = PNGPixelRect.read(urlConn.getInputStream(), PixelFormat.BGRA8888, false /* directBuffer */, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+                        _defaultIconHandle[0] = DisplayDriver.createBGRA8888Icon0(image.getPixels(), image.getSize().getWidth(), image.getSize().getHeight(), false, 0, 0);
+                    }
+                    {
+                        final URLConnection urlConn = iconRes.resolve(iconRes.resourceCount()-1);
+                        final PNGPixelRect image = PNGPixelRect.read(urlConn.getInputStream(), PixelFormat.BGRA8888, false /* directBuffer */, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+                        _defaultIconHandle[1] = DisplayDriver.createBGRA8888Icon0(image.getPixels(), image.getSize().getWidth(), image.getSize().getHeight(), false, 0, 0);
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+            defaultIconHandles = _defaultIconHandle;
+        }
+        sharedClassFactory = new RegisteredClassFactory(newtClassBaseName, WindowDriver.getNewtWndProc0(),
+                                                        false /* useDummyDispatchThread */, defaultIconHandles[0], defaultIconHandles[1]);
 
         if (!WindowDriver.initIDs0(RegisteredClassFactory.getHInstance())) {
             throw new NativeWindowException("Failed to initialize WindowsWindow jmethodIDs");
@@ -92,9 +124,33 @@ public class DisplayDriver extends DisplayImpl {
         return sharedClass.getName();
     }
 
+    @Override
+    protected final long createPointerIconImpl(PixelFormat pixelformat, int width, int height, final ByteBuffer pixels, final int hotX, final int hotY) {
+        return createBGRA8888Icon0(pixels, width, height, true, hotX, hotY);
+    }
+
+    @Override
+    protected final void destroyPointerIconImpl(final long displayHandle, long piHandle) {
+        destroyIcon0(piHandle);
+    }
+
     //----------------------------------------------------------------------
     // Internals only
     //
     private static native void DispatchMessages0();
+
+    static long createBGRA8888Icon0(Buffer pixels, int width, int height, boolean isCursor, int hotX, int hotY) {
+        if( null == pixels ) {
+            throw new IllegalArgumentException("data buffer/size");
+        }
+        final boolean pixels_is_direct = Buffers.isDirect(pixels);
+        return createBGRA8888Icon0(
+                      pixels_is_direct ? pixels : Buffers.getArray(pixels),
+                      pixels_is_direct ? Buffers.getDirectBufferByteOffset(pixels) : Buffers.getIndirectBufferByteOffset(pixels),
+                      pixels_is_direct,
+                      width, height, isCursor, hotX, hotY);
+    }
+    private static native long createBGRA8888Icon0(Object pixels, int pixels_byte_offset, boolean pixels_is_direct, int width, int height, boolean isCursor, int hotX, int hotY);
+    private static native void destroyIcon0(long handle);
 }
 
diff --git a/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java
index 6e8ac3e..a48fe2f 100644
--- a/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java
@@ -34,8 +34,11 @@
 
 package jogamp.newt.driver.windows;
 
+import java.nio.ByteBuffer;
+
 import jogamp.nativewindow.windows.GDI;
 import jogamp.nativewindow.windows.GDIUtil;
+import jogamp.newt.PointerIconImpl;
 import jogamp.newt.WindowImpl;
 
 import javax.media.nativewindow.AbstractGraphicsConfiguration;
@@ -55,15 +58,15 @@ import com.jogamp.newt.event.MouseEvent.PointerType;
 
 public class WindowDriver extends WindowImpl {
 
+    static {
+        DisplayDriver.initSingleton();
+    }
+
     private long hmon;
     private long hdc;
     private long hdc_old;
     private long windowHandleClose;
 
-    static {
-        DisplayDriver.initSingleton();
-    }
-
     public WindowDriver() {
     }
 
@@ -159,8 +162,8 @@ public class WindowDriver extends WindowImpl {
 
     @Override
     protected void closeNativeImpl() {
-        if(windowHandleClose != 0) {
-            if (hdc != 0) {
+        if( 0 != windowHandleClose ) {
+            if ( 0 != hdc ) {
                 try {
                     GDI.ReleaseDC(windowHandleClose, hdc);
                 } catch (Throwable t) {
@@ -177,10 +180,9 @@ public class WindowDriver extends WindowImpl {
                     Exception e = new Exception("Warning: closeNativeImpl failed - "+Thread.currentThread().getName(), t);
                     e.printStackTrace();
                 }
-            } finally {
-                windowHandleClose = 0;
             }
         }
+        windowHandleClose = 0;
         hdc = 0;
         hdc_old = 0;
     }
@@ -224,6 +226,11 @@ public class WindowDriver extends WindowImpl {
     }
 
     @Override
+    protected void setPointerIconImpl(final PointerIconImpl pi) {
+        setPointerIcon0(getWindowHandle(), null != pi ? pi.validatedHandle() : 0);
+    }
+
+    @Override
     protected boolean setPointerVisibleImpl(final boolean pointerVisible) {
         final boolean[] res = new boolean[] { false };
 
@@ -371,4 +378,7 @@ public class WindowDriver extends WindowImpl {
     private static native boolean setPointerVisible0(long windowHandle, boolean visible);
     private static native boolean confinePointer0(long windowHandle, boolean grab, int l, int t, int r, int b);
     private static native void warpPointer0(long windowHandle, int x, int y);
+    private static native ByteBuffer newDirectByteBuffer(long addr, long capacity);
+
+    private static native void setPointerIcon0(long windowHandle, long iconHandle);
 }
diff --git a/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java
index 5048397..5c2820d 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java
@@ -34,9 +34,14 @@
 
 package jogamp.newt.driver.x11;
 
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+
 import javax.media.nativewindow.AbstractGraphicsDevice;
 import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.util.PixelFormat;
 
+import com.jogamp.common.nio.Buffers;
 import com.jogamp.nativewindow.x11.X11GraphicsDevice;
 
 import jogamp.nativewindow.x11.X11Util;
@@ -100,16 +105,15 @@ public class DisplayDriver extends DisplayImpl {
 
     @Override
     protected void dispatchMessagesNative() {
-        aDevice.lock();
+        final AbstractGraphicsDevice _aDevice = aDevice; // aDevice could be pulled by destroy event
+        _aDevice.lock();
         try {
-            final long handle = aDevice.getHandle();
+            final long handle = _aDevice.getHandle();
             if(0 != handle) {
                 DispatchMessages0(handle, javaObjectAtom, windowDeleteAtom /*, kbdHandle */); // XKB disabled for now
             }
         } finally {
-            if(null != aDevice) { // could be pulled by destroy event
-                aDevice.unlock();
-            }
+            _aDevice.unlock();
         }
     }
 
@@ -120,6 +124,19 @@ public class DisplayDriver extends DisplayImpl {
     /** Returns <code>null</code> if !{@link #isNativeValid()}, otherwise the Boolean value of {@link X11GraphicsDevice#isXineramaEnabled()}. */
     protected Boolean isXineramaEnabled() { return isNativeValid() ? Boolean.valueOf(((X11GraphicsDevice)aDevice).isXineramaEnabled()) : null; }
 
+    @Override
+    public final PixelFormat getNativePointerIconPixelFormat() { return PixelFormat.RGBA8888; }
+
+    @Override
+    protected final long createPointerIconImpl(PixelFormat pixelformat, int width, int height, final ByteBuffer pixels, final int hotX, final int hotY) {
+        return createPointerIcon(getHandle(), pixels, width, height, hotX, hotY);
+    }
+
+    @Override
+    protected final void destroyPointerIconImpl(final long displayHandle, long piHandle) {
+        destroyPointerIcon0(displayHandle, piHandle);
+    }
+
     //----------------------------------------------------------------------
     // Internals only
     //
@@ -137,6 +154,18 @@ public class DisplayDriver extends DisplayImpl {
 
     private native void DispatchMessages0(long display, long javaObjectAtom, long windowDeleteAtom /* , long kbdHandle */); // XKB disabled for now
 
+    private static long createPointerIcon(long display, Buffer pixels, int width, int height, int hotX, int hotY) {
+        final boolean pixels_is_direct = Buffers.isDirect(pixels);
+        return createPointerIcon0(display,
+                                  pixels_is_direct ? pixels : Buffers.getArray(pixels),
+                                  pixels_is_direct ? Buffers.getDirectBufferByteOffset(pixels) : Buffers.getIndirectBufferByteOffset(pixels),
+                                  pixels_is_direct,
+                                  width, height, hotX, hotY);
+    }
+    private static native long createPointerIcon0(long display, Object pixels, int pixels_byte_offset, boolean pixels_is_direct, int width, int height, int hotX, int hotY);
+
+    private static native void destroyPointerIcon0(long display, long handle);
+
     /** X11 Window delete atom marker used on EDT */
     private long windowDeleteAtom;
 
diff --git a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java
index 5e1f7a6..0eda37e 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java
@@ -34,19 +34,26 @@
 
 package jogamp.newt.driver.x11;
 
+import java.nio.Buffer;
+
 import jogamp.nativewindow.x11.X11Lib;
 import jogamp.nativewindow.x11.X11Util;
 import jogamp.newt.DisplayImpl;
 import jogamp.newt.DisplayImpl.DisplayRunnable;
+import jogamp.newt.PointerIconImpl;
 import jogamp.newt.WindowImpl;
+import jogamp.newt.driver.PNGIcon;
+
 import javax.media.nativewindow.*;
 import javax.media.nativewindow.VisualIDHolder.VIDType;
 import javax.media.nativewindow.util.Insets;
 import javax.media.nativewindow.util.InsetsImmutable;
 import javax.media.nativewindow.util.Point;
 
+import com.jogamp.common.nio.Buffers;
 import com.jogamp.nativewindow.x11.X11GraphicsDevice;
 import com.jogamp.nativewindow.x11.X11GraphicsScreen;
+import com.jogamp.newt.NewtFactory;
 import com.jogamp.newt.event.InputEvent;
 import com.jogamp.newt.event.KeyEvent;
 import com.jogamp.newt.event.MouseEvent;
@@ -58,8 +65,30 @@ public class WindowDriver extends WindowImpl {
     private static final int X11_WHEEL_TWO_UP_BUTTON   = 6;
     private static final int X11_WHEEL_TWO_DOWN_BUTTON = 7;
 
+    private static final int defaultIconDataSize;
+    private static final Buffer defaultIconData;
+
     static {
         ScreenDriver.initSingleton();
+
+        int _icon_data_size=0, _icon_elem_bytesize=0;
+        Buffer _icon_data=null;
+        if( PNGIcon.isAvailable() ) {
+            try {
+                // NOTE: MUST BE DIRECT BUFFER, since _NET_WM_ICON Atom uses buffer directly!
+                final int[] data_size = { 0 }, elem_bytesize = { 0 };
+                _icon_data = PNGIcon.arrayToX11BGRAImages(NewtFactory.getWindowIcons(), data_size, elem_bytesize);
+                _icon_data_size = data_size[0];
+                _icon_elem_bytesize = elem_bytesize[0];
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        defaultIconDataSize = _icon_data_size;
+        defaultIconData = _icon_data;
+        if(DEBUG_IMPLEMENTATION) {
+            System.err.println("Def. Icon: data_size "+defaultIconDataSize+" * elem_size "+_icon_elem_bytesize+" = data "+defaultIconData);
+        }
     }
 
     public WindowDriver() {
@@ -97,10 +126,11 @@ public class WindowDriver extends WindowImpl {
                           ( FLAG_IS_ALWAYSONTOP | FLAG_IS_UNDECORATED ) ;
         edtDevice.lock();
         try {
-            setWindowHandle(CreateWindow0(getParentWindowHandle(),
+            setWindowHandle(CreateWindow(getParentWindowHandle(),
                                    edtDevice.getHandle(), screen.getIndex(), visualID,
                                    display.getJavaObjectAtom(), display.getWindowDeleteAtom(),
-                                   getX(), getY(), getWidth(), getHeight(), autoPosition(), flags));
+                                   getX(), getY(), getWidth(), getHeight(), autoPosition(), flags,
+                                   defaultIconDataSize, defaultIconData));
         } finally {
             edtDevice.unlock();
         }
@@ -148,20 +178,21 @@ public class WindowDriver extends WindowImpl {
 
     @Override
     protected boolean reconfigureWindowImpl(final int x, final int y, final int width, final int height, int flags) {
-        if(DEBUG_IMPLEMENTATION) {
-            System.err.println("X11Window reconfig: "+x+"/"+y+" "+width+"x"+height+", "+ getReconfigureFlagsAsString(null, flags));
-        }
         final int _x, _y;
-        if(0 == ( FLAG_IS_UNDECORATED & flags)) {
-            final InsetsImmutable i = getInsets();
-
+        final InsetsImmutable _insets;
+        if( 0 == ( FLAG_IS_UNDECORATED & flags) ) {
             // client position -> top-level window position
-            _x = x - i.getLeftWidth() ;
-            _y = y - i.getTopHeight() ;
+            _insets = getInsets();
+            _x = x - _insets.getLeftWidth() ;
+            _y = y - _insets.getTopHeight() ;
         } else {
+            _insets = null;
             _x = x;
             _y = y;
         }
+        if(DEBUG_IMPLEMENTATION) {
+            System.err.println("X11Window reconfig: "+x+"/"+y+" -> "+_x+"/"+_y+" "+width+"x"+height+", insets "+_insets+", "+ getReconfigureFlagsAsString(null, flags));
+        }
         if( 0 != ( FLAG_CHANGE_FULLSCREEN & flags ) ) {
             if( 0 != ( FLAG_IS_FULLSCREEN & flags) && 0 == ( FLAG_IS_ALWAYSONTOP & flags) ) {
                 tempFSAlwaysOnTop = true;
@@ -196,7 +227,7 @@ public class WindowDriver extends WindowImpl {
      */
     @Override
     protected void focusChanged(boolean defer, boolean focusGained) {
-        if( tempFSAlwaysOnTop && hasFocus() != focusGained && isNativeValid() ) {
+        if( isNativeValid() && isFullscreen() && tempFSAlwaysOnTop && hasFocus() != focusGained ) {
             final int flags = getReconfigureFlags(FLAG_CHANGE_ALWAYSONTOP, isVisible()) | ( focusGained ? FLAG_IS_ALWAYSONTOP : 0 );
             if(DEBUG_IMPLEMENTATION) {
                 System.err.println("X11Window reconfig.3 (focus): temporary "+getReconfigureFlagsAsString(null, flags));
@@ -245,11 +276,34 @@ public class WindowDriver extends WindowImpl {
     }
 
     @Override
+    protected void setPointerIconImpl(final PointerIconImpl pi) {
+        runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Object>() {
+            @Override
+            public Object run(long dpy) {
+                try {
+                    setPointerIcon0(dpy, getWindowHandle(), null != pi ? pi.validatedHandle() : 0);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+                return null;
+            }
+        });
+    }
+
+    @Override
     protected boolean setPointerVisibleImpl(final boolean pointerVisible) {
         return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Boolean>() {
             @Override
             public Boolean run(long dpy) {
-                return Boolean.valueOf(setPointerVisible0(dpy, getWindowHandle(), pointerVisible));
+                final PointerIconImpl pi = (PointerIconImpl)getPointerIcon();
+                final boolean res;
+                if( pointerVisible && null != pi ) {
+                    setPointerIcon0(dpy, getWindowHandle(), null != pi ? pi.validatedHandle() : 0);
+                    res = true;
+                } else {
+                    res = setPointerVisible0(dpy, getWindowHandle(), pointerVisible);
+                }
+                return Boolean.valueOf(res);
             }
         }).booleanValue();
     }
@@ -378,15 +432,33 @@ public class WindowDriver extends WindowImpl {
 
     protected static native boolean initIDs0();
 
+    private long CreateWindow(long parentWindowHandle, long display, int screen_index,
+                              int visualID, long javaObjectAtom, long windowDeleteAtom,
+                              int x, int y, int width, int height, boolean autoPosition, int flags,
+                              int pixelDataSize, Buffer pixels) {
+        // NOTE: MUST BE DIRECT BUFFER, since _NET_WM_ICON Atom uses buffer directly!
+        if( !Buffers.isDirect(pixels) ) {
+            throw new IllegalArgumentException("data buffer is not direct "+pixels);
+        }
+        return CreateWindow0(parentWindowHandle, display, screen_index,
+                             visualID, javaObjectAtom, windowDeleteAtom,
+                             x, y, width, height, autoPosition, flags,
+                             pixelDataSize,
+                             pixels, Buffers.getDirectBufferByteOffset(pixels), true /* pixels_is_direct */);
+    }
     private native long CreateWindow0(long parentWindowHandle, long display, int screen_index,
                                       int visualID, long javaObjectAtom, long windowDeleteAtom,
-                                      int x, int y, int width, int height, boolean autoPosition, int flags);
+                                      int x, int y, int width, int height, boolean autoPosition, int flags,
+                                      int pixelDataSize, Object pixels, int pixels_byte_offset, boolean pixels_is_direct);
     private native void CloseWindow0(long display, long windowHandle, long javaObjectAtom, long windowDeleteAtom /*, long kbdHandle*/ ); // XKB disabled for now
     private native void reconfigureWindow0(long display, int screen_index, long parentWindowHandle, long windowHandle,
                                            long windowDeleteAtom, int x, int y, int width, int height, int flags);
     private native void requestFocus0(long display, long windowHandle, boolean force);
 
     private static native void setTitle0(long display, long windowHandle, String title);
+
+    private static native void setPointerIcon0(long display, long windowHandle, long handle);
+
     private static native long getParentWindow0(long display, long windowHandle);
     private static native boolean setPointerVisible0(long display, long windowHandle, boolean visible);
     private static native boolean confinePointer0(long display, long windowHandle, boolean grab);
diff --git a/src/newt/native/MacWindow.m b/src/newt/native/MacWindow.m
index 30d3458..130b2e3 100644
--- a/src/newt/native/MacWindow.m
+++ b/src/newt/native/MacWindow.m
@@ -113,18 +113,6 @@ static void setJavaWindowObject(JNIEnv *env, jobject newJavaWindowObject, NewtVi
         DBG_PRINT( "setJavaWindowObject.2: View %p - Set new javaWindowObject %p\n", view, newJavaWindowObject);
         jobject globJavaWindowObject = (*env)->NewGlobalRef(env, newJavaWindowObject);
         [view setJavaWindowObject: globJavaWindowObject];
-        {
-            JavaVM *jvmHandle = NULL;
-            int jvmVersion = 0;
-
-            if(0 != (*env)->GetJavaVM(env, &jvmHandle)) {
-                jvmHandle = NULL;
-            } else {
-                jvmVersion = (*env)->GetVersion(env);
-            }
-            [view setJVMHandle: jvmHandle];
-            [view setJVMVersion: jvmVersion];
-        }
     }
     DBG_PRINT( "setJavaWindowObject.X: View %p\n", view);
 }
@@ -210,6 +198,8 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_DisplayDriver_initNSAp
     if(initialized) return JNI_TRUE;
     initialized = 1;
 
+    NewtCommon_init(env);
+
     // This little bit of magic is needed in order to receive mouse
     // motion events and allow key focus to be properly transferred.
     // FIXME: are these Carbon APIs? They come from the
@@ -285,6 +275,97 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_DisplayDriver_stopNSApplic
     [pool release];
 }
 
+static NSImage * createNSImageFromData(JNIEnv *env, unsigned char * iconData, jint jiconWidth, jint jiconHeight) {
+    if( NULL != iconData ) {
+        NSInteger iconWidth = (NSInteger) jiconWidth;
+        NSInteger iconHeight = (NSInteger) jiconHeight;
+        const NSInteger bpc = 8 /* bits per component */, spp=4 /* RGBA */, bpp = bpc * spp;
+        const NSBitmapFormat bfmt = NSAlphaNonpremultipliedBitmapFormat;
+        const BOOL hasAlpha = YES;
+
+        NSBitmapImageRep* bir = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes: &iconData
+                                    pixelsWide: iconWidth
+                                    pixelsHigh: iconHeight
+                                    bitsPerSample: bpc
+                                    samplesPerPixel: spp
+                                    hasAlpha: hasAlpha
+                                    isPlanar: NO
+                                    colorSpaceName: NSCalibratedRGBColorSpace
+                                    bitmapFormat: bfmt
+                                    bytesPerRow: iconWidth*4
+                                    bitsPerPixel: bpp];
+        [bir autorelease];
+        NSImage* nsImage = [[NSImage alloc] initWithCGImage: [bir CGImage] size:NSZeroSize];
+        return nsImage;
+    }
+    return NULL;
+}
+
+/*
+ * Class:     jogamp_newt_driver_macosx_DisplayDriver
+ * Method:    setAppIcon0
+ */
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_DisplayDriver_setAppIcon0
+  (JNIEnv *env, jobject unused, jobject pixels, jint pixels_byte_offset, jboolean pixels_is_direct, jint width, jint height)
+{
+    if( 0 == pixels ) {
+        return;
+    }
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+    // NOTE: MUST BE DIRECT BUFFER, since NSBitmapImageRep uses buffer directly!
+    unsigned char * pixelPtr = (unsigned char *) ( JNI_TRUE == pixels_is_direct ? 
+                                            (*env)->GetDirectBufferAddress(env, pixels) : 
+                                            (*env)->GetPrimitiveArrayCritical(env, pixels, NULL) );
+    NSImage * nsImage = createNSImageFromData(env, pixelPtr + pixels_byte_offset, width, height);
+    if( NULL != nsImage ) {
+        [nsImage autorelease];
+        [NSApp setApplicationIconImage: nsImage];
+    }
+    if ( JNI_FALSE == pixels_is_direct ) {
+        (*env)->ReleasePrimitiveArrayCritical(env, pixels, (void*)pixelPtr, JNI_ABORT);  
+    }
+    [pool release];
+}
+
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_DisplayDriver_createPointerIcon0
+  (JNIEnv *env, jobject unused, jobject pixels, jint pixels_byte_offset, jboolean pixels_is_direct, jint width, jint height, jint hotX, jint hotY)
+{
+    if( 0 == pixels ) {
+        return 0;
+    }
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+    unsigned char * pixelPtr = (unsigned char *) ( JNI_TRUE == pixels_is_direct ? 
+                                            (*env)->GetDirectBufferAddress(env, pixels) : 
+                                            (*env)->GetPrimitiveArrayCritical(env, pixels, NULL) );
+    NSImage * nsImage = createNSImageFromData(env, pixelPtr + pixels_byte_offset, width, height);
+    NSCursor * res = NULL;
+    if( NULL != nsImage ) {
+        [nsImage autorelease];
+        NSPoint hotP = { hotX, hotY };
+        res = [[NSCursor alloc] initWithImage: nsImage hotSpot: hotP];
+    }
+    if ( JNI_FALSE == pixels_is_direct ) {
+        (*env)->ReleasePrimitiveArrayCritical(env, pixels, (void*)pixelPtr, JNI_ABORT);  
+    }
+    [pool release];
+    DBG_PRINT( "createPointerIcon0 %p\n", res);
+    return (jlong) (intptr_t) res;
+}
+
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_DisplayDriver_destroyPointerIcon0
+  (JNIEnv *env, jobject unused, jlong handle)
+{
+    NSCursor * c = (NSCursor*) (intptr_t) handle ;
+    if( NULL != c && NO == [c isKindOfClass:[NSCursor class]] ) {
+        NewtCommon_throwNewRuntimeException(env, "Not a NSCursor %p", c);
+        return;
+    }
+    DBG_PRINT( "destroyPointerIcon0 %p\n", c);
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+    [c release];
+    [pool release];
+}
+
 static NSScreen * NewtScreen_getNSScreenByIndex(int screen_idx, BOOL cap) {
     NSArray *screens = [NSScreen screens];
     if( screen_idx<0 || screen_idx>=[screens count] ) {
@@ -628,11 +709,11 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createView0
 
     NSRect rectView = NSMakeRect(0, 0, w, h);
     NewtView *myView = [[NewtView alloc] initWithFrame: rectView] ;
-    DBG_PRINT( "createView0.X.%d - new view: %p\n", myView);
+    DBG_PRINT( "createView0.X - new view: %p\n", myView);
 
     [pool release];
 
-    return (jlong) ((intptr_t) myView);
+    return (jlong) (intptr_t) myView;
 }
 
 /**
@@ -649,7 +730,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createWindow
     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
     NewtView* myView = (NewtView*) (intptr_t) jview ;
 
-    DBG_PRINT( "createWindow0 - %p (this), %d/%d %dx%d, fs %d, style %X, buffType %X, screenidx %d, view %p (START)\n",
+    DBG_PRINT( "createWindow0 - %p (this), %d/%d %dx%d, fs %d, style %X, buffType %X, view %p (START)\n",
         (void*)(intptr_t)jthis, (int)x, (int)y, (int)w, (int)h, (int)fullscreen, 
         (int)styleMask, (int)bufferingType, myView);
     (void)myView;
@@ -674,7 +755,6 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createWindow
                                                backing: (NSBackingStoreType) bufferingType
                                                defer: YES
                                                isFullscreenWindow: fullscreen];
-
     // DBG_PRINT( "createWindow0.1 - %p, isVisible %d\n", myWindow, [myWindow isVisible]);
 
     DBG_PRINT( "createWindow0.X - %p, isVisible %d\n", myWindow, [myWindow isVisible]);
@@ -777,6 +857,7 @@ NS_ENDHANDLER
 
     // Set the content view
     changeContentView(env, jthis, parentView, myWindow, myView, NO);
+    [myWindow setInitialFirstResponder: myView];
 
     DBG_PRINT( "initWindow0.%d - %p view %p, isVisible %d\n", 
         dbgIdx++, myWindow, myView, [myWindow isVisible]);
@@ -877,7 +958,6 @@ NS_ENDHANDLER
 JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_close0
   (JNIEnv *env, jobject unused, jlong window)
 {
-    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
     NewtMacWindow* mWin = (NewtMacWindow*) ((intptr_t) window);
     if( NULL == mWin ) {
         DBG_PRINT( "windowClose.0 - NULL NEWT win - abort\n");
@@ -887,10 +967,12 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_close0
     BOOL isNewtWin = [mWin isKindOfClass:[NewtMacWindow class]];
     NSWindow *pWin = [mWin parentWindow];
     DBG_PRINT( "windowClose.0 - %p [isNSWindow %d, isNewtWin %d], parent %p\n", mWin, isNSWin, isNewtWin, pWin);
+    (void)isNSWin; // silence
     if( !isNewtWin ) {
-        DBG_PRINT( "windowClose.0 - Not a NEWT win - abort\n");
+        NewtCommon_throwNewRuntimeException(env, "Not a NewtMacWindow %p", mWin);
         return;
     }
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
     NewtView* mView = (NewtView *)[mWin contentView];
     BOOL fullscreen = mWin->isFullscreenWindow;
     BOOL destroyNotifySent, isNSView, isNewtView;
@@ -1005,6 +1087,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_requestFocus0
 #endif
     DBG_PRINT( "requestFocus - window: %p, force %d, hasFocus %d (START)\n", mWin, force, hasFocus);
 
+    [mWin setAcceptsMouseMovedEvents: YES];
     [mWin makeFirstResponder: nil];
     [mWin orderFrontRegardless];
     [mWin makeKeyWindow];
@@ -1242,31 +1325,60 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setAlwaysOnTo
 JNIEXPORT jobject JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_getLocationOnScreen0
   (JNIEnv *env, jclass unused, jlong win, jint src_x, jint src_y)
 {
-    NSObject *nsObj = (NSObject*) ((intptr_t) win);
-    NewtMacWindow * mWin = NULL;
-
-    if( [nsObj isKindOfClass:[NewtMacWindow class]] ) {
-        mWin = (NewtMacWindow*) nsObj;
-    } else {
-        NewtCommon_throwNewRuntimeException(env, "not NewtMacWindow %p\n", nsObj);
+    NewtMacWindow *mWin = (NewtMacWindow*) (intptr_t) win;
+    if( ![mWin isKindOfClass:[NewtMacWindow class]] ) {
+        NewtCommon_throwNewRuntimeException(env, "Not a NewtMacWindow %p", mWin);
+        return NULL;
     }
-
     NSPoint p0 = [mWin getLocationOnScreen: NSMakePoint(src_x, src_y)];
     return (*env)->NewObject(env, pointClz, pointCstr, (jint)p0.x, (jint)p0.y);
 }
 
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setPointerIcon0
+  (JNIEnv *env, jobject unused, jlong window, jlong handle)
+{
+    NSCursor *c = (NSCursor*) (intptr_t) handle ;
+    if ( NULL != c && NO == [c isKindOfClass:[NSCursor class]] ) {
+        NewtCommon_throwNewRuntimeException(env, "Not a NSCursor %p", c);
+        return;
+    }
+    NewtMacWindow *mWin = (NewtMacWindow*) (intptr_t) window;
+    if( ! [mWin isKindOfClass:[NewtMacWindow class]] ) {
+        NewtCommon_throwNewRuntimeException(env, "Not a NewtMacWindow %p", mWin);
+        return;
+    }
+    NewtView* nView = (NewtView *) [mWin contentView];
+    if( ! [nView isKindOfClass:[NewtView class]] ) {
+        NewtCommon_throwNewRuntimeException(env, "Not a NewtView %p", nView);
+        return;
+    }
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+    [nView setPointerIcon: c];
+    [pool release];
+}
+
 /*
  * Class:     Java_jogamp_newt_driver_macosx_WindowDriver
  * Method:    setPointerVisible0
  * Signature: (JZ)Z
  */
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setPointerVisible0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setPointerVisible0
   (JNIEnv *env, jclass clazz, jlong window, jboolean hasFocus, jboolean mouseVisible)
 {
     NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window);
-    [mWin setMouseVisible: ( JNI_TRUE == mouseVisible ) ? YES : NO 
-                 hasFocus: ( JNI_TRUE == hasFocus ) ? YES : NO];
-    return JNI_TRUE;
+    if( ! [mWin isKindOfClass:[NewtMacWindow class]] ) {
+        NewtCommon_throwNewRuntimeException(env, "Not a NewtMacWindow %p", mWin);
+        return;
+    }
+    NewtView* nView = (NewtView *) [mWin contentView];
+    if( ! [nView isKindOfClass:[NewtView class]] ) {
+        NewtCommon_throwNewRuntimeException(env, "Not a NewtView %p", nView);
+        return;
+    }
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+    [nView setMouseVisible: ( JNI_TRUE == mouseVisible ) ? YES : NO 
+                  hasFocus: ( JNI_TRUE == hasFocus ) ? YES : NO];
+    [pool release];
 }
 
 /*
@@ -1274,12 +1386,22 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setPointe
  * Method:    confinePointer0
  * Signature: (JZ)Z
  */
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_confinePointer0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_confinePointer0
   (JNIEnv *env, jclass clazz, jlong window, jboolean confine)
 {
     NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window);
-    [mWin setMouseConfined: ( JNI_TRUE == confine ) ? YES : NO];
-    return JNI_TRUE;
+    if( ! [mWin isKindOfClass:[NewtMacWindow class]] ) {
+        NewtCommon_throwNewRuntimeException(env, "Not a NewtMacWindow %p", mWin);
+        return;
+    }
+    NewtView* nView = (NewtView *) [mWin contentView];
+    if( ! [nView isKindOfClass:[NewtView class]] ) {
+        NewtCommon_throwNewRuntimeException(env, "Not a NewtView %p", nView);
+        return;
+    }
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+    [nView setMouseConfined: ( JNI_TRUE == confine ) ? YES : NO];
+    [pool release];
 }
 
 /*
@@ -1291,6 +1413,17 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_warpPointer0
   (JNIEnv *env, jclass clazz, jlong window, jint x, jint y)
 {
     NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window);
-    [mWin setMousePosition: [mWin newtRelClientTLWinPos2AbsBLScreenPos: NSMakePoint(x, y)]];
+    if( ! [mWin isKindOfClass:[NewtMacWindow class]] ) {
+        NewtCommon_throwNewRuntimeException(env, "Not a NewtMacWindow %p", mWin);
+        return;
+    }
+    NewtView* nView = (NewtView *) [mWin contentView];
+    if( ! [nView isKindOfClass:[NewtView class]] ) {
+        NewtCommon_throwNewRuntimeException(env, "Not a NewtView %p", nView);
+        return;
+    }
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+    [nView setMousePosition: [mWin newtRelClientTLWinPos2AbsBLScreenPos: NSMakePoint(x, y)]];
+    [pool release];
 }
 
diff --git a/src/newt/native/NewtCommon.c b/src/newt/native/NewtCommon.c
index c294b6e..231d618 100644
--- a/src/newt/native/NewtCommon.c
+++ b/src/newt/native/NewtCommon.c
@@ -5,17 +5,43 @@
 static const char * const ClazzNameRuntimeException = "java/lang/RuntimeException";
 static jclass    runtimeExceptionClz=NULL;
 
+static JavaVM *_jvmHandle = NULL;
+static int _jvmVersion = 0;
+
+void NewtCommon_init(JNIEnv *env) {
+    if(NULL==_jvmHandle) {
+        if(0 != (*env)->GetJavaVM(env, &_jvmHandle)) {
+            NewtCommon_FatalError(env, "NEWT: Can't fetch JavaVM handle");
+        } else {
+            _jvmVersion = (*env)->GetVersion(env);
+        }
+        jclass c = (*env)->FindClass(env, ClazzNameRuntimeException);
+        if(NULL==c) {
+            NewtCommon_FatalError(env, "NEWT: Can't find %s", ClazzNameRuntimeException);
+        }
+        runtimeExceptionClz = (jclass)(*env)->NewGlobalRef(env, c);
+        (*env)->DeleteLocalRef(env, c);
+        if(NULL==runtimeExceptionClz) {
+            NewtCommon_FatalError(env, "NEWT: Can't use %s", ClazzNameRuntimeException);
+        }
+    }
+}
+
 void NewtCommon_FatalError(JNIEnv *env, const char* msg, ...)
 {
     char buffer[512];
     va_list ap;
 
-    va_start(ap, msg);
-    vsnprintf(buffer, sizeof(buffer), msg, ap);
-    va_end(ap);
+    if( NULL != msg ) {
+        va_start(ap, msg);
+        vsnprintf(buffer, sizeof(buffer), msg, ap);
+        va_end(ap);
 
-    fprintf(stderr, "%s\n", buffer);
-    (*env)->FatalError(env, buffer);
+        fprintf(stderr, "%s\n", buffer);
+        if(NULL != env) {
+            (*env)->FatalError(env, buffer);
+        }
+    }
 }
 
 void NewtCommon_throwNewRuntimeException(JNIEnv *env, const char* msg, ...)
@@ -23,23 +49,18 @@ void NewtCommon_throwNewRuntimeException(JNIEnv *env, const char* msg, ...)
     char buffer[512];
     va_list ap;
 
-    va_start(ap, msg);
-    vsnprintf(buffer, sizeof(buffer), msg, ap);
-    va_end(ap);
+    if(NULL==_jvmHandle) {
+        NewtCommon_FatalError(env, "NEWT: NULL JVM handle, call NewtCommon_init 1st\n");
+        return;
+    }
 
-    (*env)->ThrowNew(env, runtimeExceptionClz, buffer);
-}
+    if( NULL != msg ) {
+        va_start(ap, msg);
+        vsnprintf(buffer, sizeof(buffer), msg, ap);
+        va_end(ap);
 
-void NewtCommon_init(JNIEnv *env) {
-    if(NULL==runtimeExceptionClz) {
-        jclass c = (*env)->FindClass(env, ClazzNameRuntimeException);
-        if(NULL==c) {
-            NewtCommon_FatalError(env, "NEWT: can't find %s", ClazzNameRuntimeException);
-        }
-        runtimeExceptionClz = (jclass)(*env)->NewGlobalRef(env, c);
-        (*env)->DeleteLocalRef(env, c);
-        if(NULL==runtimeExceptionClz) {
-            NewtCommon_FatalError(env, "NEWT: can't use %s", ClazzNameRuntimeException);
+        if(NULL != env) {
+            (*env)->ThrowNew(env, runtimeExceptionClz, buffer);
         }
     }
 }
@@ -65,42 +86,57 @@ const char * NewtCommon_GetStaticStringMethod(JNIEnv *jniEnv, jclass clazz, jmet
 jchar* NewtCommon_GetNullTerminatedStringChars(JNIEnv* env, jstring str)
 {
     jchar* strChars = NULL;
-    strChars = calloc((*env)->GetStringLength(env, str) + 1, sizeof(jchar));
-    if (strChars != NULL) {
-        (*env)->GetStringRegion(env, str, 0, (*env)->GetStringLength(env, str), strChars);
+    if( NULL != env && 0 != str ) {
+        strChars = calloc((*env)->GetStringLength(env, str) + 1, sizeof(jchar));
+        if (strChars != NULL) {
+            (*env)->GetStringRegion(env, str, 0, (*env)->GetStringLength(env, str), strChars);
+        }
     }
     return strChars;
 }
 
-JNIEnv* NewtCommon_GetJNIEnv(JavaVM * jvmHandle, int jvmVersion, int asDaemon, int * shallBeDetached) {
+JNIEnv* NewtCommon_GetJNIEnv(int asDaemon, int * shallBeDetached) {
     JNIEnv* curEnv = NULL;
     JNIEnv* newEnv = NULL;
     int envRes;
 
+    if(NULL==_jvmHandle) {
+        fprintf(stderr, "NEWT GetJNIEnv: NULL JVM handle, call NewtCommon_init 1st\n");
+        return NULL;
+    }
+
     // retrieve this thread's JNIEnv curEnv - or detect it's detached
-    envRes = (*jvmHandle)->GetEnv(jvmHandle, (void **) &curEnv, jvmVersion) ;
+    envRes = (*_jvmHandle)->GetEnv(_jvmHandle, (void **) &curEnv, _jvmVersion) ;
     if( JNI_EDETACHED == envRes ) {
         // detached thread - attach to JVM
         if( asDaemon ) {
-            envRes = (*jvmHandle)->AttachCurrentThreadAsDaemon(jvmHandle, (void**) &newEnv, NULL);
+            envRes = (*_jvmHandle)->AttachCurrentThreadAsDaemon(_jvmHandle, (void**) &newEnv, NULL);
         } else {
-            envRes = (*jvmHandle)->AttachCurrentThread(jvmHandle, (void**) &newEnv, NULL);
+            envRes = (*_jvmHandle)->AttachCurrentThread(_jvmHandle, (void**) &newEnv, NULL);
         }
         if( JNI_OK != envRes ) {
-            fprintf(stderr, "JNIEnv: can't attach thread: %d\n", envRes);
+            fprintf(stderr, "NEWT GetJNIEnv: Can't attach thread: %d\n", envRes);
             return NULL;
         }
         curEnv = newEnv;
     } else if( JNI_OK != envRes ) {
         // oops ..
-        fprintf(stderr, "can't GetEnv: %d\n", envRes);
+        fprintf(stderr, "NEWT GetJNIEnv: Can't GetEnv: %d\n", envRes);
         return NULL;
     }
     if (curEnv==NULL) {
-        fprintf(stderr, "env is NULL\n");
+        fprintf(stderr, "NEWT GetJNIEnv: env is NULL\n");
         return NULL;
     }
     *shallBeDetached = NULL != newEnv;
     return curEnv;
 }
 
+void NewtCommon_ReleaseJNIEnv (int shallBeDetached) {
+    if(NULL == _jvmHandle) {
+        fprintf(stderr, "NEWT ReleaseJNIEnv: No JavaVM handle registered, call NewtCommon_init(..) 1st");
+    } else if(shallBeDetached) {
+        (*_jvmHandle)->DetachCurrentThread(_jvmHandle);
+    }
+}
+
diff --git a/src/newt/native/NewtCommon.h b/src/newt/native/NewtCommon.h
index 9cc9e93..43db72b 100644
--- a/src/newt/native/NewtCommon.h
+++ b/src/newt/native/NewtCommon.h
@@ -42,23 +42,18 @@ void NewtCommon_throwNewRuntimeException(JNIEnv *env, const char* msg, ...);
 
 /**
  *
- * 1) Store jvmHandle and jvmVersion
+ * 1) Init static jvmHandle, jvmVersion and clazz references
+ *    from an early initialization call w/ valid 'JNIEnv * env'
 
-    JavaVM *jvmHandle = NULL;
-    int jvmVersion = 0;
-
-    if(0 != (*env)->GetJavaVM(env, &jvmHandle)) {
-        jvmHandle = NULL;
-    } else {
-        jvmVersion = (*env)->GetVersion(env);
-    }
+    NewtCommon_init(env);
 
  *
  * 2) Use current thread JNIEnv or attach current thread to JVM, generating new JNIEnv
  *
 
+    int asDaemon = 0;
     int shallBeDetached = 0;
-    JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
+    JNIEnv* env = NewtCommon_GetJNIEnv(asDaemon, &shallBeDetached);
     if(NULL==env) {
         DBG_PRINT("drawRect: null JNIEnv\n");
         return;
@@ -70,12 +65,13 @@ void NewtCommon_throwNewRuntimeException(JNIEnv *env, const char* msg, ...);
     .. your JNIEnv code here ..
 
  *
- * 4) Detach thread from JVM, if required
+ * 4) Detach thread from JVM if required, i.e. not attached as daemon!
+ *    Not recommended for recurring _daemon_ threads (performance)
  *
-    if (shallBeDetached) {
-        (*jvmHandle)->DetachCurrentThread(jvmHandle);
-    }
+    NativewindowCommon_ReleaseJNIEnv(shallBeDetached);
  */
-JNIEnv* NewtCommon_GetJNIEnv (JavaVM * jvmHandle, int jvmVersion, int asDaemon, int * shallBeDetached);
+JNIEnv* NewtCommon_GetJNIEnv (int asDaemon, int * shallBeDetached);
+
+void NewtCommon_ReleaseJNIEnv (int shallBeDetached);
 
 #endif
diff --git a/src/newt/native/NewtMacWindow.h b/src/newt/native/NewtMacWindow.h
index ba60b56..8f6362a 100644
--- a/src/newt/native/NewtMacWindow.h
+++ b/src/newt/native/NewtMacWindow.h
@@ -41,7 +41,7 @@
 // #define VERBOSE_ON 1
 
 #ifdef VERBOSE_ON
-    #define DBG_PRINT(...) NSLog(@ __VA_ARGS__)
+    #define DBG_PRINT(...) NSLog(@ __VA_ARGS__) ; fflush(stderr)
     // #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
 #else
     #define DBG_PRINT(...)
@@ -53,10 +53,6 @@
 {
     jobject javaWindowObject;
 
-    // This is set while messages are being dispatched and cleared afterward
-    JavaVM *jvmHandle;
-    int jvmVersion;
-
     volatile BOOL destroyNotifySent;
     volatile int softLockCount;
     pthread_mutex_t softLockSync;
@@ -64,6 +60,13 @@
     volatile NSTrackingRectTag ptrTrackingTag;
     NSRect ptrRect;
     NSCursor * myCursor;
+    BOOL modsDown[4]; // shift, ctrl, alt/option, win/command
+
+    BOOL mouseConfined;
+    BOOL mouseInside;
+    BOOL mouseVisible;
+    BOOL cursorIsHidden;
+    NSPoint lastInsideMousePosition;
 }
 
 - (id)initWithFrame:(NSRect)frameRect;
@@ -73,21 +76,11 @@
 #endif
 - (void) dealloc;
 
-/* Set during event dispatching cycle */
-- (void) setJVMHandle: (JavaVM*) vm;
-- (JavaVM*) getJVMHandle;
-- (void) setJVMVersion: (int) ver;
-- (int) getJVMVersion;
-
 /* Register or deregister (NULL) the java Window object, 
    ie, if NULL, no events are send */
 - (void) setJavaWindowObject: (jobject) javaWindowObj;
 - (jobject) getJavaWindowObject;
 
-- (void) rightMouseDown: (NSEvent*) theEvent;
-- (void) resetCursorRects;
-- (NSCursor *) cursor;
-
 - (void) setDestroyNotifySent: (BOOL) v;
 - (BOOL) getDestroyNotifySent;
 
@@ -101,6 +94,41 @@
 - (void) viewDidHide;
 - (void) viewDidUnhide;
 - (BOOL) acceptsFirstResponder;
+- (BOOL) becomeFirstResponder;
+- (BOOL) resignFirstResponder;
+
+- (void) removeCursorRects;
+- (void) addCursorRects;
+- (void) removeMyCursor;
+- (void) resetCursorRects;
+- (void) setPointerIcon: (NSCursor*)c;
+- (void) mouseEntered: (NSEvent*) theEvent;
+- (void) mouseExited: (NSEvent*) theEvent;
+- (BOOL) updateMouseInside;
+- (void) cursorHide:(BOOL)v enter:(int)enterState; 
+- (void) setPointerIcon:(NSCursor*)c;
+- (void) setMouseVisible:(BOOL)v hasFocus:(BOOL)focus;
+- (BOOL) isMouseVisible;
+- (void) setMouseConfined:(BOOL)v;
+- (void) setMousePosition:(NSPoint)p;
+- (void) mouseMoved: (NSEvent*) theEvent;
+- (void) scrollWheel: (NSEvent*) theEvent;
+- (void) mouseDown: (NSEvent*) theEvent;
+- (void) mouseDragged: (NSEvent*) theEvent;
+- (void) mouseUp: (NSEvent*) theEvent;
+- (void) rightMouseDown: (NSEvent*) theEvent;
+- (void) rightMouseDragged: (NSEvent*) theEvent;
+- (void) rightMouseUp: (NSEvent*) theEvent;
+- (void) otherMouseDown: (NSEvent*) theEvent;
+- (void) otherMouseDragged: (NSEvent*) theEvent;
+- (void) otherMouseUp: (NSEvent*) theEvent;
+- (void) sendMouseEvent: (NSEvent*) event eventType: (jshort) evType;
+- (NSPoint) screenPos2NewtClientWinPos: (NSPoint) p;
+
+- (void) handleFlagsChanged:(NSUInteger) mods;
+- (void) handleFlagsChanged:(int) keyMask keyIndex: (int) keyIdx keyCode: (int) keyCode modifiers: (NSUInteger) mods;
+- (void) sendKeyEvent: (NSEvent*) event eventType: (jshort) evType;
+- (void) sendKeyEvent: (jshort) keyCode characters: (NSString*) chars modifiers: (NSUInteger)mods eventType: (jshort) evType;
 
 @end
 
@@ -110,13 +138,7 @@
 @interface NewtMacWindow : NSWindow 
 #endif
 {
-    BOOL mouseConfined;
-    BOOL mouseVisible;
-    BOOL mouseInside;
-    BOOL cursorIsHidden;
     BOOL realized;
-    BOOL modsDown[4]; // shift, ctrl, alt/option, win/command
-    NSPoint lastInsideMousePosition;
 @public
     BOOL hasPresentationSwitch;
     NSUInteger defaultPresentationOptions;
@@ -148,19 +170,14 @@
 - (NSPoint) newtRelClientTLWinPos2AbsBLScreenPos: (NSPoint) p;
 - (NSSize) newtClientSize2TLSize: (NSSize) nsz;
 - (NSPoint) getLocationOnScreen: (NSPoint) p;
-- (NSPoint) screenPos2NewtClientWinPos: (NSPoint) p;
-
-- (BOOL) isMouseInside;
-- (void) cursorHide:(BOOL)v;
-- (void) setMouseVisible:(BOOL)v hasFocus:(BOOL)focus;
-- (void) setMouseConfined:(BOOL)v;
-- (void) setMousePosition:(NSPoint)p;
 
-- (void) sendKeyEvent: (NSEvent*) event eventType: (jshort) evType;
-- (void) sendKeyEvent: (jshort) keyCode characters: (NSString*) chars modifiers: (NSUInteger)mods eventType: (jshort) evType;
-- (void) sendMouseEvent: (NSEvent*) event eventType: (jshort) evType;
 - (void) focusChanged: (BOOL) gained;
 
+- (void) keyDown: (NSEvent*) theEvent;
+- (void) keyUp: (NSEvent*) theEvent;
+- (void) flagsChanged: (NSEvent *) theEvent;
+- (BOOL) acceptsMouseMovedEvents;
+- (BOOL) acceptsFirstResponder;
 - (BOOL) becomeFirstResponder;
 - (BOOL) resignFirstResponder;
 - (BOOL) canBecomeKeyWindow;
@@ -168,22 +185,7 @@
 - (void) resignKeyWindow;
 - (void) windowDidBecomeKey: (NSNotification *) notification;
 - (void) windowDidResignKey: (NSNotification *) notification;
-- (void) keyDown: (NSEvent*) theEvent;
-- (void) keyUp: (NSEvent*) theEvent;
-- (void) handleFlagsChanged:(int) keyMask keyIndex: (int) keyIdx keyCode: (int) keyCode modifiers: (NSUInteger) mods;
-- (void) flagsChanged: (NSEvent *) theEvent;
-- (void) mouseEntered: (NSEvent*) theEvent;
-- (void) mouseExited: (NSEvent*) theEvent;
-- (void) mouseMoved: (NSEvent*) theEvent;
-- (void) scrollWheel: (NSEvent*) theEvent;
-- (void) mouseDown: (NSEvent*) theEvent;
-- (void) mouseDragged: (NSEvent*) theEvent;
-- (void) mouseUp: (NSEvent*) theEvent;
-- (void) rightMouseDown: (NSEvent*) theEvent;
-- (void) rightMouseDragged: (NSEvent*) theEvent;
-- (void) rightMouseUp: (NSEvent*) theEvent;
-- (void) otherMouseDown: (NSEvent*) theEvent;
-- (void) otherMouseUp: (NSEvent*) theEvent;
+
 - (void) windowDidResize: (NSNotification*) notification;
 - (void) windowDidMove: (NSNotification*) notification;
 - (BOOL) windowClosingImpl: (BOOL) force;
diff --git a/src/newt/native/NewtMacWindow.m b/src/newt/native/NewtMacWindow.m
index 4b0198c..b4133ac 100644
--- a/src/newt/native/NewtMacWindow.m
+++ b/src/newt/native/NewtMacWindow.m
@@ -41,6 +41,8 @@
 
 #include <math.h>
 
+#define PRINTF(...) NSLog(@ __VA_ARGS__)
+
 static jfloat GetDelta(NSEvent *event, jint javaMods[]) {
     CGEventRef cgEvent = [event CGEvent];
     CGFloat deltaY = 0.0;
@@ -84,6 +86,88 @@ static jfloat GetDelta(NSEvent *event, jint javaMods[]) {
     return (jfloat) delta;
 }
 
+#define kVK_Shift     0x38
+#define kVK_Option    0x3A
+#define kVK_Control   0x3B
+#define kVK_Command   0x37
+
+static jint mods2JavaMods(NSUInteger mods)
+{
+    int javaMods = 0;
+    if (mods & NSShiftKeyMask) {
+        javaMods |= EVENT_SHIFT_MASK;
+    }
+    if (mods & NSControlKeyMask) {
+        javaMods |= EVENT_CTRL_MASK;
+    }
+    if (mods & NSCommandKeyMask) {
+        javaMods |= EVENT_META_MASK;
+    }
+    if (mods & NSAlternateKeyMask) {
+        javaMods |= EVENT_ALT_MASK;
+    }
+    return javaMods;
+}
+
+static CFStringRef CKCH_CreateStringForKey(CGKeyCode keyCode, const UCKeyboardLayout *keyboardLayout) {
+    UInt32 keysDown = 0;
+    UniChar chars[4];
+    UniCharCount realLength;
+
+    UCKeyTranslate(keyboardLayout, keyCode,
+                   kUCKeyActionDisplay, 0,
+                   LMGetKbdType(), kUCKeyTranslateNoDeadKeysBit,
+                   &keysDown, sizeof(chars) / sizeof(chars[0]), &realLength, chars);
+
+    return CFStringCreateWithCharacters(kCFAllocatorDefault, chars, 1);
+}
+
+static CFMutableDictionaryRef CKCH_CreateCodeToCharDict(TISInputSourceRef keyboard) {
+    CFDataRef layoutData = (CFDataRef) TISGetInputSourceProperty(keyboard, kTISPropertyUnicodeKeyLayoutData);
+    const UCKeyboardLayout *keyboardLayout = (const UCKeyboardLayout *)CFDataGetBytePtr(layoutData);
+
+    CFMutableDictionaryRef codeToCharDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 128, NULL, NULL);
+    if ( NULL != codeToCharDict ) {
+        intptr_t i;
+        for (i = 0; i < 128; ++i) {
+            CFStringRef string = CKCH_CreateStringForKey((CGKeyCode)i, keyboardLayout);
+            if( NULL != string ) {
+                CFIndex stringLen = CFStringGetLength (string);
+                if ( 0 < stringLen ) {
+                    UniChar character = CFStringGetCharacterAtIndex(string, 0);
+                    DBG_PRINT("CKCH: MAP 0x%X -> %c\n", (int)i, character);
+                    CFDictionaryAddValue(codeToCharDict, (const void *)i, (const void *)(intptr_t)character);
+                }
+                CFRelease(string);
+            }
+        }
+    }
+    return codeToCharDict;
+}
+
+static CFMutableDictionaryRef CKCH_USCodeToNNChar = NULL;
+
+static void CKCH_CreateDictionaries() {
+    TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource();
+    CKCH_USCodeToNNChar = CKCH_CreateCodeToCharDict(currentKeyboard);
+    CFRelease(currentKeyboard);
+}
+
+static UniChar CKCH_CharForKeyCode(jshort keyCode) {
+    UniChar rChar = 0;
+
+    if ( NULL != CKCH_USCodeToNNChar ) {
+        intptr_t code = (intptr_t) keyCode;
+        intptr_t character = 0;
+
+        if ( CFDictionaryGetValueIfPresent(CKCH_USCodeToNNChar, (void *)code, (const void **)&character) ) {
+            rChar = (UniChar) character;
+            DBG_PRINT("CKCH: OK 0x%X -> 0x%X\n", (int)keyCode, (int)rChar);
+        }
+    }
+    return rChar;
+}
+
 static jmethodID enqueueMouseEventID = NULL;
 static jmethodID enqueueKeyEventID = NULL;
 static jmethodID requestFocusID = NULL;
@@ -109,8 +193,6 @@ static jmethodID windowRepaintID = NULL;
     id res = [super initWithFrame:frameRect];
     javaWindowObject = NULL;
 
-    jvmHandle = NULL;
-    jvmVersion = 0;
     destroyNotifySent = NO;
     softLockCount = 0;
 
@@ -120,15 +202,17 @@ static jmethodID windowRepaintID = NULL;
     pthread_mutex_init(&softLockSync, &softLockSyncAttr); // recursive
 
     ptrTrackingTag = 0;
-
-    /**
-    NSCursor crs = [NSCursor arrowCursor];
-    NSImage crsImg = [crs image];
-    NSPoint crsHot = [crs hotSpot];
-    myCursor = [[NSCursor alloc] initWithImage: crsImg hotSpot:crsHot];
-    */
     myCursor = NULL;
 
+    modsDown[0] = NO; // shift
+    modsDown[1] = NO; // ctrl
+    modsDown[2] = NO; // alt
+    modsDown[3] = NO; // win
+    mouseConfined = NO;
+    mouseVisible = YES;
+    mouseInside = NO;
+    cursorIsHidden = NO;
+
     DBG_PRINT("NewtView::create: %p (refcnt %d)\n", res, (int)[res retainCount]);
     return res;
 }
@@ -150,35 +234,14 @@ static jmethodID windowRepaintID = NULL;
     if( 0 < softLockCount ) {
         NSLog(@"NewtView::dealloc: softLock still hold @ dealloc!\n");
     }
-    if(0 != ptrTrackingTag) {
-        // [self removeCursorRect: ptrRect cursor: myCursor];
-        [self removeTrackingRect: ptrTrackingTag];
-        ptrTrackingTag = 0;
-    }
+    [self removeCursorRects];
+    [self removeMyCursor];
+
     pthread_mutex_destroy(&softLockSync);
     DBG_PRINT("NewtView::dealloc.X: %p\n", self);
     [super dealloc];
 }
 
-- (void) setJVMHandle: (JavaVM*) vm
-{
-    jvmHandle = vm;
-}
-- (JavaVM*) getJVMHandle
-{
-    return jvmHandle;
-}
-
-- (void) setJVMVersion: (int) ver
-{
-    jvmVersion = ver;
-}
-
-- (int) getJVMVersion
-{
-    return jvmVersion;
-}
-
 - (void) setJavaWindowObject: (jobject) javaWindowObj
 {
     javaWindowObject = javaWindowObj;
@@ -189,33 +252,6 @@ static jmethodID windowRepaintID = NULL;
     return javaWindowObject;
 }
 
-- (void) rightMouseDown: (NSEvent*) theEvent
-{
-    NSResponder* next = [self nextResponder];
-    if (next != nil) {
-        [next rightMouseDown: theEvent];
-    }
-}
-
-- (void) resetCursorRects
-{
-    [super resetCursorRects];
-
-    if(0 != ptrTrackingTag) {
-        // [self removeCursorRect: ptrRect cursor: myCursor];
-        [self removeTrackingRect: ptrTrackingTag];
-        ptrTrackingTag = 0;
-    }
-    ptrRect = [self bounds]; 
-    // [self addCursorRect: ptrRect cursor: myCursor];
-    ptrTrackingTag = [self addTrackingRect: ptrRect owner: self userData: nil assumeInside: NO];
-}
-
-- (NSCursor *) cursor
-{
-    return myCursor;
-}
-
 - (void) setDestroyNotifySent: (BOOL) v
 {
     destroyNotifySent = v;
@@ -285,7 +321,7 @@ static jmethodID windowRepaintID = NULL;
         return;
     }
     int shallBeDetached = 0;
-    JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, 1 /* asDaemon */, &shallBeDetached);
+    JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached);
     if(NULL==env) {
         DBG_PRINT("drawRect: null JNIEnv\n");
         return;
@@ -297,9 +333,8 @@ static jmethodID windowRepaintID = NULL;
         dirtyRect.origin.x, viewFrame.size.height - dirtyRect.origin.y, 
         dirtyRect.size.width, dirtyRect.size.height);
 
-    /* if (shallBeDetached) {
-        (*jvmHandle)->DetachCurrentThread(jvmHandle);
-    } */
+    // detaching thread not required - daemon
+    // NewtCommon_ReleaseJNIEnv(shallBeDetached);
 }
 
 - (void) viewDidHide
@@ -309,7 +344,7 @@ static jmethodID windowRepaintID = NULL;
         return;
     }
     int shallBeDetached = 0;
-    JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, 1 /* asDaemon */, &shallBeDetached);
+    JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached);
     if(NULL==env) {
         DBG_PRINT("viewDidHide: null JNIEnv\n");
         return;
@@ -317,9 +352,8 @@ static jmethodID windowRepaintID = NULL;
 
     (*env)->CallVoidMethod(env, javaWindowObject, visibleChangedID, JNI_FALSE, JNI_FALSE);
 
-    /* if (shallBeDetached) {
-        (*jvmHandle)->DetachCurrentThread(jvmHandle);
-    } */
+    // detaching thread not required - daemon
+    // NewtCommon_ReleaseJNIEnv(shallBeDetached);
 
     [super viewDidHide];
 }
@@ -331,7 +365,7 @@ static jmethodID windowRepaintID = NULL;
         return;
     }
     int shallBeDetached = 0;
-    JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, 1 /* asDaemon */, &shallBeDetached);
+    JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached);
     if(NULL==env) {
         DBG_PRINT("viewDidUnhide: null JNIEnv\n");
         return;
@@ -339,9 +373,8 @@ static jmethodID windowRepaintID = NULL;
 
     (*env)->CallVoidMethod(env, javaWindowObject, visibleChangedID, JNI_FALSE, JNI_TRUE);
 
-    /* if (shallBeDetached) {
-        (*jvmHandle)->DetachCurrentThread(jvmHandle);
-    } */
+    // detaching thread not required - daemon
+    // NewtCommon_ReleaseJNIEnv(shallBeDetached);
 
     [super viewDidUnhide];
 }
@@ -351,340 +384,140 @@ static jmethodID windowRepaintID = NULL;
     return YES;
 }
 
- at end
-
-static CFStringRef CKCH_CreateStringForKey(CGKeyCode keyCode, const UCKeyboardLayout *keyboardLayout) {
-    UInt32 keysDown = 0;
-    UniChar chars[4];
-    UniCharCount realLength;
-
-    UCKeyTranslate(keyboardLayout, keyCode,
-                   kUCKeyActionDisplay, 0,
-                   LMGetKbdType(), kUCKeyTranslateNoDeadKeysBit,
-                   &keysDown, sizeof(chars) / sizeof(chars[0]), &realLength, chars);
-
-    return CFStringCreateWithCharacters(kCFAllocatorDefault, chars, 1);
+- (BOOL) becomeFirstResponder
+{
+    DBG_PRINT( "*************** View.becomeFirstResponder\n");
+    return [super becomeFirstResponder];
 }
 
-static CFMutableDictionaryRef CKCH_CreateCodeToCharDict(TISInputSourceRef keyboard) {
-    CFDataRef layoutData = (CFDataRef) TISGetInputSourceProperty(keyboard, kTISPropertyUnicodeKeyLayoutData);
-    const UCKeyboardLayout *keyboardLayout = (const UCKeyboardLayout *)CFDataGetBytePtr(layoutData);
+- (BOOL) resignFirstResponder
+{
+    DBG_PRINT( "*************** View.resignFirstResponder\n");
+    return [super resignFirstResponder];
+}
 
-    CFMutableDictionaryRef codeToCharDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 128, NULL, NULL);
-    if ( NULL != codeToCharDict ) {
-        intptr_t i;
-        for (i = 0; i < 128; ++i) {
-            CFStringRef string = CKCH_CreateStringForKey((CGKeyCode)i, keyboardLayout);
-            if( NULL != string ) {
-                CFIndex stringLen = CFStringGetLength (string);
-                if ( 0 < stringLen ) {
-                    UniChar character = CFStringGetCharacterAtIndex(string, 0);
-                    DBG_PRINT("CKCH: MAP 0x%X -> %c\n", (int)i, character);
-                    CFDictionaryAddValue(codeToCharDict, (const void *)i, (const void *)(intptr_t)character);
-                }
-                CFRelease(string);
-            }
+- (void) removeCursorRects
+{
+    if(0 != ptrTrackingTag) {
+        if(NULL != myCursor) {
+            [self removeCursorRect: ptrRect cursor: myCursor];
         }
+        [self removeTrackingRect: ptrTrackingTag];
+        ptrTrackingTag = 0;
     }
-    return codeToCharDict;
 }
 
-static CFMutableDictionaryRef CKCH_USCodeToNNChar = NULL;
+- (void) addCursorRects
+{
+    ptrRect = [self bounds]; 
+    if(NULL != myCursor) {
+        [self addCursorRect: ptrRect cursor: myCursor];
+    }
+    ptrTrackingTag = [self addTrackingRect: ptrRect owner: self userData: nil assumeInside: NO];
+}
 
-static void CKCH_CreateDictionaries() {
-    TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource();
-    CKCH_USCodeToNNChar = CKCH_CreateCodeToCharDict(currentKeyboard);
-    CFRelease(currentKeyboard);
+- (void) removeMyCursor
+{
+    if(NULL != myCursor) {
+        [myCursor release];
+        myCursor = NULL;
+    }
 }
 
-static UniChar CKCH_CharForKeyCode(jshort keyCode) {
-    UniChar rChar = 0;
+- (void) resetCursorRects
+{
+    [super resetCursorRects];
 
-    if ( NULL != CKCH_USCodeToNNChar ) {
-        intptr_t code = (intptr_t) keyCode;
-        intptr_t character = 0;
+    [self removeCursorRects];
+    [self addCursorRects];
+}
 
-        if ( CFDictionaryGetValueIfPresent(CKCH_USCodeToNNChar, (void *)code, (const void **)&character) ) {
-            rChar = (UniChar) character;
-            DBG_PRINT("CKCH: OK 0x%X -> 0x%X\n", (int)keyCode, (int)rChar);
+- (void) setPointerIcon: (NSCursor*)c
+{
+    DBG_PRINT( "setPointerIcon: %p -> %p, top %p, mouseInside %d\n", myCursor, c, [NSCursor currentCursor], (int)mouseInside);
+    if( c != myCursor ) {
+        [self removeCursorRects];
+        [self removeMyCursor];
+        myCursor = c;
+        if( NULL != myCursor ) {
+            [myCursor retain];
         }
     }
-    return rChar;
+    NSWindow* nsWin = [self window];
+    if( NULL != nsWin ) {
+        [nsWin invalidateCursorRectsForView: self];
+    }
 }
 
- at implementation NewtMacWindow
-
-+ (BOOL) initNatives: (JNIEnv*) env forClass: (jclass) clazz
+- (void) mouseEntered: (NSEvent*) theEvent
 {
-    enqueueMouseEventID = (*env)->GetMethodID(env, clazz, "enqueueMouseEvent", "(ZSIIISF)V");
-    enqueueKeyEventID = (*env)->GetMethodID(env, clazz, "enqueueKeyEvent", "(ZSISCC)V");
-    sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged",     "(ZIIZ)V");
-    visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(ZZ)V");
-    insetsChangedID = (*env)->GetMethodID(env, clazz, "insetsChanged", "(ZIIII)V");
-    positionChangedID = (*env)->GetMethodID(env, clazz, "screenPositionChanged", "(ZII)V");
-    focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(ZZ)V");
-    windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "(Z)Z");
-    windowRepaintID = (*env)->GetMethodID(env, clazz, "windowRepaint", "(ZIIII)V");
-    requestFocusID = (*env)->GetMethodID(env, clazz, "requestFocus", "(Z)V");
-    if (enqueueMouseEventID && enqueueKeyEventID && sizeChangedID && visibleChangedID && insetsChangedID &&
-        positionChangedID && focusChangedID && windowDestroyNotifyID && requestFocusID && windowRepaintID)
-    {
-        CKCH_CreateDictionaries();
-        return YES;
+    DBG_PRINT( "mouseEntered: confined %d, visible %d, PointerIcon %p, top %p\n", mouseConfined, mouseVisible, myCursor, [NSCursor currentCursor]);
+    mouseInside = YES;
+    [self cursorHide: !mouseVisible enter: 1];
+    if(NO == mouseConfined) {
+        [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_ENTERED];
+    }
+    NSWindow* nsWin = [self window];
+    if( NULL != nsWin ) {
+        [nsWin makeFirstResponder: self];
     }
-    return NO;
 }
 
-- (id) initWithContentRect: (NSRect) contentRect
-       styleMask: (NSUInteger) windowStyle
-       backing: (NSBackingStoreType) bufferingType
-       defer: (BOOL) deferCreation
-       isFullscreenWindow:(BOOL)isfs
+- (void) mouseExited: (NSEvent*) theEvent
 {
-    id res = [super initWithContentRect: contentRect
-                    styleMask: windowStyle
-                    backing: bufferingType
-                    defer: deferCreation];
-    // OSX 10.6
-    if ( [NSApp respondsToSelector:@selector(currentSystemPresentationOptions)] &&
-         [NSApp respondsToSelector:@selector(setPresentationOptions:)] ) {
-        hasPresentationSwitch = YES;
-        defaultPresentationOptions = [NSApp currentSystemPresentationOptions];
-        fullscreenPresentationOptions = 
-                // NSApplicationPresentationDefault|
-                // NSApplicationPresentationAutoHideDock|
-                NSApplicationPresentationHideDock|
-                // NSApplicationPresentationAutoHideMenuBar|
-                NSApplicationPresentationHideMenuBar|
-                NSApplicationPresentationDisableAppleMenu|
-                // NSApplicationPresentationDisableProcessSwitching|
-                // NSApplicationPresentationDisableSessionTermination|
-                NSApplicationPresentationDisableHideApplication|
-                // NSApplicationPresentationDisableMenuBarTransparency|
-                // NSApplicationPresentationFullScreen| // OSX 10.7
-                0 ;
+    DBG_PRINT( "mouseExited: confined %d, visible %d, PointerIcon %p, top %p\n", mouseConfined, mouseVisible, myCursor, [NSCursor currentCursor]);
+    if(NO == mouseConfined) {
+        mouseInside = NO;
+        [self cursorHide: NO enter: -1];
+        [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_EXITED];
+        [self resignFirstResponder];
     } else {
-        hasPresentationSwitch = NO;
-        defaultPresentationOptions = 0;
-        fullscreenPresentationOptions = 0; 
-    }
-    isFullscreenWindow = isfs;
-    // Why is this necessary? Without it we don't get any of the
-    // delegate methods like resizing and window movement.
-    [self setDelegate: self];
-    cachedInsets[0] = 0; // l
-    cachedInsets[1] = 0; // r
-    cachedInsets[2] = 0; // t
-    cachedInsets[3] = 0; // b
-    modsDown[0] = NO; // shift
-    modsDown[1] = NO; // ctrl
-    modsDown[2] = NO; // alt
-    modsDown[3] = NO; // win
-    mouseConfined = NO;
-    mouseVisible = YES;
-    mouseInside = NO;
-    cursorIsHidden = NO;
-    realized = YES;
-    DBG_PRINT("NewtWindow::create: %p, realized %d, hasPresentationSwitch %d[defaultOptions 0x%X, fullscreenOptions 0x%X], (refcnt %d)\n", 
-        res, realized, (int)hasPresentationSwitch, (int)defaultPresentationOptions, (int)fullscreenPresentationOptions, (int)[res retainCount]);
-    return res;
-}
-
-#ifdef DBG_LIFECYCLE
-- (void) release
-{
-    DBG_PRINT("NewtWindow::release.0: %p (refcnt %d)\n", self, (int)[self retainCount]);
-    // NSLog(@"%@",[NSThread callStackSymbols]);
-    [super release];
-}
-#endif
-
-- (void) dealloc
-{
-    DBG_PRINT("NewtWindow::dealloc.0: %p (refcnt %d)\n", self, (int)[self retainCount]);
-#ifdef DBG_LIFECYCLE
-    NSLog(@"%@",[NSThread callStackSymbols]);
-#endif
-
-    NewtView* mView = (NewtView *)[self contentView];
-    if( NULL != mView ) {
-        [mView release];
-    }
-    [super dealloc];
-    DBG_PRINT("NewtWindow::dealloc.X: %p\n", self);
-}
-
-- (void) setRealized: (BOOL)v
-{
-    realized = v;
-}
-
-- (BOOL) isRealized
-{
-    return realized;
-}
-
-- (void) updateInsets: (JNIEnv*) env jwin: (jobject) javaWin
-{
-    NSRect frameRect = [self frame];
-    NSRect contentRect = [self contentRectForFrameRect: frameRect];
-
-    // note: this is a simplistic implementation which doesn't take
-    // into account DPI and scaling factor
-    CGFloat l = contentRect.origin.x - frameRect.origin.x;
-    cachedInsets[0] = (int)l;                                                     // l
-    cachedInsets[1] = (int)(frameRect.size.width - (contentRect.size.width + l)); // r
-    cachedInsets[2] = (jint)(frameRect.size.height - contentRect.size.height);    // t
-    cachedInsets[3] = (jint)(contentRect.origin.y - frameRect.origin.y);          // b
-
-    DBG_PRINT( "updateInsets: [ l %d, r %d, t %d, b %d ]\n", cachedInsets[0], cachedInsets[1], cachedInsets[2], cachedInsets[3]);
-
-    if( NULL != env && NULL != javaWin ) {
-        (*env)->CallVoidMethod(env, javaWin, insetsChangedID, JNI_FALSE, cachedInsets[0], cachedInsets[1], cachedInsets[2], cachedInsets[3]);
+        [self setMousePosition: lastInsideMousePosition];
     }
 }
 
-- (void) attachToParent: (NSWindow*) parent
+- (void) setMousePosition:(NSPoint)p
 {
-    DBG_PRINT( "attachToParent.1\n");
-    [parent addChildWindow: self ordered: NSWindowAbove];
-    DBG_PRINT( "attachToParent.2\n");
-    [self setParentWindow: parent];
-    DBG_PRINT( "attachToParent.X\n");
-}
+    NSWindow* nsWin = [self window];
+    if( NULL != nsWin ) {
+        NSScreen* screen = [nsWin screen];
+        NSRect screenRect = [screen frame];
 
-- (void) detachFromParent: (NSWindow*) parent
-{
-    DBG_PRINT( "detachFromParent.1\n");
-    [self setParentWindow: nil];
-    if(NULL != parent) {
-        DBG_PRINT( "detachFromParent.2\n");
-        [parent removeChildWindow: self];
+        CGPoint pt = { p.x, screenRect.size.height - p.y }; // y-flip (CG is top-left origin)
+        CGEventRef ev = CGEventCreateMouseEvent (NULL, kCGEventMouseMoved, pt, kCGMouseButtonLeft);
+        CGEventPost (kCGHIDEventTap, ev);
     }
-    DBG_PRINT( "detachFromParent.X\n");
-}
-
-/**
- * p abs screen position of client-area pos w/ top-left origin, using contentView's client NSSize
- * returns: abs screen position w/ bottom-left origin
- */
-- (NSPoint) newtAbsClientTLWinPos2AbsBLScreenPos: (NSPoint) p
-{
-    NSView* mView = [self contentView];
-    NSRect mViewFrame = [mView frame]; 
-    return [self newtAbsClientTLWinPos2AbsBLScreenPos: p size: mViewFrame.size];
 }
 
-/**
- * p abs screen position of client-area pos w/ top-left origin, using given client NSSize
- * returns: abs screen position w/ bottom-left origin
- */
-- (NSPoint) newtAbsClientTLWinPos2AbsBLScreenPos: (NSPoint) p size: (NSSize) nsz
+- (BOOL) updateMouseInside
 {
-    int totalHeight = nsz.height + cachedInsets[3]; // height + insets.bottom
-
-    DBG_PRINT( "newtAbsClientTLWinPos2AbsBLScreenPos: given %d/%d %dx%d, insets bottom %d -> totalHeight %d\n", 
-        (int)p.x, (int)p.y, (int)nsz.width, (int)nsz.height, cachedInsets[3], totalHeight);
-
-    NSScreen* screen = [self screen];
-    NSRect screenFrame = [screen frame];
-
-    DBG_PRINT( "newtAbsClientTLWinPos2AbsBLScreenPos: screen %d/%d %dx%d\n", 
-        (int)screenFrame.origin.x, (int)screenFrame.origin.y, (int)screenFrame.size.width, (int)screenFrame.size.height);
-
-    NSPoint r = NSMakePoint(screenFrame.origin.x + p.x,
-                            screenFrame.origin.y + screenFrame.size.height - p.y - totalHeight);
-
-    DBG_PRINT( "newtAbsClientTLWinPos2AbsBLScreenPos: result %d/%d\n", (int)r.x, (int)r.y); 
-
-    return r;
-}
-
-/**
- * p rel client window position w/ top-left origin
- * returns: abs screen position w/ bottom-left origin
- */
-- (NSPoint) newtRelClientTLWinPos2AbsBLScreenPos: (NSPoint) p
-{
-    NSRect winFrame = [self frame];
-
-    NSView* mView = [self contentView];
-    NSRect mViewFrame = [mView frame]; 
-
-    return NSMakePoint(winFrame.origin.x + p.x,
-                       winFrame.origin.y + ( mViewFrame.size.height - p.y ) ); // y-flip in view
-}
-
-- (NSSize) newtClientSize2TLSize: (NSSize) nsz
-{
-    NSSize topSZ = { nsz.width, nsz.height + cachedInsets[2] + cachedInsets[3] }; // height + insets.top + insets.bottom
-    return topSZ;
-}
-
-/**
- * y-flips input / output
- * p rel client window position w/ top-left origin
- * returns: location in 0/0 top-left space.
- */
-- (NSPoint) getLocationOnScreen: (NSPoint) p
-{
-    NSScreen* screen = [self screen];
-    NSRect screenRect = [screen frame];
-
-    NSView* view = [self contentView];
-    NSRect viewFrame = [view frame];
-
-    NSRect r;
-    r.origin.x = p.x;
-    r.origin.y = viewFrame.size.height - p.y; // y-flip
-    r.size.width = 0;
-    r.size.height = 0;
-    // NSRect rS = [win convertRectToScreen: r]; // 10.7
-    NSPoint oS = [self convertBaseToScreen: r.origin];
-    oS.y = screenRect.origin.y + screenRect.size.height - oS.y;
-    return oS;
-}
-
-- (NSPoint) screenPos2NewtClientWinPos: (NSPoint) p
-{
-    NSView* view = [self contentView];
-    NSRect viewFrame = [view frame];
-
-    NSRect r;
-    r.origin.x = p.x;
-    r.origin.y = p.y;
-    r.size.width = 0;
-    r.size.height = 0;
-    // NSRect rS = [win convertRectFromScreen: r]; // 10.7
-    NSPoint oS = [self convertScreenToBase: r.origin];
-    oS.y = viewFrame.size.height - oS.y; // y-flip
-    return oS;
-}
-
-- (BOOL) isMouseInside
-{
-    NSView* view = [self contentView];
-    NSRect viewFrame = [view frame];
+    NSRect viewFrame = [self frame];
     NSPoint l1 = [NSEvent mouseLocation];
     NSPoint l0 = [self screenPos2NewtClientWinPos: l1];
-    return viewFrame.origin.x <= l0.x && l0.x < (viewFrame.origin.x+viewFrame.size.width) &&
-           viewFrame.origin.y <= l0.y && l0.y < (viewFrame.origin.y+viewFrame.size.height) ;
+    mouseInside = viewFrame.origin.x <= l0.x && l0.x < (viewFrame.origin.x+viewFrame.size.width) &&
+                  viewFrame.origin.y <= l0.y && l0.y < (viewFrame.origin.y+viewFrame.size.height) ;
+    return mouseInside;
 }
 
 - (void) setMouseVisible:(BOOL)v hasFocus:(BOOL)focus
 {
     mouseVisible = v;
-    mouseInside = [self isMouseInside];
+    [self updateMouseInside];
     DBG_PRINT( "setMouseVisible: confined %d, visible %d (current: %d), mouseInside %d, hasFocus %d\n", 
         mouseConfined, mouseVisible, !cursorIsHidden, mouseInside, focus);
     if(YES == focus && YES == mouseInside) {
-        [self cursorHide: !mouseVisible];
+        [self cursorHide: !mouseVisible enter: 0];
     }
 }
+- (BOOL) isMouseVisible
+{
+    return mouseVisible;
+}
 
-- (void) cursorHide:(BOOL)v
+- (void) cursorHide:(BOOL)v enter:(int)enterState
 {
-    DBG_PRINT( "cursorHide: %d -> %d\n", cursorIsHidden, v);
+    DBG_PRINT( "cursorHide: %d -> %d, enter %d; PointerIcon: %p, top %p\n", 
+        cursorIsHidden, v, enterState, myCursor, [NSCursor currentCursor]);
     if(v) {
         if(!cursorIsHidden) {
             [NSCursor hide];
@@ -704,120 +537,93 @@ static UniChar CKCH_CharForKeyCode(jshort keyCode) {
     DBG_PRINT( "setMouseConfined: confined %d, visible %d\n", mouseConfined, mouseVisible);
 }
 
-- (void) setMousePosition:(NSPoint)p
+- (void) mouseMoved: (NSEvent*) theEvent
 {
-    NSScreen* screen = [self screen];
-    NSRect screenRect = [screen frame];
-
-    CGPoint pt = { p.x, screenRect.size.height - p.y }; // y-flip (CG is top-left origin)
-    CGEventRef ev = CGEventCreateMouseEvent (NULL, kCGEventMouseMoved, pt, kCGMouseButtonLeft);
-    CGEventPost (kCGHIDEventTap, ev);
+    if( mouseInside ) {
+        NSCursor * currentCursor = [NSCursor currentCursor];
+        BOOL setCursor = NULL != myCursor && NO == cursorIsHidden && currentCursor != myCursor;
+        DBG_PRINT( "mouseMoved.set: %d; mouseInside %d, CursorHidden %d, PointerIcon: %p, top %p\n", 
+            setCursor, mouseInside, cursorIsHidden, myCursor, currentCursor);
+        if( setCursor ) {
+            // FIXME: Workaround missing NSCursor update for 'fast moving' pointer 
+            [myCursor set];
+        }
+        lastInsideMousePosition = [NSEvent mouseLocation];
+        [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED];
+    }
 }
 
-static jint mods2JavaMods(NSUInteger mods)
+- (void) scrollWheel: (NSEvent*) theEvent
 {
-    int javaMods = 0;
-    if (mods & NSShiftKeyMask) {
-        javaMods |= EVENT_SHIFT_MASK;
-    }
-    if (mods & NSControlKeyMask) {
-        javaMods |= EVENT_CTRL_MASK;
-    }
-    if (mods & NSCommandKeyMask) {
-        javaMods |= EVENT_META_MASK;
-    }
-    if (mods & NSAlternateKeyMask) {
-        javaMods |= EVENT_ALT_MASK;
-    }
-    return javaMods;
+    [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_WHEEL_MOVED];
 }
 
-- (void) sendKeyEvent: (NSEvent*) event eventType: (jshort) evType
+- (void) mouseDown: (NSEvent*) theEvent
 {
-    jshort keyCode = (jshort) [event keyCode];
-    NSString* chars = [event charactersIgnoringModifiers];
-    NSUInteger mods = [event modifierFlags];
-    [self sendKeyEvent: keyCode characters: chars modifiers: mods eventType: evType];
+    [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_PRESSED];
 }
 
-- (void) sendKeyEvent: (jshort) keyCode characters: (NSString*) chars modifiers: (NSUInteger)mods eventType: (jshort) evType
+- (void) mouseDragged: (NSEvent*) theEvent
 {
-    NSView* nsview = [self contentView];
-    if( ! [nsview isKindOfClass:[NewtView class]] ) {
-        return;
-    }
-    NewtView* view = (NewtView *) nsview;
-    jobject javaWindowObject = [view getJavaWindowObject];
-    if (javaWindowObject == NULL) {
-        DBG_PRINT("sendKeyEvent: null javaWindowObject\n");
-        return;
-    }
-    int shallBeDetached = 0;
-    JavaVM *jvmHandle = [view getJVMHandle];
-    JNIEnv* env;
-    if( NULL != jvmHandle ) {
-        env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], 1 /* asDaemon */, &shallBeDetached);
-    } else {
-        env = NULL;
-    }
-    if(NULL==env) {
-        DBG_PRINT("sendKeyEvent: JVM %p JNIEnv %p\n", jvmHandle, env);
-        return;
-    }
+    lastInsideMousePosition = [NSEvent mouseLocation];
+    // Note use of MOUSE_MOVED event type because mouse dragged events are synthesized by Java
+    [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED];
+}
 
-    int i;
-    int len = NULL != chars ? [chars length] : 0;
-    jint javaMods = mods2JavaMods(mods);
+- (void) mouseUp: (NSEvent*) theEvent
+{
+    [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_RELEASED];
+}
 
-    if(len > 0) {
-        // printable chars
-        for (i = 0; i < len; i++) {
-            // Note: the key code in the NSEvent does not map to anything we can use
-            UniChar keyChar = (UniChar) [chars characterAtIndex: i];
-            UniChar keySymChar = CKCH_CharForKeyCode(keyCode);
+- (void) rightMouseDown: (NSEvent*) theEvent
+{
+    NSResponder* next = [self nextResponder];
+    if (next != nil) {
+        [next rightMouseDown: theEvent];
+    }
+    // FIXME: ^^ OR [super rightMouseDown: theEvent] ?
+    [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_PRESSED];
+}
 
-            DBG_PRINT("sendKeyEvent: %d/%d code 0x%X, char 0x%X -> keySymChar 0x%X\n", i, len, (int)keyCode, (int)keyChar, (int)keySymChar);
+- (void) rightMouseDragged: (NSEvent*) theEvent
+{
+    lastInsideMousePosition = [NSEvent mouseLocation];
+    // Note use of MOUSE_MOVED event type because mouse dragged events are synthesized by Java
+    [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED];
+}
 
-            (*env)->CallVoidMethod(env, javaWindowObject, enqueueKeyEventID, JNI_FALSE,
-                                   evType, javaMods, keyCode, (jchar)keyChar, (jchar)keySymChar);
-        }
-    } else {
-        // non-printable chars
-        jchar keyChar = (jchar) 0;
+- (void) rightMouseUp: (NSEvent*) theEvent
+{
+    [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_RELEASED];
+}
 
-        DBG_PRINT("sendKeyEvent: code 0x%X\n", (int)keyCode);
+- (void) otherMouseDown: (NSEvent*) theEvent
+{
+    [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_PRESSED];
+}
 
-        (*env)->CallVoidMethod(env, javaWindowObject, enqueueKeyEventID, JNI_FALSE,
-                               evType, javaMods, keyCode, keyChar, keyChar);
-    }
+- (void) otherMouseDragged: (NSEvent*) theEvent
+{
+    lastInsideMousePosition = [NSEvent mouseLocation];
+    // Note use of MOUSE_MOVED event type because mouse dragged events are synthesized by Java
+    [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED];
+}
 
-    /* if (shallBeDetached) {
-        (*jvmHandle)->DetachCurrentThread(jvmHandle);
-    } */
+- (void) otherMouseUp: (NSEvent*) theEvent
+{
+    [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_RELEASED];
 }
 
 - (void) sendMouseEvent: (NSEvent*) event eventType: (jshort) evType
 {
-    NSView* nsview = [self contentView];
-    if( ! [nsview isKindOfClass:[NewtView class]] ) {
-        return;
-    }
-    NewtView* view = (NewtView *) nsview;
-    jobject javaWindowObject = [view getJavaWindowObject];
     if (javaWindowObject == NULL) {
         DBG_PRINT("sendMouseEvent: null javaWindowObject\n");
         return;
     }
     int shallBeDetached = 0;
-    JavaVM *jvmHandle = [view getJVMHandle];
-    JNIEnv* env;
-    if( NULL != jvmHandle ) {
-        env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], 1 /* asDaemon */, &shallBeDetached);
-    } else {
-        env = NULL;
-    }
+    JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached);
     if(NULL==env) {
-        DBG_PRINT("sendMouseEvent: JVM %p JNIEnv %p\n", jvmHandle, env);
+        DBG_PRINT("sendMouseEvent: null JNIEnv\n");
         return;
     }
     jint javaMods[] = { 0 } ;
@@ -865,274 +671,481 @@ static jint mods2JavaMods(NSUInteger mods)
                            (jint) location.x, (jint) location.y,
                            javaButtonNum, scrollDeltaY);
 
-    /* if (shallBeDetached) {
-        (*jvmHandle)->DetachCurrentThread(jvmHandle);
-    } */
+    // detaching thread not required - daemon
+    // NewtCommon_ReleaseJNIEnv(shallBeDetached);
 }
 
-- (void) focusChanged: (BOOL) gained
+- (NSPoint) screenPos2NewtClientWinPos: (NSPoint) p
 {
-    DBG_PRINT( "focusChanged: gained %d\n", gained);
-    NSView* nsview = [self contentView];
-    if( ! [nsview isKindOfClass:[NewtView class]] ) {
-        return;
+    NSRect viewFrame = [self frame];
+
+    NSRect r;
+    r.origin.x = p.x;
+    r.origin.y = p.y;
+    r.size.width = 0;
+    r.size.height = 0;
+    // NSRect rS = [[self window] convertRectFromScreen: r]; // 10.7
+    NSPoint oS = [[self window] convertScreenToBase: r.origin];
+    oS.y = viewFrame.size.height - oS.y; // y-flip
+    return oS;
+}
+
+- (void) handleFlagsChanged:(NSUInteger) mods
+{
+    [self handleFlagsChanged: NSShiftKeyMask keyIndex: 0 keyCode: kVK_Shift modifiers: mods];
+    [self handleFlagsChanged: NSControlKeyMask keyIndex: 1 keyCode: kVK_Control modifiers: mods];
+    [self handleFlagsChanged: NSAlternateKeyMask keyIndex: 2 keyCode: kVK_Option modifiers: mods];
+    [self handleFlagsChanged: NSCommandKeyMask keyIndex: 3 keyCode: kVK_Command modifiers: mods];
+}
+
+- (void) handleFlagsChanged:(int) keyMask keyIndex: (int) keyIdx keyCode: (int) keyCode modifiers: (NSUInteger) mods
+{
+    if ( NO == modsDown[keyIdx] && 0 != ( mods & keyMask ) )  {
+        modsDown[keyIdx] = YES;
+        [self sendKeyEvent: (jshort)keyCode characters: NULL modifiers: mods|keyMask eventType: (jshort)EVENT_KEY_PRESSED];
+    } else if ( YES == modsDown[keyIdx] && 0 == ( mods & keyMask ) )  {
+        modsDown[keyIdx] = NO;
+        [self sendKeyEvent: (jshort)keyCode characters: NULL modifiers: mods|keyMask eventType: (jshort)EVENT_KEY_RELEASED];
     }
-    NewtView* view = (NewtView *) nsview;
-    jobject javaWindowObject = [view getJavaWindowObject];
+}
+
+- (void) sendKeyEvent: (NSEvent*) event eventType: (jshort) evType
+{
+    jshort keyCode = (jshort) [event keyCode];
+    NSString* chars = [event charactersIgnoringModifiers];
+    NSUInteger mods = [event modifierFlags];
+    [self sendKeyEvent: keyCode characters: chars modifiers: mods eventType: evType];
+}
+
+- (void) sendKeyEvent: (jshort) keyCode characters: (NSString*) chars modifiers: (NSUInteger)mods eventType: (jshort) evType
+{
     if (javaWindowObject == NULL) {
-        DBG_PRINT("focusChanged: null javaWindowObject\n");
+        DBG_PRINT("sendKeyEvent: null javaWindowObject\n");
         return;
     }
     int shallBeDetached = 0;
-    JavaVM *jvmHandle = [view getJVMHandle];
-    JNIEnv* env;
-    if( NULL != jvmHandle ) {
-        env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], 1 /* asDaemon */, &shallBeDetached);
-    } else {
-        env = NULL;
-    }
+    JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached);
     if(NULL==env) {
-        DBG_PRINT("focusChanged: JVM %p JNIEnv %p\n", jvmHandle, env);
+        DBG_PRINT("sendKeyEvent: null JNIEnv\n");
         return;
     }
 
-    (*env)->CallVoidMethod(env, javaWindowObject, focusChangedID, JNI_FALSE, (gained == YES) ? JNI_TRUE : JNI_FALSE);
+    int i;
+    int len = NULL != chars ? [chars length] : 0;
+    jint javaMods = mods2JavaMods(mods);
 
-    /* if (shallBeDetached) {
-        (*jvmHandle)->DetachCurrentThread(jvmHandle);
-    } */
+    if(len > 0) {
+        // printable chars
+        for (i = 0; i < len; i++) {
+            // Note: the key code in the NSEvent does not map to anything we can use
+            UniChar keyChar = (UniChar) [chars characterAtIndex: i];
+            UniChar keySymChar = CKCH_CharForKeyCode(keyCode);
+
+            DBG_PRINT("sendKeyEvent: %d/%d code 0x%X, char 0x%X, mods 0x%X/0x%X -> keySymChar 0x%X\n", i, len, (int)keyCode, (int)keyChar, 
+                      (int)mods, (int)javaMods, (int)keySymChar);
+
+            (*env)->CallVoidMethod(env, javaWindowObject, enqueueKeyEventID, JNI_FALSE,
+                                   evType, javaMods, keyCode, (jchar)keyChar, (jchar)keySymChar);
+        }
+    } else {
+        // non-printable chars
+        jchar keyChar = (jchar) 0;
+
+        DBG_PRINT("sendKeyEvent: code 0x%X\n", (int)keyCode);
+
+        (*env)->CallVoidMethod(env, javaWindowObject, enqueueKeyEventID, JNI_FALSE,
+                               evType, javaMods, keyCode, keyChar, keyChar);
+    }
+
+    // detaching thread not required - daemon
+    // NewtCommon_ReleaseJNIEnv(shallBeDetached);
+}
+
+ at end
+
+ at implementation NewtMacWindow
+
++ (BOOL) initNatives: (JNIEnv*) env forClass: (jclass) clazz
+{
+    enqueueMouseEventID = (*env)->GetMethodID(env, clazz, "enqueueMouseEvent", "(ZSIIISF)V");
+    enqueueKeyEventID = (*env)->GetMethodID(env, clazz, "enqueueKeyEvent", "(ZSISCC)V");
+    sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged",     "(ZIIZ)V");
+    visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(ZZ)V");
+    insetsChangedID = (*env)->GetMethodID(env, clazz, "insetsChanged", "(ZIIII)V");
+    positionChangedID = (*env)->GetMethodID(env, clazz, "screenPositionChanged", "(ZII)V");
+    focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(ZZ)V");
+    windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "(Z)Z");
+    windowRepaintID = (*env)->GetMethodID(env, clazz, "windowRepaint", "(ZIIII)V");
+    requestFocusID = (*env)->GetMethodID(env, clazz, "requestFocus", "(Z)V");
+    if (enqueueMouseEventID && enqueueKeyEventID && sizeChangedID && visibleChangedID && insetsChangedID &&
+        positionChangedID && focusChangedID && windowDestroyNotifyID && requestFocusID && windowRepaintID)
+    {
+        CKCH_CreateDictionaries();
+        return YES;
+    }
+    return NO;
+}
+
+- (id) initWithContentRect: (NSRect) contentRect
+       styleMask: (NSUInteger) windowStyle
+       backing: (NSBackingStoreType) bufferingType
+       defer: (BOOL) deferCreation
+       isFullscreenWindow:(BOOL)isfs
+{
+    id res = [super initWithContentRect: contentRect
+                    styleMask: windowStyle
+                    backing: bufferingType
+                    defer: deferCreation];
+    // OSX 10.6
+    if ( [NSApp respondsToSelector:@selector(currentSystemPresentationOptions)] &&
+         [NSApp respondsToSelector:@selector(setPresentationOptions:)] ) {
+        hasPresentationSwitch = YES;
+        defaultPresentationOptions = [NSApp currentSystemPresentationOptions];
+        fullscreenPresentationOptions = 
+                // NSApplicationPresentationDefault|
+                // NSApplicationPresentationAutoHideDock|
+                NSApplicationPresentationHideDock|
+                // NSApplicationPresentationAutoHideMenuBar|
+                NSApplicationPresentationHideMenuBar|
+                NSApplicationPresentationDisableAppleMenu|
+                // NSApplicationPresentationDisableProcessSwitching|
+                // NSApplicationPresentationDisableSessionTermination|
+                NSApplicationPresentationDisableHideApplication|
+                // NSApplicationPresentationDisableMenuBarTransparency|
+                // NSApplicationPresentationFullScreen| // OSX 10.7
+                0 ;
+    } else {
+        hasPresentationSwitch = NO;
+        defaultPresentationOptions = 0;
+        fullscreenPresentationOptions = 0; 
+    }
+
+    isFullscreenWindow = isfs;
+    // Why is this necessary? Without it we don't get any of the
+    // delegate methods like resizing and window movement.
+    [self setDelegate: self];
+    cachedInsets[0] = 0; // l
+    cachedInsets[1] = 0; // r
+    cachedInsets[2] = 0; // t
+    cachedInsets[3] = 0; // b
+    realized = YES;
+    DBG_PRINT("NewtWindow::create: %p, realized %d, hasPresentationSwitch %d[defaultOptions 0x%X, fullscreenOptions 0x%X], (refcnt %d)\n", 
+        res, realized, (int)hasPresentationSwitch, (int)defaultPresentationOptions, (int)fullscreenPresentationOptions, (int)[res retainCount]);
+    return res;
+}
+
+#ifdef DBG_LIFECYCLE
+- (void) release
+{
+    DBG_PRINT("NewtWindow::release.0: %p (refcnt %d)\n", self, (int)[self retainCount]);
+    // NSLog(@"%@",[NSThread callStackSymbols]);
+    [super release];
 }
+#endif
 
-- (BOOL) becomeFirstResponder
+- (void) dealloc
 {
-    DBG_PRINT( "*************** becomeFirstResponder\n");
-    return [super becomeFirstResponder];
+    DBG_PRINT("NewtWindow::dealloc.0: %p (refcnt %d)\n", self, (int)[self retainCount]);
+#ifdef DBG_LIFECYCLE
+    NSLog(@"%@",[NSThread callStackSymbols]);
+#endif
+
+    NewtView* mView = (NewtView *)[self contentView];
+    if( NULL != mView ) {
+        [mView release];
+    }
+    [super dealloc];
+    DBG_PRINT("NewtWindow::dealloc.X: %p\n", self);
 }
 
-- (BOOL) resignFirstResponder
+- (void) setRealized: (BOOL)v
 {
-    DBG_PRINT( "*************** resignFirstResponder\n");
-    return [super resignFirstResponder];
+    realized = v;
 }
 
-- (BOOL) canBecomeKeyWindow
+- (BOOL) isRealized
 {
-    // Even if the window is borderless, we still want it to be able
-    // to become the key window to receive keyboard events
-    return YES;
+    return realized;
 }
 
-- (void) becomeKeyWindow
+- (void) updateInsets: (JNIEnv*) env jwin: (jobject) javaWin
 {
-    DBG_PRINT( "*************** becomeKeyWindow\n");
-    [super becomeKeyWindow];
+    NSRect frameRect = [self frame];
+    NSRect contentRect = [self contentRectForFrameRect: frameRect];
+
+    // note: this is a simplistic implementation which doesn't take
+    // into account DPI and scaling factor
+    CGFloat l = contentRect.origin.x - frameRect.origin.x;
+    cachedInsets[0] = (int)l;                                                     // l
+    cachedInsets[1] = (int)(frameRect.size.width - (contentRect.size.width + l)); // r
+    cachedInsets[2] = (jint)(frameRect.size.height - contentRect.size.height);    // t
+    cachedInsets[3] = (jint)(contentRect.origin.y - frameRect.origin.y);          // b
+
+    DBG_PRINT( "updateInsets: [ l %d, r %d, t %d, b %d ]\n", cachedInsets[0], cachedInsets[1], cachedInsets[2], cachedInsets[3]);
+
+    if( NULL != env && NULL != javaWin ) {
+        (*env)->CallVoidMethod(env, javaWin, insetsChangedID, JNI_FALSE, cachedInsets[0], cachedInsets[1], cachedInsets[2], cachedInsets[3]);
+    }
 }
 
-- (void) resignKeyWindow
+- (void) attachToParent: (NSWindow*) parent
 {
-    DBG_PRINT( "*************** resignKeyWindow: isFullscreen %d\n", (int)isFullscreenWindow);
-    if(!isFullscreenWindow) {
-        [super resignKeyWindow];
-    }
+    DBG_PRINT( "attachToParent.1\n");
+    [parent addChildWindow: self ordered: NSWindowAbove];
+    DBG_PRINT( "attachToParent.2\n");
+    [self setParentWindow: parent];
+    DBG_PRINT( "attachToParent.X\n");
 }
 
-- (void) windowDidBecomeKey: (NSNotification *) notification
+- (void) detachFromParent: (NSWindow*) parent
 {
-    DBG_PRINT( "*************** windowDidBecomeKey\n");
-    mouseInside = [self isMouseInside];
-    if(YES == mouseInside) {
-        [self cursorHide: !mouseVisible];
+    DBG_PRINT( "detachFromParent.1\n");
+    [self setParentWindow: nil];
+    if(NULL != parent) {
+        DBG_PRINT( "detachFromParent.2\n");
+        [parent removeChildWindow: self];
     }
-    [self focusChanged: YES];
+    DBG_PRINT( "detachFromParent.X\n");
 }
 
-- (void) windowDidResignKey: (NSNotification *) notification
+/**
+ * p abs screen position of client-area pos w/ top-left origin, using contentView's client NSSize
+ * returns: abs screen position w/ bottom-left origin
+ */
+- (NSPoint) newtAbsClientTLWinPos2AbsBLScreenPos: (NSPoint) p
 {
-    DBG_PRINT( "*************** windowDidResignKey\n");
-    // Implicit mouse exit by OS X
-    [self focusChanged: NO];
+    NSView* mView = [self contentView];
+    NSRect mViewFrame = [mView frame]; 
+    return [self newtAbsClientTLWinPos2AbsBLScreenPos: p size: mViewFrame.size];
 }
 
-- (void) keyDown: (NSEvent*) theEvent
+/**
+ * p abs screen position of client-area pos w/ top-left origin, using given client NSSize
+ * returns: abs screen position w/ bottom-left origin
+ */
+- (NSPoint) newtAbsClientTLWinPos2AbsBLScreenPos: (NSPoint) p size: (NSSize) nsz
 {
-    [self sendKeyEvent: theEvent eventType: (jshort)EVENT_KEY_PRESSED];
+    int totalHeight = nsz.height + cachedInsets[3]; // height + insets.bottom
+
+    DBG_PRINT( "newtAbsClientTLWinPos2AbsBLScreenPos: given %d/%d %dx%d, insets bottom %d -> totalHeight %d\n", 
+        (int)p.x, (int)p.y, (int)nsz.width, (int)nsz.height, cachedInsets[3], totalHeight);
+
+    NSScreen* screen = [self screen];
+    NSRect screenFrame = [screen frame];
+
+    DBG_PRINT( "newtAbsClientTLWinPos2AbsBLScreenPos: screen %d/%d %dx%d\n", 
+        (int)screenFrame.origin.x, (int)screenFrame.origin.y, (int)screenFrame.size.width, (int)screenFrame.size.height);
+
+    NSPoint r = NSMakePoint(screenFrame.origin.x + p.x,
+                            screenFrame.origin.y + screenFrame.size.height - p.y - totalHeight);
+
+    DBG_PRINT( "newtAbsClientTLWinPos2AbsBLScreenPos: result %d/%d\n", (int)r.x, (int)r.y); 
+
+    return r;
 }
 
-- (void) keyUp: (NSEvent*) theEvent
+/**
+ * p rel client window position w/ top-left origin
+ * returns: abs screen position w/ bottom-left origin
+ */
+- (NSPoint) newtRelClientTLWinPos2AbsBLScreenPos: (NSPoint) p
 {
-    [self sendKeyEvent: theEvent eventType: (jshort)EVENT_KEY_RELEASED];
-}
+    NSRect winFrame = [self frame];
 
-#define kVK_Shift     0x38
-#define kVK_Option    0x3A
-#define kVK_Control   0x3B
-#define kVK_Command   0x37
+    NSView* mView = [self contentView];
+    NSRect mViewFrame = [mView frame]; 
 
-- (void) handleFlagsChanged:(int) keyMask keyIndex: (int) keyIdx keyCode: (int) keyCode modifiers: (NSUInteger) mods
+    return NSMakePoint(winFrame.origin.x + p.x,
+                       winFrame.origin.y + ( mViewFrame.size.height - p.y ) ); // y-flip in view
+}
+
+- (NSSize) newtClientSize2TLSize: (NSSize) nsz
 {
-    if ( NO == modsDown[keyIdx] && 0 != ( mods & keyMask ) )  {
-        modsDown[keyIdx] = YES;
-        [self sendKeyEvent: (jshort)keyCode characters: NULL modifiers: mods|keyMask eventType: (jshort)EVENT_KEY_PRESSED];
-    } else if ( YES == modsDown[keyIdx] && 0 == ( mods & keyMask ) )  {
-        modsDown[keyIdx] = NO;
-        [self sendKeyEvent: (jshort)keyCode characters: NULL modifiers: mods|keyMask eventType: (jshort)EVENT_KEY_RELEASED];
-    }
+    NSSize topSZ = { nsz.width, nsz.height + cachedInsets[2] + cachedInsets[3] }; // height + insets.top + insets.bottom
+    return topSZ;
 }
 
-- (void) flagsChanged:(NSEvent *) theEvent
+/**
+ * y-flips input / output
+ * p rel client window position w/ top-left origin
+ * returns: location in 0/0 top-left space.
+ */
+- (NSPoint) getLocationOnScreen: (NSPoint) p
 {
-    NSUInteger mods = [theEvent modifierFlags];
+    NSScreen* screen = [self screen];
+    NSRect screenRect = [screen frame];
 
-    // BOOL modsDown[4]; // shift, ctrl, alt/option, win/command
+    NSView* view = [self contentView];
+    NSRect viewFrame = [view frame];
 
-    [self handleFlagsChanged: NSShiftKeyMask keyIndex: 0 keyCode: kVK_Shift modifiers: mods];
-    [self handleFlagsChanged: NSControlKeyMask keyIndex: 1 keyCode: kVK_Control modifiers: mods];
-    [self handleFlagsChanged: NSAlternateKeyMask keyIndex: 2 keyCode: kVK_Option modifiers: mods];
-    [self handleFlagsChanged: NSCommandKeyMask keyIndex: 3 keyCode: kVK_Command modifiers: mods];
+    NSRect r;
+    r.origin.x = p.x;
+    r.origin.y = viewFrame.size.height - p.y; // y-flip
+    r.size.width = 0;
+    r.size.height = 0;
+    // NSRect rS = [win convertRectToScreen: r]; // 10.7
+    NSPoint oS = [self convertBaseToScreen: r.origin];
+    oS.y = screenRect.origin.y + screenRect.size.height - oS.y;
+    return oS;
 }
 
-- (void) mouseEntered: (NSEvent*) theEvent
+- (void) focusChanged: (BOOL) gained
 {
-    DBG_PRINT( "mouseEntered: confined %d, visible %d\n", mouseConfined, mouseVisible);
-    mouseInside = YES;
-    [self cursorHide: !mouseVisible];
-    if(NO == mouseConfined) {
-        [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_ENTERED];
+    DBG_PRINT( "focusChanged: gained %d\n", gained);
+    NewtView* newtView = (NewtView *) [self contentView];
+    if( ! [newtView isKindOfClass:[NewtView class]] ) {
+        return;
+    }
+    jobject javaWindowObject = [newtView getJavaWindowObject];
+    if (javaWindowObject == NULL) {
+        DBG_PRINT("focusChanged: null javaWindowObject\n");
+        return;
+    }
+    int shallBeDetached = 0;
+    JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached);
+    if(NULL==env) {
+        DBG_PRINT("focusChanged: null JNIEnv\n");
+        return;
     }
+
+    (*env)->CallVoidMethod(env, javaWindowObject, focusChangedID, JNI_FALSE, (gained == YES) ? JNI_TRUE : JNI_FALSE);
+
+    // detaching thread not required - daemon
+    // NewtCommon_ReleaseJNIEnv(shallBeDetached);
 }
 
-- (void) mouseExited: (NSEvent*) theEvent
+- (void) keyDown: (NSEvent*) theEvent
 {
-    DBG_PRINT( "mouseExited: confined %d, visible %d\n", mouseConfined, mouseVisible);
-    if(NO == mouseConfined) {
-        mouseInside = NO;
-        [self cursorHide: NO];
-        [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_EXITED];
-    } else {
-        [self setMousePosition: lastInsideMousePosition];
+    NewtView* newtView = (NewtView *) [self contentView];
+    if( [newtView isKindOfClass:[NewtView class]] ) {
+        [newtView sendKeyEvent: theEvent eventType: (jshort)EVENT_KEY_PRESSED];
     }
 }
 
-- (void) mouseMoved: (NSEvent*) theEvent
+- (void) keyUp: (NSEvent*) theEvent
 {
-    lastInsideMousePosition = [NSEvent mouseLocation];
-    [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED];
+    NewtView* newtView = (NewtView *) [self contentView];
+    if( [newtView isKindOfClass:[NewtView class]] ) {
+        [newtView sendKeyEvent: theEvent eventType: (jshort)EVENT_KEY_RELEASED];
+    }
 }
 
-- (void) scrollWheel: (NSEvent*) theEvent
+- (void) flagsChanged:(NSEvent *) theEvent
 {
-    [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_WHEEL_MOVED];
+    NSUInteger mods = [theEvent modifierFlags];
+    NewtView* newtView = (NewtView *) [self contentView];
+    if( [newtView isKindOfClass:[NewtView class]] ) {
+        [newtView handleFlagsChanged: mods];
+    }
 }
 
-- (void) mouseDown: (NSEvent*) theEvent
+- (BOOL) acceptsMouseMovedEvents
 {
-    [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_PRESSED];
+    return YES;
 }
 
-- (void) mouseDragged: (NSEvent*) theEvent
+- (BOOL) acceptsFirstResponder 
 {
-    lastInsideMousePosition = [NSEvent mouseLocation];
-    // Note use of MOUSE_MOVED event type because mouse dragged events are synthesized by Java
-    [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED];
+    return YES;
 }
 
-- (void) mouseUp: (NSEvent*) theEvent
+- (BOOL) becomeFirstResponder
 {
-    [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_RELEASED];
+    DBG_PRINT( "*************** Win.becomeFirstResponder\n");
+    return [super becomeFirstResponder];
 }
 
-- (void) rightMouseDown: (NSEvent*) theEvent
+- (BOOL) resignFirstResponder
 {
-    [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_PRESSED];
+    DBG_PRINT( "*************** Win.resignFirstResponder\n");
+    return [super resignFirstResponder];
 }
 
-- (void) rightMouseDragged: (NSEvent*) theEvent
+- (BOOL) canBecomeKeyWindow
 {
-    lastInsideMousePosition = [NSEvent mouseLocation];
-    // Note use of MOUSE_MOVED event type because mouse dragged events are synthesized by Java
-    [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED];
+    // Even if the window is borderless, we still want it to be able
+    // to become the key window to receive keyboard events
+    return YES;
 }
 
-- (void) rightMouseUp: (NSEvent*) theEvent
+- (void) becomeKeyWindow
 {
-    [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_RELEASED];
+    DBG_PRINT( "*************** becomeKeyWindow\n");
+    [super becomeKeyWindow];
 }
 
-- (void) otherMouseDown: (NSEvent*) theEvent
+- (void) resignKeyWindow
 {
-    [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_PRESSED];
+    DBG_PRINT( "*************** resignKeyWindow: isFullscreen %d\n", (int)isFullscreenWindow);
+    if(!isFullscreenWindow) {
+        [super resignKeyWindow];
+    }
 }
 
-- (void) otherMouseDragged: (NSEvent*) theEvent
+- (void) windowDidBecomeKey: (NSNotification *) notification
 {
-    lastInsideMousePosition = [NSEvent mouseLocation];
-    // Note use of MOUSE_MOVED event type because mouse dragged events are synthesized by Java
-    [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED];
+    DBG_PRINT( "*************** windowDidBecomeKey\n");
+    NewtView* newtView = (NewtView *) [self contentView];
+    if( [newtView isKindOfClass:[NewtView class]] ) {
+        BOOL mouseInside = [newtView updateMouseInside];
+        if(YES == mouseInside) {
+            [newtView cursorHide: ![newtView isMouseVisible] enter: 1];
+        }
+    }
+    [self focusChanged: YES];
 }
 
-- (void) otherMouseUp: (NSEvent*) theEvent
+- (void) windowDidResignKey: (NSNotification *) notification
 {
-    [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_RELEASED];
+    DBG_PRINT( "*************** windowDidResignKey\n");
+    // Implicit mouse exit by OS X
+    [self focusChanged: NO];
 }
 
 - (void)windowDidResize: (NSNotification*) notification
 {
-    JNIEnv* env = NULL;
     jobject javaWindowObject = NULL;
     int shallBeDetached = 0;
-    JavaVM *jvmHandle = NULL;
-
-    NSView* nsview = [self contentView];
-    if( [nsview isKindOfClass:[NewtView class]] ) {
-        NewtView* view = (NewtView *) nsview;
-        javaWindowObject = [view getJavaWindowObject];
-        if (javaWindowObject != NULL) {
-            jvmHandle = [view getJVMHandle];
-            if( NULL != jvmHandle ) {
-                env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], 1 /* asDaemon */, &shallBeDetached);
-            }
-        }
-    }
+    JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached);
 
-    // update insets on every window resize for lack of better hook place
-    [self updateInsets: env jwin:javaWindowObject];
+    if( NULL == env ) {
+        DBG_PRINT("windowDidResize: null JNIEnv\n");
+        return;
+    }
+    NewtView* newtView = (NewtView *) [self contentView];
+    if( [newtView isKindOfClass:[NewtView class]] ) {
+        javaWindowObject = [newtView getJavaWindowObject];
+    }
+    if( NULL != javaWindowObject ) {
+        // update insets on every window resize for lack of better hook place
+        [self updateInsets: env jwin:javaWindowObject];
 
-    if( NULL != env && NULL != javaWindowObject ) {
         NSRect frameRect = [self frame];
         NSRect contentRect = [self contentRectForFrameRect: frameRect];
 
         (*env)->CallVoidMethod(env, javaWindowObject, sizeChangedID, JNI_FALSE,
                                (jint) contentRect.size.width,
                                (jint) contentRect.size.height, JNI_FALSE);
-
-        /* if (shallBeDetached) {
-            (*jvmHandle)->DetachCurrentThread(jvmHandle);
-        } */
     }
+    // detaching thread not required - daemon
+    // NewtCommon_ReleaseJNIEnv(shallBeDetached);
 }
 
 - (void)windowDidMove: (NSNotification*) notification
 {
-    NSView* nsview = [self contentView];
-    if( ! [nsview isKindOfClass:[NewtView class]] ) {
+    NewtView* newtView = (NewtView *) [self contentView];
+    if( ! [newtView isKindOfClass:[NewtView class]] ) {
         return;
     }
-    NewtView* view = (NewtView *) nsview;
-    jobject javaWindowObject = [view getJavaWindowObject];
+    jobject javaWindowObject = [newtView getJavaWindowObject];
     if (javaWindowObject == NULL) {
         DBG_PRINT("windowDidMove: null javaWindowObject\n");
         return;
     }
     int shallBeDetached = 0;
-    JavaVM *jvmHandle = [view getJVMHandle];
-    JNIEnv* env;
-    if( NULL != jvmHandle ) {
-        env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], 1 /* asDaemon */, &shallBeDetached);
-    } else {
-        env = NULL;
-    }
+    JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached);
     if(NULL==env) {
-        DBG_PRINT("windowDidMove: JVM %p JNIEnv %p\n", jvmHandle, env);
+        DBG_PRINT("windowDidMove: null JNIEnv\n");
         return;
     }
 
@@ -1140,9 +1153,8 @@ static jint mods2JavaMods(NSUInteger mods)
     p0 = [self getLocationOnScreen: p0];
     (*env)->CallVoidMethod(env, javaWindowObject, positionChangedID, JNI_FALSE, (jint) p0.x, (jint) p0.y);
 
-    /* if (shallBeDetached) {
-        (*jvmHandle)->DetachCurrentThread(jvmHandle);
-    } */
+    // detaching thread not required - daemon
+    // NewtCommon_ReleaseJNIEnv(shallBeDetached);
 }
 
 - (BOOL)windowShouldClose: (id) sender
@@ -1158,51 +1170,38 @@ static jint mods2JavaMods(NSUInteger mods)
 - (BOOL) windowClosingImpl: (BOOL) force
 {
     jboolean closed = JNI_FALSE;
-    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
-    [self cursorHide: NO];
-
-    NSView* nsview = [self contentView];
-    if( ! [nsview isKindOfClass:[NewtView class]] ) {
+    NewtView* newtView = (NewtView *) [self contentView];
+    if( ! [newtView isKindOfClass:[NewtView class]] ) {
         return NO;
     }
-    NewtView* view = (NewtView *) nsview;
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+    [newtView cursorHide: NO enter: -1];
 
-    if( false == [view getDestroyNotifySent] ) {
-        jobject javaWindowObject = [view getJavaWindowObject];
+    if( false == [newtView getDestroyNotifySent] ) {
+        jobject javaWindowObject = [newtView getJavaWindowObject];
         DBG_PRINT( "*************** windowWillClose.0: %p\n", (void *)(intptr_t)javaWindowObject);
         if (javaWindowObject == NULL) {
             DBG_PRINT("windowWillClose: null javaWindowObject\n");
+            [pool release];
             return NO;
         }
         int shallBeDetached = 0;
-        JavaVM *jvmHandle = [view getJVMHandle];
-        JNIEnv* env = NULL;
-NS_DURING
-        if( NULL != jvmHandle ) {
-            env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], 1 /* asDaemon */, &shallBeDetached);
-        }
-NS_HANDLER
-        jvmHandle = NULL;
-        env = NULL;
-        [view setJVMHandle: NULL];
-        DBG_PRINT("windowWillClose: JVMHandler Exception\n");
-NS_ENDHANDLER
-        DBG_PRINT("windowWillClose: JVM %p JNIEnv %p\n", jvmHandle, env);
+        JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached);
         if(NULL==env) {
+            DBG_PRINT("windowWillClose: null JNIEnv\n");
+            [pool release];
             return NO;
         }
-
-        [view setDestroyNotifySent: true]; // earmark assumption of being closed
+        [newtView setDestroyNotifySent: true]; // earmark assumption of being closed
         closed = (*env)->CallBooleanMethod(env, javaWindowObject, windowDestroyNotifyID, force ? JNI_TRUE : JNI_FALSE);
         if(!force && !closed) {
             // not closed on java side, not force -> clear flag
-            [view setDestroyNotifySent: false];
+            [newtView setDestroyNotifySent: false];
         }
 
-        /* if (shallBeDetached) {
-            (*jvmHandle)->DetachCurrentThread(jvmHandle);
-        } */
+        // detaching thread not required - daemon
+        // NewtCommon_ReleaseJNIEnv(shallBeDetached);
         DBG_PRINT( "*************** windowWillClose.X: %p, closed %d\n", (void *)(intptr_t)javaWindowObject, (int)closed);
     } else {
         DBG_PRINT( "*************** windowWillClose (skip)\n");
diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c
index dd0150e..c20e156 100644
--- a/src/newt/native/WindowsWindow.c
+++ b/src/newt/native/WindowsWindow.c
@@ -186,8 +186,14 @@ typedef struct {
     int height;
     /** Tristate: -1 HIDE, 0 NOP, 1 SHOW */
     int setPointerVisible;
+    /** Tristate: -1 RESET, 0 NOP, 1 SET-NEW */
+    int setPointerAction;
+    HCURSOR setPointerHandle;
+    HCURSOR defPointerHandle;
     /** Bool: 0 NOP, 1 FULLSCREEN */
-    int setFullscreen;
+    int isFullscreen;
+    /** Bool: 0 TOP, 1 CHILD */
+    int isChildWindow;
     int pointerCaptured;
     int pointerInside;
     int touchDownCount;
@@ -954,9 +960,9 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
                 #ifdef VERBOSE_ON
                     BOOL anyActive = WA_ACTIVE==fActive, clickActive = WA_CLICKACTIVE==fActive;
                     DBG_PRINT("*** WindowsWindow: WM_ACTIVATE window %p, prev %p, minimized %d, active %d (any %d, click %d, inactive %d), FS %d\n", 
-                        wnd, wndPrev, fMinimized, fActive, anyActive, clickActive, inactive, wud->setFullscreen);
+                        wnd, wndPrev, fMinimized, fActive, anyActive, clickActive, inactive, wud->isFullscreen);
                 #endif
-                if( wud->setFullscreen ) {
+                if( wud->isFullscreen ) {
                     // Bug 916 - NEWT Fullscreen Mode on Windows ALT-TAB doesn't allow Application Switching
                     // Remedy for 'some' display drivers, i.e. Intel HD: 
                     // Explicitly push fullscreen window to BOTTOM when inactive (ALT-TAB)
@@ -1023,12 +1029,40 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
                 } else /* -1 == wud->setPointerVisible */ {
                     visibilityChangeSuccessful = SafeShowCursor(FALSE);
                 }
-                useDefWindowProc = visibilityChangeSuccessful ? 1 : 0;
                 DBG_PRINT("*** WindowsWindow: WM_SETCURSOR requested visibility: %d success: %d\n", wud->setPointerVisible, visibilityChangeSuccessful);
                 wud->setPointerVisible = 0;
-                // own signal, consumed
+                // own signal, consumed, no further processing
+                res = 1;
+            } else if( 0 != wud->setPointerAction ) {
+                if( -1 == wud->setPointerAction ) {
+                    wud->setPointerHandle = wud->defPointerHandle;
+                }
+                HCURSOR preHandle = SetCursor(wud->setPointerHandle);
+                DBG_PRINT("*** WindowsWindow: WM_SETCURSOR PointerIcon change %d: pre %p -> set %p, def %p\n", 
+                    wud->setPointerAction, (void*)preHandle, (void*)wud->setPointerHandle, (void*)wud->defPointerHandle);
+                wud->setPointerAction = 0;
+                // own signal, consumed, no further processing
+                res = 1;
+            } else if( HTCLIENT == LOWORD(lParam) ) {
+                BOOL setCur = wud->isChildWindow && wud->defPointerHandle != wud->setPointerHandle;
+                #ifdef VERBOSE_ON
+                    HCURSOR cur = GetCursor();
+                    DBG_PRINT("*** WindowsWindow: WM_SETCURSOR PointerIcon NOP [1 custom-override] set %p, def %p, cur %p, isChild %d, setCur %d\n",
+                        (void*)wud->setPointerHandle, (void*)wud->defPointerHandle, (void*)cur, wud->isChildWindow, setCur);
+                #endif
+                if( setCur ) {
+                    SetCursor(wud->setPointerHandle);
+                    // own signal, consumed, no further processing
+                    res = 1;
+                } else {
+                    DBG_PRINT("*** WindowsWindow: WM_SETCURSOR PointerIcon NOP [2 parent-override] set %p, def %p\n", (void*)wud->setPointerHandle, (void*)wud->defPointerHandle);
+                    // NOP for us, allow parent to act
+                    res = 0;
+                }
             } else {
-                useDefWindowProc = 1; // NOP for us, allow parent to act
+                DBG_PRINT("*** WindowsWindow: WM_SETCURSOR !HTCLIENT\n");
+                // NOP for us, allow parent to act
+                res = 0;
             }
             break;
 
@@ -1246,6 +1280,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
                     if( 0 == wud->pointerInside ) {
                         wud->pointerInside = 1;
                         NewtWindows_trackPointerLeave(wnd);
+                        SetCursor(wud->setPointerHandle);
                     }
                     (*env)->CallVoidMethod(env, window, sendMouseEventID,
                                            (jshort) EVENT_MOUSE_MOVED,
@@ -2054,7 +2089,11 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowDriver_CreateWindo
         wud->width = width;
         wud->height = height;
         wud->setPointerVisible = 0;
-        wud->setFullscreen = 0;
+        wud->setPointerAction = 0;
+        wud->defPointerHandle = LoadCursor( NULL, IDC_ARROW);
+        wud->setPointerHandle = wud->defPointerHandle;
+        wud->isFullscreen = 0;
+        wud->isChildWindow = NULL!=parentWindow;
         wud->pointerCaptured = 0;
         wud->pointerInside = 0;
         wud->touchDownCount = 0;
@@ -2162,13 +2201,13 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_reconfigureW
 #endif
 
 
-    DBG_PRINT( "*** WindowsWindow: reconfigureWindow0 parent %p, window %p, %d/%d %dx%d, parentChange %d, hasParent %d, decorationChange %d, undecorated %d, fullscreenChange %d, fullscreen %d, alwaysOnTopChange %d, alwaysOnTop %d, visibleChange %d, visible %d -> styleChange %d\n",
+    DBG_PRINT( "*** WindowsWindow: reconfigureWindow0 parent %p, window %p, %d/%d %dx%d, parentChange %d, hasParent %d, decorationChange %d, undecorated %d, fullscreenChange %d, fullscreen %d, alwaysOnTopChange %d, alwaysOnTop %d, visibleChange %d, visible %d -> styleChange %d, isChild %d, isFullscreen %d\n",
         parent, window, x, y, width, height,
         TST_FLAG_CHANGE_PARENTING(flags),   TST_FLAG_HAS_PARENT(flags),
         TST_FLAG_CHANGE_DECORATION(flags),  TST_FLAG_IS_UNDECORATED(flags),
         TST_FLAG_CHANGE_FULLSCREEN(flags),  TST_FLAG_IS_FULLSCREEN(flags),
         TST_FLAG_CHANGE_ALWAYSONTOP(flags), TST_FLAG_IS_ALWAYSONTOP(flags),
-        TST_FLAG_CHANGE_VISIBILITY(flags), TST_FLAG_IS_VISIBLE(flags), styleChange);
+        TST_FLAG_CHANGE_VISIBILITY(flags), TST_FLAG_IS_VISIBLE(flags), styleChange, wud->isChildWindow, wud->isFullscreen);
 
     if (!IsWindow(hwnd)) {
         DBG_PRINT("*** WindowsWindow: reconfigureWindow0 failure: Passed window %p is invalid\n", (void*)hwnd);
@@ -2180,6 +2219,8 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_reconfigureW
         return;
     }
 
+    wud->isChildWindow = NULL != hwndP;
+
     if(TST_FLAG_IS_VISIBLE(flags)) {
         windowStyle |= WS_VISIBLE ;
     }
@@ -2190,12 +2231,16 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_reconfigureW
     //
     if( TST_FLAG_CHANGE_PARENTING(flags) && NULL == hwndP ) {
         // TOP: in -> out
+
+        // HIDE to allow setting ICONs (Windows bug?) .. WS_VISIBLE (style) will reset visibility
+        ShowWindow(hwnd, SW_HIDE);
+
         SetParent(hwnd, NULL);
     }
     
     if( TST_FLAG_CHANGE_FULLSCREEN(flags) && TST_FLAG_IS_FULLSCREEN(flags) ) { // FS on
         // TOP: in -> out
-        wud->setFullscreen = 1;
+        wud->isFullscreen = 1;
         NewtWindows_setFullScreen(JNI_TRUE);
     }
 
@@ -2213,7 +2258,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_reconfigureW
 
     if( TST_FLAG_CHANGE_FULLSCREEN(flags) && !TST_FLAG_IS_FULLSCREEN(flags) ) { // FS off
         // CHILD: out -> in
-        wud->setFullscreen = 0;
+        wud->isFullscreen = 0;
         NewtWindows_setFullScreen(JNI_FALSE);
     }
 
@@ -2232,7 +2277,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_reconfigureW
         }
     }
 
-    DBG_PRINT("*** WindowsWindow: reconfigureWindow0.X\n");
+    DBG_PRINT("*** WindowsWindow: reconfigureWindow0.X isChild %d, isFullscreen %d\n", wud->isChildWindow, wud->isFullscreen);
 }
 
 /*
@@ -2321,3 +2366,93 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_warpPointer0
     SetCursorPos(x, y);
 }
 
+JNIEXPORT jlong JNICALL
+Java_jogamp_newt_driver_windows_DisplayDriver_createBGRA8888Icon0(JNIEnv *env, jobject _unused, 
+    jobject pixels, jint pixels_byte_offset, jboolean pixels_is_direct, jint width, jint height, jboolean isCursor, jint hotX, jint hotY) {
+
+    if( 0 == pixels ) {
+        return 0;
+    }
+
+    const unsigned char * pixelPtr = (const unsigned char *) ( JNI_TRUE == pixels_is_direct ? 
+                                            (*env)->GetDirectBufferAddress(env, pixels) : 
+                                            (*env)->GetPrimitiveArrayCritical(env, pixels, NULL) );
+    const int bytes = 4 * width * height; // BGRA8888
+
+    DWORD dwWidth, dwHeight;
+    BITMAPV5HEADER bi;
+    HBITMAP hBitmap;
+    void *lpBits;
+    HICON handle = NULL;
+
+    dwWidth  = width;  // width of cursor
+    dwHeight = height;  // height of cursor
+
+    ZeroMemory(&bi,sizeof(BITMAPV5HEADER));
+    bi.bV5Size           = sizeof(BITMAPV5HEADER);
+    bi.bV5Width           = dwWidth;
+    bi.bV5Height          = -1 * dwHeight;
+    bi.bV5Planes = 1;
+    bi.bV5BitCount = 32;
+    bi.bV5Compression = BI_BITFIELDS;
+    // The following mask specification specifies a supported 32 BPP
+    // alpha format for Windows XP.
+    bi.bV5RedMask   =  0x00FF0000;
+    bi.bV5GreenMask =  0x0000FF00;
+    bi.bV5BlueMask  =  0x000000FF;
+    bi.bV5AlphaMask =  0xFF000000; 
+
+    HDC hdc;
+    hdc = GetDC(NULL);
+
+    // Create the DIB section with an alpha channel.
+    hBitmap = CreateDIBSection(hdc, (BITMAPINFO *)&bi, DIB_RGB_COLORS, 
+        (void **)&lpBits, NULL, (DWORD)0);
+
+    memcpy(lpBits, pixelPtr + pixels_byte_offset, bytes);
+
+    ReleaseDC(NULL,hdc);
+
+    if ( JNI_FALSE == pixels_is_direct ) {
+        (*env)->ReleasePrimitiveArrayCritical(env, pixels, (void*)pixelPtr, JNI_ABORT);  
+    }
+
+    // Create an empty mask bitmap.
+    HBITMAP hMonoBitmap = CreateBitmap(dwWidth,dwHeight,1,1,NULL);
+
+    ICONINFO ii;
+    ii.fIcon = isCursor ? FALSE : TRUE;
+    ii.xHotspot = hotX;
+    ii.yHotspot = hotY;
+    ii.hbmMask = hMonoBitmap;
+    ii.hbmColor = hBitmap;
+
+    // Create the alpha cursor with the alpha DIB section.
+    handle = CreateIconIndirect(&ii);
+
+    DeleteObject(hBitmap);          
+    DeleteObject(hMonoBitmap); 
+
+    return (jlong) (intptr_t) handle;
+}
+
+JNIEXPORT void JNICALL
+Java_jogamp_newt_driver_windows_DisplayDriver_destroyIcon0(JNIEnv *env, jobject _unused, jlong jhandle) {
+    HICON handle = (HICON) (intptr_t) jhandle;
+    DestroyIcon(handle);
+}
+
+JNIEXPORT void JNICALL
+Java_jogamp_newt_driver_windows_WindowDriver_setPointerIcon0(JNIEnv *env, jobject _unused, jlong window, jlong iconHandle) {
+    HWND hwnd = (HWND) (intptr_t) window;
+    WindowUserData * wud;
+#if !defined(__MINGW64__) && ( defined(UNDER_CE) || _MSC_VER <= 1200 )
+    wud = (WindowUserData *) GetWindowLong(hwnd, GWL_USERDATA);
+#else
+    wud = (WindowUserData *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
+#endif
+    wud->setPointerAction = 0 != iconHandle ? 1 : -1;
+    wud->setPointerHandle = (HCURSOR) (intptr_t) iconHandle;
+    SendMessage(hwnd, WM_SETCURSOR, 0, 0);
+}
+
diff --git a/src/newt/native/X11Display.c b/src/newt/native/X11Display.c
index e2392a1..b62a9b2 100644
--- a/src/newt/native/X11Display.c
+++ b/src/newt/native/X11Display.c
@@ -28,6 +28,8 @@
 
 #include "X11Common.h"
 
+#include <X11/Xcursor/Xcursor.h>
+
 // #include <X11/XKBlib.h> // XKB disabled for now
 
 jclass X11NewtWindowClazz = NULL;
@@ -670,4 +672,59 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
     }
 }
 
+/*
+ * Class:     Java_jogamp_newt_driver_x11_DisplayDriver
+ * Method:    createPointerIcon0
+ * Signature: (JJILjava/lang/Object;I)V
+ */
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_createPointerIcon0
+  (JNIEnv *env, jclass clazz, jlong display, jobject pixels, jint pixels_byte_offset, jboolean pixels_is_direct, jint width, jint height, jint hotX, jint hotY)
+{
+    Cursor c;
+
+    if( 0 != pixels ) {
+        Display * dpy = (Display *) (intptr_t) display;
+        const unsigned char * pixelPtr = (const unsigned char *) ( JNI_TRUE == pixels_is_direct ? 
+                                                (*env)->GetDirectBufferAddress(env, pixels) : 
+                                                (*env)->GetPrimitiveArrayCritical(env, pixels, NULL) );
+        XcursorImage ci;
+        ci.version = 1; // XCURSOR_IMAGE_VERSION;
+        ci.size = width; // nominal size (assume square ..)
+        ci.width = width;
+        ci.height = height;
+        ci.xhot = hotX;
+        ci.yhot = hotY;
+        ci.delay = 0;
+        ci.pixels = (XcursorPixel *)(intptr_t)(pixelPtr + pixels_byte_offset);
+
+        c = XcursorImageLoadCursor (dpy, &ci);
+
+        if ( JNI_FALSE == pixels_is_direct ) {
+            (*env)->ReleasePrimitiveArrayCritical(env, pixels, (void*)pixelPtr, JNI_ABORT);  
+        }
+        DBG_PRINT( "X11: createPointerIcon0: %p %dx%d %d/%d -> %p\n", (pixelPtr+pixels_byte_offset), width, height, hotX, hotY, (void *)c);
+
+    } else {
+        c = 0;
+    }
+    return (jlong) (intptr_t) c;
+}
+
+/*
+ * Class:     Java_jogamp_newt_driver_x11_DisplayDriver
+ * Method:    destroyPointerIcon0
+ * Signature: (JJILjava/lang/Object;I)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_destroyPointerIcon0
+  (JNIEnv *env, jclass clazz, jlong display, jlong handle)
+{
+    Display * dpy = (Display *) (intptr_t) display;
+
+    if( 0 != handle ) {
+        Cursor c = (Cursor) (intptr_t) handle;
+        DBG_PRINT( "X11: destroyPointerIcon0: %p\n", (void *)c);
+        XFreeCursor(dpy, c);
+    }
+}
+
 
diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c
index f195c56..2cc66c7 100644
--- a/src/newt/native/X11Window.c
+++ b/src/newt/native/X11Window.c
@@ -98,11 +98,11 @@ static void setJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlon
 }
 
 jobject getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlong javaObjectAtom, Bool showWarning) {
-    Atom actual_type;
-    int actual_format;
+    Atom actual_type = 0;
+    int actual_format = 0;
     int nitems_32 = ( sizeof(uintptr_t) == 8 ) ? 2 : 1 ;
     unsigned char * jogl_java_object_data_pp = NULL;
-    jobject jwindow;
+    jobject jwindow = 0;
 
     {
         unsigned long nitems= 0;
@@ -122,7 +122,9 @@ jobject getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlong ja
         }
 
         if(actual_type!=(Atom)javaObjectAtom || nitems<nitems_32 || NULL==jogl_java_object_data_pp) {
-            XFree(jogl_java_object_data_pp);
+            if( NULL != jogl_java_object_data_pp ) {
+                XFree(jogl_java_object_data_pp);
+            }
             if(True==showWarning) {
                 fprintf(stderr, "Warning: NEWT X11Window: Fetched invalid Atom NEWT_JAVA_OBJECT window property (res %d) nitems %ld, bytes_after %ld, actual_type %ld, NEWT_JAVA_OBJECT %ld, result 0!\n", 
                 res, nitems, bytes_after, (long)actual_type, (long)javaObjectAtom);
@@ -189,8 +191,8 @@ static Status NewtWindows_getWindowPositionRelative2Parent (Display *dpy, Window
     return 0; // Error
 }
 static Status NewtWindows_getFrameExtends(Display *dpy, Window window, int *left, int *right, int *top, int *bottom) {
-    Atom actual_type;
-    int actual_format;
+    Atom actual_type = 0;
+    int actual_format = 0;
     int nitems_32 = 4; // l, r, t, b
     unsigned char * frame_extends_data_pp = NULL;
 
@@ -210,7 +212,9 @@ static Status NewtWindows_getFrameExtends(Display *dpy, Window window, int *left
         }
 
         if(nitems<nitems_32 || NULL==frame_extends_data_pp) {
-            XFree(frame_extends_data_pp);
+            if( NULL != frame_extends_data_pp ) {
+                XFree(frame_extends_data_pp);
+            }
             // DBG_PRINT( "Warning: NEWT X11Window: Fetched invalid Atom _NET_FRAME_EXTENTS window property (res %d) nitems %ld, bytes_after %ld, actual_type %ld, actual_format %d, _NET_FRAME_EXTENTS %ld, result 0!\n", 
             //     res, nitems, bytes_after, (long)actual_type, actual_format, _NET_FRAME_EXTENTS);
             return 0; // Error, but ok - ie window not mapped
@@ -271,18 +275,21 @@ static Bool NewtWindows_hasDecorations (Display *dpy, Window w) {
 
 #ifdef DECOR_USE_MWM
     Atom _MOTIF_WM_HINTS = XInternAtom( dpy, "_MOTIF_WM_HINTS", False );
-    unsigned char *wm_data;
-    Atom wm_type;
-    int wm_format;
-    unsigned long wm_nitems, wm_bytes_after;
+    unsigned char *wm_data = NULL;
+    Atom wm_type = 0;
+    int wm_format = 0;
+    unsigned long wm_nitems = 0, wm_bytes_after = 0;
  
     if( Success == XGetWindowProperty(dpy, w, _MOTIF_WM_HINTS, 0, PROP_MWM_HINTS_ELEMENTS, False, AnyPropertyType, 
                                       &wm_type, &wm_format, &wm_nitems, &wm_bytes_after, &wm_data) ) {
-        if(wm_type != None) {
+        if(wm_type != None && NULL != wm_data && wm_nitems >= PROP_MWM_HINTS_ELEMENTS) {
             // unsigned long mwmhints[PROP_MWM_HINTS_ELEMENTS] = { MWM_HINTS_DECORATIONS, 0, decorated, 0, 0 }; // flags, functions, decorations, input_mode, status
             unsigned long *hints = (unsigned long *) wm_data;
             decor = ( 0 != (hints[0] & MWM_HINTS_DECORATIONS) ) && ( 0 != hints[2] );
         }
+        if( NULL != wm_data ) {
+            XFree(wm_data);
+        }
     }
 #endif
 
@@ -319,27 +326,30 @@ static int NewtWindows_getSupportedStackingEWMHFlags(Display *dpy, Window w) {
     Atom _NET_WM_ALLOWED_ACTIONS = XInternAtom( dpy, "_NET_WM_ALLOWED_ACTIONS", False );
     Atom _NET_WM_ACTION_FULLSCREEN = XInternAtom( dpy, "_NET_WM_ACTION_FULLSCREEN", False );
     Atom _NET_WM_ACTION_ABOVE = XInternAtom( dpy, "_NET_WM_ACTION_ABOVE", False );
-    Atom * actions;
-    Atom type;
-    unsigned long action_len, remain;
-    int res = 0, form, i;
+    Atom * actions = NULL;
+    Atom type = 0;
+    unsigned long action_len = 0, remain = 0;
+    int res = 0, form = 0, i = 0;
     Status s;
 
     if ( Success == (s = XGetWindowProperty(dpy, w, _NET_WM_ALLOWED_ACTIONS, 0, 1024, False, AnyPropertyType,
                                             &type, &form, &action_len, &remain, (unsigned char**)&actions)) ) {
-        for(i=0; i<action_len; i++) {
-            if(_NET_WM_ACTION_FULLSCREEN == actions[i]) {
-                DBG_PRINT( "**************** X11: FS EWMH CHECK[%d]: _NET_WM_ACTION_FULLSCREEN (*)\n", i);
-                res |= _NET_WM_STATE_FLAG_FULLSCREEN ;
-            } else if(_NET_WM_ACTION_ABOVE == actions[i]) {
-                DBG_PRINT( "**************** X11: FS EWMH CHECK[%d]: _NET_WM_ACTION_ABOVE (*)\n", i);
-                res |= _NET_WM_STATE_FLAG_ABOVE ;
-            }
-            else {
-                char * astr = XGetAtomName(dpy, actions[i]);
-                DBG_PRINT( "**************** X11: FS EWMH CHECK[%d]: %s (unused)\n", i, astr);
-                XFree(astr);
+        if( NULL != actions ) {
+            for(i=0; i<action_len; i++) {
+                if(_NET_WM_ACTION_FULLSCREEN == actions[i]) {
+                    DBG_PRINT( "**************** X11: FS EWMH CHECK[%d]: _NET_WM_ACTION_FULLSCREEN (*)\n", i);
+                    res |= _NET_WM_STATE_FLAG_FULLSCREEN ;
+                } else if(_NET_WM_ACTION_ABOVE == actions[i]) {
+                    DBG_PRINT( "**************** X11: FS EWMH CHECK[%d]: _NET_WM_ACTION_ABOVE (*)\n", i);
+                    res |= _NET_WM_STATE_FLAG_ABOVE ;
+                }
+                else {
+                    char * astr = XGetAtomName(dpy, actions[i]);
+                    DBG_PRINT( "**************** X11: FS EWMH CHECK[%d]: %s (unused)\n", i, astr);
+                    XFree(astr);
+                }
             }
+            XFree(actions);
         }
         DBG_PRINT( "**************** X11: FS EWMH CHECK: 0x%X\n", res);
     } else {
@@ -389,6 +399,9 @@ static Bool NewtWindows_setStackingEWMHFlags (Display *dpy, Window root, Window
             XSendEvent ( dpy, root, False, mask, &xev );
         }
         // Also change _NET_WM_BYPASS_COMPOSITOR!
+        //   A value of 0 indicates no preference. 
+        //   A value of 1 hints the compositor to disabling compositing of this window. 
+        //   A value of 2 hints the compositor to not disabling compositing of this window
         {
             Atom _NET_WM_BYPASS_COMPOSITOR = XInternAtom( dpy, "_NET_WM_BYPASS_COMPOSITOR", False );
             unsigned long value = enable ? 1 : 0;
@@ -494,6 +507,12 @@ static void NewtWindows_setPosSize(Display *dpy, Window w, jint x, jint y, jint
     }
 }
 
+static void NewtWindows_setIcon(Display *dpy, Window w, int data_size, const unsigned char * data_ptr) {
+    Atom _NET_WM_ICON = XInternAtom(dpy, "_NET_WM_ICON", False);
+    Atom CARDINAL = XInternAtom(dpy, "CARDINAL", False);
+    XChangeProperty(dpy, w, _NET_WM_ICON, CARDINAL, 32, PropModeReplace, data_ptr, data_size);
+}
+
 /*
  * Class:     jogamp_newt_driver_x11_WindowDriver
  * Method:    CreateWindow
@@ -502,7 +521,8 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CreateWindow0
   (JNIEnv *env, jobject obj, jlong parent, jlong display, jint screen_index, 
                              jint visualID, 
                              jlong javaObjectAtom, jlong windowDeleteAtom, 
-                             jint x, jint y, jint width, jint height, jboolean autoPosition, int flags)
+                             jint x, jint y, jint width, jint height, jboolean autoPosition, int flags,
+                             jint pixelDataSize, jobject pixels, jint pixels_byte_offset, jboolean pixels_is_direct)
 {
     Display * dpy = (Display *)(intptr_t)display;
     Atom wm_delete_atom = (Atom)windowDeleteAtom;
@@ -622,12 +642,27 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CreateWindow0
     {
         XEvent event;
         int left=0, right=0, top=0, bottom=0;
+        const unsigned char * pixelPtr = NULL;
+
+        // NOTE: MUST BE DIRECT BUFFER, since _NET_WM_ICON Atom uses buffer directly!
+        DBG_PRINT("X11: CreateWindow icon: size %d, pixels %p, offset %d, direct %d\n", pixelDataSize, (void*)pixels, pixels_byte_offset, pixels_is_direct);
+        if( 0 < pixelDataSize && NULL != pixels ) {
+            pixelPtr = (const unsigned char *) ( JNI_TRUE == pixels_is_direct ? 
+                                                    (*env)->GetDirectBufferAddress(env, pixels) : 
+                                                    (*env)->GetPrimitiveArrayCritical(env, pixels, NULL) );
+            DBG_PRINT("X11: CreateWindow icon: NIO %p\n", pixelPtr);
+            NewtWindows_setIcon(dpy, window, (int)pixelDataSize, pixelPtr+pixels_byte_offset);
+        }
 
         XMapWindow(dpy, window);
         XIfEvent( dpy, &event, WaitForMapNotify, (XPointer) window ); // wait to get proper insets values
 
         XSync(dpy, False);
 
+        if( JNI_FALSE == pixels_is_direct && NULL != pixelPtr ) {
+            (*env)->ReleasePrimitiveArrayCritical(env, pixels, (void*)pixelPtr, JNI_ABORT);  
+        }
+
         // send insets before visibility, allowing java code a proper sync point!
         NewtWindows_updateInsets(env, jwindow, dpy, window, &left, &right, &top, &bottom);
         (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_FALSE, JNI_TRUE);
@@ -704,9 +739,19 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CloseWindow0
     DBG_PRINT( "X11: CloseWindow END\n");
 }
 
-#if 0
+// #define REPARENT_WAIT_FOR_REPARENT_NOTIFY 1
+
+#ifdef REPARENT_WAIT_FOR_REPARENT_NOTIFY
 static Bool WaitForReparentNotify( Display *dpy, XEvent *event, XPointer arg ) {
-    return (event->type == ReparentNotify) && (event->xreparent.window == (Window) arg);
+    Bool res = (event->type == ReparentNotify) && (event->xreparent.window == (Window) arg);
+    #ifdef VERBOSE_ON
+    if( event->type == ReparentNotify ) {
+        DBG_PRINT( "X11.WaitForReparentNotify: Event ReparentNotify: Result %d, exp %p, has %p\n", (int)res, arg, event->xreparent.window);
+    } else {
+        DBG_PRINT( "X11.WaitForReparentNotify: Event 0x%X: Result %d, exp %p, has %p\n", (int)event->type, (int)res, arg, event->xreparent.window);
+    }
+    #endif
+    return res;
 }
 #endif
 
@@ -741,8 +786,13 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo
         } else if( !TST_FLAG_IS_ALWAYSONTOP(flags) ) {
             fsEWMHFlags |= _NET_WM_STATE_FLAG_ABOVE;     // fs off, above off
         } // else { }                                    // fs off, above on
-    }
-    if( TST_FLAG_CHANGE_ALWAYSONTOP(flags) ) {
+    } else if( TST_FLAG_CHANGE_PARENTING(flags) ) {
+        // Fix for Unity WM, i.e. _remove_ persistent previous states
+        fsEWMHFlags |= _NET_WM_STATE_FLAG_FULLSCREEN;    // fs off
+        if( !TST_FLAG_IS_ALWAYSONTOP(flags) ) {
+            fsEWMHFlags |= _NET_WM_STATE_FLAG_ABOVE;     // above off
+        }
+    } else if( TST_FLAG_CHANGE_ALWAYSONTOP(flags) ) {
         fsEWMHFlags |= _NET_WM_STATE_FLAG_ABOVE;         // toggle above
     }
 
@@ -753,11 +803,12 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo
         TST_FLAG_CHANGE_DECORATION(flags),  TST_FLAG_IS_UNDECORATED(flags),
         TST_FLAG_CHANGE_FULLSCREEN(flags),  TST_FLAG_IS_FULLSCREEN(flags), TST_FLAG_IS_FULLSCREEN_SPAN(flags),
         TST_FLAG_CHANGE_ALWAYSONTOP(flags), TST_FLAG_IS_ALWAYSONTOP(flags),
-        TST_FLAG_CHANGE_VISIBILITY(flags),  TST_FLAG_IS_VISIBLE(flags), tempInvisible, fsEWMHFlags);
+        TST_FLAG_CHANGE_VISIBILITY(flags),  TST_FLAG_IS_VISIBLE(flags), 
+        tempInvisible, fsEWMHFlags);
 
-    // FS Note: To toggle FS, utilizing the _NET_WM_STATE_FULLSCREEN WM state shall be enough.
+    // FS Note: To toggle FS, utilizing the _NET_WM_STATE_FULLSCREEN WM state should be enough.
     //          However, we have to consider other cases like reparenting and WM which don't support it.
-
+    #if 0    // Also doesn't work work properly w/ Unity WM
     if( fsEWMHFlags && !TST_FLAG_CHANGE_PARENTING(flags) && isVisible &&
         !TST_FLAG_IS_FULLSCREEN_SPAN(flags) &&
         ( TST_FLAG_CHANGE_FULLSCREEN(flags) || TST_FLAG_CHANGE_ALWAYSONTOP(flags) ) ) {
@@ -766,7 +817,16 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo
             if ( TST_FLAG_CHANGE_FULLSCREEN(flags) && !TST_FLAG_IS_FULLSCREEN(flags) ) { // FS off - restore decoration
                 NewtWindows_setDecorations (dpy, w, TST_FLAG_IS_UNDECORATED(flags) ? False : True);
             }
-            DBG_PRINT( "X11: reconfigureWindow0 X (fast)\n");
+            DBG_PRINT( "X11: reconfigureWindow0 X (fs.atop.fast)\n");
+            return;
+        }
+    }
+    #endif
+    // Toggle ALWAYSONTOP (only) w/o visibility or window stacking sideffects
+    if( isVisible && fsEWMHFlags && TST_FLAG_CHANGE_ALWAYSONTOP(flags) &&
+        !TST_FLAG_CHANGE_PARENTING(flags) && !TST_FLAG_CHANGE_FULLSCREEN(flags) ) {
+        if( NewtWindows_setStackingEWMHFlags(dpy, root, w, fsEWMHFlags, isVisible, TST_FLAG_IS_ALWAYSONTOP(flags)) ) {
+            DBG_PRINT( "X11: reconfigureWindow0 X (atop.fast)\n");
             return;
         }
     }
@@ -778,8 +838,8 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo
         // no need to notify the java side .. just temp change
     }
 
-    if( fsEWMHFlags && ( ( TST_FLAG_CHANGE_FULLSCREEN(flags)  && !TST_FLAG_IS_FULLSCREEN(flags) ) || 
-                         ( TST_FLAG_CHANGE_ALWAYSONTOP(flags) && !TST_FLAG_IS_ALWAYSONTOP(flags) ) ) ) { // FS off
+    if( fsEWMHFlags && ( ( TST_FLAG_CHANGE_FULLSCREEN(flags)  && !TST_FLAG_IS_FULLSCREEN(flags) ) ||     // FS off
+                         ( TST_FLAG_CHANGE_ALWAYSONTOP(flags) && !TST_FLAG_IS_ALWAYSONTOP(flags) ) ) ) { // AlwaysOnTop off
         NewtWindows_setStackingEWMHFlags(dpy, root, w, fsEWMHFlags, isVisible, False);
     }
 
@@ -787,9 +847,13 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo
         // TOP: in -> out
         DBG_PRINT( "X11: reconfigureWindow0 PARENTING in->out\n");
         XReparentWindow( dpy, w, parent, x, y ); // actual reparent call
-        // XIfEvent( dpy, &event, WaitForReparentNotify, (XPointer) w );
+        #ifdef REPARENT_WAIT_FOR_REPARENT_NOTIFY
+            XIfEvent( dpy, &event, WaitForReparentNotify, (XPointer) w );
+        #endif
         XSync(dpy, False);
         XSetWMProtocols(dpy, w, &wm_delete_atom, 1); // windowDeleteAtom
+        // Fix for Unity WM, i.e. _remove_ persistent previous states
+        NewtWindows_setStackingEWMHFlags(dpy, root, w, fsEWMHFlags, isVisible, False);
     }
 
     if( TST_FLAG_CHANGE_DECORATION(flags) ) {
@@ -804,7 +868,9 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo
         // CHILD: out -> in
         DBG_PRINT( "X11: reconfigureWindow0 PARENTING out->in\n");
         XReparentWindow( dpy, w, parent, x, y ); // actual reparent call
-        // XIfEvent( dpy, &event, WaitForReparentNotify, (XPointer) w );
+        #ifdef REPARENT_WAIT_FOR_REPARENT_NOTIFY
+            XIfEvent( dpy, &event, WaitForReparentNotify, (XPointer) w );
+        #endif
         XSync(dpy, False);
     }
 
@@ -828,8 +894,8 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo
         }
     }
 
-    if( fsEWMHFlags && ( ( TST_FLAG_CHANGE_FULLSCREEN(flags)  && TST_FLAG_IS_FULLSCREEN(flags) ) || 
-                         ( TST_FLAG_CHANGE_ALWAYSONTOP(flags) && TST_FLAG_IS_ALWAYSONTOP(flags) ) ) ) { // FS on
+    if( fsEWMHFlags && ( ( TST_FLAG_CHANGE_FULLSCREEN(flags)  && TST_FLAG_IS_FULLSCREEN(flags) ) ||     // FS on
+                         ( TST_FLAG_CHANGE_ALWAYSONTOP(flags) && TST_FLAG_IS_ALWAYSONTOP(flags) ) ) ) { // AlwaysOnTop on
         NewtWindows_requestFocus (dpy, w, True);
         NewtWindows_setStackingEWMHFlags(dpy, root, w, fsEWMHFlags, isVisible, True);
     }
@@ -912,6 +978,27 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_setTitle0
 
 /*
  * Class:     Java_jogamp_newt_driver_x11_WindowDriver
+ * Method:    setPointerIcon0
+ * Signature: (JJILjava/lang/Object;I)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_setPointerIcon0
+  (JNIEnv *env, jclass clazz, jlong display, jlong window, jlong handle)
+{
+    Display * dpy = (Display *) (intptr_t) display;
+    Window w = (Window)window;
+
+    if( 0 == handle ) {
+        DBG_PRINT( "X11: setPointerIcon0: reset\n");
+        XUndefineCursor(dpy, w);
+    } else {
+        Cursor c = (Cursor) (intptr_t) handle;
+        DBG_PRINT( "X11: setPointerIcon0: %p\n", (void*)c);
+        XDefineCursor(dpy, w, c);
+    }
+}
+
+/*
+ * Class:     Java_jogamp_newt_driver_x11_WindowDriver
  * Method:    setPointerVisible0
  * Signature: (JJZ)Z
  */
diff --git a/src/newt/native/bcm_vc_iv.c b/src/newt/native/bcm_vc_iv.c
index f3474ee..ee59f0a 100644
--- a/src/newt/native/bcm_vc_iv.c
+++ b/src/newt/native/bcm_vc_iv.c
@@ -30,24 +30,48 @@
 #include <stdio.h>
 #include <string.h>
 
+/** 
+ * See references in header file.
+ */
 #include "bcm_vc_iv.h"
 
 #include "jogamp_newt_driver_bcm_vc_iv_DisplayDriver.h"
 #include "jogamp_newt_driver_bcm_vc_iv_ScreenDriver.h"
 #include "jogamp_newt_driver_bcm_vc_iv_WindowDriver.h"
 
-#define VERBOSE_ON 1
+// #define VERBOSE_ON 1
 
 #ifdef VERBOSE_ON
-    #define DBG_PRINT(...) fprintf(stdout, __VA_ARGS__)
+    #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr) 
 #else
     #define DBG_PRINT(...)
 #endif
 
+typedef struct {
+ DISPMANX_ELEMENT_HANDLE_T handle; // magic BCM EGL position (EGL_DISPMANX_WINDOW_T)
+ int width;                        // magic BCM EGL position (EGL_DISPMANX_WINDOW_T)
+ int height;                       // magic BCM EGL position (EGL_DISPMANX_WINDOW_T)
+ int x;
+ int y;
+ int32_t layer;
+} BCM_ELEMENT_T;
+
+typedef struct {
+ DISPMANX_RESOURCE_HANDLE_T handle;
+ VC_IMAGE_TYPE_T type;
+ uint32_t native_image_handle;
+} BCM_RESOURCE_T;
+
+typedef struct {
+   BCM_ELEMENT_T element;
+   BCM_RESOURCE_T resource;
+   int hotX, hotY;
+} POINTER_ICON_T;
+
 static jmethodID setScreenSizeID = NULL;
 
-static jmethodID windowCreatedID = NULL;
 static jmethodID sizeChangedID = NULL;
+static jmethodID positionChangedID = NULL;
 static jmethodID visibleChangedID = NULL;
 static jmethodID windowDestroyNotifyID = NULL;
 
@@ -64,9 +88,208 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_bcm_vc_iv_DisplayDriver_initI
     return JNI_TRUE;
 }
 
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_DisplayDriver_DispatchMessages
-  (JNIEnv *env, jobject obj)
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_bcm_vc_iv_DisplayDriver_OpenBCMDisplay0
+  (JNIEnv *env, jclass clazz)
+{
+   DISPMANX_DISPLAY_HANDLE_T dispman_display = vc_dispmanx_display_open( 0 /* LCD */);
+   DBG_PRINT( "BCM.Display Open %p\n", (void*)(intptr_t)dispman_display);
+   return (jlong) (intptr_t) dispman_display;
+}
+
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_DisplayDriver_CloseBCMDisplay0
+  (JNIEnv *env, jclass clazz, jlong display)
 {
+   DISPMANX_DISPLAY_HANDLE_T dispman_display = (DISPMANX_DISPLAY_HANDLE_T) (intptr_t) display;
+   DBG_PRINT( "BCM.Display Close %p\n", (void*)(intptr_t)dispman_display);
+   vc_dispmanx_display_close( dispman_display );
+}
+
+
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_DisplayDriver_DispatchMessages0
+  (JNIEnv *env, jclass clazz)
+{
+}
+
+static void bcm_moveTo(DISPMANX_ELEMENT_HANDLE_T element, uint32_t layer, int x, int y, int width, int height) {
+   VC_RECT_T       src_rect;
+   VC_RECT_T       dst_rect;
+   uint32_t change_flags = DISPMANX_ELEMENT_CHANGE_DEST_RECT | DISPMANX_ELEMENT_CHANGE_SRC_RECT;
+   DISPMANX_RESOURCE_HANDLE_T mask = 0;
+   DISPMANX_TRANSFORM_T transform = 0;
+
+   uint8_t opacity = 0;  // NOP
+
+   dst_rect.x = x;
+   dst_rect.y = y;
+   dst_rect.width = width;
+   dst_rect.height = height;
+
+   src_rect.x = 0;
+   src_rect.y = 0;
+   src_rect.width = width << 16;
+   src_rect.height = height << 16;
+
+   DISPMANX_UPDATE_HANDLE_T dispman_update = vc_dispmanx_update_start( 0 );
+   vc_dispmanx_element_change_attributes( dispman_update,
+                                          element,
+                                          change_flags,
+                                          layer,
+                                          opacity,
+                                          &dst_rect,
+                                          &src_rect,
+                                          mask,
+                                          transform );
+   vc_dispmanx_update_submit_sync( dispman_update );
+}
+
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_bcm_vc_iv_DisplayDriver_CreatePointerIcon0
+  (JNIEnv *env, jclass clazz, jobject pixels, jint pixels_byte_offset, jboolean pixels_is_direct, jint width, jint height, jint hotX, jint hotY)
+{
+    if( 0 == pixels ) {
+        return 0;
+    }
+    int32_t success = 0;
+    VC_RECT_T dst_rect;
+    VC_RECT_T src_rect;
+    int x = 0;
+    int y = 0;
+    int pitch = width * 4; // RGBA
+
+    const unsigned char * pixelPtr = (const unsigned char *) ( JNI_TRUE == pixels_is_direct ? 
+                                            (*env)->GetDirectBufferAddress(env, pixels) : 
+                                            (*env)->GetPrimitiveArrayCritical(env, pixels, NULL) );
+
+    POINTER_ICON_T * p = calloc(1, sizeof(POINTER_ICON_T));
+    p->hotX = hotX;
+    p->hotY = hotY;
+    p->element.layer = 2000;
+    p->element.x = x;
+    p->element.y = y;
+    p->element.width = width;
+    p->element.height = height;
+    p->resource.type = VC_IMAGE_ARGB8888;   /* 32bpp with 8bit alpha at MS byte, with R, G, B (LS byte) */
+    p->resource.handle = vc_dispmanx_resource_create( p->resource.type,
+                                                     width,
+                                                     height,
+                                                     &(p->resource.native_image_handle) );
+
+    dst_rect.x = x;
+    dst_rect.y = y;
+    dst_rect.width = width;
+    dst_rect.height = height;
+      
+    vc_dispmanx_resource_write_data( p->resource.handle,
+                                    p->resource.type,
+                                    pitch,
+                                    (void*)(intptr_t)(pixelPtr + pixels_byte_offset),
+                                    &dst_rect );
+
+    if ( JNI_FALSE == pixels_is_direct ) {
+        (*env)->ReleasePrimitiveArrayCritical(env, pixels, (void*)pixelPtr, JNI_ABORT);  
+    }
+
+    DBG_PRINT( "BCM.Display PointerIcon.Create PI %p, resource %p\n", p, (void*)(intptr_t)p->resource.handle);
+    return (jlong) (intptr_t) p;
+}
+
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_DisplayDriver_DestroyPointerIcon0
+  (JNIEnv *env, jclass clazz, jlong handle)
+{
+    POINTER_ICON_T * p = (POINTER_ICON_T *) (intptr_t) handle ;
+    if( 0 == p ) {
+        return; 
+    }
+
+    DBG_PRINT( "BCM.Display PointerIcon.Destroy.0 PI %p, resource %p, element %p\n", 
+        p, (void*)(intptr_t)p->resource.handle, (void*)(intptr_t)p->element.handle);
+
+    if( 0 != p->element.handle ) {
+        DISPMANX_UPDATE_HANDLE_T dispman_update = vc_dispmanx_update_start( 0 );
+        vc_dispmanx_element_remove( dispman_update, p->element.handle );
+        p->element.handle = 0;
+        vc_dispmanx_update_submit_sync( dispman_update );
+    }
+    if( 0 != p->resource.handle ) {
+        vc_dispmanx_resource_delete( p->resource.handle );
+        p->resource.handle = 0;
+    }
+    free( p );
+}
+
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_DisplayDriver_SetPointerIcon0
+  (JNIEnv *env, jclass clazz, jlong display, jlong handle, jboolean enable, jint x, jint y)
+{
+    DISPMANX_DISPLAY_HANDLE_T dispman_display = (DISPMANX_DISPLAY_HANDLE_T) (intptr_t) display;
+    POINTER_ICON_T * p = (POINTER_ICON_T *) (intptr_t) handle ;
+    VC_RECT_T dst_rect;
+    VC_RECT_T src_rect;
+
+    if( 0 == dispman_display || NULL == p || 0 == p->resource.handle ) {
+        return; 
+    }
+
+    DBG_PRINT( "BCM.Display PointerIcon.Set.0 %p, PI %p, resource %p, element %p - enable %d - %d/%d\n", 
+        (void*)(intptr_t)display, p, (void*)(intptr_t)p->resource.handle, (void*)(intptr_t)p->element.handle, enable, x, y);
+
+    if( enable ) {
+        if( 0 != p->element.handle ) {
+            return; 
+        }
+
+        p->element.x = x;
+        p->element.y = y;
+        dst_rect.x = p->element.x - p->hotX;
+        dst_rect.y = p->element.y - p->hotY;
+        dst_rect.width = p->element.width;
+        dst_rect.height = p->element.height;
+          
+        src_rect.x = 0;
+        src_rect.y = 0;
+        src_rect.width = p->element.width << 16;
+        src_rect.height = p->element.height << 16;   
+
+        VC_DISPMANX_ALPHA_T dispman_alpha;
+        memset(&dispman_alpha, 0x0, sizeof(VC_DISPMANX_ALPHA_T));
+        dispman_alpha.flags = DISPMANX_FLAGS_ALPHA_FROM_SOURCE ;
+        dispman_alpha.opacity = 0xFF;
+        dispman_alpha.mask = 0xFF;
+
+        DISPMANX_UPDATE_HANDLE_T dispman_update = vc_dispmanx_update_start( 0 );
+        p->element.handle = vc_dispmanx_element_add ( dispman_update, dispman_display,
+                                              p->element.layer, &dst_rect, 
+                                              p->resource.handle /*src*/,
+                                              &src_rect, DISPMANX_PROTECTION_NONE, 
+                                              &dispman_alpha /*alpha */, 0/*clamp*/, 0/*transform*/);
+        vc_dispmanx_update_submit_sync( dispman_update );
+    } else {
+        // DISABLE
+        if( 0 == p->element.handle ) {
+            return; 
+        }
+        p->element.x = x;
+        p->element.y = y;
+        DISPMANX_UPDATE_HANDLE_T dispman_update = vc_dispmanx_update_start( 0 );
+        vc_dispmanx_element_remove( dispman_update, p->element.handle );
+        p->element.handle = 0;
+        vc_dispmanx_update_submit_sync( dispman_update );
+    }
+    DBG_PRINT( "BCM.Display PointerIcon.Set.X %p, PI %p, resource %p, element %p - enable %d - %d/%d\n", 
+        (void*)(intptr_t)display, p, (void*)(intptr_t)p->resource.handle, (void*)(intptr_t)p->element.handle, enable, x, y);
+}
+
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_DisplayDriver_MovePointerIcon0
+  (JNIEnv *env, jclass clazz, jlong handle, jint x, jint y)
+{
+    POINTER_ICON_T * p = (POINTER_ICON_T *) (intptr_t) handle ;
+
+    if( NULL == p || 0 == p->element.handle ) {
+        return; 
+    }
+    DBG_PRINT( "BCM.Display PointerIcon.Move.0 PI %p, resource %p, element %p - %d/%d\n", 
+        p, (void*)(intptr_t)p->resource.handle, (void*)(intptr_t)p->element.handle, x, y);
+    p->element.x = x;
+    p->element.y = y;
+    bcm_moveTo( p->element.handle, p->element.layer, p->element.x - p->hotX, p->element.y - p->hotY, p->element.width, p->element.height);
 }
 
 /**
@@ -111,12 +334,12 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_ScreenDriver_initNative
 JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_initIDs
   (JNIEnv *env, jclass clazz)
 {
-    windowCreatedID = (*env)->GetMethodID(env, clazz, "windowCreated", "(J)V");
     sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(ZIIZ)V");
+    positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(ZII)V");
     visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(ZZ)V");
     windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "(Z)Z");
-    if (windowCreatedID == NULL ||
-        sizeChangedID == NULL ||
+    if (sizeChangedID == NULL ||
+        positionChangedID == NULL ||
         visibleChangedID == NULL ||
         windowDestroyNotifyID == NULL) {
         DBG_PRINT( "initIDs failed\n" );
@@ -126,15 +349,18 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_initID
     return JNI_TRUE;
 }
 
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_CreateWindow
-  (JNIEnv *env, jobject obj, jint width, jint height, jboolean opaque, jint alphaBits)
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_CreateWindow0
+  (JNIEnv *env, jobject obj, jlong display, jint layer, jint x, jint y, jint width, jint height, jboolean opaque, jint alphaBits)
 {
    int32_t success = 0;
    VC_RECT_T dst_rect;
    VC_RECT_T src_rect;
 
-   dst_rect.x = 0;
-   dst_rect.y = 0;
+   if( 0 == display ) {
+       return;
+   }
+   dst_rect.x = x;
+   dst_rect.y = y;
    dst_rect.width = width;
    dst_rect.height = height;
       
@@ -156,58 +382,82 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_CreateWin
        dispman_alpha.mask = 0xFF;
    }
 
-   DISPMANX_DISPLAY_HANDLE_T dispman_display = vc_dispmanx_display_open( 0 /* LCD */);
-   DISPMANX_UPDATE_HANDLE_T dispman_update = vc_dispmanx_update_start( 0 );
-   DISPMANX_ELEMENT_HANDLE_T dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display,
-                                                                         0/*layer*/, &dst_rect, 0/*src*/,
-                                                                         &src_rect, DISPMANX_PROTECTION_NONE, 
-                                                                         &dispman_alpha /*alpha */, 0/*clamp*/, 0/*transform*/);
+   DISPMANX_DISPLAY_HANDLE_T dispman_display = (DISPMANX_DISPLAY_HANDLE_T) (intptr_t) display;
 
-   EGL_DISPMANX_WINDOW_T * nativeWindowPtr = calloc(1, sizeof(EGL_DISPMANX_WINDOW_T));  
-   nativeWindowPtr->element = dispman_element;
-   nativeWindowPtr->width = width;
-   nativeWindowPtr->height = height;
+   DBG_PRINT( "BCM.Display Window.Create.0 %p, %d/%d %dx%d, opaque %d, alphaBits %d, layer %d\n",
+    (void*)(intptr_t)dispman_display, x, y, width, height, opaque, alphaBits, layer);
+
+   BCM_ELEMENT_T * p = calloc(1, sizeof(BCM_ELEMENT_T));  
+   DISPMANX_UPDATE_HANDLE_T dispman_update = vc_dispmanx_update_start( 0 );
+   p->layer = layer;
+   p->x = x;
+   p->y = y;
+   p->width = width;
+   p->height = height;
+   p->handle = vc_dispmanx_element_add ( dispman_update, dispman_display,
+                                         p->layer, &dst_rect, 0/*src*/,
+                                         &src_rect, DISPMANX_PROTECTION_NONE, 
+                                         &dispman_alpha /*alpha */, 0/*clamp*/, 0/*transform*/);
 
    vc_dispmanx_update_submit_sync( dispman_update );
 
    (*env)->CallVoidMethod(env, obj, visibleChangedID, JNI_FALSE, JNI_TRUE); // FIXME: or defer=true ?
 
-   return (jlong) (intptr_t) nativeWindowPtr;
-}
+   DBG_PRINT( "BCM.Display Window.Create.X %p, element %p\n", 
+    (void*)(intptr_t)dispman_display, (void*)(intptr_t)p->handle);
 
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_RealizeWindow
-  (JNIEnv *env, jobject obj, jlong window)
-{
-    return (jlong) (intptr_t) 0;
+   return (jlong) (intptr_t) p;
 }
 
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_CloseWindow
-  (JNIEnv *env, jobject obj, jlong window, jlong juserData)
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_CloseWindow0
+  (JNIEnv *env, jobject obj, jlong display, jlong window)
 {
-    EGL_DISPMANX_WINDOW_T * nativeWindowPtr = (EGL_DISPMANX_WINDOW_T *) (intptr_t) window ;
-    free( nativeWindowPtr );
-    return 0;
-}
+    DISPMANX_DISPLAY_HANDLE_T dispman_display = (DISPMANX_DISPLAY_HANDLE_T) (intptr_t) display;
+    BCM_ELEMENT_T * p = (BCM_ELEMENT_T *) (intptr_t) window ;
 
-/*
- * Class:     jogamp_newt_driver_bcm_vc_iv_WindowDriver
- * Method:    setVisible0
- * Signature: (JJZ)V
- */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_setVisible0
-  (JNIEnv *env, jobject obj, jlong window, jboolean visible)
-{
-}
+    DBG_PRINT( "BCM.Display Window.Close %p, element %p\n", 
+        (void*)(intptr_t)dispman_display, (void*)(intptr_t)p->handle);
 
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_setFullScreen0
-  (JNIEnv *env, jobject obj, jlong window, jboolean fullscreen)
-{
+    if( 0 == dispman_display || NULL == p || 0 == p->handle ) {
+        return;
+    }
+    DISPMANX_UPDATE_HANDLE_T dispman_update = vc_dispmanx_update_start( 0 );
+    vc_dispmanx_element_remove( dispman_update, p->handle );
+    p->handle = 0;
+    vc_dispmanx_update_submit_sync( dispman_update );
+    free( p );
 }
 
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_setSize0
-  (JNIEnv *env, jobject obj, jlong window, jint width, jint height)
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_reconfigure0
+  (JNIEnv *env, jobject obj, jlong window, jint x, jint y, jint width, jint height, jint flags)
 {
-    // FIXME RESIZE (*env)->CallVoidMethod(env, obj, sizeChangedID, JNI_FALSE, (jint) width, (jint) height, JNI_FALSE);
-}
+    BCM_ELEMENT_T * p = (BCM_ELEMENT_T *) (intptr_t) window ;
 
+    if( NULL == p || 0 == p->handle ) {
+        return; 
+    }
+    /***
+        int isVisible = !TST_FLAG_CHANGE_VISIBILITY(flags) && TST_FLAG_IS_VISIBLE(flags) ;
+        ...  
+        see X11Window.c
+     */
+
+    int posChanged = p->x != x || p->y != y;
+    int sizeChanged = p->width != width || p->height != height;
+    p->x = x;
+    p->y = y;
+    p->width = width;
+    p->height = height;
+
+    DBG_PRINT( "BCM.Display Window.Reconfig %p, element %p - %d/%d %dx%d\n", 
+        p, (void*)(intptr_t)p->handle, p->x, p->y, p->width, p->height);
+
+    bcm_moveTo( p->handle, p->layer, p->x, p->y, p->width, p->height);
+    if( posChanged ) {
+        (*env)->CallVoidMethod(env, obj, positionChangedID, JNI_FALSE, x, y);
+    }
+    if( sizeChanged ) {
+        (*env)->CallVoidMethod(env, obj, sizeChangedID, JNI_FALSE, (jint) width, (jint) height, JNI_FALSE);
+    }
+}
 
diff --git a/src/newt/native/bcm_vc_iv.h b/src/newt/native/bcm_vc_iv.h
index b43483c..42189f3 100644
--- a/src/newt/native/bcm_vc_iv.h
+++ b/src/newt/native/bcm_vc_iv.h
@@ -29,6 +29,11 @@
 #ifndef BCM_VC_IV_H
 #define BCM_VC_IV_H
 
+/** 
+ * http://en.wikipedia.org/wiki/VideoCore
+ * https://github.com/raspberrypi/userland
+ */
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -150,12 +155,6 @@ typedef struct {
 } DISPMANX_CLAMP_T;
 
 
-typedef struct {
- DISPMANX_ELEMENT_HANDLE_T element;
- int width;   /* This is necessary because dispmanx elements are not queriable. */
- int height;
-} EGL_DISPMANX_WINDOW_T;
-
 typedef struct tag_VC_RECT_T {
  int32_t x;
  int32_t y;
@@ -163,6 +162,102 @@ typedef struct tag_VC_RECT_T {
  int32_t height;
 } VC_RECT_T;
 
+/* Types of image supported. */
+/* Please add any new types to the *end* of this list.  Also update
+ * case_VC_IMAGE_ANY_xxx macros (below), and the vc_image_type_info table in
+ * vc_image/vc_image_helper.c.
+ */
+typedef enum
+{
+   VC_IMAGE_MIN = 0, //bounds for error checking
+
+   VC_IMAGE_RGB565 = 1,
+   VC_IMAGE_1BPP,
+   VC_IMAGE_YUV420,
+   VC_IMAGE_48BPP,
+   VC_IMAGE_RGB888,
+   VC_IMAGE_8BPP,
+   VC_IMAGE_4BPP,    // 4bpp palettised image
+   VC_IMAGE_3D32,    /* A separated format of 16 colour/light shorts followed by 16 z values */
+   VC_IMAGE_3D32B,   /* 16 colours followed by 16 z values */
+   VC_IMAGE_3D32MAT, /* A separated format of 16 material/colour/light shorts followed by 16 z values */
+   VC_IMAGE_RGB2X9,   /* 32 bit format containing 18 bits of 6.6.6 RGB, 9 bits per short */
+   VC_IMAGE_RGB666,   /* 32-bit format holding 18 bits of 6.6.6 RGB */
+   VC_IMAGE_PAL4_OBSOLETE,     // 4bpp palettised image with embedded palette
+   VC_IMAGE_PAL8_OBSOLETE,     // 8bpp palettised image with embedded palette
+   VC_IMAGE_RGBA32,   /* RGB888 with an alpha byte after each pixel */ /* xxx: isn't it BEFORE each pixel? */
+   VC_IMAGE_YUV422,   /* a line of Y (32-byte padded), a line of U (16-byte padded), and a line of V (16-byte padded) */
+   VC_IMAGE_RGBA565,  /* RGB565 with a transparent patch */
+   VC_IMAGE_RGBA16,   /* Compressed (4444) version of RGBA32 */
+   VC_IMAGE_YUV_UV,   /* VCIII codec format */
+   VC_IMAGE_TF_RGBA32, /* VCIII T-format RGBA8888 */
+   VC_IMAGE_TF_RGBX32,  /* VCIII T-format RGBx8888 */
+   VC_IMAGE_TF_FLOAT, /* VCIII T-format float */
+   VC_IMAGE_TF_RGBA16, /* VCIII T-format RGBA4444 */
+   VC_IMAGE_TF_RGBA5551, /* VCIII T-format RGB5551 */
+   VC_IMAGE_TF_RGB565, /* VCIII T-format RGB565 */
+   VC_IMAGE_TF_YA88, /* VCIII T-format 8-bit luma and 8-bit alpha */
+   VC_IMAGE_TF_BYTE, /* VCIII T-format 8 bit generic sample */
+   VC_IMAGE_TF_PAL8, /* VCIII T-format 8-bit palette */
+   VC_IMAGE_TF_PAL4, /* VCIII T-format 4-bit palette */
+   VC_IMAGE_TF_ETC1, /* VCIII T-format Ericsson Texture Compressed */
+   VC_IMAGE_BGR888,  /* RGB888 with R & B swapped */
+   VC_IMAGE_BGR888_NP,  /* RGB888 with R & B swapped, but with no pitch, i.e. no padding after each row of pixels */
+   VC_IMAGE_BAYER,  /* Bayer image, extra defines which variant is being used */
+   VC_IMAGE_CODEC,  /* General wrapper for codec images e.g. JPEG from camera */
+   VC_IMAGE_YUV_UV32,   /* VCIII codec format */
+   VC_IMAGE_TF_Y8,   /* VCIII T-format 8-bit luma */
+   VC_IMAGE_TF_A8,   /* VCIII T-format 8-bit alpha */
+   VC_IMAGE_TF_SHORT,/* VCIII T-format 16-bit generic sample */
+   VC_IMAGE_TF_1BPP, /* VCIII T-format 1bpp black/white */
+   VC_IMAGE_OPENGL,
+   VC_IMAGE_YUV444I, /* VCIII-B0 HVS YUV 4:4:4 interleaved samples */
+   VC_IMAGE_YUV422PLANAR,  /* Y, U, & V planes separately (VC_IMAGE_YUV422 has them interleaved on a per line basis) */
+   VC_IMAGE_ARGB8888,   /* 32bpp with 8bit alpha at MS byte, with R, G, B (LS byte) */
+   VC_IMAGE_XRGB8888,   /* 32bpp with 8bit unused at MS byte, with R, G, B (LS byte) */
+
+   VC_IMAGE_YUV422YUYV,  /* interleaved 8 bit samples of Y, U, Y, V */
+   VC_IMAGE_YUV422YVYU,  /* interleaved 8 bit samples of Y, V, Y, U */
+   VC_IMAGE_YUV422UYVY,  /* interleaved 8 bit samples of U, Y, V, Y */
+   VC_IMAGE_YUV422VYUY,  /* interleaved 8 bit samples of V, Y, U, Y */
+
+   VC_IMAGE_RGBX32,      /* 32bpp like RGBA32 but with unused alpha */
+   VC_IMAGE_RGBX8888,    /* 32bpp, corresponding to RGBA with unused alpha */
+   VC_IMAGE_BGRX8888,    /* 32bpp, corresponding to BGRA with unused alpha */
+
+   VC_IMAGE_YUV420SP,    /* Y as a plane, then UV byte interleaved in plane with with same pitch, half height */
+   
+   VC_IMAGE_YUV444PLANAR,  /* Y, U, & V planes separately 4:4:4 */
+   
+   VC_IMAGE_MAX,     //bounds for error checking
+   VC_IMAGE_FORCE_ENUM_16BIT = 0xffff,
+} VC_IMAGE_TYPE_T;
+
+/**
+ * From https://github.com/raspberrypi/userland/blob/master/interface/vmcs_host/vc_vchi_dispmanx.h
+ */
+typedef enum {
+   DISPMANX_ELEMENT_CHANGE_LAYER         =  (1<<0),
+   DISPMANX_ELEMENT_CHANGE_OPACITY       =  (1<<1),
+   DISPMANX_ELEMENT_CHANGE_DEST_RECT     =  (1<<2),
+   DISPMANX_ELEMENT_CHANGE_SRC_RECT      =  (1<<3),
+   DISPMANX_ELEMENT_CHANGE_MASK_RESOURCE =  (1<<4),
+   DISPMANX_ELEMENT_CHANGE_TRANSFORM     =  (1<<5)
+/**
+ * Not working /validated !
+   DISPMANX_ELEMENT_CHANGE_MIN         =  0x00,
+   DISPMANX_ELEMENT_CHANGE_SOURCE      =  0x01,
+   DISPMANX_ELEMENT_INSERT_ABOVE       =  0x80,
+   DISPMANX_ELEMENT_CHANGE_FLAGS       =  0x100,
+   DISPMANX_ELEMENT_CHANGE_NOTHING     =  0x200,
+   DISPMANX_ELEMENT_CHANGE_ALPHA_FLAGS =  0x400,
+   DISPMANX_ELEMENT_CHANGE_PROTECTION  =  0x800,
+   DISPMANX_ELEMENT_CHANGE_MAX         =  0x1000
+ */
+} DISPMANX_ELEMENT_CHANGE_T;
+
+
+
 extern void bcm_host_init(void);
 extern void bcm_host_deinit(void);
 
@@ -171,15 +266,38 @@ extern int32_t graphics_get_display_size( const uint16_t display_number,
                                          uint32_t *height);
 
 extern DISPMANX_DISPLAY_HANDLE_T vc_dispmanx_display_open( uint32_t device );
+extern int vc_dispmanx_display_close( DISPMANX_DISPLAY_HANDLE_T display );
+
+extern DISPMANX_RESOURCE_HANDLE_T vc_dispmanx_resource_create(VC_IMAGE_TYPE_T type, uint32_t width, uint32_t height, uint32_t *native_image_handle);
+extern int vc_dispmanx_resource_write_data( DISPMANX_RESOURCE_HANDLE_T res, VC_IMAGE_TYPE_T src_type, int src_pitch, void * src_address, const VC_RECT_T * rect );
+//extern int vc_dispmanx_resource_write_data_handle( DISPMANX_RESOURCE_HANDLE_T res, VC_IMAGE_TYPE_T src_type, int src_pitch, 
+//                                                   VCHI_MEM_HANDLE_T handle, uint32_t offset, const VC_RECT_T * rect );
+extern int vc_dispmanx_resource_delete( DISPMANX_RESOURCE_HANDLE_T res );
+
+
+
 extern DISPMANX_UPDATE_HANDLE_T vc_dispmanx_update_start( int32_t priority );
 extern DISPMANX_ELEMENT_HANDLE_T vc_dispmanx_element_add ( DISPMANX_UPDATE_HANDLE_T update, DISPMANX_DISPLAY_HANDLE_T display,
                                                           int32_t layer, const VC_RECT_T *dest_rect, DISPMANX_RESOURCE_HANDLE_T src,
                                                           const VC_RECT_T *src_rect, DISPMANX_PROTECTION_T protection, 
                                                           VC_DISPMANX_ALPHA_T *alpha,
                                                           DISPMANX_CLAMP_T *clamp, DISPMANX_TRANSFORM_T transform );
+extern int vc_dispmanx_element_remove( DISPMANX_UPDATE_HANDLE_T update, DISPMANX_ELEMENT_HANDLE_T element );
+
 
 extern int vc_dispmanx_update_submit_sync( DISPMANX_UPDATE_HANDLE_T update );
 
+//New function added to VCHI to change attributes, set_opacity does not work there.
+extern int vc_dispmanx_element_change_attributes( DISPMANX_UPDATE_HANDLE_T update,
+                                                  DISPMANX_ELEMENT_HANDLE_T element,
+                                                  uint32_t change_flags,
+                                                  int32_t layer,
+                                                  uint8_t opacity,
+                                                  const VC_RECT_T *dest_rect,
+                                                  const VC_RECT_T *src_rect,
+                                                  DISPMANX_RESOURCE_HANDLE_T mask,
+                                                  DISPMANX_TRANSFORM_T transform );
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLMesaBug658NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLMesaBug658NEWT.java
index b11a6f9..cb225b9 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLMesaBug658NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLMesaBug658NEWT.java
@@ -168,7 +168,7 @@ public class TestGLMesaBug658NEWT extends UITestCase {
         gl.glBufferData(GL.GL_ARRAY_BUFFER, 4 * 32, null, GL.GL_STATIC_DRAW);
         Assert.assertTrue(gl.glGetError() == 0);
 
-        Assert.assertTrue(gl.glGetBoundBuffer(GL.GL_ARRAY_BUFFER) == name[0]);
+        Assert.assertTrue(gl.getBoundBuffer(GL.GL_ARRAY_BUFFER) == name[0]);
         gl.glEnableVertexAttribArray(1);
         Assert.assertTrue(gl.glGetError() == GL.GL_NO_ERROR);
         gl.glVertexAttribPointer(1, 4, GL.GL_FLOAT, false, 0, 0L);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLProfile01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLProfile01NEWT.java
index 462934c..88d643a 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLProfile01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLProfile01NEWT.java
@@ -3,14 +3,14 @@
  *
  * 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 JogAmp Community ``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 JogAmp Community OR
@@ -20,184 +20,392 @@
  * 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.
- * 
+ *
  * The views and conclusions contained in the software and documentation are those of the
  * authors and should not be interpreted as representing official policies, either expressed
  * or implied, of JogAmp Community.
  */
- 
+
 package com.jogamp.opengl.test.junit.jogl.acore;
 
 import java.io.IOException;
 
+import javax.media.opengl.GL;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLProfile;
+
 import org.junit.Assert;
-import org.junit.Test;
 import org.junit.FixMethodOrder;
+import org.junit.Test;
 import org.junit.runners.MethodSorters;
 
-import javax.media.opengl.*;
-
 import com.jogamp.common.GlueGenVersion;
 import com.jogamp.common.util.VersionUtil;
 import com.jogamp.nativewindow.NativeWindowVersion;
-import com.jogamp.opengl.test.junit.util.UITestCase;
-import com.jogamp.opengl.test.junit.util.DumpGLInfo;
+import com.jogamp.newt.NewtVersion;
+import com.jogamp.newt.opengl.GLWindow;
 import com.jogamp.opengl.JoglVersion;
-import com.jogamp.newt.opengl.*;
-import com.jogamp.newt.*;
+import com.jogamp.opengl.test.junit.util.UITestCase;
 
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 public class TestGLProfile01NEWT extends UITestCase {
 
     @Test
-    public void testVersion() throws InterruptedException {
+    public void test00Version() throws InterruptedException {
         System.err.println(VersionUtil.getPlatformInfo());
         System.err.println(GlueGenVersion.getInstance());
         System.err.println(NativeWindowVersion.getInstance());
         System.err.println(JoglVersion.getInstance());
         System.err.println(NewtVersion.getInstance());
 
-        System.err.println(JoglVersion.getDefaultOpenGLInfo(null, null, true).toString());        
+        final GLDrawableFactory deskFactory = GLDrawableFactory.getDesktopFactory();
+        if( null != deskFactory ) {
+            System.err.println(JoglVersion.getDefaultOpenGLInfo(deskFactory.getDefaultDevice(), null, true).toString());
+        }
+        final GLDrawableFactory eglFactory = GLDrawableFactory.getEGLFactory();
+        if( null != eglFactory ) {
+            System.err.println(JoglVersion.getDefaultOpenGLInfo(eglFactory.getDefaultDevice(), null, true).toString());
+        }
     }
 
-    @Test
-    public void testGLProfileDefault() throws InterruptedException {
-        System.out.println("GLProfile "+GLProfile.glAvailabilityToString());
-        System.out.println("GLProfile.getDefaultDevice(): "+GLProfile.getDefaultDevice());        
-        GLProfile glp = GLProfile.getDefault();
-        System.out.println("GLProfile.getDefault(): "+glp);
-        if(glp.getName().equals(GLProfile.GL4bc)) {
+    static void validate(GLProfile glp) {
+        final boolean gles3CompatAvail = GLContext.isGLES3CompatibleAvailable(GLProfile.getDefaultDevice());
+        if( glp.getImplName().equals(GLProfile.GL4bc) ) {
             Assert.assertTrue(GLProfile.isAvailable(GLProfile.GL4bc));
+            Assert.assertTrue(GLProfile.isAvailable(GLProfile.GL4));
             Assert.assertTrue(GLProfile.isAvailable(GLProfile.GL3bc));
             Assert.assertTrue(GLProfile.isAvailable(GLProfile.GL2));
+            Assert.assertTrue(GLProfile.isAvailable(GLProfile.GL2GL3));
+            if( gles3CompatAvail ) {
+                Assert.assertTrue(GLProfile.isAvailable(GLProfile.GL4ES3));
+            } else {
+                Assert.assertFalse(GLProfile.isAvailable(GLProfile.GL4ES3));
+            }
             Assert.assertTrue(GLProfile.isAvailable(GLProfile.GL2ES1));
             Assert.assertTrue(GLProfile.isAvailable(GLProfile.GL2ES2));
-        } else if(glp.getName().equals(GLProfile.GL3bc)) {
+        } else if(glp.getImplName().equals(GLProfile.GL3bc)) {
             Assert.assertTrue(GLProfile.isAvailable(GLProfile.GL3bc));
+            Assert.assertTrue(GLProfile.isAvailable(GLProfile.GL3));
             Assert.assertTrue(GLProfile.isAvailable(GLProfile.GL2));
+            Assert.assertTrue(GLProfile.isAvailable(GLProfile.GL2GL3));
             Assert.assertTrue(GLProfile.isAvailable(GLProfile.GL2ES1));
             Assert.assertTrue(GLProfile.isAvailable(GLProfile.GL2ES2));
-        } else if(glp.getName().equals(GLProfile.GL2)) {
+        } else if(glp.getImplName().equals(GLProfile.GL2)) {
             Assert.assertTrue(GLProfile.isAvailable(GLProfile.GL2));
+            Assert.assertTrue(GLProfile.isAvailable(GLProfile.GL2GL3));
             Assert.assertTrue(GLProfile.isAvailable(GLProfile.GL2ES1));
             Assert.assertTrue(GLProfile.isAvailable(GLProfile.GL2ES2));
-        } else if(glp.getName().equals(GLProfile.GL2ES1)) {
+        } else if(glp.getImplName().equals(GLProfile.GL4)) {
+            Assert.assertTrue(GLProfile.isAvailable(GLProfile.GL4));
+            Assert.assertTrue(GLProfile.isAvailable(GLProfile.GL3));
+            Assert.assertTrue(GLProfile.isAvailable(GLProfile.GL2GL3));
+            if( gles3CompatAvail ) {
+                Assert.assertTrue(GLProfile.isAvailable(GLProfile.GL4ES3));
+            } else {
+                Assert.assertFalse(GLProfile.isAvailable(GLProfile.GL4ES3));
+            }
+            Assert.assertTrue(GLProfile.isAvailable(GLProfile.GL2ES2));
+        } else if(glp.getImplName().equals(GLProfile.GL3)) {
+            Assert.assertTrue(GLProfile.isAvailable(GLProfile.GL3));
+            Assert.assertTrue(GLProfile.isAvailable(GLProfile.GL2GL3));
+            Assert.assertTrue(GLProfile.isAvailable(GLProfile.GL2ES2));
+        } else if(glp.getImplName().equals(GLProfile.GLES3)) {
+            Assert.assertTrue(GLProfile.isAvailable(GLProfile.GLES3));
+            if( gles3CompatAvail ) {
+                Assert.assertTrue(GLProfile.isAvailable(GLProfile.GL4ES3));
+            } else {
+                Assert.assertFalse(GLProfile.isAvailable(GLProfile.GL4ES3));
+            }
+            Assert.assertTrue(GLProfile.isAvailable(GLProfile.GL2ES2));
+        } else if(glp.getImplName().equals(GLProfile.GLES2)) {
+            Assert.assertTrue(GLProfile.isAvailable(GLProfile.GLES2));
+            Assert.assertTrue(GLProfile.isAvailable(GLProfile.GL2ES2));
+        } else if(glp.getImplName().equals(GLProfile.GLES1)) {
+            Assert.assertTrue(GLProfile.isAvailable(GLProfile.GLES1));
             Assert.assertTrue(GLProfile.isAvailable(GLProfile.GL2ES1));
         }
+        if( glp.isGL4bc() ) {
+            Assert.assertTrue(glp.isGL4());
+            Assert.assertTrue(glp.isGL3bc());
+            Assert.assertTrue(glp.isGL3());
+            Assert.assertTrue(glp.isGL2());
+            Assert.assertTrue(glp.isGL2GL3());
+            Assert.assertTrue(glp.isGL4ES3());
+            Assert.assertTrue(glp.isGL3ES3());
+            Assert.assertTrue(glp.isGL2ES1());
+            Assert.assertTrue(glp.isGL2ES2());
+        } else if(glp.isGL3bc()) {
+            Assert.assertTrue(glp.isGL3());
+            Assert.assertTrue(glp.isGL2());
+            Assert.assertTrue(glp.isGL2GL3());
+            Assert.assertTrue(glp.isGL2ES1());
+            Assert.assertTrue(glp.isGL2ES2());
+        } else if(glp.isGL2()) {
+            Assert.assertTrue(glp.isGL2GL3());
+            Assert.assertTrue(glp.isGL2ES1());
+            Assert.assertTrue(glp.isGL2ES2());
+        } else if(glp.isGL4()) {
+            Assert.assertTrue(glp.isGL3());
+            Assert.assertTrue(glp.isGL2GL3());
+            Assert.assertTrue(glp.isGL4ES3());
+            Assert.assertTrue(glp.isGL3ES3());
+            Assert.assertTrue(glp.isGL2ES2());
+        } else if(glp.isGL3()) {
+            Assert.assertTrue(glp.isGL2GL3());
+            Assert.assertTrue(glp.isGL3ES3());
+            Assert.assertTrue(glp.isGL2ES2());
+        } else if(glp.isGLES3()) {
+            Assert.assertTrue(glp.isGL4ES3());
+            Assert.assertTrue(glp.isGL3ES3());
+            Assert.assertTrue(glp.isGL2ES2());
+        } else if(glp.isGLES2()) {
+            Assert.assertTrue(glp.isGL2ES2());
+        } else if(glp.isGLES1()) {
+            Assert.assertTrue(glp.isGL2ES1());
+        }
+    }
+
+    static void validate(GL gl) {
+        final GLContext ctx = gl.getContext();
+        final boolean gles3CompatAvail = ctx.isGLES3Compatible();
+
+        if( gl.isGL4bc() ) {
+            Assert.assertTrue(gl.isGL4());
+            Assert.assertTrue(gl.isGL3bc());
+            Assert.assertTrue(gl.isGL3());
+            Assert.assertTrue(gl.isGL2());
+            Assert.assertTrue(gl.isGL2GL3());
+            if( gles3CompatAvail ) {
+                Assert.assertTrue(gl.isGL4ES3());
+            } else {
+                Assert.assertFalse(gl.isGL4ES3());
+            }
+            Assert.assertTrue(gl.isGL3ES3());
+            Assert.assertTrue(gl.isGL2ES1());
+            Assert.assertTrue(gl.isGL2ES2());
+        } else if(gl.isGL3bc()) {
+            Assert.assertTrue(gl.isGL3());
+            Assert.assertTrue(gl.isGL2());
+            Assert.assertTrue(gl.isGL2GL3());
+            Assert.assertTrue(gl.isGL2ES1());
+            Assert.assertTrue(gl.isGL2ES2());
+        } else if(gl.isGL2()) {
+            Assert.assertTrue(gl.isGL2GL3());
+            Assert.assertTrue(gl.isGL2ES1());
+            Assert.assertTrue(gl.isGL2ES2());
+        } else if(gl.isGL4()) {
+            Assert.assertTrue(gl.isGL3());
+            Assert.assertTrue(gl.isGL2GL3());
+            if( gles3CompatAvail ) {
+                Assert.assertTrue(gl.isGL4ES3());
+            } else {
+                Assert.assertFalse(gl.isGL4ES3());
+            }
+            Assert.assertTrue(gl.isGL3ES3());
+            Assert.assertTrue(gl.isGL2ES2());
+        } else if(gl.isGL3()) {
+            Assert.assertTrue(gl.isGL2GL3());
+            Assert.assertTrue(gl.isGL3ES3());
+            Assert.assertTrue(gl.isGL2ES2());
+        } else if(gl.isGLES3()) {
+            if( gles3CompatAvail ) {
+                Assert.assertTrue(gl.isGL4ES3());
+            } else {
+                Assert.assertFalse(gl.isGL4ES3());
+            }
+            Assert.assertTrue(gl.isGL3ES3());
+            Assert.assertTrue(gl.isGL2ES2());
+        } else if(gl.isGLES2()) {
+            Assert.assertTrue(gl.isGL2ES2());
+        } else if(gl.isGLES1()) {
+            Assert.assertTrue(gl.isGL2ES1());
+        }
+
+        if( ctx.isGL4bc() ) {
+            Assert.assertTrue(ctx.isGL4());
+            Assert.assertTrue(ctx.isGL3bc());
+            Assert.assertTrue(ctx.isGL3());
+            Assert.assertTrue(ctx.isGL2());
+            Assert.assertTrue(ctx.isGL2GL3());
+            if( gles3CompatAvail ) {
+                Assert.assertTrue(ctx.isGL4ES3());
+            } else {
+                Assert.assertFalse(ctx.isGL4ES3());
+            }
+            Assert.assertTrue(ctx.isGL3ES3());
+            Assert.assertTrue(ctx.isGL2ES1());
+            Assert.assertTrue(ctx.isGL2ES2());
+        } else if(ctx.isGL3bc()) {
+            Assert.assertTrue(ctx.isGL3());
+            Assert.assertTrue(ctx.isGL2());
+            Assert.assertTrue(ctx.isGL2GL3());
+            Assert.assertTrue(ctx.isGL2ES1());
+            Assert.assertTrue(ctx.isGL2ES2());
+        } else if(ctx.isGL2()) {
+            Assert.assertTrue(ctx.isGL2GL3());
+            Assert.assertTrue(ctx.isGL2ES1());
+            Assert.assertTrue(ctx.isGL2ES2());
+        } else if(ctx.isGL4()) {
+            Assert.assertTrue(ctx.isGL3());
+            Assert.assertTrue(ctx.isGL2GL3());
+            if( gles3CompatAvail ) {
+                Assert.assertTrue(ctx.isGL4ES3());
+            } else {
+                Assert.assertFalse(ctx.isGL4ES3());
+            }
+            Assert.assertTrue(ctx.isGL3ES3());
+            Assert.assertTrue(ctx.isGL2ES2());
+        } else if(ctx.isGL3()) {
+            Assert.assertTrue(ctx.isGL2GL3());
+            Assert.assertTrue(ctx.isGL3ES3());
+            Assert.assertTrue(ctx.isGL2ES2());
+        } else if(ctx.isGLES3()) {
+            if( gles3CompatAvail ) {
+                Assert.assertTrue(ctx.isGL4ES3());
+            } else {
+                Assert.assertFalse(ctx.isGL4ES3());
+            }
+            Assert.assertTrue(ctx.isGL3ES3());
+            Assert.assertTrue(ctx.isGL2ES2());
+        } else if(ctx.isGLES2()) {
+            Assert.assertTrue(ctx.isGL2ES2());
+        } else if(ctx.isGLES1()) {
+            Assert.assertTrue(ctx.isGL2ES1());
+        }
+    }
+
+    @Test
+    public void test01GLProfileDefault() throws InterruptedException {
+        System.out.println("GLProfile "+GLProfile.glAvailabilityToString());
+        System.out.println("GLProfile.getDefaultDevice(): "+GLProfile.getDefaultDevice());
+        GLProfile glp = GLProfile.getDefault();
+        System.out.println("GLProfile.getDefault(): "+glp);
+        validate(glp);
         dumpVersion(glp);
     }
 
     @Test
-    public void testGLProfileMaxProgrammable() throws InterruptedException {
+    public void test02GLProfileMaxProgrammable() throws InterruptedException {
         // Assuming at least one programmable profile is available
         GLProfile glp = GLProfile.getMaxProgrammable(true);
         System.out.println("GLProfile.getMaxProgrammable(): "+glp);
-        if(glp.getName().equals(GLProfile.GL4)) {
-            Assert.assertTrue(GLProfile.isAvailable(GLProfile.GL4));
-            Assert.assertTrue(GLProfile.isAvailable(GLProfile.GL3));
-            Assert.assertTrue(GLProfile.isAvailable(GLProfile.GL2ES2));
-        } else if(glp.getName().equals(GLProfile.GL3)) {
-            Assert.assertTrue(GLProfile.isAvailable(GLProfile.GL3));
-            Assert.assertTrue(GLProfile.isAvailable(GLProfile.GL2ES2));
-        } else if(glp.getName().equals(GLProfile.GL2ES2)) {
-            Assert.assertTrue(GLProfile.isAvailable(GLProfile.GL2ES2));
-        }
+        validate(glp);
         dumpVersion(glp);
     }
 
     @Test
-    public void testGLProfileGL2ES1() throws InterruptedException {
+    public void test03GLProfileMaxFixedFunc() throws InterruptedException {
+        // Assuming at least one fixed function profile is available
+        GLProfile glp = GLProfile.getMaxFixedFunc(true);
+        System.out.println("GLProfile.getMaxFixedFunc(): "+glp);
+        validate(glp);
+        dumpVersion(glp);
+    }
+
+    @Test
+    public void test04GLProfileGL2ES1() throws InterruptedException {
         if(!GLProfile.isAvailable(GLProfile.GL2ES1)) {
             System.out.println("GLProfile GL2ES1 n/a");
             return;
         }
         GLProfile glp = GLProfile.getGL2ES1();
         System.out.println("GLProfile GL2ES1: "+glp);
+        validate(glp);
         dumpVersion(glp);
     }
 
     @Test
-    public void testGLProfileGL2ES2() throws InterruptedException {
+    public void test05GLProfileGL2ES2() throws InterruptedException {
         if(!GLProfile.isAvailable(GLProfile.GL2ES2)) {
             System.out.println("GLProfile GL2ES2 n/a");
             return;
         }
         GLProfile glp = GLProfile.getGL2ES2();
         System.out.println("GLProfile GL2ES2: "+glp);
+        validate(glp);
         dumpVersion(glp);
     }
 
     @Test
-    public void testGLProfileGL4ES3() throws InterruptedException {
+    public void test06GLProfileGL4ES3() throws InterruptedException {
         if(!GLProfile.isAvailable(GLProfile.GL4ES3)) {
             System.out.println("GLProfile GL4ES3 n/a");
             return;
         }
         GLProfile glp = GLProfile.getGL4ES3();
         System.out.println("GLProfile GL4ES3: "+glp);
+        validate(glp);
         dumpVersion(glp);
     }
-    
+
     void testSpecificProfile(String glps) throws InterruptedException {
         if(GLProfile.isAvailable(glps)) {
             GLProfile glp = GLProfile.get(glps);
+            validate(glp);
             dumpVersion(glp);
         } else {
             System.err.println("Profile "+glps+" n/a");
         }
     }
-    
+
     @Test
-    public void testGL4bc() throws InterruptedException {
+    public void test10_GL4bc() throws InterruptedException {
         testSpecificProfile(GLProfile.GL4bc);
     }
 
     @Test
-    public void testGL3bc() throws InterruptedException {
+    public void test11_GL3bc() throws InterruptedException {
         testSpecificProfile(GLProfile.GL3bc);
     }
 
     @Test
-    public void testGL2() throws InterruptedException {
+    public void test12_GL2() throws InterruptedException {
         testSpecificProfile(GLProfile.GL2);
     }
-    
+
     @Test
-    public void testGL4() throws InterruptedException {
+    public void test13_GL4() throws InterruptedException {
         testSpecificProfile(GLProfile.GL4);
     }
 
     @Test
-    public void testGL3() throws InterruptedException {
+    public void test14_GL3() throws InterruptedException {
         testSpecificProfile(GLProfile.GL3);
     }
 
     @Test
-    public void testGLES1() throws InterruptedException {
+    public void test15_GLES1() throws InterruptedException {
         testSpecificProfile(GLProfile.GLES1);
     }
 
     @Test
-    public void testGLES2() throws InterruptedException {
+    public void test16_GLES2() throws InterruptedException {
         testSpecificProfile(GLProfile.GLES2);
     }
-    
+
     @Test
-    public void testGLES3() throws InterruptedException {
+    public void test17_GLES3() throws InterruptedException {
         testSpecificProfile(GLProfile.GLES3);
     }
-    
+
     protected void dumpVersion(GLProfile glp) throws InterruptedException {
-        GLCapabilities caps = new GLCapabilities(glp);        
+        GLCapabilities caps = new GLCapabilities(glp);
         GLWindow glWindow = GLWindow.create(caps);
         Assert.assertNotNull(glWindow);
         glWindow.setTitle("TestGLProfile01NEWT");
 
-        glWindow.addGLEventListener(new DumpGLInfo());
         glWindow.addGLEventListener(new GLEventListener() {
-        
+
             public void init(GLAutoDrawable drawable) {
                 final GL gl = drawable.getGL();
+                System.err.println(JoglVersion.getGLStrings(gl, null, true));
+
+                validate(gl);
+
                 final GLProfile glp = gl.getGLProfile();
                 System.err.println("GL impl. class "+gl.getClass().getName());
                 if( gl.isGL4() ) {
@@ -237,13 +445,13 @@ public class TestGLProfile01NEWT extends UITestCase {
                     System.err.println("GL Mapping "+glp+" -> GL2ES1");
                 }
             }
-        
+
             public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
             }
-        
+
             public void display(GLAutoDrawable drawable) {
             }
-        
+
             public void dispose(GLAutoDrawable drawable) {
             }
         });
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestInitConcurrent01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestInitConcurrent01NEWT.java
index 3933000..7aca280 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestInitConcurrent01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestInitConcurrent01NEWT.java
@@ -3,14 +3,14 @@
  *
  * 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 JogAmp Community ``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 JogAmp Community OR
@@ -20,12 +20,12 @@
  * 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.
- * 
+ *
  * The views and conclusions contained in the software and documentation are those of the
  * authors and should not be interpreted as representing official policies, either expressed
  * or implied, of JogAmp Community.
  */
- 
+
 package com.jogamp.opengl.test.junit.jogl.acore;
 
 import java.io.IOException;
@@ -45,17 +45,17 @@ import com.jogamp.common.os.Platform;
  */
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 public class TestInitConcurrent01NEWT extends InitConcurrentBaseNEWT {
-    
+
     @Test(timeout=180000) // TO 3 min
     public void test02TwoThreads() throws InterruptedException {
         runJOGLTasks(2, true);
     }
-    
+
     @Test(timeout=180000) // TO 3 min
-    public void test02FourThreads() throws InterruptedException {
+    public void test04FourThreads() throws InterruptedException {
         runJOGLTasks(4, true);
     }
-    
+
     @Test(timeout=300000) // TO 5 min
     public void test16SixteenThreads() throws InterruptedException {
         if( Platform.getCPUFamily() != Platform.CPUFamily.ARM &&
@@ -65,7 +65,7 @@ public class TestInitConcurrent01NEWT extends InitConcurrentBaseNEWT {
             runJOGLTasks( 6, true);
         }
     }
-    
+
     public static void main(String args[]) throws IOException {
         for(int i=0; i<args.length; i++) {
             if(args[i].equals("-time")) {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestMapBufferRead01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestMapBufferRead01NEWT.java
index 8fee790..ac82c74 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestMapBufferRead01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestMapBufferRead01NEWT.java
@@ -37,6 +37,7 @@ import java.nio.ByteOrder;
 
 import javax.media.opengl.GL;
 import javax.media.opengl.GL2GL3;
+import javax.media.opengl.GLBufferStorage;
 import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLProfile;
 
@@ -46,13 +47,15 @@ import org.junit.FixMethodOrder;
 import org.junit.runners.MethodSorters;
 
 /**
+ * Verifies content of buffer storage's content
+ * as well as general buffer- and buffer-storage tracking.
  *
  * @author Luz, et.al.
  */
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 public class TestMapBufferRead01NEWT extends UITestCase {
     static final boolean DEBUG = false;
-    
+
     @Test
     public void testWriteRead01a() throws InterruptedException {
         if(!GLProfile.isAvailable(GLProfile.GL2GL3)) {
@@ -76,51 +79,64 @@ public class TestMapBufferRead01NEWT extends UITestCase {
     private void testWriteRead01(ByteBuffer verticiesBB) throws InterruptedException {
         final NEWTGLContext.WindowContext winctx = NEWTGLContext.createOffscreenWindow(
                 new GLCapabilities(GLProfile.getGL2GL3()), 800, 600, true);
-        final GL gl = winctx.context.getGL();
-
-        int[] vertexBuffer = new int[1];
-        
-        verticiesBB.putFloat(0);
-        verticiesBB.putFloat(0.5f);
-        verticiesBB.putFloat(0);
-
-        verticiesBB.putFloat(0.5f);
-        verticiesBB.putFloat(-0.5f);
-        verticiesBB.putFloat(0);
-
-        verticiesBB.putFloat(-0.5f);
-        verticiesBB.putFloat(-0.5f);
-        verticiesBB.putFloat(0);
-        verticiesBB.rewind();
-        if(DEBUG) {
-            for(int i=0; i < verticiesBB.capacity(); i+=4) {
-                System.out.println("java "+i+": "+verticiesBB.getFloat(i));
+        try {
+            final GL gl = winctx.context.getGL();
+
+            int[] vertexBuffer = new int[1];
+
+            verticiesBB.putFloat(0);
+            verticiesBB.putFloat(0.5f);
+            verticiesBB.putFloat(0);
+
+            verticiesBB.putFloat(0.5f);
+            verticiesBB.putFloat(-0.5f);
+            verticiesBB.putFloat(0);
+
+            verticiesBB.putFloat(-0.5f);
+            verticiesBB.putFloat(-0.5f);
+            verticiesBB.putFloat(0);
+            verticiesBB.rewind();
+            if(DEBUG) {
+                for(int i=0; i < verticiesBB.capacity(); i+=4) {
+                    System.err.println("java "+i+": "+verticiesBB.getFloat(i));
+                }
             }
-        }
 
-        gl.glGenBuffers(1, vertexBuffer, 0);
+            gl.glGenBuffers(1, vertexBuffer, 0);
 
-        gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vertexBuffer[0]);
+            gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vertexBuffer[0]);
 
-        // gl.glBufferData(GL.GL_ARRAY_BUFFER, verticiesBB.capacity(), verticiesBB, GL.GL_STATIC_READ);
-        gl.glBufferData(GL.GL_ARRAY_BUFFER, verticiesBB.capacity(), verticiesBB, GL.GL_STATIC_DRAW);
-        
-        ByteBuffer bb = gl.glMapBuffer(GL.GL_ARRAY_BUFFER, GL2GL3.GL_READ_ONLY);
-        Assert.assertNotNull(bb);
-        
-        if(DEBUG) {
+            // gl.glBufferData(GL.GL_ARRAY_BUFFER, verticiesBB.capacity(), verticiesBB, GL.GL_STATIC_READ);
+            gl.glBufferData(GL.GL_ARRAY_BUFFER, verticiesBB.capacity(), verticiesBB, GL.GL_STATIC_DRAW);
+
+            final int bufferName = gl.getBoundBuffer(GL.GL_ARRAY_BUFFER);
+            final GLBufferStorage bufferStorage = gl.getBufferStorage(bufferName);
+            System.err.println("gpu-01 GL_ARRAY_BUFFER -> bufferName "+bufferName+" -> "+bufferStorage);
+            Assert.assertEquals("Buffer storage's bytes-buffer not null before map", null, bufferStorage.getMappedBuffer());
+
+            final ByteBuffer bb = gl.glMapBuffer(GL.GL_ARRAY_BUFFER, GL2GL3.GL_READ_ONLY);
+            Assert.assertNotNull(bb);
+            System.err.println("gpu-02 mapped GL_ARRAY_BUFFER -> "+bb);
+            System.err.println("gpu-03 GL_ARRAY_BUFFER -> bufferName "+bufferName+" -> "+bufferStorage);
+            Assert.assertEquals("Buffer storage size not equals buffer storage size", bufferStorage.getSize(), bb.capacity());
+            Assert.assertEquals("Buffer storage's bytes-buffer not equal with mapped bytes-buffer", bufferStorage.getMappedBuffer(), bb);
+
+            if(DEBUG) {
+                for(int i=0; i < bb.capacity(); i+=4) {
+                    System.err.println("gpu "+i+": "+bb.getFloat(i));
+                }
+            }
             for(int i=0; i < bb.capacity(); i+=4) {
-                System.out.println("gpu "+i+": "+bb.getFloat(i));
+                Assert.assertEquals(verticiesBB.getFloat(i), bb.getFloat(i), 0.0);
             }
+            gl.glUnmapBuffer(GL.GL_ARRAY_BUFFER);
+            Assert.assertEquals("Buffer storage's bytes-buffer not null after unmap", null, bufferStorage.getMappedBuffer());
+        } finally {
+            NEWTGLContext.destroyWindow(winctx);
         }
-        for(int i=0; i < bb.capacity(); i+=4) {
-            Assert.assertEquals(verticiesBB.getFloat(i), bb.getFloat(i), 0.0);
-        }
-        gl.glUnmapBuffer(GL.GL_ARRAY_BUFFER);
-        NEWTGLContext.destroyWindow(winctx);
     }
     public static void main(String args[]) throws IOException {
         String tstname = TestMapBufferRead01NEWT.class.getName();
         org.junit.runner.JUnitCore.main(tstname);
-    }    
+    }
 }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT0.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT0.java
index a8c069f..010368b 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT0.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT0.java
@@ -100,13 +100,22 @@ public class TestSharedContextVBOES2NEWT0 extends UITestCase {
     }
 
     @Test
-    public void testCommonAnimatorShared() throws InterruptedException {
+    public void test01CommonAnimatorSharedCopyBuffer() throws InterruptedException {
+        testCommonAnimatorSharedImpl(false);
+    }
+    @Test
+    public void test02CommonAnimatorMapBuffer() throws InterruptedException {
+        testCommonAnimatorSharedImpl(true);
+    }
+    private void testCommonAnimatorSharedImpl(boolean useMappedBuffers) throws InterruptedException {
         final Animator animator = new Animator();
 
         //
         // 1st
         //
         final GearsES2 g1 = new GearsES2(0);
+        g1.setUseMappedBuffers(useMappedBuffers);
+        g1.setValidateBuffers(true);
         final GLWindow f1 = runTestGL(animator, 0, 0, g1, null);
         final GLContext ctx1 = f1.getContext();
         Assert.assertTrue("Ctx is shared before shared creation", !ctx1.isShared());
@@ -178,30 +187,30 @@ public class TestSharedContextVBOES2NEWT0 extends UITestCase {
         } catch(Exception e) {
             e.printStackTrace();
         }
-        animator.stop();
 
-        f1.destroy();
-        Assert.assertTrue(AWTRobotUtil.waitForVisible(f1, false));
-        Assert.assertTrue(AWTRobotUtil.waitForRealized(f1, false));
-        Assert.assertTrue(AWTRobotUtil.waitForContextCreated(f1, false));
+        f3.destroy();
+        Assert.assertTrue(AWTRobotUtil.waitForVisible(f3, false));
+        Assert.assertTrue(AWTRobotUtil.waitForRealized(f3, false));
+        Assert.assertTrue(AWTRobotUtil.waitForContextCreated(f3, false));
         {
             final List<GLContext> ctx1Shares = ctx1.getCreatedShares();
             final List<GLContext> ctx2Shares = ctx2.getCreatedShares();
             final List<GLContext> ctx3Shares = ctx3.getCreatedShares();
-            System.err.println("XXX-D-2.1:");
+            System.err.println("XXX-D-0.1:");
             MiscUtils.dumpSharedGLContext(ctx1);
-            System.err.println("XXX-D-2.2:");
+            System.err.println("XXX-D-0.2:");
             MiscUtils.dumpSharedGLContext(ctx2);
-            System.err.println("XXX-D-2.3:");
+            System.err.println("XXX-D-0.3:");
             MiscUtils.dumpSharedGLContext(ctx3);
 
-            Assert.assertTrue("Ctx1 is not shared", ctx1.isShared());
-            Assert.assertTrue("Ctx2 is not shared", ctx2.isShared());
-            Assert.assertTrue("Ctx3 is not shared", ctx3.isShared());
-            Assert.assertEquals("Ctx1 has unexpected number of created shares", 2, ctx1Shares.size());
+            Assert.assertTrue("Ctx1 is shared", ctx1.isShared());
+            Assert.assertTrue("Ctx2 is shared", ctx2.isShared());
+            Assert.assertTrue("Ctx3 is shared", ctx3.isShared());
+            Assert.assertEquals("Ctx1 has unexpected number of created shares", 1, ctx1Shares.size());
             Assert.assertEquals("Ctx2 has unexpected number of created shares", 1, ctx2Shares.size());
-            Assert.assertEquals("Ctx3 has unexpected number of created shares", 1, ctx3Shares.size());
+            Assert.assertEquals("Ctx3 has unexpected number of created shares", 2, ctx3Shares.size());
         }
+        try { Thread.sleep(durationPostDestroy); } catch(Exception e) { e.printStackTrace(); }
 
         f2.destroy();
         Assert.assertTrue(AWTRobotUtil.waitForVisible(f2, false));
@@ -221,36 +230,42 @@ public class TestSharedContextVBOES2NEWT0 extends UITestCase {
             Assert.assertTrue("Ctx1 is not shared", ctx1.isShared());
             Assert.assertTrue("Ctx2 is not shared", ctx2.isShared());
             Assert.assertTrue("Ctx3 is not shared", ctx3.isShared());
-            Assert.assertEquals("Ctx1 has unexpected number of created shares", 1, ctx1Shares.size());
+            Assert.assertEquals("Ctx1 has unexpected number of created shares", 0, ctx1Shares.size());
             Assert.assertEquals("Ctx2 has unexpected number of created shares", 1, ctx2Shares.size());
-            Assert.assertEquals("Ctx3 has unexpected number of created shares", 0, ctx3Shares.size());
+            Assert.assertEquals("Ctx3 has unexpected number of created shares", 1, ctx3Shares.size());
         }
+        try { Thread.sleep(durationPostDestroy); } catch(Exception e) { e.printStackTrace(); }
 
-        f3.destroy();
-        Assert.assertTrue(AWTRobotUtil.waitForVisible(f3, false));
-        Assert.assertTrue(AWTRobotUtil.waitForRealized(f3, false));
-        Assert.assertTrue(AWTRobotUtil.waitForContextCreated(f3, false));
+        f1.destroy();
+        Assert.assertTrue(AWTRobotUtil.waitForVisible(f1, false));
+        Assert.assertTrue(AWTRobotUtil.waitForRealized(f1, false));
+        Assert.assertTrue(AWTRobotUtil.waitForContextCreated(f1, false));
         {
             final List<GLContext> ctx1Shares = ctx1.getCreatedShares();
             final List<GLContext> ctx2Shares = ctx2.getCreatedShares();
             final List<GLContext> ctx3Shares = ctx3.getCreatedShares();
-            System.err.println("XXX-D-0.1:");
+            System.err.println("XXX-D-2.1:");
             MiscUtils.dumpSharedGLContext(ctx1);
-            System.err.println("XXX-D-0.2:");
+            System.err.println("XXX-D-2.2:");
             MiscUtils.dumpSharedGLContext(ctx2);
-            System.err.println("XXX-D-0.3:");
+            System.err.println("XXX-D-2.3:");
             MiscUtils.dumpSharedGLContext(ctx3);
 
-            Assert.assertTrue("Ctx1 is shared", !ctx1.isShared());
-            Assert.assertTrue("Ctx2 is shared", !ctx2.isShared());
-            Assert.assertTrue("Ctx3 is shared", !ctx3.isShared());
+            Assert.assertTrue("Ctx1 is not shared", !ctx1.isShared());
+            Assert.assertTrue("Ctx2 is not shared", !ctx2.isShared());
+            Assert.assertTrue("Ctx3 is not shared", !ctx3.isShared());
             Assert.assertEquals("Ctx1 has unexpected number of created shares", 0, ctx1Shares.size());
             Assert.assertEquals("Ctx2 has unexpected number of created shares", 0, ctx2Shares.size());
             Assert.assertEquals("Ctx3 has unexpected number of created shares", 0, ctx3Shares.size());
         }
+        try { Thread.sleep(durationPostDestroy); } catch(Exception e) { e.printStackTrace(); }
+
+        animator.stop();
+        Assert.assertEquals(false, animator.isAnimating());
     }
 
     static long duration = 1000; // ms
+    static long durationPostDestroy = 1000; // ms - ~60 frames post destroy
 
     public static void main(String args[]) {
         for(int i=0; i<args.length; i++) {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT3.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT3.java
index c94ae11..a8684ad 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT3.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT3.java
@@ -93,18 +93,28 @@ public class TestSharedContextVBOES2NEWT3 extends UITestCase {
     }
 
     @Test
-    public void test01SyncedOneAnimatorCleanDtorOrder() throws InterruptedException {
-        syncedOneAnimator(true);
+    public void test01SyncedOneAnimatorCleanDtorOrderCopyBuffer() throws InterruptedException {
+        syncedOneAnimator(true, false);
+    }
+    @Test
+    public void test02SyncedOneAnimatorCleanDtorOrderMapBuffer() throws InterruptedException {
+        syncedOneAnimator(true, true);
     }
 
     @Test
-    public void test02SyncedOneAnimatorDirtyDtorOrder() throws InterruptedException {
-        syncedOneAnimator(false);
+    public void test03SyncedOneAnimatorDirtyDtorOrderCopyBuffer() throws InterruptedException {
+        syncedOneAnimator(false, false);
+    }
+    @Test
+    public void test04SyncedOneAnimatorDirtyDtorOrderMapBuffer() throws InterruptedException {
+        syncedOneAnimator(false, true);
     }
 
-    public void syncedOneAnimator(boolean destroyCleanOrder) throws InterruptedException {
+    public void syncedOneAnimator(boolean destroyCleanOrder, boolean useMappedBuffers) throws InterruptedException {
         final Animator animator = new Animator();
         final GearsES2 g1 = new GearsES2(0);
+        g1.setUseMappedBuffers(useMappedBuffers);
+        g1.setValidateBuffers(true);
         final GLWindow f1 = createGLWindow(0, 0, g1);
         animator.add(f1);
         InsetsImmutable insets = f1.getInsets();
@@ -176,21 +186,29 @@ public class TestSharedContextVBOES2NEWT3 extends UITestCase {
         } catch(Exception e) {
             e.printStackTrace();
         }
-        // Stopped animator allows native windowing system 'repaint' event
-        // to trigger GLAD 'display'
-        animator.stop();
-        Assert.assertEquals(false, animator.isAnimating());
 
         if( destroyCleanOrder ) {
             System.err.println("XXX Destroy in clean order NOW");
             f3.destroy();
+            try { Thread.sleep(durationPostDestroy); } catch(Exception e) { e.printStackTrace(); }
             f2.destroy();
+            try { Thread.sleep(durationPostDestroy); } catch(Exception e) { e.printStackTrace(); }
             f1.destroy();
+            try { Thread.sleep(durationPostDestroy); } catch(Exception e) { e.printStackTrace(); }
         } else {
             System.err.println("XXX Destroy in creation order NOW - Driver Impl. Ma trigger driver Bug i.e. not postponing GL ctx destruction after releasing all refs.");
+            animator.pause();
             f1.destroy();
+            animator.resume();
+            try { Thread.sleep(durationPostDestroy); } catch(Exception e) { e.printStackTrace(); }
+
+            animator.pause();
             f2.destroy();
+            animator.resume();
+            try { Thread.sleep(durationPostDestroy); } catch(Exception e) { e.printStackTrace(); }
+
             f3.destroy();
+            try { Thread.sleep(durationPostDestroy); } catch(Exception e) { e.printStackTrace(); }
         }
         Assert.assertTrue(AWTRobotUtil.waitForVisible(f1, false));
         Assert.assertTrue(AWTRobotUtil.waitForRealized(f1, false));
@@ -198,21 +216,33 @@ public class TestSharedContextVBOES2NEWT3 extends UITestCase {
         Assert.assertTrue(AWTRobotUtil.waitForRealized(f2, false));
         Assert.assertTrue(AWTRobotUtil.waitForVisible(f3, false));
         Assert.assertTrue(AWTRobotUtil.waitForRealized(f3, false));
+
+        animator.stop();
     }
 
     @Test
-    public void test11ASyncEachAnimatorCleanDtorOrder() throws InterruptedException {
-        asyncEachAnimator(true);
+    public void test11ASyncEachAnimatorCleanDtorOrderCopyBuffer() throws InterruptedException {
+        asyncEachAnimator(true, false);
+    }
+    @Test
+    public void test12ASyncEachAnimatorCleanDtorOrderMapBuffer() throws InterruptedException {
+        asyncEachAnimator(true, true);
     }
 
     @Test
-    public void test12AsyncEachAnimatorDirtyDtorOrder() throws InterruptedException {
-        asyncEachAnimator(false);
+    public void test13AsyncEachAnimatorDirtyDtorOrderCopyBuffers() throws InterruptedException {
+        asyncEachAnimator(false, false);
+    }
+    @Test
+    public void test14AsyncEachAnimatorDirtyDtorOrderMapBuffers() throws InterruptedException {
+        asyncEachAnimator(false, true);
     }
 
-    public void asyncEachAnimator(boolean destroyCleanOrder) throws InterruptedException {
+    public void asyncEachAnimator(boolean destroyCleanOrder, boolean useMappedBuffers) throws InterruptedException {
         final Animator a1 = new Animator();
         final GearsES2 g1 = new GearsES2(0);
+        g1.setUseMappedBuffers(useMappedBuffers);
+        g1.setValidateBuffers(true);
         final GLWindow f1 = createGLWindow(0, 0, g1);
         a1.add(f1);
         a1.start();
@@ -290,25 +320,37 @@ public class TestSharedContextVBOES2NEWT3 extends UITestCase {
         } catch(Exception e) {
             e.printStackTrace();
         }
-        // Stopped animator allows native windowing system 'repaint' event
-        // to trigger GLAD 'display'
-        a1.stop();
-        Assert.assertEquals(false, a1.isAnimating());
-        a2.stop();
-        Assert.assertEquals(false, a2.isAnimating());
-        a3.stop();
-        Assert.assertEquals(false, a3.isAnimating());
 
         if( destroyCleanOrder ) {
             System.err.println("XXX Destroy in clean order NOW");
+            a3.stop();
             f3.destroy();
+            try { Thread.sleep(durationPostDestroy); } catch(Exception e) { e.printStackTrace(); }
+            a2.stop();
             f2.destroy();
+            try { Thread.sleep(durationPostDestroy); } catch(Exception e) { e.printStackTrace(); }
+            a1.stop();
             f1.destroy();
+            try { Thread.sleep(durationPostDestroy); } catch(Exception e) { e.printStackTrace(); }
         } else {
             System.err.println("XXX Destroy in creation order NOW - Driver Impl. May trigger driver Bug i.e. not postponing GL ctx destruction after releasing all refs.");
+            a1.stop();
+            a2.pause();
+            a3.pause();
             f1.destroy();
+            a2.resume();
+            a3.resume();
+            try { Thread.sleep(durationPostDestroy); } catch(Exception e) { e.printStackTrace(); }
+
+            a2.stop();
+            a3.pause();
             f2.destroy();
+            a3.resume();
+            try { Thread.sleep(durationPostDestroy); } catch(Exception e) { e.printStackTrace(); }
+
+            a3.stop();
             f3.destroy();
+            try { Thread.sleep(durationPostDestroy); } catch(Exception e) { e.printStackTrace(); }
         }
         Assert.assertTrue(AWTRobotUtil.waitForVisible(f1, false));
         Assert.assertTrue(AWTRobotUtil.waitForRealized(f1, false));
@@ -319,6 +361,7 @@ public class TestSharedContextVBOES2NEWT3 extends UITestCase {
     }
 
     static long duration = 1000; // ms
+    static long durationPostDestroy = 1000; // ms - ~60 frames post destroy
 
     public static void main(String args[]) {
         for(int i=0; i<args.length; i++) {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/anim/TestAWTCardLayoutAnimatorStartStopBug532.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/anim/TestAWTCardLayoutAnimatorStartStopBug532.java
index 7f861d8..3790a87 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/anim/TestAWTCardLayoutAnimatorStartStopBug532.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/anim/TestAWTCardLayoutAnimatorStartStopBug532.java
@@ -2,6 +2,7 @@ package com.jogamp.opengl.test.junit.jogl.acore.anim;
 
 import java.awt.BorderLayout;
 import java.awt.CardLayout;
+import java.awt.Component;
 import java.awt.Dimension;
 import java.awt.event.ItemEvent;
 import java.awt.event.ItemListener;
@@ -30,55 +31,60 @@ import com.jogamp.opengl.util.FPSAnimator;
 
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 public class TestAWTCardLayoutAnimatorStartStopBug532 extends UITestCase {
-    static final String LABEL = "Label"; 
+    static final String LABEL = "Label";
     static final String CANVAS = "GLCanvas";
-    
+
     public enum AnimatorControlBehavior {
         StartStop, PauseResume, Continue;
     }
-    
-    static long durationPerTest = 200*4; // ms    
+
+    static long durationPerTest = 200*4; // ms
     static boolean manual = false;
     static volatile boolean shouldStop = false;
-    
+
     private String selected = LABEL;
-    
+
     @Test
     public void testFPSAnimatorStartStop() throws InterruptedException, InvocationTargetException {
         testImpl(AnimatorControlBehavior.StartStop, true);
     }
-    
+
     @Test
     public void testFPSAnimatorResumePause() throws InterruptedException, InvocationTargetException {
         testImpl(AnimatorControlBehavior.PauseResume, true);
     }
-    
+
     @Test
     public void testFPSAnimatorContinue() throws InterruptedException, InvocationTargetException {
         testImpl(AnimatorControlBehavior.Continue, true);
     }
-    
+
     @Test
     public void testAnimatorStartStop() throws InterruptedException, InvocationTargetException {
         testImpl(AnimatorControlBehavior.StartStop, false);
     }
-    
+
     @Test
     public void testAnimatorResumePause() throws InterruptedException, InvocationTargetException {
         testImpl(AnimatorControlBehavior.PauseResume, false);
     }
-    
+
     @Test
     public void testAnimatorContinue() throws InterruptedException, InvocationTargetException {
         testImpl(AnimatorControlBehavior.Continue, false);
     }
-    
+
+    private static String id(Object obj) { return "0x" + ( null!=obj ? Integer.toHexString(obj.hashCode()) : "nil" ); }
+    private static String str(Component c) {
+        return id(c)+": "+c.getClass().getSimpleName()+"[visible "+c.isVisible()+", showing "+c.isShowing()+", valid "+c.isValid()+
+                ", displayable "+c.isDisplayable()+", "+c.getX()+"/"+c.getY()+" "+c.getWidth()+"x"+c.getHeight()+"]";
+    }
     void testImpl(final AnimatorControlBehavior animCtrl, boolean useFPSAnimator) throws InterruptedException, InvocationTargetException {
-      final GLProfile glp = GLProfile.get(GLProfile.GL2); 
-      final GLCapabilities caps = new GLCapabilities(glp); 
-      final GLCanvas canvas = new GLCanvas(caps); 
+      final GLProfile glp = GLProfile.get(GLProfile.GL2);
+      final GLCapabilities caps = new GLCapabilities(glp);
+      final GLCanvas canvas = new GLCanvas(caps);
       canvas.setPreferredSize(new Dimension(640, 480));
-      
+
       final GLAnimatorControl animatorCtrl = useFPSAnimator ? new FPSAnimator(canvas, 60) : new Animator(canvas);
       animatorCtrl.setUpdateFPSFrames(60, null);// System.err);
       switch (animCtrl) {
@@ -95,7 +101,7 @@ public class TestAWTCardLayoutAnimatorStartStopBug532 extends UITestCase {
       canvas.addGLEventListener(new GearsES2(1));
       /* if(Platform.OS_TYPE == Platform.OSType.WINDOWS) {
           canvas.addGLEventListener(new GLEventListener() {
-            public void init(GLAutoDrawable drawable) { } 
+            public void init(GLAutoDrawable drawable) { }
             public void dispose(GLAutoDrawable drawable) { }
             public void display(GLAutoDrawable drawable) {
                 final NativeWindow win = (NativeWindow) drawable.getNativeSurface();
@@ -112,15 +118,17 @@ public class TestAWTCardLayoutAnimatorStartStopBug532 extends UITestCase {
 
       final JFrame frame = new JFrame();
       frame.setTitle(getSimpleTestName(" - "));
-      frame.addWindowListener(new WindowAdapter() { 
+      frame.addWindowListener(new WindowAdapter() {
          public void windowClosing(WindowEvent e) {
             animatorCtrl.stop();
             shouldStop = true;
-         } 
+         }
       });
       frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
-      
-      final JPanel cards = new JPanel(new CardLayout());      
+
+      final JLabel label = new JLabel("A label to cover the canvas");
+
+      final JPanel cards = new JPanel(new CardLayout());
       final JPanel comboBoxPanel = new JPanel(); // nicer look ..
       final JComboBox comboBox = new JComboBox(new String[] { LABEL, CANVAS });
       comboBox.setEditable(false);
@@ -131,7 +139,13 @@ public class TestAWTCardLayoutAnimatorStartStopBug532 extends UITestCase {
             if(!newSelection.equals(selected)) {
                 final String oldSelected = selected;
                 if(newSelection.equals(CANVAS)) {
-                    cl.show(cards, CANVAS); 
+                    System.err.println("XXX Card.SHOW Canvas PRE: ");
+                    System.err.println("   CANVAS "+str(canvas));
+                    System.err.println("   LABEL  "+str(label));
+                    cl.show(cards, CANVAS);
+                    System.err.println("XXX Card.SHOW Canvas POST: ");
+                    System.err.println("   CANVAS "+str(canvas));
+                    System.err.println("   LABEL  "+str(label));
                     switch (animCtrl) {
                        case StartStop:
                            animatorCtrl.start();
@@ -152,31 +166,37 @@ public class TestAWTCardLayoutAnimatorStartStopBug532 extends UITestCase {
                            break;
                        default:
                     }
-                    cl.show(cards, LABEL); 
+                    System.err.println("XXX Card.SHOW Label PRE: ");
+                    System.err.println("   CANVAS "+str(canvas));
+                    System.err.println("   LABEL  "+str(label));
+                    cl.show(cards, LABEL);
+                    System.err.println("XXX Card.SHOW Label POST: ");
+                    System.err.println("   CANVAS "+str(canvas));
+                    System.err.println("   LABEL  "+str(label));
                     selected = LABEL;
                 } else {
                     throw new RuntimeException("oops .. unexpected item: "+evt);
                 }
-                System.err.println("Item Change: "+oldSelected+" -> "+selected+", "+animatorCtrl);                
+                System.err.println("Item Change: "+oldSelected+" -> "+selected+", "+animatorCtrl);
             } else {
                 System.err.println("Item Stays: "+selected+", "+animatorCtrl);
             }
         }
       });
-      comboBoxPanel.add(comboBox);            
+      comboBoxPanel.add(comboBox);
 
-      cards.add(new JLabel("A label to cover the canvas"), LABEL); 
+      cards.add(label, LABEL);
       cards.add(canvas, CANVAS);
-      
+
       frame.add(comboBoxPanel, BorderLayout.PAGE_START);
       frame.add(cards, BorderLayout.CENTER);
-            
+
       javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
         public void run() {
-            frame.pack(); 
+            frame.pack();
             frame.setVisible(true);
         }});
-    
+
       if(manual) {
           for(long w=durationPerTest; !shouldStop && w>0; w-=100) {
               Thread.sleep(100);
@@ -187,34 +207,34 @@ public class TestAWTCardLayoutAnimatorStartStopBug532 extends UITestCase {
                 comboBox.setSelectedItem(LABEL);
             }});
           Thread.sleep(durationPerTest/4);
-          
+
           javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
             public void run() {
                 comboBox.setSelectedItem(CANVAS);
             }});
           Thread.sleep(durationPerTest/4);
-          
+
           javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
             public void run() {
                 comboBox.setSelectedItem(LABEL);
             }});
           Thread.sleep(durationPerTest/4);
-          
+
           javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
             public void run() {
                 comboBox.setSelectedItem(CANVAS);
             }});
           Thread.sleep(durationPerTest/4);
       }
-      
+
       javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
         public void run() {
             frame.setVisible(false);
             frame.dispose();
         }});
-      
+
     }
-    
+
     public static void main(String args[]) {
         for(int i=0; i<args.length; i++) {
             if(args[i].equals("-time")) {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug664GLCanvasSetVisibleSwingAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug664GLCanvasSetVisibleSwingAWT.java
index 91da73e..2a0bbfe 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug664GLCanvasSetVisibleSwingAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug664GLCanvasSetVisibleSwingAWT.java
@@ -3,14 +3,14 @@
  *
  * 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 JogAmp Community ``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 JogAmp Community OR
@@ -20,12 +20,12 @@
  * 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.
- * 
+ *
  * The views and conclusions contained in the software and documentation are those of the
  * authors and should not be interpreted as representing official policies, either expressed
  * or implied, of JogAmp Community.
  */
- 
+
 package com.jogamp.opengl.test.junit.jogl.awt;
 
 import java.awt.AWTException;
@@ -83,9 +83,9 @@ public class TestBug664GLCanvasSetVisibleSwingAWT extends UITestCase {
     @AfterClass
     public static void releaseClass() {
     }
-    
-    protected JPanel create(final JFrame[] top, final int width, final int height, final int num) 
-            throws InterruptedException, InvocationTargetException 
+
+    protected JPanel create(final JFrame[] top, final int width, final int height, final int num)
+            throws InterruptedException, InvocationTargetException
     {
         final JPanel[] jPanel = new JPanel[] { null };
         SwingUtilities.invokeAndWait(new Runnable() {
@@ -98,55 +98,55 @@ public class TestBug664GLCanvasSetVisibleSwingAWT extends UITestCase {
                     jFrame1.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); // equivalent to Frame, use windowClosing event!
                     jFrame1.getContentPane().add(jPanel[0]);
                     jFrame1.setSize(width, height);
-                    
+
                     top[0] = jFrame1;
                 } } );
-        return jPanel[0];        
+        return jPanel[0];
     }
 
-    protected void add(final Container cont, final Component comp, final JFrame jFrame) 
-            throws InterruptedException, InvocationTargetException 
+    protected void add(final Container cont, final Component comp, final JFrame jFrame)
+            throws InterruptedException, InvocationTargetException
     {
         SwingUtilities.invokeAndWait(new Runnable() {
                 public void run() {
-                    cont.add(comp, BorderLayout.CENTER);                    
+                    cont.add(comp, BorderLayout.CENTER);
                     jFrame.pack();
                     jFrame.validate();
                 } } );
     }
-    
-    protected void dispose(final GLCanvas glc) 
-            throws InterruptedException, InvocationTargetException 
+
+    protected void dispose(final GLCanvas glc)
+            throws InterruptedException, InvocationTargetException
     {
         SwingUtilities.invokeAndWait(new Runnable() {
                 public void run() {
-                    glc.destroy();                    
+                    glc.destroy();
                 } } );
     }
-    
+
     protected void setFrameVisible(final JFrame jFrame, final boolean visible) throws InterruptedException, InvocationTargetException {
         SwingUtilities.invokeAndWait(new Runnable() {
                 public void run() {
                     jFrame.setVisible(visible);
-                } } ) ;        
+                } } ) ;
     }
-    
+
     protected void setComponentVisible(final Component comp, final boolean visible) throws InterruptedException, InvocationTargetException {
         SwingUtilities.invokeAndWait(new Runnable() {
                 public void run() {
                     comp.setVisible(visible);
-                } } ) ;        
+                } } ) ;
     }
-    
+
     protected void dispose(final JFrame jFrame) throws InterruptedException, InvocationTargetException {
         SwingUtilities.invokeAndWait(new Runnable() {
                 public void run() {
                     jFrame.dispose();
-                } } ) ;        
+                } } ) ;
     }
-    
+
     private volatile int frameCount = 0;
-    
+
     protected void runTestGL(boolean onscreen, GLCapabilities caps)
             throws AWTException, InterruptedException, InvocationTargetException
     {
@@ -178,52 +178,52 @@ public class TestBug664GLCanvasSetVisibleSwingAWT extends UITestCase {
             final GearsES2 gears = new GearsES2(1);
             gears.setVerbose(false);
             glc.addGLEventListener(gears);
-            
+
             final JFrame[] top = new JFrame[] { null };
             final Container glcCont = create(top, width, height, i);
             add(glcCont, glc, top[0]);
-            
+
+            System.err.println("XXXX Visible Part 1/3");
             frameCount = 0;
             setFrameVisible(top[0], true);
             Assert.assertTrue("Component didn't become visible", AWTRobotUtil.waitForVisible(glc, true));
             Assert.assertTrue("Component didn't become realized", AWTRobotUtil.waitForRealized(glc, true));
-                        
-            anim.setUpdateFPSFrames(60, null);
+
+            anim.setUpdateFPSFrames(60, System.err);
             anim.start();
             anim.resetFPSCounter();
-            System.err.println("Visible Part 1/3");
-            
+
             while( anim.getTotalFPSDuration() < durationPerTest ) {
                 Thread.sleep(60);
-            }            
-            
+            }
+
+            System.err.println("XXXXX Invisible Part 2/3");
             setComponentVisible(glc, false);
-            Assert.assertTrue("Component didn't become invisible", AWTRobotUtil.waitForVisible(glc, false));            
+            Assert.assertTrue("Component didn't become invisible", AWTRobotUtil.waitForVisible(glc, false));
             final int frameCountT0 = frameCount;
             anim.resetFPSCounter();
-            System.err.println("Invisible Part 2/3");
-            
+
             while( anim.getTotalFPSDuration() < durationPerTest ) {
                 Thread.sleep(60);
             }
-            
-            final int frameCountT1 = frameCount;            
+
+            final int frameCountT1 = frameCount;
             System.err.println("GLCanvas invisible frame count: Before "+frameCountT0+", after "+frameCountT1);
-            Assert.assertTrue("GLCanvas rendered more that 4 times while being invisible, before "+frameCountT0+", after "+frameCountT1, 
+            Assert.assertTrue("GLCanvas rendered more that 4 times while being invisible, before "+frameCountT0+", after "+frameCountT1,
                     4 >= frameCountT1 - frameCountT0);
-            
+
+            System.err.println("XXXX Visible Part 3/3");
             setComponentVisible(glc, true);
             Assert.assertTrue("Component didn't become visible", AWTRobotUtil.waitForVisible(glc, true));
             anim.resetFPSCounter();
-            System.err.println("Visible Part 3/3");
-            
+
             while( anim.getTotalFPSDuration() < durationPerTest ) {
                 Thread.sleep(60);
             }
-                        
+
             System.err.println("GLCanvas isOffscreenLayerSurfaceEnabled: "+glc.isOffscreenLayerSurfaceEnabled()+": "+glc.getChosenGLCapabilities());
-            
-            dispose(top[0]);            
+
+            dispose(top[0]);
         }
     }
 
@@ -258,7 +258,7 @@ public class TestBug664GLCanvasSetVisibleSwingAWT extends UITestCase {
         }
         runTestGL(false, caps);
     }
-    
+
     public static void main(String args[]) throws IOException {
         for(int i=0; i<args.length; i++) {
             if(args[i].equals("-time")) {
@@ -272,10 +272,10 @@ public class TestBug664GLCanvasSetVisibleSwingAWT extends UITestCase {
                 shallUseOffscreenPBufferLayer = true;
             } else if(args[i].equals("-wait")) {
                 waitForKey = true;
-            }            
+            }
         }
         System.err.println("waitForKey                    "+waitForKey);
-        
+
         System.err.println("shallUseOffscreenFBOLayer     "+shallUseOffscreenFBOLayer);
         System.err.println("shallUseOffscreenPBufferLayer "+shallUseOffscreenPBufferLayer);
         if(waitForKey) {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug816JTabbedPanelVisibilityB849B878AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug816JTabbedPanelVisibilityB849B878AWT.java
index f28a034..84af232 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug816JTabbedPanelVisibilityB849B878AWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug816JTabbedPanelVisibilityB849B878AWT.java
@@ -34,6 +34,7 @@ import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLProfile;
 import javax.media.opengl.awt.GLCanvas;
 import javax.swing.JFrame;
+import javax.swing.JLabel;
 import javax.swing.JPanel;
 import javax.swing.JTabbedPane;
 import javax.swing.SwingUtilities;
@@ -63,7 +64,7 @@ import com.jogamp.opengl.test.junit.util.UITestCase;
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 public class TestBug816JTabbedPanelVisibilityB849B878AWT extends UITestCase {
 
-    static long durationPerTest = 500*4; // ms
+    static long durationPerTest = 500*6; // ms
     static boolean manual = false;
 
     @Test
@@ -72,6 +73,7 @@ public class TestBug816JTabbedPanelVisibilityB849B878AWT extends UITestCase {
 
         final JPanel panel1 = new javax.swing.JPanel();
         final JPanel panel2 = new javax.swing.JPanel();
+        final JPanel panel3 = new javax.swing.JPanel();
 
         panel1.setLayout(new BorderLayout());
         panel2.setLayout(new BorderLayout());
@@ -82,23 +84,29 @@ public class TestBug816JTabbedPanelVisibilityB849B878AWT extends UITestCase {
         glCanvas.setSize(new java.awt.Dimension(640, 480));
         glCanvas.addGLEventListener(new GearsES2(1));
         panel1.add(glCanvas, BorderLayout.CENTER);
+        panel3.add(new JLabel("A label to cover the canvas"), BorderLayout.CENTER);
 
         final JTabbedPane tabbedPanel = new JTabbedPane();
-        tabbedPanel.addTab("tab1", panel1);
-        tabbedPanel.addTab("tab2", panel2);
+        tabbedPanel.addTab("tab1", panel1); // glcanvas
+        tabbedPanel.addTab("tab2", panel2); // glcanvas
+        tabbedPanel.addTab("tab3", panel3); // text
 
         tabbedPanel.addChangeListener(new javax.swing.event.ChangeListener() {
             @Override
             public void stateChanged(javax.swing.event.ChangeEvent evt) {
                 if (tabbedPanel.getSelectedIndex() == 0) {
+                    System.err.println("XXXX Add GLCanvas Panel2("+id(panel2)+" -> Panel1("+id(panel1)+") START");
                     dumpGLCanvasStats(glCanvas);
                     panel1.add(glCanvas, BorderLayout.CENTER);
                     dumpGLCanvasStats(glCanvas);
-                } else {
+                } else if (tabbedPanel.getSelectedIndex() == 1) {
                     System.err.println("XXXX Add GLCanvas Panel1("+id(panel1)+" -> Panel2("+id(panel2)+") START");
                     dumpGLCanvasStats(glCanvas);
                     panel2.add(glCanvas, BorderLayout.CENTER);
                     dumpGLCanvasStats(glCanvas);
+                } else {
+                    System.err.println("XXXX NOP");
+                    dumpGLCanvasStats(glCanvas);
                 }
             }
         });
@@ -119,33 +127,44 @@ public class TestBug816JTabbedPanelVisibilityB849B878AWT extends UITestCase {
                 Thread.sleep(100);
             }
         } else {
+            Thread.sleep(durationPerTest/6);
             javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
                 public void run() {
-                    System.err.println("XXXX Add GLCanvas Panel2("+id(panel2)+") -> Panel1("+id(panel1)+" START");
-                    tabbedPanel.setSelectedIndex(0);
+                    System.err.println("XXXX Panel1("+id(panel1)+" -> Panel2("+id(panel2)+") START");
+                    tabbedPanel.setSelectedIndex(1);
                 }});
-            Thread.sleep(durationPerTest/4);
 
+            Thread.sleep(durationPerTest/6);
             javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
                 public void run() {
-                    System.err.println("XXXX Add GLCanvas Panel1("+id(panel1)+" -> Panel2("+id(panel2)+") START");
-                    tabbedPanel.setSelectedIndex(1);
+                    System.err.println("XXXX Panel2("+id(panel2)+") -> Panel3("+id(panel3)+" START");
+                    tabbedPanel.setSelectedIndex(2);
                 }});
-            Thread.sleep(durationPerTest/4);
 
+            Thread.sleep(durationPerTest/6);
             javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
                 public void run() {
-                    System.err.println("XXXX Add GLCanvas Panel2("+id(panel2)+") -> Panel1("+id(panel1)+" START");
+                    System.err.println("XXXX Panel3("+id(panel3)+") -> Panel1("+id(panel1)+" START");
                     tabbedPanel.setSelectedIndex(0);
                 }});
-            Thread.sleep(durationPerTest/4);
 
+            // one loop done
+
+            Thread.sleep(durationPerTest/6);
             javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
                 public void run() {
-                    System.err.println("XXXX Add GLCanvas Panel1("+id(panel1)+" -> Panel2("+id(panel2)+") START");
+                    System.err.println("XXXX Panel1("+id(panel1)+" -> Panel2("+id(panel2)+") START");
                     tabbedPanel.setSelectedIndex(1);
                 }});
-            Thread.sleep(durationPerTest/4);
+
+            Thread.sleep(durationPerTest/6);
+            javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+                public void run() {
+                    System.err.println("XXXX Panel2("+id(panel2)+") -> Panel1("+id(panel1)+" START");
+                    tabbedPanel.setSelectedIndex(0);
+                }});
+
+            Thread.sleep(durationPerTest/6);
         }
 
         SwingUtilities.invokeLater(new Runnable() {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug816OSXCALayerPos01AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug816OSXCALayerPos01AWT.java
index 5a7c5c9..ace578e 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug816OSXCALayerPos01AWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug816OSXCALayerPos01AWT.java
@@ -63,8 +63,6 @@ import java.lang.reflect.InvocationTargetException;
 
 import org.junit.Assert;
 import org.junit.Assume;
-import org.junit.BeforeClass;
-import org.junit.AfterClass;
 import org.junit.Test;
 import org.junit.FixMethodOrder;
 import org.junit.runners.MethodSorters;
@@ -80,23 +78,12 @@ public class TestBug816OSXCALayerPos01AWT extends UITestCase {
     public enum FrameLayout { None, Flow, DoubleBorderCenterSurrounded, Box, Split };
 
     static long duration = 1600; // ms
-    static int width, height;
+    static final int width = 640, height = 480;
 
     static boolean forceES2 = false;
     static boolean forceGL3 = false;
     static int swapInterval = 1;
-    static java.awt.Dimension rwsize;
-
-    @BeforeClass
-    public static void initClass() {
-        width  = 640;
-        height = 480;
-        rwsize = new Dimension(800, 600);
-    }
-
-    @AfterClass
-    public static void releaseClass() {
-    }
+    static java.awt.Dimension rwsize = new Dimension(800, 600);
 
     static void setComponentSize(final Frame frame, final Component comp1, final java.awt.Dimension new_sz1, final Component comp2, final java.awt.Dimension new_sz2) {
         try {
@@ -278,16 +265,18 @@ public class TestBug816OSXCALayerPos01AWT extends UITestCase {
         }
 
         Thread.sleep(Math.max(1000, duration/2));
-        final Dimension compRSizeHalf = new Dimension(rwsize.width/2, rwsize.height);
-        final Dimension frameRSizeHalf = new Dimension(twoCanvas ? rwsize.width + 64: rwsize.width/2 + 64, rwsize.height + 64);
-        if( resizeByComp ) {
-           setComponentSize(frame, glCanvas1, compRSizeHalf, glCanvas2, compRSizeHalf);
-        } else {
-           setFrameSize(frame, true, frameRSizeHalf);
-        }
-        System.err.println("resize canvas1 pos/siz: "+glCanvas1.getX()+"/"+glCanvas1.getY()+" "+glCanvas1.getWidth()+"x"+glCanvas1.getHeight());
-        if( twoCanvas ) {
-            System.err.println("resize canvas2 pos/siz: "+glCanvas2.getX()+"/"+glCanvas2.getY()+" "+glCanvas2.getWidth()+"x"+glCanvas2.getHeight());
+        if( null != rwsize ) {
+            final Dimension compRSizeHalf = new Dimension(rwsize.width/2, rwsize.height);
+            final Dimension frameRSizeHalf = new Dimension(twoCanvas ? rwsize.width + 64: rwsize.width/2 + 64, rwsize.height + 64);
+            if( resizeByComp ) {
+               setComponentSize(frame, glCanvas1, compRSizeHalf, glCanvas2, compRSizeHalf);
+            } else {
+               setFrameSize(frame, true, frameRSizeHalf);
+            }
+            System.err.println("resize canvas1 pos/siz: "+glCanvas1.getX()+"/"+glCanvas1.getY()+" "+glCanvas1.getWidth()+"x"+glCanvas1.getHeight());
+            if( twoCanvas ) {
+                System.err.println("resize canvas2 pos/siz: "+glCanvas2.getX()+"/"+glCanvas2.getY()+" "+glCanvas2.getWidth()+"x"+glCanvas2.getHeight());
+            }
         }
 
         final long t0 = System.currentTimeMillis();
@@ -465,6 +454,8 @@ public class TestBug816OSXCALayerPos01AWT extends UITestCase {
             } else if(args[i].equals("-test")) {
                 i++;
                 testNum = MiscUtils.atoi(args[i], 0);
+            } else if(args[i].equals("-noresize")) {
+                rwsize = null;
             } else if(args[i].equals("-es2")) {
                 forceES2 = true;
             } else if(args[i].equals("-gl3")) {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug816OSXCALayerPos03aB729AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug816OSXCALayerPos03aB729AWT.java
index e1a0944..29dc9a1 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug816OSXCALayerPos03aB729AWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug816OSXCALayerPos03aB729AWT.java
@@ -95,8 +95,10 @@ public class TestBug816OSXCALayerPos03aB729AWT extends UITestCase {
         final Checkbox checkbox = new Checkbox("Visible canvas", true);
         checkbox.addItemListener(new ItemListener() {
             public void itemStateChanged(ItemEvent ev) {
-                glCanvas1.setVisible(checkbox.getState());
-                System.out.println("Canvas visible: "+glCanvas1.isVisible());
+                final boolean visible = checkbox.getState();
+                System.err.println("XXXX Canvas setVisible "+visible);
+                glCanvas1.setVisible(visible);
+                System.err.println("XXXX Canvas visible: "+glCanvas1.isVisible());
                 if( glCanvas1.isVisible() ) {
                     frame.validate(); // take care of resized frame while hidden
                 }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug816OSXCALayerPos03bB849AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug816OSXCALayerPos03bB849AWT.java
index b9ee6a4..3e60c8b 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug816OSXCALayerPos03bB849AWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug816OSXCALayerPos03bB849AWT.java
@@ -101,8 +101,10 @@ public class TestBug816OSXCALayerPos03bB849AWT extends UITestCase {
         final Checkbox checkbox = new Checkbox("Visible canvas", true);
         checkbox.addItemListener(new ItemListener() {
             public void itemStateChanged(ItemEvent ev) {
-                panel.setVisible(checkbox.getState());
-                System.out.println("Visible: [panel "+panel.isVisible()+", canvas "+glCanvas1.isVisible()+"]; Displayable: [panel "+panel.isDisplayable()+", canvas "+glCanvas1.isDisplayable()+"]");
+                final boolean visible = checkbox.getState();
+                System.err.println("XXXX Panel setVisible "+visible);
+                panel.setVisible(visible);
+                System.err.println("XXXX Visible: [panel "+panel.isVisible()+", canvas "+glCanvas1.isVisible()+"]; Displayable: [panel "+panel.isDisplayable()+", canvas "+glCanvas1.isDisplayable()+"]");
                 if( panel.isVisible() ) {
                     frame.validate(); // take care of resized frame while hidden
                 }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug816OSXCALayerPos03cB849AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug816OSXCALayerPos03cB849AWT.java
index 9a536d5..24f9de9 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug816OSXCALayerPos03cB849AWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug816OSXCALayerPos03cB849AWT.java
@@ -103,8 +103,10 @@ public class TestBug816OSXCALayerPos03cB849AWT extends UITestCase {
         final JCheckBox checkbox = new JCheckBox("Visible canvas", true);
         checkbox.addItemListener(new ItemListener() {
             public void itemStateChanged(ItemEvent ev) {
-                panel.setVisible(checkbox.getSelectedObjects()!=null);
-                System.out.println("Visible: [panel "+panel.isVisible()+", canvas "+glCanvas1.isVisible()+"]; Displayable: [panel "+panel.isDisplayable()+", canvas "+glCanvas1.isDisplayable()+"]");
+                final boolean visible = checkbox.getSelectedObjects()!=null;
+                System.err.println("XXXX Panel setVisible "+visible);
+                panel.setVisible(visible);
+                System.err.println("XXXX Visible: [panel "+panel.isVisible()+", canvas "+glCanvas1.isVisible()+"]; Displayable: [panel "+panel.isDisplayable()+", canvas "+glCanvas1.isDisplayable()+"]");
                 if( panel.isVisible() ) {
                     frame.validate(); // take care of resized frame while hidden
                 }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/GearsObject.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/GearsObject.java
index 9526df2..00d360f 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/GearsObject.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/GearsObject.java
@@ -45,8 +45,9 @@ public abstract class GearsObject {
     public GLArrayDataServer outwardFace;
     public GLArrayDataServer insideRadiusCyl;
     public boolean isShared;
+    protected boolean validateBuffers = false;
 
-    public abstract GLArrayDataServer createInterleaved(int comps, int dataType, boolean normalized, int initialSize, int vboUsage);
+    public abstract GLArrayDataServer createInterleaved(boolean useMappedBuffers, int comps, int dataType, boolean normalized, int initialSize, int vboUsage);
     public abstract void addInterleavedVertexAndNormalArrays(GLArrayDataServer array, int components);
     public abstract void draw(GL gl, float x, float y, float angle);
 
@@ -61,16 +62,6 @@ public abstract class GearsObject {
         array.enableBuffer(gl, false);
     }
 
-    /** Init VBO and data .. */
-    public final void init(GL gl) {
-        init(gl, frontFace);
-        init(gl, frontSide);
-        init(gl, backFace);
-        init(gl, backSide);
-        init(gl, outwardFace);
-        init(gl, insideRadiusCyl);
-    }
-
     public void destroy(GL gl) {
         if(!isShared) {
             // could be already destroyed by shared configuration
@@ -104,6 +95,7 @@ public abstract class GearsObject {
 
     public GearsObject ( GearsObject shared ) {
         isShared = true;
+        validateBuffers = shared.validateBuffers;
         frontFace = createInterleavedClone(shared.frontFace);
         addInterleavedVertexAndNormalArrays(frontFace, 3);
         backFace = createInterleavedClone(shared.backFace);
@@ -120,12 +112,12 @@ public abstract class GearsObject {
     }
 
     public GearsObject (
+            GL gl,
+            boolean useMappedBuffers,
             FloatBuffer gearColor,
             float inner_radius,
             float outer_radius,
-            float width,
-            int teeth,
-            float tooth_depth)
+            float width, int teeth, float tooth_depth, boolean validateBuffers)
     {
         final float dz = width * 0.5f;
         int i;
@@ -137,6 +129,7 @@ public abstract class GearsObject {
         float normal[] = new float[3];
         // final int tris_per_tooth = 32;
 
+        this.validateBuffers = validateBuffers;
         this.isShared = false;
         this.gearColor = gearColor;
 
@@ -151,19 +144,28 @@ public abstract class GearsObject {
 
         final int vboUsage = GL.GL_STATIC_DRAW;
 
-        frontFace = createInterleaved(6, GL.GL_FLOAT, false, 4*teeth+2, vboUsage);
+        frontFace = createInterleaved(useMappedBuffers, 6, GL.GL_FLOAT, false, 4*teeth+2, vboUsage);
         addInterleavedVertexAndNormalArrays(frontFace, 3);
-        backFace = createInterleaved(6, GL.GL_FLOAT, false, 4*teeth+2, vboUsage);
+        backFace = createInterleaved(useMappedBuffers, 6, GL.GL_FLOAT, false, 4*teeth+2, vboUsage);
         addInterleavedVertexAndNormalArrays(backFace, 3);
-        frontSide = createInterleaved(6, GL.GL_FLOAT, false, 6*teeth, vboUsage);
+        frontSide = createInterleaved(useMappedBuffers, 6, GL.GL_FLOAT, false, 6*teeth, vboUsage);
         addInterleavedVertexAndNormalArrays(frontSide, 3);
-        backSide = createInterleaved(6, GL.GL_FLOAT, false, 6*teeth, vboUsage);
+        backSide = createInterleaved(useMappedBuffers, 6, GL.GL_FLOAT, false, 6*teeth, vboUsage);
         addInterleavedVertexAndNormalArrays(backSide, 3);
-        outwardFace = createInterleaved(6, GL.GL_FLOAT, false, 4*4*teeth+2, vboUsage);
+        outwardFace = createInterleaved(useMappedBuffers, 6, GL.GL_FLOAT, false, 4*4*teeth+2, vboUsage);
         addInterleavedVertexAndNormalArrays(outwardFace, 3);
-        insideRadiusCyl = createInterleaved(6, GL.GL_FLOAT, false, 2*teeth+2, vboUsage);
+        insideRadiusCyl = createInterleaved(useMappedBuffers, 6, GL.GL_FLOAT, false, 2*teeth+2, vboUsage);
         addInterleavedVertexAndNormalArrays(insideRadiusCyl, 3);
 
+        if( useMappedBuffers ) {
+            frontFace.mapStorage(gl, GL.GL_WRITE_ONLY);
+            backFace.mapStorage(gl, GL.GL_WRITE_ONLY);
+            frontSide.mapStorage(gl, GL.GL_WRITE_ONLY);
+            backSide.mapStorage(gl, GL.GL_WRITE_ONLY);
+            outwardFace.mapStorage(gl, GL.GL_WRITE_ONLY);
+            insideRadiusCyl.mapStorage(gl, GL.GL_WRITE_ONLY);
+        }
+
         for (i = 0; i < teeth; i++) {
             angle = i * 2.0f * M_PI / teeth;
             sincos(angle + da * 0f, s, 0, c, 0);
@@ -290,6 +292,23 @@ public abstract class GearsObject {
         vert(insideRadiusCyl, r0 * c[4], r0 * s[4], -dz, normal);
         vert(insideRadiusCyl, r0 * c[4], r0 * s[4],  dz, normal);
         insideRadiusCyl.seal(true);
+
+        if( useMappedBuffers ) {
+            frontFace.unmapStorage(gl);
+            backFace.unmapStorage(gl);
+            frontSide.unmapStorage(gl);
+            backSide.unmapStorage(gl);
+            outwardFace.unmapStorage(gl);
+            insideRadiusCyl.unmapStorage(gl);
+        } else {
+            /** Init VBO and data .. */
+            init(gl, frontFace);
+            init(gl, frontSide);
+            init(gl, backFace);
+            init(gl, backSide);
+            init(gl, outwardFace);
+            init(gl, insideRadiusCyl);
+        }
     }
 
     @Override
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/TextureSequenceDemo01.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/TextureSequenceDemo01.java
index 38d4d8b..b015aeb 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/TextureSequenceDemo01.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/TextureSequenceDemo01.java
@@ -27,7 +27,7 @@ public class TextureSequenceDemo01 implements TextureSequence {
         if(null == frame) {
             TextureData texData = null;
             try {
-                URLConnection urlConn = IOUtil.getResource("jogl/util/data/av/test-ntsc01-160x90.png", this.getClass().getClassLoader());
+                URLConnection urlConn = IOUtil.getResource("jogl/util/data/av/test-ntsc01-57x32.png", this.getClass().getClassLoader());
                 if(null != urlConn) {
                     texData = TextureIO.newTextureData(GLProfile.getGL2ES2(), urlConn.getInputStream(), false, TextureIO.PNG);
                 }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/GearsES1.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/GearsES1.java
index 9f191d3..f4c5e8b 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/GearsES1.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/GearsES1.java
@@ -63,6 +63,8 @@ public class GearsES1 implements GLEventListener {
   private GearsObject gear1=null, gear2=null, gear3=null;
   private FloatBuffer gear1Color=GearsObject.red, gear2Color=GearsObject.green, gear3Color=GearsObject.blue;
   private volatile boolean usesSharedGears = false;
+  private boolean useMappedBuffers = false;
+  private boolean validateBuffers = false;
   private float angle = 0.0f;
   private final int swapInterval;
   private final MouseListener gearsMouse = new GearsMouseAdapter();
@@ -115,6 +117,9 @@ public class GearsES1 implements GLEventListener {
 
   public boolean usesSharedGears() { return usesSharedGears; }
 
+  public void setUseMappedBuffers(boolean v) { useMappedBuffers = v; }
+  public void setValidateBuffers(boolean v) { validateBuffers = v; }
+
   public void init(GLAutoDrawable drawable) {
     System.err.println(Thread.currentThread()+" GearsES1.init ...");
 
@@ -161,8 +166,7 @@ public class GearsES1 implements GLEventListener {
 
     /* make the gears */
     if(null == gear1) {
-        gear1 = new GearsObjectES1(gear1Color, 1.0f, 4.0f, 1.0f, 20, 0.7f);
-        gear1.init(gl);
+        gear1 = new GearsObjectES1(gl, useMappedBuffers, gear1Color, 1.0f, 4.0f, 1.0f, 20, 0.7f, validateBuffers);
         System.err.println("gear1 created: "+gear1);
     } else {
         usesSharedGears = true;
@@ -170,8 +174,7 @@ public class GearsES1 implements GLEventListener {
     }
 
     if(null == gear2) {
-        gear2 = new GearsObjectES1(gear2Color, 0.5f, 2.0f, 2.0f, 10, 0.7f);
-        gear2.init(gl);
+        gear2 = new GearsObjectES1(gl, useMappedBuffers, gear2Color, 0.5f, 2.0f, 2.0f, 10, 0.7f, validateBuffers);
         System.err.println("gear2 created: "+gear2);
     } else {
         usesSharedGears = true;
@@ -179,8 +182,7 @@ public class GearsES1 implements GLEventListener {
     }
 
     if(null == gear3) {
-        gear3 = new GearsObjectES1(gear3Color, 1.3f, 2.0f, 0.5f, 10, 0.7f);
-        gear3.init(gl);
+        gear3 = new GearsObjectES1(gl, useMappedBuffers, gear3Color, 1.3f, 2.0f, 0.5f, 10, 0.7f, validateBuffers);
         System.err.println("gear3 created: "+gear3);
     } else {
         usesSharedGears = true;
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/GearsObjectES1.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/GearsObjectES1.java
index fb9251e..777fb04 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/GearsObjectES1.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/GearsObjectES1.java
@@ -24,6 +24,8 @@ import java.nio.FloatBuffer;
 
 import javax.media.opengl.GL;
 import javax.media.opengl.GL2ES1;
+import javax.media.opengl.GLBufferStorage;
+import javax.media.opengl.GLException;
 import javax.media.opengl.fixedfunc.GLPointerFunc;
 
 import com.jogamp.opengl.test.junit.jogl.demos.GearsObject;
@@ -35,14 +37,18 @@ import com.jogamp.opengl.util.GLArrayDataServer;
  */
 public class GearsObjectES1 extends GearsObject {
 
-    public GearsObjectES1(FloatBuffer gearColor, float inner_radius, float outer_radius, float width,
-            int teeth, float tooth_depth) {
-        super(gearColor, inner_radius, outer_radius, width, teeth, tooth_depth);
+    public GearsObjectES1(GL gl, boolean useMappedBuffers, FloatBuffer gearColor, float inner_radius,
+            float outer_radius, float width, int teeth, float tooth_depth, boolean validateBuffers) {
+        super(gl, useMappedBuffers, gearColor, inner_radius, outer_radius, width, teeth, tooth_depth, validateBuffers);
     }
 
     @Override
-    public GLArrayDataServer createInterleaved(int comps, int dataType, boolean normalized, int initialSize, int vboUsage) {
-        return GLArrayDataServer.createFixedInterleaved(comps, dataType, normalized, initialSize, vboUsage);
+    public GLArrayDataServer createInterleaved(boolean useMappedBuffers, int comps, int dataType, boolean normalized, int initialSize, int vboUsage) {
+        if( useMappedBuffers ) {
+            return GLArrayDataServer.createFixedInterleavedMapped(comps, dataType, normalized, initialSize, vboUsage);
+        } else {
+            return GLArrayDataServer.createFixedInterleaved(comps, dataType, normalized, initialSize, vboUsage);
+        }
     }
 
     @Override
@@ -54,6 +60,20 @@ public class GearsObjectES1 extends GearsObject {
     private void draw(GL2ES1 gl, GLArrayDataServer array, int mode) {
         if( !isShared || gl.glIsBuffer(array.getVBOName()) ) {
             array.enableBuffer(gl, true);
+            if( validateBuffers ) {
+                final int bufferTarget = array.getVBOTarget();
+                final int bufferName = array.getVBOName();
+                final long bufferSize = array.getSizeInBytes();
+                final int hasBufferName = gl.getBoundBuffer(bufferTarget);
+                final GLBufferStorage hasStorage = gl.getBufferStorage(hasBufferName);
+                final boolean ok = bufferName == hasBufferName &&
+                                   bufferName == hasStorage.getName() &&
+                                   bufferSize == hasStorage.getSize();
+                if( !ok ) {
+                    throw new GLException("GLBufferStorage Validation Error: Target[exp 0x"+Integer.toHexString(bufferTarget)+", has 0x"+Integer.toHexString(bufferTarget)+
+                                          ", Name[exp "+bufferName+", has "+hasBufferName+", Size exp "+bufferSize+", Storage "+hasStorage+"]");
+                }
+            }
             gl.glDrawArrays(mode, 0, array.getElementCount());
             array.enableBuffer(gl, false);
         }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java
index d85d386..653937a 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java
@@ -67,6 +67,8 @@ public class GearsES2 implements GLEventListener, TileRendererBase.TileRendererL
     private float panX = 0.0f, panY = 0.0f, panZ=0.0f;
     private volatile GearsObjectES2 gear1=null, gear2=null, gear3=null;
     private GearsES2 sharedGears = null;
+    private boolean useMappedBuffers = false;
+    private boolean validateBuffers = false;
     private volatile boolean usesSharedGears = false;
     private FloatBuffer gear1Color=GearsObject.red, gear2Color=GearsObject.green, gear3Color=GearsObject.blue;
     private float angle = 0.0f;
@@ -164,6 +166,9 @@ public class GearsES2 implements GLEventListener, TileRendererBase.TileRendererL
 
     public boolean usesSharedGears() { return usesSharedGears; }
 
+    public void setUseMappedBuffers(boolean v) { useMappedBuffers = v; }
+    public void setValidateBuffers(boolean v) { validateBuffers = v; }
+
     private static final int TIME_OUT     = 2000; // 2s
     private static final int POLL_DIVIDER   = 20; // TO/20
     private static final int TIME_SLICE   = TIME_OUT / POLL_DIVIDER ;
@@ -184,14 +189,14 @@ public class GearsES2 implements GLEventListener, TileRendererBase.TileRendererL
     @Override
     public void init(GLAutoDrawable drawable) {
         if(null != sharedGears && !sharedGears.isInit() ) {
-            System.err.println(Thread.currentThread()+" GearsES2.init "+sid()+": pending shared Gears .. re-init later XXXXX");
+            System.err.println(Thread.currentThread()+" GearsES2.init.0 "+sid()+": pending shared Gears .. re-init later XXXXX");
             drawable.setGLEventListenerInitState(this, false);
             return;
         }
 
         final GL2ES2 gl = drawable.getGL().getGL2ES2();
         if(verbose) {
-            System.err.println(Thread.currentThread()+" GearsES2.init "+sid()+": tileRendererInUse "+tileRendererInUse);
+            System.err.println(Thread.currentThread()+" GearsES2.init.0 "+sid()+": tileRendererInUse "+tileRendererInUse+", "+this);
             System.err.println("GearsES2 init "+sid()+" on "+Thread.currentThread());
             System.err.println("Chosen GLCapabilities: " + drawable.getChosenGLCapabilities());
             System.err.println("INIT GL IS: " + gl.getClass().getName());
@@ -245,8 +250,7 @@ public class GearsES2 implements GLEventListener, TileRendererBase.TileRendererL
                 }
         } else {
             if(null == gear1) {
-                gear1 = new GearsObjectES2(st, gear1Color, 1.0f, 4.0f, 1.0f, 20, 0.7f, pmvMatrix, pmvMatrixUniform, colorU);
-                gear1.init(gl);
+                gear1 = new GearsObjectES2(gl, useMappedBuffers, st, gear1Color, 1.0f, 4.0f, 1.0f, 20, 0.7f, pmvMatrix, pmvMatrixUniform, colorU, validateBuffers);
                 if(verbose) {
                     System.err.println("gear1 "+sid()+" created: "+gear1);
                 }
@@ -260,8 +264,7 @@ public class GearsES2 implements GLEventListener, TileRendererBase.TileRendererL
             }
 
             if(null == gear2) {
-                gear2 = new GearsObjectES2(st, gear2Color, 0.5f, 2.0f, 2.0f, 10, 0.7f, pmvMatrix, pmvMatrixUniform, colorU);
-                gear2.init(gl);
+                gear2 = new GearsObjectES2(gl, useMappedBuffers, st, gear2Color, 0.5f, 2.0f, 2.0f, 10, 0.7f, pmvMatrix, pmvMatrixUniform, colorU, validateBuffers);
                 if(verbose) {
                     System.err.println("gear2 "+sid()+" created: "+gear2);
                 }
@@ -275,8 +278,7 @@ public class GearsES2 implements GLEventListener, TileRendererBase.TileRendererL
             }
 
             if(null == gear3) {
-                gear3 = new GearsObjectES2(st, gear3Color, 1.3f, 2.0f, 0.5f, 10, 0.7f, pmvMatrix, pmvMatrixUniform, colorU);
-                gear3.init(gl);
+                gear3 = new GearsObjectES2(gl, useMappedBuffers, st, gear3Color, 1.3f, 2.0f, 0.5f, 10, 0.7f, pmvMatrix, pmvMatrixUniform, colorU, validateBuffers);
                 if(verbose) {
                     System.err.println("gear3 "+sid()+" created: "+gear2);
                 }
@@ -310,7 +312,7 @@ public class GearsES2 implements GLEventListener, TileRendererBase.TileRendererL
 
         isInit = true;
         if(verbose) {
-            System.err.println(Thread.currentThread()+" GearsES2.init "+sid()+" FIN "+this);
+            System.err.println(Thread.currentThread()+" GearsES2.init.X "+sid()+" FIN "+this);
         }
     }
 
@@ -516,7 +518,7 @@ public class GearsES2 implements GLEventListener, TileRendererBase.TileRendererL
 
     @Override
     public String toString() {
-        return "GearsES2[obj "+sid()+" isInit "+isInit+", usesShared "+usesSharedGears+", 1 "+gear1+", 2 "+gear2+", 3 "+gear3+"]";
+        return "GearsES2[obj "+sid()+" isInit "+isInit+", usesShared "+usesSharedGears+", 1 "+gear1+", 2 "+gear2+", 3 "+gear3+", sharedGears "+sharedGears+"]";
     }
 
     boolean confinedFixedCenter = false;
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsObjectES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsObjectES2.java
index f3367ad..4cef639 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsObjectES2.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsObjectES2.java
@@ -24,6 +24,8 @@ import java.nio.FloatBuffer;
 
 import javax.media.opengl.GL;
 import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLBufferStorage;
+import javax.media.opengl.GLException;
 import javax.media.opengl.GLUniformData;
 
 import com.jogamp.opengl.test.junit.jogl.demos.GearsObject;
@@ -41,13 +43,13 @@ public class GearsObjectES2 extends GearsObject {
     final GLUniformData colorUniform;
     final ShaderState st;
 
-    public GearsObjectES2(ShaderState st, FloatBuffer gearColor, float inner_radius, float outer_radius,
-                          float width, int teeth,
-                          float tooth_depth,
-                          PMVMatrix pmvMatrix,
-                          GLUniformData pmvMatrixUniform, GLUniformData colorUniform)
+    public GearsObjectES2(GL gl, boolean useMappedBuffers, ShaderState st, FloatBuffer gearColor,
+                          float inner_radius, float outer_radius,
+                          float width,
+                          int teeth,
+                          float tooth_depth, PMVMatrix pmvMatrix, GLUniformData pmvMatrixUniform, GLUniformData colorUniform, boolean validateBuffers)
     {
-        super(gearColor, inner_radius, outer_radius, width, teeth, tooth_depth);
+        super(gl, useMappedBuffers, gearColor, inner_radius, outer_radius, width, teeth, tooth_depth, validateBuffers);
         this.pmvMatrix = pmvMatrix;
         this.pmvMatrixUniform = pmvMatrixUniform;
         this.colorUniform = colorUniform;
@@ -78,8 +80,12 @@ public class GearsObjectES2 extends GearsObject {
     }
 
     @Override
-    public GLArrayDataServer createInterleaved(int comps, int dataType, boolean normalized, int initialSize, int vboUsage) {
-        return GLArrayDataServer.createGLSLInterleaved(comps, dataType, normalized, initialSize, vboUsage);
+    public GLArrayDataServer createInterleaved(boolean useMappedBuffers, int comps, int dataType, boolean normalized, int initialSize, int vboUsage) {
+        if( useMappedBuffers ) {
+            return GLArrayDataServer.createGLSLInterleavedMapped(comps, dataType, normalized, initialSize, vboUsage);
+        } else {
+            return GLArrayDataServer.createGLSLInterleaved(comps, dataType, normalized, initialSize, vboUsage);
+        }
     }
 
     @Override
@@ -90,6 +96,21 @@ public class GearsObjectES2 extends GearsObject {
 
     private void draw(GL2ES2 gl, GLArrayDataServer array, int mode, int face) {
         if( !isShared || gl.glIsBuffer(array.getVBOName()) ) {
+            if( validateBuffers ) {
+                array.bindBuffer(gl, true);
+                final int bufferTarget = array.getVBOTarget();
+                final int bufferName = array.getVBOName();
+                final long bufferSize = array.getSizeInBytes();
+                final int hasBufferName = gl.getBoundBuffer(bufferTarget);
+                final GLBufferStorage hasStorage = gl.getBufferStorage(hasBufferName);
+                final boolean ok = bufferName == hasBufferName &&
+                                   bufferName == hasStorage.getName() &&
+                                   bufferSize == hasStorage.getSize();
+                if( !ok ) {
+                    throw new GLException("GLBufferStorage Validation Error: Target[exp 0x"+Integer.toHexString(bufferTarget)+", has 0x"+Integer.toHexString(bufferTarget)+
+                                          ", Name[exp "+bufferName+", has "+hasBufferName+", Size exp "+bufferSize+", Storage "+hasStorage+"]");
+                }
+            }
             array.enableBuffer(gl, true);
             // System.err.println("XXX Draw face "+face+" of "+this);
             gl.glDrawArrays(mode, 0, array.getElementCount());
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareMappedES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareMappedES2.java
new file mode 100644
index 0000000..f0c9fc6
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareMappedES2.java
@@ -0,0 +1,281 @@
+/**
+ * Copyright 2010 JogAmp Community. 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 JogAmp Community ``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 JogAmp Community OR
+ * 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package com.jogamp.opengl.test.junit.jogl.demos.es2;
+
+import java.nio.FloatBuffer;
+
+import com.jogamp.opengl.JoglVersion;
+import com.jogamp.opengl.util.GLArrayDataServer;
+import com.jogamp.opengl.util.PMVMatrix;
+import com.jogamp.opengl.util.TileRendererBase;
+import com.jogamp.opengl.util.glsl.ShaderCode;
+import com.jogamp.opengl.util.glsl.ShaderProgram;
+import com.jogamp.opengl.util.glsl.ShaderState;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLBufferStorage;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLUniformData;
+
+public class RedSquareMappedES2 implements GLEventListener, TileRendererBase.TileRendererListener {
+    private ShaderState st;
+    private PMVMatrix pmvMatrix;
+    private GLUniformData pmvMatrixUniform;
+    private GLArrayDataServer vertices ;
+    private GLArrayDataServer colors ;
+    private long t0;
+    private int swapInterval = 0;
+    private float aspect = 1.0f;
+    private boolean doRotate = true;
+    private boolean clearBuffers = true;
+    private TileRendererBase tileRendererInUse = null;
+    private boolean doRotateBeforePrinting;
+
+    public RedSquareMappedES2(int swapInterval) {
+        this.swapInterval = swapInterval;
+    }
+
+    public RedSquareMappedES2() {
+        this.swapInterval = 1;
+    }
+
+    @Override
+    public void addTileRendererNotify(TileRendererBase tr) {
+        tileRendererInUse = tr;
+        doRotateBeforePrinting = doRotate;
+        setDoRotation(false);
+    }
+    @Override
+    public void removeTileRendererNotify(TileRendererBase tr) {
+        tileRendererInUse = null;
+        setDoRotation(doRotateBeforePrinting);
+    }
+    @Override
+    public void startTileRendering(TileRendererBase tr) {
+        System.err.println("RedSquareES2.startTileRendering: "+tr);
+    }
+    @Override
+    public void endTileRendering(TileRendererBase tr) {
+        System.err.println("RedSquareES2.endTileRendering: "+tr);
+    }
+
+    public void setAspect(float aspect) { this.aspect = aspect; }
+    public void setDoRotation(boolean rotate) { this.doRotate = rotate; }
+    public void setClearBuffers(boolean v) { clearBuffers = v; }
+
+    @Override
+    public void init(GLAutoDrawable glad) {
+        System.err.println(Thread.currentThread()+" RedSquareES2.init: tileRendererInUse "+tileRendererInUse);
+        final GL2ES2 gl = glad.getGL().getGL2ES2();
+
+        System.err.println("RedSquareES2 init on "+Thread.currentThread());
+        System.err.println("Chosen GLCapabilities: " + glad.getChosenGLCapabilities());
+        System.err.println("INIT GL IS: " + gl.getClass().getName());
+        System.err.println(JoglVersion.getGLStrings(gl, null, false).toString());
+        if( !gl.hasGLSL() ) {
+            System.err.println("No GLSL available, no rendering.");
+            return;
+        }
+        st = new ShaderState();
+        st.setVerbose(true);
+        final ShaderCode vp0 = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, this.getClass(), "shader",
+                "shader/bin", "RedSquareShader", true);
+        final ShaderCode fp0 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, this.getClass(), "shader",
+                "shader/bin", "RedSquareShader", true);
+        vp0.defaultShaderCustomization(gl, true, true);
+        fp0.defaultShaderCustomization(gl, true, true);
+        final ShaderProgram sp0 = new ShaderProgram();
+        sp0.add(gl, vp0, System.err);
+        sp0.add(gl, fp0, System.err);
+        st.attachShaderProgram(gl, sp0, true);
+
+        // setup mgl_PMVMatrix
+        pmvMatrix = new PMVMatrix();
+        pmvMatrix.glMatrixMode(PMVMatrix.GL_PROJECTION);
+        pmvMatrix.glLoadIdentity();
+        pmvMatrix.glMatrixMode(PMVMatrix.GL_MODELVIEW);
+        pmvMatrix.glLoadIdentity();
+        pmvMatrixUniform = new GLUniformData("mgl_PMVMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf()); // P, Mv
+        st.ownUniform(pmvMatrixUniform);
+        st.uniform(gl, pmvMatrixUniform);
+
+        // Allocate Vertex Array
+        vertices = GLArrayDataServer.createGLSLMapped("mgl_Vertex", 3, GL.GL_FLOAT, false, 4, GL.GL_STATIC_DRAW);
+        {
+            final GLArrayDataServer ad = vertices;
+            final GLBufferStorage store = ad.mapStorage(gl, GL.GL_WRITE_ONLY);
+            {
+                final FloatBuffer fb = store.getMappedBuffer().asFloatBuffer();
+                fb.put(-2); fb.put( 2); fb.put( 0);
+                fb.put( 2); fb.put( 2); fb.put( 0);
+                fb.put(-2); fb.put(-2); fb.put( 0);
+                fb.put( 2); fb.put(-2); fb.put( 0);
+            }
+            ad.unmapStorage(gl);
+        }
+        vertices.seal(gl, true);
+        st.ownAttribute(vertices, true);
+        vertices.enableBuffer(gl, false);
+
+        // Allocate Color Array
+        colors = GLArrayDataServer.createGLSLMapped("mgl_Color", 4, GL.GL_FLOAT, false, 4, GL.GL_STATIC_DRAW);
+        {
+            final GLArrayDataServer ad = colors;
+            final GLBufferStorage store = ad.mapStorage(gl, GL.GL_WRITE_ONLY);
+            {
+                final FloatBuffer fb = store.getMappedBuffer().asFloatBuffer();
+                fb.put(1); fb.put(0); fb.put(0); fb.put(1);
+                fb.put(0); fb.put(0); fb.put(1); fb.put(1);
+                fb.put(1); fb.put(0); fb.put(0); fb.put(1);
+                fb.put(1); fb.put(0); fb.put(0); fb.put(1);
+            }
+            ad.unmapStorage(gl);
+        }
+        colors.seal(gl, true);
+        st.ownAttribute(colors, true);
+        colors.enableBuffer(gl, false);
+
+        // OpenGL Render Settings
+        gl.glEnable(GL2ES2.GL_DEPTH_TEST);
+        st.useProgram(gl, false);
+
+        t0 = System.currentTimeMillis();
+        System.err.println(Thread.currentThread()+" RedSquareES2.init FIN");
+    }
+
+    @Override
+    public void display(GLAutoDrawable glad) {
+        long t1 = System.currentTimeMillis();
+
+        final GL2ES2 gl = glad.getGL().getGL2ES2();
+        if( clearBuffers ) {
+            if( null != tileRendererInUse ) {
+              gl.glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
+            } else {
+                gl.glClearColor(0, 0, 0, 0);
+            }
+            gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
+        }
+        if( !gl.hasGLSL() ) {
+            return;
+        }
+        st.useProgram(gl, true);
+        // One rotation every four seconds
+        pmvMatrix.glMatrixMode(PMVMatrix.GL_MODELVIEW);
+        pmvMatrix.glLoadIdentity();
+        pmvMatrix.glTranslatef(0, 0, -10);
+        if(doRotate) {
+            float ang = ((t1 - t0) * 360.0F) / 4000.0F;
+            pmvMatrix.glRotatef(ang, 0, 0, 1);
+            pmvMatrix.glRotatef(ang, 0, 1, 0);
+        }
+        st.uniform(gl, pmvMatrixUniform);
+
+        // Draw a square
+        vertices.enableBuffer(gl, true);
+        colors.enableBuffer(gl, true);
+        gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, 4);
+        vertices.enableBuffer(gl, false);
+        colors.enableBuffer(gl, false);
+        st.useProgram(gl, false);
+    }
+
+    @Override
+    public void reshape(GLAutoDrawable glad, int x, int y, int width, int height) {
+        final GL2ES2 gl = glad.getGL().getGL2ES2();
+        if(-1 != swapInterval) {
+            gl.setSwapInterval(swapInterval);
+        }
+        reshapeImpl(gl, x, y, width, height, width, height);
+    }
+
+    @Override
+    public void reshapeTile(TileRendererBase tr,
+                            int tileX, int tileY, int tileWidth, int tileHeight,
+                            int imageWidth, int imageHeight) {
+        final GL2ES2 gl = tr.getAttachedDrawable().getGL().getGL2ES2();
+        gl.setSwapInterval(0);
+        reshapeImpl(gl, tileX, tileY, tileWidth, tileHeight, imageWidth, imageHeight);
+    }
+
+    void reshapeImpl(GL2ES2 gl, int tileX, int tileY, int tileWidth, int tileHeight, int imageWidth, int imageHeight) {
+        System.err.println(Thread.currentThread()+" RedSquareES2.reshape "+tileX+"/"+tileY+" "+tileWidth+"x"+tileHeight+" of "+imageWidth+"x"+imageHeight+", swapInterval "+swapInterval+", drawable 0x"+Long.toHexString(gl.getContext().getGLDrawable().getHandle())+", tileRendererInUse "+tileRendererInUse);
+        // Thread.dumpStack();
+        if( !gl.hasGLSL() ) {
+            return;
+        }
+
+        st.useProgram(gl, true);
+        // Set location in front of camera
+        pmvMatrix.glMatrixMode(PMVMatrix.GL_PROJECTION);
+        pmvMatrix.glLoadIdentity();
+
+        // compute projection parameters 'normal' perspective
+        final float fovy=45f;
+        final float aspect2 = ( (float) imageWidth / (float) imageHeight ) / aspect;
+        final float zNear=1f;
+        final float zFar=100f;
+
+        // compute projection parameters 'normal' frustum
+        final float top=(float)Math.tan(fovy*((float)Math.PI)/360.0f)*zNear;
+        final float bottom=-1.0f*top;
+        final float left=aspect2*bottom;
+        final float right=aspect2*top;
+        final float w = right - left;
+        final float h = top - bottom;
+
+        // compute projection parameters 'tiled'
+        final float l = left + tileX * w / imageWidth;
+        final float r = l + tileWidth * w / imageWidth;
+        final float b = bottom + tileY * h / imageHeight;
+        final float t = b + tileHeight * h / imageHeight;
+
+        pmvMatrix.glFrustumf(l, r, b, t, zNear, zFar);
+        //pmvMatrix.glOrthof(-4.0f, 4.0f, -4.0f, 4.0f, 1.0f, 100.0f);
+        st.uniform(gl, pmvMatrixUniform);
+        st.useProgram(gl, false);
+
+        System.err.println(Thread.currentThread()+" RedSquareES2.reshape FIN");
+    }
+
+    @Override
+    public void dispose(GLAutoDrawable glad) {
+        System.err.println(Thread.currentThread()+" RedSquareES2.dispose: tileRendererInUse "+tileRendererInUse);
+        final GL2ES2 gl = glad.getGL().getGL2ES2();
+        if( !gl.hasGLSL() ) {
+            return;
+        }
+        st.destroy(gl);
+        st = null;
+        pmvMatrix.destroy();
+        pmvMatrix = null;
+        System.err.println(Thread.currentThread()+" RedSquareES2.dispose FIN");
+    }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java
index ddf5c70..fcf1cd2 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java
@@ -36,6 +36,7 @@ import java.nio.FloatBuffer;
 
 import javax.media.opengl.GL;
 import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLAnimatorControl;
 import javax.media.opengl.GLAutoDrawable;
 import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLES2;
@@ -84,6 +85,9 @@ public class MovieSimple implements GLEventListener {
     public static final int EFFECT_GRADIENT_BOTTOM2TOP     = 1<<1;
     public static final int EFFECT_TRANSPARENT             = 1<<3;
 
+    private static final String WINDOW_KEY = "window";
+    private static final String PLAYER = "player";
+
     private static boolean waitForKey = false;
     private int winWidth, winHeight;
     private int prevMouseX; // , prevMouseY;
@@ -286,6 +290,7 @@ public class MovieSimple implements GLEventListener {
         mPlayerShared = null != mPlayer;
         if( !mPlayerShared ) {
             mPlayer = GLMediaPlayerFactory.createDefault();
+            mPlayer.attachObject(PLAYER, this);
         }
         System.out.println("pC.1a shared "+mPlayerShared+", "+mPlayer);
     }
@@ -701,6 +706,94 @@ public class MovieSimple implements GLEventListener {
         st.useProgram(gl, false);
     }
 
+    static class MyGLMediaEventListener implements GLMediaEventListener {
+            void destroyWindow(final Window window) {
+                new Thread() {
+                    public void run() {
+                        window.destroy();
+                    } }.start();
+            }
+
+            @Override
+            public void newFrameAvailable(GLMediaPlayer ts, TextureFrame newFrame, long when) {
+            }
+
+            @Override
+            public void attributesChanged(final GLMediaPlayer mp, int event_mask, long when) {
+                System.err.println("MovieSimple AttributesChanges: events_mask 0x"+Integer.toHexString(event_mask)+", when "+when);
+                System.err.println("MovieSimple State: "+mp);
+                final GLWindow window = (GLWindow) mp.getAttachedObject(WINDOW_KEY);
+                final MovieSimple ms = (MovieSimple)mp.getAttachedObject(PLAYER);
+                if( 0 != ( GLMediaEventListener.EVENT_CHANGE_SIZE & event_mask ) ) {
+                    System.err.println("MovieSimple State: CHANGE_SIZE");
+                    if( origSize ) {
+                        window.setSize(mp.getWidth(), mp.getHeight());
+                    }
+                    // window.disposeGLEventListener(ms, false /* remove */ );
+                    ms.resetGLState();
+                }
+                if( 0 != ( GLMediaEventListener.EVENT_CHANGE_INIT & event_mask ) ) {
+                    System.err.println("MovieSimple State: INIT");
+                    // Use GLEventListener in all cases [A+V, V, A]
+                    window.addGLEventListener(ms);
+                    final GLAnimatorControl anim = window.getAnimator();
+                    anim.setUpdateFPSFrames(60, System.err);
+                    anim.resetFPSCounter();
+
+                    /**
+                     * Kick off player w/o GLEventListener, i.e. for audio only.
+                     *
+                        try {
+                            ms.mPlayer.initGL(null);
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                            destroyWindow();
+                            return;
+                        }
+                        ms.mPlayer.play();
+                        System.out.println("play.1 "+ms.mPlayer);
+                    */
+                }
+                boolean destroy = false;
+                Throwable err = null;
+
+                if( 0 != ( GLMediaEventListener.EVENT_CHANGE_EOS & event_mask ) ) {
+                    err = ms.mPlayer.getStreamException();
+                    if( null != err ) {
+                        System.err.println("MovieSimple State: EOS + Exception");
+                        destroy = true;
+                    } else {
+                        System.err.println("MovieSimple State: EOS");
+                        if( loopEOS ) {
+                            ms.mPlayer.seek(0);
+                            ms.mPlayer.play();
+                        } else {
+                            destroy = true;
+                        }
+                    }
+                }
+                if( 0 != ( GLMediaEventListener.EVENT_CHANGE_ERR & event_mask ) ) {
+                    err = ms.mPlayer.getStreamException();
+                    if( null != err ) {
+                        System.err.println("MovieSimple State: ERR + Exception");
+                    } else {
+                        System.err.println("MovieSimple State: ERR");
+                    }
+                    destroy = true;
+                }
+                if( destroy ) {
+                    if( null != err ) {
+                        err.printStackTrace();
+                    }
+                    destroyWindow(window);
+                }
+            }
+        };
+    final static MyGLMediaEventListener myGLMediaEventListener = new MyGLMediaEventListener();
+
+    static boolean loopEOS = false;
+    static boolean origSize;
+
     public static void main(String[] args) throws IOException, URISyntaxException {
         int swapInterval = 1;
         int width = 640;
@@ -708,7 +801,6 @@ public class MovieSimple implements GLEventListener {
         int textureCount = 3; // default - threaded
         boolean ortho = true;
         boolean zoom = false;
-        boolean _loopEOS = false;
 
         boolean forceES2 = false;
         boolean forceES3 = false;
@@ -716,9 +808,20 @@ public class MovieSimple implements GLEventListener {
         boolean forceGLDef = false;
         int vid = GLMediaPlayer.STREAM_ID_AUTO;
         int aid = GLMediaPlayer.STREAM_ID_AUTO;
-        final boolean origSize;
 
-        String url_s=null, file_s1=null, file_s2=null;
+        final int windowCount;
+        {
+            int _windowCount = 1;
+            for(int i=0; i<args.length; i++) {
+                if(args[i].equals("-windows")) {
+                    i++;
+                    _windowCount = MiscUtils.atoi(args[i], _windowCount);
+                }
+            }
+            windowCount = _windowCount;
+        }
+        String[] urls_s = new String[windowCount];
+        String file_s1=null, file_s2=null;
         {
             boolean _origSize = false;
             for(int i=0; i<args.length; i++) {
@@ -755,10 +858,15 @@ public class MovieSimple implements GLEventListener {
                 } else if(args[i].equals("-zoom")) {
                     zoom=true;
                 } else if(args[i].equals("-loop")) {
-                    _loopEOS=true;
+                    loopEOS=true;
+                } else if(args[i].equals("-urlN")) {
+                    i++;
+                    final int n = MiscUtils.atoi(args[i], 0);
+                    i++;
+                    urls_s[n] = args[i];
                 } else if(args[i].equals("-url")) {
                     i++;
-                    url_s = args[i];
+                    urls_s[0] = args[i];
                 } else if(args[i].equals("-file1")) {
                     i++;
                     file_s1 = args[i];
@@ -771,21 +879,20 @@ public class MovieSimple implements GLEventListener {
             }
             origSize = _origSize;
         }
-        final boolean loopEOS = _loopEOS;
-        final URI streamLoc;
-        if( null != url_s ) {
-            streamLoc = new URI(url_s);
+        final URI streamLoc0;
+        if( null != urls_s[0] ) {
+            streamLoc0 = new URI(urls_s[0]);
         } else if( null != file_s1 ) {
             File movieFile = new File(file_s1);
-            streamLoc = movieFile.toURI();
+            streamLoc0 = movieFile.toURI();
         } else if( null != file_s2 ) {
-            streamLoc = IOUtil.toURISimple(new File(file_s2));
+            streamLoc0 = IOUtil.toURISimple(new File(file_s2));
         } else {
-            streamLoc = defURI;
+            streamLoc0 = defURI;
         }
-        System.err.println("url_s "+url_s);
+        System.err.println("url_s "+urls_s[0]);
         System.err.println("file_s 1: "+file_s1+", 2: "+file_s2);
-        System.err.println("stream "+streamLoc);
+        System.err.println("stream0 "+streamLoc0);
         System.err.println("vid "+vid+", aid "+aid);
         System.err.println("textureCount "+textureCount);
         System.err.println("forceES2   "+forceES2);
@@ -794,119 +901,57 @@ public class MovieSimple implements GLEventListener {
         System.err.println("forceGLDef "+forceGLDef);
         System.err.println("swapInterval "+swapInterval);
 
-        final MovieSimple ms = new MovieSimple(null);
-        ms.setSwapInterval(swapInterval);
-        ms.setScaleOrig(!zoom);
-        ms.setOrthoProjection(ortho);
+        final GLProfile glp;
+        if(forceGLDef) {
+            glp = GLProfile.getDefault();
+        } else if(forceGL3) {
+            glp = GLProfile.get(GLProfile.GL3);
+        } else if(forceES3) {
+            glp = GLProfile.get(GLProfile.GLES3);
+        } else if(forceES2) {
+            glp = GLProfile.get(GLProfile.GLES2);
+        } else {
+            glp = GLProfile.getGL2ES2();
+        }
+        System.err.println("GLProfile: "+glp);
+        GLCapabilities caps = new GLCapabilities(glp);
 
-        try {
-            final GLProfile glp;
-            if(forceGLDef) {
-                glp = GLProfile.getDefault();
-            } else if(forceGL3) {
-                glp = GLProfile.get(GLProfile.GL3);
-            } else if(forceES3) {
-                glp = GLProfile.get(GLProfile.GLES3);
-            } else if(forceES2) {
-                glp = GLProfile.get(GLProfile.GLES2);
-            } else {
-                glp = GLProfile.getGL2ES2();
-            }
-            System.err.println("GLProfile: "+glp);
-            GLCapabilities caps = new GLCapabilities(glp);
-            final GLWindow window = GLWindow.create(caps);
-            final Animator anim = new Animator(window);
-            window.addWindowListener(new WindowAdapter() {
+        final Animator anim = new Animator();
+        anim.start();
+
+        final MovieSimple[] mss = new MovieSimple[windowCount];
+        final GLWindow[] windows = new GLWindow[windowCount];
+        for(int i=0; i<windowCount; i++) {
+            windows[i] = GLWindow.create(caps);
+            windows[i].addWindowListener(new WindowAdapter() {
                 public void windowDestroyed(WindowEvent e) {
                     anim.stop();
                 }
             });
-            window.setSize(width, height);
-            window.setVisible(true);
-            anim.start();
-
-            ms.mPlayer.addEventListener(new GLMediaEventListener() {
-                void destroyWindow() {
-                    new Thread() {
-                        public void run() {
-                            window.destroy();
-                        } }.start();
-                }
-
-                @Override
-                public void newFrameAvailable(GLMediaPlayer ts, TextureFrame newFrame, long when) {
-                }
-
-                @Override
-                public void attributesChanged(final GLMediaPlayer mp, int event_mask, long when) {
-                    System.err.println("MovieSimple AttributesChanges: events_mask 0x"+Integer.toHexString(event_mask)+", when "+when);
-                    System.err.println("MovieSimple State: "+mp);
-                    if( 0 != ( GLMediaEventListener.EVENT_CHANGE_SIZE & event_mask ) ) {
-                        System.err.println("MovieSimple State: CHANGE_SIZE");
-                        if( origSize ) {
-                            window.setSize(mp.getWidth(), mp.getHeight());
-                        }
-                        // window.disposeGLEventListener(ms, false /* remove */ );
-                        ms.resetGLState();
-                    }
-                    if( 0 != ( GLMediaEventListener.EVENT_CHANGE_INIT & event_mask ) ) {
-                        System.err.println("MovieSimple State: INIT");
-                        // Use GLEventListener in all cases [A+V, V, A]
-                        window.addGLEventListener(ms);
-                        anim.setUpdateFPSFrames(60, System.err);
-                        anim.resetFPSCounter();
-                        /**
-                         * Kick off player w/o GLEventListener, i.e. for audio only.
-                         *
-                            try {
-                                ms.mPlayer.initGL(null);
-                            } catch (Exception e) {
-                                e.printStackTrace();
-                                destroyWindow();
-                                return;
-                            }
-                            ms.mPlayer.play();
-                            System.out.println("play.1 "+ms.mPlayer);
-                        */
-                    }
-                    boolean destroy = false;
-                    Throwable err = null;
-
-                    if( 0 != ( GLMediaEventListener.EVENT_CHANGE_EOS & event_mask ) ) {
-                        err = ms.mPlayer.getStreamException();
-                        if( null != err ) {
-                            System.err.println("MovieSimple State: EOS + Exception");
-                            destroy = true;
-                        } else {
-                            System.err.println("MovieSimple State: EOS");
-                            if( loopEOS ) {
-                                ms.mPlayer.seek(0);
-                                ms.mPlayer.play();
-                            } else {
-                                destroy = true;
-                            }
-                        }
-                    }
-                    if( 0 != ( GLMediaEventListener.EVENT_CHANGE_ERR & event_mask ) ) {
-                        err = ms.mPlayer.getStreamException();
-                        if( null != err ) {
-                            System.err.println("MovieSimple State: ERR + Exception");
-                        } else {
-                            System.err.println("MovieSimple State: ERR");
-                        }
-                        destroy = true;
-                    }
-                    if( destroy ) {
-                        if( null != err ) {
-                            err.printStackTrace();
-                        }
-                        destroyWindow();
-                    }
+            mss[i] = new MovieSimple(null);
+            mss[i].setSwapInterval(swapInterval);
+            mss[i].setScaleOrig(!zoom);
+            mss[i].setOrthoProjection(ortho);
+            mss[i].mPlayer.attachObject(WINDOW_KEY, windows[i]);
+            mss[i].mPlayer.addEventListener(myGLMediaEventListener);
+
+            windows[i].setTitle("Player "+i);
+            windows[i].setSize(width, height);
+            windows[i].setVisible(true);
+            anim.add(windows[i]);
+
+            final URI streamLocN;
+            if( 0 == i ) {
+                streamLocN = streamLoc0;
+            } else {
+                if( null != urls_s[i] ) {
+                    streamLocN = new URI(urls_s[i]);
+                } else {
+                    streamLocN = defURI;
                 }
-            });
-            ms.initStream(streamLoc, vid, aid, textureCount);
-        } catch (Throwable t) {
-            t.printStackTrace();
+            }
+            System.err.println("Win #"+i+": stream "+streamLocN);
+            mss[i].initStream(streamLocN, vid, aid, textureCount);
         }
     }
 }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java
index b54a2cd..5d5b0c9 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java
@@ -29,10 +29,14 @@
 package com.jogamp.opengl.test.junit.jogl.demos.es2.newt;
 
 import java.io.IOException;
+import java.net.URLConnection;
 
+import com.jogamp.common.util.IOUtil;
 import com.jogamp.newt.Display;
+import com.jogamp.newt.Display.PointerIcon;
 import com.jogamp.newt.NewtFactory;
 import com.jogamp.newt.Screen;
+import com.jogamp.newt.Window;
 import com.jogamp.newt.event.KeyAdapter;
 import com.jogamp.newt.event.KeyEvent;
 import com.jogamp.newt.event.MouseAdapter;
@@ -40,13 +44,13 @@ import com.jogamp.newt.event.MouseEvent;
 import com.jogamp.newt.event.WindowEvent;
 import com.jogamp.newt.event.WindowAdapter;
 import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.newt.util.EDTUtil;
 import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
 import com.jogamp.opengl.test.junit.util.MiscUtils;
 import com.jogamp.opengl.test.junit.util.UITestCase;
 import com.jogamp.opengl.test.junit.util.QuitAdapter;
-
 import com.jogamp.opengl.util.Animator;
-
+import com.jogamp.opengl.util.PNGPixelRect;
 import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
 
 import javax.media.nativewindow.NativeWindowFactory;
@@ -54,7 +58,6 @@ import javax.media.nativewindow.util.Dimension;
 import javax.media.nativewindow.util.Point;
 import javax.media.nativewindow.util.PointImmutable;
 import javax.media.nativewindow.util.DimensionImmutable;
-
 import javax.media.opengl.GLAnimatorControl;
 import javax.media.opengl.GLAutoDrawable;
 import javax.media.opengl.GLCapabilities;
@@ -62,6 +65,8 @@ import javax.media.opengl.GLCapabilitiesImmutable;
 import javax.media.opengl.GLEventListener;
 import javax.media.opengl.GLProfile;
 
+import jogamp.newt.DefaultEDTUtil;
+
 import org.junit.Assert;
 import org.junit.BeforeClass;
 import org.junit.AfterClass;
@@ -86,6 +91,7 @@ public class TestGearsES2NEWT extends UITestCase {
     static boolean waitForKey = false;
     static boolean mouseVisible = true;
     static boolean mouseConfined = false;
+    static boolean setPointerIcon = false;
     static boolean showFPS = false;
     static int loops = 1;
     static boolean loop_shutdown = false;
@@ -96,7 +102,8 @@ public class TestGearsES2NEWT extends UITestCase {
     static boolean mainRun = false;
     static boolean exclusiveContext = false;
     static boolean useAnimator = true;
-    static enum SysExit { none, testExit, testError, displayExit, displayError };
+    static boolean useMappedBuffers = false;
+    static enum SysExit { none, testExit, testError, testEDTError, displayExit, displayError, displayEDTError };
     static SysExit sysExit = SysExit.none;
 
     @BeforeClass
@@ -129,6 +136,8 @@ public class TestGearsES2NEWT extends UITestCase {
 
         final GearsES2 demo = new GearsES2(swapInterval);
         demo.setPMVUseBackingArray(pmvUseBackingArray);
+        demo.setUseMappedBuffers(useMappedBuffers);
+        demo.setValidateBuffers(true);
         glWindow.addGLEventListener(demo);
 
         final SnapshotGLEventListener snap = new SnapshotGLEventListener();
@@ -156,7 +165,7 @@ public class TestGearsES2NEWT extends UITestCase {
             animator.setExclusiveContext(exclusiveContext);
         }
 
-        QuitAdapter quitAdapter = new QuitAdapter();
+        final QuitAdapter quitAdapter = new QuitAdapter();
         //glWindow.addKeyListener(new TraceKeyAdapter(quitAdapter));
         //glWindow.addWindowListener(new TraceWindowAdapter(quitAdapter));
         glWindow.addKeyListener(quitAdapter);
@@ -171,7 +180,55 @@ public class TestGearsES2NEWT extends UITestCase {
             }
         });
 
+        final PointerIcon[] pointerIcons = { null, null, null };
+        {
+            final Display disp = glWindow.getScreen().getDisplay();
+            disp.createNative();
+            {
+                PointerIcon _pointerIcon = null;
+                final IOUtil.ClassResources res = new IOUtil.ClassResources(glWindow.getClass(), new String[] { "newt/data/cross-grey-alpha-16x16.png" } );
+                try {
+                    _pointerIcon = disp.createPointerIcon(res, 8, 8);
+                    System.err.println("Create PointerIcon #01: "+_pointerIcon);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+                pointerIcons[0] = _pointerIcon;
+            }
+            {
+                PointerIcon _pointerIcon = null;
+                final IOUtil.ClassResources res = new IOUtil.ClassResources(glWindow.getClass(), new String[] { "newt/data/pointer-grey-alpha-16x24.png" } );
+                try {
+                    _pointerIcon = disp.createPointerIcon(res, 0, 0);
+                    System.err.println("Create PointerIcon #02: "+_pointerIcon);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+                pointerIcons[1] = _pointerIcon;
+            }
+            {
+                PointerIcon _pointerIcon = null;
+                final IOUtil.ClassResources res = new IOUtil.ClassResources(glWindow.getClass(), new String[] { "jogamp-pointer-64x64.png" } );
+                try {
+                    final URLConnection urlConn = res.resolve(0);
+                    final PNGPixelRect image = PNGPixelRect.read(urlConn.getInputStream(), null, false /* directBuffer */, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+                    System.err.println("Create PointerIcon #03: "+image);
+                    _pointerIcon = disp.createPointerIcon(image, 32, 0);
+                    System.err.println("Create PointerIcon #03: "+_pointerIcon);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+                pointerIcons[2] = _pointerIcon;
+            }
+        }
+        if( setPointerIcon ) {
+            glWindow.setPointerIcon(pointerIcons[0]);
+            System.err.println("Set PointerIcon: "+glWindow.getPointerIcon());
+        }
+
         glWindow.addKeyListener(new KeyAdapter() {
+            int pointerIconIdx = 0;
+
             @Override
             public void keyPressed(final KeyEvent e) {
                 if( e.isAutoRepeat() ) {
@@ -222,6 +279,23 @@ public class TestGearsES2NEWT extends UITestCase {
                             System.err.println("[set position post]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", "+glWindow.getInsets());
                             glWindow.setExclusiveContextThread(t);
                     } }.start();
+                } else if(e.getKeyChar()=='c') {
+                    new Thread() {
+                        public void run() {
+                            final Thread t = glWindow.setExclusiveContextThread(null);
+                            System.err.println("[set pointer-icon pre]");
+                            final PointerIcon currentPI = glWindow.getPointerIcon();
+                            final PointerIcon newPI;
+                            if( pointerIconIdx >= pointerIcons.length ) {
+                                newPI=null;
+                                pointerIconIdx=0;
+                            } else {
+                                newPI=pointerIcons[pointerIconIdx++];
+                            }
+                            glWindow.setPointerIcon( newPI );
+                            System.err.println("[set pointer-icon post] "+currentPI+" -> "+glWindow.getPointerIcon());
+                            glWindow.setExclusiveContextThread(t);
+                    } }.start();
                 } else if(e.getKeyChar()=='i') {
                     new Thread() {
                         public void run() {
@@ -282,25 +356,38 @@ public class TestGearsES2NEWT extends UITestCase {
             Assert.assertEquals(exclusiveContext ? animator.getThread() : null, glWindow.getExclusiveContextThread());
         }
 
-        if( SysExit.displayError == sysExit || SysExit.displayExit == sysExit ) {
+        if( SysExit.displayError == sysExit || SysExit.displayExit == sysExit || SysExit.displayEDTError == sysExit ) {
             glWindow.addGLEventListener(new GLEventListener() {
-
                 @Override
                 public void init(GLAutoDrawable drawable) {}
-
                 @Override
                 public void dispose(GLAutoDrawable drawable) { }
-
                 @Override
                 public void display(GLAutoDrawable drawable) {
                     final GLAnimatorControl anim = drawable.getAnimator();
                     if( null != anim && anim.isAnimating() ) {
-                        if( anim.getTotalFPSDuration() >= duration/2 ) {
+                        final long ms = anim.getTotalFPSDuration();
+                        if( ms >= duration/2 || ms >= 3000 ) { // max 3s wait until provoking error
                             if( SysExit.displayError == sysExit ) {
-                                throw new Error("test error send from GLEventListener");
+                                throw new Error("test error send from GLEventListener.display - "+Thread.currentThread());
                             } else if ( SysExit.displayExit == sysExit ) {
                                 System.err.println("exit(0) send from GLEventListener");
                                 System.exit(0);
+                            } else if ( SysExit.displayEDTError == sysExit ) {
+                                final Object upstream = drawable.getUpstreamWidget();
+                                System.err.println("EDT invokeAndWaitError: upstream type "+upstream.getClass().getName());
+                                if( upstream instanceof Window ) {
+                                    final EDTUtil edt = ((Window)upstream).getScreen().getDisplay().getEDTUtil();
+                                    System.err.println("EDT invokeAndWaitError: edt type "+edt.getClass().getName());
+                                    if( edt instanceof DefaultEDTUtil ) {
+                                        quitAdapter.doQuit();
+                                        ((DefaultEDTUtil)edt).invokeAndWaitError(new Runnable() {
+                                            public void run() {
+                                                throw new RuntimeException("XXX Should never ever be seen! - "+Thread.currentThread());
+                                            }
+                                        });
+                                    }
+                                }
                             }
                         }
                     } else {
@@ -336,13 +423,25 @@ public class TestGearsES2NEWT extends UITestCase {
         while(!quitAdapter.shouldQuit() && t1-t0<duration) {
             Thread.sleep(100);
             t1 = System.currentTimeMillis();
-            if( t1-t0 >= duration/2 ) {
-                if( SysExit.testError == sysExit || SysExit.testExit == sysExit ) {
+            if( SysExit.testError == sysExit || SysExit.testExit == sysExit || SysExit.testEDTError == sysExit) {
+                final long ms = t1-t0;
+                if( ms >= duration/2 || ms >= 3000 ) { // max 3s wait until provoking error
                     if( SysExit.testError == sysExit ) {
                         throw new Error("test error send from test thread");
                     } else if ( SysExit.testExit == sysExit ) {
                         System.err.println("exit(0) send from test thread");
                         System.exit(0);
+                    } else if ( SysExit.testEDTError == sysExit ) {
+                        final EDTUtil edt = glWindow.getScreen().getDisplay().getEDTUtil();
+                        System.err.println("EDT invokeAndWaitError: edt type "+edt.getClass().getName());
+                        if( edt instanceof DefaultEDTUtil ) {
+                            quitAdapter.doQuit();
+                            ((DefaultEDTUtil)edt).invokeAndWaitError(new Runnable() {
+                                public void run() {
+                                    throw new RuntimeException("XXX Should never ever be seen!");
+                                }
+                            });
+                        }
                     }
                 }
             }
@@ -453,12 +552,16 @@ public class TestGearsES2NEWT extends UITestCase {
                 forceGL3 = true;
             } else if(args[i].equals("-gl2")) {
                 forceGL2 = true;
+            } else if(args[i].equals("-mappedBuffers")) {
+                useMappedBuffers = true;
             } else if(args[i].equals("-wait")) {
                 waitForKey = true;
             } else if(args[i].equals("-mouseInvisible")) {
                 mouseVisible = false;
             } else if(args[i].equals("-mouseConfine")) {
                 mouseConfined = true;
+            } else if(args[i].equals("-pointerIcon")) {
+                setPointerIcon = true;
             } else if(args[i].equals("-showFPS")) {
                 showFPS = true;
             } else if(args[i].equals("-width")) {
@@ -514,6 +617,7 @@ public class TestGearsES2NEWT extends UITestCase {
         System.err.println("pmvDirect "+(!pmvUseBackingArray));
         System.err.println("mouseVisible "+mouseVisible);
         System.err.println("mouseConfined "+mouseConfined);
+        System.err.println("pointerIcon "+setPointerIcon);
         System.err.println("loops "+loops);
         System.err.println("loop shutdown "+loop_shutdown);
         System.err.println("forceES2 "+forceES2);
@@ -524,6 +628,7 @@ public class TestGearsES2NEWT extends UITestCase {
         System.err.println("exclusiveContext "+exclusiveContext);
         System.err.println("useAnimator "+useAnimator);
         System.err.println("sysExitWithin "+sysExit);
+        System.err.println("mappedBuffers "+useMappedBuffers);
 
         if(waitForKey) {
             UITestCase.waitForKey("Start");
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestRedSquareES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestRedSquareES2NEWT.java
index 69879dd..6300bbd 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestRedSquareES2NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestRedSquareES2NEWT.java
@@ -3,14 +3,14 @@
  *
  * 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 JogAmp Community ``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 JogAmp Community OR
@@ -20,12 +20,12 @@
  * 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.
- * 
+ *
  * The views and conclusions contained in the software and documentation are those of the
  * authors and should not be interpreted as representing official policies, either expressed
  * or implied, of JogAmp Community.
  */
- 
+
 package com.jogamp.opengl.test.junit.jogl.demos.es2.newt;
 
 import com.jogamp.newt.event.KeyAdapter;
@@ -35,13 +35,13 @@ import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
 import com.jogamp.opengl.test.junit.util.MiscUtils;
 import com.jogamp.opengl.test.junit.util.UITestCase;
 import com.jogamp.opengl.test.junit.util.QuitAdapter;
-
 import com.jogamp.opengl.util.Animator;
-
 import com.jogamp.opengl.test.junit.jogl.demos.es2.RedSquareES2;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.RedSquareMappedES2;
 
 import javax.media.nativewindow.NativeWindowFactory;
 import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLEventListener;
 import javax.media.opengl.GLProfile;
 
 import org.junit.Assert;
@@ -61,6 +61,7 @@ public class TestRedSquareES2NEWT extends UITestCase {
     static boolean forceGL3 = false;
     static boolean mainRun = false;
     static boolean doRotate = true;
+    static boolean useMappedBuffers = false;
 
     @BeforeClass
     public static void initClass() {
@@ -79,14 +80,22 @@ public class TestRedSquareES2NEWT extends UITestCase {
         glWindow.setTitle(getSimpleTestName("."));
         glWindow.setSize(width, height);
 
-        final RedSquareES2 demo = new RedSquareES2(vsync ? 1 : -1);
-        demo.setDoRotation(doRotate);
+        final GLEventListener demo;
+        if( useMappedBuffers ) {
+            final RedSquareMappedES2 red = new RedSquareMappedES2(vsync ? 1 : -1);
+            red.setDoRotation(doRotate);
+            demo = red;
+        } else {
+            final RedSquareES2 red = new RedSquareES2(vsync ? 1 : -1);
+            red.setDoRotation(doRotate);
+            demo = red;
+        }
         glWindow.addGLEventListener(demo);
 
         final SnapshotGLEventListener snap = new SnapshotGLEventListener();
         snap.setPostSNDetail(demo.getClass().getSimpleName());
         glWindow.addGLEventListener(snap);
-        
+
         Animator animator = new Animator(glWindow);
         QuitAdapter quitAdapter = new QuitAdapter();
 
@@ -99,7 +108,7 @@ public class TestRedSquareES2NEWT extends UITestCase {
             public void keyReleased(KeyEvent e) {
                 if( !e.isPrintableKey() || e.isAutoRepeat() ) {
                     return;
-                }            
+                }
                 if(e.getKeyChar()=='f') {
                     new Thread() {
                         public void run() {
@@ -115,16 +124,16 @@ public class TestRedSquareES2NEWT extends UITestCase {
         });
 
         animator.start();
-        
+
         glWindow.setVisible(true);
 
         System.err.println("NW chosen: "+glWindow.getDelegatedWindow().getChosenCapabilities());
         System.err.println("GL chosen: "+glWindow.getChosenCapabilities());
         System.err.println("window pos/siz: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", "+glWindow.getInsets());
-        
+
         animator.setUpdateFPSFrames(60, System.err);
         snap.setMakeSnapshot();
-        
+
         while(!quitAdapter.shouldQuit() && animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
             Thread.sleep(100);
         }
@@ -157,11 +166,11 @@ public class TestRedSquareES2NEWT extends UITestCase {
             }
         }
     }
-    
+
     @Test
     public void test02GL3() throws InterruptedException {
         if(mainRun) return;
-        
+
         if( !GLProfile.isAvailable(GLProfile.GL3) ) {
             System.err.println("GL3 n/a");
             return;
@@ -169,7 +178,7 @@ public class TestRedSquareES2NEWT extends UITestCase {
         final GLProfile glp = GLProfile.get(GLProfile.GL3);
         final GLCapabilities caps = new GLCapabilities( glp );
         runTestGL(caps);
-    }    
+    }
 
     static long duration = 500; // ms
 
@@ -185,6 +194,8 @@ public class TestRedSquareES2NEWT extends UITestCase {
                 forceGL3 = true;
             } else if(args[i].equals("-norotate")) {
                 doRotate = false;
+            } else if(args[i].equals("-mappedBuffers")) {
+                useMappedBuffers = true;
             } else if(args[i].equals("-loops")) {
                 i++;
                 loops = MiscUtils.atoi(args[i], 1);
@@ -196,6 +207,7 @@ public class TestRedSquareES2NEWT extends UITestCase {
         System.err.println("loop shutdown "+loop_shutdown);
         System.err.println("forceES2 "+forceES2);
         System.err.println("forceGL3 "+forceGL3);
+        System.err.println("mappedBuffers "+useMappedBuffers);
         org.junit.runner.JUnitCore.main(TestRedSquareES2NEWT.class.getName());
     }
 }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/Teapot.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/Teapot.java
index ae5a0b3..dac917e 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/Teapot.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/Teapot.java
@@ -33,7 +33,7 @@ public class Teapot implements GLEventListener {
         gl.glClearColor(0.5f, 0.5f, 0.5f, 0.0f);
 
         try {
-            URLConnection urlConn = IOUtil.getResource("jogl/util/data/av/test-ntsc01-160x90.png", this.getClass().getClassLoader());
+            URLConnection urlConn = IOUtil.getResource("jogl/util/data/av/test-ntsc01-57x32.png", this.getClass().getClassLoader());
             tex = TextureIO.newTexture(gl, TextureIO.newTextureData(gl.getGLProfile(), urlConn.getInputStream(), false, TextureIO.PNG));
         } catch (Exception e) {
             e.printStackTrace();
@@ -121,4 +121,4 @@ public class Teapot implements GLEventListener {
     @Override
     public void dispose(GLAutoDrawable gLDrawable) {
     }
-}
\ No newline at end of file
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/GLSLMiscHelper.java b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/GLSLMiscHelper.java
index 361c291..f55e331 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/GLSLMiscHelper.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/GLSLMiscHelper.java
@@ -145,7 +145,7 @@ public class GLSLMiscHelper {
         Assert.assertTrue(vDataArray.sealed());
         Assert.assertEquals(4, vDataArray.getElementCount());
         Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());        
-        Assert.assertEquals(0, gl.glGetBoundBuffer(GL.GL_ARRAY_BUFFER)); // should be cleared ASAP
+        Assert.assertEquals(0, gl.getBoundBuffer(GL.GL_ARRAY_BUFFER)); // should be cleared ASAP
         validateGLArrayDataServerState(gl, st, vDataArray);
         return vDataArray;
     }
@@ -190,7 +190,7 @@ public class GLSLMiscHelper {
         Assert.assertTrue(cDataArray.isVBOWritten());
         Assert.assertTrue(cDataArray.sealed());
         Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
-        Assert.assertEquals(0, gl.glGetBoundBuffer(GL.GL_ARRAY_BUFFER)); // should be cleared ASAP
+        Assert.assertEquals(0, gl.getBoundBuffer(GL.GL_ARRAY_BUFFER)); // should be cleared ASAP
         validateGLArrayDataServerState(gl, st, cDataArray);
         return cDataArray;
     }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/perf/TestPerf001GLJPanelInit01AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/perf/TestPerf001GLJPanelInit01AWT.java
index 0472fdb..0ca84e4 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/perf/TestPerf001GLJPanelInit01AWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/perf/TestPerf001GLJPanelInit01AWT.java
@@ -61,6 +61,7 @@ import com.jogamp.opengl.util.Animator;
  */
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 public class TestPerf001GLJPanelInit01AWT extends UITestCase {
+    final long INIT_TIMEOUT = 10L*1000L; // 10s
 
     @BeforeClass
     public static void initClass() {
@@ -119,22 +120,26 @@ public class TestPerf001GLJPanelInit01AWT extends UITestCase {
             throwable.printStackTrace();
             Assume.assumeNoException( throwable );
         }
-        while( panelCount > initCount ) {
+        final long t0 = System.currentTimeMillis();
+        long t1 = t0;
+        while( panelCount > initCount && INIT_TIMEOUT > t1 - t0 ) {
             try {
-                Thread.sleep(10);
+                Thread.sleep(100);
+                System.err.println("Sleep initialized: "+initCount+"/"+panelCount);
             } catch (InterruptedException e1) {
                 e1.printStackTrace();
             }
+            t1 = System.currentTimeMillis();
         }
         t[3] = Platform.currentTimeMillis();
-        final double panelCountF = panelCount;
+        final double panelCountF = initCount;
         System.err.printf("P: %d %s:%n\tctor\t%6d/t %6.2f/1%n\tvisible\t%6d/t %6.2f/1%n\tsum-i\t%6d/t %6.2f/1%n",
-                panelCount,
+                initCount,
                 useGLJPanel?"GLJPanel":"GLCanvas",
                 t[1]-t[0], (t[1]-t[0])/panelCountF,
                 t[3]-t[1], (t[3]-t[1])/panelCountF,
                 t[3]-t[0], (t[3]-t[0])/panelCountF);
-        System.err.println("INIT END: "+initCount);
+        System.err.println("INIT END: "+initCount+"/"+panelCount);
         if( wait ) {
             UITestCase.waitForKey("Post-Init");
         }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/perf/TestPerf001GLJPanelInit02AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/perf/TestPerf001GLJPanelInit02AWT.java
index b513af9..2b1dc41 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/perf/TestPerf001GLJPanelInit02AWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/perf/TestPerf001GLJPanelInit02AWT.java
@@ -63,6 +63,7 @@ import com.jogamp.opengl.util.Animator;
  */
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 public class TestPerf001GLJPanelInit02AWT extends UITestCase {
+    final long INIT_TIMEOUT = 10L*1000L; // 10s
 
     @BeforeClass
     public static void initClass() {
@@ -175,23 +176,27 @@ public class TestPerf001GLJPanelInit02AWT extends UITestCase {
             throwable.printStackTrace();
             Assume.assumeNoException( throwable );
         }
-        while( frameCount > initCount ) {
+        final long t0 = System.currentTimeMillis();
+        long t1 = t0;
+        while( frameCount > initCount && INIT_TIMEOUT > t1 - t0 ) {
             try {
-                Thread.sleep(10);
+                Thread.sleep(100);
+                System.err.println("Sleep initialized: "+initCount+"/"+frameCount);
             } catch (InterruptedException e1) {
                 e1.printStackTrace();
             }
+            t1 = System.currentTimeMillis();
         }
         t[3] = Platform.currentTimeMillis();
-        final double panelCountF = frameCount;
+        final double panelCountF = initCount;
         System.err.printf("P: %d %s%s:%n\tctor\t%6d/t %6.2f/1%n\tvisible\t%6d/t %6.2f/1%n\tsum-i\t%6d/t %6.2f/1%n",
-                frameCount,
+                initCount,
                 useGLJPanel?"GLJPanel":(useGLCanvas?"GLCanvas":"No_GL"), initMT?" (mt)":" (01)",
                 t[1]-t[0], (t[1]-t[0])/panelCountF,
                 t[3]-t[1], (t[3]-t[1])/panelCountF,
                 t[3]-t[0], (t[3]-t[0])/panelCountF);
 
-        System.err.println("INIT END: "+initCount);
+        System.err.println("INIT END: "+initCount+"/"+frameCount);
         if( wait ) {
             UITestCase.waitForKey("Post-Init");
         }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/perf/TestPerf001GLWindowInit03NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/perf/TestPerf001GLWindowInit03NEWT.java
index 4915cff..18b3d54 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/perf/TestPerf001GLWindowInit03NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/perf/TestPerf001GLWindowInit03NEWT.java
@@ -53,6 +53,7 @@ import com.jogamp.opengl.test.junit.util.UITestCase;
  */
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 public class TestPerf001GLWindowInit03NEWT extends UITestCase {
+    final long INIT_TIMEOUT = 10L*1000L; // 10s
 
     @BeforeClass
     public static void initClass() {
@@ -108,22 +109,26 @@ public class TestPerf001GLWindowInit03NEWT extends UITestCase {
         }
         t[2] = Platform.currentTimeMillis();
 
-        while( frameCount > initCount ) {
+        final long t0 = System.currentTimeMillis();
+        long t1 = t0;
+        while( frameCount > initCount && INIT_TIMEOUT > t1 - t0 ) {
             try {
-                Thread.sleep(10);
+                Thread.sleep(100);
+                System.err.println("Sleep initialized: "+initCount+"/"+frameCount);
             } catch (InterruptedException e1) {
                 e1.printStackTrace();
             }
+            t1 = System.currentTimeMillis();
         }
         t[3] = Platform.currentTimeMillis();
-        final double panelCountF = frameCount;
+        final double panelCountF = initCount;
         System.err.printf("P: %d GLWindow:%n\tctor\t%6d/t %6.2f/1%n\tvisible\t%6d/t %6.2f/1%n\tsum-i\t%6d/t %6.2f/1%n",
-                frameCount,
+                initCount,
                 t[1]-t[0], (t[1]-t[0])/panelCountF,
                 t[3]-t[1], (t[3]-t[1])/panelCountF,
                 t[3]-t[0], (t[3]-t[0])/panelCountF);
 
-        System.err.println("INIT END: "+initCount);
+        System.err.println("INIT END: "+initCount+"/"+frameCount);
         if( wait ) {
             UITestCase.waitForKey("Post-Init");
         }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/DemoGL2ES1TextureImmModeSink.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/DemoGL2ES1TextureImmModeSink.java
index 3e58d3c..d776021 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/DemoGL2ES1TextureImmModeSink.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/DemoGL2ES1TextureImmModeSink.java
@@ -95,7 +95,7 @@ public class DemoGL2ES1TextureImmModeSink implements GLEventListener, TextureDra
         }
         GL2ES1 gl = FixedFuncUtil.wrapFixedFuncEmul(_gl, ShaderSelectionMode.AUTO, null, forceFFPEmu, verboseFFPEmu);
 
-        URLConnection testTextureUrlConn = IOUtil.getResource("jogl/util/data/av/test-ntsc01-160x90.png", this.getClass().getClassLoader());
+        URLConnection testTextureUrlConn = IOUtil.getResource("jogl/util/data/av/test-ntsc01-57x32.png", this.getClass().getClassLoader());
         try {
             InputStream  testTextureStream = testTextureUrlConn.getInputStream();
             textureData = TextureIO.newTextureData(gl.getGLProfile(), testTextureStream , false /* mipmap */, TextureIO.PNG);
diff --git a/src/newt/classes/jogamp/newt/driver/android/NewtDebugActivity.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/PNGTstFiles.java
similarity index 62%
rename from src/newt/classes/jogamp/newt/driver/android/NewtDebugActivity.java
rename to src/test/com/jogamp/opengl/test/junit/jogl/util/texture/PNGTstFiles.java
index 40a6ec6..0d5d74a 100644
--- a/src/newt/classes/jogamp/newt/driver/android/NewtDebugActivity.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/PNGTstFiles.java
@@ -1,5 +1,5 @@
 /**
- * Copyright 2013 JogAmp Community. All rights reserved.
+ * Copyright 2014 JogAmp Community. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without modification, are
  * permitted provided that the following conditions are met:
@@ -25,14 +25,30 @@
  * authors and should not be interpreted as representing official policies, either expressed
  * or implied, of JogAmp Community.
  */
-package jogamp.newt.driver.android;
+package com.jogamp.opengl.test.junit.jogl.util.texture;
 
-import android.os.Bundle;
-
-public class NewtDebugActivity extends NewtVersionBaseActivity {
-
-   @Override
-   public void onCreate(Bundle savedInstanceState) {
-       super.onCreate("NewtDebugActivity - DEBUG MODE", savedInstanceState);
-   }
+public class PNGTstFiles {
+    static public final String[] allBasenames = {
+        "test-ntscN_3-01-160x90",
+        "test-ntscN_4-01-160x90",
+        "test-ntscNG4-01-160x90",
+        "test-ntscI_3-01-160x90",
+        "test-ntscI_4-01-160x90",
+        "test-ntscIG3-01-160x90",
+        "test-ntscIG4-01-160x90",
+        "test-ntscP_3-01-160x90",
+        "test-ntscP_4-01-160x90",
+        "grayscale_texture",
+        "bug724-transparent-grey_orig",
+        "bug724-transparent-grey_gimpexp",
+        "cross-grey-alpha-16x16",
+        "pointer-grey-alpha-16x24",
+    };
+    static public final String[] greyBasenames = {
+        "grayscale_texture",
+        "bug724-transparent-grey_orig",
+        "bug724-transparent-grey_gimpexp",
+        "cross-grey-alpha-16x16",
+        "pointer-grey-alpha-16x24",
+    };
 }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestBug362DDSImageCreateFromData.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestBug362DDSImageCreateFromData.java
new file mode 100644
index 0000000..4212aba
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestBug362DDSImageCreateFromData.java
@@ -0,0 +1,98 @@
+package com.jogamp.opengl.test.junit.jogl.util.texture;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.nio.ByteBuffer;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.jogamp.common.util.IOUtil;
+import com.jogamp.opengl.util.texture.spi.DDSImage;
+import com.jogamp.opengl.util.texture.spi.DDSImage.ImageInfo;
+
+/**
+ * This test uses the DDSImage class to read a dds image from file, extract the data, 
+ * and use the class to create a new DDSImage from the extracted data
+ * <br></br>
+ * Bug Reference: https://jogamp.org/bugzilla/show_bug.cgi?id=362
+ * <br></br>
+ * The bug pertains to incorrect size calculation for checking validity of data. Compressed DXT1 has min of 8 bytes, DXT5 has min of 16 bytes. 
+ * It exists in {@link DDSImage#createFromData(int, int, int, ByteBuffer[])} 
+ * where an {@link IllegalArgumentException} is thrown for Mipmap level size mismatch.
+ * <br></br>
+ * <ul>The following cases are tested:
+ * <li>Uncompressed 64x32 RGB DDS Image with all mipmap levels (64x32 --> 1x1)</li>
+ * <li>DXT1 compressed 64x32 RGB DDS Image with all mipmap levels (64x32 --> 1x1)</li>
+ * <li>DXT5 compressed 64x32 RGB DDS Image with all mipmap levels (64x32 --> 1x1)</li>
+ * </ul>
+ * 
+ * @author Michael Esemplare
+ *
+ */
+public class TestBug362DDSImageCreateFromData {
+	
+	File testDDSImage01Uncompressed;
+	File testDDSImage02DXT1;
+	File testDDSImage03DXT5;
+	
+	@Before
+    public void setup() throws Throwable {
+		testDDSImage01Uncompressed = initFile("test-64x32_uncompressed.dds");
+		testDDSImage02DXT1 = initFile("test-64x32_DXT1.dds");
+		testDDSImage03DXT5 = initFile("test-64x32_DXT5.dds");
+    }
+	
+    @After
+    public void teardown() {
+    	testDDSImage01Uncompressed = null;
+		testDDSImage02DXT1 = null;
+		testDDSImage03DXT5 = null;
+    }
+    
+    private File initFile(String filename) throws URISyntaxException {
+    	URLConnection connection = IOUtil.getResource(getClass(), filename);
+    	Assert.assertNotNull(connection);
+    	URL url = connection.getURL();
+    	File file = new File(url.toURI());
+    	Assert.assertTrue(file.exists());
+    	return file;
+    }
+    
+    private void testImpl(File file) throws IOException {
+    	DDSImage ddsImage = DDSImage.read(file);
+    	Assert.assertNotNull(ddsImage);
+    	int numMipMaps = ddsImage.getNumMipMaps();
+		ByteBuffer[] mipMapArray = new ByteBuffer[numMipMaps];
+		for (int i=0;i<numMipMaps;i++){
+			ImageInfo info = ddsImage.getMipMap(i);
+			mipMapArray[i] = info.getData();
+		}
+		DDSImage newImage = DDSImage.createFromData(ddsImage.getPixelFormat(), ddsImage.getWidth(), ddsImage.getHeight(), mipMapArray);
+		Assert.assertNotNull(newImage);
+    }
+    
+    @Test
+    public void test00_DDSImage_CreateFromData_Uncompressed_RGB () throws IOException {
+    	testImpl(testDDSImage01Uncompressed);
+    }
+    
+    @Test
+    public void test01_DDSImage_CreateFromData_DXT1_RGB () throws IOException {
+    	testImpl(testDDSImage02DXT1);
+    }
+    
+    @Test
+    public void test02_DDSImage_CreateFromData_DXT5_RGB () throws IOException {
+    	testImpl(testDDSImage03DXT5);
+    }
+    
+	public static void main(String[] args) {
+		org.junit.runner.JUnitCore.main(TestBug362DDSImageCreateFromData.class.getName());
+	}
+}
\ No newline at end of file
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGImage00NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGImage00NEWT.java
deleted file mode 100644
index f4b3cab..0000000
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGImage00NEWT.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/**
- * Copyright 2010 JogAmp Community. 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 JogAmp Community ``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 JogAmp Community OR
- * 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.
- * 
- * The views and conclusions contained in the software and documentation are those of the
- * authors and should not be interpreted as representing official policies, either expressed
- * or implied, of JogAmp Community.
- */
-package com.jogamp.opengl.test.junit.jogl.util.texture;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URLConnection;
-
-import org.junit.Assert;
-import org.junit.Test;
-import org.junit.FixMethodOrder;
-import org.junit.runners.MethodSorters;
-
-import com.jogamp.common.util.IOUtil;
-import com.jogamp.opengl.test.junit.util.UITestCase;
-import com.jogamp.opengl.util.texture.spi.PNGImage;
-
- at FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class TestPNGImage00NEWT extends UITestCase {
-    @Test
-    public void testPNGReadWriteAndCompare() throws InterruptedException, IOException, MalformedURLException {
-        final File out1_f=new File(getSimpleTestName(".")+"-PNGImageTest1.png");
-        final File out2_f=new File(getSimpleTestName(".")+"-PNGImageTest2.png");
-        final File out2F_f=new File(getSimpleTestName(".")+"-PNGImageTest2Flipped.png");
-        final File out2R_f=new File(getSimpleTestName(".")+"-PNGImageTest2Reversed.png");
-        final File out2RF_f=new File(getSimpleTestName(".")+"-PNGImageTest2ReversedFlipped.png");
-        final String url_s="jogl/util/data/av/test-ntsc01-160x90.png";
-        URLConnection urlConn = IOUtil.getResource(url_s, this.getClass().getClassLoader());
-        PNGImage image1 = PNGImage.read(urlConn.getInputStream());
-        System.err.println("PNGImage - Orig: "+image1);        
-        image1.write(out1_f, true); 
-        {
-            Assert.assertEquals(image1.getData(), PNGImage.read(out1_f.toURI().toURL().openStream()).getData());
-        }
-        
-        final PNGImage image2 = PNGImage.createFromData(image1.getWidth(), image1.getHeight(), 
-                                                        image1.getDpi()[0], image1.getDpi()[1], 
-                                                        image1.getBytesPerPixel(), false /* reverseChannels */, image1.isGLOriented(), image1.getData());
-        image2.write(out2_f, true);
-        {
-            Assert.assertEquals(image1.getData(), PNGImage.read(out2_f.toURI().toURL().openStream()).getData());
-        }
-        
-        // flipped
-        final PNGImage image2F = PNGImage.createFromData(image1.getWidth(), image1.getHeight(), 
-                                                         image1.getDpi()[0], image1.getDpi()[1], 
-                                                         image1.getBytesPerPixel(), false /* reverseChannels */, !image1.isGLOriented(), image1.getData());
-        image2F.write(out2F_f, true);
-        
-        // reversed channels
-        final PNGImage image2R = PNGImage.createFromData(image1.getWidth(), image1.getHeight(), 
-                                                         image1.getDpi()[0], image1.getDpi()[1], 
-                                                         image1.getBytesPerPixel(), true /* reverseChannels */, image1.isGLOriented(), image1.getData());
-        image2R.write(out2R_f, true);
-        
-        // reversed channels and flipped
-        final PNGImage image2RF = PNGImage.createFromData(image1.getWidth(), image1.getHeight(), 
-                                                         image1.getDpi()[0], image1.getDpi()[1], 
-                                                         image1.getBytesPerPixel(), true /* reverseChannels */, !image1.isGLOriented(), image1.getData());
-        image2RF.write(out2RF_f, true);
-    }
-    
-    public static void main(String args[]) {
-        org.junit.runner.JUnitCore.main(TestPNGImage00NEWT.class.getName());
-    }
-}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGPixelRect00NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGPixelRect00NEWT.java
new file mode 100644
index 0000000..c2b39f0
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGPixelRect00NEWT.java
@@ -0,0 +1,226 @@
+/**
+ * Copyright 2014 JogAmp Community. 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 JogAmp Community ``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 JogAmp Community OR
+ * 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package com.jogamp.opengl.test.junit.jogl.util.texture;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.URLConnection;
+
+import javax.media.nativewindow.util.PixelFormat;
+import javax.media.nativewindow.util.PixelFormatUtil;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.FixMethodOrder;
+import org.junit.runners.MethodSorters;
+
+import com.jogamp.common.util.IOUtil;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.util.PNGPixelRect;
+
+ at FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class TestPNGPixelRect00NEWT extends UITestCase {
+    @Test
+    public void testPNGRead01_All() throws InterruptedException, IOException, MalformedURLException {
+        for(int i=0; i<PNGTstFiles.allBasenames.length; i++) {
+            final String basename = PNGTstFiles.allBasenames[i];
+            final String pathname="";
+            testPNG01Impl(pathname, basename, null, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+        }
+    }
+
+    @Test
+    public void testPNGRead02_RGB888_to_RGBA8888() throws InterruptedException, IOException, MalformedURLException {
+        final String basename ="test-ntscN_3-01-160x90";
+        final String pathname="";
+        testPNG01Impl(pathname, basename, PixelFormat.RGBA8888, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+    }
+
+    @Test
+    public void testPNGRead03_RGB888_to_RGBA8888_stride1000() throws InterruptedException, IOException, MalformedURLException {
+        final String basename ="test-ntscN_3-01-160x90"; // 640 bytes = 4 * 160
+        final String pathname="";
+        testPNG01Impl(pathname, basename, PixelFormat.RGBA8888, 1000 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+    }
+
+    @Test
+    public void testPNGRead04_RGB888_to_RGBA8888_stride999() throws InterruptedException, IOException, MalformedURLException {
+        final String basename ="test-ntscN_3-01-160x90"; // 640 bytes = 4 * 160
+        final String pathname="";
+        testPNG01Impl(pathname, basename, PixelFormat.RGBA8888, 999 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+    }
+
+    @Test
+    public void testPNGRead11_RGBA8888_to_LUMINA() throws InterruptedException, IOException, MalformedURLException {
+        final String basename ="test-ntscN_4-01-160x90";
+        final String pathname="";
+        testPNG02Impl(pathname, basename, PixelFormat.LUMINANCE, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+    }
+
+    @Test
+    public void testPNGRead12_RGBA8888_to_RGB888() throws InterruptedException, IOException, MalformedURLException {
+        final String basename ="test-ntscN_4-01-160x90";
+        final String pathname="";
+        testPNG02Impl(pathname, basename, PixelFormat.RGB888, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+    }
+
+    @Test
+    public void testPNGRead13_RGBA8888_to_BGR888() throws InterruptedException, IOException, MalformedURLException {
+        final String basename ="test-ntscN_4-01-160x90";
+        final String pathname="";
+        testPNG02Impl(pathname, basename, PixelFormat.BGR888, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+    }
+
+    @Test
+    public void testPNGRead14_RGBA8888_to_BGRA8888() throws InterruptedException, IOException, MalformedURLException {
+        final String basename ="test-ntscN_4-01-160x90";
+        final String pathname="";
+        testPNG02Impl(pathname, basename, PixelFormat.BGRA8888, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+    }
+    @Test
+    public void testPNGRead15_RGBA8888_to_ARGB8888() throws InterruptedException, IOException, MalformedURLException {
+        final String basename ="test-ntscN_4-01-160x90";
+        final String pathname="";
+        testPNG02Impl(pathname, basename, PixelFormat.ARGB8888, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+    }
+    @Test
+    public void testPNGRead16_RGBA8888_to_ABGR8888() throws InterruptedException, IOException, MalformedURLException {
+        final String basename ="test-ntscN_4-01-160x90";
+        final String pathname="";
+        testPNG02Impl(pathname, basename, PixelFormat.ABGR8888, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+    }
+
+    private void testPNG01Impl(final String pathname, final String basename,
+                             final PixelFormat destFmt, final int destMinStrideInBytes, final boolean destIsGLOriented)
+            throws InterruptedException, IOException, MalformedURLException
+    {
+        System.err.println("Test01: "+pathname+basename+".png, destFmt "+destFmt+", destMinStrideInBytes "+destMinStrideInBytes+", destIsGLOriented "+destIsGLOriented);
+
+        final File out1_f=new File(getSimpleTestName(".")+"-01-"+basename+"-orig.png");
+        final File out2F_f=new File(getSimpleTestName(".")+"-02-"+basename+"-flipped.png");
+        final File out2R_f=new File(getSimpleTestName(".")+"-03-"+basename+"-reversed.png");
+        final File out2RF_f=new File(getSimpleTestName(".")+"-04-"+basename+"-reversed_flipped.png");
+        URLConnection urlConn = IOUtil.getResource(this.getClass(), pathname+basename+".png");
+        if( null == urlConn ) {
+            throw new IOException("Cannot find "+pathname+basename+".png");
+        }
+        final PNGPixelRect image1 = PNGPixelRect.read(urlConn.getInputStream(), destFmt, false /* directBuffer */, destMinStrideInBytes, destIsGLOriented);
+        System.err.println("PNGPixelRect - Orig: "+image1);
+        {
+            final OutputStream outs = new BufferedOutputStream(IOUtil.getFileOutputStream(out1_f, true /* allowOverwrite */));
+            image1.write(outs, true /* close */);
+            {
+                final PNGPixelRect image1_R = PNGPixelRect.read(out1_f.toURI().toURL().openStream(), image1.getPixelformat(), false /* directBuffer */, destMinStrideInBytes, destIsGLOriented);
+                System.err.println("PNGPixelRect - Orig (Read Back): "+image1_R);
+                Assert.assertEquals(image1.getPixels(), image1_R.getPixels());
+            }
+        }
+
+        //
+        // Flipped Orientation
+        //
+        {
+            final PNGPixelRect image2F = new PNGPixelRect(image1.getPixelformat(), image1.getSize(),
+                                                          image1.getStride(), !image1.isGLOriented(), image1.getPixels(),
+                                                          image1.getDpi()[0], image1.getDpi()[1]);
+            System.err.println("PNGPixelRect - Flip : "+image2F);
+            final OutputStream outs = new BufferedOutputStream(IOUtil.getFileOutputStream(out2F_f, true /* allowOverwrite */));
+            image2F.write(outs, true /* close */);
+            {
+                // flip again .. to compare w/ original
+                final PNGPixelRect image2F_R = PNGPixelRect.read(out2F_f.toURI().toURL().openStream(), image1.getPixelformat(), false /* directBuffer */, destMinStrideInBytes, !destIsGLOriented);
+                System.err.println("PNGPixelRect - Flip (Read Back): "+image2F_R);
+                Assert.assertEquals(image1.getPixels(), image2F_R.getPixels());
+            }
+        }
+
+        //
+        // Reversed Components
+        //
+        final PixelFormat revFmt = PixelFormatUtil.getReversed(image1.getPixelformat());
+        {
+            final PNGPixelRect image2R = new PNGPixelRect(revFmt, image1.getSize(),
+                                                          image1.getStride(), image1.isGLOriented(), image1.getPixels(),
+                                                          image1.getDpi()[0], image1.getDpi()[1]);
+            System.err.println("PNGPixelRect - Reversed : "+image2R);
+            final OutputStream outs = new BufferedOutputStream(IOUtil.getFileOutputStream(out2R_f, true /* allowOverwrite */));
+            image2R.write(outs, true /* close */);
+            {
+                // reverse again .. to compare w/ original
+                final PNGPixelRect image2R_R = PNGPixelRect.read(out2R_f.toURI().toURL().openStream(), revFmt, false /* directBuffer */, destMinStrideInBytes, destIsGLOriented);
+                System.err.println("PNGPixelRect - Reversed (Read Back): "+image2R_R);
+                Assert.assertEquals(image1.getPixels(), image2R_R.getPixels());
+            }
+        }
+
+        // reversed channels and flipped
+        {
+            final PNGPixelRect image2RF = new PNGPixelRect(revFmt, image1.getSize(),
+                                                           image1.getStride(), !image1.isGLOriented(), image1.getPixels(),
+                                                           image1.getDpi()[0], image1.getDpi()[1]);
+            System.err.println("PNGPixelRect - Reversed+Flipped : "+image2RF);
+            final OutputStream outs = new BufferedOutputStream(IOUtil.getFileOutputStream(out2RF_f, true /* allowOverwrite */));
+            image2RF.write(outs, true /* close */);
+            {
+                // reverse+flip again .. to compare w/ original
+                final PNGPixelRect image2RF_R = PNGPixelRect.read(out2RF_f.toURI().toURL().openStream(), revFmt, false /* directBuffer */, destMinStrideInBytes, !destIsGLOriented);
+                System.err.println("PNGPixelRect - Reversed+FLipped (Read Back): "+image2RF_R);
+                Assert.assertEquals(image1.getPixels(), image2RF_R.getPixels());
+            }
+        }
+    }
+
+    private void testPNG02Impl(final String pathname, final String basename,
+                             final PixelFormat destFmt, final int destMinStrideInBytes, final boolean destIsGLOriented)
+            throws InterruptedException, IOException, MalformedURLException
+    {
+        System.err.println("Test02: "+pathname+basename+".png, destFmt "+destFmt+", destMinStrideInBytes "+destMinStrideInBytes+", destIsGLOriented "+destIsGLOriented);
+
+        final File out1_f=new File(getSimpleTestName(".")+"-"+basename+"-orig.png");
+        URLConnection urlConn = IOUtil.getResource(this.getClass(), pathname+basename+".png");
+
+        final PNGPixelRect image1 = PNGPixelRect.read(urlConn.getInputStream(), destFmt, false /* directBuffer */, destMinStrideInBytes, destIsGLOriented);
+        System.err.println("PNGPixelRect - Orig: "+image1);
+        {
+            final OutputStream outs = new BufferedOutputStream(IOUtil.getFileOutputStream(out1_f, true /* allowOverwrite */));
+            image1.write(outs, true /* close */);
+            {
+                final PNGPixelRect image1_R = PNGPixelRect.read(out1_f.toURI().toURL().openStream(), image1.getPixelformat(), false /* directBuffer */, destMinStrideInBytes, destIsGLOriented);
+                System.err.println("PNGPixelRect - Orig (Read Back): "+image1_R);
+                Assert.assertEquals(image1.getPixels(), image1_R.getPixels());
+            }
+        }
+    }
+
+    public static void main(String args[]) {
+        org.junit.runner.JUnitCore.main(TestPNGPixelRect00NEWT.class.getName());
+    }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGImage01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGPixelRect01NEWT.java
similarity index 69%
rename from src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGImage01NEWT.java
rename to src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGPixelRect01NEWT.java
index 29e0419..3b1d9fb 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGImage01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGPixelRect01NEWT.java
@@ -3,14 +3,14 @@
  *
  * 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 JogAmp Community ``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 JogAmp Community OR
@@ -20,7 +20,7 @@
  * 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.
- * 
+ *
  * The views and conclusions contained in the software and documentation are those of the
  * authors and should not be interpreted as representing official policies, either expressed
  * or implied, of JogAmp Community.
@@ -32,6 +32,7 @@ import java.io.InputStream;
 import java.net.MalformedURLException;
 import java.net.URLConnection;
 
+import javax.media.nativewindow.util.PixelFormat;
 import javax.media.opengl.GL;
 import javax.media.opengl.GLAutoDrawable;
 import javax.media.opengl.GLCapabilities;
@@ -52,10 +53,10 @@ import com.jogamp.opengl.test.junit.util.QuitAdapter;
 import com.jogamp.opengl.test.junit.util.UITestCase;
 import com.jogamp.opengl.util.Animator;
 import com.jogamp.opengl.util.GLReadBufferUtil;
+import com.jogamp.opengl.util.PNGPixelRect;
 import com.jogamp.opengl.util.GLPixelBuffer.GLPixelAttributes;
 import com.jogamp.opengl.util.texture.TextureData;
 import com.jogamp.opengl.util.texture.TextureIO;
-import com.jogamp.opengl.util.texture.spi.PNGImage;
 
 /**
  * Test reading and displaying a PNG image.
@@ -64,71 +65,71 @@ import com.jogamp.opengl.util.texture.spi.PNGImage;
  * </p>
  */
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class TestPNGImage01NEWT extends UITestCase {
-    
+public class TestPNGPixelRect01NEWT extends UITestCase {
     static boolean showFPS = false;
     static long duration = 200; // ms
-    
-    public void testImpl(final InputStream istream) throws InterruptedException, IOException {        
-        final PNGImage image = PNGImage.read(istream);
+
+    public void testImpl(final int num, final String basename, final InputStream istream, final PixelFormat destFmt) throws InterruptedException, IOException {
+        final GLProfile glp = GLProfile.getGL2ES2();
+        final PNGPixelRect image = PNGPixelRect.read(istream, destFmt, true /* directBuffer */, 0 /* destMinStrideInBytes */, true /* destIsGLOriented */);
         Assert.assertNotNull(image);
-        final boolean hasAlpha = 4 == image.getBytesPerPixel();        
-        System.err.println("PNGImage: "+image);
-        
+        final GLPixelAttributes glpa = GLPixelAttributes.convert(image.getPixelformat(), glp);
+        final boolean hasAlpha = 4 == glpa.bytesPerPixel;
+        System.err.println("PNGPixelRect: "+basename+", "+image+", glpa "+glpa);
+
         final GLReadBufferUtil screenshot = new GLReadBufferUtil(true, false);
-        final GLProfile glp = GLProfile.getGL2ES2();
         final GLCapabilities caps = new GLCapabilities(glp);
         if( hasAlpha  ) {
             caps.setAlphaBits(1);
         }
-        
+
         final int internalFormat;
         if(glp.isGL2ES3()) {
             internalFormat = hasAlpha ? GL.GL_RGBA8 : GL.GL_RGB8;
         } else {
             internalFormat = hasAlpha ? GL.GL_RGBA : GL.GL_RGB;
-        }        
+        }
         final TextureData texData = new TextureData(glp, internalFormat,
-                                       image.getWidth(),
-                                       image.getHeight(),
+                                       image.getSize().getWidth(),
+                                       image.getSize().getHeight(),
                                        0,
-                                       new GLPixelAttributes(image.getGLFormat(), image.getGLType()),
+                                       glpa,
                                        false /* mipmap */,
                                        false /* compressed */,
                                        false /* must flip-vert */,
-                                       image.getData(),
+                                       image.getPixels(),
                                        null);
-        
+
         // final TextureData texData = TextureIO.newTextureData(glp, istream, false /* mipmap */, TextureIO.PNG);
-        System.err.println("TextureData: "+texData);        
-        
+        System.err.println("TextureData: "+texData);
+
         final GLWindow glad = GLWindow.create(caps);
-        glad.setTitle("TestPNGImage01NEWT");
+        glad.setTitle(this.getSimpleTestName("."));
         // Size OpenGL to Video Surface
         glad.setSize(texData.getWidth(), texData.getHeight());
-        
+
         // load texture from file inside current GL context to match the way
         // the bug submitter was doing it
         final TextureDraw01ES2Listener gle = new TextureDraw01ES2Listener( texData, 0 ) ;
         // gle.setClearColor(new float[] { 1.0f, 0.0f, 0.0f, 1.0f } );
 
         glad.addGLEventListener(gle);
-        glad.addGLEventListener(new GLEventListener() {                    
+        glad.addGLEventListener(new GLEventListener() {
             boolean shot = false;
-            
+
             @Override public void init(GLAutoDrawable drawable) {
                 System.err.println("Chosen Caps: " + drawable.getChosenGLCapabilities());
                 System.err.println("GL ctx: " + drawable.getGL().getContext());
             }
-            
+
             @Override public void display(GLAutoDrawable drawable) {
                 // 1 snapshot
                 if(null!=((TextureDraw01Accessor)gle).getTexture() && !shot) {
                     shot = true;
-                    snapshot(0, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
+                    snapshot(num, basename, drawable.getGL(), screenshot, TextureIO.PNG, null);
                 }
             }
-            
+
             @Override public void dispose(GLAutoDrawable drawable) { }
             @Override public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
         });
@@ -144,28 +145,52 @@ public class TestPNGImage01NEWT extends UITestCase {
         while(!quitAdapter.shouldQuit() && animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
             Thread.sleep(100);
         }
-        
+
         animator.stop();
         glad.destroy();
     }
-    
+
     @Test
-    public void testRead01_RGBn_exp() throws InterruptedException, IOException, MalformedURLException {
-        final String fname = null == _fname ? "bug724-transparent-grey_gimpexp.png" : _fname;
-        final URLConnection urlConn = IOUtil.getResource(this.getClass(), fname);
-        testImpl(urlConn.getInputStream());
+    public void testRead00_Manual() throws InterruptedException, IOException, MalformedURLException {
+        if( null == _fname ) {
+            return;
+        }
+        final URLConnection urlConn = IOUtil.getResource(this.getClass(), _fname);
+        if( null == urlConn ) {
+            throw new IOException("Cannot find "+_fname+".png");
+        }
+        testImpl(0, _fname, urlConn.getInputStream(), null);
     }
 
     @Test
-    public void testRead02_RGBn_orig() throws InterruptedException, IOException, MalformedURLException {
+    public void testRead01_All() throws InterruptedException, IOException, MalformedURLException {
         if( null != _fname ) {
             return;
         }
-        final String fname = "bug724-transparent-grey_orig.png";
-        final URLConnection urlConn = IOUtil.getResource(this.getClass(), fname);
-        testImpl(urlConn.getInputStream());
+        for(int i=0; i<PNGTstFiles.allBasenames.length; i++) {
+            final String basename = PNGTstFiles.allBasenames[i];
+            final URLConnection urlConn = IOUtil.getResource(this.getClass(), basename+".png");
+            if( null == urlConn ) {
+                throw new IOException("Cannot find "+basename+".png");
+            }
+            testImpl(i, basename, urlConn.getInputStream(), null);
+        }
     }
-    
+    @Test
+    public void testRead02_Gray2RGBA() throws InterruptedException, IOException, MalformedURLException {
+        if( null != _fname ) {
+            return;
+        }
+        for(int i=0; i<PNGTstFiles.greyBasenames.length; i++) {
+            final String basename = PNGTstFiles.greyBasenames[i];
+            final URLConnection urlConn = IOUtil.getResource(this.getClass(), basename+".png");
+            if( null == urlConn ) {
+                throw new IOException("Cannot find "+basename+".png");
+            }
+            testImpl(i, basename, urlConn.getInputStream(), PixelFormat.RGBA8888);
+        }
+    }
+
     static String _fname = null;
     public static void main(String args[]) {
         for(int i=0; i<args.length; i++) {
@@ -177,6 +202,6 @@ public class TestPNGImage01NEWT extends UITestCase {
                 _fname = args[i];
             }
         }
-        org.junit.runner.JUnitCore.main(TestPNGImage01NEWT.class.getName());
+        org.junit.runner.JUnitCore.main(TestPNGPixelRect01NEWT.class.getName());
     }
 }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPixelFormatUtil00NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPixelFormatUtil00NEWT.java
new file mode 100644
index 0000000..bfcf9c2
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPixelFormatUtil00NEWT.java
@@ -0,0 +1,364 @@
+/**
+ * Copyright 2014 JogAmp Community. 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 JogAmp Community ``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 JogAmp Community OR
+ * 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package com.jogamp.opengl.test.junit.jogl.util.texture;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+import javax.media.nativewindow.util.Dimension;
+import javax.media.nativewindow.util.PixelFormat;
+import javax.media.nativewindow.util.PixelFormatUtil;
+import javax.media.nativewindow.util.PixelRectangle;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.FixMethodOrder;
+import org.junit.runners.MethodSorters;
+
+import com.jogamp.opengl.test.junit.util.UITestCase;
+
+/**
+ * Testing PixelFormatUtil's Conversion using synthetic test data
+ * including strides, endian-order and all PixelFormat conversions.
+ */
+ at FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class TestPixelFormatUtil00NEWT extends UITestCase {
+    @Test
+    public void testConversion01_srcS000_BE_TL_destS000_TL() throws InterruptedException, IOException, MalformedURLException {
+        testPNG00Impl(0 /* srcMinStrideInBytes */, ByteOrder.BIG_ENDIAN, false /* srcIsGLOriented */,
+                      0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+    }
+    @Test
+    public void testConversion02_srcS000_LE_TL_destS000_TL() throws InterruptedException, IOException, MalformedURLException {
+        testPNG00Impl(0 /* srcMinStrideInBytes */, ByteOrder.LITTLE_ENDIAN, false /* srcIsGLOriented */,
+                      0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+    }
+    @Test
+    public void testConversion03_srcS000_BE_TL_destS259_TL() throws InterruptedException, IOException, MalformedURLException {
+        testPNG00Impl(0 /* srcMinStrideInBytes */, ByteOrder.BIG_ENDIAN, false /* srcIsGLOriented */,
+                      259 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+    }
+    @Test
+    public void testConversion04_srcS259_BE_TL_destS259_TL() throws InterruptedException, IOException, MalformedURLException {
+        testPNG00Impl(259 /* srcMinStrideInBytes */, ByteOrder.BIG_ENDIAN, false /* srcIsGLOriented */,
+                      259 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+    }
+    @Test
+    public void testConversion05_srcS301_BE_TL_destS259_TL() throws InterruptedException, IOException, MalformedURLException {
+        testPNG00Impl(301 /* srcMinStrideInBytes */, ByteOrder.BIG_ENDIAN, false /* srcIsGLOriented */,
+                      259 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+    }
+
+    static final byte red___val = (byte)0x01;
+    static final byte green_val = (byte)0x02;
+    static final byte blue__val = (byte)0x03;
+    static final byte alpha_val = (byte)0x04;
+    static final byte undef_val = (byte)0xff;
+
+    static final void getComponents(final int srcComps, final PixelFormat fmt, final byte[] components) {
+        final byte b1, b2, b3, b4;
+        if( 1 == srcComps ) {
+            // LUM -> Fmt Conversion
+            switch(fmt) {
+                case LUMINANCE:
+                    b1 = red___val;
+                    b2 = undef_val;
+                    b3 = undef_val;
+                    b4 = undef_val;
+                    break;
+                case RGB888:
+                    b1 = red___val;
+                    b2 = red___val;
+                    b3 = red___val;
+                    b4 = undef_val;
+                    break;
+                case BGR888:
+                    b1 = red___val;
+                    b2 = red___val;
+                    b3 = red___val;
+                    b4 = undef_val;
+                    break;
+                case RGBA8888:
+                    b1 = red___val;
+                    b2 = red___val;
+                    b3 = red___val;
+                    b4 = undef_val;
+                    break;
+                case ABGR8888:
+                    b1 = undef_val;
+                    b2 = red___val;
+                    b3 = red___val;
+                    b4 = red___val;
+                    break;
+                case BGRA8888:
+                    b1 = red___val;
+                    b2 = red___val;
+                    b3 = red___val;
+                    b4 = undef_val;
+                    break;
+                case ARGB8888:
+                    b1 = undef_val;
+                    b2 = red___val;
+                    b3 = red___val;
+                    b4 = red___val;
+                    break;
+                default:
+                    throw new InternalError("Unhandled format "+fmt);
+            }
+        } else {
+            // 1:1 values
+            switch(fmt) {
+                case LUMINANCE:
+                    if( srcComps > 1 ) {
+                        b1 = ( red___val + green_val+ blue__val ) / 3;
+                        b2 = undef_val;
+                        b3 = undef_val;
+                        b4 = undef_val;
+                    } else {
+                        b1 = red___val;
+                        b2 = undef_val;
+                        b3 = undef_val;
+                        b4 = undef_val;
+                    }
+                    break;
+                case RGB888:
+                    b1 = red___val;
+                    b2 = green_val;
+                    b3 = blue__val;
+                    b4 = undef_val;
+                    break;
+                case BGR888:
+                    b1 = blue__val;
+                    b2 = green_val;
+                    b3 = red___val;
+                    b4 = undef_val;
+                    break;
+                case RGBA8888:
+                    b1 = red___val;
+                    b2 = green_val;
+                    b3 = blue__val;
+                    b4 = srcComps > 3 ? alpha_val : undef_val;
+                    break;
+                case ABGR8888:
+                    b1 = srcComps > 3 ? alpha_val : undef_val;
+                    b2 = blue__val;
+                    b3 = green_val;
+                    b4 = red___val;
+                    break;
+                case BGRA8888:
+                    b1 = blue__val;
+                    b2 = green_val;
+                    b3 = red___val;
+                    b4 = srcComps > 3 ? alpha_val : undef_val;
+                    break;
+                case ARGB8888:
+                    b1 = srcComps > 3 ? alpha_val : undef_val;
+                    b2 = red___val;
+                    b3 = green_val;
+                    b4 = blue__val;
+                    break;
+                default:
+                    throw new InternalError("Unhandled format "+fmt);
+            }
+        }
+        components[0] = b1;
+        components[1] = b2;
+        components[2] = b3;
+        components[3] = b4;
+    }
+    private void testPNG00Impl(final int srcMinStrideInBytes, final ByteOrder srcByteOrder, final boolean srcIsGLOriented,
+                               final int destMinStrideInBytes, final boolean destIsGLOriented)
+            throws InterruptedException, IOException, MalformedURLException
+    {
+        System.err.println("Test00: srcMinStrideInBytes "+srcMinStrideInBytes+", srcByteOrder "+srcByteOrder+", srcIsGLOriented "+srcIsGLOriented+
+                           ", destMinStrideInBytes "+destMinStrideInBytes+", destIsGLOriented "+destIsGLOriented);
+
+        final PixelFormat[] formats = PixelFormat.values();
+        final int width  = 64, height = 64;
+
+        for(int i=0; i<formats.length; i++) {
+            final PixelFormat srcFmt = formats[i];
+            final int srcBpp = srcFmt.bytesPerPixel();
+            final int srcStrideBytes = Math.max(srcMinStrideInBytes, width*srcBpp);
+            final ByteBuffer srcPixels = ByteBuffer.allocate(height*srcStrideBytes).order(srcByteOrder);
+            final byte[] srcComponents = new byte[4];
+            getComponents(srcFmt.componentCount, srcFmt, srcComponents);
+            for(int y=0; y<height; y++) {
+                int o = y*srcStrideBytes;
+                for(int x=0; x<width; x++) {
+                    switch(srcFmt) {
+                        case LUMINANCE:
+                            srcPixels.put(o++, srcComponents[0]);
+                            break;
+                        case RGB888:
+                        case BGR888:
+                            srcPixels.put(o++, srcComponents[0]);
+                            srcPixels.put(o++, srcComponents[1]);
+                            srcPixels.put(o++, srcComponents[2]);
+                            break;
+                        case RGBA8888:
+                        case ABGR8888:
+                        case BGRA8888:
+                        case ARGB8888:
+                            srcPixels.put(o++, srcComponents[0]);
+                            srcPixels.put(o++, srcComponents[1]);
+                            srcPixels.put(o++, srcComponents[2]);
+                            srcPixels.put(o++, srcComponents[3]);
+                            break;
+                        default:
+                            throw new InternalError("Unhandled format "+srcFmt);
+                    }
+                }
+            }
+            final PixelRectangle imageSrc = new PixelRectangle.GenericPixelRect(srcFmt, new Dimension(width, height), srcStrideBytes, srcIsGLOriented, srcPixels);
+            System.err.println("CONVERT["+i+"][*]: Image0 - Orig: "+imageSrc);
+            testComponents(imageSrc, 0, 0, srcComponents);
+            testComponents(imageSrc, width-1, height-1, srcComponents);
+
+            for(int j=0; j<formats.length; j++) {
+                final PixelFormat destFmt = formats[j];
+                System.err.println("CONVERT["+i+"]["+j+"]: "+srcFmt+" -> "+destFmt);
+
+                final int destStrideBytes = Math.max(destMinStrideInBytes, width*destFmt.bytesPerPixel());
+                final byte[] destComponents = new byte[4];
+                getComponents(srcFmt.componentCount, destFmt, destComponents);
+                final PixelRectangle imageConv1 = PixelFormatUtil.convert32(imageSrc, destFmt, destStrideBytes, destIsGLOriented, false /* nio */);
+                System.err.println("CONVERT["+i+"]["+j+"]: Conv1: "+imageConv1);
+                testComponents(imageConv1, 0, 0, destComponents);
+                testComponents(imageConv1, width-1, height-1, destComponents);
+                if( PixelFormat.LUMINANCE != srcFmt && PixelFormat.LUMINANCE == destFmt ) {
+                    // Cannot convert: RGB* -> LUM -> RGB*
+                    System.err.println("CONVERT["+i+"]["+j+"]: Conv2: Dropped due to RGB* -> LUM");
+                } else if( srcFmt.componentCount > destFmt.componentCount ) {
+                    // Cannot convert back if: src.componentCount > dest.componentCount
+                    System.err.println("CONVERT["+i+"]["+j+"]: Conv2: Dropped due to src.componentCount > dest.componentCount");
+                } else {
+                    final PixelRectangle imageConv2 = PixelFormatUtil.convert32(imageConv1, imageSrc.getPixelformat(), imageSrc.getStride(), imageSrc.isGLOriented(), false /* nio */);
+                    System.err.println("CONVERT["+i+"]["+j+"]: Conv2: "+imageConv2);
+                    testComponents(imageConv2, 0, 0, srcComponents);
+                    testComponents(imageConv2, width-1, height-1, srcComponents);
+                    if( imageSrc.getStride() == imageConv1.getStride() ) {
+                        Assert.assertEquals(imageSrc.getPixels(), imageConv2.getPixels());
+                    }
+                }
+            }
+        }
+    }
+    private void dumpComponents(PixelRectangle image, int x1, int y1, int w, int h) {
+        if( x1 + w >= image.getSize().getWidth() ) {
+            x1 = image.getSize().getWidth() - w;
+        }
+        if( y1 + h >= image.getSize().getHeight() ) {
+            y1 = image.getSize().getHeight() - h;
+        }
+        System.err.print("PixelsBytes "+x1+"/"+y1+" "+w+"x"+h+":");
+        final ByteBuffer bb = image.getPixels();
+        final int bpp = image.getPixelformat().bytesPerPixel();
+        for(int y = y1; y< y1+h; y++) {
+            System.err.printf("%n[%3d][%3d] ", x1, y);
+            int o = y * image.getStride()+x1*bpp;
+            for(int x = x1; x< x1+w; x++) {
+                switch(bpp) {
+                    case 1: {
+                        final byte a = bb.get(o++);
+                        System.err.printf(" 0x%02X", a);
+                        }
+                        break;
+                    case 2: {
+                        final byte a = bb.get(o++), b = bb.get(o++);
+                        System.err.printf(" 0x%02X%02X", b, a);
+                      }
+                      break;
+                    case 3: {
+                        final byte a = bb.get(o++), b = bb.get(o++), c = bb.get(o++);
+                        System.err.printf(" 0x%02X%02X%02X", c, b, a);
+                      }
+                      break;
+                    case 4: {
+                        final byte a = bb.get(o++), b = bb.get(o++), c = bb.get(o++), d = bb.get(o++);
+                        System.err.printf(" 0x%02X%02X%02X%02X", d, c, b, a);
+                      }
+                      break;
+                }
+            }
+        }
+        System.err.println();
+    }
+    private void testComponents(PixelRectangle image, int x, int y, byte[] components) {
+        dumpComponents(image, x, y, 3, 3);
+        final ByteBuffer bb = image.getPixels();
+        final int bpp = image.getPixelformat().bytesPerPixel();
+        int o = y * image.getStride()+x*bpp;
+        switch(bpp) {
+            case 1: {
+                final byte c1 = bb.get(o++);
+                final boolean equal = c1==components[0];
+                System.err.printf("Test [%3d][%3d] exp 0x%02X == has 0x%02X : %b%n",
+                        x, y, components[0], c1, equal );
+                Assert.assertEquals(components[0], c1);
+                }
+                break;
+            case 2: {
+                final byte c1 = bb.get(o++), c2 = bb.get(o++);
+                final boolean equal = c1==components[0] && c2==components[1];
+                System.err.printf("Test [%3d][%3d] exp 0x%02X%02X == has 0x%02X%02X : %b%n",
+                        x, components[1], components[0], c2, c1, equal );
+                Assert.assertEquals(components[0], c1);
+                Assert.assertEquals(components[1], c2);
+              }
+              break;
+            case 3: {
+                final byte c1 = bb.get(o++), c2 = bb.get(o++), c3 = bb.get(o++);
+                final boolean equal = c1==components[0] && c2==components[1] && c3==components[2];
+                System.err.printf("Test [%3d][%3d] exp 0x%02X%02X%02X == has 0x%02X%02X%02X : %b%n",
+                        x, y, components[2], components[1], components[0], c3, c2, c1, equal );
+                Assert.assertEquals(components[0], c1);
+                Assert.assertEquals(components[1], c2);
+                Assert.assertEquals(components[2], c3);
+              }
+              break;
+            case 4: {
+                final byte c1 = bb.get(o++), c2 = bb.get(o++), c3 = bb.get(o++), c4 = bb.get(o++);
+                final boolean equal = c1==components[0] && c2==components[1] && c3==components[2] && c4==components[3];
+                System.err.printf("Test [%3d][%3d] exp 0x%02X%02X%02X%02X == has 0x%02X%02X%02X%02X : %b%n",
+                        x, y, components[3], components[2], components[1], components[0], c4, c3, c2, c1, equal );
+                Assert.assertEquals(components[0], c1);
+                Assert.assertEquals(components[1], c2);
+                Assert.assertEquals(components[2], c3);
+                Assert.assertEquals(components[3], c4);
+              }
+              break;
+        }
+    }
+
+    public static void main(String args[]) {
+        org.junit.runner.JUnitCore.main(TestPixelFormatUtil00NEWT.class.getName());
+    }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPixelFormatUtil01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPixelFormatUtil01NEWT.java
new file mode 100644
index 0000000..f548613
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPixelFormatUtil01NEWT.java
@@ -0,0 +1,105 @@
+/**
+ * Copyright 2014 JogAmp Community. 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 JogAmp Community ``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 JogAmp Community OR
+ * 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package com.jogamp.opengl.test.junit.jogl.util.texture;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URLConnection;
+
+import javax.media.nativewindow.util.PixelFormat;
+import javax.media.nativewindow.util.PixelFormatUtil;
+import javax.media.nativewindow.util.PixelRectangle;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.FixMethodOrder;
+import org.junit.runners.MethodSorters;
+
+import com.jogamp.common.util.IOUtil;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.util.PNGPixelRect;
+
+/**
+ * Testing PixelFormatUtil's Conversion using PNG test data
+ * including strides, endian-order and PixelFormat conversions:
+ *    { PixelFormat.RGBA8888, PixelFormat.ABGR8888, PixelFormat.BGRA8888, PixelFormat.ARGB8888 }
+ */
+ at FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class TestPixelFormatUtil01NEWT extends UITestCase {
+    @Test
+    public void testPNGRead11_fromRGBA8888() throws InterruptedException, IOException, MalformedURLException {
+        final String basename ="test-ntscN_4-01-160x90";
+        final String pathname="";
+        testPNG01Impl(pathname, basename, PixelFormat.RGBA8888, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+    }
+    @Test
+    public void testPNGRead12_fromABGR8888() throws InterruptedException, IOException, MalformedURLException {
+        final String basename ="test-ntscN_4-01-160x90";
+        final String pathname="";
+        testPNG01Impl(pathname, basename, PixelFormat.ABGR8888, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+    }
+    @Test
+    public void testPNGRead13_fromBGRA8888() throws InterruptedException, IOException, MalformedURLException {
+        final String basename ="test-ntscN_4-01-160x90";
+        final String pathname="";
+        testPNG01Impl(pathname, basename, PixelFormat.BGRA8888, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+    }
+    @Test
+    public void testPNGRead14_fromARGB8888() throws InterruptedException, IOException, MalformedURLException {
+        final String basename ="test-ntscN_4-01-160x90";
+        final String pathname="";
+        testPNG01Impl(pathname, basename, PixelFormat.ARGB8888, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+    }
+
+    private void testPNG01Impl(final String pathname, final String basename, final PixelFormat srcFmt,
+                               final int destMinStrideInBytes, final boolean destIsGLOriented)
+            throws InterruptedException, IOException, MalformedURLException
+    {
+        System.err.println("Test01: "+pathname+basename+".png, srcFmt "+srcFmt+", destMinStrideInBytes "+destMinStrideInBytes+", destIsGLOriented "+destIsGLOriented);
+
+        URLConnection urlConn = IOUtil.getResource(this.getClass(), pathname+basename+".png");
+
+        final PNGPixelRect image1 = PNGPixelRect.read(urlConn.getInputStream(), srcFmt, false /* directBuffer */, destMinStrideInBytes, false /* isGLOriented */);
+        System.err.println("PNGPixelRect - Orig: "+image1);
+
+        final PixelFormat[] formats = new PixelFormat[] { PixelFormat.RGBA8888, PixelFormat.ABGR8888, PixelFormat.BGRA8888, PixelFormat.ARGB8888 };
+        for(int i=0; i<formats.length; i++) {
+            final PixelFormat destFmt = formats[i];
+            System.err.println("CONVERT["+i+"]: "+srcFmt+" -> "+destFmt);
+            final PixelRectangle imageConv1 = PixelFormatUtil.convert32(image1, destFmt, destMinStrideInBytes, destIsGLOriented, false /* nio */);
+            System.err.println("PNGPixelRect - Conv1: "+imageConv1);
+            final PixelRectangle imageConv2 = PixelFormatUtil.convert32(imageConv1, image1.getPixelformat(), image1.getStride(), image1.isGLOriented(), false /* nio */);
+            System.err.println("PNGPixelRect - Conv2: "+imageConv2);
+            Assert.assertEquals(image1.getPixels(), imageConv2.getPixels());
+        }
+    }
+
+    public static void main(String args[]) {
+        org.junit.runner.JUnitCore.main(TestPixelFormatUtil01NEWT.class.getName());
+    }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/cross-grey-alpha-16x16.png b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/cross-grey-alpha-16x16.png
new file mode 100644
index 0000000..303c454
Binary files /dev/null and b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/cross-grey-alpha-16x16.png differ
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/pointer-grey-alpha-16x24.png b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/pointer-grey-alpha-16x24.png
new file mode 100644
index 0000000..98b2c86
Binary files /dev/null and b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/pointer-grey-alpha-16x24.png differ
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-64x32_DXT1.dds b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-64x32_DXT1.dds
new file mode 100644
index 0000000..81ae64e
Binary files /dev/null and b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-64x32_DXT1.dds differ
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-64x32_DXT5.dds b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-64x32_DXT5.dds
new file mode 100644
index 0000000..5b9e364
Binary files /dev/null and b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-64x32_DXT5.dds differ
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-64x32_uncompressed.dds b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-64x32_uncompressed.dds
new file mode 100644
index 0000000..034d251
Binary files /dev/null and b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-64x32_uncompressed.dds differ
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java
index f7fbc73..dc9aac8 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java
@@ -28,20 +28,27 @@
 package com.jogamp.opengl.test.junit.newt.parenting;
 
 import java.awt.Frame;
+import java.net.URLConnection;
 
 import javax.media.nativewindow.util.InsetsImmutable;
 
+import com.jogamp.common.util.IOUtil;
+import com.jogamp.newt.Display;
+import com.jogamp.newt.Display.PointerIcon;
 import com.jogamp.newt.awt.NewtCanvasAWT;
 import com.jogamp.newt.event.KeyAdapter;
 import com.jogamp.newt.event.KeyEvent;
 import com.jogamp.newt.opengl.GLWindow;
 import com.jogamp.opengl.test.junit.util.QuitAdapter;
+import com.jogamp.opengl.util.PNGPixelRect;
 
 public class NewtAWTReparentingKeyAdapter extends KeyAdapter {
     final Frame frame;
     final NewtCanvasAWT newtCanvasAWT;
     final GLWindow glWindow;
     final QuitAdapter quitAdapter;
+    PointerIcon[] pointerIcons = null;
+    int pointerIconIdx = 0;
 
     public NewtAWTReparentingKeyAdapter(Frame frame, NewtCanvasAWT newtCanvasAWT, GLWindow glWindow, QuitAdapter quitAdapter) {
         this.frame = frame;
@@ -54,9 +61,7 @@ public class NewtAWTReparentingKeyAdapter extends KeyAdapter {
         if( !e.isPrintableKey() || e.isAutoRepeat() ) {
             return;
         }
-        if( e.getKeySymbol() == KeyEvent.VK_I ) {
-            System.err.println(glWindow);
-        } else if( e.getKeySymbol() == KeyEvent.VK_L ) {
+        if( e.getKeySymbol() == KeyEvent.VK_L ) {
             javax.media.nativewindow.util.Point p0 = newtCanvasAWT.getNativeWindow().getLocationOnScreen(null);
             javax.media.nativewindow.util.Point p1 = glWindow.getLocationOnScreen(null);
             System.err.println("NewtCanvasAWT position: "+p0+", "+p1);
@@ -96,6 +101,12 @@ public class NewtAWTReparentingKeyAdapter extends KeyAdapter {
                     }
                 }
             }.run();
+        } else if( e.getKeySymbol() == KeyEvent.VK_A ) {
+            new Thread() {
+                public void run() {
+                    glWindow.setAlwaysOnTop(!glWindow.isAlwaysOnTop());
+                }
+            }.run();
         } else if( e.getKeySymbol() == KeyEvent.VK_R ) {
             if( null != quitAdapter ) {
                 quitAdapter.enable(false);
@@ -134,6 +145,90 @@ public class NewtAWTReparentingKeyAdapter extends KeyAdapter {
                         quitAdapter.enable(true);
                     }
             } }.start();
+        } else if(e.getKeySymbol() == KeyEvent.VK_C ) {
+            if( null == pointerIcons ) {
+                {
+                    pointerIcons = new PointerIcon[3];
+                    final Display disp = glWindow.getScreen().getDisplay();
+                    {
+                        PointerIcon _pointerIcon = null;
+                        final IOUtil.ClassResources res = new IOUtil.ClassResources(glWindow.getClass(), new String[] { "newt/data/cross-grey-alpha-16x16.png" } );
+                        try {
+                            _pointerIcon = disp.createPointerIcon(res, 8, 8);
+                            System.err.println("Create PointerIcon #01: "+_pointerIcon);
+                        } catch (Exception ex) {
+                            ex.printStackTrace();
+                        }
+                        pointerIcons[0] = _pointerIcon;
+                    }
+                    {
+                        PointerIcon _pointerIcon = null;
+                        final IOUtil.ClassResources res = new IOUtil.ClassResources(glWindow.getClass(), new String[] { "newt/data/pointer-grey-alpha-16x24.png" } );
+                        try {
+                            _pointerIcon = disp.createPointerIcon(res, 0, 0);
+                            System.err.println("Create PointerIcon #02: "+_pointerIcon);
+                        } catch (Exception ex) {
+                            ex.printStackTrace();
+                        }
+                        pointerIcons[1] = _pointerIcon;
+                    }
+                    {
+                        PointerIcon _pointerIcon = null;
+                        final IOUtil.ClassResources res = new IOUtil.ClassResources(glWindow.getClass(), new String[] { "jogamp-pointer-64x64.png" } );
+                        try {
+                            final URLConnection urlConn = res.resolve(0);
+                            final PNGPixelRect image = PNGPixelRect.read(urlConn.getInputStream(), null, false /* directBuffer */, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+                            System.err.println("Create PointerIcon #03: "+image);
+                            _pointerIcon = disp.createPointerIcon(image, 32, 0);
+                            System.err.println("Create PointerIcon #03: "+_pointerIcon);
+                        } catch (Exception ex) {
+                            ex.printStackTrace();
+                        }
+                        pointerIcons[2] = _pointerIcon;
+                    }
+                }
+            }
+            new Thread() {
+                public void run() {
+                    final Thread t = glWindow.setExclusiveContextThread(null);
+                    System.err.println("[set pointer-icon pre]");
+                    final PointerIcon currentPI = glWindow.getPointerIcon();
+                    final PointerIcon newPI;
+                    if( pointerIconIdx >= pointerIcons.length ) {
+                        newPI=null;
+                        pointerIconIdx=0;
+                    } else {
+                        newPI=pointerIcons[pointerIconIdx++];
+                    }
+                    glWindow.setPointerIcon( newPI );
+                    System.err.println("[set pointer-icon post] "+currentPI+" -> "+glWindow.getPointerIcon());
+                    glWindow.setExclusiveContextThread(t);
+            } }.start();
+        } else if( e.getKeySymbol() == KeyEvent.VK_I ) {
+            new Thread() {
+                public void run() {
+                    final Thread t = glWindow.setExclusiveContextThread(null);
+                    System.err.println("[set mouse visible pre]: "+glWindow.isPointerVisible());
+                    glWindow.setPointerVisible(!glWindow.isPointerVisible());
+                    System.err.println("[set mouse visible post]: "+glWindow.isPointerVisible());
+                    glWindow.setExclusiveContextThread(t);
+            } }.start();
+        } else if(e.getKeySymbol() == KeyEvent.VK_J ) {
+            new Thread() {
+                public void run() {
+                    final Thread t = glWindow.setExclusiveContextThread(null);
+                    System.err.println("[set mouse confined pre]: "+glWindow.isPointerConfined());
+                    glWindow.confinePointer(!glWindow.isPointerConfined());
+                    System.err.println("[set mouse confined post]: "+glWindow.isPointerConfined());
+                    glWindow.setExclusiveContextThread(t);
+            } }.start();
+        } else if(e.getKeySymbol() == KeyEvent.VK_W ) {
+            new Thread() {
+               public void run() {
+                   System.err.println("[set mouse pos pre]");
+                   glWindow.warpPointer(glWindow.getWidth()/2, glWindow.getHeight()/2);
+                   System.err.println("[set mouse pos post]");
+               } }.start();
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01dAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01dAWT.java
index 00b32ac..288918e 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01dAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01dAWT.java
@@ -145,8 +145,8 @@ public class TestParenting01dAWT extends UITestCase {
         });
         Assert.assertEquals(newtCanvasAWT.getNativeWindow(),glWindow1.getParent());
 
-        Assert.assertTrue(AWTRobotUtil.waitForRealized(glWindow1, true));
         Assert.assertTrue(AWTRobotUtil.waitForVisible(glWindow1, true));
+        Assert.assertTrue(AWTRobotUtil.waitForRealized(glWindow1, true));
         glWindow1.display();
         Assert.assertEquals("Init Counter Invalid "+glelCounter, 1, glelCounter.initCount);
         Assert.assertEquals("Dispose Counter Invalid "+glelCounter, 0, glelCounter.disposeCount);
@@ -172,11 +172,14 @@ public class TestParenting01dAWT extends UITestCase {
         // GL state shall be preserved!
         //
         glWindow1.setVisible(false);
+        Assert.assertTrue(AWTRobotUtil.waitForVisible(glWindow1, false));
         System.err.println(getSimpleTestName(".")+": Start Reparent #2");
         final Window.ReparentOperation rop2 = glWindow1.reparentWindow(newtCanvasAWT.getNativeWindow(), -1, -1, reparentingHints);
         System.err.println(getSimpleTestName(".")+": Result Reparent #2: "+rop2);
         Assert.assertEquals(Window.ReparentOperation.ACTION_NATIVE_CREATION, rop2);
         glWindow1.setVisible(true);
+        Assert.assertTrue(AWTRobotUtil.waitForVisible(glWindow1, true));
+        Assert.assertTrue(AWTRobotUtil.waitForRealized(glWindow1, true));
         glWindow1.display();
         if( triggerPreserveGLState ) {
             Assert.assertEquals("Init Counter Invalid (Preserve Failed 2) "+glelCounter, 1, glelCounter.initCount);
diff --git a/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java b/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java
index cf58ae2..599a6dc 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java
@@ -656,7 +656,7 @@ public class AWTRobotUtil {
             }
         } else if(NativeWindowFactory.isAWTAvailable() && obj instanceof java.awt.Component) {
             java.awt.Component comp = (java.awt.Component) obj;
-            for (wait=0; wait<POLL_DIVIDER && visible != comp.isVisible(); wait++) {
+            for (wait=0; wait<POLL_DIVIDER && visible != comp.isShowing(); wait++) {
                 Thread.sleep(TIME_SLICE);
             }
         } else {
@@ -719,7 +719,7 @@ public class AWTRobotUtil {
             }
         } else if (NativeWindowFactory.isAWTAvailable() && obj instanceof java.awt.Component) {
             java.awt.Component comp = (java.awt.Component) obj;
-            while( (t1-t0) < TIME_OUT && realized != comp.isDisplayable() ) {
+            while( (t1-t0) < TIME_OUT && realized != comp.isShowing() ) {
                 if( null != waitAction ) {
                     waitAction.run();
                 } else {
diff --git a/src/test/com/jogamp/opengl/test/junit/util/QuitAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/QuitAdapter.java
index b5864e3..467dd7f 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/QuitAdapter.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/QuitAdapter.java
@@ -3,14 +3,14 @@
  *
  * 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 JogAmp Community ``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 JogAmp Community OR
@@ -20,12 +20,12 @@
  * 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.
- * 
+ *
  * The views and conclusions contained in the software and documentation are those of the
  * authors and should not be interpreted as representing official policies, either expressed
  * or implied, of JogAmp Community.
  */
- 
+
 package com.jogamp.opengl.test.junit.util;
 
 import com.jogamp.newt.event.*;
@@ -35,10 +35,11 @@ public class QuitAdapter extends WindowAdapter implements WindowListener, KeyLis
     boolean enabled = true;
 
     public void enable(boolean v) { enabled = v; }
-    
+
     public void clear() { shouldQuit = false; }
-    
+
     public boolean shouldQuit() { return shouldQuit; }
+    public void doQuit() { shouldQuit=true; }
 
     public void windowDestroyNotify(WindowEvent e) {
         if( enabled ) {
@@ -50,7 +51,7 @@ public class QuitAdapter extends WindowAdapter implements WindowListener, KeyLis
     public void keyReleased(KeyEvent e) {
         if( !e.isPrintableKey() || e.isAutoRepeat() ) {
             return;
-        }            
+        }
         if( enabled ) {
             if(e.getKeyChar()=='q') {
                 System.err.println("QUIT Key "+Thread.currentThread());

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/libjogl2-java.git



More information about the pkg-java-commits mailing list