[libjogl2-java] 32/58: Imported Upstream version 2.0-rc11

Tony Mancill tmancill at moszumanska.debian.org
Thu Sep 4 03:59:16 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 bc4be11d7517566bebe32d569be839b38764a4c0
Author: tony mancill <tmancill at debian.org>
Date:   Fri Aug 29 18:44:51 2014 -0700

    Imported Upstream version 2.0-rc11
---
 doc/TODO.txt                                       |   24 +-
 doc/deployment/JOGL-DEPLOYMENT.html                |  123 +-
 doc/userguide/index.html                           |    9 +-
 etc/test.sh                                        |    2 +-
 jnlp-files/jogl-all-awt-cg.jnlp                    |   12 +-
 jnlp-files/jogl-all-awt.jnlp                       |    6 +-
 jnlp-files/jogl-all-mobile.jnlp                    |    6 +-
 jnlp-files/jogl-all-noawt.jnlp                     |    6 +-
 .../jogl-applet-runner-newt-gears-gl3-napplet.html |  107 ++
 jnlp-files/jogl-test-applets.html                  |    3 +-
 make/build-common.xml                              |   19 +-
 make/build-jogl.xml                                |   37 +-
 make/build-nativewindow.xml                        |   15 +-
 make/build-newt.xml                                |  113 +-
 make/build-test.xml                                |    8 +-
 make/build.xml                                     |    2 +-
 make/config/jogl/cgl-macosx.cfg                    |    4 +
 make/config/jogl/cglext.cfg                        |    4 +
 make/config/jogl/egl.cfg                           |    6 +-
 make/config/jogl/eglext.cfg                        |    4 +
 make/config/jogl/gl-common.cfg                     |   69 +-
 make/config/jogl/gl-gl4bc.cfg                      |   10 +
 .../config/jogl/gl-impl-CustomJavaCode-common.java |   20 +
 make/config/jogl/gl2_es2-common.cfg                |   10 -
 make/config/jogl/glx-CustomCCode.c                 |   60 +-
 make/config/jogl/glx-CustomJavaCode.java           |   56 +-
 make/config/jogl/glx-x11.cfg                       |    6 +-
 make/config/jogl/glxext.cfg                        |    4 +
 make/config/jogl/wgl-win32.cfg                     |    6 +-
 make/config/jogl/wglext.cfg                        |    4 +
 make/config/nativewindow/x11-CustomJavaCode.java   |    5 +
 make/scripts/adb-install-all-armv6.sh              |    4 +
 make/scripts/adb-launch-main.sh                    |    6 +-
 make/scripts/adb-reinstall-all-armv6.sh            |    5 +
 make/scripts/java-win32-dbg.bat                    |   19 +-
 make/scripts/java-win32.bat                        |   13 +-
 make/scripts/java-win64-dbg.bat                    |   12 +-
 make/scripts/java-win64.bat                        |    4 +-
 make/scripts/lstjars.sh                            |   24 +-
 make/scripts/make.jogl.all.android-armv6-cross.sh  |   92 ++
 ...cross.sh => make.jogl.all.linux-armv6-cross.sh} |   12 +-
 ...linux-armv7.sh => make.jogl.all.linux-armv6.sh} |   10 +-
 ...oss.sh => make.jogl.all.linux-armv6hf-cross.sh} |   14 +-
 make/scripts/make.jogl.all.linux-armv6hf.sh        |   27 +
 make/scripts/make.jogl.all.win32.bat               |    4 +-
 make/scripts/make.jogl.all.win64.bat               |    6 +-
 make/scripts/targetcommand-awt.sh                  |   12 +-
 ...{targetcommand-awt.sh => targetcommand-loop.sh} |   40 +-
 make/scripts/targetcommand-newt.sh                 |   21 +-
 make/scripts/tests-armv6_armel.sh                  |    7 +
 make/scripts/tests-armv6_armhf.sh                  |    7 +
 make/scripts/tests-armv7l_eabi.sh                  |    7 -
 make/scripts/tests-javaws-x64.bat                  |    2 +-
 make/scripts/tests-linux-armv6.sh                  |    7 +
 make/scripts/tests-linux-armv6hf.sh                |    7 +
 make/scripts/tests-linux-armv7.sh                  |    7 -
 make/scripts/tests-linux-armv7hf.sh                |    7 -
 make/scripts/tests-x32.bat                         |    9 +-
 make/scripts/tests-x64.bat                         |   50 +-
 make/scripts/tests.sh                              |  140 ++-
 make/stub_includes/opengl/GL/glxext.h              |   10 +
 make/stub_includes/opengl/macosx-window-system.h   |   13 +-
 make/stub_includes/x11/window-lib.c                |    5 +-
 make/versions.xml                                  |    2 +-
 .../com/jogamp/graph/curve/opengl/RenderState.java |    6 +-
 src/jogl/classes/com/jogamp/opengl/FBObject.java   | 1298 +++++++++++++-------
 src/jogl/classes/com/jogamp/opengl/FloatUtil.java  |  130 +-
 .../jogamp}/opengl/GLAutoDrawableDelegate.java     |   81 +-
 .../classes/com/jogamp/opengl/GLExtensions.java    |    3 +
 .../com/jogamp/opengl/GLRendererQuirks.java        |  144 +++
 .../opengl/GenericGLCapabilitiesChooser.java}      |   35 +-
 .../classes/com/jogamp/opengl/JoglVersion.java     |   17 +
 .../com/jogamp/opengl/OffscreenAutoDrawable.java   |   98 --
 .../classes/com/jogamp/opengl/swt/GLCanvas.java    |   75 +-
 .../com/jogamp/opengl/util/GLArrayDataClient.java  |   39 +-
 .../jogamp/opengl/util/GLArrayDataEditable.java    |   33 +-
 .../com/jogamp/opengl/util/GLArrayDataWrapper.java |   14 +-
 .../classes/com/jogamp/opengl/util/GLBuffers.java  |   73 +-
 .../com/jogamp/opengl/util/GLReadBufferUtil.java   |    8 +-
 .../com/jogamp/opengl/util/ImmModeSink.java        | 1029 ++++++++++------
 .../classes/com/jogamp/opengl/util/PMVMatrix.java  |  732 ++++++++---
 .../com/jogamp/opengl/util/glsl/ShaderCode.java    |   30 +
 .../com/jogamp/opengl/util/glsl/ShaderProgram.java |   37 +-
 .../com/jogamp/opengl/util/glsl/ShaderState.java   |  145 ++-
 .../com/jogamp/opengl/util/glsl/ShaderUtil.java    |   49 +-
 .../opengl/util/glsl/fixedfunc/FixedFuncUtil.java  |   46 +-
 .../util/glsl/fixedfunc/ShaderSelectionMode.java   |   27 +
 .../com/jogamp/opengl/util/texture/Texture.java    |    9 +-
 .../opengl/util/texture/spi/LEDataInputStream.java |    2 +-
 .../media/opengl/DefaultGLCapabilitiesChooser.java |   39 +-
 .../classes/javax/media/opengl/GLArrayData.java    |    6 +-
 .../classes/javax/media/opengl/GLAutoDrawable.java |   38 +-
 src/jogl/classes/javax/media/opengl/GLBase.java    |   38 +
 .../classes/javax/media/opengl/GLCapabilities.java |  125 +-
 .../media/opengl/GLCapabilitiesImmutable.java      |   79 +-
 src/jogl/classes/javax/media/opengl/GLContext.java |  315 +++--
 .../classes/javax/media/opengl/GLDrawable.java     |    2 +-
 .../javax/media/opengl/GLDrawableFactory.java      |  271 +++-
 .../classes/javax/media/opengl/GLFBODrawable.java  |  175 +++
 .../media/opengl/GLOffscreenAutoDrawable.java}     |   71 +-
 src/jogl/classes/javax/media/opengl/GLPbuffer.java |    6 +-
 src/jogl/classes/javax/media/opengl/GLProfile.java |  167 +--
 .../classes/javax/media/opengl/GLRunnable2.java}   |   18 +-
 .../classes/javax/media/opengl/GLUniformData.java  |   36 +-
 .../classes/javax/media/opengl/awt/GLCanvas.java   |  183 +--
 .../classes/javax/media/opengl/awt/GLJPanel.java   |   15 +-
 .../javax/media/opengl/fixedfunc/GLMatrixFunc.java |  175 ++-
 .../media/opengl/fixedfunc/GLPointerFuncUtil.java  |   15 +-
 .../graph/curve/opengl/RegionRendererImpl01.java   |    4 +-
 .../graph/curve/opengl/TextRendererImpl01.java     |    4 +-
 .../jogamp/graph/curve/opengl/VBORegion2PES2.java  |   18 +-
 .../jogamp/graph/curve/opengl/VBORegionSPES2.java  |   14 +-
 .../opengl/shader/curverenderer01-es2-merged.vp    |    4 +-
 .../curve/opengl/shader/curverenderer01-es2.vp     |    4 +-
 .../opengl/shader/curverenderer01a-es2-merged.fp   |    4 +-
 .../curve/opengl/shader/curverenderer01b-es2.fp    |    2 +-
 .../curve/opengl/shader/curverenderer02a-es2.fp    |    2 +-
 .../curve/opengl/shader/curverenderer02b-es2.fp    |    2 +-
 .../classes/jogamp/graph/font/JavaFontLoader.java  |    8 +-
 .../jogamp/graph/font/UbuntuFontLoader.java        |   14 +-
 .../classes/jogamp/graph/geom/plane/Path2D.java    |    2 +-
 .../classes/jogamp/opengl/GLAutoDrawableBase.java  |   96 +-
 .../jogamp/opengl/GLBufferStateTracker.java        |   14 +-
 src/jogl/classes/jogamp/opengl/GLContextImpl.java  |  301 +++--
 .../jogamp/opengl/GLDrawableFactoryImpl.java       |  175 +--
 .../classes/jogamp/opengl/GLDrawableHelper.java    |  196 ++-
 src/jogl/classes/jogamp/opengl/GLDrawableImpl.java |   94 +-
 .../classes/jogamp/opengl/GLFBODrawableImpl.java   |  571 +++++++--
 .../jogamp/opengl/GLGraphicsConfigurationUtil.java |  233 ++--
 .../jogamp/opengl/GLOffscreenAutoDrawableImpl.java |  123 ++
 src/jogl/classes/jogamp/opengl/GLPbufferImpl.java  |   31 +-
 .../classes/jogamp/opengl/GLVersionNumber.java     |   26 +-
 .../classes/jogamp/opengl/GLXExtensions.java}      |   24 +-
 src/jogl/classes/jogamp/opengl/ProjectFloat.java   |  356 +++---
 src/jogl/classes/jogamp/opengl/ThreadingImpl.java  |    3 +-
 src/jogl/classes/jogamp/opengl/egl/EGLContext.java |   67 +-
 .../classes/jogamp/opengl/egl/EGLDisplayUtil.java  |  157 ++-
 .../classes/jogamp/opengl/egl/EGLDrawable.java     |  142 +--
 .../jogamp/opengl/egl/EGLDrawableFactory.java      |  608 +++++----
 .../opengl/egl/EGLDummyUpstreamSurfaceHook.java    |   59 +
 .../jogamp/opengl/egl/EGLExternalContext.java      |   11 -
 .../jogamp/opengl/egl/EGLGLCapabilities.java       |   23 +-
 .../opengl/egl/EGLGraphicsConfiguration.java       |  233 ++--
 .../egl/EGLGraphicsConfigurationFactory.java       |   70 +-
 .../jogamp/opengl/egl/EGLOnscreenContext.java      |   11 -
 .../jogamp/opengl/egl/EGLOnscreenDrawable.java     |    4 +-
 .../jogamp/opengl/egl/EGLPbufferContext.java       |   10 -
 .../jogamp/opengl/egl/EGLPbufferDrawable.java      |    8 +-
 .../jogamp/opengl/egl/EGLUpstreamSurfaceHook.java  |  145 ++-
 .../jogamp/opengl/egl/EGLWrappedSurface.java       |   26 +
 .../classes/jogamp/opengl/glu/GLUquadricImpl.java  |   42 +-
 .../jogamp/opengl/macosx/cgl/MacOSXCGLContext.java |  775 ++++++++----
 .../opengl/macosx/cgl/MacOSXCGLDrawable.java       |   48 +-
 .../macosx/cgl/MacOSXCGLDrawableFactory.java       |  134 +-
 .../macosx/cgl/MacOSXCGLGraphicsConfiguration.java |  193 ++-
 .../cgl/MacOSXCGLGraphicsConfigurationFactory.java |   30 +-
 .../macosx/cgl/MacOSXExternalCGLContext.java       |    7 +-
 .../macosx/cgl/MacOSXOnscreenCGLContext.java       |   19 +-
 .../macosx/cgl/MacOSXOnscreenCGLDrawable.java      |    4 +-
 .../opengl/macosx/cgl/MacOSXPbufferCGLContext.java |    1 +
 .../macosx/cgl/MacOSXPbufferCGLDrawable.java       |   42 +-
 .../classes/jogamp/opengl/shader/texture01_xxx.fp  |   19 +
 .../classes/jogamp/opengl}/shader/texture01_xxx.vp |   12 +-
 .../classes/jogamp/opengl/util/GLArrayHandler.java |   21 +-
 .../jogamp/opengl/util/GLArrayHandlerFlat.java     |    4 +-
 .../opengl/util/GLArrayHandlerInterleaved.java     |   40 +-
 .../jogamp/opengl/util/GLDataArrayHandler.java     |   41 +-
 .../jogamp/opengl/util/GLFixedArrayHandler.java    |   41 +-
 .../opengl/util/GLFixedArrayHandlerFlat.java       |   36 +-
 ...ataArrayHandler.java => GLVBOArrayHandler.java} |   45 +-
 .../jogamp/opengl/util/av/EGLMediaPlayerImpl.java  |    6 +-
 .../jogamp/opengl/util/av/GLMediaPlayerImpl.java   |   13 +-
 .../av/impl/FFMPEGDynamicLibraryBundleInfo.java    |   17 +
 .../opengl/util/av/impl/FFMPEGMediaPlayer.java     |   16 +-
 .../jogamp/opengl/util/glsl/GLSLArrayHandler.java  |   28 +-
 .../opengl/util/glsl/GLSLArrayHandlerFlat.java     |   36 +-
 .../util/glsl/GLSLArrayHandlerInterleaved.java     |   40 +-
 .../opengl/util/glsl/fixedfunc/FixedFuncHook.java  |  210 +++-
 .../util/glsl/fixedfunc/FixedFuncPipeline.java     | 1234 +++++++++++++++----
 .../util/glsl/fixedfunc/shaders/FixedFuncColor.fp  |   28 +-
 .../util/glsl/fixedfunc/shaders/FixedFuncColor.vp  |    6 +
 .../glsl/fixedfunc/shaders/FixedFuncColorLight.vp  |   16 +-
 .../fixedfunc/shaders/FixedFuncColorTexture.fp     |  136 +-
 .../util/glsl/fixedfunc/shaders/FixedFuncPoints.fp |   47 +
 .../util/glsl/fixedfunc/shaders/FixedFuncPoints.vp |   40 +
 .../util/glsl/fixedfunc/shaders/mgl_alphatest.fp   |   33 +
 .../util/glsl/fixedfunc/shaders/mgl_attribute.glsl |   28 +-
 .../util/glsl/fixedfunc/shaders/mgl_const.glsl     |   31 +-
 .../util/glsl/fixedfunc/shaders/mgl_lightdef.glsl  |    3 +
 .../util/glsl/fixedfunc/shaders/mgl_settexcoord.vp |    6 +
 .../util/glsl/fixedfunc/shaders/mgl_uniform.glsl   |   43 +-
 .../glsl/fixedfunc/shaders/mgl_uniform_light.glsl  |    1 +
 .../util/glsl/fixedfunc/shaders/mgl_varying.glsl   |    2 +
 .../opengl/util/pngj/chunks/PngChunkTIME.java      |    2 +-
 .../opengl/windows/wgl/WGLGLCapabilities.java      |   47 +-
 .../windows/wgl/WindowsExternalWGLContext.java     |    4 +-
 .../windows/wgl/WindowsExternalWGLDrawable.java    |    4 +-
 .../windows/wgl/WindowsPbufferWGLDrawable.java     |   66 +-
 .../opengl/windows/wgl/WindowsWGLContext.java      |   14 +-
 .../opengl/windows/wgl/WindowsWGLDrawable.java     |   43 +-
 .../windows/wgl/WindowsWGLDrawableFactory.java     |   87 +-
 .../wgl/WindowsWGLGraphicsConfiguration.java       |  556 +++++----
 .../WindowsWGLGraphicsConfigurationFactory.java    |  164 ++-
 .../classes/jogamp/opengl/x11/glx/GLXUtil.java     |   81 +-
 .../opengl/x11/glx/X11ExternalGLXContext.java      |   29 +-
 .../opengl/x11/glx/X11ExternalGLXDrawable.java     |   33 +-
 .../jogamp/opengl/x11/glx/X11GLXContext.java       |  167 +--
 .../jogamp/opengl/x11/glx/X11GLXDrawable.java      |    7 +-
 .../opengl/x11/glx/X11GLXDrawableFactory.java      |  125 +-
 .../x11/glx/X11GLXGraphicsConfiguration.java       |  340 +++--
 .../glx/X11GLXGraphicsConfigurationFactory.java    |  154 +--
 .../opengl/x11/glx/X11OnscreenGLXDrawable.java     |    2 +-
 .../opengl/x11/glx/X11PbufferGLXDrawable.java      |   35 +-
 .../macosx/MacOSXWindowSystemInterface-calayer.m   |  840 +++++++++++++
 .../macosx/MacOSXWindowSystemInterface-pbuffer.m   |  494 --------
 .../native/macosx/MacOSXWindowSystemInterface.m    |   81 +-
 .../DelegatedUpstreamSurfaceHookMutableSize.java   |   39 +
 ...elegatedUpstreamSurfaceHookWithSurfaceSize.java |   54 +
 .../UpstreamSurfaceHookMutableSize.java            |   45 +
 .../com/jogamp/nativewindow/awt/JAWTWindow.java    |   99 +-
 .../jogamp/nativewindow/egl/EGLGraphicsDevice.java |   19 +-
 .../com/jogamp/nativewindow/swt/SWTAccessor.java   |   38 +-
 .../jogamp/nativewindow/x11/X11GraphicsDevice.java |   42 +-
 .../jogamp/nativewindow/x11/X11GraphicsScreen.java |   16 +-
 .../media/nativewindow/AbstractGraphicsDevice.java |   13 +-
 .../javax/media/nativewindow/Capabilities.java     |  182 +--
 .../media/nativewindow/CapabilitiesImmutable.java  |   35 +-
 .../nativewindow/DefaultCapabilitiesChooser.java   |    9 +-
 .../media/nativewindow/DefaultGraphicsDevice.java  |   24 +-
 .../nativewindow/GraphicsConfigurationFactory.java |    2 +-
 .../javax/media/nativewindow/NativeSurface.java    |    5 +-
 .../media/nativewindow/NativeWindowFactory.java    |  345 +++---
 .../media/nativewindow/OffscreenLayerSurface.java  |    3 +
 .../javax/media/nativewindow/ProxySurface.java     |  266 +---
 .../javax/media/nativewindow/ToolkitLock.java      |   38 +-
 .../{ToolkitLock.java => UpstreamSurfaceHook.java} |   34 +-
 ...JAWTToolkitLock.java => GlobalToolkitLock.java} |   72 +-
 .../nativewindow/NativeWindowFactoryImpl.java      |   15 +-
 .../jogamp/nativewindow/NullToolkitLock.java       |   26 +-
 .../nativewindow/ProxySurfaceImpl.java}            |  204 +--
 ...11ToolkitLock.java => ResourceToolkitLock.java} |   65 +-
 .../nativewindow/SharedResourceToolkitLock.java    |  148 +++
 .../jogamp/nativewindow/ToolkitProperties.java     |   47 +
 .../jogamp/nativewindow/WrappedSurface.java        |   53 +-
 .../jogamp/nativewindow/jawt/JAWTJNILibLoader.java |    2 +-
 .../classes/jogamp/nativewindow/jawt/JAWTUtil.java |   55 +-
 .../nativewindow/jawt/macosx/MacOSXJAWTWindow.java |   84 +-
 .../nativewindow/jawt/x11/X11JAWTWindow.java       |    3 +-
 .../macosx/OSXDummyUpstreamSurfaceHook.java        |   56 +
 .../jogamp/nativewindow/macosx/OSXUtil.java        |   55 +-
 .../windows/GDIDummyUpstreamSurfaceHook.java       |   50 +
 .../jogamp/nativewindow/windows/GDISurface.java    |   34 +-
 .../jogamp/nativewindow/windows/GDIUtil.java       |   40 +-
 .../x11/X11DummyUpstreamSurfaceHook.java           |   70 ++
 .../classes/jogamp/nativewindow/x11/X11Util.java   |  365 +++---
 .../awt/X11AWTGraphicsConfigurationFactory.java    |    7 +-
 src/nativewindow/native/macosx/OSXmisc.m           |  189 ++-
 src/nativewindow/native/x11/Xmisc.c                |  148 ++-
 src/newt/classes/com/jogamp/newt/Display.java      |   49 +-
 src/newt/classes/com/jogamp/newt/NewtFactory.java  |   13 +-
 src/newt/classes/com/jogamp/newt/Screen.java       |   10 +-
 src/newt/classes/com/jogamp/newt/Window.java       |    8 +-
 .../classes/com/jogamp/newt/awt/NewtCanvasAWT.java |    9 +
 .../classes/com/jogamp/newt/event/InputEvent.java  |   90 +-
 .../classes/com/jogamp/newt/event/KeyEvent.java    |  419 +++----
 .../classes/com/jogamp/newt/event/MouseEvent.java  |   23 +-
 .../classes/com/jogamp/newt/event/NEWTEvent.java   |   14 +-
 .../classes/com/jogamp/newt/event/WindowEvent.java |   13 +-
 .../com/jogamp/newt/event/WindowUpdateEvent.java   |   11 +-
 .../jogamp/newt/event/awt/AWTWindowAdapter.java    |   28 +-
 .../classes/com/jogamp/newt/opengl/GLWindow.java   |   25 +-
 .../classes/com/jogamp/newt/swt/NewtCanvasSWT.java |   20 +-
 .../classes/com/jogamp/newt/swt/SWTEDTUtil.java    |  217 +++-
 src/newt/classes/com/jogamp/newt/util/EDTUtil.java |   40 +-
 .../classes/com/jogamp/newt/util/MainThread.java   |    6 +-
 src/newt/classes/jogamp/newt/DefaultEDTUtil.java   |   62 +-
 src/newt/classes/jogamp/newt/DisplayImpl.java      |  111 +-
 src/newt/classes/jogamp/newt/OffscreenWindow.java  |   31 +-
 src/newt/classes/jogamp/newt/ScreenImpl.java       |   74 +-
 src/newt/classes/jogamp/newt/WindowImpl.java       |  132 +-
 .../{AndroidDisplay.java => DisplayDriver.java}    |    6 +-
 .../newt/driver/android/NewtBaseActivity.java      |   25 +-
 .../newt/driver/android/NewtVersionActivity.java   |    2 +-
 .../{AndroidScreen.java => ScreenDriver.java}      |    6 +-
 .../{AndroidWindow.java => WindowDriver.java}      |   56 +-
 .../classes/jogamp/newt/driver/awt/AWTCanvas.java  |   29 +-
 .../classes/jogamp/newt/driver/awt/AWTEDTUtil.java |  221 +++-
 .../awt/{AWTDisplay.java => DisplayDriver.java}    |   16 +-
 .../awt/{AWTScreen.java => ScreenDriver.java}      |    4 +-
 .../awt/{AWTWindow.java => WindowDriver.java}      |   90 +-
 .../Display.java => bcm/egl/DisplayDriver.java}    |   12 +-
 .../egl/Screen.java => bcm/egl/ScreenDriver.java}  |    8 +-
 .../egl/Window.java => bcm/egl/WindowDriver.java}  |    8 +-
 .../vc/iv/DisplayDriver.java}                      |   36 +-
 .../vc/iv/ScreenDriver.java}                       |   57 +-
 .../KDWindow.java => bcm/vc/iv/WindowDriver.java}  |  114 +-
 .../intel/gdl/{Display.java => DisplayDriver.java} |   20 +-
 .../intel/gdl/{Screen.java => ScreenDriver.java}   |    7 +-
 .../intel/gdl/{Window.java => WindowDriver.java}   |   19 +-
 .../kd/{KDDisplay.java => DisplayDriver.java}      |    9 +-
 .../driver/kd/{KDScreen.java => ScreenDriver.java} |    6 +-
 .../driver/kd/{KDWindow.java => WindowDriver.java} |    8 +-
 .../newt/driver/linux/LinuxMouseTracker.java       |  221 ++++
 .../macosx/{MacDisplay.java => DisplayDriver.java} |   11 +-
 .../jogamp/newt/driver/macosx/MacKeyUtil.java      |  172 +--
 .../macosx/{MacScreen.java => ScreenDriver.java}   |    6 +-
 .../macosx/{MacWindow.java => WindowDriver.java}   |  128 +-
 .../{WindowsDisplay.java => DisplayDriver.java}    |    9 +-
 .../{WindowsScreen.java => ScreenDriver.java}      |    6 +-
 .../{WindowsWindow.java => WindowDriver.java}      |   80 +-
 .../x11/{X11Display.java => DisplayDriver.java}    |   80 +-
 .../x11/{X11Screen.java => ScreenDriver.java}      |   41 +-
 .../x11/{X11Window.java => WindowDriver.java}      |  125 +-
 src/newt/native/AndroidWindow.c                    |   18 +-
 src/newt/native/InputEvent.h                       |   27 +-
 src/newt/native/IntelGDL.c                         |   24 +-
 src/newt/native/KDWindow.c                         |   20 +-
 src/newt/native/MacWindow.m                        |  165 +--
 src/newt/native/NewtMacWindow.h                    |    4 +
 src/newt/native/NewtMacWindow.m                    |   73 +-
 src/newt/native/WindowsWindow.c                    |  300 +++--
 src/newt/native/X11Common.h                        |    7 +-
 src/newt/native/X11Display.c                       |  176 +--
 src/newt/native/{X11Display.c => X11Event.c}       |  443 +------
 src/newt/native/X11Event.h                         |    9 +
 src/newt/native/X11Screen.c                        |   87 +-
 .../native/{X11Screen.c => X11ScreenRandR11.c}     |  288 +----
 .../native/{X11Screen.c => X11ScreenRandR13.c}     |  311 ++---
 src/newt/native/X11Window.c                        |   54 +-
 src/newt/native/XCBEvent.c                         |  314 +++++
 src/newt/native/XCBEvent.h                         |   10 +
 src/newt/native/{BroadcomEGL.c => bcm_egl.c}       |   16 +-
 src/newt/native/bcm_vc_iv.c                        |  219 ++++
 src/newt/native/bcm_vc_iv.h                        |  187 +++
 src/test-native/contextRetargetDrawable01.c        |  154 +++
 src/test-native/contextRetargetDrawable02.c        |  382 ++++++
 src/test-native/glExtensionsListGL2.c              |    2 +
 src/test-native/glExtensionsListGL3.c              |   25 +-
 src/test-native/make.sh                            |    2 +
 .../test/android/MovieCubeActivityLauncher0.java   |    2 +
 .../opengl/test/android/MovieSimpleActivity0.java  |    6 +-
 .../opengl/test/android/MovieSimpleActivity1.java  |   10 +-
 .../test/android/NEWTGearsES2ActivityLauncher.java |    8 +-
 .../android/NEWTGraphUI1pActivityLauncher.java     |   22 +-
 ...urrentNEWT.java => InitConcurrentBaseNEWT.java} |   86 +-
 ...WT.java => TestFBOAutoDrawableDeadlockAWT.java} |   11 +-
 .../jogl/acore/TestFBOAutoDrawableFactoryNEWT.java |  375 ++++++
 .../test/junit/jogl/acore/TestFBODrawableNEWT.java |  272 ----
 .../test/junit/jogl/acore/TestFBOMRTNEWT01.java    |   25 +-
 .../junit/jogl/acore/TestFBOMix2DemosES2NEWT.java  |    2 +-
 ...FBOOffThreadSharedContextMix2DemosES2NEWT.java} |  216 ++--
 ... TestFBOOnThreadSharedContext1DemoES2NEWT.java} |  191 +--
 .../jogl/acore/TestGLAutoDrawableDelegateNEWT.java |  152 ---
 ...estGLAutoDrawableDelegateOnOffscrnCapsNEWT.java |  385 ++++++
 .../TestGLAutoDrawableFactoryOffscrnCapsNEWT.java  |  306 +++++
 ...TestGLAutoDrawableGLCanvasOnOffscrnCapsAWT.java |  324 +++++
 ...estGLAutoDrawableGLWindowOnOffscrnCapsNEWT.java |  339 +++++
 ...LAutoDrawableNewtCanvasAWTOnOffscrnCapsAWT.java |  299 +++++
 .../acore/TestGLContextDrawableSwitchNEWT.java     |   44 +-
 .../jogl/acore/TestGLExtensionQueryOffscreen.java  |   19 +-
 .../junit/jogl/acore/TestGLProfile00NEWT.java}     |   30 +-
 .../test/junit/jogl/acore/TestGPUMemSec01NEWT.java |    4 +-
 .../acore/TestInitConcurrent01NEWT.java}           |   78 +-
 .../junit/jogl/acore/TestInitConcurrent02NEWT.java |   96 ++
 .../jogl/acore/TestNEWTCloseX11DisplayBug565.java  |   46 +-
 .../acore/TestOffscreenLayer01GLCanvasAWT.java}    |   94 +-
 .../acore/TestOffscreenLayer02NewtCanvasAWT.java}  |  111 +-
 .../junit/jogl/acore/TestPBufferDeadlockAWT.java   |    2 +
 .../test/junit/jogl/acore/TestPMVMatrix01NEWT.java |  442 +++++++
 .../test/junit/jogl/acore/TestPMVMatrix02NEWT.java |  109 ++
 .../test/junit/jogl/acore/TestPointsNEWT.java      |  156 +++
 .../junit/jogl/acore/TestSharedContextListAWT.java |   20 +-
 .../jogl/acore/TestSharedContextListNEWT.java      |   20 +-
 .../jogl/acore/TestSharedContextListNEWT2.java     |   14 +-
 .../jogl/acore/TestSharedContextNewtAWTBug523.java |   17 +-
 .../jogl/acore/TestSharedContextVBOES1NEWT.java    |   20 +-
 .../jogl/acore/TestSharedContextVBOES2NEWT.java    |  132 +-
 .../jogl/acore/TestSharedContextVBOES2NEWT2.java   |  168 ---
 .../junit/jogl/acore/TestShutdownCompleteAWT.java  |    4 +-
 .../junit/jogl/acore/TestShutdownCompleteNEWT.java |   14 +-
 .../junit/jogl/acore/TestShutdownSharedAWT.java    |  124 --
 .../junit/jogl/acore/TestShutdownSharedNEWT.java   |  127 --
 .../opengl/test/junit/jogl/awt/TestAWT01GLn.java   |   60 +-
 ...ava => TestBug461FBOSupersamplingSwingAWT.java} |   12 +-
 ...=> TestBug461PBufferSupersamplingSwingAWT.java} |    6 +-
 .../opengl/test/junit/jogl/awt/TestBug572AWT.java  |  127 ++
 .../opengl/test/junit/jogl/awt/TestBug611AWT.java  |   81 ++
 .../jogl/awt/TestJScrollPaneMixHwLw01AWT.java      |  172 +++
 .../junit/jogl/caps/TestBug605FlippedImageAWT.java |  185 +++
 .../jogl/caps/TestBug605FlippedImageNEWT.java      |  176 +++
 .../junit/jogl/caps/TestMultisampleES1AWT.java     |    2 +-
 .../junit/jogl/caps/TestMultisampleES1NEWT.java    |    2 +-
 .../junit/jogl/caps/TestMultisampleES2NEWT.java    |    2 +-
 .../opengl/test/junit/jogl/demos/GearsObject.java  |   14 +-
 .../opengl/test/junit/jogl/demos/PointsDemo.java}  |   32 +-
 .../opengl/test/junit/jogl/demos/es1/GearsES1.java |   50 +-
 .../test/junit/jogl/demos/es1/GearsObjectES1.java  |    7 +-
 .../junit/jogl/demos/es1/MultisampleDemoES1.java   |   11 +-
 .../test/junit/jogl/demos/es1/OneTriangle.java     |   11 +-
 .../test/junit/jogl/demos/es1/PointsDemoES1.java   |  198 +++
 .../test/junit/jogl/demos/es1/RedSquareES1.java    |   65 +-
 .../jogl/demos/es1/newt/TestGearsES1NEWT.java      |   27 +-
 .../jogl/demos/es1/newt/TestRedSquareES1NEWT.java  |   27 +-
 .../test/junit/jogl/demos/es2/FBOMix2DemosES2.java |   51 +-
 .../opengl/test/junit/jogl/demos/es2/GearsES2.java |   33 +-
 .../test/junit/jogl/demos/es2/GearsObjectES2.java  |   17 +-
 .../{FBOMix2DemosES2.java => Mix2TexturesES2.java} |  169 +--
 .../junit/jogl/demos/es2/MultisampleDemoES2.java   |   14 +-
 .../es2/{RedSquareES2.java => PointsDemoES2.java}  |  164 +--
 .../test/junit/jogl/demos/es2/RedSquareES2.java    |   31 +-
 .../jogl/demos/es2/TextureDraw01ES2Listener.java   |   17 +-
 .../junit/jogl/demos/es2/awt/TestGearsES2AWT.java  |   62 +-
 .../jogl/demos/es2/newt/TestGearsES2NEWT.java      |   52 +-
 .../jogl/demos/es2/newt/TestRedSquareES2NEWT.java  |   41 +-
 .../junit/jogl/demos/es2/shader/PointsShader.fp    |   47 +
 .../junit/jogl/demos/es2/shader/PointsShader.vp    |   47 +
 .../junit/jogl/demos/es2/shader/RedSquareShader.fp |   19 +-
 .../junit/jogl/demos/es2/shader/RedSquareShader.vp |   15 +-
 .../jogl/demos/es2/shader/RedSquareShader2.fp      |   22 +-
 .../test/junit/jogl/demos/es2/shader/default.vp    |    5 +
 .../shader/elektronenmultiplizierer_development.fp |   12 +-
 .../es2/shader/elektronenmultiplizierer_port.fp    |   12 +-
 .../test/junit/jogl/demos/es2/shader/gears.fp      |   10 +-
 .../test/junit/jogl/demos/es2/shader/gears.vp      |    7 +-
 .../junit/jogl/demos/es2/shader/mgl_default_xxx.fp |   10 +-
 .../junit/jogl/demos/es2/shader/mgl_default_xxx.vp |    4 +
 .../test/junit/jogl/demos/es2/shader/ruler.fp      |    9 +-
 .../junit/jogl/demos/es2/shader/texsequence_xxx.fp |    9 +-
 .../junit/jogl/demos/es2/shader/texsequence_xxx.vp |    5 +
 .../junit/jogl/demos/es2/shader/texture01_xxx.fp   |   10 +-
 .../junit/jogl/demos/es2/shader/texture01_xxx.vp   |    5 +
 .../junit/jogl/demos/es2/shader/texture02_xxx.fp   |   14 +-
 .../opengl/test/junit/jogl/demos/gl2/Gears.java    |   13 +-
 .../jogl/demos/gl2/awt/TestGLJPanelAWTBug450.java  |    2 +-
 .../demos/gl2/newt/TestGearsNewtAWTWrapper.java    |   20 +-
 .../junit/jogl/drawable/TestDrawable01NEWT.java    |  183 ---
 .../test/junit/jogl/glsl/GLSLMiscHelper.java       |    8 +-
 .../junit/jogl/glsl/TestGLSLShaderState01NEWT.java |   10 +-
 .../junit/jogl/glsl/TestGLSLShaderState02NEWT.java |   28 +-
 .../test/junit/jogl/glsl/TestRulerNEWT01.java      |    8 +-
 .../test/junit/jogl/offscreen/ReadBufferBase.java  |    2 +-
 .../test/junit/jogl/swt/TestNewtCanvasSWTGLn.java  |    2 +-
 .../junit/jogl/swt/TestSWTAccessor03AWTGLn.java    |  137 ++-
 .../junit/jogl/swt/TestSWTJOGLGLCanvas01GLn.java   |    2 +-
 .../junit/jogl/util/DemoGL2ES1ImmModeSink.java     |   97 ++
 .../test/junit/jogl/util/DemoGL2ES1Plain.java      |  161 +++
 .../jogl/util/DemoGL2ES1TextureImmModeSink.java    |  142 +++
 .../TestES1FixedFunctionPipelineNEWT.java}         |   95 +-
 .../junit/jogl/util/TestImmModeSinkES1NEWT.java    |  140 +++
 .../TestGLReadBufferUtilTextureIOWrite01AWT.java   |    4 +-
 .../TestGLReadBufferUtilTextureIOWrite01NEWT.java  |   16 +-
 .../TestGLReadBufferUtilTextureIOWrite02AWT.java   |    2 +-
 .../TestGLReadBufferUtilTextureIOWrite02NEWT.java  |    2 +-
 .../util/texture/TestPNGTextureFromFileAWT.java    |    2 +-
 .../util/texture/TestPNGTextureFromFileNEWT.java   |    2 +-
 .../test/junit/newt/TestFocus01SwingAWTRobot.java  |   27 +-
 .../test/junit/newt/TestFocus02SwingAWTRobot.java  |   20 +-
 .../junit/newt/TestNewtKeyCodeModifiersAWT.java    |  275 +++++
 ...SwingAWTRobot.java => TestNewtKeyCodesAWT.java} |  222 ++--
 .../junit/newt/TestNewtKeyEventAutoRepeatAWT.java  |  320 +++++
 ...AWTRobot.java => TestNewtKeyEventOrderAWT.java} |  210 ++--
 ...=> TestNewtKeyPressReleaseUnmaskRepeatAWT.java} |  197 +--
 .../test/junit/newt/TestRemoteGLWindows01NEWT.java |    1 -
 .../test/junit/newt/TestRemoteWindow01NEWT.java    |    2 +-
 .../test/junit/newt/TestScreenMode00NEWT.java      |    2 +-
 .../test/junit/newt/TestScreenMode00bNEWT.java     |    2 +-
 .../test/junit/newt/TestScreenMode01NEWT.java      |   50 +-
 .../opengl/test/junit/newt/TestWindows01NEWT.java  |    3 +-
 .../parenting/NewtAWTReparentingKeyAdapter.java    |    6 +-
 .../TestParentingFocusTraversal01AWT.java          |    5 +-
 .../opengl/test/junit/util/AWTFocusAdapter.java    |   11 +-
 .../opengl/test/junit/util/AWTKeyAdapter.java      |   65 +-
 .../opengl/test/junit/util/AWTMouseAdapter.java    |   43 +-
 .../opengl/test/junit/util/AWTRobotUtil.java       |  124 +-
 .../test/junit/util/AWTWindowFocusAdapter.java     |   11 +-
 .../opengl/test/junit/util/EventCountAdapter.java  |    9 +
 .../test/junit/util/InputEventCountAdapter.java    |    6 +
 ...CountAdapter.java => KeyEventCountAdapter.java} |   11 +-
 .../jogamp/opengl/test/junit/util/MiscUtils.java   |   48 +
 .../opengl/test/junit/util/NEWTFocusAdapter.java   |   11 +-
 .../opengl/test/junit/util/NEWTGLContext.java      |    4 +-
 .../opengl/test/junit/util/NEWTKeyAdapter.java     |   80 +-
 .../jogamp/opengl/test/junit/util/NEWTKeyUtil.java |  185 +++
 .../opengl/test/junit/util/NEWTMouseAdapter.java   |   44 +-
 .../jogamp/opengl/test/junit/util/UITestCase.java  |  159 ++-
 .../{MiscUtils.java => ValidateLockListener.java}  |   67 +-
 486 files changed, 25754 insertions(+), 12249 deletions(-)

diff --git a/doc/TODO.txt b/doc/TODO.txt
index d31466f..80eb7ba 100644
--- a/doc/TODO.txt
+++ b/doc/TODO.txt
@@ -1,9 +1,23 @@
-WIP:
+Version 2.0:
+
+- SIGG slides / video 
+- ES3 / GL 4.3
+
+
++++
+
+NVIDIA Tegra: discard problem (still exist?):
+  OK:
+    GL_RENDERER: NVIDIA Tegra
+    GL_VERSION: OpenGL ES 2.0 14.01002
 
-- GLPbuffer -> GLOffscreenAutoDrawable
-    - GLPbuffer GLDrawableFactory.createPbuffer() ->
-      GLOffscreenAutoDrawable GLDrawableFactory.createOffsceenAutoDrawable()
-    - Mark both deprecated!
++++
+
+TestSharedContextVBOES2NEWT crashes the NV driver sporadically.
+
+++
+
+WIP:
 
 - Optimize/Fix NIO caching of glMapBuffer/glUnmapBuffer
   - optimize the NIO caching, i.e. memory range, incr. reference count
diff --git a/doc/deployment/JOGL-DEPLOYMENT.html b/doc/deployment/JOGL-DEPLOYMENT.html
index abaa661..d4916a2 100644
--- a/doc/deployment/JOGL-DEPLOYMENT.html
+++ b/doc/deployment/JOGL-DEPLOYMENT.html
@@ -28,10 +28,61 @@
             <div id="main">
                 <div id="text" class="fill">
 
+                    <h1><a name="TraditionalApplets">Traditional Applets</a></h1>
+
+                    <p>
+                    You may choose to use traditional <a href="http://java.sun.com/applets/">Java Applets</a> to deploy your 
+                    in-browser applet and reference the JOGL resources.<p/>
+
+                    <p>
+                    This method simply requires a Java plugin and uses JogAmp's
+                    <a href="../userguide/index.html#automatednativelibraryloading">build-in method to automatically load</a>
+                    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>
+                    <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">
+                           <comment>
+                             <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/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">
+                                <noembed>Sorry, no Java support detected.</noembed>
+                             </embed>
+                           </comment>
+                        </object>
+                    </pre>
+
+
                     <h1><a name="JNLPFiles">JNLP Files</a></h1>
 
                     <p>
-                    You may choose to use JNLP to deploy your application
+                    You may choose to use JNLP to deploy your application or in-browser applet
                     and reference the JOGL resources.<p/>
 
                     <p>
@@ -45,7 +96,7 @@
                     <ul>
                         <li> <code><b> http://jogamp.org/deployment/jogamp-current/ </b></code> Current Version </li>
                         <li> <code><b> http://jogamp.org/deployment/jogamp-next/ </b></code> Next Version </li>
-                        <li> <code><b> http://jogamp.org/deployment/v2.0-rc3/ </b></code> Specific Version </li>
+                        <li> <code><b> http://jogamp.org/deployment/v2.0-rc10/ </b></code> Specific Version </li>
                     </ul>
 
                     <h2>Desktop All in One</h2>
@@ -103,8 +154,9 @@
                         <li>linux-amd64</li>
                         <li>linux-ia64</li>
                         <li>linux-i586</li>
-                        <li>linux-armv7</li>
-                        <li>android-armv7</li>
+                        <li>linux-armv6</li>
+                        <li>linux-armv6hf</li>
+                        <li>android-armv6</li>
                         <li>macosx-universal</li>
                         <li>solaris-sparc</li>
                         <li>solaris-sparcv9</li>
@@ -138,7 +190,7 @@
 
                     <a name="JOGLAllInOneJARsAWT">With AWT</a>:
                     <ul>
-                        <li><code>jogl.all.jar</code><br/>
+                        <li><code>jogl-all.jar</code><br/>
                             <ul>
                                 <li><code>jogl-all-natives-<b><i>os.and.arch</i></b>.jar</code></li>
                             </ul>
@@ -147,7 +199,7 @@
 
                     <a name="JOGLAllInOneJARsNoAWT">Without AWT</a>:
                     <ul>
-                        <li><code>jogl.all-noawt.jar</code><br/>
+                        <li><code>jogl-all-noawt.jar</code><br/>
                             <ul>
                                 <li><code>jogl-all-natives-<b><i>os.and.arch</i></b>.jar</code></li>
                             </ul>
@@ -156,7 +208,7 @@
 
                     <a name="JOGLAllInOneJARsMobile">Mobile</a>:
                     <ul>
-                        <li><code>jogl.all-mobile.jar</code><br/>
+                        <li><code>jogl-all-mobile.jar</code><br/>
                             <ul>
                                 <li><code>jogl-all-natives-<b><i>os.and.arch</i></b>.jar</code></li>
                             </ul>
@@ -165,7 +217,7 @@
 
                     <a name="JOGLAllInOneJARsAndroid">Android</a>:
                     <ul>
-                        <li><code>jogl.all-android.jar</code><br/>
+                        <li><code>jogl-all-android.jar</code><br/>
                             <ul>
                                 <li><code>jogl-all-natives-<b><i>os.and.arch</i></b>.jar</code></li>
                             </ul>
@@ -185,14 +237,14 @@
                     <ul>
                         <li>Mandatory:<br/>
                             <ul>
-                                <li>nativewindow.core.jar</li>
-                                <li>jogl.core.jar</li>
+                                <li>nativewindow-core.jar</li>
+                                <li>jogl-core.jar</li>
                             </ul></li>
 
                         <li>Newt (optional):<br/>
                             <ul>
-                                <li>newt.core.jar</li>
-                                <li>newt.ogl.jar  (to use NEWT with JOGL)</li>
+                                <li>newt-core.jar</li>
+                                <li>newt-ogl.jar  (to use NEWT with JOGL)</li>
                             </ul></li>
                     </ul>
 
@@ -203,23 +255,26 @@
                     <ul>
                         <li>NativeWindow [pick your platfrom, if available]:<br/>
                             <ul>
-                                <li>nativewindow.os.x11.jar</li>
+                                <li>nativewindow-os-x11.jar</li>
                             </ul></li>
 
                         <li>JOGL [pick your platform]:<br/>
                             <ul>
-                                <li>jogl.os.x11.jar</li>
-                                <li>jogl.os.win.jar</li>
-                                <li>jogl.os.osx.jar</li>
+                                <li>jogl-os-x11.jar</li>
+                                <li>jogl-os-win.jar</li>
+                                <li>jogl-os-osx.jar</li>
                                 <li>none</li>
                             </ul></li>
 
                         <li>Newt [pick your platform] (optional):<br/>
                             <ul>
-                                <li>newt.driver.x11.jar</li>
-                                <li>newt.driver.win.jar</li>
-                                <li>newt.driver.osx.jar</li>
-                                <li>newt.driver.kd.jar</li>
+                                <li>newt-driver-x11.jar</li>
+                                <li>newt-driver-win.jar</li>
+                                <li>newt-driver-osx.jar</li>
+                                <li>newt-driver-kd.jar</li>
+                                <li>newt-driver-bcm-vc.jar</li>
+                                <li>newt-driver-bcm-old.jar</li>
+                                <li>newt-driver-intelgdl.jar</li>
                                 <li>none</li>
                             </ul></li>
                     </ul>
@@ -231,17 +286,17 @@
                     <ul>
                         <li>Embedded Device Profiles<br/>
                             <ul>
-                                <li>jogl.glmobile.jar<br/>
+                                <li>jogl-glmobile.jar<br/>
                                     <ul>
-                                        <li>jogl.glmobile.dbg.jar</li>
+                                        <li>jogl-glmobile-dbg.jar</li>
                                     </ul></li>
                             </ul></li>
 
                         <li>Desktop Profiles<br/>
                             <ul>
-                                <li>jogl.gldesktop.jar<br/>
+                                <li>jogl-gldesktop.jar<br/>
                                     <ul>
-                                        <li>jogl.gldesktop.dbg.jar</li>
+                                        <li>jogl-gldesktop-dbg.jar</li>
                                     </ul></li>
                             </ul></li>
                     </ul>
@@ -249,26 +304,26 @@
 
                     <h4>JOGL Toolkits/Misc (optional)</h4>
                     <ul>
-                        <li>jogl.util.jar</li>
-                        <li>jogl.util.gl2.jar</li>
-                        <li>jogl.util.fixedfuncemu.jar</li>
+                        <li>jogl-util.jar</li>
+                        <li>jogl-util-gldesktop.jar</li>
+                        <li>jogl-util-fixedfuncemu.jar</li>
                     </ul>
 
 
                     <h4>AWT (optional) </h4>
 
                     <ul>
-                        <li> nativewindow.awt.jar</li>
-                        <li> jogl.awt.jar</li>
-                        <li> jogl.util.awt.jar (if using jogl.util)</li>
-                        <li> newt.awt.jar (if using with NEWT)</li>
+                        <li> nativewindow-awt.jar</li>
+                        <li> jogl-awt.jar</li>
+                        <li> jogl-util-awt.jar (if using jogl-util)</li>
+                        <li> newt-awt.jar (if using with NEWT)</li>
                     </ul>
 
                     <h4>GLU (optional) </h4>
                     <ul>
-                        <li>jogl.glutess.jar</li>
-                        <li>jogl.glumipmap.jar</li>
-                        <li>jogl.glugl2.jar</li>
+                        <li>jogl-glu-tess.jar</li>
+                        <li>jogl-glu-mipmap.jar</li>
+                        <li>jogl-glu-gldesktop.jar</li>
                     </ul>
 
                     <h2><a name="NativeLibraryFiles">Native Library Files</a></h2>
diff --git a/doc/userguide/index.html b/doc/userguide/index.html
index cdb26f1..f90a260 100644
--- a/doc/userguide/index.html
+++ b/doc/userguide/index.html
@@ -184,9 +184,9 @@ bundles.
 
 Modify your <code>CLASSPATH</code>
 environment variable to include the full paths to 
-<code>gluegen-rt.jar</code> and <code>jogl.all.jar</code>, for example
+<code>gluegen-rt.jar</code> and <code>jogl-all.jar</code>, for example
 <pre>
-".;C:\Some\Other\Package\foo.jar;C:\Users\myhome\jogamp-all-platforms\jar\gluegen-rt.jar;C:\Users\myhome\jogamp-all-platforms\jar\jogl.all.jar".
+".;C:\Some\Other\Package\foo.jar;C:\Users\myhome\jogamp-all-platforms\jar\gluegen-rt.jar;C:\Users\myhome\jogamp-all-platforms\jar\jogl-all.jar".
 </pre>
 (If you did not previously set the CLASSPATH environment variable, you
 may want to make sure that ".", the current directory, is on your new
@@ -208,9 +208,12 @@ size, in particular on smaller devices. See <a href="../deployment/JOGL-DEPLOYME
 <p>
 
 JOGL 2.0 has a brand new feature allowing to automatically extract the proper native 
-libraries required to use JOGL from JARs containing them without relying on the Java 
+libraries required to use JOGL 
+<a href="../deployment/JOGL-DEPLOYMENT.html#NativeJARFiles">from JARs containing them</a> 
+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> 
 to utilize the native library JAR files the same way Webstart/JNLP does.
 
 </p>
diff --git a/etc/test.sh b/etc/test.sh
index 1912a95..714c3d8 100755
--- a/etc/test.sh
+++ b/etc/test.sh
@@ -12,7 +12,7 @@ echo LIBGL_DRIVERS_PATH: $LIBGL_DRIVERS_PATH 2>&1 | tee -a $logfile
 echo LIBGL_DEBUG: $LIBGL_DEBUG 2>&1 | tee -a $logfile
 echo java $X_ARGS $D_ARGS $* 2>&1 | tee -a $logfile
 
-CLASSPATH=jar/gluegen-rt.jar:jar/jogl.all.jar
+CLASSPATH=jar/gluegen-rt.jar:jar/jogl-all.jar
 export CLASSPATH
 
 echo CLASSPATH: $CLASSPATH
diff --git a/jnlp-files/jogl-all-awt-cg.jnlp b/jnlp-files/jogl-all-awt-cg.jnlp
index 24c22c2..ab4c1cd 100644
--- a/jnlp-files/jogl-all-awt-cg.jnlp
+++ b/jnlp-files/jogl-all-awt-cg.jnlp
@@ -69,12 +69,16 @@
       <nativelib href = "jar/atomic/jogl-cg-natives-linux-amd64.jar" />
     </resources>
     <resources os="Linux" arch="arm">
-      <nativelib href = "jar/jogl-all-natives-linux-armv7.jar" />
-      <nativelib href = "jar/atomic/jogl-cg-natives-linux-armv7.jar" />
+      <nativelib href = "jar/jogl-all-natives-linux-armv6.jar" />
+      <nativelib href = "jar/jogl-all-natives-linux-armv6hf.jar" />
+      <nativelib href = "jar/atomic/jogl-cg-natives-linux-armv6.jar" />
+      <nativelib href = "jar/atomic/jogl-cg-natives-linux-armv6hf.jar" />
     </resources>
     <resources os="Linux" arch="armv7">
-      <nativelib href = "jar/jogl-all-natives-linux-armv7.jar" />
-      <nativelib href = "jar/atomic/jogl-cg-natives-linux-armv7.jar" />
+      <nativelib href = "jar/jogl-all-natives-linux-armv6.jar" />
+      <nativelib href = "jar/jogl-all-natives-linux-armv6hf.jar" />
+      <nativelib href = "jar/atomic/jogl-cg-natives-linux-armv6.jar" />
+      <nativelib href = "jar/atomic/jogl-cg-natives-linux-armv6hf.jar" />
     </resources>
     <resources os="Mac OS X" arch="i386">
       <nativelib href = "jar/jogl-all-natives-macosx-universal.jar" />
diff --git a/jnlp-files/jogl-all-awt.jnlp b/jnlp-files/jogl-all-awt.jnlp
index 4e05f8d..a666eb4 100644
--- a/jnlp-files/jogl-all-awt.jnlp
+++ b/jnlp-files/jogl-all-awt.jnlp
@@ -56,10 +56,12 @@
       <nativelib href = "jar/jogl-all-natives-linux-amd64.jar" />
     </resources>
     <resources os="Linux" arch="arm">
-      <nativelib href = "jar/jogl-all-natives-linux-armv7.jar" />
+      <nativelib href = "jar/jogl-all-natives-linux-armv6.jar" />
+      <nativelib href = "jar/jogl-all-natives-linux-armv6hf.jar" />
     </resources>
     <resources os="Linux" arch="armv7">
-      <nativelib href = "jar/jogl-all-natives-linux-armv7.jar" />
+      <nativelib href = "jar/jogl-all-natives-linux-armv6.jar" />
+      <nativelib href = "jar/jogl-all-natives-linux-armv6hf.jar" />
     </resources>
     <resources os="Mac OS X" arch="i386">
       <nativelib href = "jar/jogl-all-natives-macosx-universal.jar" />
diff --git a/jnlp-files/jogl-all-mobile.jnlp b/jnlp-files/jogl-all-mobile.jnlp
index 43b9b3b..710f74a 100644
--- a/jnlp-files/jogl-all-mobile.jnlp
+++ b/jnlp-files/jogl-all-mobile.jnlp
@@ -56,10 +56,12 @@
       <nativelib href = "jar/jogl-all-natives-linux-amd64.jar" />
     </resources>
     <resources os="Linux" arch="arm">
-      <nativelib href = "jar/jogl-all-natives-linux-armv7.jar" />
+      <nativelib href = "jar/jogl-all-natives-linux-armv6.jar" />
+      <nativelib href = "jar/jogl-all-natives-linux-armv6hf.jar" />
     </resources>
     <resources os="Linux" arch="armv7">
-      <nativelib href = "jar/jogl-all-natives-linux-armv7.jar" />
+      <nativelib href = "jar/jogl-all-natives-linux-armv6.jar" />
+      <nativelib href = "jar/jogl-all-natives-linux-armv6hf.jar" />
     </resources>
     <resources os="Mac OS X" arch="i386">
       <nativelib href = "jar/jogl-all-natives-macosx-universal.jar" />
diff --git a/jnlp-files/jogl-all-noawt.jnlp b/jnlp-files/jogl-all-noawt.jnlp
index eed6749..802b9b9 100644
--- a/jnlp-files/jogl-all-noawt.jnlp
+++ b/jnlp-files/jogl-all-noawt.jnlp
@@ -56,10 +56,12 @@
       <nativelib href = "jar/jogl-all-natives-linux-amd64.jar" />
     </resources>
     <resources os="Linux" arch="arm">
-      <nativelib href = "jar/jogl-all-natives-linux-armv7.jar" />
+      <nativelib href = "jar/jogl-all-natives-linux-armv6.jar" />
+      <nativelib href = "jar/jogl-all-natives-linux-armv6hf.jar" />
     </resources>
     <resources os="Linux" arch="armv7">
-      <nativelib href = "jar/jogl-all-natives-linux-armv7.jar" />
+      <nativelib href = "jar/jogl-all-natives-linux-armv6.jar" />
+      <nativelib href = "jar/jogl-all-natives-linux-armv6hf.jar" />
     </resources>
     <resources os="Mac OS X" arch="i386">
       <nativelib href = "jar/jogl-all-natives-macosx-universal.jar" />
diff --git a/jnlp-files/jogl-applet-runner-newt-gears-gl3-napplet.html b/jnlp-files/jogl-applet-runner-newt-gears-gl3-napplet.html
new file mode 100644
index 0000000..13d8919
--- /dev/null
+++ b/jnlp-files/jogl-applet-runner-newt-gears-gl3-napplet.html
@@ -0,0 +1,107 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+<title>JOGL NEWT Applet Runner - GearsES2 - GL3 Core - Normal Applet</title>
+</head>
+<body  BGCOLOR="#ffffff">
+
+<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>
+</ul>
+</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">
+   <param name="gl_debug" value="false">
+   <param name="gl_trace" value="false">
+   <comment>
+     <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/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"
+          gl_debug="false"
+          gl_trace="false">
+        <noembed>Sorry, no Java support detected.</noembed>
+     </embed>
+   </comment>
+</object>
+
+</P>
+
+<P>
+Applet is using a GL3 core context, failure is expected if n/a on your platform!
+</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="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">
+   <param name="gl_debug" value="false">
+   <param name="gl_trace" value="false">
+   <comment>
+     <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/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"
+          gl_debug="false"
+          gl_trace="false">
+        <noembed>Sorry, no Java support detected.</noembed>
+     </embed>
+   </comment>
+</object>
+
+</pre>
+
+</P>
+<P>
+
+Note that the jogl-test.jar, which contains the test applet class,
+<B>does not need to be signed</B>! JogAmp Community signs
+jogl.jar and gluegen-rt.jar, which contain
+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>
+
+</body>
+</html>
diff --git a/jnlp-files/jogl-test-applets.html b/jnlp-files/jogl-test-applets.html
index 81902a8..132945e 100644
--- a/jnlp-files/jogl-test-applets.html
+++ b/jnlp-files/jogl-test-applets.html
@@ -71,7 +71,8 @@ See Legend below table
                 <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>)<br/>
+                 (<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/>
             </td>
             <td>
                 Classic OpenGL Gears for ES2 
diff --git a/make/build-common.xml b/make/build-common.xml
index 4de5de5..a718ae0 100644
--- a/make/build-common.xml
+++ b/make/build-common.xml
@@ -140,7 +140,7 @@
           <istrue value="${isLinuxX86}" />
         </condition>
         <condition property="swt.jar" value="${project.root}/make/lib/swt/gtk-linux-x86/swt-debug.jar">
-          <istrue value="${isLinuxARMv7}" /> <!-- FIXME JAU .. hack -->
+          <istrue value="${isLinuxARMv6}" /> <!-- FIXME JAU .. hack -->
         </condition>
         <condition property="swt.jar" value="${project.root}/make/lib/swt/gtk-linux-x86/swt-debug.jar">
           <istrue value="${isAndroid}" /> <!-- FIXME JAU .. hack -->
@@ -278,6 +278,7 @@
         <property name="jogl-glmobile.jar"              value="${build.jogl}/jogl-glmobile.jar" />
         <property name="jogl-glmobile-dbg.jar"          value="${build.jogl}/jogl-glmobile-dbg.jar" />
         <property name="jogl-util.jar"                  value="${build.jogl}/jogl-util.jar" />
+        <property name="jogl-util-graph.jar"            value="${build.jogl}/jogl-util-graph.jar" />
         <property name="jogl-glutess.jar"               value="${build.jogl}/jogl-glu-tess.jar" />
         <property name="jogl-glumipmap.jar"             value="${build.jogl}/jogl-glu-mipmap.jar" />
         <property name="jogl-util-fixedfuncemu.jar"     value="${build.jogl}/jogl-util-fixedfuncemu.jar" />
@@ -301,6 +302,7 @@
             <pathelement location="${jogl-glmobile.jar}" />
             <pathelement location="${jogl-glmobile-dbg.jar}" />
             <pathelement location="${jogl-util.jar}" />
+            <pathelement location="${jogl-util-graph.jar}" />
             <pathelement location="${jogl-glutess.jar}" />
             <pathelement location="${jogl-glumipmap.jar}" />
             <pathelement location="${jogl-util-fixedfuncemu.jar}" />
@@ -322,6 +324,7 @@
             <pathelement location="${jogl-glmobile.jar}" />
             <pathelement location="${jogl-glmobile-dbg.jar}" />
             <pathelement location="${jogl-util.jar}" />
+            <pathelement location="${jogl-util-graph.jar}" />
             <pathelement location="${jogl-glutess.jar}" />
             <pathelement location="${jogl-glumipmap.jar}" />
             <pathelement location="${jogl-util-fixedfuncemu.jar}" />
@@ -339,6 +342,7 @@
             <pathelement location="${jogl-glmobile.jar}" />
             <pathelement location="${jogl-glmobile-dbg.jar}" />
             <pathelement location="${jogl-util.jar}" />
+            <pathelement location="${jogl-util-graph.jar}" />
             <pathelement location="${jogl-glutess.jar}" />
             <pathelement location="${jogl-glumipmap.jar}" />
             <pathelement location="${jogl-util-fixedfuncemu.jar}" />
@@ -350,6 +354,7 @@
             <pathelement location="${jogl-glmobile.jar}" />
             <pathelement location="${jogl-glmobile-dbg.jar}" />
             <pathelement location="${jogl-util.jar}" />
+            <pathelement location="${jogl-util-graph.jar}" />
             <pathelement location="${jogl-glutess.jar}" />
             <pathelement location="${jogl-glumipmap.jar}" />
             <pathelement location="${jogl-util-fixedfuncemu.jar}" />
@@ -357,41 +362,49 @@
             <pathelement location="${jogl-omx.jar}" />
         </path>
         <!-- 
-            ${jogl-core.jar} ${jogl-glutess.jar} ${jogl-glumipmap.jar} ${jogl-glu-gldesktop.jar} ${jogl-os-x11.jar} ${jogl-os-win.jar} ${jogl-os-osx.jar} ${jogl-gldesktop.jar} ${jogl-gldesktop-dbg.jar} ${jogl-glmobile.jar} ${jogl-glmobile-dbg.jar} ${jogl-omx.jar} ${jogl-util.jar} ${jogl-util-gldesktop.jar} ${jogl-util-awt.jar} ${jogl-util-fixedfuncemu.jar} ${jogl-sdk.jar} -->
+            ${jogl-core.jar} ${jogl-glutess.jar} ${jogl-glumipmap.jar} ${jogl-glu-gldesktop.jar} ${jogl-os-x11.jar} ${jogl-os-win.jar} ${jogl-os-osx.jar} ${jogl-gldesktop.jar} ${jogl-gldesktop-dbg.jar} ${jogl-glmobile.jar} ${jogl-glmobile-dbg.jar} ${jogl-omx.jar} ${jogl-util.jar} ${jogl-util-graph.jar} ${jogl-util-gldesktop.jar} ${jogl-util-awt.jar} ${jogl-util-fixedfuncemu.jar} ${jogl-sdk.jar} -->
 
         <property name="newt-core.jar"                  value="${build.newt}/newt-core.jar" />
         <property name="newt-ogl.jar"                   value="${build.newt}/newt-ogl.jar" />
         <property name="newt-awt.jar"                   value="${build.newt}/newt-awt.jar" />
         <property name="newt-swt.jar"                   value="${build.newt}/newt-swt.jar" />
         <property name="newt-event.jar"                 value="${build.newt}/newt-event.jar" />              <!-- using NEWT events w/o NEWT -->
+        <property name="newt-driver-linux.jar"          value="${build.newt}/newt-driver-linux.jar" />
         <property name="newt-driver-x11.jar"            value="${build.newt}/newt-driver-x11.jar" />
         <property name="newt-driver-win.jar"            value="${build.newt}/newt-driver-win.jar" />
         <property name="newt-driver-osx.jar"            value="${build.newt}/newt-driver-osx.jar" />
         <property name="newt-driver-android.jar"        value="${build.newt}/newt-driver-android.jar" />     <!-- excluded from all -->
         <property name="newt-driver-kd.jar"             value="${build.newt}/newt-driver-kd.jar" />          <!-- excluded from all -->
         <property name="newt-driver-intelgdl.jar"       value="${build.newt}/newt-driver-intelgdl.jar" />    <!-- excluded from all -->
-        <property name="newt-driver-broadcomegl.jar"    value="${build.newt}/newt-driver-broadcomegl.jar" /> <!-- excluded from all -->
+        <property name="newt-driver-bcm-old.jar"        value="${build.newt}/newt-driver-bcm-old.jar" />     <!-- excluded from all -->
+        <property name="newt-driver-bcm-vc.jar"         value="${build.newt}/newt-driver-bcm-vc.jar" />
         <path id="newt_all_atoms.classpath">
             <pathelement location="${newt-core.jar}" />
             <pathelement location="${newt-ogl.jar}" />
             <pathelement location="${newt-awt.jar}" />
             <pathelement location="${newt-swt.jar}" />
+            <pathelement location="${newt-driver-linux.jar}" />
             <pathelement location="${newt-driver-x11.jar}" />
             <pathelement location="${newt-driver-win.jar}" />
             <pathelement location="${newt-driver-osx.jar}" />
+            <pathelement location="${newt-driver-bcm-vc.jar}" />
         </path>
         <path id="newt_all-noawt_atoms.classpath">
             <pathelement location="${newt-core.jar}" />
             <pathelement location="${newt-ogl.jar}" />
+            <pathelement location="${newt-driver-linux.jar}" />
             <pathelement location="${newt-driver-x11.jar}" />
             <pathelement location="${newt-driver-win.jar}" />
             <pathelement location="${newt-driver-osx.jar}" />
+            <pathelement location="${newt-driver-bcm-vc.jar}" />
         </path>
         <path id="newt_all-mobile_atoms.classpath">
             <pathelement location="${newt-core.jar}" />
             <pathelement location="${newt-ogl.jar}" />
+            <pathelement location="${newt-driver-linux.jar}" />
             <pathelement location="${newt-driver-x11.jar}" />
             <pathelement location="${newt-driver-win.jar}" />
+            <pathelement location="${newt-driver-bcm-vc.jar}" />
         </path>
         <path id="newt_all-android_atoms.classpath">
             <pathelement location="${newt-core.jar}" />
diff --git a/make/build-jogl.xml b/make/build-jogl.xml
index 2605104..3c6f0fc 100644
--- a/make/build-jogl.xml
+++ b/make/build-jogl.xml
@@ -89,7 +89,7 @@
                   value="com/jogamp/gluegen/runtime/opengl/*"/>
 
         <property name="java.part.core" 
-                  value="${java.part.gluegen-gl-rt} javax/media/opengl/* javax/media/opengl/fixedfunc/* javax/media/opengl/glu/* javax/media/opengl/glu/gl2es1/* com/jogamp/opengl/* jogamp/opengl/* jogamp/opengl/glu/* jogamp/opengl/glu/error/*"/>
+                  value="${java.part.gluegen-gl-rt} javax/media/opengl/* javax/media/opengl/fixedfunc/* javax/media/opengl/glu/* javax/media/opengl/glu/gl2es1/* com/jogamp/opengl/* jogamp/opengl/* jogamp/opengl/glu/* jogamp/opengl/glu/error/* jogamp/opengl/shader/**"/>
         <property name="java.part.core.exclude" value="javax/media/opengl/Debug* javax/media/opengl/Trace*"/>
 
         <property name="java.part.nv-cg"
@@ -167,6 +167,9 @@
         <property name="java.part.util.graph.fonts"
                   value="jogamp/graph/font/fonts/**"/>
 
+        <property name="java.part.core.shadercode"
+                  value="jogamp/opengl/shader/* jogamp/opengl/shader/bin/**"/>
+
         <property name="java.part.util.graph.shadercode"
                   value="jogamp/graph/curve/opengl/shader/* jogamp/graph/curve/opengl/shader/bin/**"/>
 
@@ -177,7 +180,7 @@
                   value="jogamp/opengl/util/glsl/fixedfunc/shaders/* jogamp/opengl/util/glsl/fixedfunc/shaders/bin/**"/>
 
         <property name="java.part.nonjava" 
-                  value="${java.part.util.fixedfuncemu.shadercode} ${java.part.util.graph.shadercode} ${java.part.util.graph.fonts}"/>
+                  value="${java.part.core.shadercode} ${java.part.util.fixedfuncemu.shadercode} ${java.part.util.graph.shadercode} ${java.part.util.graph.fonts}"/>
 
         <property name="java.part.all-desktop" 
                   value="${java.part.sdk} ${java.part.glx} ${java.part.wgl} ${java.part.cgl} ${java.part.gldesktop} ${java.part.glugldesktop} ${java.part.util.gldesktop}"/>
@@ -1054,7 +1057,7 @@
         </javac>
     </target>
 
-    <target name="java.compile.secondpass.android" if="isAndroid">
+    <target name="java.compile.secondpass.android" if="android-jars.available">
         <!-- Perform the second pass Java compile; everything except portion of fixed function emulation depending on generated code. -->
         <javac destdir="${classes}"
                includes="${java.part.android}"
@@ -1119,7 +1122,7 @@
         <includepath path="/usr/local/include" />
       </compiler>
 
-      <compiler id="compiler.cfg.linux.armv7.jogl.x11" extends="compiler.cfg.linux.armv7">
+      <compiler id="compiler.cfg.linux.armv6.jogl.x11" extends="compiler.cfg.linux.armv6">
         <!-- Need to force /usr/include headers on to include path (after all others), due to crosscompiler usage -->
         <compilerarg value="-idirafter" />
         <compilerarg value="/usr/include" />
@@ -1147,7 +1150,7 @@
         <syslibset libs="X11"/>
       </linker>
 
-      <linker id="linker.cfg.linux.armv7.jogl.x11" extends="linker.cfg.linux.armv7">
+      <linker id="linker.cfg.linux.armv6.jogl.x11" extends="linker.cfg.linux.armv6">
         <syslibset dir="${env.TARGET_PLATFORM_ROOT}/usr/lib" libs="X11"/>
       </linker>
 
@@ -1236,10 +1239,10 @@
       <property name="linker.cfg.id.os"                    value="linker.cfg.linux.amd64.jogl.x11" />
     </target>
     
-    <target name="c.configure.linux.armv7" if="isLinuxARMv7">
-      <echo message="Linux.armv7" />
-      <property name="compiler.cfg.id"                     value="compiler.cfg.linux.armv7.jogl.x11" />
-      <property name="linker.cfg.id.os"                    value="linker.cfg.linux.armv7.jogl.x11" />
+    <target name="c.configure.linux.armv6" if="isLinuxARMv6">
+      <echo message="Linux.armv6" />
+      <property name="compiler.cfg.id"                     value="compiler.cfg.linux.armv6.jogl.x11" />
+      <property name="linker.cfg.id.os"                    value="linker.cfg.linux.armv6.jogl.x11" />
     </target>
     
     <target name="c.configure.linux.ia64" if="isLinuxIA64">
@@ -1284,7 +1287,7 @@
       <property name="linker.cfg.id.os"                    value="linker.cfg.linux.jogl.x11" />
     </target>
 
-    <target name="c.configure.linux" depends="c.configure.linux.armv7,c.configure.linux.x86,c.configure.linux.amd64,c.configure.linux.ia64,c.configure.linux.hppa,c.configure.linux.mips,c.configure.linux.mipsel,c.configure.linux.ppc,c.configure.linux.s390,c.configure.linux.sparc,c.configure.x11" if="isLinux" />
+    <target name="c.configure.linux" depends="c.configure.linux.armv6,c.configure.linux.x86,c.configure.linux.amd64,c.configure.linux.ia64,c.configure.linux.hppa,c.configure.linux.mips,c.configure.linux.mipsel,c.configure.linux.ppc,c.configure.linux.s390,c.configure.linux.sparc,c.configure.x11" if="isLinux" />
 
     <target name="c.configure.android" if="isAndroid">
       <echo message="Android" />
@@ -1375,7 +1378,7 @@
           <include name="${rootrel.src.c}/timespec.c" if="isOSX"/> <!-- currently only used for OSX -->
           <include name="${rootrel.src.c}/macosx/MacOSXCustomCGLCode.c" if="isOSX"/>
           <include name="${rootrel.src.c}/macosx/MacOSXWindowSystemInterface.m" if="isOSX"/>
-          <include name="${rootrel.src.c}/macosx/MacOSXWindowSystemInterface-pbuffer.m" if="isOSX"/>
+          <include name="${rootrel.src.c}/macosx/MacOSXWindowSystemInterface-calayer.m" if="isOSX"/>
           <include name="${rootrel.src.c}/macosx/ContextUpdater.m" if="isOSX"/>
           <include name="${rootrel.src.c}/GLXGetProcAddressARB.c" if="isX11"/>
           <!-- FIXME: the Mixer should be moved to another library -->
@@ -1550,7 +1553,7 @@
             <srcfileset dir="${src.java}"
                      includes="${java.part.nonjava}"/>
             <targetfileset dir="."
-                     includes="${jogl-util.jar} ${jogl-util-fixedfuncemu.jar}" />
+                     includes="${jogl-core.jar} ${jogl-util.jar} ${jogl-util-graph.jar} ${jogl-util-fixedfuncemu.jar}" />
         </dependset>
     </target>
     <target name="build-jars" depends="build-jars-dependset,build-jars-javase" />
@@ -1581,7 +1584,7 @@
         </jar>
     </target>
 
-    <target name="build-jars-android" depends="setup-manifestfile" if="isAndroid">
+    <target name="build-jars-android" depends="setup-manifestfile" if="android-jars.available">
         <jar manifest="${build.jogl}/manifest.mf" destfile="${jogl-os-android.jar}" filesonly="true">
             <fileset dir="${classes}" includes="${java.part.android}"/>
         </jar>
@@ -1662,10 +1665,14 @@
         </jar>
         <jar manifest="${build.jogl}/manifest.mf" destfile="${jogl-util.jar}" filesonly="true">
             <fileset dir="${classes}"
-                     includes="${java.part.util} ${java.part.util.glsl} ${java.part.util.graph}"
-                     excludes="${java.part.util.awt} ${java.part.util.gldesktop} ${java.part.util.fixedfuncemu}"/>
+                     includes="${java.part.util} ${java.part.util.glsl}"
+                     excludes="${java.part.util.awt} ${java.part.util.gldesktop} ${java.part.util.fixedfuncemu} ${java.part.util.graph}"/>
             <fileset dir="resources/assets" includes="jogl/util/**" />
         </jar>
+        <jar manifest="${build.jogl}/manifest.mf" destfile="${jogl-util-graph.jar}" filesonly="true">
+            <fileset dir="${classes}"
+                     includes="${java.part.util.graph}"/>
+        </jar>
         <jar manifest="${build.jogl}/manifest.mf" destfile="${jogl-util-fixedfuncemu.jar}" filesonly="true">
             <fileset dir="${classes}"
                      includes="${java.part.util.fixedfuncemu}"/>
diff --git a/make/build-nativewindow.xml b/make/build-nativewindow.xml
index c77558d..3c97d9d 100644
--- a/make/build-nativewindow.xml
+++ b/make/build-nativewindow.xml
@@ -342,7 +342,7 @@
         <includepath path="/usr/local/include" />
       </compiler>
 
-      <compiler id="compiler.cfg.linux.armv7.nativewindow.x11" extends="compiler.cfg.linux.armv7">
+      <compiler id="compiler.cfg.linux.armv6.nativewindow.x11" extends="compiler.cfg.linux.armv6">
         <!-- Need to force /usr/include headers on to include path (after all others), due to crosscompiler usage -->
         <compilerarg value="-idirafter" />
         <compilerarg value="/usr/include" />
@@ -396,7 +396,7 @@
         <syslibset libs="Xrender"/>
       </linker>
 
-      <linker id="linker.cfg.linux.armv7.nativewindow.x11" extends="linker.cfg.linux.armv7">
+      <linker id="linker.cfg.linux.armv6.nativewindow.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="Xxf86vm" />
         <syslibset dir="${env.TARGET_PLATFORM_ROOT}/usr/lib" libs="Xrender" />
@@ -487,10 +487,10 @@
       <property name="linker.cfg.id.oswin"                  value="linker.cfg.linux.amd64.nativewindow.x11" />
     </target>
     
-    <target name="c.configure.linux.armv7" if="isLinuxARMv7">
-      <echo message="Linux.armv7" />
-      <property name="compiler.cfg.id"                      value="compiler.cfg.linux.armv7.nativewindow.x11" />
-      <property name="linker.cfg.id.oswin"                  value="linker.cfg.linux.armv7.nativewindow.x11" />
+    <target name="c.configure.linux.armv6" if="isLinuxARMv6">
+      <echo message="Linux.armv6" />
+      <property name="compiler.cfg.id"                      value="compiler.cfg.linux.armv6.nativewindow.x11" />
+      <property name="linker.cfg.id.oswin"                  value="linker.cfg.linux.armv6.nativewindow.x11" />
     </target>
     
     <target name="c.configure.linux.ia64" if="isLinuxIA64">
@@ -535,7 +535,7 @@
       <property name="linker.cfg.id.oswin"                  value="linker.cfg.linux.nativewindow.x11" />
     </target>
 
-    <target name="c.configure.linux" depends="c.configure.linux.armv7,c.configure.linux.x86,c.configure.linux.amd64,c.configure.linux.ia64,c.configure.linux.hppa,c.configure.linux.mips,c.configure.linux.mipsel,c.configure.linux.ppc,c.configure.linux.s390,c.configure.linux.sparc,c.configure.x11" if="isLinux" />
+    <target name="c.configure.linux" depends="c.configure.linux.armv6,c.configure.linux.x86,c.configure.linux.amd64,c.configure.linux.ia64,c.configure.linux.hppa,c.configure.linux.mips,c.configure.linux.mipsel,c.configure.linux.ppc,c.configure.linux.s390,c.configure.linux.sparc,c.configure.x11" if="isLinux" />
 
     <target name="c.configure.android" if="isAndroid">
       <echo message="Android" />
@@ -759,6 +759,7 @@
 
     <target name="c.build.nativewindow.windowlib.x11" if="isX11">
       <javah destdir="${src.generated.c}/X11" classpath="${javah.classpath}" class="jogamp.nativewindow.x11.X11Lib" />
+      <javah destdir="${src.generated.c}/X11" classpath="${javah.classpath}" class="jogamp.nativewindow.x11.X11Util" />
 
       <c.build c.compiler.src.files="c.src.files.x11"
                output.lib.name="nativewindow_x11"
diff --git a/make/build-newt.xml b/make/build-newt.xml
index 7767088..7b9a518 100644
--- a/make/build-newt.xml
+++ b/make/build-newt.xml
@@ -48,7 +48,7 @@
        setup.noNativeDesktop
        setup.addNativeKD
        setup.addNativeIntelGDL
-       setup.addNativeBroadcomEGL
+       setup.addNativeBroadcom  ( always true if 'isLinux' )
 
    - Internal settings, may not be necessary to set them manually,
      since all JAR archives are orthogonal.
@@ -71,6 +71,10 @@
       -->
     <target name="base.init" depends="common.init">
 
+        <condition property="setup.addNativeBroadcom">
+           <isset property="isLinux"/>
+        </condition>
+
         <condition property="setup.nonatives">
             <and>
                 <isfalse value="${isWindows}" />
@@ -79,7 +83,7 @@
                 <isfalse value="${isAndroid}" />
                 <isfalse value="${setup.addNativeKD}" />
                 <isfalse value="${setup.addNativeIntelGDL}" />
-                <isfalse value="${setup.addNativeBroadcomEGL}" />
+                <isfalse value="${setup.addNativeBroadcom}" />
             </and>
         </condition>
 
@@ -90,7 +94,7 @@
         <echo message="isAndroid: ${isAndroid}" />
         <echo message="setup.addNativeKD: ${setup.addNativeKD}" />
         <echo message="setup.addNativeIntelGDL: ${setup.addNativeIntelGDL}" />
-        <echo message="setup.addNativeBroadcomEGL: ${setup.addNativeBroadcomEGL}" />
+        <echo message="setup.addNativeBroadcom: ${setup.addNativeBroadcom}" />
         <echo message="setup.nonatives: ${setup.nonatives}" />
 
         <!-- partitioning -->
@@ -110,6 +114,9 @@
         <property name="java.part.swt"
                   value="com/jogamp/newt/swt/**"/>
 
+        <property name="java.part.driver.linux"
+                  value="jogamp/newt/driver/linux/**"/>
+
         <property name="java.part.driver.x11"
                   value="jogamp/newt/driver/x11/**"/>
 
@@ -125,8 +132,11 @@
         <property name="java.part.driver.intelgdl"
                   value="jogamp/newt/driver/intel/gdl/**"/>
 
-        <property name="java.part.driver.broadcomegl"
-                  value="jogamp/newt/driver/broadcom/egl/**"/>
+        <property name="java.part.driver.bcm.old"
+                  value="jogamp/newt/driver/bcm/egl/**"/>
+
+        <property name="java.part.driver.bcm.vc"
+                  value="jogamp/newt/driver/bcm/vc/**"/>
 
         <property name="java.part.driver.android"
                   value="jogamp/newt/driver/android/**"/>
@@ -201,7 +211,8 @@
         <mkdir dir="${src.generated.c}/Windows" />
         <mkdir dir="${src.generated.c}/KD" />
         <mkdir dir="${src.generated.c}/IntelGDL" />
-        <mkdir dir="${src.generated.c}/BroadcomEGL" />
+        <mkdir dir="${src.generated.c}/bcm/egl" />
+        <mkdir dir="${src.generated.c}/bcm/vc/iv" />
         <mkdir dir="${classes}" />
         <mkdir dir="${obj.newt}" />
     </target>
@@ -226,7 +237,7 @@
         </javac>
     </target>
 
-    <target name="java.compile.android" if="isAndroid">
+    <target name="java.compile.android" if="android-jars.available">
         <javac destdir="${classes}"
                excludes="${java.excludes.all}"
                fork="yes"
@@ -254,7 +265,7 @@
         <includepath path="/usr/local/include" />
       </compiler>
 
-      <compiler id="compiler.cfg.linux.armv7.newt.x11" extends="compiler.cfg.linux.armv7">
+      <compiler id="compiler.cfg.linux.armv6.newt.x11" extends="compiler.cfg.linux.armv6">
         <!-- Need to force /usr/include headers on to include path (after all others), due to crosscompiler usage -->
         <compilerarg value="-idirafter" />
         <compilerarg value="/usr/include" />
@@ -274,7 +285,16 @@
         <syslibset libs="Xrandr"/>
       </linker>
 
-      <linker id="linker.cfg.linux.newt.broadcom_egl" extends="linker.cfg.linux">
+      <linker id="linker.cfg.linux.newt.bcm_egl" extends="linker.cfg.linux">
+        <syslibset libs="EGL"/>
+        <syslibset libs="GLES_CM"/>
+      </linker>
+
+      <linker id="linker.cfg.linux.newt.bcm_vc" extends="linker.cfg.linux">
+        <!-- syslibset libs="EGL"/ -->
+      </linker>
+
+      <linker id="linker.cfg.linux.newt.bcm_egl" extends="linker.cfg.linux">
         <syslibset libs="EGL"/>
         <syslibset libs="GLES_CM"/>
       </linker>
@@ -282,19 +302,25 @@
       <linker id="linker.cfg.linux.newt.x11" extends="linker.cfg.linux">
         <syslibset libs="X11"/>
         <syslibset libs="Xrandr"/>
+        <!--syslibset libs="xcb" /-->
+        <!--syslibset libs="X11-xcb" /-->
       </linker>
 
       <linker id="linker.cfg.linux.x86.newt.x11" extends="linker.cfg.linux.x86">
         <syslibset libs="X11"/>
         <syslibset libs="Xrandr"/>
+        <!--syslibset libs="xcb" /-->
+        <!--syslibset libs="X11-xcb" /-->
       </linker>
 
       <linker id="linker.cfg.linux.amd64.newt.x11" extends="linker.cfg.linux.amd64">
         <syslibset libs="X11"/>
         <syslibset libs="Xrandr"/>
+        <!--syslibset libs="xcb" /-->
+        <!--syslibset libs="X11-xcb" /-->
       </linker>
 
-      <linker id="linker.cfg.linux.armv7.newt.x11" extends="linker.cfg.linux.armv7">
+      <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" />
       </linker>
@@ -384,11 +410,11 @@
       <echo message="linker.cfg.id.oswin ${linker.cfg.id.oswin}" />
     </target>
 
-    <target name="c.configure.linux.armv7" if="isLinuxARMv7">
-      <echo message="Linux.armv7" />
-      <property name="compiler.cfg.id"                      value="compiler.cfg.linux.armv7.newt.x11" />
-      <condition property="linker.cfg.id.oswin"             value="linker.cfg.linux.armv7.newt.x11"
-                                                            else="linker.cfg.linux.armv7">
+    <target name="c.configure.linux.armv6" if="isLinuxARMv6">
+      <echo message="Linux.armv6" />
+      <property name="compiler.cfg.id"                      value="compiler.cfg.linux.armv6.newt.x11" />
+      <condition property="linker.cfg.id.oswin"             value="linker.cfg.linux.armv6.newt.x11"
+                                                            else="linker.cfg.linux.armv6">
           <isset property="isX11" />
       </condition>
       <echo message="linker.cfg.id.oswin ${linker.cfg.id.oswin}" />
@@ -460,7 +486,7 @@
       <property name="linker.cfg.id.oswin"                  value="linker.cfg.linux.newt.x11" />
     </target>
 
-    <target name="c.configure.linux" depends="c.configure.linux.x86,c.configure.linux.amd64,c.configure.linux.armv7,c.configure.linux.hppa,c.configure.linux.mips,c.configure.linux.mipsel,c.configure.linux.ppc,c.configure.linux.s390,c.configure.linux.sparc,c.configure.linux.ia64,c.configure.x11" if="isLinux"/>
+    <target name="c.configure.linux" depends="c.configure.linux.x86,c.configure.linux.amd64,c.configure.linux.armv6,c.configure.linux.hppa,c.configure.linux.mips,c.configure.linux.mipsel,c.configure.linux.ppc,c.configure.linux.s390,c.configure.linux.sparc,c.configure.linux.ia64,c.configure.x11" if="isLinux"/>
 
     <target name="c.configure.android" if="isAndroid">
       <echo message="Android" />
@@ -560,11 +586,14 @@
           <include name="${rootrel.src.c}/*.m"             if="isOSX"/>
           <include name="${rootrel.src.c}/AndroidWindow.c" if="isAndroid"/>
           <include name="${rootrel.src.c}/X11Display.c"    if="isX11"/>
+          <!-- include name="${rootrel.src.c}/X11Event.c"      if="isX11"/-->
+          <!-- include name="${rootrel.src.c}/XCBEvent.c"      if="isX11"/-->
           <include name="${rootrel.src.c}/X11Screen.c"     if="isX11"/>
           <include name="${rootrel.src.c}/X11Window.c"     if="isX11"/>
           <include name="${rootrel.src.c}/KDWindow.c"      if="setup.addNativeKD"/>
           <include name="${rootrel.src.c}/IntelGDL.c"      if="setup.addNativeIntelGDL"/>
-          <include name="${rootrel.src.c}/BroadcomEGL.c"   if="setup.addNativeBroadcomEGL"/>
+          <include name="${rootrel.src.c}/bcm_egl.c"       if="setup.addNativeBroadcom"/>
+          <include name="${rootrel.src.c}/bcm_vc_iv.c"     if="setup.addNativeBroadcom"/>
         </patternset>
 
         <echo message="Compiling @{output.lib.name}" />
@@ -609,7 +638,8 @@
                 <includepath path="${src.generated.c}/KD"           if="setup.addNativeKD" />
                 <includepath path="${src.generated.c}/IntelGDL"     if="setup.addNativeIntelGDL" />
                 <includepath path="stub_includes/embedded/IntelGDL" if="setup.addNativeIntelGDL" />
-                <includepath path="${src.generated.c}/BroadcomEGL"  if="setup.addNativeBroadcomEGL" />
+                <includepath path="${src.generated.c}/bcm/egl"      if="setup.addNativeBroadcom" />
+                <includepath path="${src.generated.c}/bcm/vc/iv"    if="setup.addNativeBroadcom" />
     
                 <!-- This must come last to not override real include paths -->
                 <!-- includepath path="stub_includes/macosx" if="isOSX" / -->
@@ -648,27 +678,30 @@
     </macrodef>
 
     <target name="c.build.newt.prepare">
-      <javah destdir="${src.generated.c}/KD"          classpath="${javah.classpath}" class="jogamp.newt.driver.kd.KDWindow" />
+      <javah destdir="${src.generated.c}/KD"          classpath="${javah.classpath}" class="jogamp.newt.driver.kd.WindowDriver" />
 
-      <javah destdir="${src.generated.c}/IntelGDL"    classpath="${javah.classpath}" class="jogamp.newt.driver.intel.gdl.Display" />
-      <javah destdir="${src.generated.c}/IntelGDL"    classpath="${javah.classpath}" class="jogamp.newt.driver.intel.gdl.Screen" />
-      <javah destdir="${src.generated.c}/IntelGDL"    classpath="${javah.classpath}" class="jogamp.newt.driver.intel.gdl.Window" />
+      <javah destdir="${src.generated.c}/IntelGDL"    classpath="${javah.classpath}" class="jogamp.newt.driver.intel.gdl.DisplayDriver" />
+      <javah destdir="${src.generated.c}/IntelGDL"    classpath="${javah.classpath}" class="jogamp.newt.driver.intel.gdl.ScreenDriver" />
+      <javah destdir="${src.generated.c}/IntelGDL"    classpath="${javah.classpath}" class="jogamp.newt.driver.intel.gdl.WindowDriver" />
 
-      <javah destdir="${src.generated.c}/BroadcomEGL" classpath="${javah.classpath}" class="jogamp.newt.driver.broadcom.egl.Window" />
+      <javah destdir="${src.generated.c}/bcm/egl"     classpath="${javah.classpath}" class="jogamp.newt.driver.bcm.egl.WindowDriver" />
+      <javah destdir="${src.generated.c}/bcm/vc/iv"   classpath="${javah.classpath}" class="jogamp.newt.driver.bcm.vc.iv.DisplayDriver" />
+      <javah destdir="${src.generated.c}/bcm/vc/iv"   classpath="${javah.classpath}" class="jogamp.newt.driver.bcm.vc.iv.ScreenDriver" />
+      <javah destdir="${src.generated.c}/bcm/vc/iv"   classpath="${javah.classpath}" class="jogamp.newt.driver.bcm.vc.iv.WindowDriver" />
 
-      <javah destdir="${src.generated.c}/Windows"     classpath="${javah.classpath}" class="jogamp.newt.driver.windows.WindowsWindow" />
-      <javah destdir="${src.generated.c}/Windows"     classpath="${javah.classpath}" class="jogamp.newt.driver.windows.WindowsScreen" />
-      <javah destdir="${src.generated.c}/Windows"     classpath="${javah.classpath}" class="jogamp.newt.driver.windows.WindowsDisplay" />
-      <javah destdir="${src.generated.c}/MacOSX"      classpath="${javah.classpath}" class="jogamp.newt.driver.macosx.MacWindow" />
-      <javah destdir="${src.generated.c}/MacOSX"      classpath="${javah.classpath}" class="jogamp.newt.driver.macosx.MacScreen" />
-      <javah destdir="${src.generated.c}/MacOSX"      classpath="${javah.classpath}" class="jogamp.newt.driver.macosx.MacDisplay" />
-      <javah destdir="${src.generated.c}/X11"         classpath="${javah.classpath}" class="jogamp.newt.driver.x11.X11Window" />
-      <javah destdir="${src.generated.c}/X11"         classpath="${javah.classpath}" class="jogamp.newt.driver.x11.X11Screen" />
-      <javah destdir="${src.generated.c}/X11"         classpath="${javah.classpath}" class="jogamp.newt.driver.x11.X11Display" />
+      <javah destdir="${src.generated.c}/Windows"     classpath="${javah.classpath}" class="jogamp.newt.driver.windows.WindowDriver" />
+      <javah destdir="${src.generated.c}/Windows"     classpath="${javah.classpath}" class="jogamp.newt.driver.windows.ScreenDriver" />
+      <javah destdir="${src.generated.c}/Windows"     classpath="${javah.classpath}" class="jogamp.newt.driver.windows.DisplayDriver" />
+      <javah destdir="${src.generated.c}/MacOSX"      classpath="${javah.classpath}" class="jogamp.newt.driver.macosx.WindowDriver" />
+      <javah destdir="${src.generated.c}/MacOSX"      classpath="${javah.classpath}" class="jogamp.newt.driver.macosx.ScreenDriver" />
+      <javah destdir="${src.generated.c}/MacOSX"      classpath="${javah.classpath}" class="jogamp.newt.driver.macosx.DisplayDriver" />
+      <javah destdir="${src.generated.c}/X11"         classpath="${javah.classpath}" class="jogamp.newt.driver.x11.WindowDriver" />
+      <javah destdir="${src.generated.c}/X11"         classpath="${javah.classpath}" class="jogamp.newt.driver.x11.ScreenDriver" />
+      <javah destdir="${src.generated.c}/X11"         classpath="${javah.classpath}" class="jogamp.newt.driver.x11.DisplayDriver" />
     </target>
 
     <target name="c.build.newt.prepare.android" if="isAndroid">
-      <javah destdir="${src.generated.c}/Android"     classpath="${javah.classpath}:${android.jar}" class="jogamp.newt.driver.android.AndroidWindow" />
+      <javah destdir="${src.generated.c}/Android"     classpath="${javah.classpath}:${android.jar}" class="jogamp.newt.driver.android.WindowDriver" />
     </target>
 
     <target name="c.build.newt.windowlib" unless="setup.nonatives">
@@ -730,6 +763,10 @@
     </target>
 
     <target name="build-jars-driver" depends="setup-manifestfile">
+        <jar manifest="${build.newt}/manifest.mf" destfile="${newt-driver-linux.jar}" filesonly="true">
+            <fileset dir="${classes}"
+                     includes="${java.part.driver.linux}"/>
+        </jar>
         <jar manifest="${build.newt}/manifest.mf" destfile="${newt-driver-x11.jar}" filesonly="true">
             <fileset dir="${classes}"
                      includes="${java.part.driver.x11}"/>
@@ -746,9 +783,13 @@
             <fileset dir="${classes}"
                      includes="${java.part.driver.kd}"/>
         </jar>
-        <jar manifest="${build.newt}/manifest.mf" destfile="${newt-driver-broadcomegl.jar}" filesonly="true">
+        <jar manifest="${build.newt}/manifest.mf" destfile="${newt-driver-bcm-old.jar}" filesonly="true">
+            <fileset dir="${classes}"
+                     includes="${java.part.driver.bcm.old}"/>
+        </jar>
+        <jar manifest="${build.newt}/manifest.mf" destfile="${newt-driver-bcm-vc.jar}" filesonly="true">
             <fileset dir="${classes}"
-                     includes="${java.part.driver.broadcomegl}"/>
+                     includes="${java.part.driver.bcm.vc}"/>
         </jar>
         <jar manifest="${build.newt}/manifest.mf" destfile="${newt-driver-intelgdl.jar}" filesonly="true">
             <fileset dir="${classes}"
@@ -773,7 +814,7 @@
         </jar>
     </target>
 
-    <target name="build-jars-android" depends="setup-manifestfile" if="isAndroid">
+    <target name="build-jars-android" depends="setup-manifestfile" if="android-jars.available">
         <jar manifest="${build.newt}/manifest.mf" destfile="${newt-driver-android.jar}" filesonly="true">
             <fileset dir="${classes}"
                      includes="${java.part.driver.android}"/>
diff --git a/make/build-test.xml b/make/build-test.xml
index f295ae3..3402b4d 100644
--- a/make/build-test.xml
+++ b/make/build-test.xml
@@ -96,7 +96,7 @@
         </jar>
     </target>
 
-    <target name="test.compile.android" if="isAndroid">
+    <target name="test.compile.android" if="android-jars.available">
         <!-- Perform the junit pass Java Android compile -->
         <javac destdir="${classes}"
                fork="yes"
@@ -129,7 +129,9 @@
                      includes="${java.part.test.all}"/>
             <fileset dir="resources/assets-test" includes="**" />
         </jar>
+    </target>
 
+    <target name="test.package.android" depends="test.compile.android" if="isAndroid">
         <aapt.signed 
             assetsdir="resources/assets-test"
             jarsrcdir="${src}/test"
@@ -171,7 +173,7 @@
             </fileset>
         </copy>
         <antcall target="test.compile.javase" inheritRefs="true" inheritAll="true"/>
-        <antcall target="test.compile.android" inheritRefs="true" inheritAll="true"/>
+        <antcall target="test.package.android" inheritRefs="true" inheritAll="true"/>
     </target>
 
     <target name="test.manual.run" depends="test.compile">
@@ -865,7 +867,7 @@ rsync:
     -rt 
 -->
 
-    <target name="junit.run.remote.adb" if="isAndroidARMv7">
+    <target name="junit.run.remote.adb" if="isAndroidARMv6">
         <echo message="#! /system/bin/sh${line.separator}" append="false" file="${build.test}/targetcommand.sh" />
         <echo message="${line.separator}
 rsync -rtv --delete --delete-after --delete-excluded \${line.separator}
diff --git a/make/build.xml b/make/build.xml
index 23aa218..44adf80 100644
--- a/make/build.xml
+++ b/make/build.xml
@@ -98,7 +98,7 @@
         </copy>
     </target>
 
-    <target name="one.jar.dir.android" depends="one.jar.dir.prep" if="isAndroid" unless="one.dir.skip">
+    <target name="one.jar.dir.android" depends="one.jar.dir.prep" if="android-jars.available" unless="one.dir.skip">
         <jar manifest="${build.jogl}/manifest.mf" destfile="${jogl-all-android.jar}" filesonly="true" excludes="META-INF/*">
             <archives>
                 <zips>
diff --git a/make/config/jogl/cgl-macosx.cfg b/make/config/jogl/cgl-macosx.cfg
index 7d17c4a..203802d 100644
--- a/make/config/jogl/cgl-macosx.cfg
+++ b/make/config/jogl/cgl-macosx.cfg
@@ -10,6 +10,10 @@ Include gl-common.cfg
 Include gl-common-extensions.cfg
 Include gl-desktop.cfg
 
+# Only NIO direct function, no arrays ..
+NIOOnly __ALL__
+NIODirectOnly __ALL__
+
 GLHeader GL/cglext.h
 
 Opaque long void *
diff --git a/make/config/jogl/cglext.cfg b/make/config/jogl/cglext.cfg
index 34a59dd..3c67084 100644
--- a/make/config/jogl/cglext.cfg
+++ b/make/config/jogl/cglext.cfg
@@ -14,6 +14,10 @@ ImplJavaClass CGLExtImpl
 Include gl-common.cfg
 Include gl-desktop.cfg
 
+# Only NIO direct function, no arrays ..
+NIOOnly __ALL__
+NIODirectOnly __ALL__
+
 GLHeader GL/cglext.h
 
 EmitProcAddressTable true
diff --git a/make/config/jogl/egl.cfg b/make/config/jogl/egl.cfg
index ee74b46..b309850 100644
--- a/make/config/jogl/egl.cfg
+++ b/make/config/jogl/egl.cfg
@@ -9,6 +9,10 @@ Style AllStatic
 # Shouldn't matter which one of these we pick up
 Include egl-common.cfg
 
+# Only NIO direct function, no arrays ..
+NIOOnly __ALL__
+NIODirectOnly __ALL__
+
 HierarchicalNativeOutput false
 
 # Use a ProcAddressTable so we dynamically look up the routines
@@ -44,7 +48,7 @@ CustomJavaCode EGL  {
 CustomJavaCode EGL    if (eglGetProcAddressHandle == 0) {
 CustomJavaCode EGL      throw new GLException("Passed null pointer for method \"eglGetProcAddress\"");
 CustomJavaCode EGL    }
-CustomJavaCode EGL    return dispatch_eglGetProcAddress1(procname, eglGetProcAddressHandle);
+CustomJavaCode EGL    return dispatch_eglGetProcAddress0(procname, eglGetProcAddressHandle);
 CustomJavaCode EGL  }
 
 
diff --git a/make/config/jogl/eglext.cfg b/make/config/jogl/eglext.cfg
index 2e422ff..a7fb454 100644
--- a/make/config/jogl/eglext.cfg
+++ b/make/config/jogl/eglext.cfg
@@ -11,6 +11,10 @@ ImplJavaClass EGLExtImpl
 # Shouldn't matter which one of these we pick up
 Include egl-common.cfg
 
+# Only NIO direct function, no arrays ..
+NIOOnly __ALL__
+NIODirectOnly __ALL__
+
 ExtendedInterfaceSymbolsIgnore ../build-temp/gensrc/classes/jogamp/opengl/egl/EGL.java
 
 HierarchicalNativeOutput false
diff --git a/make/config/jogl/gl-common.cfg b/make/config/jogl/gl-common.cfg
index 9c54675..f8f4f07 100644
--- a/make/config/jogl/gl-common.cfg
+++ b/make/config/jogl/gl-common.cfg
@@ -360,48 +360,55 @@ ReturnsString glGetStringi
 # NIOOnly __ALL__
 
 #
-# NIODirectOnly directives for vertex arrays and other core routines
+# NIODirectOnly directives for pointer functions 
+#               essential where memory needs to be kept pinpointed after the function call.
 #               essential where the buffer lifecycle extends the function call.
 #
-# Note: API calls like glColorPointer(..) will not be exploded to 
-#       multiple primitive arrays, since the pointer argument is 'void *'.
+# Note-1:       API calls like glColorPointer(..) will not be exploded to 
+#               multiple primitive arrays, since the pointer argument is 'void *'.
 #
-
-#NIO Review: No technical reason to constrain array access for these:
-#NIODirectOnly glColorPointer
-#NIODirectOnly glEdgeFlagPointer
-#NIODirectOnly glIndexPointer
-#NIODirectOnly glNormalPointer
-#NIODirectOnly glTexCoordPointer
-#NIODirectOnly glVertexPointer
-#NIODirectOnly glVertexAttribPointer
-#NIODirectOnly glFogCoordPointer
-#NIODirectOnly glSecondaryColorPointer
-
-#Return values
-#NIODirectOnly glGenBuffers
-#NIODirectOnly glGetPointerv
-#NIODirectOnly glFeedbackBuffer
-#NIODirectOnly glSelectBuffer
-#NIODirectOnly glGetBufferSubData
-
-#
-# NIODirectOnly directives for other extensions
+# Note-2:       It may be possible to track the primitive non-direct NIO backed arrays and pinpoint them.
+#               JNI's Get*ArrayElements may be able to pinpoint, however it could result
+#               in a copy of the data, which would render this feature non performant. 
+#               The tracking itself may be another no-go, since it would add up complexity
+#               and failing to free resources would be another negative sideeffect.
 #
-#NIO Review: No technical reason to constrain array access for these:
-#NIODirectOnly glMatrixIndexPointerARB
+NIODirectOnly glColorPointer
+NIODirectOnly glEdgeFlagPointer
+NIODirectOnly glFeedbackBuffer
+NIODirectOnly glFogCoordPointer
+NIODirectOnly glGetBufferSubData
 NIODirectOnly glGetProgramStringARB
+NIODirectOnly glIndexPointer
+NIODirectOnly glMatrixIndexPointerARB
+NIODirectOnly glMultiTexCoordPointerEXT
+NIODirectOnly glNormalPointer
 NIODirectOnly glPixelDataRangeNV
+NIODirectOnly glSecondaryColorPointer
+NIODirectOnly glSelectBuffer
+NIODirectOnly glTangentPointerEXT
+NIODirectOnly glTexCoordPointer
+NIODirectOnly glVariantPointerEXT
 NIODirectOnly glVertexArrayRangeNV
 NIODirectOnly glVertexArrayRangeApple
+NIODirectOnly glVertexAttribIPointer
+NIODirectOnly glVertexAttribLPointer
+NIODirectOnly glVertexAttribPointer
+NIODirectOnly glVertexPointer
+NIODirectOnly glVertexWeightPointerEXT
+NIODirectOnly glWeightPointerARB
 NIODirectOnly wglFreeMemoryNV
 NIODirectOnly glXFreeMemoryNV
 
+#NIO Review: No technical reason to constrain array access for these:
+#Return values
+#NIODirectOnly glGenBuffers
+#NIODirectOnly glGetPointerv
+
 #
-# NIOOnly for a few API calls ..
+# NIODirectOnly directives for other extensions
 #
-NIOOnly glVertexAttribPointerNV
-NIOOnly glVertexWeightPointerEXT
+#NIO Review: No technical reason to constrain array access for these:
 
 # Capacity of wglAllocateMemoryNV/glXAllocateMemoryNV return value is
 # same as value of first argument
@@ -532,6 +539,8 @@ BufferObjectKind Array glVertexPointer
 BufferObjectKind Array glVertexAttribPointer
 BufferObjectKind Array glVertexAttribPointerARB
 BufferObjectKind Array glVertexAttribPointerNV
+BufferObjectKind Array glVertexAttribIPointer
+BufferObjectKind Array glVertexAttribLPointer
 BufferObjectKind Array glVertexWeightPointerEXT
 BufferObjectKind Array glWeightPointerARB
 
@@ -604,6 +613,8 @@ RangeCheck glTexCoordPointer          3 1
 RangeCheck glVariantPointerEXT        3 1
 RangeCheck glVertexPointer            3 1
 RangeCheck glVertexAttribPointer      5 1
+RangeCheck glVertexAttribIPointer     4 1
+RangeCheck glVertexAttribLPointer     4 1
 RangeCheck glVertexAttribPointerARB   5 1
 RangeCheck glWeightPointerARB         3 1
 
diff --git a/make/config/jogl/gl-gl4bc.cfg b/make/config/jogl/gl-gl4bc.cfg
index ae77b2e..ce68831 100644
--- a/make/config/jogl/gl-gl4bc.cfg
+++ b/make/config/jogl/gl-gl4bc.cfg
@@ -87,6 +87,16 @@ CustomJavaCode GL4bcImpl   glFrustum((double)left, (double)right, (double)bottom
 CustomJavaCode GL4bcImpl public void glOrthof(float left, float right, float bottom, float top, float zNear, float zFar) {
 CustomJavaCode GL4bcImpl   glOrtho((double)left, (double)right, (double)bottom, (double)top, (double)zNear, (double)zFar); }
 
+JavaPrologue glDepthRangef if ( !_context.isGLES2Compatible() ) {
+JavaPrologue glDepthRangef   glDepthRange( (double)zNear, (double)zFar );  
+JavaPrologue glDepthRangef   return;
+JavaPrologue glDepthRangef }
+
+JavaPrologue glClearDepthf if ( !_context.isGLES2Compatible() ) {
+JavaPrologue glClearDepthf   glClearDepth( (double)depth );  
+JavaPrologue glClearDepthf   return;
+JavaPrologue glClearDepthf }
+
 Include gl-headers.cfg
 Include gl3ext-headers.cfg
 
diff --git a/make/config/jogl/gl-impl-CustomJavaCode-common.java b/make/config/jogl/gl-impl-CustomJavaCode-common.java
index b05ba26..283a4e6 100644
--- a/make/config/jogl/gl-impl-CustomJavaCode-common.java
+++ b/make/config/jogl/gl-impl-CustomJavaCode-common.java
@@ -51,6 +51,26 @@
     }
 
     @Override
+    public final boolean hasBasicFBOSupport() {
+      return _context.hasBasicFBOSupport();
+    }
+
+    @Override
+    public final boolean hasFullFBOSupport() {
+      return _context.hasFullFBOSupport();
+    }
+
+    @Override
+    public final int getMaxRenderbufferSamples() {
+      return _context.getMaxRenderbufferSamples();
+    }
+
+    @Override
+    public final boolean isTextureFormatBGRA8888Available() {
+      return _context.isTextureFormatBGRA8888Available();
+    }
+
+    @Override
     public final GLContext getContext() {
       return _context;
     }
diff --git a/make/config/jogl/gl2_es2-common.cfg b/make/config/jogl/gl2_es2-common.cfg
index d26c76e..b769f3b 100644
--- a/make/config/jogl/gl2_es2-common.cfg
+++ b/make/config/jogl/gl2_es2-common.cfg
@@ -11,13 +11,3 @@ JavaPrologue glGetShaderPrecisionFormat if ( !_context.isGLES2Compatible() ) {
 JavaPrologue glGetShaderPrecisionFormat     throw new GLException("Method \"glGetShaderPrecisionFormat\" not available");
 JavaPrologue glGetShaderPrecisionFormat }
 
-JavaPrologue glDepthRangef if ( !_context.isGLES2Compatible() ) {
-JavaPrologue glDepthRangef   glDepthRange( (double)zNear, (double)zFar );  
-JavaPrologue glDepthRangef   return;
-JavaPrologue glDepthRangef }
-
-JavaPrologue glClearDepthf if ( !_context.isGLES2Compatible() ) {
-JavaPrologue glClearDepthf   glClearDepth( (double)depth );  
-JavaPrologue glClearDepthf   return;
-JavaPrologue glClearDepthf }
-
diff --git a/make/config/jogl/glx-CustomCCode.c b/make/config/jogl/glx-CustomCCode.c
index e372e51..71dc68b 100644
--- a/make/config/jogl/glx-CustomCCode.c
+++ b/make/config/jogl/glx-CustomCCode.c
@@ -89,36 +89,30 @@ Java_jogamp_opengl_x11_glx_GLX_dispatch_1glXGetVisualFromFBConfig(JNIEnv *env, j
 
 /*   Java->C glue code:
  *   Java package: jogamp.opengl.x11.glx.GLX
- *    Java method: java.nio.LongBuffer glXChooseFBConfig(long dpy, int screen, java.nio.IntBuffer attribList, java.nio.IntBuffer nitems)
+ *    Java method: com.jogamp.common.nio.PointerBuffer dispatch_glXChooseFBConfig(long dpy, int screen, java.nio.IntBuffer attribList, java.nio.IntBuffer nitems)
  *     C function: GLXFBConfig *  glXChooseFBConfig(Display *  dpy, int screen, const int *  attribList, int *  nitems);
  */
 JNIEXPORT jobject JNICALL 
 Java_jogamp_opengl_x11_glx_GLX_dispatch_1glXChooseFBConfig(JNIEnv *env, jclass _unused, jlong dpy, jint screen, jobject attribList, jint attribList_byte_offset, jobject nitems, jint nitems_byte_offset, jlong procAddress) {
-  typedef GLXFBConfig* (APIENTRY*_local_PFNGLXCHOOSEFBCONFIG)(Display *  dpy, int screen, const int *  attribList, int *  nitems);
-  _local_PFNGLXCHOOSEFBCONFIG ptr_glXChooseFBConfig;
-  int * _ptr2 = NULL;
-  int * _ptr3 = NULL;
+  typedef GLXFBConfig *  (APIENTRY*_local_PFNGLXCHOOSEFBCONFIGPROC)(Display *  dpy, int screen, const int *  attribList, int *  nitems);
+  _local_PFNGLXCHOOSEFBCONFIGPROC ptr_glXChooseFBConfig;
+  int * _attribList_ptr = NULL;
+  int * _nitems_ptr = NULL;
   GLXFBConfig *  _res;
   int count;
   jobject jbyteSource;
   jobject jbyteCopy;
-  ptr_glXChooseFBConfig = (_local_PFNGLXCHOOSEFBCONFIG) (intptr_t) procAddress;
+    if ( NULL != attribList ) {
+        _attribList_ptr = (int *) (((char*) (*env)->GetDirectBufferAddress(env, attribList)) + attribList_byte_offset);
+    }
+    if ( NULL != nitems ) {
+        _nitems_ptr = (int *) (((char*) (*env)->GetDirectBufferAddress(env, nitems)) + nitems_byte_offset);
+    }
+  ptr_glXChooseFBConfig = (_local_PFNGLXCHOOSEFBCONFIGPROC) (intptr_t) procAddress;
   assert(ptr_glXChooseFBConfig != NULL);
-  if (attribList != NULL) {
-    _ptr2 = (int *) (((char*) (*env)->GetPrimitiveArrayCritical(env, attribList, NULL)) + attribList_byte_offset);
-  }
-  if (nitems != NULL) {
-    _ptr3 = (int *) (((char*) (*env)->GetPrimitiveArrayCritical(env, nitems, NULL)) + nitems_byte_offset);
-  }
-  _res = (*ptr_glXChooseFBConfig)((Display *) (intptr_t) dpy, (int) screen, (int *) _ptr2, (int *) _ptr3);
-  count = _ptr3[0];
-  if (attribList != NULL) {
-    (*env)->ReleasePrimitiveArrayCritical(env, attribList, _ptr2, 0);
-  }
-  if (nitems != NULL) {
-    (*env)->ReleasePrimitiveArrayCritical(env, nitems, _ptr3, 0);
-  }
-  if (_res == NULL) return NULL;
+  _res = (* ptr_glXChooseFBConfig) ((Display *) (intptr_t) dpy, (int) screen, (int *) _attribList_ptr, (int *) _nitems_ptr);
+  count = _nitems_ptr[0];
+  if (NULL == _res) return NULL;
 
   _initClazzAccess(env);
 
@@ -130,29 +124,27 @@ Java_jogamp_opengl_x11_glx_GLX_dispatch_1glXChooseFBConfig(JNIEnv *env, jclass _
   return jbyteCopy;
 }
 
+
 /*   Java->C glue code:
  *   Java package: jogamp.opengl.x11.glx.GLX
- *    Java method: XVisualInfo glXChooseVisual(long dpy, int screen, java.nio.IntBuffer attribList)
+ *    Java method: XVisualInfo dispatch_glXChooseVisual(long dpy, int screen, java.nio.IntBuffer attribList)
  *     C function: XVisualInfo *  glXChooseVisual(Display *  dpy, int screen, int *  attribList);
  */
 JNIEXPORT jobject JNICALL 
 Java_jogamp_opengl_x11_glx_GLX_dispatch_1glXChooseVisual(JNIEnv *env, jclass _unused, jlong dpy, jint screen, jobject attribList, jint attribList_byte_offset, jlong procAddress) {
-  typedef XVisualInfo* (APIENTRY*_local_PFNGLXCHOOSEVISUAL)(Display *  dpy, int screen, int *  attribList);
-  _local_PFNGLXCHOOSEVISUAL ptr_glXChooseVisual;
-  int * _ptr2 = NULL;
+  typedef XVisualInfo *  (APIENTRY*_local_PFNGLXCHOOSEVISUALPROC)(Display *  dpy, int screen, int *  attribList);
+  _local_PFNGLXCHOOSEVISUALPROC ptr_glXChooseVisual;
+  int * _attribList_ptr = NULL;
   XVisualInfo *  _res;
   jobject jbyteSource;
   jobject jbyteCopy;
-  ptr_glXChooseVisual = (_local_PFNGLXCHOOSEVISUAL) (intptr_t) procAddress;
+    if ( NULL != attribList ) {
+        _attribList_ptr = (int *) (((char*) (*env)->GetDirectBufferAddress(env, attribList)) + attribList_byte_offset);
+    }
+  ptr_glXChooseVisual = (_local_PFNGLXCHOOSEVISUALPROC) (intptr_t) procAddress;
   assert(ptr_glXChooseVisual != NULL);
-  if (attribList != NULL) {
-    _ptr2 = (int *) (((char*) (*env)->GetPrimitiveArrayCritical(env, attribList, NULL)) + attribList_byte_offset);
-  }
-  _res = (*ptr_glXChooseVisual)((Display *) (intptr_t) dpy, (int) screen, (int *) _ptr2);
-  if (attribList != NULL) {
-    (*env)->ReleasePrimitiveArrayCritical(env, attribList, _ptr2, 0);
-  }
-  if (_res == NULL) return NULL;
+  _res = (* ptr_glXChooseVisual) ((Display *) (intptr_t) dpy, (int) screen, (int *) _attribList_ptr);
+  if (NULL == _res) return NULL;
 
   _initClazzAccess(env);
 
diff --git a/make/config/jogl/glx-CustomJavaCode.java b/make/config/jogl/glx-CustomJavaCode.java
index 36ad100..ed126a5 100644
--- a/make/config/jogl/glx-CustomJavaCode.java
+++ b/make/config/jogl/glx-CustomJavaCode.java
@@ -16,43 +16,49 @@
   private static native java.nio.ByteBuffer dispatch_glXGetVisualFromFBConfig(long dpy, long config, long procAddr);
 
 
-  /** Interface to C language function: <br> - Alias for: <br> <code> GLXFBConfig *  glXChooseFBConfigSGIX, glXChooseFBConfig(Display *  dpy, int screen, const int *  attribList, int *  nitems); </code>    */
-  public static com.jogamp.common.nio.PointerBuffer glXChooseFBConfig(long dpy, int screen, int[] attribList, int attribList_offset, int[] nitems, int nitems_offset)
-  {
+  /** Entry point to C language function: <code> GLXFBConfig *  glXChooseFBConfig(Display *  dpy, int screen, const int *  attribList, int *  nitems); </code> <br>Part of CORE FUNC
+      @param attribList a direct only {@link java.nio.IntBuffer}
+      @param nitems a direct only {@link java.nio.IntBuffer}   */
+  public static PointerBuffer glXChooseFBConfig(long dpy, int screen, IntBuffer attribList, IntBuffer nitems)  {
+
+    if (!Buffers.isDirect(attribList))
+      throw new GLException("Argument \"attribList\" is not a direct buffer");
+    if (!Buffers.isDirect(nitems))
+      throw new GLException("Argument \"nitems\" is not a direct buffer");
     final long __addr_ = glxProcAddressTable._addressof_glXChooseFBConfig;
     if (__addr_ == 0) {
-        throw new GLException("Method \"glXChooseFBConfig\" not available");
+      throw new GLException("Method \"glXChooseFBConfig\" not available");
     }
-    if(attribList != null && attribList.length <= attribList_offset)
-      throw new GLException("array offset argument \"attribList_offset\" (" + attribList_offset + ") equals or exceeds array length (" + attribList.length + ")");
-    if(nitems != null && nitems.length <= nitems_offset)
-      throw new GLException("array offset argument \"nitems_offset\" (" + nitems_offset + ") equals or exceeds array length (" + nitems.length + ")");
-    java.nio.ByteBuffer _res;
-    _res = dispatch_glXChooseFBConfig(dpy, screen, attribList, Buffers.SIZEOF_INT * attribList_offset, nitems, Buffers.SIZEOF_INT * nitems_offset, __addr_);
-
+    final ByteBuffer _res;
+    _res = dispatch_glXChooseFBConfig(dpy, screen, attribList, Buffers.getDirectBufferByteOffset(attribList), nitems, Buffers.getDirectBufferByteOffset(nitems), __addr_);
     if (_res == null) return null;
+    Buffers.nativeOrder(_res);
     return PointerBuffer.wrap(_res);
   }
 
-  /** Entry point to C language function: - Alias for: <br> <code> GLXFBConfig *  glXChooseFBConfigSGIX, glXChooseFBConfig(Display *  dpy, int screen, const int *  attribList, int *  nitems); </code>    */
-  private static native java.nio.ByteBuffer dispatch_glXChooseFBConfig(long dpy, int screen, Object attribList, int attribList_byte_offset, Object nitems, int nitems_byte_offset, long procAddr);
+  /** Entry point to C language function: <code> GLXFBConfig *  glXChooseFBConfig(Display *  dpy, int screen, const int *  attribList, int *  nitems); </code> <br>Part of CORE FUNC
+      @param attribList a direct only {@link java.nio.IntBuffer}
+      @param nitems a direct only {@link java.nio.IntBuffer}   */
+  private static native ByteBuffer dispatch_glXChooseFBConfig(long dpy, int screen, Object attribList, int attribList_byte_offset, Object nitems, int nitems_byte_offset, long procAddress);
 
-  /** Interface to C language function: <br> - Alias for: <br> <code> XVisualInfo *  glXChooseVisual(Display *  dpy, int screen, int *  attribList); </code>    */
-  public static XVisualInfo glXChooseVisual(long dpy, int screen, int[] attribList, int attribList_offset)
-  {
+
+  /** Entry point to C language function: <code> XVisualInfo *  glXChooseVisual(Display *  dpy, int screen, int *  attribList); </code> <br>Part of <code>GLX_VERSION_1_X</code>
+      @param attribList a direct only {@link java.nio.IntBuffer}   */
+  public static XVisualInfo glXChooseVisual(long dpy, int screen, IntBuffer attribList)  {
+
+    if (!Buffers.isDirect(attribList))
+      throw new GLException("Argument \"attribList\" is not a direct buffer");
     final long __addr_ = glxProcAddressTable._addressof_glXChooseVisual;
     if (__addr_ == 0) {
-        throw new GLException("Method \"glXChooseVisual\" not available");
+      throw new GLException("Method \"glXChooseVisual\" not available");
     }
-    if(attribList != null && attribList.length <= attribList_offset)
-      throw new GLException("array offset argument \"attribList_offset\" (" + attribList_offset + ") equals or exceeds array length (" + attribList.length + ")");
-    java.nio.ByteBuffer _res;
-    _res = dispatch_glXChooseVisual(dpy, screen, attribList, Buffers.SIZEOF_INT * attribList_offset, __addr_);
-
+    final ByteBuffer _res;
+    _res = dispatch_glXChooseVisual(dpy, screen, attribList, Buffers.getDirectBufferByteOffset(attribList), __addr_);
     if (_res == null) return null;
-    return XVisualInfo.create(_res);
+    return XVisualInfo.create(Buffers.nativeOrder(_res));
   }
 
-  /** Entry point to C language function: - Alias for: <br> <code> XVisualInfo *  glXChooseVisual(Display *  dpy, int screen, int *  attribList); </code>    */
-  private static native java.nio.ByteBuffer dispatch_glXChooseVisual(long dpy, int screen, Object attribList, int attribList_byte_offset, long procAddr);
+  /** Entry point to C language function: <code> XVisualInfo *  glXChooseVisual(Display *  dpy, int screen, int *  attribList); </code> <br>Part of <code>GLX_VERSION_1_X</code>
+      @param attribList a direct only {@link java.nio.IntBuffer}   */
+  private static native ByteBuffer dispatch_glXChooseVisual(long dpy, int screen, Object attribList, int attribList_byte_offset, long procAddress);
 
diff --git a/make/config/jogl/glx-x11.cfg b/make/config/jogl/glx-x11.cfg
index 4daa78b..017b1e0 100644
--- a/make/config/jogl/glx-x11.cfg
+++ b/make/config/jogl/glx-x11.cfg
@@ -13,6 +13,10 @@ Include gl-desktop.cfg
 GLHeader GL/glx.h
 GLHeader GL/glxext.h
 
+# Only NIO direct function, no arrays ..
+NIOOnly __ALL__
+NIODirectOnly __ALL__
+
 ForceProcAddressGen __ALL__
 LocalProcAddressCallingConvention __ALL__ APIENTRY
 
@@ -95,6 +99,6 @@ CustomJavaCode GLX  {
 CustomJavaCode GLX    if (glXGetProcAddressHandle == 0) {
 CustomJavaCode GLX      throw new GLException("Passed null pointer for method \"glXGetProcAddress\"");
 CustomJavaCode GLX    }
-CustomJavaCode GLX    return dispatch_glXGetProcAddress1(procname, glXGetProcAddressHandle);
+CustomJavaCode GLX    return dispatch_glXGetProcAddress0(procname, glXGetProcAddressHandle);
 CustomJavaCode GLX  }
 
diff --git a/make/config/jogl/glxext.cfg b/make/config/jogl/glxext.cfg
index de23b9f..c73753e 100644
--- a/make/config/jogl/glxext.cfg
+++ b/make/config/jogl/glxext.cfg
@@ -13,6 +13,10 @@ ExtendedInterfaceSymbolsIgnore ../build-temp/gensrc/classes/jogamp/opengl/x11/gl
 Include gl-common.cfg
 Include gl-desktop.cfg
 
+# Only NIO direct function, no arrays ..
+NIOOnly __ALL__
+NIODirectOnly __ALL__
+
 GLHeader GL/glx.h
 GLHeader GL/glxext.h
 
diff --git a/make/config/jogl/wgl-win32.cfg b/make/config/jogl/wgl-win32.cfg
index 4d2fea5..d9dbb13 100644
--- a/make/config/jogl/wgl-win32.cfg
+++ b/make/config/jogl/wgl-win32.cfg
@@ -18,6 +18,10 @@ GLHeader GL/wglext.h
 ForceProcAddressGen __ALL__
 LocalProcAddressCallingConvention __ALL__ APIENTRY
 
+# Only NIO direct function, no arrays ..
+NIOOnly __ALL__
+NIODirectOnly __ALL__
+
 AllowNonGLExtensions true
 EmitProcAddressTable true
 ProcAddressTableClassName WGLProcAddressTable
@@ -63,6 +67,6 @@ CustomJavaCode WGL  {
 CustomJavaCode WGL    if (wglGetProcAddressHandle == 0) {
 CustomJavaCode WGL      throw new GLException("Passed null pointer for method \"wglGetProcAddress\"");
 CustomJavaCode WGL    }
-CustomJavaCode WGL    return dispatch_wglGetProcAddress1(procname, wglGetProcAddressHandle);
+CustomJavaCode WGL    return dispatch_wglGetProcAddress0(procname, wglGetProcAddressHandle);
 CustomJavaCode WGL  }
 
diff --git a/make/config/jogl/wglext.cfg b/make/config/jogl/wglext.cfg
index 15986b6..57707d6 100644
--- a/make/config/jogl/wglext.cfg
+++ b/make/config/jogl/wglext.cfg
@@ -13,6 +13,10 @@ Include gl-desktop.cfg
 
 AllowNonGLExtensions true
 
+# Only NIO direct function, no arrays ..
+NIOOnly __ALL__
+NIODirectOnly __ALL__
+
 GLHeader wingdi.h
 GLHeader GL/wglext.h
 
diff --git a/make/config/nativewindow/x11-CustomJavaCode.java b/make/config/nativewindow/x11-CustomJavaCode.java
index 56aec47..8e5da3b 100644
--- a/make/config/nativewindow/x11-CustomJavaCode.java
+++ b/make/config/nativewindow/x11-CustomJavaCode.java
@@ -36,6 +36,11 @@
   }
   private static native Object GetRelativeLocation0(long display, int screen_index, long src_win, long dest_win, int src_x, int src_y);
 
+  public static boolean QueryExtension(long display, String extensionName) {
+    return QueryExtension0(display, extensionName);
+  }
+  private static native boolean QueryExtension0(long display, String extensionName);
+
   public static native int XCloseDisplay(long display);
   public static native void XUnlockDisplay(long display);
   public static native void XLockDisplay(long display);
diff --git a/make/scripts/adb-install-all-armv6.sh b/make/scripts/adb-install-all-armv6.sh
new file mode 100755
index 0000000..0ba9f3c
--- /dev/null
+++ b/make/scripts/adb-install-all-armv6.sh
@@ -0,0 +1,4 @@
+#adb $* install ../../gluegen/build-android-armv6/jogamp-android-launcher.apk
+#adb $* install ../../gluegen/build-android-armv6/gluegen-rt-android-armeabi.apk
+adb $* install ../build-android-armv6/jar/jogl-all-android-armeabi.apk
+adb $* install ../build-android-armv6/jar/jogl-test-android.apk
diff --git a/make/scripts/adb-launch-main.sh b/make/scripts/adb-launch-main.sh
index ff47a7a..6d67192 100644
--- a/make/scripts/adb-launch-main.sh
+++ b/make/scripts/adb-launch-main.sh
@@ -12,7 +12,7 @@ export TARGET_IP=jautab01
 export TARGET_ADB_PORT=5555
 export TARGET_ROOT=/data/projects
 
-export BUILD_DIR=../build-android-armv7
+export BUILD_DIR=../build-android-armv6
 
 if [ -e /opt-linux-x86/android-sdk-linux_x86 ] ; then
     export ANDROID_SDK_HOME=/opt-linux-x86/android-sdk-linux_x86
@@ -61,9 +61,9 @@ am start -a android.intent.action.MAIN -n jogamp.android.launcher/jogamp.android
 # \
 #dalvikvm \
 #  -Xjnigreflimit:2000 \
-#  -cp ../../gluegen/make/$BUILD_DIR/jogamp.android-launcher.apk:../../gluegen/make/lib/ant-junit-all.apk:../../gluegen/make/$BUILD_DIR/gluegen-rt-android-armeabi-v7a.apk:$BUILD_DIR/jar/jogl.all-android-armeabi-v7a.apk:$BUILD_DIR/jar/jogl.test.apk \
+#  -cp ../../gluegen/make/$BUILD_DIR/jogamp.android-launcher.apk:../../gluegen/make/lib/ant-junit-all.apk:../../gluegen/make/$BUILD_DIR/gluegen-rt-android-armeabi.apk:$BUILD_DIR/jar/jogl.all-android-armeabi.apk:$BUILD_DIR/jar/jogl.test.apk \
 #  -Dgluegen.root=../../gluegen \
-#  -Drootrel.build=build-android-armv7 \
+#  -Drootrel.build=build-android-armv6 \
 #  com.android.internal.util.WithFramework \
 #  $TSTCLASS \
 " >> $BUILD_DIR/jogl-targetcommand.sh
diff --git a/make/scripts/adb-reinstall-all-armv6.sh b/make/scripts/adb-reinstall-all-armv6.sh
new file mode 100755
index 0000000..0e62c59
--- /dev/null
+++ b/make/scripts/adb-reinstall-all-armv6.sh
@@ -0,0 +1,5 @@
+sdir=`dirname $0`
+
+$sdir/adb-uninstall-all.sh $*
+$sdir/adb-install-all-armv6.sh $*
+
diff --git a/make/scripts/java-win32-dbg.bat b/make/scripts/java-win32-dbg.bat
index 6f82067..e0760d0 100755
--- a/make/scripts/java-win32-dbg.bat
+++ b/make/scripts/java-win32-dbg.bat
@@ -1,26 +1,27 @@
 
 set BLD_SUB=build-win32
-set J2RE_HOME=c:\jre1.6.0_30_x32
-set JAVA_HOME=c:\jdk1.6.0_30_x32
+set J2RE_HOME=c:\jre1.6.0_35_x32
+set JAVA_HOME=c:\jdk1.6.0_35_x32
 set ANT_PATH=C:\apache-ant-1.8.2
 
 set PROJECT_ROOT=D:\projects\jogamp\jogl
 set BLD_DIR=..\%BLD_SUB%
 
-set FFMPEG_LIB=%PROJECT_ROOT%\make\lib\ffmpeg\x32
-
-REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%FFMPEG_LIB%;%PATH%
-REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PROJECT_ROOT%\make\lib\external\angle\win32;%PATH%
-set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PROJECT_ROOT%\make\lib\external\PVRVFrame\OGLES-2.0\Windows_x86_32;%PATH%
+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%
+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%
 
 REM set LIB_DIR=%BLD_DIR%\lib;..\..\gluegen\%BLD_SUB%\obj
-set LIB_DIR=%FFMPEG_LIB%
+REM set FFMPEG_LIB=%PROJECT_ROOT%\make\lib\ffmpeg\x32
+REM set LIB_DIR=%FFMPEG_LIB%
+set LIB_DIR=
 
 set CP_ALL=.;%BLD_DIR%\jar\jogl-all.jar;%BLD_DIR%\jar\jogl-test.jar;..\..\gluegen\%BLD_SUB%\gluegen-rt.jar;..\..\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%
 
-set D_ARGS="-Djogl.debug.GLContext" "-Djogl.debug.FBObject"
+set D_ARGS="-Djogl.debug.GLDrawable" "-Djogl.debug.GLContext" "-Djogl.debug.FBObject" "-Djogl.enable.ANGLE"
 REM set D_ARGS="-Djogl.debug.GLDrawable" "-Djogl.debug.EGLDrawableFactory.DontQuery"
 REM set D_ARGS="-Djogl.debug.GLDrawable" "-Djogl.debug.EGLDrawableFactory.QueryNativeTK"
 REM set D_ARGS="-Djogl.debug=all" "-Dnewt.debug=all" "-Dnativewindow.debug=all"
diff --git a/make/scripts/java-win32.bat b/make/scripts/java-win32.bat
index 1d84302..d357157 100755
--- a/make/scripts/java-win32.bat
+++ b/make/scripts/java-win32.bat
@@ -1,18 +1,21 @@
 
 set BLD_SUB=build-win32
-set J2RE_HOME=c:\jre1.6.0_30_x32
-set JAVA_HOME=c:\jdk1.6.0_30_x32
+set J2RE_HOME=c:\jre1.6.0_35_x32
+set JAVA_HOME=c:\jdk1.6.0_35_x32
 set ANT_PATH=C:\apache-ant-1.8.2
 
 set PROJECT_ROOT=D:\projects\jogamp\jogl
 set BLD_DIR=..\%BLD_SUB%
 
-REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;c:\mingw\bin;%PATH%
-REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PROJECT_ROOT%\make\lib\angle\win32;%PATH%
-set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PROJECT_ROOT%\make\lib\PVRVFrame\OGLES-2.0\Windows_x86_32;%PATH%
+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%
+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 BLD_DIR=..\%BLD_SUB%
 REM set LIB_DIR=..\..\gluegen\%BLD_SUB%\obj;%BLD_DIR%\lib
+REM set FFMPEG_LIB=%PROJECT_ROOT%\make\lib\ffmpeg\x32
+REM set LIB_DIR=%FFMPEG_LIB%
 set LIB_DIR=
 
 set CP_ALL=.;%BLD_DIR%\jar\jogl-all.jar;%BLD_DIR%\jar\jogl-test.jar;..\..\gluegen\%BLD_SUB%\gluegen-rt.jar;..\..\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
diff --git a/make/scripts/java-win64-dbg.bat b/make/scripts/java-win64-dbg.bat
index c8a9045..5dc34f4 100755
--- a/make/scripts/java-win64-dbg.bat
+++ b/make/scripts/java-win64-dbg.bat
@@ -1,7 +1,7 @@
 
 set BLD_SUB=build-win64
-set J2RE_HOME=c:\jre1.6.0_30_x64
-set JAVA_HOME=c:\jdk1.6.0_30_x64
+set J2RE_HOME=c:\jre1.6.0_35_x64
+set JAVA_HOME=c:\jdk1.6.0_35_x64
 set ANT_PATH=C:\apache-ant-1.8.2
 
 set PROJECT_ROOT=D:\projects\jogamp\jogl
@@ -30,6 +30,7 @@ REM set D_ARGS="-Djogl.debug.ExtensionAvailabilityCache" "-Djogl.debug=all" "-Dn
 REM set D_ARGS="-Djogl.debug=all" "-Dnewt.debug=all" "-Dnativewindow.debug=all" "-Djogamp.debug.NativeLibrary=true"
 REM set D_ARGS="-Djogl.debug.GLContext" "-Djogl.debug.ExtensionAvailabilityCache" "-Djogamp.debug.ProcAddressHelper=true"
 REM set D_ARGS="-Djogl.debug.GraphicsConfiguration"
+REM set D_ARGS="-Djogl.debug.GLContext" "-Djogl.debug.GLDrawable" "-Dnativewindow.debug.GraphicsConfiguration"
 REM set D_ARGS="-Djogamp.debug.JNILibLoader=true" "-Djogamp.debug.NativeLibrary=true" "-Djogamp.debug.NativeLibrary.Lookup=true" "-Djogl.debug.GLProfile=true"
 REM set D_ARGS="-Djogl.debug=all" "-Dnewt.debug=all" "-Dnativewindow.debug=all" "-Djogamp.debug.Lock" "-Djogamp.debug.Lock.TraceLock"
 REM set D_ARGS="-Djogl.debug=all" "-Dnativewindow.debug=all"
@@ -37,7 +38,9 @@ REM set D_ARGS="-Djogl.debug=all"
 REM set D_ARGS="-Djogl.debug.GLCanvas" "-Djogl.debug.Animator" "-Djogl.debug.GLContext" "-Djogl.debug.GLContext.TraceSwitch" "-Djogl.debug.DebugGL" "-Djogl.debug.TraceGL"
 REM set D_ARGS="-Djogl.debug.GLCanvas" "-Djogl.debug.Animator" "-Djogl.debug.GLContext" "-Djogl.debug.GLContext.TraceSwitch" "-Djogl.windows.useWGLVersionOf5WGLGDIFuncSet"
 REM set D_ARGS="-Djogl.debug.GLCanvas" "-Djogl.debug.Animator" "-Djogl.debug.GLContext" "-Djogl.debug.GLContext.TraceSwitch"
-set D_ARGS="-Dnewt.debug.Window" "-Dnewt.debug.Display"
+REM set D_ARGS="-Dnewt.debug.Window"
+REM set D_ARGS="-Dnewt.debug.Window.KeyEvent"
+REM set D_ARGS="-Dnewt.debug.Window" "-Dnewt.debug.Display"
 REM set D_ARGS="-Djogl.debug.GLDebugMessageHandler" "-Djogl.debug.DebugGL" "-Djogl.debug.TraceGL"
 REM set D_ARGS="-Djogl.debug.DebugGL" "-Djogl.debug.GLDebugMessageHandler" "-Djogl.debug.GLSLCode"
 REM set D_ARGS="-Djogl.debug.GLContext" "-Dnewt.debug=all"
@@ -51,4 +54,5 @@ REM set X_ARGS="-Dsun.java2d.noddraw=true" "-Dsun.java2d.opengl=true" "-Dsun.awt
 REM set X_ARGS="-Dsun.java2d.noddraw=true" "-Dsun.java2d.d3d=false" "-Dsun.java2d.ddoffscreen=false" "-Dsun.java2d.gdiblit=false" "-Dsun.java2d.opengl=false" "-Dsun.awt.noerasebackground=true" "-Xms512m" "-Xmx1024m"
 REM set X_ARGS="-Dsun.java2d.noddraw=true" "-Dsun.java2d.d3d=false" "-Dsun.java2d.ddoffscreen=false" "-Dsun.java2d.gdiblit=false" "-Dsun.java2d.opengl=true" "-Dsun.awt.noerasebackground=true" "-Xms512m" "-Xmx1024m"
 
-%J2RE_HOME%\bin\java -classpath %CP_ALL% "-Djava.library.path=%LIB_DIR%" %D_ARGS% %X_ARGS% %* > java-win64-dbg.log 2>&1
+REM %J2RE_HOME%\bin\java -classpath %CP_ALL% "-Djava.library.path=%LIB_DIR%" %D_ARGS% %X_ARGS% %* > java-win64-dbg.log 2>&1
+%J2RE_HOME%\bin\java -classpath %CP_ALL% "-Djava.library.path=%LIB_DIR%" %D_ARGS% %X_ARGS% %* 
diff --git a/make/scripts/java-win64.bat b/make/scripts/java-win64.bat
index 2c09fee..99f9bdc 100755
--- a/make/scripts/java-win64.bat
+++ b/make/scripts/java-win64.bat
@@ -1,7 +1,7 @@
 
 set BLD_SUB=build-win64
-set J2RE_HOME=c:\jre1.6.0_30_x64
-set JAVA_HOME=c:\jdk1.6.0_30_x64
+set J2RE_HOME=c:\jre1.6.0_35_x64
+set JAVA_HOME=c:\jdk1.6.0_35_x64
 set ANT_PATH=C:\apache-ant-1.8.2
 
 REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;c:\mingw\bin;%PATH%
diff --git a/make/scripts/lstjars.sh b/make/scripts/lstjars.sh
index 82e378e..5763e41 100755
--- a/make/scripts/lstjars.sh
+++ b/make/scripts/lstjars.sh
@@ -1,5 +1,7 @@
 #! /bin/sh
 
+#set -x
+
 THISDIR=$(pwd)
 
 BUILDDIR=$1
@@ -21,7 +23,7 @@ fi
 function report() {
     #ls -1 -s --block-size=1024 $*
     #ls -1 -s --block-size=1024 $* | awk ' BEGIN { sum=0 ; } { sum=sum+$1; } END { printf("%d Total\n", sum); }'
-    du -ksc $*
+    du -ksc $* | awk ' { printf("%5d kB  %s\n", $1, $2); } '
 }
 
 OSS=x11
@@ -35,15 +37,23 @@ function listdeployment() {
     echo
 
     echo JOGL ALL
-    report gluegen-rt.$JAR_SUFFIX jogl.all.$JAR_SUFFIX libgluegen-rt.so.gz libnativewindow_awt.so.gz libnativewindow_x11.so.gz libjogl_desktop.so.gz libnewt.so.gz
+    report gluegen-rt.$JAR_SUFFIX jogl-all.$JAR_SUFFIX libgluegen-rt.so.gz libnativewindow_awt.so.gz libnativewindow_x11.so.gz libjogl_desktop.so.gz libnewt.so.gz
     echo
 
     echo JOGL ALL no AWT
-    report gluegen-rt.$JAR_SUFFIX jogl.all-noawt.$JAR_SUFFIX libgluegen-rt.so.gz libnativewindow_x11.so.gz libjogl_desktop.so.gz libnewt.so.gz
+    report gluegen-rt.$JAR_SUFFIX jogl-all-noawt.$JAR_SUFFIX libgluegen-rt.so.gz libnativewindow_x11.so.gz libjogl_desktop.so.gz libnewt.so.gz
+    echo
+
+    echo JOGL Min X11 Min egl es1 es2
+    report gluegen-rt.$JAR_SUFFIX atomic/jogl-core.$JAR_SUFFIX atomic/jogl-glmobile.$JAR_SUFFIX atomic/jogl-util.$JAR_SUFFIX atomic/nativewindow-core.$JAR_SUFFIX atomic/newt-core.$JAR_SUFFIX atomic/nativewindow-os-x11.$JAR_SUFFIX atomic/newt-driver-x11.$JAR_SUFFIX libgluegen-rt.so.gz libjogl_mobile.so.gz libnativewindow_x11.so.gz libnewt.so.gz
     echo
 
     echo JOGL Android - mobile egl es1 es2
-    report gluegen-rt.$JAR_SUFFIX jogl.all-android.$JAR_SUFFIX libgluegen-rt.so.gz libjogl_mobile.so.gz
+    report gluegen-rt-android.$JAR_SUFFIX jogl-all-android.$JAR_SUFFIX libgluegen-rt.so.gz libjogl_mobile.so.gz
+    echo
+
+    echo JOGL Min Android/Mobile Min egl es1 es2
+    report gluegen-rt-android.$JAR_SUFFIX atomic/jogl-core.$JAR_SUFFIX atomic/jogl-glmobile.$JAR_SUFFIX atomic/jogl-os-android.$JAR_SUFFIX atomic/jogl-util.$JAR_SUFFIX atomic/nativewindow-core.$JAR_SUFFIX atomic/newt-core.$JAR_SUFFIX atomic/newt-driver-android.$JAR_SUFFIX libgluegen-rt.so.gz libjogl_mobile.so.gz
     echo
 }
 
@@ -52,6 +62,7 @@ mkdir -p $STATDIR
 cp -a $BUILDDIR/lib/*.so $STATDIR
 cp -a $BUILDDIR/jar/*    $STATDIR
 cp -a $BUILDDIR_GLUEGEN/gluegen-rt.jar $STATDIR
+cp -a $BUILDDIR_GLUEGEN/gluegen-rt-android.jar $STATDIR
 cp -a $BUILDDIR_GLUEGEN/obj/libgluegen-rt.so $STATDIR
 
 cd $STATDIR
@@ -84,13 +95,14 @@ sort atomic/jogl*.lst | uniq -d
 
 cat atomic/*.lst | sort -u > allparts.lst
 mv nope/*jar .
-cat jogl.all.lst gluegen-rt.lst  | sort -u > allall.lst
+cat jogl-all.lst gluegen-rt.lst  | sort -u > allall.lst
 
 echo all vs allparts delta
 echo
 diff -Nur allparts.lst allall.lst
 
-mv nope/* .
+mv nope/*.jar .
+#mv nope/atomic/*.jar atomic/
 
 listdeployment jar
 
diff --git a/make/scripts/make.jogl.all.android-armv6-cross.sh b/make/scripts/make.jogl.all.android-armv6-cross.sh
new file mode 100755
index 0000000..2625600
--- /dev/null
+++ b/make/scripts/make.jogl.all.android-armv6-cross.sh
@@ -0,0 +1,92 @@
+#! /bin/sh
+
+export NODE_LABEL=.
+
+export HOST_UID=jogamp
+# jogamp02 - 10.1.0.122
+export HOST_IP=10.1.0.122
+export HOST_RSYNC_ROOT=PROJECTS/JOGL
+
+export TARGET_UID=jogamp
+export TARGET_IP=panda02
+#export TARGET_IP=jautab03
+#export TARGET_IP=jauphone04
+export TARGET_ADB_PORT=5555
+# needs executable bit (probably su)
+export TARGET_ROOT=/data/projects
+export TARGET_ANT_HOME=/usr/share/ant
+
+echo ANDROID_SDK_HOME $ANDROID_SDK_HOME
+echo NDK_ROOT $NDK_ROOT
+
+if [ -z "$NDK_ROOT" ] ; then
+    #
+    # Generic android-ndk
+    #
+    if [ -e /usr/local/android-ndk ] ; then
+        NDK_ROOT=/usr/local/android-ndk
+    elif [ -e /opt-linux-x86/android-ndk ] ; then
+        NDK_ROOT=/opt-linux-x86/android-ndk
+    elif [ -e /opt/android-ndk ] ; then
+        NDK_ROOT=/opt/android-ndk
+    #
+    # Specific android-ndk-r7b
+    #
+    elif [ -e /usr/local/android-ndk-r7b ] ; then
+        NDK_ROOT=/usr/local/android-ndk-r7b
+    elif [ -e /opt-linux-x86/android-ndk-r7b ] ; then
+        NDK_ROOT=/opt-linux-x86/android-ndk-r7b
+    elif [ -e /opt/android-ndk-r7b ] ; then
+        NDK_ROOT=/opt/android-ndk-r7b
+    else 
+        echo NDK_ROOT is not specified and does not exist in default locations
+        exit 1
+    fi
+elif [ ! -e $NDK_ROOT ] ; then
+    echo NDK_ROOT $NDK_ROOT does not exist
+    exit 1
+fi
+export NDK_ROOT
+
+if [ -z "$ANDROID_SDK_HOME" ] ; then
+    if [ -e /usr/local/android-sdk-linux_x86 ] ; then
+        ANDROID_SDK_HOME=/usr/local/android-sdk-linux_x86
+    elif [ -e /opt-linux-x86/android-sdk-linux_x86 ] ; then
+        ANDROID_SDK_HOME=/opt-linux-x86/android-sdk-linux_x86
+    elif [ -e /opt/android-sdk-linux_x86 ] ; then
+        ANDROID_SDK_HOME=/opt/android-sdk-linux_x86
+    else 
+        echo ANDROID_SDK_HOME is not specified and does not exist in default locations
+        exit 1
+    fi
+elif [ ! -e $ANDROID_SDK_HOME ] ; then
+    echo ANDROID_SDK_HOME $ANDROID_SDK_HOME does not exist
+    exit 1
+fi
+export ANDROID_SDK_HOME
+
+export ANDROID_VERSION=9
+export SOURCE_LEVEL=1.6
+export TARGET_LEVEL=1.6
+export TARGET_RT_JAR=/opt-share/jre1.6.0_30/lib/rt.jar
+
+export GCC_VERSION=4.4.3
+HOST_ARCH=linux-x86
+export TARGET_TRIPLE=arm-linux-androideabi
+
+export NDK_TOOLCHAIN_ROOT=$NDK_ROOT/toolchains/${TARGET_TRIPLE}-${GCC_VERSION}/prebuilt/${HOST_ARCH}
+export TARGET_PLATFORM_ROOT=${NDK_ROOT}/platforms/android-${ANDROID_VERSION}/arch-arm
+
+# Need to add toolchain bins to the PATH. 
+export PATH="$NDK_TOOLCHAIN_ROOT/$TARGET_TRIPLE/bin:$ANDROID_SDK_HOME/platform-tools:$PATH"
+
+export GLUEGEN_CPPTASKS_FILE=`pwd`/../../gluegen/make/lib/gluegen-cpptasks-android-armv6.xml
+
+#export JUNIT_DISABLED="true"
+#export JUNIT_RUN_ARG0="-Dnewt.test.Screen.disableScreenMode"
+
+# BUILD_ARCHIVE=true \
+ant \
+    -Drootrel.build=build-android-armv6 \
+    $* 2>&1 | tee -a make.jogl.all.android-armv6-cross.log
+
diff --git a/make/scripts/make.jogl.all.linux-armv7-cross.sh b/make/scripts/make.jogl.all.linux-armv6-cross.sh
similarity index 81%
rename from make/scripts/make.jogl.all.linux-armv7-cross.sh
rename to make/scripts/make.jogl.all.linux-armv6-cross.sh
index 5bb5728..9f31b79 100755
--- a/make/scripts/make.jogl.all.linux-armv7-cross.sh
+++ b/make/scripts/make.jogl.all.linux-armv6-cross.sh
@@ -14,7 +14,7 @@ export PATH
 #    -Dgluegen.cpptasks.detected.os=true \
 #    -DisUnix=true \
 #    -DisLinux=true \
-#    -DisLinuxARMv7=true \
+#    -DisLinuxARMv6=true \
 #    -DisX11=false \
 
 export NODE_LABEL=.
@@ -29,22 +29,22 @@ export TARGET_IP=panda01
 export TARGET_ROOT=/home/jogamp/projects-cross
 export TARGET_ANT_HOME=/usr/share/ant
 
-export TARGET_PLATFORM_ROOT=/opt-linux-armv7-armel
+export TARGET_PLATFORM_ROOT=/opt-linux-armv6-armel
 export TARGET_PLATFORM_LIBS=$TARGET_PLATFORM_ROOT/usr/lib
 export TARGET_JAVA_LIBS=$TARGET_PLATFORM_ROOT/jre/lib/arm
 
-export GLUEGEN_CPPTASKS_FILE="../../gluegen/make/lib/gluegen-cpptasks-linux-armv4.xml"
+export GLUEGEN_CPPTASKS_FILE="../../gluegen/make/lib/gluegen-cpptasks-linux-armv6.xml"
 
 #export JUNIT_DISABLED="true"
 export JUNIT_RUN_ARG0="-Dnewt.test.Screen.disableScreenMode"
 
 ant \
-    -Drootrel.build=build-linux-armv7 \
+    -Drootrel.build=build-linux-armv6 \
     \
     -Dsetup.addNativeKD=true \
     -Dsetup.addNativeOpenMAX=true \
-    -Dsetup.addNativeBroadcomEGL=true \
-    $* 2>&1 | tee make.jogl.all.linux-armv7-cross.log
+    -Dsetup.addNativeBroadcom=true \
+    $* 2>&1 | tee make.jogl.all.linux-armv6-cross.log
 
 
 
diff --git a/make/scripts/make.jogl.all.linux-armv7.sh b/make/scripts/make.jogl.all.linux-armv6.sh
similarity index 77%
rename from make/scripts/make.jogl.all.linux-armv7.sh
rename to make/scripts/make.jogl.all.linux-armv6.sh
index 0fd0b6e..3d526ea 100755
--- a/make/scripts/make.jogl.all.linux-armv7.sh
+++ b/make/scripts/make.jogl.all.linux-armv6.sh
@@ -8,20 +8,20 @@ export PATH
 #    -Dgluegen.cpptasks.detected.os=true \
 #    -DisUnix=true \
 #    -DisLinux=true \
-#    -DisLinuxARMv7=true \
+#    -DisLinuxARMv6=true \
 #    -DisX11=false \
 
 export TARGET_PLATFORM_ROOT=/
 export TARGET_PLATFORM_LIBS=/usr/lib/arm-linux-gnueabi
 export TARGET_JAVA_LIBS=/usr/lib/jvm/default-java/jre/lib/arm
 
-export GLUEGEN_CPPTASKS_FILE="../../gluegen/make/lib/gluegen-cpptasks-linux-armv4.xml"
+export GLUEGEN_CPPTASKS_FILE="../../gluegen/make/lib/gluegen-cpptasks-linux-armv6.xml"
 
 ant \
-    -Drootrel.build=build-linux-armv7 \
+    -Drootrel.build=build-linux-armv6 \
     -Dsetup.addNativeKD=true \
     -Dsetup.addNativeOpenMAX=true \
-    -Dsetup.addNativeBroadcomEGL=true \
+    -Dsetup.addNativeBroadcom=true \
     -Djunit.run.arg0="-Dnewt.test.Screen.disableScreenMode" \
-    $* 2>&1 | tee make.jogl.all.linux-armv7.log
+    $* 2>&1 | tee make.jogl.all.linux-armv6.log
 
diff --git a/make/scripts/make.jogl.all.linux-armv7hf-cross.sh b/make/scripts/make.jogl.all.linux-armv6hf-cross.sh
similarity index 79%
rename from make/scripts/make.jogl.all.linux-armv7hf-cross.sh
rename to make/scripts/make.jogl.all.linux-armv6hf-cross.sh
index cd82d82..6295a90 100755
--- a/make/scripts/make.jogl.all.linux-armv7hf-cross.sh
+++ b/make/scripts/make.jogl.all.linux-armv6hf-cross.sh
@@ -14,7 +14,7 @@ export PATH
 #    -Dgluegen.cpptasks.detected.os=true \
 #    -DisUnix=true \
 #    -DisLinux=true \
-#    -DisLinuxARMv7=true \
+#    -DisLinuxARMv6=true \
 #    -DisX11=false \
 
 export NODE_LABEL=.
@@ -24,27 +24,27 @@ export HOST_IP=jogamp02
 export HOST_RSYNC_ROOT=PROJECTS/JOGL
 
 export TARGET_UID=jogamp
-export TARGET_IP=panda01
+export TARGET_IP=panda02
 #export TARGET_IP=jautab02
 export TARGET_ROOT=/home/jogamp/projects-cross
 export TARGET_ANT_HOME=/usr/share/ant
 
-export TARGET_PLATFORM_ROOT=/opt-linux-armv7-armhf
+export TARGET_PLATFORM_ROOT=/opt-linux-armv6-armhf
 export TARGET_PLATFORM_LIBS=$TARGET_PLATFORM_ROOT/usr/lib
 export TARGET_JAVA_LIBS=$TARGET_PLATFORM_ROOT/jre/lib/arm
 
-export GLUEGEN_CPPTASKS_FILE="../../gluegen/make/lib/gluegen-cpptasks-linux-armv7hf.xml"
+export GLUEGEN_CPPTASKS_FILE="../../gluegen/make/lib/gluegen-cpptasks-linux-armv6hf.xml"
 
 #export JUNIT_DISABLED="true"
 export JUNIT_RUN_ARG0="-Dnewt.test.Screen.disableScreenMode"
 
 ant \
-    -Drootrel.build=build-linux-armv7hf \
+    -Drootrel.build=build-linux-armv6hf \
     \
     -Dsetup.addNativeKD=true \
     -Dsetup.addNativeOpenMAX=true \
-    -Dsetup.addNativeBroadcomEGL=true \
-    $* 2>&1 | tee make.jogl.all.linux-armv7hf-cross.log
+    -Dsetup.addNativeBroadcom=true \
+    $* 2>&1 | tee make.jogl.all.linux-armv6hf-cross.log
 
 
 
diff --git a/make/scripts/make.jogl.all.linux-armv6hf.sh b/make/scripts/make.jogl.all.linux-armv6hf.sh
new file mode 100755
index 0000000..7d9480f
--- /dev/null
+++ b/make/scripts/make.jogl.all.linux-armv6hf.sh
@@ -0,0 +1,27 @@
+#! /bin/sh
+
+# arm-linux-gnueabihf == armhf triplet
+PATH=`pwd`/../../gluegen/make/lib/linux/arm-linux-gnueabihf/bin:$PATH
+export PATH
+
+#    -Dc.compiler.debug=true 
+#    -Dgluegen.cpptasks.detected.os=true \
+#    -DisUnix=true \
+#    -DisLinux=true \
+#    -DisLinuxARMv6=true \
+#    -DisX11=false \
+
+export TARGET_PLATFORM_ROOT=/
+export TARGET_PLATFORM_LIBS=/usr/lib/arm-linux-gnueabihf
+export TARGET_JAVA_LIBS=/usr/lib/jvm/java-6-openjdk-armhf/jre/lib/arm
+
+export GLUEGEN_CPPTASKS_FILE="../../gluegen/make/lib/gluegen-cpptasks-linux-armv6hf.xml"
+
+ant \
+    -Drootrel.build=build-linux-armv6hf \
+    -Dsetup.addNativeKD=true \
+    -Dsetup.addNativeOpenMAX=true \
+    -Dsetup.addNativeBroadcom=true \
+    -Djunit.run.arg0="-Dnewt.test.Screen.disableScreenMode" \
+    $* 2>&1 | tee make.jogl.all.linux-armv6hf.log
+
diff --git a/make/scripts/make.jogl.all.win32.bat b/make/scripts/make.jogl.all.win32.bat
index 52ea33a..c4c80a7 100755
--- a/make/scripts/make.jogl.all.win32.bat
+++ b/make/scripts/make.jogl.all.win32.bat
@@ -1,7 +1,7 @@
 set THISDIR="C:\JOGL"
 
-set J2RE_HOME=c:\jre1.6.0_30_x32
-set JAVA_HOME=c:\jdk1.6.0_30_x32
+set J2RE_HOME=c:\jre1.6.0_35_x32
+set JAVA_HOME=c:\jdk1.6.0_35_x32
 set ANT_PATH=C:\apache-ant-1.8.2
 
 set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;c:\mingw\bin;%PATH%
diff --git a/make/scripts/make.jogl.all.win64.bat b/make/scripts/make.jogl.all.win64.bat
index e1d258c..7355c6a 100755
--- a/make/scripts/make.jogl.all.win64.bat
+++ b/make/scripts/make.jogl.all.win64.bat
@@ -1,10 +1,10 @@
 set THISDIR="C:\JOGL"
 
-set J2RE_HOME=c:\jre1.6.0_30_x64
-set JAVA_HOME=c:\jdk1.6.0_30_x64
+set J2RE_HOME=c:\jre1.6.0_35_x64
+set JAVA_HOME=c:\jdk1.6.0_35_x64
 set ANT_PATH=C:\apache-ant-1.8.2
 
-set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;c:\mingw64\bin;c:\mingw\bin;%PATH%
+set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;c:\mingw64\bin;%PATH%
 
 set LIB_GEN=%THISDIR%\lib
 set CLASSPATH=.;%THISDIR%\build-win64\classes
diff --git a/make/scripts/targetcommand-awt.sh b/make/scripts/targetcommand-awt.sh
index af3b5f7..6bd4dd2 100755
--- a/make/scripts/targetcommand-awt.sh
+++ b/make/scripts/targetcommand-awt.sh
@@ -2,6 +2,8 @@
 
 THISDIR=`pwd`
 
+ROOT_REL=build-linux-armv6hf
+
 #XTRA_FLAGS="-Dnewt.test.Screen.disableScreenMode"
 XTRA_FLAGS="-Dnewt.test.Screen.disableScreenMode -Djogl.debug.EGL -Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.GLDrawable"
 #XTRA_FLAGS="-Dnewt.debug.Screen"
@@ -14,23 +16,24 @@ XTRA_FLAGS="-Dnewt.test.Screen.disableScreenMode -Djogl.debug.EGL -Dnativewindow
 #XTRA_FLAGS="-Djogl.debug.TraceGL"
 #XTRA_FLAGS="-Djogl.debug.DebugGL -Djogl.debug.TraceGL"
 
-TSTCLASS=com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2AWT
+#TSTCLASS=com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2AWT
 #TSTCLASS=com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsAWT
+TSTCLASS=com.jogamp.opengl.test.junit.jogl.awt.TestAWT01GLn
  
  mkdir -p $THISDIR/projects-cross 
 
  rsync -av --delete --delete-after --delete-excluded \
        --exclude 'build-x86*/' --exclude 'build-linux-x*/' --exclude 'build-android*/' --exclude 'build-win*/' --exclude 'build-mac*/' \
        --exclude 'classes/' --exclude 'src/' --exclude '.git/' --exclude '*-java-src.zip' \
+       --exclude 'make/lib/external/' \
        jogamp at jogamp02::PROJECTS/JOGL/gluegen jogamp at jogamp02::PROJECTS/JOGL/jogl $THISDIR/projects-cross 
 
  cd $THISDIR/projects-cross/jogl/make 
  
 function junit_run() {
      java \
-     -cp ../../gluegen/make/lib/junit.jar:/usr/share/ant/lib/ant.jar:/usr/share/ant/lib/ant-junit.jar:../../gluegen/build-linux-armv7/gluegen-rt.jar:../build-linux-armv7/jar/jogl.all.jar:../build-linux-armv7/jar/jogl.test.jar\
+     -cp ../../gluegen/make/lib/junit.jar:/usr/share/ant/lib/ant.jar:/usr/share/ant/lib/ant-junit.jar:../../gluegen/$ROOT_REL/gluegen-rt.jar:../$ROOT_REL/jar/jogl-all.jar:../$ROOT_REL/jar/jogl-test.jar\
      $XTRA_FLAGS \
-     com.jogamp.newt.util.MainThread\
      org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner \
      $TSTCLASS \
      filtertrace=true \
@@ -46,9 +49,8 @@ function junit_run() {
  
 function main_run() {
      java \
-     -cp ../../gluegen/make/lib/junit.jar:/usr/share/ant/lib/ant.jar:/usr/share/ant/lib/ant-junit.jar:../../gluegen/build-linux-armv7/gluegen-rt.jar:../build-linux-armv7/jar/jogl.all.jar:../build-linux-armv7/jar/jogl.test.jar\
+     -cp ../../gluegen/make/lib/junit.jar:/usr/share/ant/lib/ant.jar:/usr/share/ant/lib/ant-junit.jar:../../gluegen/$ROOT_REL/gluegen-rt.jar:../$ROOT_REL/jar/jogl-all.jar:../$ROOT_REL/jar/jogl-test.jar\
      $XTRA_FLAGS \
-     com.jogamp.newt.util.MainThread\
      $TSTCLASS \
      $*
 }
diff --git a/make/scripts/targetcommand-awt.sh b/make/scripts/targetcommand-loop.sh
old mode 100755
new mode 100644
similarity index 59%
copy from make/scripts/targetcommand-awt.sh
copy to make/scripts/targetcommand-loop.sh
index af3b5f7..fc7baa7
--- a/make/scripts/targetcommand-awt.sh
+++ b/make/scripts/targetcommand-loop.sh
@@ -2,8 +2,14 @@
 
 THISDIR=`pwd`
 
-#XTRA_FLAGS="-Dnewt.test.Screen.disableScreenMode"
-XTRA_FLAGS="-Dnewt.test.Screen.disableScreenMode -Djogl.debug.EGL -Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.GLDrawable"
+ROOT_REL=build-linux-armv6hf
+
+# export LD_LIBRARY_PATH=$THISDIR/PVRTrace/:$LD_LIBRARY_PATH
+
+XTRA_FLAGS="-Dnewt.test.Screen.disableScreenMode"
+#XTRA_FLAGS="-Dnewt.test.Screen.disableScreenMode -Djogl.debug.TraceGL"
+#XTRA_FLAGS="-Dnewt.test.Screen.disableScreenMode -Djogl.debug.DebugGL -Djogl.debug.TraceGL"
+#XTRA_FLAGS="-Dnewt.test.Screen.disableScreenMode -Djogl.debug.EGL -Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.GLDrawable"
 #XTRA_FLAGS="-Dnewt.debug.Screen"
 #XTRA_FLAGS="-Dnativewindow.debug.GraphicsConfiguration -Dnativewindow.debug.NativeWindow"
 #XTRA_FLAGS="-Dnewt.debug.Window -Djogl.debug.EGL -Djogl.debug.GLContext -Djogl.debug.GLDrawable"
@@ -14,23 +20,26 @@ XTRA_FLAGS="-Dnewt.test.Screen.disableScreenMode -Djogl.debug.EGL -Dnativewindow
 #XTRA_FLAGS="-Djogl.debug.TraceGL"
 #XTRA_FLAGS="-Djogl.debug.DebugGL -Djogl.debug.TraceGL"
 
-TSTCLASS=com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2AWT
-#TSTCLASS=com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsAWT
- 
- mkdir -p $THISDIR/projects-cross 
+#TSTCLASS=com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT
+TSTCLASS=com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestRedSquareES2NEWT
+
+ mkdir -p $THISDIR/projects-cross
 
  rsync -av --delete --delete-after --delete-excluded \
        --exclude 'build-x86*/' --exclude 'build-linux-x*/' --exclude 'build-android*/' --exclude 'build-win*/' --exclude 'build-mac*/' \
        --exclude 'classes/' --exclude 'src/' --exclude '.git/' --exclude '*-java-src.zip' \
+       --exclude 'make/lib/external/' \
        jogamp at jogamp02::PROJECTS/JOGL/gluegen jogamp at jogamp02::PROJECTS/JOGL/jogl $THISDIR/projects-cross 
 
  cd $THISDIR/projects-cross/jogl/make 
  
+ cp -a $THISDIR/pvrtrace.cfg .
+ 
 function junit_run() {
      java \
-     -cp ../../gluegen/make/lib/junit.jar:/usr/share/ant/lib/ant.jar:/usr/share/ant/lib/ant-junit.jar:../../gluegen/build-linux-armv7/gluegen-rt.jar:../build-linux-armv7/jar/jogl.all.jar:../build-linux-armv7/jar/jogl.test.jar\
+     -cp ../../gluegen/make/lib/junit.jar:/usr/share/ant/lib/ant.jar:/usr/share/ant/lib/ant-junit.jar:../../gluegen/$ROOT_REL/gluegen-rt.jar:../$ROOT_REL/jar/jogl-all-noawt.jar:../$ROOT_REL/jar/jogl-test.jar\
+     -Djava.awt.headless=true\
      $XTRA_FLAGS \
-     com.jogamp.newt.util.MainThread\
      org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner \
      $TSTCLASS \
      filtertrace=true \
@@ -46,14 +55,21 @@ function junit_run() {
  
 function main_run() {
      java \
-     -cp ../../gluegen/make/lib/junit.jar:/usr/share/ant/lib/ant.jar:/usr/share/ant/lib/ant-junit.jar:../../gluegen/build-linux-armv7/gluegen-rt.jar:../build-linux-armv7/jar/jogl.all.jar:../build-linux-armv7/jar/jogl.test.jar\
+     -cp ../../gluegen/make/lib/junit.jar:/usr/share/ant/lib/ant.jar:/usr/share/ant/lib/ant-junit.jar:../../gluegen/$ROOT_REL/gluegen-rt.jar:../$ROOT_REL/jar/jogl-all-noawt.jar:../$ROOT_REL/jar/jogl-test.jar\
+     -Djava.awt.headless=true\
      $XTRA_FLAGS \
-     com.jogamp.newt.util.MainThread\
      $TSTCLASS \
      $*
 }
  
-# junit_run 2>&1 | tee $THISDIR/targetcommand.log
 
-main_run $* 2>&1 | tee $THISDIR/targetcommand.log
+let i=0
+
+while true ; do
+ let i=$i+1
+ echo TEST RUN $i
+  # junit_run $* 
+  main_run -time 100 $*
+ cp -a trace-*.pvrt $THISDIR/
+done
  
diff --git a/make/scripts/targetcommand-newt.sh b/make/scripts/targetcommand-newt.sh
index 47b7a0b..1cf7c30 100755
--- a/make/scripts/targetcommand-newt.sh
+++ b/make/scripts/targetcommand-newt.sh
@@ -2,10 +2,13 @@
 
 THISDIR=`pwd`
 
+ROOT_REL=build-linux-armv6hf
+
 export LD_LIBRARY_PATH=$THISDIR/PVRTrace/:$LD_LIBRARY_PATH
 
-XTRA_FLAGS="-Dnewt.test.Screen.disableScreenMode -Djogl.debug.DebugGL -Djogl.debug.TraceGL -Djogl.debug.GLContext.TraceSwitch "
+#XTRA_FLAGS="-Dnewt.test.Screen.disableScreenMode -Djogl.debug.DebugGL -Djogl.debug.TraceGL -Djogl.debug.GLContext.TraceSwitch "
 #XTRA_FLAGS="-Dnewt.test.Screen.disableScreenMode -Djogl.debug.DebugGL -Djogl.debug.TraceGL"
+#XTRA_FLAGS="-Dnewt.test.Screen.disableScreenMode -Djogl.debug.DebugGL"
 #XTRA_FLAGS="-Dnewt.test.Screen.disableScreenMode -Djogl.debug.EGL -Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.GLDrawable"
 #XTRA_FLAGS="-Dnewt.debug.Screen"
 #XTRA_FLAGS="-Dnativewindow.debug.GraphicsConfiguration -Dnativewindow.debug.NativeWindow"
@@ -26,8 +29,11 @@ XTRA_FLAGS="-Dnewt.test.Screen.disableScreenMode -Djogl.debug.DebugGL -Djogl.deb
 #TSTCLASS=com.jogamp.opengl.test.junit.graph.TestTextRendererNEWT01  # (Tegra regressions)
 #TSTCLASS=com.jogamp.opengl.test.junit.jogl.acore.TestGLDebug00NEWT
 #TSTCLASS=com.jogamp.opengl.test.junit.jogl.acore.TestGLDebug01NEWT
-TSTCLASS=com.jogamp.opengl.test.junit.jogl.acore.TestGPUMemSec01NEWT
+#TSTCLASS=com.jogamp.opengl.test.junit.jogl.acore.TestGPUMemSec01NEWT
+TSTCLASS=com.jogamp.opengl.test.junit.jogl.acore.TestGLDrawable01NEWT
 #TSTCLASS=com.jogamp.opengl.test.junit.jogl.acore.TestInitConcurrentNEWT
+#TSTCLASS=com.jogamp.opengl.test.junit.jogl.acore.TestFBODrawableNEWT
+#TSTCLASS=com.jogamp.opengl.test.junit.jogl.caps.TestMultisampleES1NEWT
 
 # Some Regressions (Panda, Omap4)
 #
@@ -42,16 +48,16 @@ TSTCLASS=com.jogamp.opengl.test.junit.jogl.acore.TestGPUMemSec01NEWT
 #TSTCLASS=com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2NEWT2
 #TSTCLASS=com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteNEWT
 #TSTCLASS=com.jogamp.opengl.test.junit.jogl.acore.TestShutdownSharedNEWT
-#TSTCLASS=com.jogamp.opengl.test.junit.jogl.caps.TestMultisampleES1NEWT
 #TSTCLASS=com.jogamp.opengl.test.junit.jogl.caps.TestTranslucencyNEWT
 #TSTCLASS=com.jogamp.opengl.test.junit.jogl.demos.es1.newt.TestGearsES1NEWT
 #TSTCLASS=com.jogamp.opengl.test.junit.jogl.demos.es1.newt.TestRedSquareES1NEWT
 #TSTCLASS=com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestElektronenMultipliziererNEWT
 #TSTCLASS=com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT
 #TSTCLASS=com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestRedSquareES2NEWT
+#TSTCLASS=com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieCube
 #TSTCLASS=com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNEWT
-#TSTCLASS=com.jogamp.opengl.test.junit.jogl.drawable.TestDrawable01NEWT
 #TSTCLASS=com.jogamp.opengl.test.junit.jogl.glsl.TestFBOMRTNEWT01
+#TSTCLASS=com.jogamp.opengl.test.junit.jogl.acore.TestFBOMix2DemosES2NEWT
 #TSTCLASS=com.jogamp.opengl.test.junit.jogl.glsl.TestGLSLShaderState01NEWT
 #TSTCLASS=com.jogamp.opengl.test.junit.jogl.glsl.TestGLSLShaderState02NEWT
 #TSTCLASS=com.jogamp.opengl.test.junit.jogl.glsl.TestGLSLSimple01NEWT
@@ -81,6 +87,7 @@ TSTCLASS=com.jogamp.opengl.test.junit.jogl.acore.TestGPUMemSec01NEWT
  rsync -av --delete --delete-after --delete-excluded \
        --exclude 'build-x86*/' --exclude 'build-linux-x*/' --exclude 'build-android*/' --exclude 'build-win*/' --exclude 'build-mac*/' \
        --exclude 'classes/' --exclude 'src/' --exclude '.git/' --exclude '*-java-src.zip' \
+       --exclude 'make/lib/external/' \
        jogamp at jogamp02::PROJECTS/JOGL/gluegen jogamp at jogamp02::PROJECTS/JOGL/jogl $THISDIR/projects-cross 
 
  cd $THISDIR/projects-cross/jogl/make 
@@ -89,10 +96,9 @@ TSTCLASS=com.jogamp.opengl.test.junit.jogl.acore.TestGPUMemSec01NEWT
  
 function junit_run() {
      java \
-     -cp ../../gluegen/make/lib/junit.jar:/usr/share/ant/lib/ant.jar:/usr/share/ant/lib/ant-junit.jar:../../gluegen/build-linux-armv7/gluegen-rt.jar:../build-linux-armv7/jar/jogl.all-noawt.jar:../build-linux-armv7/jar/jogl.test.jar\
+     -cp ../../gluegen/make/lib/junit.jar:/usr/share/ant/lib/ant.jar:/usr/share/ant/lib/ant-junit.jar:../../gluegen/$ROOT_REL/gluegen-rt.jar:../$ROOT_REL/jar/jogl-all-noawt.jar:../$ROOT_REL/jar/jogl-test.jar\
      -Djava.awt.headless=true\
      $XTRA_FLAGS \
-     com.jogamp.newt.util.MainThread\
      org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner \
      $TSTCLASS \
      filtertrace=true \
@@ -108,10 +114,9 @@ function junit_run() {
  
 function main_run() {
      java \
-     -cp ../../gluegen/make/lib/junit.jar:/usr/share/ant/lib/ant.jar:/usr/share/ant/lib/ant-junit.jar:../../gluegen/build-linux-armv7/gluegen-rt.jar:../build-linux-armv7/jar/jogl.all-noawt.jar:../build-linux-armv7/jar/jogl.test.jar\
+     -cp ../../gluegen/make/lib/junit.jar:/usr/share/ant/lib/ant.jar:/usr/share/ant/lib/ant-junit.jar:../../gluegen/$ROOT_REL/gluegen-rt.jar:../$ROOT_REL/jar/jogl-all-noawt.jar:../$ROOT_REL/jar/jogl-test.jar\
      -Djava.awt.headless=true\
      $XTRA_FLAGS \
-     com.jogamp.newt.util.MainThread\
      $TSTCLASS \
      $*
 }
diff --git a/make/scripts/tests-armv6_armel.sh b/make/scripts/tests-armv6_armel.sh
new file mode 100755
index 0000000..8bc3eff
--- /dev/null
+++ b/make/scripts/tests-armv6_armel.sh
@@ -0,0 +1,7 @@
+#! /bin/bash
+
+spath=`dirname $0`
+
+. $spath/tests.sh  `which java` -DummyArg ../build-linux-armv6 $*
+
+
diff --git a/make/scripts/tests-armv6_armhf.sh b/make/scripts/tests-armv6_armhf.sh
new file mode 100755
index 0000000..6b66a47
--- /dev/null
+++ b/make/scripts/tests-armv6_armhf.sh
@@ -0,0 +1,7 @@
+#! /bin/bash
+
+spath=`dirname $0`
+
+. $spath/tests.sh  `which java` -DummyArg ../build-linux-armv6hf $*
+
+
diff --git a/make/scripts/tests-armv7l_eabi.sh b/make/scripts/tests-armv7l_eabi.sh
deleted file mode 100755
index 2ed3070..0000000
--- a/make/scripts/tests-armv7l_eabi.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#! /bin/bash
-
-spath=`dirname $0`
-
-. $spath/tests.sh  `which java` -DummyArg ../build-armv7l_eabi $*
-
-
diff --git a/make/scripts/tests-javaws-x64.bat b/make/scripts/tests-javaws-x64.bat
index 40f1182..deef4ca 100755
--- a/make/scripts/tests-javaws-x64.bat
+++ b/make/scripts/tests-javaws-x64.bat
@@ -1,4 +1,4 @@
-set JRE_PATH=C:\jre1.6.0_30_x64\bin
+set JRE_PATH=C:\jre1.6.0_35_x64\bin
 set LOG_PATH=%USERPROFILE%\AppData\LocalLow\Sun\Java\Deployment\log
 
 %JRE_PATH%\javaws -uninstall
diff --git a/make/scripts/tests-linux-armv6.sh b/make/scripts/tests-linux-armv6.sh
new file mode 100755
index 0000000..8bc3eff
--- /dev/null
+++ b/make/scripts/tests-linux-armv6.sh
@@ -0,0 +1,7 @@
+#! /bin/bash
+
+spath=`dirname $0`
+
+. $spath/tests.sh  `which java` -DummyArg ../build-linux-armv6 $*
+
+
diff --git a/make/scripts/tests-linux-armv6hf.sh b/make/scripts/tests-linux-armv6hf.sh
new file mode 100755
index 0000000..6b66a47
--- /dev/null
+++ b/make/scripts/tests-linux-armv6hf.sh
@@ -0,0 +1,7 @@
+#! /bin/bash
+
+spath=`dirname $0`
+
+. $spath/tests.sh  `which java` -DummyArg ../build-linux-armv6hf $*
+
+
diff --git a/make/scripts/tests-linux-armv7.sh b/make/scripts/tests-linux-armv7.sh
deleted file mode 100755
index 6ec93db..0000000
--- a/make/scripts/tests-linux-armv7.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#! /bin/bash
-
-spath=`dirname $0`
-
-. $spath/tests.sh  `which java` -DummyArg ../build-linux-armv7 $*
-
-
diff --git a/make/scripts/tests-linux-armv7hf.sh b/make/scripts/tests-linux-armv7hf.sh
deleted file mode 100755
index 5526e81..0000000
--- a/make/scripts/tests-linux-armv7hf.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#! /bin/bash
-
-spath=`dirname $0`
-
-. $spath/tests.sh  `which java` -DummyArg ../build-linux-armv7hf $*
-
-
diff --git a/make/scripts/tests-x32.bat b/make/scripts/tests-x32.bat
index 7947759..ec6c41f 100755
--- a/make/scripts/tests-x32.bat
+++ b/make/scripts/tests-x32.bat
@@ -1,6 +1,7 @@
 REM scripts\java-win32-dbg.bat jogamp.newt.awt.opengl.VersionApplet
-REM scripts\java-win32-dbg.bat com.jogamp.newt.opengl.GLWindow
+scripts\java-win32-dbg.bat com.jogamp.newt.opengl.GLWindow
 REM scripts\java-win32-dbg.bat javax.media.opengl.awt.GLCanvas
+REM scripts\java-win32.bat com.jogamp.opengl.test.junit.jogl.acore.TestInitConcurrentNEWT %*
 REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestMainVersionGLWindowNEWT %*
 REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.offscreen.TestOffscreen01GLPBufferNEWT -time 5000
 REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.awt.TestAWT01GLn
@@ -71,6 +72,10 @@ REM scripts\java-win32.bat com.jogamp.opengl.test.junit.newt.TestWindowClosingPr
 REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWT01GLn %*
 REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWT02GLn %*
 REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWTAWT01GLn $*
+REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting04AWT $*
+REM scripts\java-win32.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting01aSWT $*
+REM scripts\java-win32.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting04SWT $*
+REM scripts\java-win32.bat com.jogamp.opengl.test.junit.jogl.swt.TestNewtCanvasSWTGLn $*
 
 REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.offscreen.TestOffscreen02BitmapNEWT -time 5000
 
@@ -94,7 +99,7 @@ REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestGPUMe
 REM scripts\java-win32.bat com.jogamp.opengl.test.junit.jogl.acore.TestMapBuffer01NEWT
 
 REM scripts\java-win32.bat com.jogamp.opengl.test.junit.jogl.glsl.TestRulerNEWT01
-scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestFBODrawableNEWT %*
+REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestFBODrawableNEWT %*
 REM scripts\java-win32.bat com.jogamp.opengl.test.junit.jogl.glsl.TestFBOMRTNEWT01
 
 REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestElektronenMultipliziererNEWT %*
diff --git a/make/scripts/tests-x64.bat b/make/scripts/tests-x64.bat
index 6d3e46a..c8bc030 100755
--- a/make/scripts/tests-x64.bat
+++ b/make/scripts/tests-x64.bat
@@ -1,6 +1,9 @@
 REM scripts\java-win64-dbg.bat jogamp.newt.awt.opengl.VersionApplet
 REM scripts\java-win64-dbg.bat com.jogamp.newt.opengl.GLWindow
 REM scripts\java-win64-dbg.bat javax.media.opengl.awt.GLCanvas
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLCapabilities01NEWT %*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteNEWT %*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteAWT %*
 REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestMainVersionGLWindowNEWT %*
 REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.offscreen.TestOffscreen01GLPBufferNEWT -time 5000
 REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.awt.TestAWT01GLn
@@ -16,7 +19,7 @@ REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLPro
 REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNewtAWTWrapper %*
 REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNEWT -time 30000
 REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.es1.newt.TestGearsES1NEWT %*
-REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT %*
+scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT %*
 REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT -vsync -time 4000 -x 10 -y 10 -width 100 -height 100 -screen 0
 REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT -vsync -time 40000 -width 100 -height 100 -screen 0 %*
 REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.awt.TestAWTCardLayoutAnimatorStartStopBug532 %*
@@ -29,6 +32,12 @@ REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.glsl.TestGLSLSi
 
 REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestParenting01AWT
 REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestListenerCom01AWT
+
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestNewtKeyEventOrderAWT %*
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestNewtKeyEventAutoRepeatAWT %*
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestNewtKeyPressReleaseUnmaskRepeatAWT %*
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestNewtKeyCodesAWT %*
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestNewtKeyCodeModifiersAWT %*
 REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting01NEWT %*
 REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting02NEWT %*
 REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting01bAWT %*
@@ -37,13 +46,13 @@ REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestP
 REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting03bAWT -time 100000
 REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParentingFocusTraversal01AWT %*
 REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParentingOffscreenLayer01AWT %*
-REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting01aSWT $*
-REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting04AWT $*
-scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting04SWT $*
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting01aSWT %*
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting04AWT %*
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting04SWT %*
 
-REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWTAccessor03AWTGLn $*
-REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWTJOGLGLCanvas01GLn $*
-REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestNewtCanvasSWTGLn $*
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWTAccessor03AWTGLn %*
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWTJOGLGLCanvas01GLn %*
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestNewtCanvasSWTGLn %*
 
 REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestWindows01NEWT
 REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestGLWindows01NEWT
@@ -70,9 +79,9 @@ REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.caps.TestMultis
 REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.awt.TestBug461OffscreenSupersamplingSwingAWT
 REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.glsl.TestShaderCompilationBug459AWT
 
-REM scripts\java-win64.bat com.jogamp.opengl.test.junit.newt.TestWindowClosingProtocol01AWT $*
-REM scripts\java-win64.bat com.jogamp.opengl.test.junit.newt.TestWindowClosingProtocol02NEWT $*
-REM scripts\java-win64.bat com.jogamp.opengl.test.junit.newt.TestWindowClosingProtocol03NewtAWT $*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.newt.TestWindowClosingProtocol01AWT %*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.newt.TestWindowClosingProtocol02NEWT %*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.newt.TestWindowClosingProtocol03NewtAWT %*
 
 REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWT01GLn %*
 REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWT02GLn %*
@@ -93,16 +102,25 @@ REM scripts\java-win64.bat com.jogamp.opengl.test.junit.graph.demos.GPUTextNewtD
 REM scripts\java-win64.bat com.jogamp.opengl.test.junit.graph.demos.GPURegionNewtDemo01
 REM scripts\java-win64.bat com.jogamp.opengl.test.junit.graph.demos.GPURegionNewtDemo02
 
-REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLDebug00NEWT $*
-REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLDebug01NEWT $*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLDebug00NEWT %*
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLDebug01NEWT %*
 
-REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestGPUMemSec01NEWT $*
-REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestGPUMemSec01NEWT $*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestGPUMemSec01NEWT %*
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestGPUMemSec01NEWT %*
 REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestMapBuffer01NEWT
 
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableDelegateOnOffscrnCapsNEWT $*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableGLWindowOnOffscrnCapsNEWT $*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableGLCanvasOnOffscrnCapsAWT $*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableFactoryOffscrnCapsNEWT $*
+
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestFBOAutoDrawableFactoryNEWT $*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestFBOAutoDrawableOffThreadSharedContextES2NEWT $*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestFBOMix2DemosES2NEWT $*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestFBOMRTNEWT01 $*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestFBOAutoDrawableDeadlockAWT $*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.awt.TestBug461FBOSupersamplingSwingAWT
 REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.glsl.TestRulerNEWT01
-REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestFBODrawableNEWT %*
-REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.glsl.TestFBOMRTNEWT01 %*
 
 REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestElektronenMultipliziererNEWT %*
 
diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh
index 43d04c6..ef64aa7 100755
--- a/make/scripts/tests.sh
+++ b/make/scripts/tests.sh
@@ -32,7 +32,13 @@ MOSX=0
 MOSX_MT=0
 uname -a | grep -i Darwin && MOSX=1
 if [ $MOSX -eq 1 ] ; then
-    #export NSZombieEnabled=YES
+    echo setup OSX environment vars
+    export NSZombieEnabled=YES
+    export NSTraceEvents=YES
+    #export OBJC_PRINT_EXCEPTIONS=YES
+    echo NSZombieEnabled $NSZombieEnabled 2>&1 | tee -a java-run.log
+    echo NSTraceEvents $NSTraceEvents  2>&1 | tee -a java-run.log
+    echo OBJC_PRINT_EXCEPTIONS $OBJC_PRINT_EXCEPTIONS  2>&1 | tee -a java-run.log
     MOSX_MT=1
 fi
 
@@ -53,31 +59,49 @@ function jrun() {
     swton=$1
     shift
 
-    #D_ARGS="-Djogl.debug.TraceGL -Djogl.debug.DebugGL -Djogl.debug.GLSLCode"
+    #D_ARGS="-Dnativewindow.debug.X11Util.ATI_HAS_NO_XCLOSEDISPLAY_BUG"
+    #D_ARGS="-Dnativewindow.debug.X11Util.ATI_HAS_NO_MULTITHREADING_BUG"
+    #D_ARGS="-Djogl.disable.opengles"
+    #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.GLSLCode"
+    #D_ARGS="-Djogl.debug.GLSLCode -Djogl.debug.DebugGL -Djogl.debug.TraceGL"
+    #D_ARGS="-Djogl.debug.FixedFuncPipeline -Djogl.debug.GLSLCode"
+    #D_ARGS="-Djogl.debug.FixedFuncPipeline -Djogl.debug.GLSLState"
+    #D_ARGS="-Djogl.debug.FixedFuncPipeline"
+    #D_ARGS="-Djogl.debug.ImmModeSink.Buffer -Djogl.debug.ImmModeSink.Draw"
+    #D_ARGS="-Djogl.debug.FixedFuncPipeline -Djogl.debug.GLSLState -Djogl.debug.ImmModeSink.Buffer -Djogl.debug.ImmModeSink.Draw"
+    #D_ARGS="-Djogl.debug.TraceGL -Djogl.debug.DebugGL -Djogl.debug.GLSLCode"
+    #D_ARGS="-Djogl.debug.DebugGL -Djogl.debug.FBObject -Djogl.debug.GLContext -Djogl.debug.GLDrawable -Djogl.debug.GLCanvas -Dnewt.debug.Window"
     #D_ARGS="-Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.GLDrawable -Djogl.debug.GLContext -Djogl.debug.FBObject"
     #D_ARGS="-Djogl.debug.GLContext.NoProfileAliasing"
     #D_ARGS="-Djogamp.debug=all -Dnativewindow.debug=all -Djogl.debug=all -Dnewt.debug=all"
-    #D_ARGS="-Djogl.debug=all -Dnativewindow.debug=all -Dnewt.debug=all"
-    #D_ARGS="-Djogl.debug=all -Dnativewindow.debug=all -Dnewt.debug=all -Djogamp.debug.Lock"
-    #D_ARGS="-Djogl.debug=all -Dnativewindow.debug=all"
-    #D_ARGS="-Dnewt.debug.Window"
+    #D_ARGS="-Dnativewindow.debug=all -Djogl.debug=all -Dnewt.debug=all"
+    #D_ARGS="-Djogl.debug=all -Dnewt.debug=all"
+    #D_ARGS="-Djogl.debug.GLContext -Djogl.debug.GLDrawable -Dnativewindow.debug.GraphicsConfiguration"
     #D_ARGS="-Djogl.debug.GLDrawable"
+    #D_ARGS="-Djogl.fbo.force.none"
+    #D_ARGS="-Djogl.debug=all -Dnativewindow.debug=all -Dnewt.debug=all -Djogamp.debug.Lock"
+    #D_ARGS="-Djogl.debug=all"
     #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"
     #D_ARGS="-Djogl.debug.GLDebugMessageHandler -Djogl.debug.DebugGL -Djogl.debug.TraceGL"
-    #D_ARGS="-Djogamp.debug.NativeLibrary -Djogamp.debug.NativeLibrary.UseCurrentThreadLibLoader"
+    #D_ARGS="-Djogamp.debug.NativeLibrary"
     #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.GLArrayData"
-    #D_ARGS="-Djogl.debug.EGL -Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.GLDrawable"
+    #D_ARGS="-Djogl.debug.GLDrawable"
+    #D_ARGS="-Djogl.debug.EGLDisplayUtil -Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.GLDrawable"
+    #D_ARGS="-Djogl.debug.EGLDisplayUtil -Dnativewindow.debug.X11Util"
     #D_ARGS="-Djogl.debug.GLDrawable"
     #D_ARGS="-Dnewt.test.Screen.disableScreenMode -Dnewt.debug.Screen"
+    #D_ARGS="-Dnewt.debug.Screen -Djogl.debug.Animator"
     #D_ARGS="-Djogl.debug.ExtensionAvailabilityCache -Djogl.debug=all -Dnativewindow.debug=all -Djogamp.debug.ProcAddressHelper=true -Djogamp.debug.NativeLibrary=true -Djogamp.debug.NativeLibrary.Lookup=true"
     #D_ARGS="-Dnewt.debug.MainThread"
     #D_ARGS="-Dnewt.debug.Window"
@@ -87,26 +111,26 @@ function jrun() {
     #D_ARGS="-Djogl.debug.GLContext -Djogl.debug.GLProfile -Djogl.debug.GLDrawable"
     #D_ARGS="-Djogl.debug.GLContext -Djogl.debug.GLProfile"
     #D_ARGS="-Djogl.debug.GLProfile"
-    #D_ARGS="-Dnewt.debug.EDT -Dnativewindow.debug.ToolkitLock.TraceLock -Dnativewindow.debug.NativeWindow"
     #D_ARGS="-Dnativewindow.debug.NativeWindow"
     #D_ARGS="-Dnewt.debug.Window -Dnewt.debug.Display -Dnewt.debug.EDT"
     #D_ARGS="-Dnewt.debug.EDT -Dnewt.debug.Window -Djogl.debug.GLContext"
     #D_ARGS="-Dnativewindow.debug.X11Util.XErrorStackDump -Dnativewindow.debug.X11Util.TraceDisplayLifecycle -Dnativewindow.debug.X11Util"
     #D_ARGS="-Dnativewindow.debug.X11Util -Djogl.debug.GLContext -Djogl.debug.GLDrawable -Dnewt.debug=all"
     #D_ARGS="-Dnativewindow.debug.X11Util -Dnativewindow.debug.X11Util.XSync"
+    #D_ARGS="-Dnativewindow.debug.X11Util.XSync -Dnativewindow.debug.X11Util.TraceDisplayLifecycle"
     #D_ARGS="-Dnativewindow.debug.X11Util.XSync -Dnewt.debug.Window"
     #D_ARGS="-Djogl.debug.GLDrawable -Djogl.debug.GLContext"
+    #D_ARGS="-Dnativewindow.debug.NativeWindow -Dnativewindow.debug.X11Util"
     #D_ARGS="-Djogamp.common.utils.locks.Lock.timeout=3000 -Djogamp.debug.Lock -Djogl.debug.GLContext.TraceSwitch"
-    #D_ARGS="-Djogamp.common.utils.locks.Lock.timeout=600000 -Djogamp.debug.Lock -Djogamp.debug.Lock.TraceLock"
+    #D_ARGS="-Djogamp.common.utils.locks.Lock.timeout=3000 -Djogamp.debug.Lock -Dnativewindow.debug.ToolkitLock.TraceLock"
     #D_ARGS="-Djogamp.common.utils.locks.Lock.timeout=600000 -Djogamp.debug.Lock -Djogamp.debug.Lock.TraceLock -Dnativewindow.debug.ToolkitLock.TraceLock"
     #D_ARGS="-Djogamp.common.utils.locks.Lock.timeout=600000 -Djogamp.debug.Lock -Dnativewindow.debug.X11Util"
     #D_ARGS="-Dnewt.debug.EDT -Djogamp.common.utils.locks.Lock.timeout=600000 -Djogl.debug.Animator -Dnewt.debug.Display -Dnewt.debug.Screen"
-    #D_ARGS="-Dnewt.debug.Screen"
     #D_ARGS="-Dnewt.debug.Window -Djogamp.common.utils.locks.Lock.timeout=600000 -Djogl.debug.Animator"
     #D_ARGS="-Djogl.debug.Animator -Dnewt.debug=all"
     #D_ARGS="-Dnewt.debug.EDT -Dnewt.debug.Display -Dnativewindow.debug.X11Util -Djogl.debug.GLDrawable -Djogl.debug.GLCanvas"
     #D_ARGS="-Djogl.debug.GLContext"
-    #D_ARGS="-Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.CapabilitiesChooser"
+    #D_ARGS="-Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.CapabilitiesChooser -Djogl.debug.GLDrawable -Djogl.debug.GLProfile"
     #D_ARGS="-Dnewt.debug.Screen -Dnewt.debug.EDT -Djogamp.debug.Lock"
     #D_ARGS="-Djogl.debug.GLContext -Dnativewindow.debug.GraphicsConfiguration"
     #D_ARGS="-Dnewt.debug.EDT"
@@ -122,7 +146,10 @@ function jrun() {
     #D_ARGS="-Djogl.debug.Animator"
     #D_ARGS="-Dnativewindow.debug=all"
     #D_ARGS="-Djogl.debug.GLCanvas"
-    #D_ARGS="-Dnativewindow.debug.ToolkitLock.TraceLock"
+    #D_ARGS="-Djogl.debug.GLContext -Dnativewindow.debug.X11Util.XSync"
+    #D_ARGS="-Dnativewindow.debug.X11Util.XSync -Dnativewindow.debug.ToolkitLock.TraceLock"
+    #D_ARGS="-Dnativewindow.debug.NativeWindow"
+    #D_ARGS="-Dnativewindow.debug.ToolkitLock"
     #D_ARGS="-Djogl.debug.graph.curve -Djogl.debug.GLSLCode -Djogl.debug.TraceGL"
     #D_ARGS="-Djogl.debug.graph.curve -Djogl.debug.GLSLState"
     #D_ARGS="-Djogamp.debug.JNILibLoader -Djogamp.debug.TempJarCache -Djogamp.debug.JarUtil"
@@ -174,6 +201,8 @@ function jrun() {
     #export LD_LIBRARY_PATH=/opt-linux-x86_64/mesa-7.8.1/lib64:$LD_LIBRARY_PATH
     #export LD_LIBRARY_PATH=/usr/lib/mesa:/usr/lib32/mesa:$LD_LIBRARY_PATH
     #export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/mesa:/usr/lib/i386-linux-gnu/mesa:$LD_LIBRARY_PATH
+    #export LD_LIBRARY_PATH=`pwd`/lib/external/mesa/x86_64-linux-gnu:$LD_LIBRARY_PATH
+    #export LD_LIBRARY_PATH=`pwd`/lib/external/mesa/x86_64-linux-gnu/gallium:$LD_LIBRARY_PATH
     echo
     echo "Test Start: $*"
     echo
@@ -181,6 +210,9 @@ function jrun() {
     echo
     echo $javaexe $javaxargs $X_ARGS $D_ARGS $C_ARG $*
     #LIBGL_DRIVERS_PATH=/usr/lib/mesa:/usr/lib32/mesa \
+    #LIBGL_DEBUG=verbose INTEL_STRICT_CONFORMANCE=1 INTEL_DEBUG="buf bat" \
+    #LIBGL_DEBUG=verbose MESA_DEBUG=true INTEL_STRICT_CONFORMANCE=1 \
+    #export LIBGL_DEBUG=verbose MESA_DEBUG=true LIBGL_ALWAYS_SOFTWARE=true
     #gdb --args $javaexe $javaxargs $X_ARGS $D_ARGS $C_ARG $*
     $javaexe $javaxargs $X_ARGS $D_ARGS $C_ARG $*
     echo
@@ -206,7 +238,7 @@ function testawtswt() {
 }
 
 #
-# newt (testnoawt and testawt)
+# core/newt (testnoawt and testawt)
 #
 #testnoawt com.jogamp.nativewindow.NativeWindowVersion $*
 #testnoawt com.jogamp.opengl.JoglVersion $*
@@ -214,15 +246,18 @@ function testawtswt() {
 #testnoawt com.jogamp.newt.opengl.GLWindow $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.offscreen.TestOffscreen01GLPBufferNEWT $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.offscreen.TestOffscreen02BitmapNEWT $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $*
+testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestElektronenMultipliziererNEWT $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFloatUtil01MatrixMatrixMultNOUI $*
-testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestNEWTCloseX11DisplayBug565 $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestPMVMatrix01NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestPMVMatrix02NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestNEWTCloseX11DisplayBug565 $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestMainVersionGLWindowNEWT $*
+#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.TestShutdownSharedNEWT $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestInitConcurrentNEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestInitConcurrent01NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestInitConcurrent02NEWT $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLContextSurfaceLockNEWT $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLDebug00NEWT $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLDebug01NEWT $*
@@ -230,10 +265,28 @@ testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestNEWTCloseX11DisplayBug565
 #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextListNEWT2 $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES1NEWT $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2NEWT $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2NEWT2 $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableDelegateNEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableDelegateOnOffscrnCapsNEWT $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLContextDrawableSwitchNEWT $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBODrawableNEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestPointsNEWT $*
+
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableGLWindowOnOffscrnCapsNEWT $*
+#testawt com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableGLCanvasOnOffscrnCapsAWT $*
+#testawt com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableNewtCanvasAWTOnOffscrnCapsAWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableFactoryOffscrnCapsNEWT $*
+
+#testawt com.jogamp.opengl.test.junit.jogl.acore.TestOffscreenLayer01GLCanvasAWT $*
+#testawt com.jogamp.opengl.test.junit.jogl.acore.TestOffscreenLayer02NewtCanvasAWT $*
+#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParentingFocusTraversal01AWT $*
+#testawt com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2AWT $*
+
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOAutoDrawableFactoryNEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOOffThreadSharedContextMix2DemosES2NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOOnThreadSharedContext1DemoES2NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOMix2DemosES2NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOMRTNEWT01 $*
+#testawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOAutoDrawableDeadlockAWT $*
+#testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug461FBOSupersamplingSwingAWT
+#testawt com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2AWT $*
 
 #testnoawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting01NEWT $*
 #testnoawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting02NEWT $*
@@ -273,13 +326,15 @@ testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestNEWTCloseX11DisplayBug565
 #testawt javax.media.opengl.awt.GLCanvas $*
 #testawt com.jogamp.opengl.test.junit.jogl.acore.TestMainVersionGLCanvasAWT $*
 #testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug551AWT $*
+#testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug572AWT $*
+#testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug611AWT $*
 #testawt com.jogamp.opengl.test.junit.jogl.awt.TestAWT01GLn $*
 #testawt com.jogamp.opengl.test.junit.jogl.acore.TestAWTCloseX11DisplayBug565 $*
 #testawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextListAWT $*
 #testawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextNewtAWTBug523 $*
+#testawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOAutoDrawableDeadlockAWT $*
 #testawt com.jogamp.opengl.test.junit.jogl.acore.TestPBufferDeadlockAWT $*
 #testawt com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteAWT $*
-#testawt com.jogamp.opengl.test.junit.jogl.acore.TestShutdownSharedAWT $*
 #testawt com.jogamp.opengl.test.junit.jogl.acore.x11.TestGLXCallsOnAWT $*
 #testawt com.jogamp.opengl.test.junit.jogl.awt.TestSwingAWT01GLn
 #testawt com.jogamp.opengl.test.junit.jogl.awt.TestAWT03GLCanvasRecreate01 $*
@@ -290,7 +345,8 @@ testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestNEWTCloseX11DisplayBug565
 #testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsAWTAnalyzeBug455 $*
 #testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsGLJPanelAWT $*
 #testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsGLJPanelAWTBug450 $*
-#testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug461OffscreenSupersamplingSwingAWT
+#testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug461FBOSupersamplingSwingAWT
+#testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug461PBufferSupersamplingSwingAWT
 #testawt com.jogamp.opengl.test.junit.jogl.glu.TestBug463ScaleImageMemoryAWT $*
 #testawt com.jogamp.opengl.test.junit.jogl.awt.TestAWTCardLayoutAnimatorStartStopBug532 $*
 
@@ -314,11 +370,16 @@ testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestNEWTCloseX11DisplayBug565
 #
 # newt.awt (testawt)
 #
-#testawt com.jogamp.opengl.test.junit.jogl.newt.TestSwingAWTRobotUsageBeforeJOGLInitBug411
-#testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNewtAWTWrapper
+#testawt com.jogamp.opengl.test.junit.jogl.newt.TestSwingAWTRobotUsageBeforeJOGLInitBug411 $*
+#testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNewtAWTWrapper $*
 #testawt com.jogamp.opengl.test.junit.newt.TestEventSourceNotAWTBug
 #testawt com.jogamp.opengl.test.junit.newt.TestFocus01SwingAWTRobot $*
 #testawt com.jogamp.opengl.test.junit.newt.TestFocus02SwingAWTRobot $*
+#testawt com.jogamp.opengl.test.junit.newt.TestNewtKeyEventOrderAWT $*
+#testawt com.jogamp.opengl.test.junit.newt.TestNewtKeyEventAutoRepeatAWT $*
+#testawt com.jogamp.opengl.test.junit.newt.TestNewtKeyPressReleaseUnmaskRepeatAWT $*
+#testawt com.jogamp.opengl.test.junit.newt.TestNewtKeyCodesAWT $*
+#testawt com.jogamp.opengl.test.junit.newt.TestNewtKeyCodeModifiersAWT $*
 #testawt com.jogamp.opengl.test.junit.newt.TestListenerCom01AWT
 #testawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting01aAWT $*
 #testawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting01bAWT $*
@@ -330,8 +391,6 @@ testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestNEWTCloseX11DisplayBug565
 #testawtswt com.jogamp.opengl.test.junit.newt.parenting.TestParenting01aSWT $*
 #testawtswt com.jogamp.opengl.test.junit.newt.parenting.TestParenting04SWT $*
 #testawt com.jogamp.opengl.test.junit.newt.parenting.TestParentingFocusTraversal01AWT $*
-#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParentingOffscreenLayer01GLCanvasAWT $*
-#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParentingOffscreenLayer02NewtCanvasAWT $*
 #testawt com.jogamp.opengl.test.junit.newt.parenting.TestTranslucentParentingAWT $*
 #testawt com.jogamp.opengl.test.junit.newt.TestCloseNewtAWT
 #testawt com.jogamp.opengl.test.junit.jogl.caps.TestMultisampleES1AWT $*
@@ -339,6 +398,8 @@ testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestNEWTCloseX11DisplayBug565
 #testnoawt com.jogamp.opengl.test.junit.jogl.caps.TestMultisampleES2NEWT $*
 #testawt com.jogamp.opengl.test.junit.jogl.caps.TestTranslucencyAWT $*
 #testawt com.jogamp.opengl.test.junit.jogl.caps.TestTranslucencyNEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.caps.TestBug605FlippedImageNEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.caps.TestBug605FlippedImageAWT $*
 #testawt com.jogamp.opengl.test.junit.jogl.glsl.TestShaderCompilationBug459AWT
 
 #testawt com.jogamp.opengl.test.junit.newt.TestWindowClosingProtocol01AWT $*
@@ -348,6 +409,14 @@ testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestNEWTCloseX11DisplayBug565
 #testawt $*
 
 #
+# Misc Utils
+#
+#testnoawt com.jogamp.opengl.test.junit.jogl.util.TestImmModeSinkES1NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.util.TestES1FixedFunctionPipelineNEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es1.newt.TestGearsES1NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es1.newt.TestRedSquareES1NEWT $*
+
+#
 # Texture / TextureUtils
 #
 #testnoawt com.jogamp.opengl.test.junit.jogl.util.TestPNGImage01NEWT $*
@@ -365,16 +434,13 @@ testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestNEWTCloseX11DisplayBug565
 #testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieCube $*
 
 #
-# GLSL / FBO / ..
+# GLSL
 #
 #testnoawt com.jogamp.opengl.test.junit.jogl.glsl.TestTransformFeedbackVaryingsBug407NEWT $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.glsl.TestGLSLSimple01NEWT $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.glsl.TestGLSLShaderState01NEWT $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.glsl.TestGLSLShaderState02NEWT $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.glsl.TestRulerNEWT01 $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOMRTNEWT01 $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOMix2DemosES2NEWT $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBODrawableNEWT $*
 
 #
 # Graph
@@ -409,14 +475,16 @@ testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestNEWTCloseX11DisplayBug565
 #testawt com.jogamp.opengl.test.junit.newt.TestFocus01SwingAWTRobot $*
 #testawt com.jogamp.opengl.test.junit.newt.TestFocus02SwingAWTRobot $*
 
-#linux:
-
 # osx:
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLDrawable02NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.newt.TestScreenMode02NEWT
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBODrawableNEWT $*
 #testawt com.jogamp.opengl.test.junit.newt.parenting.TestParentingFocusTraversal01AWT $*
-#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParentingOffscreenLayer01GLCanvasAWT $*
 
-#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParentingOffscreenLayer01GLCanvasAWT $*
-#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParentingOffscreenLayer02NewtCanvasAWT $*
+#linux:
+#testawt com.jogamp.opengl.test.junit.newt.TestWindowClosingProtocol01AWT $*
+
+
 
 $spath/count-edt-start.sh java-run.log
 
diff --git a/make/stub_includes/opengl/GL/glxext.h b/make/stub_includes/opengl/GL/glxext.h
index 06dbb27..3d85521 100644
--- a/make/stub_includes/opengl/GL/glxext.h
+++ b/make/stub_includes/opengl/GL/glxext.h
@@ -439,6 +439,16 @@ typedef GLXContext ( * PFNGLXCREATECONTEXTATTRIBSARBPROC) (Display *dpy, GLXFBCo
 #define GLX_EXT_visual_info 1
 #endif
 
+#ifndef GLX_MESA_swap_control
+#define GLX_MESA_swap_control 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern int glXSwapIntervalMESA(unsigned int interval);
+extern int glXGetSwapIntervalMESA(void);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef int ( * PFNGLXSWAPINTERVALMESAPROC)(unsigned int interval);
+typedef int ( * PFNGLXGETSWAPINTERVALMESAPROC)(void);
+#endif
+
 #ifndef GLX_SGI_swap_control
 #define GLX_SGI_swap_control 1
 #ifdef GLX_GLXEXT_PROTOTYPES
diff --git a/make/stub_includes/opengl/macosx-window-system.h b/make/stub_includes/opengl/macosx-window-system.h
index 47b51a5..aaa0cc4 100644
--- a/make/stub_includes/opengl/macosx-window-system.h
+++ b/make/stub_includes/opengl/macosx-window-system.h
@@ -13,6 +13,7 @@
 #include <AppKit/NSOpenGLLayer.h>
 #include <OpenGL/CGLDevice.h>
 #include <OpenGL/OpenGL.h>
+#include <gluegen_stdint.h>
 
 typedef int Bool;
 
@@ -31,7 +32,7 @@ NSView* getNSView(NSOpenGLContext* ctx);
 
 NSOpenGLContext* createContext(NSOpenGLContext* shareContext,
                     NSView* nsView,
-                    Bool allowIncompleteView,
+                    Bool incompleteView,
                     NSOpenGLPixelFormat* pixelFormat,
                     Bool opaque,
                     int* viewNotReady);
@@ -51,12 +52,13 @@ NSOpenGLPixelBuffer* createPBuffer(int renderTarget, int internalFormat, int wid
 Bool destroyPBuffer(NSOpenGLPixelBuffer* pBuffer);
 void setContextPBuffer(NSOpenGLContext* ctx, NSOpenGLPixelBuffer* pBuffer);
 void setContextTextureImageToPBuffer(NSOpenGLContext* ctx, NSOpenGLPixelBuffer* pBuffer, GLenum colorBuffer);
+Bool isNSOpenGLPixelBuffer(uint64_t object);
 
-// NSOpenGLLayer* createNSOpenGLLayer(NSOpenGLContext* ctx, NSOpenGLPixelFormat* fmt, NSView* view, Bool opaque);
-NSOpenGLLayer* createNSOpenGLLayer(NSOpenGLContext* ctx, NSOpenGLPixelFormat* fmt, NSOpenGLPixelBuffer* pbuffer, Bool opaque, int texWidth, int texHeight);
+NSOpenGLLayer* createNSOpenGLLayer(NSOpenGLContext* ctx, int gl3ShaderProgramName, NSOpenGLPixelFormat* fmt, NSOpenGLPixelBuffer* p, uint32_t texID, Bool opaque, int texWidth, int texHeight);
 void setNSOpenGLLayerSwapInterval(NSOpenGLLayer* layer, int interval);
 void waitUntilNSOpenGLLayerIsReady(NSOpenGLLayer* layer, long to_micros);
-void setNSOpenGLLayerNeedsDisplay(NSOpenGLLayer* glLayer);
+void setNSOpenGLLayerNeedsDisplayFBO(NSOpenGLLayer* layer, uint32_t texID);
+void setNSOpenGLLayerNeedsDisplayPBuffer(NSOpenGLLayer* layer, NSOpenGLPixelBuffer* p);
 void releaseNSOpenGLLayer(NSOpenGLLayer *glLayer);
 
 void* getProcAddress(const char *procName);
@@ -67,6 +69,3 @@ void setSwapInterval(NSOpenGLContext* ctx, int interval);
 Bool setGammaRamp(int tableSize, float* redRamp, float* greenRamp, float* blueRamp);
 void resetGammaRamp();
 
-/* returns the screen refresh rate in Hz */
-int getScreenRefreshRate(int scrn_idx);
-
diff --git a/make/stub_includes/x11/window-lib.c b/make/stub_includes/x11/window-lib.c
index bc5df4a..1204d03 100644
--- a/make/stub_includes/x11/window-lib.c
+++ b/make/stub_includes/x11/window-lib.c
@@ -27,9 +27,12 @@ extern void XLockDisplay(Display *display);
 
 extern void XUnlockDisplay(Display *display);
 
-extern Window RootWindow(Display *display, int screen_number);
 extern int DefaultScreen(Display *display);
 
+extern int ScreenCount(Display *display);
+
+extern Window RootWindow(Display *display, int screen_number);
+
 extern XVisualInfo *XGetVisualInfo(
     Display*		/* display */,
     long		/* vinfo_mask */,
diff --git a/make/versions.xml b/make/versions.xml
index f5d17ba..6256831 100644
--- a/make/versions.xml
+++ b/make/versions.xml
@@ -12,7 +12,7 @@
        betas before release candidates to give the Community time to
        react.-->
   <property name="jogl_base_version" value="2.0" />
-  <property name="jogl_int_version"  value="0914010" /> <!-- xxyyzzz, xx=API yy screen-from-to zzz app-version-->
+  <property name="jogl_int_version"  value="0914011" /> <!-- xxyyzzz, xx=API yy screen-from-to zzz app-version-->
 
   <!-- Uncomment this property in order to produce a JOGL release
        build without running the "RI" (Reference Implementation)
diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/RenderState.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/RenderState.java
index eb07142..5e305d6 100644
--- a/src/jogl/classes/com/jogamp/graph/curve/opengl/RenderState.java
+++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/RenderState.java
@@ -93,19 +93,19 @@ public abstract class RenderState {
         return false;
     }    
     
-    public StringBuilder toString(StringBuilder sb) {
+    public StringBuilder toString(StringBuilder sb, boolean alsoUnlocated) {
         if(null==sb) {
             sb = new StringBuilder();
         }
 
         sb.append("RenderState[");
-        st.toString(sb).append(Platform.getNewline());
+        st.toString(sb, alsoUnlocated).append(Platform.getNewline());
         sb.append("]");
 
         return sb;
     }
     
     public String toString() {
-        return toString(null).toString();
+        return toString(null, false).toString();
     }    
 }
diff --git a/src/jogl/classes/com/jogamp/opengl/FBObject.java b/src/jogl/classes/com/jogamp/opengl/FBObject.java
index 644d87b..b7188a7 100644
--- a/src/jogl/classes/com/jogamp/opengl/FBObject.java
+++ b/src/jogl/classes/com/jogamp/opengl/FBObject.java
@@ -28,13 +28,13 @@
 
 package com.jogamp.opengl;
 
-import java.util.ArrayList;
 import java.util.Arrays;
 
 import javax.media.opengl.GL;
 import javax.media.opengl.GL2GL3;
 import javax.media.opengl.GL3;
 import javax.media.opengl.GLBase;
+import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLContext;
 import javax.media.opengl.GLException;
 import javax.media.opengl.GLProfile;
@@ -47,7 +47,7 @@ import com.jogamp.opengl.FBObject.Attachment.Type;
  * Core utility class simplifying usage of framebuffer objects (FBO)
  * with all {@link GLProfile}s. 
  * <p>
- * Supports on-the-fly reconfiguration of dimension and multisample buffers via {@link #reset(GL, int, int, int)}
+ * Supports on-the-fly reconfiguration of dimension and multisample buffers via {@link #reset(GL, int, int, int, boolean)}
  * while preserving the {@link Attachment} references.
  * </p>
  * <p>
@@ -59,54 +59,36 @@ import com.jogamp.opengl.FBObject.Attachment.Type;
  */
 public class FBObject {
     protected static final boolean DEBUG = Debug.debug("FBObject");
+    private static final boolean forceMinimumFBOSupport = Debug.isPropertyDefined("jogl.fbo.force.min", true);
+    private static final boolean FBOResizeQuirk = false;
+    
+    private static enum DetachAction { NONE, DISPOSE, RECREATE };
     
     /** 
-     * 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
-     * <code>ARB_ES2_compatibility</code>, <code>ARB_framebuffer_object</code>, <code>EXT_framebuffer_object</code> or <code>OES_framebuffer_object</code>.
-     * </p>
-     * <p>
-     * Basic FBO support may only include one color attachment and no multisampling,
-     * as well as limited internal formats for renderbuffer.
-     * </p>
-     * @see GLContext#hasFBO()
-     */
-    public static final boolean supportsBasicFBO(GL gl) {
-        return gl.getContext().hasFBO();
-    }
-  
-    /** 
-     * 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
-     * <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>.
-     * </p>
-     * <p>
-     * Full FBO support includes multiple color attachments and multisampling.
-     * </p>
+     * Marker interface, denotes a color buffer attachment.
+     * <p>Always an instance of {@link Attachment}.</p>
+     * <p>Either an instance of {@link ColorAttachment} or {@link TextureAttachment}.</b> 
      */
-    public static final boolean supportsFullFBO(GL gl) {
-        return gl.isGL3() ||                                                         // GL >= 3.0
-                
-               gl.isExtensionAvailable(GLExtensions.ARB_framebuffer_object) ||       // ARB_framebuffer_object
-               
-               ( gl.isExtensionAvailable(GLExtensions.EXT_framebuffer_object) &&     // All EXT_framebuffer_object*
-                 gl.isExtensionAvailable(GLExtensions.EXT_framebuffer_multisample) &&
-                 gl.isExtensionAvailable(GLExtensions.EXT_framebuffer_blit) &&
-                 gl.isExtensionAvailable(GLExtensions.EXT_packed_depth_stencil) ) ;
-    }
-    
-    public static final int getMaxSamples(GL gl) {
-        if( supportsFullFBO(gl) ) {
-            int[] val = new int[] { 0 } ;
-            gl.glGetIntegerv(GL2GL3.GL_MAX_SAMPLES, val, 0);
-            return val[0];
-        } else {
-            return 0;
-        }
+    public static interface Colorbuffer {        
+        /** 
+         * Initializes the color buffer and set it's parameter, if uninitialized, i.e. name is <code>zero</code>.
+         * @return <code>true</code> if newly initialized, otherwise <code>false</code>.
+         * @throws GLException if buffer generation or setup fails. The just created buffer name will be deleted in this case. 
+         */
+        public boolean initialize(GL gl) throws GLException;
+        
+        /** 
+         * Releases the color buffer if initialized, i.e. name is not <code>zero</code>.
+         * @throws GLException if buffer release fails. 
+         */
+        public void free(GL gl) throws GLException;
+        
+        /**
+         * Writes the internal format to the given GLCapabilities object.
+         * @param caps the destination for format bits
+         * @param rgba8Avail whether rgba8 is available
+         */
+        public void formatToGLCapabilities(GLCapabilities caps, boolean rgba8Avail);        
     }
     
     /** Common super class of all attachments */
@@ -137,7 +119,7 @@ public class FBObject {
                     case GL.GL_DEPTH24_STENCIL8:
                         return Type.DEPTH_STENCIL;
                     default:
-                        throw new IllegalArgumentException("format invalid: 0x"+Integer.toHexString(format));
+                        throw new IllegalArgumentException("format invalid: "+toHexString(format));
                 }        
             }
         };
@@ -152,21 +134,91 @@ public class FBObject {
         
         private int name;
         
-        /** <code>true</code> if resource is initialized by {@link #initialize(GL)}, hence {@link #free(GL)} is allowed to free the GL resources. */
-        protected boolean resourceOwner;
-        
-        private int initCounter;
-        
         protected Attachment(Type type, int iFormat, int width, int height, int name) {
             this.type = type;
             this.format = iFormat;
             this.width = width;
             this.height = height;
             this.name = name;
-            this.resourceOwner = false;
-            this.initCounter = 0;
         }
         
+        /**
+         * Writes the internal format to the given GLCapabilities object.
+         * @param caps the destination for format bits
+         * @param rgba8Avail whether rgba8 is available
+         */
+        public final void formatToGLCapabilities(GLCapabilities caps, boolean rgba8Avail) {        
+            final int _format;
+            switch(format) {
+                case GL.GL_RGBA:
+                case 4:
+                    _format = rgba8Avail ? GL.GL_RGBA8 : GL.GL_RGBA4;  
+                    break;
+                case GL.GL_RGB:
+                case 3:
+                    _format = rgba8Avail ? GL.GL_RGB8 : GL.GL_RGB565;
+                    break;
+                default:
+                    _format = format;
+            }
+            switch(_format) {
+                case GL.GL_RGBA4:
+                    caps.setRedBits(4);
+                    caps.setGreenBits(4);
+                    caps.setBlueBits(4);
+                    caps.setAlphaBits(4);
+                    break;
+                case GL.GL_RGB5_A1:
+                    caps.setRedBits(5);
+                    caps.setGreenBits(5);
+                    caps.setBlueBits(5);
+                    caps.setAlphaBits(1);
+                    break;
+                case GL.GL_RGB565:
+                    caps.setRedBits(5);
+                    caps.setGreenBits(6);
+                    caps.setBlueBits(5);
+                    caps.setAlphaBits(0);
+                    break;
+                case GL.GL_RGB8:
+                    caps.setRedBits(8);
+                    caps.setGreenBits(8);
+                    caps.setBlueBits(8);
+                    caps.setAlphaBits(0);
+                    break;
+                case GL.GL_RGBA8:
+                    caps.setRedBits(8);
+                    caps.setGreenBits(8);
+                    caps.setBlueBits(8);
+                    caps.setAlphaBits(8);
+                    break;                    
+                case GL.GL_DEPTH_COMPONENT16:
+                    caps.setDepthBits(16);
+                    break;
+                case GL.GL_DEPTH_COMPONENT24:
+                    caps.setDepthBits(24);
+                    break;
+                case GL.GL_DEPTH_COMPONENT32:
+                    caps.setDepthBits(32);
+                    break;
+                case GL.GL_STENCIL_INDEX1:
+                    caps.setStencilBits(1);
+                    break;
+                case GL.GL_STENCIL_INDEX4:
+                    caps.setStencilBits(4);
+                    break;
+                case GL.GL_STENCIL_INDEX8:
+                    caps.setStencilBits(8);
+                    break;
+                case GL.GL_DEPTH24_STENCIL8:
+                    caps.setDepthBits(24);
+                    caps.setStencilBits(8);
+                    break;
+                default:
+                    throw new IllegalArgumentException("format invalid: "+toHexString(format));
+            }
+        }
+                
         /** width of attachment */
         public final int getWidth() { return width; }
         /** height of attachment */
@@ -177,45 +229,31 @@ public class FBObject {
         public final int getName() { return name; }        
         /* pp */ final void setName(int n) { name = n; }
         
-        public final int getInitCounter() { return initCounter; }
-        
         /** 
-         * Initializes the attachment buffer and set it's parameter, if uninitialized, i.e. name is <code>zero</code>.
-         * <p>Implementation employs an initialization counter, hence it can be paired recursively with {@link #free(GL)}.</p>
-         * @throws GLException if buffer generation or setup fails. The just created buffer name will be deleted in this case. 
-         */
-        public void initialize(GL gl) throws GLException {
-            initCounter++;
-            /*
-            super.initialize(gl);
-            if(1 == getInitCounter() && 0 == getName()  ) {
+         * Initializes the attachment and set it's parameter, if uninitialized, i.e. name is <code>zero</code>.
+         * <pre>
+            final boolean init = 0 == name;
+            if( init ) {
                 do init ..
-                freeResources = true; // if all OK
             }
-            */
-        }
+            return init;
+         * </pre>
+         * @return <code>true</code> if newly initialized, otherwise <code>false</code>.
+         * @throws GLException if buffer generation or setup fails. The just created buffer name will be deleted in this case. 
+         */
+        public abstract boolean initialize(GL gl) throws GLException;
         
         /** 
-         * Releases the attachment buffer if initialized, i.e. name is <code>zero</code>.
-         * <p>Implementation employs an initialization counter, hence it can be paired recursively with {@link #initialize(GL)}.</p>
-         * @throws GLException if buffer release fails. 
-         */
-        public void free(GL gl) throws GLException {
-            /*
-            if(1 == getInitCounter() && freeResources && .. ) {
+         * Releases the attachment if initialized, i.e. name is not <code>zero</code>.
+         * <pre>
+            if(0 != name) {
                 do free ..
-            }
-            super.free(gl);
-            */
-            initCounter--;
-            if(0 == initCounter) {
-                resourceOwner = false;
                 name = 0;
             }
-            if(DEBUG) {
-                System.err.println("Attachment.free: "+this);
-            }
-        }
+         * </pre>
+         * @throws GLException if buffer release fails. 
+         */
+        public abstract void free(GL gl) throws GLException;
         
         /**
          * <p>
@@ -229,9 +267,9 @@ public class FBObject {
             if( ! ( o instanceof Attachment ) ) return false;
             final Attachment a = (Attachment)o;
             return type == a.type &&
-                   format == a.format ||
-                   width == a.width   ||
-                   height== a.height  ||
+                   format == a.format &&
+                   width == a.width   &&
+                   height== a.height  &&
                    name == a.name     ;
         }
         
@@ -255,9 +293,8 @@ public class FBObject {
         int objectHashCode() { return super.hashCode(); }
         
         public String toString() {
-            return getClass().getSimpleName()+"[type "+type+", format 0x"+Integer.toHexString(format)+", "+width+"x"+height+
-                   ", name 0x"+Integer.toHexString(name)+", obj 0x"+Integer.toHexString(objectHashCode())+
-                   ", resOwner "+resourceOwner+", initCount "+initCounter+"]";
+            return getClass().getSimpleName()+"[type "+type+", format "+toHexString(format)+", "+width+"x"+height+
+                   "; name "+toHexString(name)+", obj "+toHexString(objectHashCode())+"]";
         }
         
         public static Type getType(int attachmentPoint, int maxColorAttachments) {
@@ -270,17 +307,17 @@ public class FBObject {
                 case GL.GL_STENCIL_ATTACHMENT:            
                     return Type.STENCIL;
                 default: 
-                    throw new IllegalArgumentException("Invalid attachment point 0x"+Integer.toHexString(attachmentPoint));
+                    throw new IllegalArgumentException("Invalid attachment point "+toHexString(attachmentPoint));
             }
         }
     }
-    
+
     /** Other renderbuffer attachment which maybe a colorbuffer, depth or stencil. */
     public static class RenderAttachment extends Attachment {
         private int samples;
         
         /**
-         * @param type allowed types are {@link Type#DEPTH}, {@link Type#STENCIL} or {@link Type#COLOR}
+         * @param type allowed types are {@link Type#DEPTH_STENCIL} {@link Type#DEPTH}, {@link Type#STENCIL} or {@link Type#COLOR}
          * @param iFormat
          * @param samples
          * @param width
@@ -298,6 +335,7 @@ public class FBObject {
         
         private static Type validateType(Type type) {
             switch(type) {
+                case DEPTH_STENCIL:
                 case DEPTH:
                 case STENCIL:
                 case COLOR:
@@ -336,14 +374,13 @@ public class FBObject {
         }
 
         @Override
-        public void initialize(GL gl) throws GLException {
-            super.initialize(gl);
-            if( 1 == getInitCounter() && 0 == getName() ) {
+        public boolean initialize(GL gl) throws GLException {
+            final boolean init = 0 == getName();
+            if( init ) {
+                checkPreGLError(gl);
+                
                 final int[] name = new int[] { -1 };
                 gl.glGenRenderbuffers(1, name, 0);
-                if( 0 == name[0] ) {
-                    throw new GLException("null renderbuffer, "+this);
-                }
                 setName(name[0]);
                 
                 gl.glBindRenderbuffer(GL.GL_RENDERBUFFER, getName());
@@ -352,43 +389,37 @@ public class FBObject {
                 } else {
                     gl.glRenderbufferStorage(GL.GL_RENDERBUFFER, format, getWidth(), getHeight());
                 }
-                int glerr = gl.glGetError();
+                final int glerr = gl.glGetError();
                 if(GL.GL_NO_ERROR != glerr) {
                     gl.glDeleteRenderbuffers(1, name, 0);
                     setName(0);
-                    throw new GLException("GL Error 0x"+Integer.toHexString(glerr)+" while creating "+this);
+                    throw new GLException("GL Error "+toHexString(glerr)+" while creating "+this);
                 }
-                resourceOwner = true;
                 if(DEBUG) {
-                    System.err.println("Attachment.init: "+this);
+                    System.err.println("Attachment.init.X: "+this);
                 }
             }
+            return init;
         }
         
         @Override
         public void free(GL gl) {
-            if(1 == getInitCounter() && resourceOwner && 0 != getName() ) {
-                final int[] name = new int[] { getName() };
+            final int[] name = new int[] { getName() };
+            if( 0 != name[0] ) {
+                if(DEBUG) {
+                    System.err.println("Attachment.free.0: "+this);
+                }
                 gl.glDeleteRenderbuffers(1, name, 0);
+                setName(0);
             }
-            super.free(gl);
         }
         
         public String toString() {
-            return getClass().getSimpleName()+"[type "+type+", format 0x"+Integer.toHexString(format)+", samples "+samples+", "+getWidth()+"x"+getHeight()+
-                   ", name 0x"+Integer.toHexString(getName())+", obj 0x"+Integer.toHexString(objectHashCode())+
-                   ", resOwner "+resourceOwner+", initCount "+getInitCounter()+"]";
+            return getClass().getSimpleName()+"[type "+type+", format "+toHexString(format)+", samples "+samples+", "+getWidth()+"x"+getHeight()+
+                   ", name "+toHexString(getName())+", obj "+toHexString(objectHashCode())+"]";
         }
     }
     
-    /** 
-     * Marker interface, denotes a color buffer attachment.
-     * <p>Always an instance of {@link Attachment}.</p>
-     * <p>Either an instance of {@link ColorAttachment} or {@link TextureAttachment}.</b> 
-     */
-    public static interface Colorbuffer {        
-    }
-    
     /** Color render buffer attachment  */
     public static class ColorAttachment extends RenderAttachment implements Colorbuffer {
         public ColorAttachment(int iFormat, int samples, int width, int height, int name) {
@@ -441,9 +472,11 @@ public class FBObject {
          * @throws GLException if texture generation and setup fails. The just created texture name will be deleted in this case. 
          */
         @Override
-        public void initialize(GL gl) throws GLException {
-            super.initialize(gl);
-            if( 1 == getInitCounter() && 0 == getName() ) {
+        public boolean initialize(GL gl) throws GLException {
+            final boolean init = 0 == getName();
+            if( init ) {
+                checkPreGLError(gl);
+                
                 final int[] name = new int[] { -1 };            
                 gl.glGenTextures(1, name, 0);
                 if(0 == name[0]) {
@@ -452,7 +485,6 @@ public class FBObject {
                 setName(name[0]);
                 
                 gl.glBindTexture(GL.GL_TEXTURE_2D, name[0]);
-                gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, format, getWidth(), getHeight(), 0, dataFormat, dataType, null);
                 if( 0 < magFilter ) {
                     gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, magFilter);
                 }
@@ -464,32 +496,131 @@ public class FBObject {
                 }
                 if( 0 < wrapT ) {
                     gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, wrapT);            
-                }        
+                }
+                boolean preTexImage2D = true;
                 int glerr = gl.glGetError();
+                if(GL.GL_NO_ERROR == glerr) {
+                    preTexImage2D = false;
+                    gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, format, getWidth(), getHeight(), 0, dataFormat, dataType, null);
+                    glerr = gl.glGetError();
+                }
                 if(GL.GL_NO_ERROR != glerr) {
                     gl.glDeleteTextures(1, name, 0);
                     setName(0);
-                    throw new GLException("GL Error 0x"+Integer.toHexString(glerr)+" while creating "+this);
+                    throw new GLException("GL Error "+toHexString(glerr)+" while creating (pre TexImage2D "+preTexImage2D+") "+this);
+                }
+                if(DEBUG) {
+                    System.err.println("Attachment.init.X: "+this);
                 }
-                resourceOwner = true;
-            }
-            if(DEBUG) {
-                System.err.println("Attachment.init: "+this);
             }
+            return init;
         }
 
         @Override
         public void free(GL gl) {
-            if(1 == getInitCounter() && resourceOwner && 0 != getName() ) {
-                final int[] name = new int[] { getName() };
+            final int[] name = new int[] { getName() };
+            if( 0 != name[0] ) {
+                if(DEBUG) {
+                    System.err.println("Attachment.free.0: "+this);
+                }
                 gl.glDeleteTextures(1, name, 0);
+                setName(0);
             }
-            super.free(gl);
+        }
+        public String toString() {
+            return getClass().getSimpleName()+"[type "+type+", target GL_TEXTURE_2D, level 0, format "+toHexString(format)+
+                                              ", "+getWidth()+"x"+getHeight()+", border 0, dataFormat "+toHexString(dataFormat)+
+                                              ", dataType "+toHexString(dataType)+
+                                              "; min/mag "+toHexString(minFilter)+"/"+toHexString(magFilter)+
+                                              ", wrap S/T "+toHexString(wrapS)+"/"+toHexString(wrapT)+
+                                              "; name "+toHexString(getName())+", obj "+toHexString(objectHashCode())+"]";
+        }               
+    }
+    static String toHexString(int v) {
+        return "0x"+Integer.toHexString(v);
+    }
+    
+    /**
+     * Creates a color {@link TextureAttachment}, i.e. type {@link Type#COLOR_TEXTURE}, 
+     * selecting the texture data type and format automatically.
+     * 
+     * <p>Using default min/mag filter {@link GL#GL_NEAREST} and default wrapS/wrapT {@link GL#GL_CLAMP_TO_EDGE}.</p>
+     * 
+     * @param glp the chosen {@link GLProfile}
+     * @param alpha set to <code>true</code> if you request alpha channel, otherwise <code>false</code>;
+     * @param width texture width 
+     * @param height texture height
+     * @return the created and uninitialized color {@link TextureAttachment}
+     */
+    public static final TextureAttachment createColorTextureAttachment(GLProfile glp, boolean alpha, int width, int height) {
+        return createColorTextureAttachment(glp, alpha, width, height, GL.GL_NEAREST, GL.GL_NEAREST, GL.GL_CLAMP_TO_EDGE, GL.GL_CLAMP_TO_EDGE);
+    }
+    
+    /**
+     * Creates a color {@link TextureAttachment}, i.e. type {@link Type#COLOR_TEXTURE}, 
+     * selecting the texture data type and format automatically.
+     * 
+     * @param glp the chosen {@link GLProfile}
+     * @param alpha set to <code>true</code> if you request alpha channel, otherwise <code>false</code>;
+     * @param width texture width 
+     * @param height texture height
+     * @param magFilter if > 0 value for {@link GL#GL_TEXTURE_MAG_FILTER}
+     * @param minFilter if > 0 value for {@link GL#GL_TEXTURE_MIN_FILTER} 
+     * @param wrapS if > 0 value for {@link GL#GL_TEXTURE_WRAP_S}
+     * @param wrapT if > 0 value for {@link GL#GL_TEXTURE_WRAP_T}
+     * @return the created and uninitialized color {@link TextureAttachment}
+     */
+    public static final TextureAttachment createColorTextureAttachment(GLProfile glp, boolean alpha, int width, int height, 
+                                                                       int magFilter, int minFilter, int wrapS, int wrapT) {
+        final int textureInternalFormat, textureDataFormat, textureDataType;
+        if(glp.isGLES()) { 
+            textureInternalFormat = alpha ? GL.GL_RGBA : GL.GL_RGB;
+            textureDataFormat = alpha ? GL.GL_RGBA : GL.GL_RGB;
+            textureDataType = GL.GL_UNSIGNED_BYTE;
+        } else { 
+            textureInternalFormat = alpha ? GL.GL_RGBA8 : GL.GL_RGB8;
+            // textureInternalFormat = alpha ? GL.GL_RGBA : GL.GL_RGB;
+            // textureInternalFormat = alpha ? 4 : 3;
+            textureDataFormat = alpha ? GL.GL_BGRA : GL.GL_RGB;
+            textureDataType = alpha ? GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV : GL.GL_UNSIGNED_BYTE;
+        }
+        return createColorTextureAttachment(textureInternalFormat, width, height, textureDataFormat, textureDataType, magFilter, minFilter, wrapS, wrapT);
+    }
+    
+    /**
+     * Creates a color {@link TextureAttachment}, i.e. type {@link Type#COLOR_TEXTURE}. 
+     *
+     * @param internalFormat internalFormat parameter to {@link GL#glTexImage2D(int, int, int, int, int, int, int, int, long)}
+     * @param width texture width 
+     * @param height texture height
+     * @param dataFormat format parameter to {@link GL#glTexImage2D(int, int, int, int, int, int, int, int, long)}
+     * @param dataType type parameter to {@link GL#glTexImage2D(int, int, int, int, int, int, int, int, long)}
+     * @param magFilter if > 0 value for {@link GL#GL_TEXTURE_MAG_FILTER}
+     * @param minFilter if > 0 value for {@link GL#GL_TEXTURE_MIN_FILTER} 
+     * @param wrapS if > 0 value for {@link GL#GL_TEXTURE_WRAP_S}
+     * @param wrapT if > 0 value for {@link GL#GL_TEXTURE_WRAP_T}
+     * @return the created and uninitialized color {@link TextureAttachment}
+     */
+    public static final TextureAttachment createColorTextureAttachment(int internalFormat, int width, int height, int dataFormat, int dataType,
+                                                                       int magFilter, int minFilter, int wrapS, int wrapT) {
+        return new TextureAttachment(Type.COLOR_TEXTURE, internalFormat, width, height, dataFormat, dataType, 
+                                     magFilter, minFilter, wrapS, wrapT, 0 /* name */);
+    }
+    
+    private static boolean hasAlpha(int format) {
+        switch(format) {
+            case GL.GL_RGBA8:
+            case GL.GL_RGBA4:
+            case GL.GL_RGBA:
+            case GL.GL_BGRA:
+            case 4:
+                return true;
+            default:
+                return false;
         }
     }
     
     private boolean initialized;
-    private boolean basicFBOSupport;
     private boolean fullFBOSupport;
     private boolean rgba8Avail;
     private boolean depth24Avail;
@@ -503,6 +634,7 @@ public class FBObject {
 
     private int width, height, samples;
     private int vStatus;
+    private boolean ignoreStatus;
     private int fbName;
     private boolean bound;
 
@@ -519,18 +651,21 @@ public class FBObject {
     //
     
     private final void validateColorAttachmentPointRange(int point) {
+        if(!initialized) {
+            throw new GLException("FBO not initialized");
+        }                
         if(maxColorAttachments != colorAttachmentPoints.length) {
             throw new InternalError("maxColorAttachments "+maxColorAttachments+", array.lenght "+colorAttachmentPoints);
         }
         if(0 > point || point >= maxColorAttachments) {
-            throw new IllegalArgumentException("attachment point out of range: "+point+", should be within [0.."+(maxColorAttachments-1)+"]");
+            throw new IllegalArgumentException("attachment point out of range: "+point+", should be within [0.."+(maxColorAttachments-1)+"], "+this);
         }
     }
     
     private final void validateAddColorAttachment(int point, Colorbuffer ca) {
         validateColorAttachmentPointRange(point);
         if( null != colorAttachmentPoints[point] ) {
-            throw new IllegalArgumentException("Cannot attach "+ca+", attachment point already in use by "+colorAttachmentPoints[point]);
+            throw new IllegalArgumentException("Cannot attach "+ca+", attachment point already in use by "+colorAttachmentPoints[point]+", "+this);
         }        
     }
     
@@ -617,7 +752,6 @@ public class FBObject {
         this.initialized = false;
         
         // TBD @ init
-        this.basicFBOSupport = false;
         this.fullFBOSupport = false;
         this.rgba8Avail = false;
         this.depth24Avail = false;
@@ -635,7 +769,8 @@ public class FBObject {
         this.width = 0;
         this.height = 0;
         this.samples = 0;
-        this.vStatus = -1;        
+        this.vStatus = -1;
+        this.ignoreStatus = false;
         this.fbName = 0;
         this.bound = false;
         
@@ -652,14 +787,11 @@ public class FBObject {
     private void init(GL gl, int width, int height, int samples) throws GLException {
         if(initialized) {
             throw new GLException("FBO already initialized");
-        }        
-        fullFBOSupport = supportsFullFBO(gl);
-        
-        if( !fullFBOSupport && !supportsBasicFBO(gl) ) {
+        }
+        if( !gl.hasBasicFBOSupport() ) {
             throw new GLException("FBO not supported w/ context: "+gl.getContext()+", "+this);
         }
-        
-        basicFBOSupport = true;
+        fullFBOSupport = gl.hasFullFBOSupport();        
         
         rgba8Avail = gl.isGL2GL3() || gl.isExtensionAvailable(GLExtensions.OES_rgb8_rgba8);
         depth24Avail = fullFBOSupport || gl.isExtensionAvailable(GLExtensions.OES_depth24);
@@ -669,64 +801,51 @@ public class FBObject {
         stencil08Avail = fullFBOSupport || gl.isExtensionAvailable(GLExtensions.OES_stencil8);
         stencil16Avail = fullFBOSupport;
         
-        packedDepthStencilAvail = fullFBOSupport || gl.isExtensionAvailable(GLExtensions.OES_packed_depth_stencil);
+        packedDepthStencilAvail = fullFBOSupport ||
+                                  gl.isExtensionAvailable(GLExtensions.OES_packed_depth_stencil) ||
+                                  gl.isExtensionAvailable(GLExtensions.EXT_packed_depth_stencil) ;
         
         final boolean NV_fbo_color_attachments = gl.isExtensionAvailable(GLExtensions.NV_fbo_color_attachments);
                                 
         int val[] = new int[1];
         
-        int glerr = gl.glGetError();
-        if(DEBUG && GL.GL_NO_ERROR != glerr) {
-            System.err.println("FBObject.init-preexisting.0 GL Error 0x"+Integer.toHexString(glerr));
-        }
+        checkPreGLError(gl);
 
         int realMaxColorAttachments = 1;
         maxColorAttachments = 1;
         if( null != samplesSink && fullFBOSupport || NV_fbo_color_attachments ) {
             try {
                 gl.glGetIntegerv(GL2GL3.GL_MAX_COLOR_ATTACHMENTS, val, 0);
-                glerr = gl.glGetError();
-                if(GL.GL_NO_ERROR == glerr) {
-                    realMaxColorAttachments = 1 <= val[0] ? val[0] : 1; // cap minimum to 1
-                } else if(DEBUG) {
-                    System.err.println("FBObject.init-GL_MAX_COLOR_ATTACHMENTS query GL Error 0x"+Integer.toHexString(glerr));
-                }
-            } catch (GLException gle) {}
+                realMaxColorAttachments = 1 <= val[0] ? val[0] : 1; // cap minimum to 1
+            } catch (GLException gle) { gle.printStackTrace(); }
         }
         maxColorAttachments = realMaxColorAttachments <= 8 ? realMaxColorAttachments : 8; // cap to limit array size
         
         colorAttachmentPoints = new Colorbuffer[maxColorAttachments];
         colorAttachmentCount = 0;
         
-        maxSamples = 0;
-        if(fullFBOSupport) {
-            gl.glGetIntegerv(GL2GL3.GL_MAX_SAMPLES, val, 0);
-            glerr = gl.glGetError();
-            if(GL.GL_NO_ERROR == glerr) {
-                maxSamples = val[0];
-            } else if(DEBUG) {
-                System.err.println("FBObject.init-GL_MAX_SAMPLES query GL Error 0x"+Integer.toHexString(glerr));
-            }
+        maxSamples = gl.getMaxRenderbufferSamples();
+        if(!forceMinimumFBOSupport) {
+            gl.glGetIntegerv(GL.GL_MAX_TEXTURE_SIZE, val, 0);
+            maxTextureSize = val[0];
+            gl.glGetIntegerv(GL.GL_MAX_RENDERBUFFER_SIZE, val, 0);
+            maxRenderbufferSize = val[0];
+        } else {
+            maxTextureSize = 2048;
+            maxRenderbufferSize = 2048;
         }
-        gl.glGetIntegerv(GL.GL_MAX_TEXTURE_SIZE, val, 0);
-        maxTextureSize = val[0];
-        gl.glGetIntegerv(GL.GL_MAX_RENDERBUFFER_SIZE, val, 0);
-        this.maxRenderbufferSize = val[0];
         
-        glerr = gl.glGetError();
-        if(DEBUG && GL.GL_NO_ERROR != glerr) {
-            System.err.println("FBObject.init-preexisting.1 GL Error 0x"+Integer.toHexString(glerr));
-        }
+        checkPreGLError(gl);
         
         this.width = width;
         this.height = height;
         this.samples = samples <= maxSamples ? samples : maxSamples;
         
         if(DEBUG) {
-            System.err.println("FBObject "+width+"x"+height+", "+samples+" -> "+samples+" samples");
-            System.err.println("basicFBOSupport:          "+basicFBOSupport);
+            System.err.println("FBObject "+width+"x"+height+", "+samples+" -> "+this.samples+" samples");
             System.err.println("fullFBOSupport:           "+fullFBOSupport);
-            System.err.println("maxColorAttachments:      "+maxColorAttachments+"/"+realMaxColorAttachments);
+            System.err.println("isSamplesSink:            "+(null == samplesSink));
+            System.err.println("maxColorAttachments:      "+maxColorAttachments+"/"+realMaxColorAttachments+" [capped/real]");
             System.err.println("maxSamples:               "+maxSamples);
             System.err.println("maxTextureSize:           "+maxTextureSize);
             System.err.println("maxRenderbufferSize:      "+maxRenderbufferSize);
@@ -751,12 +870,8 @@ public class FBObject {
             throw new GLException("size "+width+"x"+height+" exceeds on of the maxima [texture "+maxTextureSize+", renderbuffer "+maxRenderbufferSize+"]");
         }
 
-        if(null != samplesSink) {        
-            // init sampling sink
-            samplesSink.reset(gl, width, height);
-            resetMSAATexture2DSink(gl);
-        }
-
+        resetSamplingSink(gl);
+        
         // generate fbo ..
         gl.glGenFramebuffers(1, val, 0);
         fbName = val[0];
@@ -770,10 +885,11 @@ public class FBObject {
         if(!gl.glIsFramebuffer(fbName)) {
             checkNoError(gl, GL.GL_INVALID_VALUE, "FBObject Init.isFB"); // throws GLException
         }
-        bound = true;        
+        bound = true;
+        samplesSinkDirty = true;
         initialized = true;
         
-        updateStatus(gl);
+        vStatus = GL.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; // always incomplete w/o attachments!
         if(DEBUG) {
             System.err.println("FBObject.init(): "+this);
         }
@@ -787,7 +903,7 @@ public class FBObject {
      * to match the new given parameters.
      * </p>
      * <p>
-     * Currently incompatibility and hence recreation is given if
+     * Incompatibility and hence recreation is forced if
      * the size or sample count doesn't match for subsequent calls.
      * </p>
      * 
@@ -799,7 +915,7 @@ public class FBObject {
      * @throws GLException in case of an error
      */
     public final void reset(GL gl, int newWidth, int newHeight) {
-        reset(gl, newWidth, newHeight, 0);
+        reset(gl, newWidth, newHeight, 0, false);
     }
     
     /**
@@ -810,28 +926,41 @@ public class FBObject {
      * to match the new given parameters.
      * </p>
      * <p>
-     * Currently incompatibility and hence recreation is given if
-     * the size or sample count doesn't match for subsequent calls.
+     * Currently incompatibility and hence recreation of the attachments will be performed 
+     * if the size or sample count doesn't match for subsequent calls.
      * </p>
      * 
      * <p>Leaves the FBO bound state untouched</p>
      * 
      * @param gl the current GL context
-     * @param newWidth
-     * @param newHeight
+     * @param newWidth the new width, it's minimum is capped to 1
+     * @param newHeight the new height, it's minimum is capped to 1
      * @param newSamples if > 0, MSAA will be used, otherwise no multisampling. Will be capped to {@link #getMaxSamples()}.
-     * @throws GLException in case of an error
+     * @param resetSamplingSink <code>true</code> calls {@link #resetSamplingSink(GL)} immediatly. 
+     *                          <code>false</code> postpones resetting the sampling sink until {@link #use(GL, TextureAttachment)} or {@link #syncSamplingSink(GL)},
+     *                          allowing to use the samples sink's FBO and texture until then. The latter is useful to benefit 
+     *                          from implicit double buffering while resetting the sink just before it's being used, eg. at swap-buffer. 
+     *                          
+     * @throws GLException in case of an error, i.e. size too big, etc ..
      */
-    public final void reset(GL gl, int newWidth, int newHeight, int newSamples) {
+    public final void reset(GL gl, int newWidth, int newHeight, int newSamples, boolean resetSamplingSink) {
         if(!initialized) {
             init(gl, newWidth, newHeight, newSamples);
             return;
         }
+        
         newSamples = newSamples <= maxSamples ? newSamples : maxSamples; // clamp
         
         if( newWidth !=  width || newHeight !=  height || newSamples != samples ) {
+            if(0>=newWidth)  { newWidth = 1; }
+            if(0>=newHeight) { newHeight = 1; }
+            if(newWidth > 2 + maxTextureSize  || newHeight> 2 + maxTextureSize ||
+               newWidth > maxRenderbufferSize || newHeight> maxRenderbufferSize  ) {
+                throw new GLException("size "+width+"x"+height+" exceeds on of the maxima [texture "+maxTextureSize+", renderbuffer "+maxRenderbufferSize+"]");
+            }
+        
             if(DEBUG) {
-                System.err.println("FBObject.reset - START - "+this);
+                System.err.println("FBObject.reset - START - "+width+"x"+height+", "+samples+" -> "+newWidth+"x"+newHeight+", "+newSamples+"; "+this);
             }        
             
             final boolean wasBound = isBound();
@@ -839,12 +968,14 @@ public class FBObject {
             width = newWidth;
             height = newHeight;
             samples = newSamples;
-            detachAllImpl(gl, true , true);
-            resetMSAATexture2DSink(gl);
+            detachAllImpl(gl, true , true);            
+            if(resetSamplingSink) {
+                resetSamplingSink(gl);
+            }
             
-            if(wasBound) {
-                bind(gl);
-            } else {
+            samplesSinkDirty = true;
+
+            if(!wasBound) {
                 unbind(gl);
             }
             
@@ -854,6 +985,28 @@ public class FBObject {
         }        
     }
             
+    /**
+     * Writes the internal format of the attachments to the given GLCapabilities object.
+     * @param caps the destination for format bits
+     */
+    public final void formatToGLCapabilities(GLCapabilities caps) {
+        caps.setSampleBuffers(samples > 0);
+        caps.setNumSamples(samples);
+        caps.setDepthBits(0);
+        caps.setStencilBits(0);
+        
+        final Colorbuffer cb = samples > 0 ? getSamplingSink() : getColorbuffer(0);
+        if(null != cb) {
+            cb.formatToGLCapabilities(caps, rgba8Avail);
+        }        
+        if(null != depth) {
+            depth.formatToGLCapabilities(caps, rgba8Avail);
+        }
+        if(null != stencil && stencil != depth) {
+            stencil.formatToGLCapabilities(caps, rgba8Avail);
+        }
+    }
+    
     /** 
      * Note that the status may reflect an incomplete state during transition of attachments.
      * @return The FB status. {@link GL.GL_FRAMEBUFFER_COMPLETE} if ok, otherwise return GL FBO error state or -1
@@ -877,31 +1030,31 @@ public class FBObject {
                 return "OK";
                 
             case GL.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
-                return("GL FBO: incomplete, incomplete attachment\n");
+                return("FBO incomplete attachment\n");
             case GL.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
-                return("GL FBO: incomplete, missing attachment");
+                return("FBO missing attachment");
             case GL.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
-                return("GL FBO: incomplete, attached images must have same dimensions");
+                return("FBO attached images must have same dimensions");
             case GL.GL_FRAMEBUFFER_INCOMPLETE_FORMATS:
-                 return("GL FBO: incomplete, attached images must have same format");
+                 return("FBO attached images must have same format");
             case GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
-                return("GL FBO: incomplete, missing draw buffer");
+                return("FBO missing draw buffer");
             case GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
-                return("GL FBO: incomplete, missing read buffer");
+                return("FBO missing read buffer");
             case GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
-                return("GL FBO: incomplete, missing multisample buffer");
+                return("FBO missing multisample buffer");
             case GL3.GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:                
-                return("GL FBO: incomplete, layer targets");
+                return("FBO missing layer targets");
                 
             case GL.GL_FRAMEBUFFER_UNSUPPORTED:
-                return("GL FBO: Unsupported framebuffer format");
+                return("Unsupported FBO format");
             case GL2GL3.GL_FRAMEBUFFER_UNDEFINED:
-                 return("GL FBO: framebuffer undefined");
+                 return("FBO undefined");
                  
             case 0:
-                return("GL FBO: incomplete, implementation fault");
+                return("FBO implementation fault");
             default:
-                return("GL FBO: incomplete, implementation ERROR 0x"+Integer.toHexString(fbStatus));
+                return("FBO incomplete, implementation ERROR "+toHexString(fbStatus));
         }
     }
     
@@ -932,19 +1085,28 @@ public class FBObject {
                 
             case 0:                
             default:
-                System.out.println("Framebuffer " + fbName + " is incomplete: status = 0x" + Integer.toHexString(vStatus) + 
+                System.err.println("Framebuffer " + fbName + " is incomplete, status = " + toHexString(vStatus) + 
                         " : " + getStatusString(vStatus));
                 return false;
         }
     }
         
+    private static int checkPreGLError(GL gl) {
+        int glerr = gl.glGetError();
+        if(DEBUG && GL.GL_NO_ERROR != glerr) {
+            System.err.println("Pre-existing GL error: "+toHexString(glerr));
+            Thread.dumpStack();
+        }
+        return glerr;        
+    }
+    
     private final boolean checkNoError(GL gl, int err, String exceptionMessage) throws GLException {
         if(GL.GL_NO_ERROR != err) {
             if(null != gl) {
                 destroy(gl);
             }
             if(null != exceptionMessage) {
-                throw new GLException(exceptionMessage+" GL Error 0x"+Integer.toHexString(err));
+                throw new GLException(exceptionMessage+" GL Error "+toHexString(err)+" of "+this.toString());
             }
             return false;
         }
@@ -958,7 +1120,7 @@ public class FBObject {
     }
     
     /**
-     * Attaches a Texture2D Color Buffer to this FBO's instance at the given attachment point,
+     * Attaches a {@link Colorbuffer}, i.e. {@link TextureAttachment}, to this FBO's instance at the given attachment point,
      * selecting the texture data type and format automatically.
      * 
      * <p>Using default min/mag filter {@link GL#GL_NEAREST} and default wrapS/wrapT {@link GL#GL_CLAMP_TO_EDGE}.</p>
@@ -970,13 +1132,15 @@ public class FBObject {
      * @param alpha set to <code>true</code> if you request alpha channel, otherwise <code>false</code>;
      * @return TextureAttachment instance describing the new attached texture colorbuffer if bound and configured successfully, otherwise GLException is thrown
      * @throws GLException in case the texture colorbuffer couldn't be allocated or MSAA has been chosen
+     * @see #createColorTextureAttachment(GLProfile, boolean, int, int)
      */
     public final TextureAttachment attachTexture2D(GL gl, int attachmentPoint, boolean alpha) throws GLException {
-        return attachTexture2D(gl, attachmentPoint, alpha, GL.GL_NEAREST, GL.GL_NEAREST, GL.GL_CLAMP_TO_EDGE, GL.GL_CLAMP_TO_EDGE);
+        return (TextureAttachment)attachColorbuffer(gl, attachmentPoint,
+                     createColorTextureAttachment(gl.getGLProfile(), alpha, width, height));
     }
     
     /**
-     * Attaches a Texture2D Color Buffer to this FBO's instance at the given attachment point,
+     * Attaches a {@link Colorbuffer}, i.e. {@link TextureAttachment}, to this FBO's instance at the given attachment point,
      * selecting the texture data type and format automatically.
      * 
      * <p>Leaves the FBO bound.</p>
@@ -990,23 +1154,15 @@ public class FBObject {
      * @param wrapT if > 0 value for {@link GL#GL_TEXTURE_WRAP_T}
      * @return TextureAttachment instance describing the new attached texture colorbuffer if bound and configured successfully, otherwise GLException is thrown
      * @throws GLException in case the texture colorbuffer couldn't be allocated or MSAA has been chosen
+     * @see #createColorTextureAttachment(GLProfile, boolean, int, int, int, int, int, int)
      */
     public final TextureAttachment attachTexture2D(GL gl, int attachmentPoint, boolean alpha, int magFilter, int minFilter, int wrapS, int wrapT) throws GLException {
-        final int textureInternalFormat, textureDataFormat, textureDataType;
-        if(gl.isGLES()) { 
-            textureInternalFormat = alpha ? GL.GL_RGBA : GL.GL_RGB;
-            textureDataFormat = alpha ? GL.GL_RGBA : GL.GL_RGB;
-            textureDataType = GL.GL_UNSIGNED_BYTE;
-        } else { 
-            textureInternalFormat = alpha ? GL.GL_RGBA8 : GL.GL_RGB8;
-            textureDataFormat = alpha ? GL.GL_BGRA : GL.GL_RGB;
-            textureDataType = alpha ? GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV : GL.GL_UNSIGNED_BYTE;
-        }
-        return attachTexture2D(gl, attachmentPoint, textureInternalFormat, textureDataFormat, textureDataType, magFilter, minFilter, wrapS, wrapT);
+        return (TextureAttachment)attachColorbuffer(gl, attachmentPoint,
+                     createColorTextureAttachment(gl.getGLProfile(), alpha, width, height, magFilter, minFilter, wrapS, wrapT));
     }
     
     /**
-     * Attaches a Texture2D Color Buffer to this FBO's instance at the given attachment point.
+     * Attaches a {@link Colorbuffer}, i.e. {@link TextureAttachment}, to this FBO's instance at the given attachment point.
      * 
      * <p>Leaves the FBO bound.</p>
      * 
@@ -1021,64 +1177,33 @@ public class FBObject {
      * @param wrapT if > 0 value for {@link GL#GL_TEXTURE_WRAP_T}
      * @return TextureAttachment instance describing the new attached texture colorbuffer if bound and configured successfully, otherwise GLException is thrown
      * @throws GLException in case the texture colorbuffer couldn't be allocated or MSAA has been chosen
+     * @see #createColorTextureAttachment(int, int, int, int, int, int, int, int, int)
      */
     public final TextureAttachment attachTexture2D(GL gl, int attachmentPoint,
                                                    int internalFormat, int dataFormat, int dataType,
                                                    int magFilter, int minFilter, int wrapS, int wrapT) throws GLException {
-        return attachTexture2D(gl, attachmentPoint, 
-                               new TextureAttachment(Type.COLOR_TEXTURE, internalFormat, width, height, dataFormat, dataType, 
-                                                     magFilter, minFilter, wrapS, wrapT, 0 /* name */));
+        return (TextureAttachment)attachColorbuffer(gl, attachmentPoint,
+                     createColorTextureAttachment(internalFormat, width, height, dataFormat, dataType, magFilter, minFilter, wrapS, wrapT));
     }
     
     /**
-     * Attaches a Texture2D Color Buffer to this FBO's instance at the given attachment point.
+     * Creates a {@link ColorAttachment}, selecting the format automatically.
      *  
-     * <p>
-     * In case the passed TextureAttachment <code>texA</code> is uninitialized, i.e. it's texture name is <code>zero</code>,
-     * a new texture name is generated and setup w/ the texture parameter.<br/>
-     * Otherwise, i.e. texture name is not <code>zero</code>, the passed TextureAttachment <code>texA</code> is
-     * considered complete and assumed matching this FBO requirement. A GL error may occur is the latter is untrue. 
-     * </p>
-     *    
-     * <p>Leaves the FBO bound.</p>
-     * 
-     * @param gl the current GL context
-     * @param attachmentPoint the color attachment point ranging from [0..{@link #getMaxColorAttachments()}-1]
-     * @param texA the to be attached {@link TextureAttachment}. Maybe complete or uninitialized, see above. 
-     * @return the passed TextureAttachment <code>texA</code> instance describing the new attached texture colorbuffer if bound and configured successfully, otherwise GLException is thrown
-     * @throws GLException in case the texture colorbuffer couldn't be allocated or MSAA has been chosen
+     * @param alpha set to <code>true</code> if you request alpha channel, otherwise <code>false</code>;
+     * @return uninitialized ColorAttachment instance describing the new attached colorbuffer
      */
-    public final TextureAttachment attachTexture2D(GL gl, int attachmentPoint, TextureAttachment texA) throws GLException {
-        validateAddColorAttachment(attachmentPoint, texA);
-        
-        if(samples>0) {
-            removeColorAttachment(attachmentPoint, texA);
-            throw new GLException("Texture2D not supported w/ MSAA. If you have enabled MSAA with exisiting texture attachments, you may want to detach them via detachAllTexturebuffer(gl).");
-        }
-        
-        texA.initialize(gl);
-        addColorAttachment(attachmentPoint, texA);
-                
-        bind(gl);
-
-        // Set up the color buffer for use as a renderable texture:
-        gl.glFramebufferTexture2D(GL.GL_FRAMEBUFFER,
-                                  GL.GL_COLOR_ATTACHMENT0 + attachmentPoint,
-                                  GL.GL_TEXTURE_2D, texA.getName(), 0);
-        updateStatus(gl);
-        
-        if(!isStatusValid()) {
-            detachColorbuffer(gl, attachmentPoint);
-            throw new GLException("attachTexture2D "+texA+" at "+attachmentPoint+" failed "+getStatusString()+", "+this);
-        }
-        if(DEBUG) {
-            System.err.println("FBObject.attachTexture2D: "+this);
+    public final ColorAttachment createColorAttachment(boolean alpha) {
+        final int internalFormat;
+        if( rgba8Avail ) {
+            internalFormat = alpha ? GL.GL_RGBA8 : GL.GL_RGB8 ;
+        } else {
+            internalFormat = alpha ? GL.GL_RGBA4 : GL.GL_RGB565;
         }
-        return texA;
+        return new ColorAttachment(internalFormat, samples, width, height, 0);
     }
-    
+        
     /**
-     * Attaches a Color Buffer to this FBO's instance at the given attachment point,
+     * Attaches a {@link Colorbuffer}, i.e. {@link ColorAttachment}, to this FBO's instance at the given attachment point,
      * selecting the format automatically.
      *  
      * <p>Leaves the FBO bound.</p>
@@ -1088,19 +1213,14 @@ public class FBObject {
      * @param alpha set to <code>true</code> if you request alpha channel, otherwise <code>false</code>;
      * @return ColorAttachment instance describing the new attached colorbuffer if bound and configured successfully, otherwise GLException is thrown
      * @throws GLException in case the colorbuffer couldn't be allocated
+     * @see #createColorAttachment(boolean)
      */
     public final ColorAttachment attachColorbuffer(GL gl, int attachmentPoint, boolean alpha) throws GLException {
-        final int internalFormat;
-        if( rgba8Avail ) {
-            internalFormat = alpha ? GL.GL_RGBA8 : GL.GL_RGB8 ;
-        } else {
-            internalFormat = alpha ? GL.GL_RGBA4 : GL.GL_RGB565;
-        }
-        return attachColorbuffer(gl, attachmentPoint, internalFormat);
+        return (ColorAttachment) attachColorbuffer(gl, attachmentPoint, createColorAttachment(alpha));
     }
     
     /**
-     * Attaches a Color Buffer to this FBO's instance at the given attachment point.
+     * Attaches a {@link Colorbuffer}, i.e. {@link ColorAttachment}, to this FBO's instance at the given attachment point.
      *  
      * <p>Leaves the FBO bound.</p>
      * 
@@ -1114,47 +1234,86 @@ public class FBObject {
     public final ColorAttachment attachColorbuffer(GL gl, int attachmentPoint, int internalFormat) throws GLException, IllegalArgumentException {
         final Attachment.Type atype = Attachment.Type.determine(internalFormat);
         if( Attachment.Type.COLOR != atype ) {
-            throw new IllegalArgumentException("colorformat invalid: 0x"+Integer.toHexString(internalFormat)+", "+this);
+            throw new IllegalArgumentException("colorformat invalid: "+toHexString(internalFormat)+", "+this);
         }
         
-        return attachColorbuffer(gl, attachmentPoint, new ColorAttachment(internalFormat, samples, width, height, 0));
+        return (ColorAttachment) attachColorbuffer(gl, attachmentPoint, new ColorAttachment(internalFormat, samples, width, height, 0));
     }
     
     /**
-     * Attaches a Color Buffer to this FBO's instance at the given attachment point.
+     * Attaches a {@link Colorbuffer}, i.e. {@link ColorAttachment} or {@link TextureAttachment},  
+     * to this FBO's instance at the given attachment point.
      *  
+     * <p>
+     * If {@link Colorbuffer} is a {@link TextureAttachment} and is uninitialized, i.e. it's texture name is <code>zero</code>,
+     * a new texture name is generated and setup w/ the texture parameter.<br/>
+     * Otherwise, i.e. texture name is not <code>zero</code>, the passed TextureAttachment <code>texA</code> is
+     * considered complete and assumed matching this FBO requirement. A GL error may occur is the latter is untrue. 
+     * </p>
+     * 
      * <p>Leaves the FBO bound.</p>
      * 
      * @param gl
      * @param attachmentPoint the color attachment point ranging from [0..{@link #getMaxColorAttachments()}-1]
-     * @param colA the template for the new {@link ColorAttachment}   
-     * @return ColorAttachment instance describing the new attached colorbuffer if bound and configured successfully, otherwise GLException is thrown
-     * @throws GLException in case the colorbuffer couldn't be allocated
+     * @param colbuf the to be attached {@link Colorbuffer}   
+     * @return newly attached {@link Colorbuffer} instance if bound and configured successfully, otherwise GLException is thrown
+     * @throws GLException in case the colorbuffer couldn't be allocated or MSAA has been chosen in case of a {@link TextureAttachment} 
      */
-    public final ColorAttachment attachColorbuffer(GL gl, int attachmentPoint, ColorAttachment colA) throws GLException {
-        validateAddColorAttachment(attachmentPoint, colA);
-        
-        colA.initialize(gl);        
-        addColorAttachment(attachmentPoint, colA);
-        
+    public final Colorbuffer attachColorbuffer(GL gl, int attachmentPoint, Colorbuffer colbuf) throws GLException {
         bind(gl);
-                
-        // Attach the color buffer
-        gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, 
-                                     GL.GL_COLOR_ATTACHMENT0 + attachmentPoint, 
-                                     GL.GL_RENDERBUFFER, colA.getName());
+        return attachColorbufferImpl(gl, attachmentPoint, colbuf);
+    }
 
-        updateStatus(gl);                
-        if(!isStatusValid()) {
-            detachColorbuffer(gl, attachmentPoint);
-            throw new GLException("attachColorbuffer "+colA+" at "+attachmentPoint+" failed "+getStatusString()+", "+this);
+    private final Colorbuffer attachColorbufferImpl(GL gl, int attachmentPoint, Colorbuffer colbuf) throws GLException {
+        validateAddColorAttachment(attachmentPoint, colbuf);
+        
+        final boolean initializedColorbuf = colbuf.initialize(gl);
+        addColorAttachment(attachmentPoint, colbuf);
+                
+        if(colbuf instanceof TextureAttachment) {
+            final TextureAttachment texA = (TextureAttachment) colbuf;
+            
+            if(samples>0) {
+                removeColorAttachment(attachmentPoint, texA);
+                if(initializedColorbuf) {
+                    texA.free(gl);
+                }
+                throw new GLException("Texture2D not supported w/ MSAA. If you have enabled MSAA with exisiting texture attachments, you may want to detach them via detachAllTexturebuffer(gl).");
+            }
+            
+            // Set up the color buffer for use as a renderable texture:
+            gl.glFramebufferTexture2D(GL.GL_FRAMEBUFFER,
+                                      GL.GL_COLOR_ATTACHMENT0 + attachmentPoint,
+                                      GL.GL_TEXTURE_2D, texA.getName(), 0);
+            
+            if(!ignoreStatus) {
+                updateStatus(gl);        
+                if(!isStatusValid()) {
+                    detachColorbuffer(gl, attachmentPoint, true);
+                    throw new GLException("attachTexture2D "+texA+" at "+attachmentPoint+" failed "+getStatusString()+", "+this);
+                }
+            }
+        } else if(colbuf instanceof ColorAttachment) {
+            final ColorAttachment colA = (ColorAttachment) colbuf;
+            
+            // Attach the color buffer
+            gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, 
+                                         GL.GL_COLOR_ATTACHMENT0 + attachmentPoint, 
+                                         GL.GL_RENDERBUFFER, colA.getName());
+    
+            if(!ignoreStatus) {
+                updateStatus(gl);
+                if(!isStatusValid()) {
+                    detachColorbuffer(gl, attachmentPoint, true);
+                    throw new GLException("attachColorbuffer "+colA+" at "+attachmentPoint+" failed "+getStatusString()+", "+this);
+                }
+            }
         }
         if(DEBUG) {
-            System.err.println("FBObject.attachColorbuffer: "+this);
+            System.err.println("FBObject.attachColorbuffer.X: [attachmentPoint "+attachmentPoint+", colbuf "+colbuf+"]: "+this);
         }
-        return colA;
+        return colbuf;
     }
-
     
     /**
      * Attaches one depth, stencil or packed-depth-stencil buffer to this FBO's instance,
@@ -1270,18 +1429,20 @@ public class FBObject {
     public final void attachRenderbuffer(GL gl, int internalFormat) throws GLException, IllegalArgumentException {
         final Attachment.Type atype = Attachment.Type.determine(internalFormat);
         if( Attachment.Type.DEPTH != atype && Attachment.Type.STENCIL != atype && Attachment.Type.DEPTH_STENCIL != atype ) {
-            throw new IllegalArgumentException("renderformat invalid: 0x"+Integer.toHexString(internalFormat)+", "+this);
+            throw new IllegalArgumentException("renderformat invalid: "+toHexString(internalFormat)+", "+this);
         }
         attachRenderbufferImpl(gl, atype, internalFormat);
     }
     
     protected final void attachRenderbufferImpl(GL gl, Attachment.Type atype, int internalFormat) throws GLException {
         if( null != depth && ( Attachment.Type.DEPTH == atype || Attachment.Type.DEPTH_STENCIL == atype ) ) {
-            throw new GLException("FBO depth buffer already attached (rb "+depth+"), type is "+atype+", 0x"+Integer.toHexString(internalFormat)+", "+this);
+            throw new GLException("FBO depth buffer already attached (rb "+depth+"), type is "+atype+", "+toHexString(internalFormat)+", "+this);
         }        
         if( null != stencil && ( Attachment.Type.STENCIL== atype || Attachment.Type.DEPTH_STENCIL == atype ) ) {
-            throw new GLException("FBO stencil buffer already attached (rb "+stencil+"), type is "+atype+", 0x"+Integer.toHexString(internalFormat)+", "+this);
+            throw new GLException("FBO stencil buffer already attached (rb "+stencil+"), type is "+atype+", "+toHexString(internalFormat)+", "+this);
         }
+        bind(gl);
+        
         attachRenderbufferImpl2(gl, atype, internalFormat);
     }
         
@@ -1304,24 +1465,19 @@ public class FBObject {
             stencil.initialize(gl);
         } else if( Attachment.Type.DEPTH_STENCIL == atype ) {
             if(null == depth) {
-                depth = new RenderAttachment(Type.DEPTH, internalFormat, samples, width, height, 0);
+                if(null != stencil) {
+                    throw new InternalError("XXX: DEPTH_STENCIL, depth was null, stencil not: "+this.toString());
+                }
+                depth = new RenderAttachment(Type.DEPTH_STENCIL, internalFormat, samples, width, height, 0);
             } else {
                 depth.setSize(width, height);
                 depth.setSamples(samples);
             }
             depth.initialize(gl);
-            if(null == stencil) {
-                stencil = new RenderAttachment(Type.STENCIL, internalFormat, samples, width, height, depth.getName());
-            } else {
-                stencil.setName(depth.getName());
-                stencil.setSize(width, height);
-                stencil.setSamples(samples);
-            }
-            stencil.initialize(gl);
+            // DEPTH_STENCIL shares buffer w/ depth and stencil
+            stencil = depth;
         }
 
-        bind(gl);
-        
         // Attach the buffer
         if( Attachment.Type.DEPTH == atype ) {
             gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_DEPTH_ATTACHMENT, GL.GL_RENDERBUFFER, depth.getName());
@@ -1332,40 +1488,50 @@ public class FBObject {
             gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, stencil.getName());
         }
         
-        updateStatus(gl);
-        if( !isStatusValid() ) {
-            detachRenderbuffer(gl, atype);
-            throw new GLException("renderbuffer attachment failed: "+this.getStatusString());
+        if(!ignoreStatus) {
+            updateStatus(gl);
+            if( !isStatusValid() ) {
+                detachRenderbuffer(gl, atype, true);
+                throw new GLException("renderbuffer [attachmentType "+atype+", iformat "+toHexString(internalFormat)+"] failed: "+this.getStatusString()+": "+this.toString());
+            }
         }
 
         if(DEBUG) {
-            System.err.println("FBObject.attachRenderbuffer: "+this);
-        }
+            System.err.println("FBObject.attachRenderbuffer.X: [attachmentType "+atype+", iformat "+toHexString(internalFormat)+"]: "+this);
+        }        
     }
     
     /**
+     * Detaches a {@link Colorbuffer}, i.e. {@link ColorAttachment} or {@link TextureAttachment}. 
      * <p>Leaves the FBO bound!</p>
+     * 
      * @param gl
-     * @param ca
+     * @param attachmentPoint
+     * @param dispose true if the Colorbuffer shall be disposed
+     * @return the detached Colorbuffer
      * @throws IllegalArgumentException
      */
-    public final void detachColorbuffer(GL gl, int attachmentPoint) throws IllegalArgumentException {
-        if(null == detachColorbufferImpl(gl, attachmentPoint, false)) {
+    public final Colorbuffer detachColorbuffer(GL gl, int attachmentPoint, boolean dispose) throws IllegalArgumentException {
+        bind(gl);
+        
+        final Colorbuffer res = detachColorbufferImpl(gl, attachmentPoint, dispose ? DetachAction.DISPOSE : DetachAction.NONE);
+        if(null == res) {
             throw new IllegalArgumentException("ColorAttachment at "+attachmentPoint+", not attached, "+this);            
         }
         if(DEBUG) {
-            System.err.println("FBObject.detachAll: "+this);
+            System.err.println("FBObject.detachColorbuffer.X: [attachmentPoint "+attachmentPoint+", dispose "+dispose+"]: "+res+", "+this);
         }
+        return res;
     }
     
-    private final Colorbuffer detachColorbufferImpl(GL gl, int attachmentPoint, boolean recreate) {
-        final Colorbuffer colbuf = colorAttachmentPoints[attachmentPoint]; // shortcut, don't validate here
+    private final Colorbuffer detachColorbufferImpl(GL gl, int attachmentPoint, DetachAction detachAction) {
+        Colorbuffer colbuf = colorAttachmentPoints[attachmentPoint]; // shortcut, don't validate here
         
         if(null == colbuf) {
             return null;
         }
         
-        bind(gl);
+        removeColorAttachment(attachmentPoint, colbuf);
         
         if(colbuf instanceof TextureAttachment) {
             final TextureAttachment texA = (TextureAttachment) colbuf;
@@ -1374,12 +1540,23 @@ public class FBObject {
                               GL.GL_COLOR_ATTACHMENT0 + attachmentPoint,
                               GL.GL_TEXTURE_2D, 0, 0);
                 gl.glBindTexture(GL.GL_TEXTURE_2D, 0);
+                switch(detachAction) {
+                    case DISPOSE:
+                    case RECREATE:
+                        texA.free(gl);
+                        break;
+                    default:
+                }
             }
-            texA.free(gl);
-            removeColorAttachment(attachmentPoint, texA);                
-            if(recreate) {
-                texA.setSize(width, height);
-                attachTexture2D(gl, attachmentPoint, texA);
+            if(DetachAction.RECREATE == detachAction) {
+                if(samples == 0) {
+                    // stay non MSAA
+                    texA.setSize(width, height);                        
+                } else {
+                    // switch to MSAA
+                    colbuf = createColorAttachment(hasAlpha(texA.format));
+                }
+                attachColorbufferImpl(gl, attachmentPoint, colbuf);
             }
         } else if(colbuf instanceof ColorAttachment) {
             final ColorAttachment colA = (ColorAttachment) colbuf;
@@ -1387,37 +1564,94 @@ public class FBObject {
                 gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, 
                                              GL.GL_COLOR_ATTACHMENT0+attachmentPoint, 
                                              GL.GL_RENDERBUFFER, 0);
+                switch(detachAction) {
+                    case DISPOSE:
+                    case RECREATE:
+                        colA.free(gl);
+                        break;
+                    default:
+                }
             }
-            colA.free(gl);
-            removeColorAttachment(attachmentPoint, colbuf);
-            if(recreate) {
-                colA.setSize(width, height);
-                colA.setSamples(samples);
-                attachColorbuffer(gl, attachmentPoint, colA);
+            if(DetachAction.RECREATE == detachAction) {
+                if(samples > 0) {
+                    // stay MSAA
+                    colA.setSize(width, height);
+                    colA.setSamples(samples);
+                } else {
+                    // switch to non MSAA
+                    if(null != samplesSinkTexture) {
+                        colbuf = createColorTextureAttachment(samplesSinkTexture.format, width, height, 
+                                                              samplesSinkTexture.dataFormat, samplesSinkTexture.dataType, 
+                                                              samplesSinkTexture.magFilter, samplesSinkTexture.minFilter, 
+                                                              samplesSinkTexture.wrapS, samplesSinkTexture.wrapT);
+                    } else {
+                        colbuf = createColorTextureAttachment(gl.getGLProfile(), true, width, height);
+                    }
+                }
+                attachColorbuffer(gl, attachmentPoint, colbuf);
             }
         }
         return colbuf;
     }
     
+    private final void freeAllColorbufferImpl(GL gl) {
+        for(int i=0; i<maxColorAttachments; i++) {
+            final Colorbuffer colbuf = colorAttachmentPoints[i]; // shortcut, don't validate here
+            
+            if(null == colbuf) {
+                return;
+            }
+            
+            if(colbuf instanceof TextureAttachment) {
+                final TextureAttachment texA = (TextureAttachment) colbuf;
+                if( 0 != texA.getName() ) {
+                    gl.glFramebufferTexture2D(GL.GL_FRAMEBUFFER,
+                                  GL.GL_COLOR_ATTACHMENT0 + i,
+                                  GL.GL_TEXTURE_2D, 0, 0);
+                    gl.glBindTexture(GL.GL_TEXTURE_2D, 0);
+                }
+                texA.free(gl);
+            } else if(colbuf instanceof ColorAttachment) {
+                final ColorAttachment colA = (ColorAttachment) colbuf;
+                if( 0 != colA.getName() ) {
+                    gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, 
+                                                 GL.GL_COLOR_ATTACHMENT0 + i, 
+                                                 GL.GL_RENDERBUFFER, 0);
+                }
+                colA.free(gl);
+            }
+        }
+    }
+    
     /**
      * 
      * @param gl
+     * @param dispose true if the Colorbuffer shall be disposed
      * @param reqAType {@link Type#DEPTH}, {@link Type#DEPTH} or {@link Type#DEPTH_STENCIL} 
      */
-    public final void detachRenderbuffer(GL gl, Attachment.Type atype) throws IllegalArgumentException {
-        detachRenderbufferImpl(gl, atype, false);
+    public final void detachRenderbuffer(GL gl, Attachment.Type atype, boolean dispose) throws IllegalArgumentException {
+        bind(gl);        
+        detachRenderbufferImpl(gl, atype, dispose ? DetachAction.DISPOSE : DetachAction.NONE);
+        if(DEBUG) {
+            System.err.println("FBObject.detachRenderbuffer.X: [attachmentType "+atype+", dispose "+dispose+"]: "+this);
+        }        
     }
     
     public final boolean isDepthStencilPackedFormat() {
         final boolean res = null != depth && null != stencil &&
                             depth.format == stencil.format ;
-        if(res && depth.getName() != stencil.getName() ) {
-            throw new InternalError("depth/stencil packed format not sharing: depth "+depth+", stencil "+stencil);
+        if(res) {
+            if(depth.getName() != stencil.getName() ) {
+                throw new InternalError("depth/stencil packed format not sharing: depth "+depth+", stencil "+stencil);
+            }
+            if(depth != stencil) {
+                throw new InternalError("depth/stencil packed format not a shared reference: depth "+depth+", stencil "+stencil);
+            }
         }
         return res;
     }
         
-    private final void detachRenderbufferImpl(GL gl, Attachment.Type atype, boolean recreate) throws IllegalArgumentException {
+    private final void detachRenderbufferImpl(GL gl, Attachment.Type atype, DetachAction detachAction) throws IllegalArgumentException {
         switch ( atype ) {
             case DEPTH:
             case STENCIL:
@@ -1429,80 +1663,124 @@ public class FBObject {
         if( null == depth && null == stencil ) {
             return ; // nop
         } 
-        // reduction of possible combinations, create unique atype command(s)
-        final ArrayList<Attachment.Type> actions = new ArrayList<Attachment.Type>(2);  
-        if( isDepthStencilPackedFormat() ) {
-            // packed
-            actions.add(Attachment.Type.DEPTH_STENCIL);
-        } else {
-            // individual
-            switch ( atype ) {
-                case DEPTH:
-                    if( null != depth ) { actions.add(Attachment.Type.DEPTH); }
-                    break;
-                case STENCIL:
-                    if( null != stencil ) { actions.add(Attachment.Type.STENCIL); }
-                    break;
-                case DEPTH_STENCIL:
-                    if( null != depth ) { actions.add(Attachment.Type.DEPTH); }
-                    if( null != stencil ) { actions.add(Attachment.Type.STENCIL); }
-                    break;
-                 default: // handled
-            }
+        final boolean packed = isDepthStencilPackedFormat();
+        if( packed ) {
+            // Note: DEPTH_STENCIL shares buffer w/ depth and stencil
+            atype = Attachment.Type.DEPTH_STENCIL;
         }
-        
-        bind(gl);        
-        
-        for(int i = 0; i < actions.size(); i++) {
-            final int format;
-            
-            Attachment.Type action = actions.get(i);
-            switch ( action ) {
-                case DEPTH:
-                    format = depth.format;
+        switch ( atype ) {
+            case DEPTH:
+                if( null != depth ) {
+                    final int format = depth.format;
                     if( 0 != depth.getName() ) {
                         gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_DEPTH_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
+                        switch(detachAction) {
+                            case DISPOSE:
+                            case RECREATE:
+                                depth.free(gl);
+                                break;
+                            default:
+                        }
                     }
-                    depth.free(gl);
-                    if(!recreate) {
+                    if(DetachAction.RECREATE == detachAction) {
+                        attachRenderbufferImpl2(gl, atype, format);
+                    } else {
                         depth = null;
                     }
-                    break;
-                case STENCIL:
-                    format = stencil.format;
+                }
+                break;
+            case STENCIL:
+                if( null != stencil ) {
+                    final int format = stencil.format;
                     if(0 != stencil.getName()) {
                         gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
+                        switch(detachAction) {
+                            case DISPOSE:
+                            case RECREATE:
+                                stencil.free(gl);
+                                break;
+                            default:
+                        }
                     }
-                    stencil.free(gl);
-                    if(!recreate) {
+                    if(DetachAction.RECREATE == detachAction) {
+                        attachRenderbufferImpl2(gl, atype, format);
+                    } else {
                         stencil = null;
                     }
-                    break;
-                case DEPTH_STENCIL:
-                    format = depth.format;
+                }
+                break;
+            case DEPTH_STENCIL:
+                if( null != depth ) {
+                    final int format = depth.format;
                     if(0 != depth.getName()) {
                         gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_DEPTH_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
-                        gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
+                        if(packed) {
+                            gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
+                        }
+                        switch(detachAction) {
+                            case DISPOSE:
+                            case RECREATE:
+                                depth.free(gl);
+                                break;
+                            default:
+                        }
                     }
-                    depth.free(gl);
-                    stencil.free(gl);
-                    if(!recreate) {
+                    if(DetachAction.RECREATE == detachAction) {
+                        attachRenderbufferImpl2(gl, packed ? Attachment.Type.DEPTH_STENCIL : Attachment.Type.DEPTH, format);
+                    } else {
                         depth = null;
+                        if(packed) {
+                            stencil = null;
+                        }
+                    }                    
+                }
+                if( !packed && null != stencil ) {
+                    final int format = stencil.format;
+                    if(0 != stencil.getName()) {
+                        gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
+                        switch(detachAction) {
+                            case DISPOSE:
+                            case RECREATE:
+                                stencil.free(gl);
+                                break;
+                            default:
+                        }
+                    }
+                    if(DetachAction.RECREATE == detachAction) {
+                        attachRenderbufferImpl2(gl, Attachment.Type.STENCIL, format);
+                    } else {
                         stencil = null;
                     }
-                    break;
-                 default:
-                    throw new InternalError("XXX");
-            }
-            if(recreate) {
-                attachRenderbufferImpl2(gl, action, format);
-            }
+                }
+                break;
+             default: // handled
         }        
     }
         
+    private final void freeAllRenderbufferImpl(GL gl) throws IllegalArgumentException {
+        // Note: DEPTH_STENCIL shares buffer w/ depth and stencil
+        final boolean packed = isDepthStencilPackedFormat();
+        if( null != depth ) { 
+            if(0 != depth.getName()) {
+                gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_DEPTH_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
+                if(packed) {
+                    gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, 0);                    
+                }
+                depth.free(gl);
+            }
+        }
+        if( !packed && null != stencil ) {
+            if(0 != stencil.getName()) {
+                gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
+                stencil.free(gl);                    
+            }
+        }
+    }
+    
     /** 
-     * Detaches all {@link ColorAttachment}s, {@link TextureAttachment}s and {@link RenderAttachment}s.
-     * <p>Leaves the FBO bound!</p>
+     * Detaches all {@link ColorAttachment}s, {@link TextureAttachment}s and {@link RenderAttachment}s
+     * and disposes them.
+     * <p>Leaves the FBO bound, if initialized!</p>
      * <p>
      * An attached sampling sink texture will be detached as well, see {@link #getSamplingSink()}.
      * </p> 
@@ -1516,8 +1794,9 @@ public class FBObject {
     }
     
     /** 
-     * Detaches all {@link ColorAttachment}s and {@link TextureAttachment}s.
-     * <p>Leaves the FBO bound!</p>
+     * Detaches all {@link ColorAttachment}s and {@link TextureAttachment}s 
+     * and disposes them.
+     * <p>Leaves the FBO bound, if initialized!</p>
      * <p>
      * An attached sampling sink texture will be detached as well, see {@link #getSamplingSink()}.
      * </p> 
@@ -1531,45 +1810,80 @@ public class FBObject {
     }
     
     /** 
-     * Detaches all {@link TextureAttachment}s 
-     * <p>Leaves the FBO bound!</p>
+     * Detaches all {@link TextureAttachment}s and disposes them.
+     * <p>Leaves the FBO bound, if initialized!</p>
      * <p>
      * An attached sampling sink texture will be detached as well, see {@link #getSamplingSink()}.
      * </p> 
      * @param gl the current GL context
      */
     public final void detachAllTexturebuffer(GL gl) {
+        if( !isInitialized() ) {
+            return;
+        }
         if(null != samplesSink) {
             samplesSink.detachAllTexturebuffer(gl);
         }
+        bind(gl);        
         for(int i=0; i<maxColorAttachments; i++) {
             if(colorAttachmentPoints[i] instanceof TextureAttachment) {
-                detachColorbufferImpl(gl, i, false);
+                detachColorbufferImpl(gl, i, DetachAction.DISPOSE);
             }
         }
+        if(DEBUG) {
+            System.err.println("FBObject.detachAllTexturebuffer.X: "+this);
+        }
     }
     
     public final void detachAllRenderbuffer(GL gl) {
+        if( !isInitialized() ) {
+            return;
+        }
         if(null != samplesSink) {
             samplesSink.detachAllRenderbuffer(gl);
         }
-        detachRenderbufferImpl(gl, Attachment.Type.DEPTH_STENCIL, false);
+        bind(gl);        
+        detachRenderbufferImpl(gl, Attachment.Type.DEPTH_STENCIL, DetachAction.DISPOSE);
     }
     
     private final void detachAllImpl(GL gl, boolean detachNonColorbuffer, boolean recreate) {
-        for(int i=0; i<maxColorAttachments; i++) {
-            detachColorbufferImpl(gl, i, recreate);
-        }
-        if( !recreate && colorAttachmentCount>0 ) {
-            throw new InternalError("Non zero ColorAttachments "+this);
+        if( !isInitialized() ) {
+            return;
         }
-        
-        if(detachNonColorbuffer) {
-            detachRenderbufferImpl(gl, Attachment.Type.DEPTH_STENCIL, recreate);
+        ignoreStatus = recreate; // ignore status on single calls only if recreate -> reset
+        try {
+            bind(gl);
+            if(FBOResizeQuirk) {
+                if(detachNonColorbuffer && recreate) {
+                    // free all colorbuffer & renderbuffer 1st
+                    freeAllColorbufferImpl(gl);
+                    freeAllRenderbufferImpl(gl);
+                }
+            }
+            for(int i=0; i<maxColorAttachments; i++) {
+                detachColorbufferImpl(gl, i, recreate ? DetachAction.RECREATE : DetachAction.DISPOSE);
+            }
+            if( !recreate && colorAttachmentCount>0 ) {
+                throw new InternalError("Non zero ColorAttachments "+this);
+            }
+            
+            if(detachNonColorbuffer) {
+                detachRenderbufferImpl(gl, Attachment.Type.DEPTH_STENCIL, recreate ? DetachAction.RECREATE : DetachAction.DISPOSE);
+            }
+            if(ignoreStatus) { // post validate
+                /* if(true) {
+                    throw new GLException("Simulating bug 617, reset FBO failure");
+                } */
+                updateStatus(gl);
+                if(!isStatusValid()) {
+                    throw new GLException("detachAllImpl failed "+getStatusString()+", "+this);
+                }
+            }
+        } finally {
+            ignoreStatus = false;
         }
-        
         if(DEBUG) {
-            System.err.println("FBObject.detachAll: [resetNonColorbuffer "+detachNonColorbuffer+", recreate "+recreate+"]: "+this);
+            System.err.println("FBObject.detachAll.X: [resetNonColorbuffer "+detachNonColorbuffer+", recreate "+recreate+"]: "+this);
         }
     }
         
@@ -1577,7 +1891,14 @@ public class FBObject {
      * @param gl the current GL context
      */
     public final void destroy(GL gl) {
-        if(null != samplesSink) {
+        if(!initialized) {
+            return;
+        }
+        if(DEBUG) {
+            System.err.println("FBObject.destroy.0: "+this);
+            // Thread.dumpStack();
+        }
+        if( null != samplesSink && samplesSink.isInitialized() ) {
             samplesSink.destroy(gl);
         }
         
@@ -1596,7 +1917,7 @@ public class FBObject {
         initialized = false;
         bound = false;
         if(DEBUG) {
-            System.err.println("FBObject.destroy: "+this);
+            System.err.println("FBObject.destroy.X: "+this);
         }
     }
 
@@ -1618,21 +1939,42 @@ public class FBObject {
         return depthMismatch || stencilMismatch;                
     }
         
-    private final void resetMSAATexture2DSink(GL gl) throws GLException {
+    /**
+     * Manually reset the MSAA sampling sink, if used.
+     * <p>
+     * Automatically called by {@link #reset(GL, int, int, int, boolean)} 
+     * and {@link #syncSamplingSink(GL)}.
+     * </p>
+     * <p>
+     * It is recommended to call this method after initializing the FBO and attaching renderbuffer etc for the 1st time
+     * if access to sampling sink resources is required.
+     * </p>
+     * @param gl the current GL context
+     * @throws GLException in case of an error, i.e. size too big, etc ..
+     */
+    public final void resetSamplingSink(GL gl) throws GLException {
+        if(null == samplesSink ) {
+            return; // this is the sample sink!
+        }
         if(0 == samples) {
             // MSAA off
-            if(null != samplesSink) {
+            if(samplesSink.initialized) {
+                // cleanup
                 samplesSink.detachAll(gl);
             }
             return;
         }
         
+        if(!samplesSink.initialized) {
+            samplesSink.init(gl, width, height, 0);
+        }
+        
         boolean sampleSinkSizeMismatch = sampleSinkSizeMismatch();
         boolean sampleSinkTexMismatch = sampleSinkTexMismatch();
         boolean sampleSinkDepthStencilMismatch = sampleSinkDepthStencilMismatch();
         
         /** if(DEBUG) {
-            System.err.println("FBObject.resetMSAATexture2DSink.0: \n\tTHIS "+this+",\n\tSINK "+samplesSink+
+            System.err.println("FBObject.resetSamplingSink.0: \n\tTHIS "+this+",\n\tSINK "+samplesSink+
                                "\n\t size "+sampleSinkSizeMismatch +", tex "+sampleSinkTexMismatch +", depthStencil "+sampleSinkDepthStencilMismatch);
         } */
         
@@ -1644,7 +1986,7 @@ public class FBObject {
         unbind(gl);
         
         if(DEBUG) {
-            System.err.println("FBObject.resetMSAATexture2DSink: BEGIN\n\tTHIS "+this+",\n\tSINK "+samplesSink+
+            System.err.println("FBObject.resetSamplingSink: BEGIN\n\tTHIS "+this+",\n\tSINK "+samplesSink+
                                "\n\t size "+sampleSinkSizeMismatch +", tex "+sampleSinkTexMismatch +", depthStencil "+sampleSinkDepthStencilMismatch);
         }
                 
@@ -1660,7 +2002,7 @@ public class FBObject {
             samplesSinkTexture = samplesSink.attachTexture2D(gl, 0, true);
         } else if( 0 == samplesSinkTexture.getName() ) {
             samplesSinkTexture.setSize(width, height);
-            samplesSink.attachTexture2D(gl, 0, samplesSinkTexture);
+            samplesSink.attachColorbuffer(gl, 0, samplesSinkTexture);
         }
         
         if( sampleSinkDepthStencilMismatch ) {
@@ -1679,7 +2021,7 @@ public class FBObject {
         }
         
         if(DEBUG) {
-            System.err.println("FBObject.resetMSAATexture2DSink: END\n\tTHIS "+this+",\n\tSINK "+samplesSink+
+            System.err.println("FBObject.resetSamplingSink: END\n\tTHIS "+this+",\n\tSINK "+samplesSink+
                                "\n\t size "+sampleSinkSizeMismatch +", tex "+sampleSinkTexMismatch +", depthStencil "+sampleSinkDepthStencilMismatch);
         }
     }
@@ -1709,7 +2051,6 @@ public class FBObject {
                 gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, getWriteFramebuffer());                
             }
 
-            checkNoError(null, gl.glGetError(), "FBObject post-bind"); // throws GLException if error
             bound = true;
             samplesSinkDirty = true;
         }
@@ -1734,10 +2075,20 @@ public class FBObject {
             } else {
                 gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0); // default draw buffer                
             }
-            checkNoError(null, gl.glGetError(), "FBObject post-unbind"); // throws GLException if error
             bound = false;
         }
     }
+    
+    /**
+     * Method simply marks this FBO unbound w/o interfering w/ the bound framebuffer as perfomed by {@link #unbind(GL)}.
+     * <p>
+     * Only use this method if a subsequent {@link #unbind(GL)}, {@link #use(GL, TextureAttachment)} or {@link #bind(GL)}
+     * follows on <i>any</i> FBO.
+     * </p>
+     */
+    public final void markUnbound() {
+        bound = false;
+    }
 
     /** 
      * Returns <code>true</code> if framebuffer object is bound via {@link #bind(GL)}, otherwise <code>false</code>.
@@ -1755,49 +2106,57 @@ public class FBObject {
     public final boolean isBound() { return bound; }
     
     /** 
-     * Samples the multisampling colorbuffer (msaa-buffer) to it's sink {@link #getSamplingSink()}.
-     *
-     * <p>The operation is skipped, if no multisampling is used or 
-     * the msaa-buffer has not been flagged dirty by a previous call of {@link #bind(GL)},
-     * see {@link #isSamplingBufferDirty()} </p>
-     * 
-     * <p>If full FBO is supported, sets the read and write framebuffer individually to default after sampling, hence not disturbing 
-     * an optional operating MSAA FBO, see {@link GLBase#getDefaultReadFramebuffer()} and {@link GLBase#getDefaultDrawFramebuffer()}</p>
-     * 
-     * <p>In case you intend to employ {@link GL#glReadPixels(int, int, int, int, int, int, java.nio.Buffer) glReadPixels(..)}
+     * If multisampling is being used and flagged dirty by a previous call of {@link #bind(GL)} or after initialization,
+     * the msaa-buffers are sampled to it's sink {@link #getSamplingSink()}.
+     * <p>
+     * Method also resets the sampling sink configuration via {@link #resetSamplingSink(GL)} if used and required.
+     * </p>
+     * <p>
+     * Method is called automatically by {@link #use(GL, TextureAttachment)}.
+     * </p>
+     * <p>
+     * Method always resets the framebuffer binding to default in the end.
+     * If full FBO is supported, sets the read and write framebuffer individually to default after sampling, hence not disturbing 
+     * an optional operating MSAA FBO, see {@link GLBase#getDefaultReadFramebuffer()} and {@link GLBase#getDefaultDrawFramebuffer()}
+     * </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()});
      * </p>
-     * 
      * <p>Leaves the FBO unbound.</p>
      * 
      * @param gl the current GL context
      * @param ta {@link TextureAttachment} to use, prev. attached w/  {@link #attachTexture2D(GL, int, boolean, int, int, int, int) attachTexture2D(..)}
      * @throws IllegalArgumentException  
      */
-    public final void syncSamplingBuffer(GL gl) {
-        unbind(gl);
+    public final void syncSamplingSink(GL gl) {
+        markUnbound();
         if(samples>0 && samplesSinkDirty) {
             samplesSinkDirty = false;
-            resetMSAATexture2DSink(gl);
+            resetSamplingSink(gl);
+            checkPreGLError(gl);
             gl.glBindFramebuffer(GL2GL3.GL_READ_FRAMEBUFFER, fbName);
             gl.glBindFramebuffer(GL2GL3.GL_DRAW_FRAMEBUFFER, samplesSink.getWriteFramebuffer());
-            ((GL2GL3)gl).glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, // since MSAA is supported, ugly cast is OK
+            ((GL2GL3)gl).glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, // since MSAA is supported, casting to GL2GL3 is OK
                                            GL.GL_COLOR_BUFFER_BIT, GL.GL_NEAREST);
-            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);
-            } else {
-                gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0); // default draw buffer                
-            }
+            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);
+        } else {
+            gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0); // default draw buffer                
         }
     }
     
     /** 
      * Bind the given texture colorbuffer.
      * 
-     * <p>If multisampling is being used, {@link #syncSamplingBuffer(GL)} is being called.</p>
+     * <p>If using multiple texture units, ensure you call {@link GL#glActiveTexture(int)} first!</p>
+     * 
+     * <p>{@link #syncSamplingSink(GL)} is being called</p>
      *  
      * <p>Leaves the FBO unbound!</p>
      * 
@@ -1806,12 +2165,8 @@ public class FBObject {
      * @throws IllegalArgumentException  
      */
     public final void use(GL gl, TextureAttachment ta) throws IllegalArgumentException {
-        if(null == ta) { throw new IllegalArgumentException("null TextureAttachment"); }
-        if(samples > 0 && samplesSinkTexture == ta) {
-            syncSamplingBuffer(gl);
-        } else {
-            unbind(gl);            
-        }
+        if(null == ta) { throw new IllegalArgumentException("Null TextureAttachment, this: "+toString()); }
+        syncSamplingSink(gl);
         gl.glBindTexture(GL.GL_TEXTURE_2D, ta.getName()); // use it ..
     }
 
@@ -1825,14 +2180,8 @@ public class FBObject {
         gl.glBindTexture(GL.GL_TEXTURE_2D, 0); // don't use it
     }
 
-    /** 
-     * Returns <code>true</code> if <i>basic</i> or <i>full</i> FBO is supported, otherwise <code>false</code>.
-     * @param full <code>true</code> for <i>full</i> FBO supported query, otherwise <code>false</code> for <i>basic</i> FBO support query.
-     * @see #supportsFullFBO(GL)
-     * @see #supportsBasicFBO(GL)
-     * @throws GLException if {@link #init(GL)} hasn't been called.
-     */
-    public final boolean supportsFBO(boolean full) throws GLException { checkInitialized(); return full ? fullFBOSupport : basicFBOSupport; }
+    /** @see GL#hasFullFBOSupport() */    
+    public final boolean hasFullFBOSupport() throws GLException { checkInitialized(); return this.fullFBOSupport; }
     
     /** 
      * Returns <code>true</code> if renderbuffer accepts internal format {@link GL#GL_RGB8} and {@link GL#GL_RGBA8}, otherwise <code>false</code>.
@@ -1848,7 +2197,7 @@ public class FBObject {
     public final boolean supportsDepth(int bits) throws GLException {
         checkInitialized();
         switch(bits) {
-            case 16: return basicFBOSupport; 
+            case 16: return true; 
             case 24: return depth24Avail;
             case 32: return depth32Avail;
             default: return false;            
@@ -1883,15 +2232,15 @@ public class FBObject {
      */
     public final int getMaxColorAttachments() throws GLException { checkInitialized(); return maxColorAttachments; }
     
-    /**
-     * Returns the maximum number of samples for multisampling. Maybe zero if multisampling is not supported. 
-     * @throws GLException if {@link #init(GL)} hasn't been called.
-     */
-    public final int getMaxSamples() throws GLException { checkInitialized(); return maxSamples; }
+    public final int getMaxTextureSize() throws GLException { checkInitialized(); return this.maxTextureSize; }
+    public final int getMaxRenderbufferSize() throws GLException { checkInitialized(); return this.maxRenderbufferSize; }
+    
+    /** @see GL#getMaxRenderbufferSamples() */
+    public final int getMaxSamples() throws GLException { checkInitialized(); return this.maxSamples; }
     
     /**
      * Returns <code>true</code> if this instance has been initialized with {@link #reset(GL, int, int)} 
-     * or {@link #reset(GL, int, int, int)}, otherwise <code>false</code>
+     * or {@link #reset(GL, int, int, int, boolean)}, otherwise <code>false</code>
      */
     public final boolean isInitialized() { return initialized; }
     /** Returns the width */
@@ -1927,10 +2276,11 @@ public class FBObject {
     
     public final String toString() {
         final String caps = null != colorAttachmentPoints ? Arrays.asList(colorAttachmentPoints).toString() : null ; 
-        return "FBO[name r/w "+fbName+"/"+getReadFramebuffer()+", init "+initialized+", bound "+bound+", size "+width+"x"+height+", samples "+samples+"/"+maxSamples+
-               ", depth "+depth+", stencil "+stencil+", color attachments: "+colorAttachmentCount+"/"+maxColorAttachments+
+        return "FBO[name r/w "+fbName+"/"+getReadFramebuffer()+", init "+initialized+", bound "+bound+", size "+width+"x"+height+
+               ", samples "+samples+"/"+maxSamples+", depth "+depth+", stencil "+stencil+
+               ", color attachments: "+colorAttachmentCount+"/"+maxColorAttachments+
                ": "+caps+", msaa-sink "+samplesSinkTexture+", isSamplesSink "+(null == samplesSink)+
-               ", obj 0x"+Integer.toHexString(objectHashCode())+"]";
+               ", state "+getStatusString()+", obj "+toHexString(objectHashCode())+"]";
     }
     
     private final void updateStatus(GL gl) {
diff --git a/src/jogl/classes/com/jogamp/opengl/FloatUtil.java b/src/jogl/classes/com/jogamp/opengl/FloatUtil.java
index 93543ea..ffd2344 100644
--- a/src/jogl/classes/com/jogamp/opengl/FloatUtil.java
+++ b/src/jogl/classes/com/jogamp/opengl/FloatUtil.java
@@ -29,6 +29,8 @@ package com.jogamp.opengl;
 
 import java.nio.FloatBuffer;
 
+import com.jogamp.common.os.Platform;
+
 /**
  * Basic Float math utility functions.
  * <p>
@@ -71,7 +73,7 @@ public class FloatUtil {
    * Make matrix an identity matrix
    */
   public static final void makeIdentityf(FloatBuffer m) {
-    int oldPos = m.position();
+    final int oldPos = m.position();
     m.put(IDENTITY_MATRIX);
     m.position(oldPos);
   }
@@ -89,7 +91,7 @@ public class FloatUtil {
    * Make matrix an zero matrix
    */
   public static final void makeZero(FloatBuffer m) {
-    int oldPos = m.position();
+    final int oldPos = m.position();
     m.put(ZERO_MATRIX);
     m.position(oldPos);
   }
@@ -244,10 +246,10 @@ public class FloatUtil {
    * @param v_in 4-component column-vector
    * @param v_out m_in * v_in
    */
-  public static final void multMatrixVecf(float[] m_in, int m_in_off, float[] v_in, int v_in_off, float[] v_out) {
+  public static final void multMatrixVecf(float[] m_in, int m_in_off, float[] v_in, int v_in_off, float[] v_out, int v_out_off) {
     for (int i = 0; i < 4; i++) {
       // (one matrix row in column-major order) X (column vector)
-      v_out[i] =
+      v_out[i + v_out_off] =
         v_in[0+v_in_off] * m_in[0*4+i+m_in_off] +
         v_in[1+v_in_off] * m_in[1*4+i+m_in_off] +
         v_in[2+v_in_off] * m_in[2*4+i+m_in_off] +
@@ -277,10 +279,44 @@ public class FloatUtil {
    * @param v_in 4-component column-vector
    * @param v_out m_in * v_in
    */
+  public static final void multMatrixVecf(FloatBuffer m_in, float[] v_in, int v_in_off, float[] v_out, int v_out_off) {
+    final int matrixPos = m_in.position();
+    for (int i = 0; i < 4; i++) {
+      // (one matrix row in column-major order) X (column vector)
+      v_out[i+v_out_off] =
+        v_in[0+v_in_off] * m_in.get(0*4+i+matrixPos) +
+        v_in[1+v_in_off] * m_in.get(1*4+i+matrixPos) +
+        v_in[2+v_in_off] * m_in.get(2*4+i+matrixPos) +
+        v_in[3+v_in_off] * m_in.get(3*4+i+matrixPos);      
+    }
+  }
+  
+  /**
+   * @param m_in 4x4 matrix in column-major order
+   * @param v_in 4-component column-vector
+   * @param v_out m_in * v_in
+   */
+  public static final void multMatrixVecf(FloatBuffer m_in, float[] v_in, float[] v_out) {
+    final int matrixPos = m_in.position();
+    for (int i = 0; i < 4; i++) {
+      // (one matrix row in column-major order) X (column vector)
+      v_out[i] =
+        v_in[0] * m_in.get(0*4+i+matrixPos) +
+        v_in[1] * m_in.get(1*4+i+matrixPos) +
+        v_in[2] * m_in.get(2*4+i+matrixPos) +
+        v_in[3] * m_in.get(3*4+i+matrixPos);      
+    }
+  }
+  
+  /**
+   * @param m_in 4x4 matrix in column-major order
+   * @param v_in 4-component column-vector
+   * @param v_out m_in * v_in
+   */
   public static final void multMatrixVecf(FloatBuffer m_in, FloatBuffer v_in, FloatBuffer v_out) {
-    int inPos = v_in.position();
-    int outPos = v_out.position();
-    int matrixPos = m_in.position();
+    final int inPos = v_in.position();
+    final int outPos = v_out.position();
+    final int matrixPos = m_in.position();
     for (int i = 0; i < 4; i++) {
       // (one matrix row in column-major order) X (column vector)
       v_out.put(i + outPos,
@@ -291,4 +327,84 @@ public class FloatUtil {
     }
   }
 
+  /** 
+   * @param sb optional passed StringBuilder instance to be used
+   * @param f the format string of one floating point, i.e. "%10.5f", see {@link java.util.Formatter}
+   * @param a mxn matrix (rows x columns)
+   * @param aOffset offset to <code>a</code>'s current position
+   * @param rows
+   * @param columns
+   * @param rowMajorOrder if true floats are layed out in row-major-order, otherwise column-major-order (OpenGL)
+   * @param row row number to print 
+   * @return matrix row string representation
+   */
+  public static StringBuilder matrixRowToString(StringBuilder sb, String f, FloatBuffer a, int aOffset, int rows, int columns, boolean rowMajorOrder, int row) {
+      if(null == sb) {
+          sb = new StringBuilder();
+      }
+      final int a0 = aOffset + a.position();
+      if(rowMajorOrder) {
+          for(int c=0; c<columns; c++) {
+              sb.append( String.format( f+" ", a.get( a0 + row*columns + c ) ) ); 
+          }
+      } else {
+          for(int r=0; r<columns; r++) {
+              sb.append( String.format( f+" ", a.get( a0 + row + r*rows ) ) ); 
+          }
+      }
+      return sb;
+  }
+
+  /** 
+   * @param sb optional passed StringBuilder instance to be used
+   * @param rowPrefix optional prefix for each row 
+   * @param f the format string of one floating point, i.e. "%10.5f", see {@link java.util.Formatter}
+   * @param a mxn matrix (rows x columns)
+   * @param aOffset offset to <code>a</code>'s current position
+   * @param rows
+   * @param columns
+   * @param rowMajorOrder if true floats are layed out in row-major-order, otherwise column-major-order (OpenGL)
+   * @return matrix string representation
+   */
+  public static StringBuilder matrixToString(StringBuilder sb, String rowPrefix, String f, FloatBuffer a, int aOffset, int rows, int columns, boolean rowMajorOrder) {
+      if(null == sb) {
+          sb = new StringBuilder();
+      }
+      final String prefix = ( null == rowPrefix ) ? "" : rowPrefix;
+      for(int i=0; i<rows; i++) {
+          sb.append(prefix).append("[ ");
+          matrixRowToString(sb, f, a, aOffset, rows, columns, rowMajorOrder, i);
+          sb.append("]").append(Platform.getNewline());      
+      }
+      return sb;
+  }
+
+  /** 
+   * @param sb optional passed StringBuilder instance to be used
+   * @param rowPrefix optional prefix for each row 
+   * @param f the format string of one floating point, i.e. "%10.5f", see {@link java.util.Formatter}
+   * @param a 4x4 matrix in column major order (OpenGL)
+   * @param aOffset offset to <code>a</code>'s current position
+   * @param b 4x4 matrix in column major order (OpenGL)
+   * @param bOffset offset to <code>a</code>'s current position
+   * @param rows
+   * @param columns
+   * @param rowMajorOrder if true floats are layed out in row-major-order, otherwise column-major-order (OpenGL)
+   * @return side by side representation
+   */
+  public static StringBuilder matrixToString(StringBuilder sb, String rowPrefix, String f, FloatBuffer a, int aOffset, FloatBuffer b, int bOffset, int rows, int columns, boolean rowMajorOrder) {
+      if(null == sb) {
+          sb = new StringBuilder();
+      }
+      final String prefix = ( null == rowPrefix ) ? "" : rowPrefix;
+      for(int i=0; i<rows; i++) {
+          sb.append(prefix).append("[ ");
+          matrixRowToString(sb, f, a, aOffset, rows, columns, rowMajorOrder, i);
+          sb.append("=?= ");
+          matrixRowToString(sb, f, b, bOffset, rows, columns, rowMajorOrder, i);
+          sb.append("]").append(Platform.getNewline());      
+      }
+      return sb;
+  }
+  
 }
\ No newline at end of file
diff --git a/src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java b/src/jogl/classes/com/jogamp/opengl/GLAutoDrawableDelegate.java
similarity index 63%
rename from src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java
rename to src/jogl/classes/com/jogamp/opengl/GLAutoDrawableDelegate.java
index 67e8127..38a8dee 100644
--- a/src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java
+++ b/src/jogl/classes/com/jogamp/opengl/GLAutoDrawableDelegate.java
@@ -26,14 +26,21 @@
  * or implied, of JogAmp Community.
  */
  
-package javax.media.opengl;
+package com.jogamp.opengl;
 
 import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.WindowClosingProtocol;
+import javax.media.nativewindow.WindowClosingProtocol.WindowClosingMode;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLException;
 
 import com.jogamp.common.util.locks.LockFactory;
 import com.jogamp.common.util.locks.RecursiveLock;
 
-import jogamp.opengl.Debug;
 import jogamp.opengl.GLAutoDrawableBase;
 import jogamp.opengl.GLContextImpl;
 import jogamp.opengl.GLDrawableImpl;
@@ -46,44 +53,64 @@ import jogamp.opengl.GLDrawableImpl;
  * Since no native windowing system events are being processed, it is recommended
  * to handle at least:
  * <ul>
- *   <li>{@link com.jogamp.newt.event.WindowListener#windowRepaint(com.jogamp.newt.event.WindowUpdateEvent) repaint} using {@link #defaultWindowRepaintOp()}</li>
- *   <li>{@link com.jogamp.newt.event.WindowListener#windowResized(com.jogamp.newt.event.WindowEvent) resize} using {@link #defaultWindowResizedOp()}</li>
- *   <li>{@link com.jogamp.newt.event.WindowListener#windowDestroyNotify(com.jogamp.newt.event.WindowEvent) destroy-notify}  using {@link #defaultWindowDestroyNotifyOp()}</li> 
+ *   <li>{@link com.jogamp.newt.event.WindowListener#windowRepaint(com.jogamp.newt.event.WindowUpdateEvent) repaint} using {@link #windowRepaintOp()}</li>
+ *   <li>{@link com.jogamp.newt.event.WindowListener#windowResized(com.jogamp.newt.event.WindowEvent) resize} using {@link #windowResizedOp()}</li>
+ *   <li>{@link com.jogamp.newt.event.WindowListener#windowDestroyNotify(com.jogamp.newt.event.WindowEvent) destroy-notify}  using {@link #windowDestroyNotifyOp()}</li> 
  * </ul> 
  * </p>
  * <p> 
  * See example {@link com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableDelegateNEWT TestGLAutoDrawableDelegateNEWT}.
  * </p>
  */
-public class GLAutoDrawableDelegate extends GLAutoDrawableBase {
-    public static final boolean DEBUG = Debug.debug("GLAutoDrawableDelegate");
-    
+public class GLAutoDrawableDelegate extends GLAutoDrawableBase implements GLAutoDrawable {
     /**
-     * @param drawable a valid {@link GLDrawable}, may not be realized yet.
+     * @param drawable a valid and already realized {@link GLDrawable}
      * @param context a valid {@link GLContext}, may not be made current (created) yet.
      * @param upstreamWidget optional UI element holding this instance, see {@link #getUpstreamWidget()}.
      * @param ownDevice pass <code>true</code> if {@link AbstractGraphicsDevice#close()} shall be issued,
      *                  otherwise pass <code>false</code>. Closing the device is required in case
      *                  the drawable is created w/ it's own new instance, e.g. offscreen drawables,
      *                  and no further lifecycle handling is applied.
+     * @param lock optional custom {@link RecursiveLock}.
      */
-    public GLAutoDrawableDelegate(GLDrawable drawable, GLContext context, Object upstreamWidget, boolean ownDevice) {
+    public GLAutoDrawableDelegate(GLDrawable drawable, GLContext context, Object upstreamWidget, boolean ownDevice, RecursiveLock lock) {
         super((GLDrawableImpl)drawable, (GLContextImpl)context, ownDevice);
-        this.upstreamWidget = null;
+        if(null == drawable) {
+            throw new IllegalArgumentException("null drawable");
+        }
+        if(null == context) {
+            throw new IllegalArgumentException("null context");
+        }        
+        if(!drawable.isRealized()) {
+            throw new IllegalArgumentException("drawable not realized");
+        }
+        this.upstreamWidget = upstreamWidget;
+        this.lock = ( null != lock ) ? lock : LockFactory.createRecursiveLock() ;
     }
     
     //
     // expose default methods
     //
-    
+
+    /** Default implementation to handle repaint events from the windowing system */
     public final void windowRepaintOp() {
         super.defaultWindowRepaintOp();
     }
     
-    public final void windowResizedOp() {
-        super.defaultWindowResizedOp();
+    /** Implementation to handle resize events from the windowing system. All required locks are being claimed. */
+    public final void windowResizedOp(int newWidth, int newHeight) {
+        super.defaultWindowResizedOp(newWidth, newHeight);
     }
     
+    /** 
+     * Implementation to handle destroy notifications from the windowing system.
+     * 
+     * <p>
+     * If the {@link NativeSurface} does not implement {@link WindowClosingProtocol} 
+     * or {@link WindowClosingMode#DISPOSE_ON_CLOSE} is enabled (default),
+     * a thread safe destruction is being induced.
+     * </p> 
+     */
     public final void windowDestroyNotifyOp() {
         super.defaultWindowDestroyNotifyOp();
     }
@@ -92,8 +119,8 @@ public class GLAutoDrawableDelegate extends GLAutoDrawableBase {
     // Complete GLAutoDrawable
     //
     
-    private final RecursiveLock lock = LockFactory.createRecursiveLock();  // instance wide lock
-    private final Object upstreamWidget;
+    private Object upstreamWidget;
+    private final RecursiveLock lock;
     
     @Override
     protected final RecursiveLock getLock() { return lock; }
@@ -104,6 +131,14 @@ public class GLAutoDrawableDelegate extends GLAutoDrawableBase {
     }
     
     /**
+     * Set the upstream UI toolkit object.
+     * @see #getUpstreamWidget()
+     */
+    public final void setUpstreamWidget(Object newUpstreamWidget) {
+        upstreamWidget = newUpstreamWidget;
+    }
+    
+    /**
      * {@inheritDoc}
      * <p>
      * This implementation calls {@link #defaultDestroy()}.
@@ -119,7 +154,12 @@ public class GLAutoDrawableDelegate extends GLAutoDrawableBase {
     }
 
     @Override
-    public void display() {
+    protected void destroyImplInLock() {
+        super.destroyImplInLock();
+    }
+    
+    @Override
+    public void display() {        
         defaultDisplay();
     }
     
@@ -140,5 +180,10 @@ public class GLAutoDrawableDelegate extends GLAutoDrawableBase {
     public final void swapBuffers() throws GLException {
          defaultSwapBuffers();
     }
-        
+     
+    @Override
+    public String toString() {
+        return getClass().getSimpleName()+"[ \n\tHelper: " + helper + ", \n\tDrawable: " + drawable +
+               ", \n\tContext: " + context + ", \n\tUpstreamWidget: "+upstreamWidget+ /** ", \n\tFactory: "+factory+ */ "]";
+    }    
 }
diff --git a/src/jogl/classes/com/jogamp/opengl/GLExtensions.java b/src/jogl/classes/com/jogamp/opengl/GLExtensions.java
index f7e25fa..cf81b85 100644
--- a/src/jogl/classes/com/jogamp/opengl/GLExtensions.java
+++ b/src/jogl/classes/com/jogamp/opengl/GLExtensions.java
@@ -72,6 +72,9 @@ public class GLExtensions {
   
   public static final String OES_EGL_image_external          = "GL_OES_EGL_image_external";
   
+  public static final String ARB_gpu_shader_fp64             = "GL_ARB_gpu_shader_fp64";
+  public static final String ARB_shader_objects              = "GL_ARB_shader_objects";
+   
   //
   // Aliased GLX/WGL/.. extensions
   //
diff --git a/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java b/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java
new file mode 100644
index 0000000..2f453a4
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java
@@ -0,0 +1,144 @@
+/**
+ * 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;
+
+/** 
+ * GLRendererQuirks contains information of known bugs of various GL renderer. 
+ * This information allows us to workaround them.
+ * <p>
+ * Using centralized quirk identifier enables us to
+ * locate code dealing w/ it and hence eases it's maintenance.   
+ * </p>
+ */
+public class GLRendererQuirks {
+    /** 
+     * Crashes XServer when using double buffered PBuffer with:
+     * <ul>
+     *  <li>Mesa DRI Intel(R) Sandybridge Desktop</li>
+     *  <li>Mesa DRI Intel(R) Ivybridge Mobile - 3.0 Mesa 8.0.4</li>
+     *  <li>Gallium 0.4 on AMD CYPRESS</li>
+     * </ul>
+     * For now, it is safe to disable it w/ hw-acceleration.
+     */
+    public static final int NoDoubleBufferedPBuffer = 0;
+    
+    /** On Windows no double buffered bitmaps are guaranteed to be available. */
+    public static final int NoDoubleBufferedBitmap  = 1;
+
+    /** Crashes application when trying to set EGL swap interval on Android 4.0.3 / Pandaboard ES / PowerVR SGX 540 */
+    public static final int NoSetSwapInterval       = 2;
+    
+    /** No offscreen bitmap available, currently true for JOGL's OSX implementation. */
+    public static final int NoOffscreenBitmap       = 3;
+    
+    /** 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 happen on Nvidia Tegra2. FIXME: Constrain version. */
+    public static final int GLSLBuggyDiscard = 5;
+    
+    /** Number of quirks known. */
+    public static final int COUNT = 6;
+    
+    private static final String[] _names = new String[] { "NoDoubleBufferedPBuffer", "NoDoubleBufferedBitmap", "NoSetSwapInterval",
+                                                          "NoOffscreenBitmap", "NoSetSwapIntervalPostRetarget", "GLSLBuggyDiscard"
+                                                        };
+
+    private final int _bitmask;
+
+    /**
+     * @param quirks an array of valid quirks
+     * @param offset offset in quirks array to start reading
+     * @param len number of quirks to read from offset within quirks array
+     * @throws IllegalArgumentException if one of the quirks is out of range
+     */
+    public GLRendererQuirks(int[] quirks, int offset, int len) throws IllegalArgumentException {
+        int bitmask = 0;
+        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++) {
+            final int quirk = quirks[i];
+            validateQuirk(quirk);
+            bitmask |= 1 << quirk;
+        }
+        _bitmask = bitmask;
+    }      
+
+    /**
+     * @param quirk the quirk to be tested
+     * @return true if quirk exist, otherwise false
+     * @throws IllegalArgumentException if quirk is out of range
+     */
+    public final boolean exist(int quirk) throws IllegalArgumentException {
+        validateQuirk(quirk);
+        return 0 != ( ( 1 << quirk )  & _bitmask );
+    }
+
+    public final StringBuilder toString(StringBuilder sb) {
+        if(null == sb) {
+            sb = new StringBuilder();
+        }
+        sb.append("[");
+        boolean first=true;
+        for(int i=0; i<COUNT; i++) {
+            final int testmask = 1 << i;
+            if( 0 != ( _bitmask & testmask ) ) {
+                if(!first) { sb.append(", "); }
+                sb.append(toString(i));
+                first=false;
+            }
+        }
+        sb.append("]");
+        return sb;
+    }
+    
+    public final String toString() {
+        return toString(null).toString();
+    }
+
+    /**
+     * @param quirk the quirk to be validated, i.e. whether it is out of range
+     * @throws IllegalArgumentException if quirk is out of range
+     */
+    public static void validateQuirk(int quirk) throws IllegalArgumentException {
+        if( !( 0 <= quirk && quirk < COUNT ) ) {
+            throw new IllegalArgumentException("Quirks must be in range [0.."+COUNT+"[, but quirk: "+quirk);
+        }        
+    }
+
+    /**
+     * @param quirk the quirk to be converted to String
+     * @return the String equivalent of this quirk
+     * @throws IllegalArgumentException if quirk is out of range
+     */
+    public static final String toString(int quirk) throws IllegalArgumentException {
+        validateQuirk(quirk);
+        return _names[quirk];
+    }
+}
diff --git a/src/newt/classes/com/jogamp/newt/event/WindowUpdateEvent.java b/src/jogl/classes/com/jogamp/opengl/GenericGLCapabilitiesChooser.java
similarity index 67%
copy from src/newt/classes/com/jogamp/newt/event/WindowUpdateEvent.java
copy to src/jogl/classes/com/jogamp/opengl/GenericGLCapabilitiesChooser.java
index 505939d..73ec108 100644
--- a/src/newt/classes/com/jogamp/newt/event/WindowUpdateEvent.java
+++ b/src/jogl/classes/com/jogamp/opengl/GenericGLCapabilitiesChooser.java
@@ -1,5 +1,5 @@
 /**
- * Copyright 2010 JogAmp Community. All rights reserved.
+ * 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:
@@ -25,25 +25,24 @@
  * authors and should not be interpreted as representing official policies, either expressed
  * or implied, of JogAmp Community.
  */
- 
-package com.jogamp.newt.event;
 
-import javax.media.nativewindow.util.Rectangle;
+package com.jogamp.opengl;
 
-public class WindowUpdateEvent extends WindowEvent {
-    final Rectangle bounds;
+import java.util.List;
+import javax.media.nativewindow.CapabilitiesImmutable;
+import javax.media.opengl.DefaultGLCapabilitiesChooser;
 
-    public WindowUpdateEvent(int eventType, Object source, long when, Rectangle bounds)
-    {
-        super(eventType, source, when);
-        this.bounds = bounds;
-    }
-
-    public Rectangle getBounds() {
-        return bounds;
-    }
+/**
+ * Ignores windowSystemRecommendedChoice parameter,
+ * otherwise uses {@link DefaultGLCapabilitiesChooser} implementation.
+ */
+public class GenericGLCapabilitiesChooser extends DefaultGLCapabilitiesChooser {
+    
+  @Override
+  public int chooseCapabilities(final CapabilitiesImmutable desired,
+                                final List<? extends CapabilitiesImmutable> available,
+                                final int windowSystemRecommendedChoice) {
+    return super.chooseCapabilities(desired, available, -1);
+  }
 
-    public String toString() {
-        return "WindowUpdateEvent["+super.toString()+", "+bounds+"]";
-    }
 }
diff --git a/src/jogl/classes/com/jogamp/opengl/JoglVersion.java b/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
index cdb4b82..52721e3 100644
--- a/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
+++ b/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
@@ -169,6 +169,23 @@ public class JoglVersion extends JogampVersion {
         return sb;
     }
 
+    public StringBuilder getBriefOSGLBuildInfo(GL gl, StringBuilder sb) {        
+        if(null==sb) {
+            sb = new StringBuilder();
+        }
+        sb.append("OS: ").append(Platform.getOSName()).append(", version ").append(Platform.getOSVersion()).append(", arch ").append(Platform.getArchName());
+        sb.append(Platform.getNewline());
+        sb.append("GL_VENDOR     ").append(gl.glGetString(GL.GL_VENDOR));
+        sb.append(Platform.getNewline());
+        sb.append("GL_RENDERER   ").append(gl.glGetString(GL.GL_RENDERER));
+        sb.append(Platform.getNewline());
+        sb.append("GL_VERSION    ").append(gl.glGetString(GL.GL_VERSION));
+        sb.append(Platform.getNewline());
+        sb.append("JOGL GIT sha1 ").append(getImplementationCommit());
+        sb.append(Platform.getNewline());
+        return sb;
+    }
+    
     public static void main(String args[]) {
         System.err.println(VersionUtil.getPlatformInfo());
         System.err.println(GlueGenVersion.getInstance());
diff --git a/src/jogl/classes/com/jogamp/opengl/OffscreenAutoDrawable.java b/src/jogl/classes/com/jogamp/opengl/OffscreenAutoDrawable.java
deleted file mode 100644
index 8450ffd..0000000
--- a/src/jogl/classes/com/jogamp/opengl/OffscreenAutoDrawable.java
+++ /dev/null
@@ -1,98 +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;
-
-import javax.media.nativewindow.AbstractGraphicsDevice;
-import javax.media.opengl.GLAutoDrawableDelegate;
-import javax.media.opengl.GLContext;
-import javax.media.opengl.GLDrawable;
-import javax.media.opengl.GLException;
-
-import jogamp.opengl.GLFBODrawableImpl;
-
-/** 
- * Platform-independent class exposing FBO offscreen functionality to
- * applications.
- * <p>
- * This class distinguishes itself from {@link GLAutoDrawableDelegate}
- * with it's {@link #setSize(int, int)} functionality.
- * </p>
- */
-public class OffscreenAutoDrawable extends GLAutoDrawableDelegate {
-  
-    /**
-     * @param drawable a valid {@link GLDrawable}, may not be realized yet.
-     * @param context a valid {@link GLContext}, may not be made current (created) yet.
-     * @param ownDevice pass <code>true</code> if {@link AbstractGraphicsDevice#close()} shall be issued,
-     *                  otherwise pass <code>false</code>. Closing the device is required in case
-     *                  the drawable is created w/ it's own new instance, e.g. offscreen drawables,
-     *                  and no further lifecycle handling is applied.
-     */
-    public OffscreenAutoDrawable(GLDrawable drawable, GLContext context, boolean ownDevice) {
-        super(drawable, context, null, ownDevice);
-    }
-
-    /**
-     * Attempts to resize this offscreen auto drawable, if supported
-     * by the underlying {@link GLDrawable).
-     * @param newWidth
-     * @param newHeight
-     * @return <code>true</code> if resize was executed, otherwise <code>false</code>.
-     * @throws GLException in case of an error during the resize operation
-     */
-    public boolean setSize(int newWidth, int newHeight) throws GLException {
-        boolean done = false;
-        if(drawable instanceof GLFBODrawableImpl) {
-            context.makeCurrent();
-            try {                        
-                ((GLFBODrawableImpl)drawable).setSize(context.getGL(), newWidth, newHeight);
-                done = true;
-            } finally {
-                context.release();
-            }
-        }
-        if(done) {
-            this.defaultWindowResizedOp();
-            return true;
-        }
-        return false;
-    }
-    
-    /**
-     * If the underlying {@link GLDrawable} is an FBO implementation
-     * and contains an {#link FBObject}, the same is returned.
-     * Otherwise returns <code>null</code>.
-     */
-    public FBObject getFBObject() { 
-        if(drawable instanceof GLFBODrawableImpl) {
-            return ((GLFBODrawableImpl)drawable).getFBObject();
-        }
-        return null;
-    }
-}
diff --git a/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java b/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
index 8d23716..3332262 100644
--- a/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
+++ b/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
@@ -30,6 +30,7 @@ package com.jogamp.opengl.swt;
 import javax.media.nativewindow.AbstractGraphicsDevice;
 import javax.media.nativewindow.NativeSurface;
 import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
 import javax.media.opengl.GL;
 import javax.media.opengl.GLAnimatorControl;
 import javax.media.opengl.GLAutoDrawable;
@@ -48,6 +49,7 @@ import javax.media.opengl.Threading;
 import jogamp.opengl.Debug;
 import jogamp.opengl.GLContextImpl;
 import jogamp.opengl.GLDrawableHelper;
+import jogamp.opengl.GLDrawableImpl;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.ControlAdapter;
@@ -97,8 +99,8 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
    private final GLCapabilitiesImmutable capsRequested;
    private final GLCapabilitiesChooser capsChooser; 
    
-   private volatile GLDrawable drawable; // volatile: avoid locking for read-only access
-   private GLContext context;
+   private volatile GLDrawableImpl drawable; // volatile: avoid locking for read-only access
+   private GLContextImpl context;
 
    /* Native window surface */
    private AbstractGraphicsDevice device;
@@ -116,7 +118,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
    private final Runnable initAction = new Runnable() {
       @Override
       public void run() {
-         helper.init(GLCanvas.this);
+         helper.init(GLCanvas.this, !sendReshape);
       }
    };
 
@@ -151,24 +153,18 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
    };
 
    /* Swaps buffers, assuming the GLContext is current */
-   private final Runnable swapBuffersAction = new Runnable() {
+   private final Runnable swapBuffersOnEDTAction = new Runnable() {
       @Override
       public void run() {
-         drawable.swapBuffers();
-      }
-   };
-
-   /* Swaps buffers, making the GLContext current first */
-   private final Runnable makeCurrentAndSwapBuffersOnEDTAction = new Runnable() {
-      @Override
-      public void run() {
-         final RecursiveLock _lock = lock;
-         _lock.lock();
-         try {            
-           helper.invokeGL(drawable, context, swapBuffersAction, initAction);
-         } finally {
-             _lock.unlock();
-         }
+        final RecursiveLock _lock = lock;
+        _lock.lock();
+        try {
+            if(null != drawable) {
+                drawable.swapBuffers();
+            }
+        } finally {
+            _lock.unlock();
+        }
       }
    };
 
@@ -286,7 +282,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
       clientArea = GLCanvas.this.getClientArea();
 
       /* Get the nativewindow-Graphics Device associated with this control (which is determined by the parent Composite). 
-       * Note: SWT is owner of the native handle, hence no closing operation will be a NOP. */
+       * Note: SWT is owner of the native handle, hence closing operation will be a NOP. */
       device = SWTAccessor.getDevice(this);
 
       /* Select default GLCapabilities if none was provided, otherwise clone provided caps to ensure safety */
@@ -319,7 +315,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
          }
       });
    }
-   private final ProxySurface.UpstreamSurfaceHook swtCanvasUpStreamHook = new ProxySurface.UpstreamSurfaceHook() {
+   private final UpstreamSurfaceHook swtCanvasUpStreamHook = new UpstreamSurfaceHook() {
        @Override
        public final void create(ProxySurface s) { /* nop */ }
 
@@ -349,7 +345,27 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
            ( nClientArea.width != oClientArea.width || nClientArea.height != oClientArea.height )
          ) {
           clientArea = nClientArea; // write back new value
-          sendReshape = true; // Mark for OpenGL reshape next time the control is painted
+          
+          GLDrawableImpl _drawable = drawable;
+          if( null != _drawable ) {
+              if(DEBUG) {
+                  System.err.println("GLCanvas.sizeChanged: ("+Thread.currentThread().getName()+"): "+nClientArea.width+"x"+nClientArea.height+" - surfaceHandle 0x"+Long.toHexString(getNativeSurface().getSurfaceHandle()));
+              }
+              if( ! _drawable.getChosenGLCapabilities().isOnscreen() ) {
+                  final RecursiveLock _lock = lock;
+                  _lock.lock();
+                  try {
+                      final GLDrawableImpl _drawableNew = GLDrawableHelper.resizeOffscreenDrawable(_drawable, context, nClientArea.width, nClientArea.height);
+                      if(_drawable != _drawableNew) {
+                          // write back 
+                          drawable = _drawableNew;
+                      }
+                  } finally {
+                      _lock.unlock();
+                  }
+                  sendReshape = true; // async if display() doesn't get called below, but avoiding deadlock
+              }
+          }          
       }
    }
    
@@ -367,7 +383,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
           return false;
       }
       final Rectangle nClientArea = clientArea;
-      if(0 == nClientArea.width * nClientArea.height) {
+      if(0 >= nClientArea.width || 0 >= nClientArea.height) {
           return false;
       }
                
@@ -391,10 +407,10 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
           
           if(null != proxySurface) {
               /* Associate a GL surface with the proxy */
-              drawable = glFactory.createGLDrawable(proxySurface);
+              drawable = (GLDrawableImpl) glFactory.createGLDrawable(proxySurface);
               drawable.setRealized(true);
         
-              context = drawable.createContext(shareWith);
+              context = (GLContextImpl) drawable.createContext(shareWith);
           }
       } finally {
           _lock.unlock();
@@ -456,6 +472,11 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
    }
 
    @Override
+   public final GLDrawable getDelegatedDrawable() {
+      return drawable;
+   }
+   
+   @Override
    public GLContext getContext() {
       return null != drawable ? context : null;
    }
@@ -502,7 +523,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
       _lock.lock();
       try {            
           final GLContext oldCtx = context;
-          final boolean newCtxCurrent = helper.switchContext(drawable, oldCtx, newCtx, additionalCtxCreationFlags);
+          final boolean newCtxCurrent = GLDrawableHelper.switchContext(drawable, oldCtx, newCtx, additionalCtxCreationFlags);
           context=(GLContextImpl)newCtx;
           if(newCtxCurrent) {
               context.makeCurrent();
@@ -600,7 +621,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
 
    @Override
    public void swapBuffers() throws GLException {
-      runInGLThread(makeCurrentAndSwapBuffersOnEDTAction);
+      runInGLThread(swapBuffersOnEDTAction);
    }
 
    @Override
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java
index 134dd96..88cb330 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java
@@ -124,33 +124,41 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
   // Data read access
   //
 
+  @Override
   public final boolean isVBOWritten() { return bufferWritten; }
 
+  @Override
   public final boolean sealed() { return sealed; }
   
+  @Override
   public final boolean enabled() { return bufferEnabled; }
 
   //
   // Data and GL state modification ..
   //
 
+  @Override
   public final void setVBOWritten(boolean written) { bufferWritten=written; }
 
+  @Override
   public void destroy(GL gl) {
     reset(gl);
     super.destroy(gl);
   }
 
+  @Override
   public void reset(GL gl) {
     enableBuffer(gl, false);
     reset();
   }
 
+  @Override
   public void seal(GL gl, boolean seal) {
     seal(seal);
     enableBuffer(gl, seal);
   }
 
+  @Override
   public void enableBuffer(GL gl, boolean enable) {
     if( enableBufferAlways || bufferEnabled != enable ) { 
         if(enable) {
@@ -167,17 +175,22 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
         } else {
             ext = null;
         }
-        if(enable) {
-            glArrayHandler.syncData(gl, true, ext);
-            glArrayHandler.enableState(gl, true, ext);
-        } else {
-            glArrayHandler.enableState(gl, false, ext);
-            glArrayHandler.syncData(gl, false, ext);
-        }
+        glArrayHandler.enableState(gl, enable, ext);
         bufferEnabled = enable;
     }
   }
-
+  
+  @Override
+  public boolean bindBuffer(GL gl, boolean bind) {
+      if(bind) {
+          checkSeal(true);
+          // init/generate VBO name if not done yet
+          init_vbo(gl);
+      }
+      return glArrayHandler.bindBuffer(gl, bind);
+  }
+  
+  @Override
   public void setEnableAlways(boolean always) {
     enableBufferAlways = always;
   }
@@ -186,6 +199,7 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
   // Data modification ..
   //
 
+  @Override
   public void reset() {
     if(buffer!=null) {
         buffer.clear();
@@ -195,6 +209,7 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
     this.bufferWritten=false;
   }
 
+  @Override
   public void seal(boolean seal)
   {
     if(sealed==seal) return;
@@ -211,12 +226,14 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
   }
 
 
+  @Override
   public void rewind() {
     if(buffer!=null) {
         buffer.rewind();
     }
   }
 
+  @Override
   public void padding(int doneInByteSize) {
     if ( buffer==null || sealed ) return;
     while(doneInByteSize<strideB) {
@@ -231,6 +248,7 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
    * This class buffer Class must match the arguments buffer class.
    * The arguments remaining elements must be a multiple of this arrays element stride.
    */
+  @Override
   public void put(Buffer v) {
     if ( sealed ) return;
     /** FIXME: isn't true for interleaved arrays !
@@ -241,28 +259,33 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
     Buffers.put(buffer, v);
   }
 
+  @Override
   public void putb(byte v) {
     if ( sealed ) return;
     growBufferIfNecessary(1);
     Buffers.putb(buffer, v);
   }
 
+  @Override
   public void puts(short v) {
     if ( sealed ) return;
     growBufferIfNecessary(1);
     Buffers.puts(buffer, v);
   }
 
+  @Override
   public void puti(int v) {
     if ( sealed ) return;
     growBufferIfNecessary(1);
     Buffers.puti(buffer, v);
   }
 
+  @Override
   public void putx(int v) {
     puti(v);
   }
 
+  @Override
   public void putf(float v) {
     if ( sealed ) return;
     growBufferIfNecessary(1);
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataEditable.java b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataEditable.java
index bb22a4b..9b04a48 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataEditable.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataEditable.java
@@ -14,7 +14,7 @@ import java.nio.*;
 public interface GLArrayDataEditable extends GLArrayData {
 
     public boolean sealed();
-    
+
     public boolean enabled();
 
     /**
@@ -45,9 +45,14 @@ public interface GLArrayDataEditable extends GLArrayData {
     public void seal(GL gl, boolean seal);
 
     /**
-     * <p>Enables/disables the buffer, 
-     * sets the client state, binds the VBO if used
-     * and transfers the data if necessary.</p>
+     * Enables the buffer if <code>enable</code> is <code>true</code>, 
+     * and transfers the data if required.
+     * In case {@link #isVBO() VBO is used}, it is bound accordingly for the data transfer and association,
+     * i.e. it issued {@link #bindBuffer(GL, boolean)}.
+     * The VBO buffer is unbound when the method returns. 
+     * <p>
+     * Disables the buffer if <code>enable</code> is <code>false</code>. 
+     * </p>
      * 
      * <p>The action will only be executed,
      * if the internal enable state differs, 
@@ -63,6 +68,26 @@ public interface GLArrayDataEditable extends GLArrayData {
     public void enableBuffer(GL gl, boolean enable);
 
     /**
+     * if <code>bind</code> is true and the data uses {@link #isVBO() VBO}, 
+     * the latter will be bound and data written to the GPU if required.
+     * <p>
+     * If  <code>bind</code> is false and the data uses {@link #isVBO() VBO},
+     * the latter will be unbound.
+     * </p>
+     * <p>
+     * This method is exposed to allow data VBO arrays, i.e. {@link GL#GL_ELEMENT_ARRAY_BUFFER},
+     * to be bounded and written while keeping the VBO bound. The latter is in contrast to {@link #enableBuffer(GL, boolean)},
+     * which leaves the VBO unbound, since it's not required for vertex attributes or pointers.
+     * </p>
+     * 
+     * @param gl current GL object
+     * @param bind true if VBO shall be bound and data written, 
+     *        otherwise clear VBO binding. 
+     * @return true if data uses VBO and action was performed, otherwise false 
+     */
+    public boolean bindBuffer(GL gl, boolean bind);
+
+    /**
      * Affects the behavior of 'enableBuffer'.
      *
      * The default is 'false'
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java
index bade0a3..f4a197b 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java
@@ -253,16 +253,10 @@ public class GLArrayDataWrapper implements GLArrayData {
     
     this.componentType = componentType;
     componentClazz = getBufferClass(componentType);
-    switch(componentType) {
-        case GL.GL_BYTE:
-        case GL.GL_UNSIGNED_BYTE:
-        case GL.GL_SHORT:
-        case GL.GL_UNSIGNED_SHORT:
-        case GL.GL_FIXED:
-            this.normalized = normalized;
-            break;
-        default:    
-            this.normalized = false;
+    if( GLBuffers.isGLTypeFixedPoint(componentType) ) {
+        this.normalized = normalized;
+    } else {
+        this.normalized = false;
     }
     componentByteSize = GLBuffers.sizeOfGLType(componentType);
     if(0 > componentByteSize) {
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java b/src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java
index 331d6fa..174935d 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java
@@ -38,7 +38,8 @@
  */
 package com.jogamp.opengl.util;
 
-import com.jogamp.common.nio.Buffers;
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
 
 import javax.media.opengl.GL;
 import javax.media.opengl.GL2;
@@ -47,7 +48,7 @@ import javax.media.opengl.GL2GL3;
 import javax.media.opengl.GLES2;
 import javax.media.opengl.GLException;
 
-import java.nio.*;
+import com.jogamp.common.nio.Buffers;
 
 /**
  * Utility routines for dealing with direct buffers.
@@ -57,6 +58,47 @@ import java.nio.*;
 public class GLBuffers extends Buffers {
 
     /**
+     * @param glType GL primitive type
+     * @return false if one of GL primitive unsigned types, otherwise true
+     *              GL_UNSIGNED_BYTE, <br/>
+     *              GL_UNSIGNED_SHORT, <br/>
+     *              GL_UNSIGNED_INT, <br/>
+     *              GL_HILO16_NV <br/>
+     */
+    public static final boolean isSignedGLType(int glType) {
+        switch (glType) { // 29
+            case GL.GL_UNSIGNED_BYTE:
+            case GL.GL_UNSIGNED_SHORT:
+            case GL.GL_UNSIGNED_INT:
+            case GL2.GL_HILO16_NV:
+                return false;
+                
+        }
+        return true;
+    }
+    
+    /**
+     * @param glType GL primitive type
+     * @return false if one of GL primitive floating point types, otherwise true
+     *              GL_FLOAT, <br/>
+     *              GL_HALF_FLOAT, <br/>
+     *              GL_HALF_FLOAT_OES, <br/>
+     *              GL_DOUBLE <br/>
+     */
+    public static final boolean isGLTypeFixedPoint(int glType) {
+        switch(glType) {
+            case GL.GL_FLOAT:
+            case GL.GL_HALF_FLOAT:
+            case GLES2.GL_HALF_FLOAT_OES:
+            case GL2GL3.GL_DOUBLE:
+                return false;
+                
+            default:
+                return true;
+        }        
+    }
+    
+    /**
      * @param glType shall be one of (29) <br/>
      *              GL_BYTE, GL_UNSIGNED_BYTE, <br/>
      *              GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV, <br/>
@@ -224,15 +266,20 @@ public class GLBuffers extends Buffers {
         if (parent == null || byteLen == 0) {
             return null;
         }
+        final int parentPos = parent.position();
+        final int parentLimit = parent.limit();
+        
         parent.position(bytePos);
         parent.limit(bytePos + byteLen);
-
+        Buffer res = null;
+        
         switch (glType) { // 29
             case GL.GL_BYTE:
             case GL.GL_UNSIGNED_BYTE:
             case GL2GL3.GL_UNSIGNED_BYTE_3_3_2:
             case GL2GL3.GL_UNSIGNED_BYTE_2_3_3_REV:
-                return parent.slice();
+                res = parent.slice().order(parent.order()); // slice and duplicate may change byte order
+                break;
                 
             case GL.GL_SHORT:
             case GL.GL_UNSIGNED_SHORT:
@@ -244,7 +291,8 @@ public class GLBuffers extends Buffers {
             case GL2GL3.GL_UNSIGNED_SHORT_1_5_5_5_REV:
             case GL.GL_HALF_FLOAT:
             case GLES2.GL_HALF_FLOAT_OES:
-                return parent.asShortBuffer();
+                res = parent.slice().order(parent.order()).asShortBuffer(); // slice and duplicate may change byte order
+                break;
                 
             case GL.GL_FIXED:
             case GL2GL3.GL_INT:
@@ -258,18 +306,23 @@ public class GLBuffers extends Buffers {
             case GL2GL3.GL_UNSIGNED_INT_5_9_9_9_REV:
             case GL2.GL_HILO16_NV:
             case GL2.GL_SIGNED_HILO16_NV:
-                return parent.asIntBuffer();
+                res = parent.slice().order(parent.order()).asIntBuffer(); // slice and duplicate may change byte order
+                break;
                 
             case GL2GL3.GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
-                return parent.asLongBuffer();
+                res = parent.slice().order(parent.order()).asLongBuffer(); // slice and duplicate may change byte order
+                break;
                 
             case GL.GL_FLOAT:
-                return parent.asFloatBuffer();
+                res = parent.slice().order(parent.order()).asFloatBuffer(); // slice and duplicate may change byte order
+                break;
                 
             case GL2.GL_DOUBLE:
-                return parent.asDoubleBuffer();
+                res = parent.slice().order(parent.order()).asDoubleBuffer(); // slice and duplicate may change byte order
+                break;
         }
-        return null;
+        parent.position(parentPos).limit(parentLimit);
+        return res;
     }
 
     private static final int glGetInteger(GL gl, int pname, int[] tmp) {
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java b/src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java
index b0fae8a..b8709f3 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java
@@ -116,6 +116,10 @@ public class GLReadBufferUtil {
      * @see #GLReadBufferUtil(boolean, boolean)
      */
     public boolean readPixels(GL gl, boolean flip) {
+        final int glerr0 = gl.glGetError();
+        if(GL.GL_NO_ERROR != glerr0) {
+            System.err.println("Info: GLReadBufferUtil.readPixels: pre-exisiting GL error 0x"+Integer.toHexString(glerr0));
+        }
         final GLDrawable drawable = gl.getContext().getGLReadDrawable();
         final int textureInternalFormat, textureDataFormat, textureDataType;
         final int[] glImplColorReadVals = new int[] { 0, 0 };
@@ -175,7 +179,9 @@ public class GLReadBufferUtil {
         if(res) {
             psm.setAlignment(gl, alignment, alignment);
             readPixelBuffer.clear();
-            gl.glReadPixels(0, 0, drawable.getWidth(), drawable.getHeight(), textureDataFormat, textureDataType, readPixelBuffer);
+            try {
+                gl.glReadPixels(0, 0, drawable.getWidth(), drawable.getHeight(), textureDataFormat, textureDataType, readPixelBuffer);
+            } catch(GLException gle) { res = false; gle.printStackTrace(); }
             readPixelBuffer.position(readPixelSize);
             readPixelBuffer.flip();
             final int glerr1 = gl.glGetError();
diff --git a/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java b/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java
index cf03730..f01896b 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java
@@ -3,6 +3,7 @@ package com.jogamp.opengl.util;
 
 import java.nio.Buffer;
 import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
 import java.nio.ShortBuffer;
 import java.util.ArrayList;
 import java.util.Iterator;
@@ -13,52 +14,112 @@ import javax.media.opengl.GL2ES2;
 import javax.media.opengl.GLException;
 import javax.media.opengl.fixedfunc.GLPointerFunc;
 
-import com.jogamp.common.util.ReflectionUtil;
+import jogamp.opengl.Debug;
+
+import com.jogamp.common.nio.Buffers;
+import com.jogamp.common.os.Platform;
 import com.jogamp.opengl.util.glsl.ShaderState;
 
+/**
+ * <p>
+ * Immediate mode sink, implementing OpenGL fixed function subset of immediate mode operations, i.e.
+ * <pre>
+ *   glBegin();
+ *     glVertex3f(1f, 1f, 1f);
+ *     glColor4f(1f, 1f, 1f, 1f);
+ *     ...
+ *   glEnd();
+ * </pre>
+ * Implementation buffers all vertex, colors, normal and texture-coord elements in their respective buffers
+ * to be either rendered directly via {@link #glEnd(GL)} or to be added to an internal display list
+ * via {@link #glEnd(GL, boolean) glEnd(gl, false)} for deferred rendering via {@link #draw(GL, boolean)}.
+ * </p>
+ * <a name="storageDetails"><h5>Buffer storage and it's creation via {@link #createFixed(int, int, int, int, int, int, int, int, int, int) createFixed(..)} 
+ * and {@link #createGLSL(int, int, int, int, int, int, int, int, int, int) createGLSL(..)}</h5></a> 
+ * <p>
+ * If unsure whether <i>colors</i>, <i>normals</i> and <i>textures</i> will be used, 
+ * simply add them with an expected component count.
+ * This implementation will only render buffers which are being filled.<br/>
+ * The buffer growing implementation will only grow the exceeded buffers, unused buffers are not resized.
+ * </p>
+ * <p>
+ * Note: Optional types, i.e. color, must be either not used or used w/ the same element count as vertex, etc. 
+ * This is a semantic constraint, same as in the original OpenGL spec.
+ * </p>
+ */
 public class ImmModeSink {
+  protected static final boolean DEBUG_BEGIN_END = Debug.isPropertyDefined("jogl.debug.ImmModeSink.BeginEnd", true);
+  protected static final boolean DEBUG_DRAW = Debug.isPropertyDefined("jogl.debug.ImmModeSink.Draw", true);  
+  protected static final boolean DEBUG_BUFFER = Debug.isPropertyDefined("jogl.debug.ImmModeSink.Buffer", true);  
 
-  public static final boolean DEBUG_BEGIN_END = false;
-  public static final boolean DEBUG_DRAW = false;
-
-  // public static final int GL_QUADS      = 0x0007; // Needs data manipulation
+  public static final int GL_QUADS      = 0x0007; // Needs data manipulation on ES1/ES2
   public static final int GL_QUAD_STRIP = 0x0008;
   public static final int GL_POLYGON    = 0x0009;
 
   /**
    * Uses a GL2ES1, or ES2 fixed function emulation immediate mode sink
+   * <p>
+   * See <a href="#storageDetails"> buffer storage details</a>.
+   * </p>
+   * 
+   * @param initialElementCount initial buffer size, if subsequent mutable operations are about to exceed the buffer size, the buffer will grow about the initial size.
+   * @param vComps mandatory vertex component count, should be 2, 3 or 4.
+   * @param vDataType mandatory vertex data type, e.g. {@link GL#GL_FLOAT}
+   * @param cComps optional color component count, may be 0, 3 or 4
+   * @param cDataType optional color data type, e.g. {@link GL#GL_FLOAT}
+   * @param nComps optional normal component count, may be 0, 3 or 4
+   * @param nDataType optional normal data type, e.g. {@link GL#GL_FLOAT}
+   * @param tComps optional texture-coordinate  component count, may be 0, 2 or 3
+   * @param tDataType optional texture-coordinate data type, e.g. {@link GL#GL_FLOAT}
+   * @param glBufferUsage VBO <code>usage</code> parameter for {@link GL#glBufferData(int, long, Buffer, int)}, e.g. {@link GL#GL_STATIC_DRAW}, 
+   *                      set to <code>0</code> for no VBO usage
    */
-  public static ImmModeSink createFixed(GL gl, int glBufferUsage, int initialElementCount,
+  public static ImmModeSink createFixed(int initialElementCount, 
                                         int vComps, int vDataType,
-                                        int cComps, int cDataType, 
+                                        int cComps, int cDataType,
                                         int nComps, int nDataType, 
-                                        int tComps, int tDataType) {
-    return new ImmModeSink(gl, glBufferUsage, initialElementCount, 
-                           vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType, false);
+                                        int tComps, int tDataType, 
+                                        int glBufferUsage) {
+    return new ImmModeSink(initialElementCount, 
+                           vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType, 
+                           false, glBufferUsage);
   }
 
   /**
    * Uses a GL2ES2 GLSL shader immediate mode sink.
    * To issue the draw() command,
    * a ShaderState must be current, using ShaderState.glUseProgram().
-   *
+   * <p>
+   * See <a href="#storageDetails"> buffer storage details</a>.
+   * </p>
+   * 
+   * @param initialElementCount initial buffer size, if subsequent mutable operations are about to exceed the buffer size, the buffer will grow about the initial size.
+   * @param vComps mandatory vertex component count, should be 2, 3 or 4.
+   * @param vDataType mandatory vertex data type, e.g. {@link GL#GL_FLOAT}
+   * @param cComps optional color component count, may be 0, 3 or 4
+   * @param cDataType optional color data type, e.g. {@link GL#GL_FLOAT}
+   * @param nComps optional normal component count, may be 0, 3 or 4
+   * @param nDataType optional normal data type, e.g. {@link GL#GL_FLOAT}
+   * @param tComps optional texture-coordinate  component count, may be 0, 2 or 3
+   * @param tDataType optional texture-coordinate data type, e.g. {@link GL#GL_FLOAT}
+   * @param glBufferUsage VBO <code>usage</code> parameter for {@link GL#glBufferData(int, long, Buffer, int)}, e.g. {@link GL#GL_STATIC_DRAW}, 
+   *                      set to <code>0</code> for no VBO usage
+   * 
    * @see #draw(GL, boolean)
    * @see com.jogamp.opengl.util.glsl.ShaderState#useProgram(GL2ES2, boolean)
    * @see com.jogamp.opengl.util.glsl.ShaderState#getCurrentShaderState()
    */
-  public static ImmModeSink createGLSL(GL gl, int glBufferUsage, int initialElementCount,
+  public static ImmModeSink createGLSL(int initialElementCount, 
                                        int vComps, int vDataType,
-                                       int cComps, int cDataType, 
+                                       int cComps, int cDataType,
                                        int nComps, int nDataType, 
-                                       int tComps, int tDataType) {
-    return new ImmModeSink(gl, glBufferUsage, initialElementCount, 
-                           vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType, true);
+                                       int tComps, int tDataType, 
+                                       int glBufferUsage) {
+    return new ImmModeSink(initialElementCount, 
+                           vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType, 
+                           true, glBufferUsage);
   }
 
-  public static boolean usesVBO() { return vboUsage; }
-
-  public static void setVBOUsage(boolean v) { vboUsage = v; }
-
   public void destroy(GL gl) {
     destroyList(gl);
 
@@ -93,45 +154,38 @@ public class ImmModeSink {
 
   public void draw(GL gl, boolean disableBufferAfterDraw) {
     if(DEBUG_DRAW) {
-        Exception e = new Exception("Info: ImmModeSink.draw(disableBufferAfterDraw: "+disableBufferAfterDraw+"):\n\t"+this);
-        e.printStackTrace();
+        System.err.println("ImmModeSink.draw(disableBufferAfterDraw: "+disableBufferAfterDraw+"):\n\t"+this);
     }
     int n=0;
-    for(Iterator<VBOSet> i=vboSetList.iterator(); i.hasNext() ; n++) {
-        i.next().draw(gl, null, disableBufferAfterDraw, n);
+    for(int i=0; i<vboSetList.size(); i++, n++) {
+        vboSetList.get(i).draw(gl, null, disableBufferAfterDraw, n);
     }
   }
 
   public void draw(GL gl, Buffer indices, boolean disableBufferAfterDraw) {
     if(DEBUG_DRAW) {
-        Exception e = new Exception("Info: ImmModeSink.draw(disableBufferAfterDraw: "+disableBufferAfterDraw+"):\n\t"+this);
-        e.printStackTrace();
+        System.err.println("ImmModeSink.draw(disableBufferAfterDraw: "+disableBufferAfterDraw+"):\n\t"+this);
     }
     int n=0;
-    for(Iterator<VBOSet> i=vboSetList.iterator(); i.hasNext() ; n++) {
-        i.next().draw(gl, indices, disableBufferAfterDraw, n);
+    for(int i=0; i<vboSetList.size(); i++, n++) {
+        vboSetList.get(i).draw(gl, indices, disableBufferAfterDraw, n);
     }
   }
 
   public void glBegin(int mode) {
-    if(DEBUG_BEGIN_END) {
-        Exception e = new Exception("Info: ImmModeSink.glBegin("+vboSet.mode+"):\n\t"+this);
-        e.printStackTrace();
-    }
     vboSet.modeOrig = mode;
     switch(mode) {
-        // Needs data manipulation ..
-        //case GL_QUADS:
-        //    mode=GL.GL_LINES;
-        //    break;
         case GL_QUAD_STRIP:
             mode=GL.GL_TRIANGLE_STRIP;
             break;
         case GL_POLYGON:
-            mode=GL.GL_LINES;
+            mode=GL.GL_TRIANGLE_FAN;
             break;
     }
     vboSet.mode = mode;
+    if(DEBUG_BEGIN_END) {
+        System.err.println("ImmModeSink.glBegin("+vboSet.modeOrig+" -> "+vboSet.mode+")");
+    }
     vboSet.checkSeal(false);
   }
 
@@ -149,8 +203,7 @@ public class ImmModeSink {
 
   private void glEnd(GL gl, Buffer indices, boolean immediateDraw) {
     if(DEBUG_BEGIN_END) {
-        Exception e = new Exception("Info: ImmModeSink START glEnd(immediate: "+immediateDraw+"):\n\t"+this);
-        e.printStackTrace();
+        System.err.println("ImmModeSink START glEnd(immediate: "+immediateDraw+")");
     }
     if(immediateDraw) {
         vboSet.seal(gl, true);
@@ -160,7 +213,10 @@ public class ImmModeSink {
         vboSet.seal(gl, true);
         vboSet.enableBuffer(gl, false);
         vboSetList.add(vboSet);
-        vboSet = vboSet.regenerate();
+        vboSet = vboSet.regenerate(gl);
+    }
+    if(DEBUG_BEGIN_END) {
+        System.err.println("ImmModeSink END glEnd(immediate: "+immediateDraw+")");
     }
   }
 
@@ -249,10 +305,18 @@ public class ImmModeSink {
     vboSet.glColor3b(x,y,z);
   }
 
+  public final void glColor3ub(byte x, byte y, byte z) {
+    vboSet.glColor3ub(x,y,z);
+  }
+  
   public final void glColor4b(byte x, byte y, byte z, byte a) {
     vboSet.glColor4b(x,y,z,a);
   }
 
+  public final void glColor4ub(byte x, byte y, byte z, byte a) {
+    vboSet.glColor4ub(x,y,z,a);
+  }
+  
   public final void glTexCoord2b(byte x, byte y) {
     vboSet.glTexCoord2b(x,y);
   }
@@ -261,50 +325,86 @@ public class ImmModeSink {
     vboSet.glTexCoord3b(x,y,z);
   }
 
-  protected ImmModeSink(GL gl, int glBufferUsage, int initialElementCount,
-                        int vComps, int vDataType,
+  protected ImmModeSink(int initialElementCount, 
+                        int vComps, int vDataType, 
                         int cComps, int cDataType, 
                         int nComps, int nDataType, 
-                        int tComps, int tDataType, boolean useGLSL) {
-    if(useGLSL && !gl.hasGLSL()) {
-        throw new GLException("ImmModeSink GLSL usage not supported: "+gl);
-    }
-    vboSet = new  VBOSet(gl, glBufferUsage, initialElementCount, 
-                         vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType, useGLSL);
+                        int tComps, int tDataType, 
+                        boolean useGLSL, int glBufferUsage) {
+    vboSet = new  VBOSet(initialElementCount, 
+                         vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType, 
+                         useGLSL, glBufferUsage);
     this.vboSetList   = new ArrayList<VBOSet>();
   }
-
+  
+  public boolean getUseVBO() { return vboSet.getUseVBO(); }
+  
+  /**
+   * Returns the additional element count if buffer resize is required.
+   * @see #setResizeElementCount(int)
+   */
+  public int getResizeElementCount() { return vboSet.getResizeElementCount(); }
+  
+  /**
+   * Sets the additional element count if buffer resize is required,
+   * defaults to <code>initialElementCount</code> of factory method.
+   * @see #createFixed(int, int, int, int, int, int, int, int, int, int)
+   * @see #createGLSL(int, int, int, int, int, int, int, int, int, int)
+   */
+  public void setResizeElementCount(int v) { vboSet.setResizeElementCount(v); }
+  
   private void destroyList(GL gl) {
-    for(Iterator<VBOSet> i=vboSetList.iterator(); i.hasNext() ; ) {
-        i.next().destroy(gl);
+    for(int i=0; i<vboSetList.size(); i++) {
+        vboSetList.get(i).destroy(gl);
     }
     vboSetList.clear();
   }
 
   private VBOSet vboSet;
-  private ArrayList<VBOSet> vboSetList;
-  private static boolean vboUsage = true;
+  private final ArrayList<VBOSet> vboSetList;
 
   protected static class VBOSet {
-    protected VBOSet (GL gl, int glBufferUsage, int initialElementCount,
-                      int vComps, int vDataType,
+    protected VBOSet (int initialElementCount, 
+                      int vComps, int vDataType, 
                       int cComps, int cDataType, 
                       int nComps, int nDataType, 
-                      int tComps, int tDataType, boolean useGLSL) {
-        this.gl=gl;
+                      int tComps, int tDataType, 
+                      boolean useGLSL, int glBufferUsage) {
         this.glBufferUsage=glBufferUsage;
         this.initialElementCount=initialElementCount;
+        this.resizeElementCount=initialElementCount;
         this.vDataType=vDataType;
+        this.vDataTypeSigned=GLBuffers.isSignedGLType(vDataType);
         this.vComps=vComps;
+        this.vCompsBytes=vComps * GLBuffers.sizeOfGLType(vDataType);
         this.cDataType=cDataType;
+        this.cDataTypeSigned=GLBuffers.isSignedGLType(cDataType);
         this.cComps=cComps;
+        this.cCompsBytes=cComps * GLBuffers.sizeOfGLType(cDataType);
         this.nDataType=nDataType;
+        this.nDataTypeSigned=GLBuffers.isSignedGLType(nDataType);
         this.nComps=nComps;
+        this.nCompsBytes=nComps * GLBuffers.sizeOfGLType(nDataType);
         this.tDataType=tDataType;
+        this.tDataTypeSigned=GLBuffers.isSignedGLType(tDataType);
         this.tComps=tComps;
+        this.tCompsBytes=tComps * GLBuffers.sizeOfGLType(tDataType); 
         this.useGLSL=useGLSL;
-
-        allocateBuffer(initialElementCount);
+        this.useVBO = 0 != glBufferUsage;
+        this.vboName = 0;
+                
+        this.vCount=0;
+        this.cCount=0;
+        this.nCount=0;
+        this.tCount=0;
+        this.vElems=0;
+        this.cElems=0;
+        this.nElems=0;
+        this.tElems=0;
+        
+        this.pageSize = Platform.getMachineDescription().pageSizeInBytes();
+        
+        reallocateBuffer(initialElementCount);
         rewind();
 
         this.sealed=false;
@@ -313,11 +413,17 @@ public class ImmModeSink {
         this.modeOrig = 0;
         this.bufferEnabled=false;
         this.bufferWritten=false;
+        this.bufferWrittenOnce=false;
     }
 
-    protected final VBOSet regenerate() {
-        return new VBOSet(gl, glBufferUsage, initialElementCount, 
-                          vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType, useGLSL);
+    protected int getResizeElementCount() { return resizeElementCount; }
+    protected void setResizeElementCount(int v) { resizeElementCount=v; }
+    
+    protected boolean getUseVBO() { return useVBO; }
+    
+    protected final VBOSet regenerate(GL gl) {
+        return new VBOSet(initialElementCount, vComps, 
+                          vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType, useGLSL, glBufferUsage);
     }
 
     protected void checkSeal(boolean test) throws GLException {
@@ -335,280 +441,336 @@ public class ImmModeSink {
 
     protected void draw(GL gl, Buffer indices, boolean disableBufferAfterDraw, int i)
     {
-        if(DEBUG_DRAW) {
-            Exception e = new Exception("Info: ImmModeSink.draw["+i+"](disableBufferAfterDraw: "+disableBufferAfterDraw+"):\n\t"+this);
-            e.printStackTrace();
-        }
         enableBuffer(gl, true);
 
+        if(DEBUG_DRAW) {
+            System.err.println("ImmModeSink.draw["+i+"].0 (disableBufferAfterDraw: "+disableBufferAfterDraw+"):\n\t"+this);
+        }
+        
         if (buffer!=null) {
             if(null==indices) {
-                gl.glDrawArrays(mode, 0, count);
+                if ( GL_QUADS == mode && !gl.isGL2() ) {
+                    for (int j = 0; j < vElems - 3; j += 4) {
+                        gl.glDrawArrays(GL.GL_TRIANGLE_FAN, j, 4);
+                    }
+                } else {
+                    gl.glDrawArrays(mode, 0, vElems);
+                }
             } else {
-                Class<?> clazz = indices.getClass();
-                int type=-1;
-                if(ReflectionUtil.instanceOf(clazz, ByteBuffer.class.getName())) {
+                final int type;
+                if(indices instanceof ByteBuffer) {
                     type =  GL.GL_UNSIGNED_BYTE;
-                } else if(ReflectionUtil.instanceOf(clazz, ShortBuffer.class.getName())) {
+                } else if(indices instanceof ShortBuffer) {
                     type =  GL.GL_UNSIGNED_SHORT;
+                } else if(indices instanceof IntBuffer) {
+                    type =  GL.GL_UNSIGNED_INT;
+                } else {
+                    throw new GLException("Given Buffer Class not supported: "+indices.getClass()+", should be ubyte, ushort or uint:\n\t"+this);
                 }
-                if(0>type) {
-                    throw new GLException("Given Buffer Class not supported: "+clazz+", should be ubyte or ushort:\n\t"+this);
+                final int idxLen = indices.remaining();
+                final int idx0 = indices.position();
+                
+                if ( GL_QUADS == mode && !gl.isGL2() ) {
+                    if( GL.GL_UNSIGNED_BYTE == type ) {
+                        final ByteBuffer b = (ByteBuffer) indices;
+                        for (int j = 0; j < idxLen; j++) {
+                            gl.glDrawArrays(GL.GL_TRIANGLE_FAN, (int)(0x000000ff & b.get(idx0+j)), 4);
+                        }                        
+                    } else if( GL.GL_UNSIGNED_SHORT == type ){
+                        final ShortBuffer b = (ShortBuffer) indices;
+                        for (int j = 0; j < idxLen; j++) {
+                            gl.glDrawArrays(GL.GL_TRIANGLE_FAN, (int)(0x0000ffff & b.get(idx0+j)), 4);
+                        }                                                
+                    } else {
+                        final IntBuffer b = (IntBuffer) indices;
+                        for (int j = 0; j < idxLen; j++) {
+                            gl.glDrawArrays(GL.GL_TRIANGLE_FAN, (int)(0xffffffff & b.get(idx0+j)), 4);
+                        }                                                
+                    }
+                } else {
+                    gl.glDrawElements(mode, idxLen, type, indices);
+                    // GL2: gl.glDrawRangeElements(mode, 0, idxLen-1, idxLen, type, indices);
                 }
-                gl.glDrawElements(mode, indices.remaining(), type, indices);
-                // GL2: gl.glDrawRangeElements(mode, 0, indices.remaining()-1, indices.remaining(), type, indices);
             }
         }
 
         if(disableBufferAfterDraw) {
             enableBuffer(gl, false);
         }
+        
+        if(DEBUG_DRAW) {
+            System.err.println("ImmModeSink.draw["+i+"].X (disableBufferAfterDraw: "+disableBufferAfterDraw+")");
+        }
     }
 
     public void glVertexv(Buffer v) {
         checkSeal(false);
-        GLBuffers.put(vertexArray, v);
+        Buffers.put(vertexArray, v);
     }
     public void glNormalv(Buffer v) {
         checkSeal(false);
-        GLBuffers.put(normalArray, v);
+        Buffers.put(normalArray, v);
     }
     public void glColorv(Buffer v) {
         checkSeal(false);
-        GLBuffers.put(colorArray, v);
+        Buffers.put(colorArray, v);
     }
     public void glTexCoordv(Buffer v) {
         checkSeal(false);
-        GLBuffers.put(textCoordArray, v);
+        Buffers.put(textCoordArray, v);
     }
 
     public void glVertex2b(byte x, byte y) {
         checkSeal(false);
-        growBufferIfNecessary(VERTEX, 2);
+        growBuffer(VERTEX);
         if(vComps>0) 
-            GLBuffers.putb(vertexArray, x);
-        if(vComps>1) 
-            GLBuffers.putb(vertexArray, y);
-        padding(VERTEX, vComps-2);
+            Buffers.putNb(vertexArray, vDataTypeSigned, x, true);
+        if(vComps>1)
+            Buffers.putNb(vertexArray, vDataTypeSigned, y, true);
+        countAndPadding(VERTEX, vComps-2);
     }
     public void glVertex3b(byte x, byte y, byte z) {
         checkSeal(false);
-        growBufferIfNecessary(VERTEX, 3);
-        if(vComps>0) 
-            GLBuffers.putb(vertexArray, x);
-        if(vComps>1) 
-            GLBuffers.putb(vertexArray, y);
-        if(vComps>2) 
-            GLBuffers.putb(vertexArray, z);
-        padding(VERTEX, vComps-3);
+        growBuffer(VERTEX);
+        if(vComps>0)
+            Buffers.putNb(vertexArray, vDataTypeSigned, x, true);
+        if(vComps>1)
+            Buffers.putNb(vertexArray, vDataTypeSigned, y, true);
+        if(vComps>2)
+            Buffers.putNb(vertexArray, vDataTypeSigned, z, true);
+        countAndPadding(VERTEX, vComps-3);
     }
     public void glVertex2s(short x, short y) {
         checkSeal(false);
-        growBufferIfNecessary(VERTEX, 2);
-        if(vComps>0) 
-            GLBuffers.puts(vertexArray, x);
+        growBuffer(VERTEX);
+        if(vComps>0)
+            Buffers.putNs(vertexArray, vDataTypeSigned, x, true);
         if(vComps>1) 
-            GLBuffers.puts(vertexArray, y);
-        padding(VERTEX, vComps-2);
+            Buffers.putNs(vertexArray, vDataTypeSigned, y, true);
+        countAndPadding(VERTEX, vComps-2);
     }
     public void glVertex3s(short x, short y, short z) {
         checkSeal(false);
-        growBufferIfNecessary(VERTEX, 3);
-        if(vComps>0) 
-            GLBuffers.puts(vertexArray, x);
+        growBuffer(VERTEX);
+        if(vComps>0)
+            Buffers.putNs(vertexArray, vDataTypeSigned, x, true);
         if(vComps>1) 
-            GLBuffers.puts(vertexArray, y);
+            Buffers.putNs(vertexArray, vDataTypeSigned, y, true);
         if(vComps>2) 
-            GLBuffers.puts(vertexArray, z);
-        padding(VERTEX, vComps-3);
+            Buffers.putNs(vertexArray, vDataTypeSigned, z, true);
+        countAndPadding(VERTEX, vComps-3);
     }
     public void glVertex2f(float x, float y) {
         checkSeal(false);
-        growBufferIfNecessary(VERTEX, 2);
+        growBuffer(VERTEX);
         if(vComps>0) 
-            GLBuffers.putf(vertexArray, x);
-        if(vComps>1) 
-            GLBuffers.putf(vertexArray, y);
-        padding(VERTEX, vComps-2);
+            Buffers.putNf(vertexArray, vDataTypeSigned, x);
+        if(vComps>1)
+            Buffers.putNf(vertexArray, vDataTypeSigned, y);
+        countAndPadding(VERTEX, vComps-2);
     }
     public void glVertex3f(float x, float y, float z) {
         checkSeal(false);
-        growBufferIfNecessary(VERTEX, 3);
+        growBuffer(VERTEX);
         if(vComps>0) 
-            GLBuffers.putf(vertexArray, x);
-        if(vComps>1) 
-            GLBuffers.putf(vertexArray, y);
+            Buffers.putNf(vertexArray, vDataTypeSigned, x);
+        if(vComps>1)
+            Buffers.putNf(vertexArray, vDataTypeSigned, y);
         if(vComps>2) 
-            GLBuffers.putf(vertexArray, z);
-        padding(VERTEX, vComps-3);
+            Buffers.putNf(vertexArray, vDataTypeSigned, z);
+        countAndPadding(VERTEX, vComps-3);
     }
 
     public void glNormal3b(byte x, byte y, byte z) {
         checkSeal(false);
-        growBufferIfNecessary(NORMAL, 3);
-        if(nComps>0) 
-            GLBuffers.putb(normalArray, x);
+        growBuffer(NORMAL);
+        if(nComps>0)             
+            Buffers.putNb(normalArray, nDataTypeSigned, x, true);
         if(nComps>1) 
-            GLBuffers.putb(normalArray, y);
+            Buffers.putNb(normalArray, nDataTypeSigned, y, true);
         if(nComps>2) 
-            GLBuffers.putb(normalArray, z);
-        padding(NORMAL, nComps-3);
+            Buffers.putNb(normalArray, nDataTypeSigned, z, true);
+        countAndPadding(NORMAL, nComps-3);
     }
     public void glNormal3s(short x, short y, short z) {
         checkSeal(false);
-        growBufferIfNecessary(NORMAL, 3);
+        growBuffer(NORMAL);
         if(nComps>0) 
-            GLBuffers.puts(normalArray, x);
+            Buffers.putNs(normalArray, nDataTypeSigned, x, true);
         if(nComps>1) 
-            GLBuffers.puts(normalArray, y);
+            Buffers.putNs(normalArray, nDataTypeSigned, y, true);
         if(nComps>2) 
-            GLBuffers.puts(normalArray, z);
-        padding(NORMAL, nComps-3);
+            Buffers.putNs(normalArray, nDataTypeSigned, z, true);
+        countAndPadding(NORMAL, nComps-3);
     }
     public void glNormal3f(float x, float y, float z) {
         checkSeal(false);
-        growBufferIfNecessary(NORMAL, 3);
+        growBuffer(NORMAL);
         if(nComps>0) 
-            GLBuffers.putf(normalArray, x);
-        if(nComps>1) 
-            GLBuffers.putf(normalArray, y);
+            Buffers.putNf(normalArray, nDataTypeSigned, x);
+        if(nComps>1)
+            Buffers.putNf(normalArray, nDataTypeSigned, y);
         if(nComps>2) 
-            GLBuffers.putf(normalArray, z);
-        padding(NORMAL, nComps-3);
+            Buffers.putNf(normalArray, nDataTypeSigned, z);
+        countAndPadding(NORMAL, nComps-3);
     }
 
     public void glColor3b(byte r, byte g, byte b) {
         checkSeal(false);
-        growBufferIfNecessary(COLOR, 3);
+        growBuffer(COLOR);
+        if(cComps>0) 
+            Buffers.putNb(colorArray, cDataTypeSigned, r, true);
+        if(cComps>1) 
+            Buffers.putNb(colorArray, cDataTypeSigned, g, true);
+        if(cComps>2) 
+            Buffers.putNb(colorArray, cDataTypeSigned, b, true);
+        countAndPadding(COLOR, cComps-3);
+    }
+    public void glColor3ub(byte r, byte g, byte b) {
+        checkSeal(false);
+        growBuffer(COLOR);
         if(cComps>0) 
-            GLBuffers.putb(colorArray, r);
+            Buffers.putNb(colorArray, cDataTypeSigned, r, false);
         if(cComps>1) 
-            GLBuffers.putb(colorArray, g);
+            Buffers.putNb(colorArray, cDataTypeSigned, g, false);
         if(cComps>2) 
-            GLBuffers.putb(colorArray, b);
-        padding(COLOR, cComps-3);
+            Buffers.putNb(colorArray, cDataTypeSigned, b, false);
+        countAndPadding(COLOR, cComps-3);
     }
     public void glColor4b(byte r, byte g, byte b, byte a) {
         checkSeal(false);
-        growBufferIfNecessary(COLOR, 4);
+        growBuffer(COLOR);
         if(cComps>0) 
-            GLBuffers.putb(colorArray, r);
+            Buffers.putNb(colorArray, cDataTypeSigned, r, true);
         if(cComps>1) 
-            GLBuffers.putb(colorArray, g);
+            Buffers.putNb(colorArray, cDataTypeSigned, g, true);
         if(cComps>2) 
-            GLBuffers.putb(colorArray, b);
+            Buffers.putNb(colorArray, cDataTypeSigned, b, true);
         if(cComps>3) 
-            GLBuffers.putb(colorArray, a);
-        padding(COLOR, cComps-4);
+            Buffers.putNb(colorArray, cDataTypeSigned, a, true);
+        countAndPadding(COLOR, cComps-4);
+    }
+    public void glColor4ub(byte r, byte g, byte b, byte a) {
+        checkSeal(false);
+        growBuffer(COLOR);
+        if(cComps>0) 
+            Buffers.putNb(colorArray, cDataTypeSigned, r, false);
+        if(cComps>1) 
+            Buffers.putNb(colorArray, cDataTypeSigned, g, false);
+        if(cComps>2) 
+            Buffers.putNb(colorArray, cDataTypeSigned, b, false);
+        if(cComps>3) 
+            Buffers.putNb(colorArray, cDataTypeSigned, a, false);
+        countAndPadding(COLOR, cComps-4);
     }
     public void glColor3s(short r, short g, short b) {
         checkSeal(false);
-        growBufferIfNecessary(COLOR, 3);
+        growBuffer(COLOR);
         if(cComps>0) 
-            GLBuffers.puts(colorArray, r);
+            Buffers.putNs(colorArray, cDataTypeSigned, r, true);
         if(cComps>1) 
-            GLBuffers.puts(colorArray, g);
+            Buffers.putNs(colorArray, cDataTypeSigned, g, true);
         if(cComps>2) 
-            GLBuffers.puts(colorArray, b);
-        padding(COLOR, cComps-3);
+            Buffers.putNs(colorArray, cDataTypeSigned, b, true);
+        countAndPadding(COLOR, cComps-3);
     }
     public void glColor4s(short r, short g, short b, short a) {
         checkSeal(false);
-        growBufferIfNecessary(COLOR, 4);
+        growBuffer(COLOR);
         if(cComps>0) 
-            GLBuffers.puts(colorArray, r);
+            Buffers.putNs(colorArray, cDataTypeSigned, r, true);
         if(cComps>1) 
-            GLBuffers.puts(colorArray, g);
+            Buffers.putNs(colorArray, cDataTypeSigned, g, true);
         if(cComps>2) 
-            GLBuffers.puts(colorArray, b);
+            Buffers.putNs(colorArray, cDataTypeSigned, b, true);
         if(cComps>3) 
-            GLBuffers.puts(colorArray, a);
-        padding(COLOR, cComps-4);
+            Buffers.putNs(colorArray, cDataTypeSigned, a, true);
+        countAndPadding(COLOR, cComps-4);
     }
     public void glColor3f(float r, float g, float b) {
         checkSeal(false);
-        growBufferIfNecessary(COLOR, 3);
+        growBuffer(COLOR);
         if(cComps>0) 
-            GLBuffers.putf(colorArray, r);
+            Buffers.putNf(colorArray, cDataTypeSigned, r);
         if(cComps>1) 
-            GLBuffers.putf(colorArray, g);
+            Buffers.putNf(colorArray, cDataTypeSigned, g);
         if(cComps>2) 
-            GLBuffers.putf(colorArray, b);
-        padding(COLOR, cComps-3);
+            Buffers.putNf(colorArray, cDataTypeSigned, b);
+        countAndPadding(COLOR, cComps-3);
     }
     public void glColor4f(float r, float g, float b, float a) {
         checkSeal(false);
-        growBufferIfNecessary(COLOR, 4);
+        growBuffer(COLOR);
         if(cComps>0) 
-            GLBuffers.putf(colorArray, r);
+            Buffers.putNf(colorArray, cDataTypeSigned, r);
         if(cComps>1) 
-            GLBuffers.putf(colorArray, g);
+            Buffers.putNf(colorArray, cDataTypeSigned, g);
         if(cComps>2) 
-            GLBuffers.putf(colorArray, b);
+            Buffers.putNf(colorArray, cDataTypeSigned, b);
         if(cComps>3) 
-            GLBuffers.putf(colorArray, a);
-        padding(COLOR, cComps-4);
+            Buffers.putNf(colorArray, cDataTypeSigned, a);
+        countAndPadding(COLOR, cComps-4);
     }
 
     public void glTexCoord2b(byte x, byte y) {
         checkSeal(false);
-        growBufferIfNecessary(TEXTCOORD, 2);
+        growBuffer(TEXTCOORD);
         if(tComps>0) 
-            GLBuffers.putb(textCoordArray, x);
+            Buffers.putNb(textCoordArray, tDataTypeSigned, x, true);
         if(tComps>1) 
-            GLBuffers.putb(textCoordArray, y);
-        padding(TEXTCOORD, tComps-2);
+            Buffers.putNb(textCoordArray, tDataTypeSigned, y, true);
+        countAndPadding(TEXTCOORD, tComps-2);
     }
     public void glTexCoord3b(byte x, byte y, byte z) {
         checkSeal(false);
-        growBufferIfNecessary(TEXTCOORD, 3);
+        growBuffer(TEXTCOORD);
         if(tComps>0) 
-            GLBuffers.putb(textCoordArray, x);
+            Buffers.putNb(textCoordArray, tDataTypeSigned, x, true);
         if(tComps>1) 
-            GLBuffers.putb(textCoordArray, y);
+            Buffers.putNb(textCoordArray, tDataTypeSigned, y, true);
         if(tComps>2) 
-            GLBuffers.putb(textCoordArray, z);
-        padding(TEXTCOORD, tComps-3);
+            Buffers.putNb(textCoordArray, tDataTypeSigned, z, true);
+        countAndPadding(TEXTCOORD, tComps-3);
     }
     public void glTexCoord2s(short x, short y) {
         checkSeal(false);
-        growBufferIfNecessary(TEXTCOORD, 2);
+        growBuffer(TEXTCOORD);
         if(tComps>0) 
-            GLBuffers.puts(textCoordArray, x);
+            Buffers.putNs(textCoordArray, tDataTypeSigned, x, true);
         if(tComps>1) 
-            GLBuffers.puts(textCoordArray, y);
-        padding(TEXTCOORD, tComps-2);
+            Buffers.putNs(textCoordArray, tDataTypeSigned, y, true);
+        countAndPadding(TEXTCOORD, tComps-2);
     }
     public void glTexCoord3s(short x, short y, short z) {
         checkSeal(false);
-        growBufferIfNecessary(TEXTCOORD, 3);
+        growBuffer(TEXTCOORD);
         if(tComps>0) 
-            GLBuffers.puts(textCoordArray, x);
+            Buffers.putNs(textCoordArray, tDataTypeSigned, x, true);
         if(tComps>1) 
-            GLBuffers.puts(textCoordArray, y);
+            Buffers.putNs(textCoordArray, tDataTypeSigned, y, true);
         if(tComps>2) 
-            GLBuffers.puts(textCoordArray, z);
-        padding(TEXTCOORD, tComps-3);
+            Buffers.putNs(textCoordArray, tDataTypeSigned, z, true);
+        countAndPadding(TEXTCOORD, tComps-3);
     }
     public void glTexCoord2f(float x, float y) {
         checkSeal(false);
-        growBufferIfNecessary(TEXTCOORD, 2);
+        growBuffer(TEXTCOORD);
         if(tComps>0) 
-            GLBuffers.putf(textCoordArray, x);
+            Buffers.putNf(textCoordArray, tDataTypeSigned, x);
         if(tComps>1) 
-            GLBuffers.putf(textCoordArray, y);
-        padding(TEXTCOORD, tComps-2);
+            Buffers.putNf(textCoordArray, tDataTypeSigned, y);
+        countAndPadding(TEXTCOORD, tComps-2);
     }
     public void glTexCoord3f(float x, float y, float z) {
         checkSeal(false);
-        growBufferIfNecessary(TEXTCOORD, 3);
+        growBuffer(TEXTCOORD);
         if(tComps>0) 
-            GLBuffers.putf(textCoordArray, x);
+            Buffers.putNf(textCoordArray, tDataTypeSigned, x);
         if(tComps>1) 
-            GLBuffers.putf(textCoordArray, y);
+            Buffers.putNf(textCoordArray, tDataTypeSigned, y);
         if(tComps>2) 
-            GLBuffers.putf(textCoordArray, z);
-        padding(TEXTCOORD, tComps-3);
+            Buffers.putNf(textCoordArray, tDataTypeSigned, z);
+        countAndPadding(TEXTCOORD, tComps-3);
     }
 
     public void rewind() {
@@ -629,10 +791,10 @@ public class ImmModeSink {
     public void destroy(GL gl) {
         reset(gl);
 
+        vCount=0; cCount=0; nCount=0; tCount=0;
         vertexArray=null; colorArray=null; normalArray=null; textCoordArray=null;
         vArrayData=null; cArrayData=null; nArrayData=null; tArrayData=null;
         buffer=null;
-        bSize=0; count=0;
     }
 
     public void reset(GL gl) {
@@ -649,8 +811,13 @@ public class ImmModeSink {
         this.mode = 0;
         this.modeOrig = 0;
         this.sealed=false;
+        this.sealedGL=false;
         this.bufferEnabled=false;
         this.bufferWritten=false;
+        this.vElems=0;
+        this.cElems=0;
+        this.nElems=0;
+        this.tElems=0;        
     }
 
     public void seal(GL glObj, boolean seal)
@@ -660,19 +827,25 @@ public class ImmModeSink {
         sealedGL = seal;
         GL gl = glObj.getGL();
         if(seal) {
-            if(vboUsage && vboName==0) {
-                int[] tmp = new int[1];
-                gl.glGenBuffers(1, tmp, 0);
-                vboName = tmp[0];
+            if(useVBO) {
+                if(0 == vboName) {
+                    int[] tmp = new int[1];
+                    gl.glGenBuffers(1, tmp, 0);
+                    vboName = tmp[0];
+                }
+                if(null!=vArrayData) {
+                    vArrayData.setVBOName(vboName);
+                }
+                if(null!=cArrayData) {
+                    cArrayData.setVBOName(vboName);
+                }
+                if(null!=nArrayData) {
+                    nArrayData.setVBOName(vboName);
+                }
+                if(null!=tArrayData) {
+                    tArrayData.setVBOName(vboName);
+                }
             }
-            if(null!=vArrayData)
-                vArrayData.setVBOName(vboName);
-            if(null!=cArrayData)
-                cArrayData.setVBOName(vboName);
-            if(null!=nArrayData)
-                nArrayData.setVBOName(vboName);
-            if(null!=tArrayData)
-                tArrayData.setVBOName(vboName);
             enableBuffer(gl, true);
         } else {
             enableBuffer(gl, false);
@@ -685,68 +858,114 @@ public class ImmModeSink {
         sealed = seal;
         if(seal) {
             bufferWritten=false;
+            rewind();
         }
     }
 
   public void enableBuffer(GL gl, boolean enable) {
-    /* if(enableBufferAlways && enable) {
-        bufferEnabled = false;
-    } */
-    if( bufferEnabled != enable && count>0 ) {
+    if( bufferEnabled != enable && vElems>0 ) {
         if(enable) {
             checkSeal(true);
         }
+        bufferEnabled = enable;
         if(useGLSL) { 
             enableBufferGLSL(gl, enable);
         } else {
             enableBufferFixed(gl, enable);
         }
-        bufferEnabled = enable;
     }
   }
 
+  private final void writeBuffer(GL gl) {
+    final int vBytes  = vElems * vCompsBytes;
+    final int cBytes  = cElems * cCompsBytes;
+    final int nBytes  = nElems * nCompsBytes;
+    final int tBytes  = tElems * tCompsBytes;
+    final int delta = buffer.limit() - (vBytes+cBytes+nBytes+tBytes);
+    if( bufferWrittenOnce && delta > pageSize ) {
+        if(0 < vBytes) {
+            gl.glBufferSubData(GL.GL_ARRAY_BUFFER, vOffset, vBytes, vertexArray);
+        }
+        if(0 < cBytes) {
+            gl.glBufferSubData(GL.GL_ARRAY_BUFFER, cOffset, cBytes, colorArray);
+        }
+        if(0 < nBytes) {
+            gl.glBufferSubData(GL.GL_ARRAY_BUFFER, nOffset, nBytes, normalArray);
+        }
+        if(0 < tBytes) {
+            gl.glBufferSubData(GL.GL_ARRAY_BUFFER, tOffset, tBytes, textCoordArray);
+        }
+    } else {
+        gl.glBufferData(GL.GL_ARRAY_BUFFER, buffer.limit(), buffer, glBufferUsage);
+        bufferWrittenOnce = true;                    
+    }                      
+  }
+  
   public void enableBufferFixed(GL gl, boolean enable) {
     GL2ES1 glf = gl.getGL2ES1();
+    
+    final boolean useV = vComps>0 && vElems>0 ;
+    final boolean useC = cComps>0 && cElems>0 ;
+    final boolean useN = nComps>0 && nElems>0 ;
+    final boolean useT = tComps>0 && tElems>0 ;
+    
+    if(DEBUG_DRAW) {
+        System.err.println("ImmModeSink.enableFixed.0 "+enable+": use [ v "+useV+", c "+useC+", n "+useN+", t "+useT+"], "+getElemUseCountStr()+", "+buffer);        
+    }
 
     if(enable) {
-        gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vboName);
-
-        if(!bufferWritten) {
-            gl.glBufferData(GL.GL_ARRAY_BUFFER, buffer.limit(), buffer, GL.GL_STATIC_DRAW);
-            bufferWritten=true;
+        if(useVBO) {
+            if(0 == vboName) {
+                throw new InternalError("Using VBO but no vboName");
+            }
+            glf.glBindBuffer(GL.GL_ARRAY_BUFFER, vboName);
+            
+            if(!bufferWritten) {
+                writeBuffer(gl);
+            }
         }
+        bufferWritten=true;
+    }
 
-        if(vComps>0) {
+    if(useV) {
+       if(enable) {
            glf.glEnableClientState(GLPointerFunc.GL_VERTEX_ARRAY);
            glf.glVertexPointer(vArrayData);
-        }
-        if(cComps>0) {
+       } else {
+           glf.glDisableClientState(GLPointerFunc.GL_VERTEX_ARRAY);               
+       }
+    }
+    if(useC) {
+       if(enable) {
            glf.glEnableClientState(GLPointerFunc.GL_COLOR_ARRAY);
            glf.glColorPointer(cArrayData);
-        }
-        if(nComps>0) {
+       } else {
+           glf.glDisableClientState(GLPointerFunc.GL_COLOR_ARRAY);
+       }
+    }
+    if(useN) {
+       if(enable) {
            glf.glEnableClientState(GLPointerFunc.GL_NORMAL_ARRAY);
            glf.glNormalPointer(nArrayData);
-        }
-        if(tComps>0) {
+       } else {
+           glf.glDisableClientState(GLPointerFunc.GL_NORMAL_ARRAY);
+       }
+    }
+    if(useT) {
+       if(enable) {
            glf.glEnableClientState(GLPointerFunc.GL_TEXTURE_COORD_ARRAY);
            glf.glTexCoordPointer(tArrayData);
-        }
+       } else {
+           glf.glDisableClientState(GLPointerFunc.GL_TEXTURE_COORD_ARRAY);
+       }
+    }
 
+    if(enable && useVBO) {
         gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
-    } else {
-        if(vComps>0) {
-           glf.glDisableClientState(GLPointerFunc.GL_VERTEX_ARRAY);
-        }
-        if(cComps>0) {
-           glf.glDisableClientState(GLPointerFunc.GL_COLOR_ARRAY);
-        }
-        if(nComps>0) {
-           glf.glDisableClientState(GLPointerFunc.GL_NORMAL_ARRAY);
-        }
-        if(tComps>0) {
-           glf.glDisableClientState(GLPointerFunc.GL_TEXTURE_COORD_ARRAY);
-        }
+    }
+    
+    if(DEBUG_DRAW) {
+        System.err.println("ImmModeSink.enableFixed.X ");        
     }
   }
 
@@ -757,54 +976,79 @@ public class ImmModeSink {
     }      
     GL2ES2 glsl = gl.getGL2ES2();
  
+    final boolean useV = vComps>0 && vElems>0 ;
+    final boolean useC = cComps>0 && cElems>0 ;
+    final boolean useN = nComps>0 && nElems>0 ;
+    final boolean useT = tComps>0 && tElems>0 ;
+    
+    if(DEBUG_DRAW) {
+        System.err.println("ImmModeSink.enableGLSL.0 "+enable+": use [ v "+useV+", c "+useC+", n "+useN+", t "+useT+"], "+getElemUseCountStr()+", "+buffer);        
+    }
+    
     if(enable) {
-        glsl.glBindBuffer(GL.GL_ARRAY_BUFFER, vboName);
-
-        if(!bufferWritten) {
-            glsl.glBufferData(GL.GL_ARRAY_BUFFER, buffer.limit(), buffer, GL.GL_STATIC_DRAW);
-            bufferWritten=true;
+        if(useVBO) {
+            if(0 == vboName) {
+                throw new InternalError("Using VBO but no vboName");
+            }
+            glsl.glBindBuffer(GL.GL_ARRAY_BUFFER, vboName);
+            if(!bufferWritten) {
+                writeBuffer(gl);
+            }
         }
+        bufferWritten=true;
+    }
 
-        if(vComps>0) {
+    if(useV) {
+       if(enable) {
            st.enableVertexAttribArray(glsl, vArrayData);
            st.vertexAttribPointer(glsl, vArrayData);
-        }
-        if(cComps>0) {
+       } else {
+           st.disableVertexAttribArray(glsl, vArrayData);
+       }
+    }
+    if(useC) {
+       if(enable) {
            st.enableVertexAttribArray(glsl, cArrayData);
            st.vertexAttribPointer(glsl, cArrayData);
-        }
-        if(nComps>0) {
+       } else {
+           st.disableVertexAttribArray(glsl, cArrayData);
+       }
+    }
+    if(useN) {
+       if(enable) {
            st.enableVertexAttribArray(glsl, nArrayData);
            st.vertexAttribPointer(glsl, nArrayData);
-        }
-        if(tComps>0) {
+       } else {
+           st.disableVertexAttribArray(glsl, nArrayData);
+       }
+    }
+    if(useT) {
+       if(enable) {
            st.enableVertexAttribArray(glsl, tArrayData);
            st.vertexAttribPointer(glsl, tArrayData);
-        }
-
-        glsl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
-    } else {
-        if(vComps>0) {
-           st.disableVertexAttribArray(glsl, vArrayData);
-        }
-        if(cComps>0) {
-           st.disableVertexAttribArray(glsl, cArrayData);
-        }
-        if(nComps>0) {
-           st.disableVertexAttribArray(glsl, nArrayData);
-        }
-        if(tComps>0) {
+       } else {
            st.disableVertexAttribArray(glsl, tArrayData);
-        }
+       }
+    }
+    
+    if(enable && useVBO) {
+        glsl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
+    }
+    
+    if(DEBUG_DRAW) {
+        System.err.println("ImmModeSink.enableGLSL.X ");        
     }
   }
 
     public String toString() {
         return "VBOSet[mode "+mode+ 
                        ", modeOrig "+modeOrig+ 
+                       ", use/count "+getElemUseCountStr()+
                        ", sealed "+sealed+ 
+                       ", sealedGL "+sealedGL+
                        ", bufferEnabled "+bufferEnabled+ 
-                       ", bufferWritten "+bufferWritten+ 
+                       ", bufferWritten "+bufferWritten+" (once "+bufferWrittenOnce+")"+
+                       ", useVBO "+useVBO+", vboName "+vboName+
                        ",\n\t"+vArrayData+
                        ",\n\t"+cArrayData+
                        ",\n\t"+nArrayData+
@@ -814,165 +1058,236 @@ public class ImmModeSink {
 
     // non public matters
 
-    protected void allocateBuffer(int elementCount) {
-        int vWidth = vComps * GLBuffers.sizeOfGLType(vDataType);
-        int cWidth = cComps * GLBuffers.sizeOfGLType(cDataType);
-        int nWidth = nComps * GLBuffers.sizeOfGLType(nDataType);
-        int tWidth = tComps * GLBuffers.sizeOfGLType(tDataType);
-
-        count  = elementCount;
-        bSize  = count * ( vWidth + cWidth + nWidth + tWidth ) ;
-
-        buffer = GLBuffers.newDirectByteBuffer(bSize);
-
-        int pos = 0;
-        int size= count * vWidth ;
-        if(size>0) {
-            vertexArray = GLBuffers.sliceGLBuffer(buffer, pos, size, vDataType);
+    protected String getElemUseCountStr() {
+        return "[v "+vElems+"/"+vCount+", c "+cElems+"/"+cCount+", n "+nElems+"/"+nCount+", t "+tElems+"/"+tCount+"]";
+    }
+    
+    protected boolean fitElementInBuffer(int type) {
+        final int addElems = 1;
+        switch (type) {
+            case VERTEX:
+                return ( vCount - vElems ) >= addElems ;
+            case COLOR:
+                return ( cCount - cElems ) >= addElems ;
+            case NORMAL:
+                return ( nCount - nElems ) >= addElems ;
+            case TEXTCOORD:
+                return ( tCount - tElems ) >= addElems ;
+            default:
+                throw new InternalError("XXX");
+        }
+    }
+    
+    protected boolean reallocateBuffer(int addElems) {
+        final int vAdd = addElems - ( vCount - vElems );
+        final int cAdd = addElems - ( cCount - cElems );
+        final int nAdd = addElems - ( nCount - nElems );
+        final int tAdd = addElems - ( tCount - tElems );
+        
+        if( 0>=vAdd && 0>=cAdd && 0>=nAdd && 0>=tAdd) {
+            if(DEBUG_BUFFER) {
+                System.err.println("ImmModeSink.realloc: "+getElemUseCountStr()+" + "+addElems+" -> NOP");
+            }
+            return false;
+        }
+        
+        if(DEBUG_BUFFER) {
+            System.err.println("ImmModeSink.realloc: "+getElemUseCountStr()+" + "+addElems);
+        }
+        vCount += vAdd;
+        cCount += cAdd;
+        nCount += nAdd;
+        tCount += tAdd;
+        
+        final int vBytes  = vCount * vCompsBytes;
+        final int cBytes  = cCount * cCompsBytes;
+        final int nBytes  = nCount * nCompsBytes;
+        final int tBytes  = tCount * tCompsBytes;
+        
+        buffer = Buffers.newDirectByteBuffer( vBytes + cBytes + nBytes + tBytes );
+        vOffset = 0;
+        
+        if(vBytes>0) {
+            vertexArray = GLBuffers.sliceGLBuffer(buffer, vOffset, vBytes, vDataType);
         } else {
             vertexArray = null;
-        }
-        vOffset = pos;
-        pos+=size;
+        }        
+        cOffset=vOffset+vBytes;
 
-        size= count * cWidth ;
-        if(size>0) {
-            colorArray = GLBuffers.sliceGLBuffer(buffer, pos, size, cDataType);
+        if(cBytes>0) {
+            colorArray = GLBuffers.sliceGLBuffer(buffer, cOffset, cBytes, cDataType);
         } else {
             colorArray = null;
         }
-        cOffset = pos;
-        pos+=size;
+        nOffset=cOffset+cBytes;
 
-        size= count * nWidth ;
-        if(size>0) {
-            normalArray = GLBuffers.sliceGLBuffer(buffer, pos, size, nDataType);
+        if(nBytes>0) {
+            normalArray = GLBuffers.sliceGLBuffer(buffer, nOffset, nBytes, nDataType);
         } else {
             normalArray = null;
         }
-        nOffset = pos;
-        pos+=size;
+        tOffset=nOffset+nBytes;
 
-        size= count * tWidth ;
-        if(size>0) {
-            textCoordArray = GLBuffers.sliceGLBuffer(buffer, pos, size, tDataType);
+        if(tBytes>0) {
+            textCoordArray = GLBuffers.sliceGLBuffer(buffer, tOffset, tBytes, tDataType);
         } else {
             textCoordArray = null;
         }
-        tOffset = pos;
-        pos+=size;
 
-        buffer.position(pos);
+        buffer.position(tOffset+tBytes);
         buffer.flip();
 
         if(vComps>0) {
-            vArrayData = GLArrayDataWrapper.createFixed(GLPointerFunc.GL_VERTEX_ARRAY, vComps, vDataType, false, 0,
+            vArrayData = GLArrayDataWrapper.createFixed(GLPointerFunc.GL_VERTEX_ARRAY, vComps, 
+                                                        vDataType, GLBuffers.isGLTypeFixedPoint(vDataType), 0,
                                                         vertexArray, 0, vOffset, GL.GL_STATIC_DRAW, GL.GL_ARRAY_BUFFER);
         } else {
             vArrayData = null;
         }
         if(cComps>0) {
-            cArrayData = GLArrayDataWrapper.createFixed(GLPointerFunc.GL_COLOR_ARRAY, cComps, cDataType, false, 0,
+            cArrayData = GLArrayDataWrapper.createFixed(GLPointerFunc.GL_COLOR_ARRAY, cComps, 
+                                                        cDataType, GLBuffers.isGLTypeFixedPoint(cDataType), 0,
                                                         colorArray, 0, cOffset, GL.GL_STATIC_DRAW, GL.GL_ARRAY_BUFFER);
         } else {
             cArrayData = null;
         }
         if(nComps>0) {
-            nArrayData = GLArrayDataWrapper.createFixed(GLPointerFunc.GL_NORMAL_ARRAY, nComps, nDataType, false, 0,
+            nArrayData = GLArrayDataWrapper.createFixed(GLPointerFunc.GL_NORMAL_ARRAY, nComps, 
+                                                        nDataType, GLBuffers.isGLTypeFixedPoint(nDataType), 0,
                                                         normalArray, 0, nOffset, GL.GL_STATIC_DRAW, GL.GL_ARRAY_BUFFER);
         } else {
             nArrayData = null;
         }
         if(tComps>0) {
-            tArrayData = GLArrayDataWrapper.createFixed(GLPointerFunc.GL_TEXTURE_COORD_ARRAY, tComps, tDataType, false, 0,
+            tArrayData = GLArrayDataWrapper.createFixed(GLPointerFunc.GL_TEXTURE_COORD_ARRAY, tComps, 
+                                                        tDataType, GLBuffers.isGLTypeFixedPoint(tDataType), 0,
                                                         textCoordArray, 0, tOffset, GL.GL_STATIC_DRAW, GL.GL_ARRAY_BUFFER);
         } else {
             tArrayData = null;
         }
-
-    }
-
-    protected final boolean growBufferIfNecessary(int type, int spare) {
-        if(buffer==null || count < spare) { 
-            growBuffer(type, initialElementCount);
-            return true;
+        
+        bufferWrittenOnce = false; // new buffer data storage size!
+        
+        if(DEBUG_BUFFER) {
+            System.err.println("ImmModeSink.realloc.X: "+this.toString());
+            Thread.dumpStack();
         }
-        return false;
+        return true;
     }
 
-    protected final void growBuffer(int type, int additional) {
-        if(sealed || 0==additional) return;
-
-        // save olde values ..
-        Buffer _vertexArray=vertexArray, _colorArray=colorArray, _normalArray=normalArray, _textCoordArray=textCoordArray;
-
-        allocateBuffer(count+additional);
-
-        if(null!=_vertexArray) {
-            _vertexArray.flip();
-            GLBuffers.put(vertexArray, _vertexArray);
-        }
-        if(null!=_colorArray) {
-            _colorArray.flip();
-            GLBuffers.put(colorArray, _colorArray);
-        }
-        if(null!=_normalArray) {
-            _normalArray.flip();
-            GLBuffers.put(normalArray, _normalArray);
-        }
-        if(null!=_textCoordArray) {
-            _textCoordArray.flip();
-            GLBuffers.put(textCoordArray, _textCoordArray);
+    /** grow buffer by initialElementCount if there is no space for one more element in the designated buffer */
+    protected final boolean growBuffer(int type) {
+        if( null !=buffer && !sealed ) {
+            if( !fitElementInBuffer(type) ) {
+                // save olde values ..
+                final Buffer _vertexArray=vertexArray, _colorArray=colorArray, _normalArray=normalArray, _textCoordArray=textCoordArray;
+        
+                if ( reallocateBuffer(resizeElementCount) ) {
+                    if(null!=_vertexArray) {
+                        _vertexArray.flip();
+                        Buffers.put(vertexArray, _vertexArray);
+                    }
+                    if(null!=_colorArray) {
+                        _colorArray.flip();
+                        Buffers.put(colorArray, _colorArray);
+                    }
+                    if(null!=_normalArray) {
+                        _normalArray.flip();
+                        Buffers.put(normalArray, _normalArray);
+                    }
+                    if(null!=_textCoordArray) {
+                        _textCoordArray.flip();
+                        Buffers.put(textCoordArray, _textCoordArray);
+                    }
+                    return true;
+                }
+            }
         }
+        return false;
     }
 
-    protected void padding(int type, int fill) {
+    /**
+     * Fourth element default value for color (alpha), vertex (w) is '1',
+     * as specified w/ VertexAttributes (ES2/GL3).
+     * <p>
+     * vec4 v = vec4(0, 0, 0, 1);
+     * vec4 c = vec4(0, 0, 0, 1);
+     * </p>
+     * 
+     * @param type
+     * @param fill
+     */
+    private void countAndPadding(int type, int fill) {
         if ( sealed ) return;
 
-        Buffer dest = null;
-
+        final Buffer dest;
+        final boolean dSigned;
+        final int e; // either 0 or 1
+                
         switch (type) {
             case VERTEX:
                 dest = vertexArray;
+                dSigned = vDataTypeSigned;
+                e = 4 == vComps ? 1 : 0;
+                vElems++;
                 break;
             case COLOR:
                 dest = colorArray;
+                dSigned = cDataTypeSigned;
+                e = 4 == cComps ? 1 : 0;
+                cElems++;
                 break;
             case NORMAL:
                 dest = normalArray;
+                dSigned = nDataTypeSigned;
+                e = 0;
+                nElems++;
                 break;
             case TEXTCOORD:
                 dest = textCoordArray;
+                dSigned = tDataTypeSigned;
+                e = 0;
+                tElems++;
                 break;
+            default: throw new InternalError("Invalid type "+type);
         }
 
         if ( null==dest ) return;
 
-        while((fill--)>0) {
-            GLBuffers.putb(dest, (byte)0);
+        while( fill > e ) {
+            fill--;
+            Buffers.putNf(dest, dSigned, 0f);            
+        }
+        if( fill > 0 ) { // e == 1, add missing '1f end component'
+            Buffers.putNf(dest, dSigned, 1f);
         }
     }
 
-    protected int mode, modeOrig;
-    protected int glBufferUsage, initialElementCount;
-
-    protected ByteBuffer buffer;
-    protected int bSize, count, vboName;
-
-    public static final int VERTEX = 0;
-    public static final int COLOR = 1;
-    public static final int NORMAL = 2;
-    public static final int TEXTCOORD = 3;
-
-    protected int vOffset, cOffset, nOffset, tOffset;
-    protected int vComps,    cComps,    nComps,    tComps;
-    protected int vDataType, cDataType, nDataType, tDataType;
-    protected Buffer vertexArray, colorArray, normalArray, textCoordArray;
-    protected GLArrayDataWrapper vArrayData, cArrayData, nArrayData, tArrayData;
-
-    protected boolean sealed, sealedGL, useGLSL;
-    protected boolean bufferEnabled, bufferWritten;
-    protected GL gl;
+    final private int glBufferUsage, initialElementCount;
+    final private boolean useVBO;
+    private int mode, modeOrig, resizeElementCount;
+
+    private ByteBuffer buffer;
+    private int vboName;
+
+    private static final int VERTEX = 0;
+    private static final int COLOR = 1;
+    private static final int NORMAL = 2;
+    private static final int TEXTCOORD = 3;
+
+    private int vCount,    cCount,    nCount,    tCount;       // number of elements fit in each buffer 
+    private int vOffset,   cOffset,   nOffset,   tOffset;      // offset of specific array in common buffer
+    private int vElems,    cElems,    nElems,    tElems;       // number of used elements in each buffer
+    private final int vComps,    cComps,    nComps,    tComps; // number of components for each elements [2, 3, 4] 
+    private final int vCompsBytes, cCompsBytes, nCompsBytes, tCompsBytes; // byte size of all components 
+    private final int vDataType, cDataType, nDataType, tDataType;
+    private final boolean vDataTypeSigned, cDataTypeSigned, nDataTypeSigned, tDataTypeSigned;
+    private final int pageSize;
+    private Buffer vertexArray, colorArray, normalArray, textCoordArray;
+    private GLArrayDataWrapper vArrayData, cArrayData, nArrayData, tArrayData;
+
+    private boolean sealed, sealedGL, useGLSL;
+    private boolean bufferEnabled, bufferWritten, bufferWrittenOnce;
   }
 
 }
diff --git a/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java b/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java
index fc6ef3e..80df9cd 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java
@@ -48,12 +48,146 @@ import jogamp.opengl.ProjectFloat;
 
 import com.jogamp.opengl.FloatUtil;
 import com.jogamp.common.nio.Buffers;
-
+import com.jogamp.common.os.Platform;
+
+/**
+ * PMVMatrix implements a subset of the fixed function pipeline
+ * regarding the projection (P), modelview (Mv) matrix operation
+ * which is specified in {@link GLMatrixFunc}.
+ * <p>
+ * Further more, PMVMatrix provides the {@link #glGetMviMatrixf() inverse modelview matrix (Mvi)} and 
+ * {@link #glGetMvitMatrixf() inverse transposed modelview matrix (Mvit)}.
+ * To keep both synchronized after mutable Mv operations like {@link #glRotatef(float, float, float, float) glRotatef(..)}
+ * in {@link #glMatrixMode(int) glMatrixMode}({@link GLMatrixFunc#GL_MODELVIEW GL_MODELVIEW}), 
+ * users have to call {@link #update()} before using Mvi and Mvit. 
+ * </p>
+ * <p>
+ * All matrices are provided in column-major order, 
+ * as specified in the OpenGL fixed function pipeline, i.e. compatibility profile. 
+ * </p>
+ * <p>
+ * PMVMatrix can supplement {@link GL2ES2} applications w/ the 
+ * lack of the described matrix functionality.
+ * </p>
+ * <a name="storageDetails"><h5>Matrix storage details</h5></a> 
+ * <p>
+ * All matrices use a common FloatBuffer storage
+ * and are a {@link Buffers#slice2Float(Buffer, float[], int, int) sliced} representation of it.
+ * The common FloatBuffer and hence all matrices may use NIO direct storage or a {@link #usesBackingArray() backing float array},
+ * depending how the instance if {@link #PMVMatrix(boolean) being constructed}.
+ * </p>
+ * <p>
+ * <b>Note:</b> 
+ * <ul> 
+ *   <li>The matrix is a {@link Buffers#slice2Float(Buffer, float[], int, int) sliced part } of a host matrix and it's start position has been {@link FloatBuffer#mark() marked}.</li>
+ *   <li>Use {@link FloatBuffer#reset() reset()} to rewind it to it's start position after relative operations, like {@link FloatBuffer#get() get()}.</li>
+ *   <li>If using absolute operations like {@link FloatBuffer#get(int) get(int)}, use it's {@link FloatBuffer#reset() reset} {@link FloatBuffer#position() position} as it's offset.</li> 
+ * </ul>
+ * </p>
+ */
 public class PMVMatrix implements GLMatrixFunc {
 
-    protected final float[] matrixBufferArray;
+    /** Bit value stating a modified {@link #glGetPMatrixf() projection matrix (P)}, since last {@link #update()} call. */
+    public static final int MODIFIED_PROJECTION                    = 1 << 0;
+    /** Bit value stating a modified {@link #glGetMvMatrixf() modelview matrix (Mv)}, since last {@link #update()} call. */
+    public static final int MODIFIED_MODELVIEW                     = 1 << 1;
+    /** Bit value stating a modified {@link #glGetTMatrixf() texture matrix (T)}, since last {@link #update()} call. */
+    public static final int MODIFIED_TEXTURE                       = 1 << 2;
+    /** Bit value stating all is modified */
+    public static final int MODIFIED_ALL                           = MODIFIED_PROJECTION | MODIFIED_MODELVIEW | MODIFIED_TEXTURE ;
+    
+    /** Bit value stating a dirty {@link #glGetMviMatrixf() inverse modelview matrix (Mvi)}. */
+    public static final int DIRTY_INVERSE_MODELVIEW             = 1 << 0;
+    /** Bit value stating a dirty {@link #glGetMvitMatrixf() inverse transposed modelview matrix (Mvit)}. */
+    public static final int DIRTY_INVERSE_TRANSPOSED_MODELVIEW  = 1 << 1;    
+    /** Bit value stating all is dirty */
+    public static final int DIRTY_ALL                           = DIRTY_INVERSE_MODELVIEW | DIRTY_INVERSE_TRANSPOSED_MODELVIEW ;
+    
+    /**
+     * @param matrixModeName One of {@link GLMatrixFunc#GL_MODELVIEW GL_MODELVIEW}, {@link GLMatrixFunc#GL_PROJECTION GL_PROJECTION} or {@link GL#GL_TEXTURE GL_TEXTURE}  
+     * @return true if the given matrix-mode name is valid, otherwise false.
+     */                     
+    public static final boolean isMatrixModeName(final int matrixModeName) {
+        switch(matrixModeName) {
+            case GL_MODELVIEW_MATRIX:
+            case GL_PROJECTION_MATRIX:
+            case GL_TEXTURE_MATRIX:
+                return true;
+        }
+        return false;
+    }
 
     /**
+     * @param matrixModeName One of {@link GLMatrixFunc#GL_MODELVIEW GL_MODELVIEW}, {@link GLMatrixFunc#GL_PROJECTION GL_PROJECTION} or {@link GL#GL_TEXTURE GL_TEXTURE}  
+     * @return The corresponding matrix-get name, one of {@link GLMatrixFunc#GL_MODELVIEW_MATRIX GL_MODELVIEW_MATRIX}, {@link GLMatrixFunc#GL_PROJECTION_MATRIX GL_PROJECTION_MATRIX} or {@link GLMatrixFunc#GL_TEXTURE_MATRIX GL_TEXTURE_MATRIX}
+     */                     
+    public static final int matrixModeName2MatrixGetName(final int matrixModeName) {
+        switch(matrixModeName) {
+            case GL_MODELVIEW:
+                return GL_MODELVIEW_MATRIX;
+            case GL_PROJECTION:
+                return GL_PROJECTION_MATRIX;
+            case GL.GL_TEXTURE:
+                return GL_TEXTURE_MATRIX;
+            default:
+              throw new GLException("unsupported matrixName: "+matrixModeName);
+        }
+    }
+
+    /**
+     * @param matrixGetName One of {@link GLMatrixFunc#GL_MODELVIEW_MATRIX GL_MODELVIEW_MATRIX}, {@link GLMatrixFunc#GL_PROJECTION_MATRIX GL_PROJECTION_MATRIX} or {@link GLMatrixFunc#GL_TEXTURE_MATRIX GL_TEXTURE_MATRIX}  
+     * @return true if the given matrix-get name is valid, otherwise false.
+     */                     
+    public static final boolean isMatrixGetName(final int matrixGetName) {
+        switch(matrixGetName) {
+            case GL_MATRIX_MODE:
+            case GL_MODELVIEW_MATRIX:
+            case GL_PROJECTION_MATRIX:
+            case GL_TEXTURE_MATRIX:
+                return true;
+        }
+        return false;
+    }
+
+    /**
+     * @param matrixGetName One of  {@link GLMatrixFunc#GL_MODELVIEW_MATRIX GL_MODELVIEW_MATRIX}, {@link GLMatrixFunc#GL_PROJECTION_MATRIX GL_PROJECTION_MATRIX} or {@link GLMatrixFunc#GL_TEXTURE_MATRIX GL_TEXTURE_MATRIX}
+     * @return The corresponding matrix-mode name, one of {@link GLMatrixFunc#GL_MODELVIEW GL_MODELVIEW}, {@link GLMatrixFunc#GL_PROJECTION GL_PROJECTION} or {@link GL#GL_TEXTURE GL_TEXTURE}
+     */                     
+    public static final int matrixGetName2MatrixModeName(final int matrixGetName) {
+        switch(matrixGetName) {
+            case GL_MODELVIEW_MATRIX:
+                return GL_MODELVIEW;
+            case GL_PROJECTION_MATRIX:
+                return GL_PROJECTION;
+            case GL_TEXTURE_MATRIX:
+                return GL.GL_TEXTURE;
+            default:
+              throw new GLException("unsupported matrixGetName: "+matrixGetName);
+        }
+    }
+    
+    /** 
+     * @param sb optional passed StringBuilder instance to be used
+     * @param f the format string of one floating point, i.e. "%10.5f", see {@link java.util.Formatter}
+     * @param a 4x4 matrix in column major order (OpenGL)
+     * @return matrix string representation
+     */
+    public static StringBuilder matrixToString(StringBuilder sb, String f, FloatBuffer a) {
+        return FloatUtil.matrixToString(sb, null, f, a, 0, 4, 4, false);        
+    }
+    
+    /** 
+     * @param sb optional passed StringBuilder instance to be used
+     * @param f the format string of one floating point, i.e. "%10.5f", see {@link java.util.Formatter}
+     * @param a 4x4 matrix in column major order (OpenGL)
+     * @param b 4x4 matrix in column major order (OpenGL)
+     * @return side by side representation
+     */
+    public static StringBuilder matrixToString(StringBuilder sb, String f, FloatBuffer a, FloatBuffer b) {
+        return FloatUtil.matrixToString(sb, null, f, a, 0, b, 0, 4, 4, false);        
+    }
+    
+    /**
      * Creates an instance of PMVMatrix {@link #PMVMatrix(boolean) PMVMatrix(boolean useBackingArray)},
      * with <code>useBackingArray = true</code>. 
      */
@@ -132,13 +266,16 @@ public class PMVMatrix implements GLMatrixFunc {
           glLoadIdentity();
           glMatrixMode(GL.GL_TEXTURE);
           glLoadIdentity();
-          setDirty();
-          update();
+          modifiedBits = MODIFIED_ALL;
+          dirtyBits = DIRTY_ALL;
+          requestMask = 0;
+          matrixMode = GL_MODELVIEW;
     }
 
+    /** @see #PMVMatrix(boolean) */
     public final boolean usesBackingArray() { return usesBackingArray; }          
     
-    public void destroy() {
+    public final void destroy() {
         if(null!=projectFloat) {
             projectFloat.destroy(); projectFloat=null;
         }
@@ -169,170 +306,156 @@ public class PMVMatrix implements GLMatrixFunc {
         }
     }
 
-
-    public static final boolean isMatrixModeName(final int matrixModeName) {
-        switch(matrixModeName) {
-            case GL_MODELVIEW_MATRIX:
-            case GL_PROJECTION_MATRIX:
-            case GL_TEXTURE_MATRIX:
-                return true;
-        }
-        return false;
-    }
-
-    public static final int matrixModeName2MatrixGetName(final int matrixModeName) {
-        switch(matrixModeName) {
-            case GL_MODELVIEW:
-                return GL_MODELVIEW_MATRIX;
-            case GL_PROJECTION:
-                return GL_PROJECTION_MATRIX;
-            case GL.GL_TEXTURE:
-                return GL_TEXTURE_MATRIX;
-            default:
-              throw new GLException("unsupported matrixName: "+matrixModeName);
-        }
-    }
-
-    public static final boolean isMatrixGetName(final int matrixGetName) {
-        switch(matrixGetName) {
-            case GL_MATRIX_MODE:
-            case GL_MODELVIEW_MATRIX:
-            case GL_PROJECTION_MATRIX:
-            case GL_TEXTURE_MATRIX:
-                return true;
-        }
-        return false;
-    }
-
-    public static final int matrixGetName2MatrixModeName(final int matrixGetName) {
-        switch(matrixGetName) {
-            case GL_MODELVIEW_MATRIX:
-                return GL_MODELVIEW;
-            case GL_PROJECTION_MATRIX:
-                return GL_PROJECTION;
-            case GL_TEXTURE_MATRIX:
-                return GL.GL_TEXTURE;
-            default:
-              throw new GLException("unsupported matrixGetName: "+matrixGetName);
-        }
-    }
-
-    public void setDirty() {
-          modified   = DIRTY_MODELVIEW | DIRTY_PROJECTION | DIRTY_TEXTURE ;
-          matrixMode = GL_MODELVIEW;
-    }
-
-    public int getDirtyBits() {
-        return modified;
-    }
-
-    public boolean isDirty(final int matrixName) {
-        boolean res;
-        switch(matrixName) {
-            case GL_MODELVIEW:
-                res = (modified&DIRTY_MODELVIEW)!=0 ;
-                break;
-            case GL_PROJECTION:
-                res = (modified&DIRTY_PROJECTION)!=0 ;
-                break;
-            case GL.GL_TEXTURE:
-                res = (modified&DIRTY_TEXTURE)!=0 ;
-                break;
-            default:
-              throw new GLException("unsupported matrixName: "+matrixName);
-        }
-        return res;
-    }
-
-    public boolean isDirty() {
-        return modified!=0;
-    }
-
-    /**
-     * Update the derived Mvi, Mvit and Pmv matrices
-     * in case Mv or P has changed.
-     * 
-     * @return
-     */
-    public boolean update() {
-        if(0==modified) return false;
-
-        final int res = modified;
-        if( (res&DIRTY_MODELVIEW)!=0 ) {
-            setMviMvit();
-        }
-        modified=0;
-        return res!=0;
-    }
-
+    
+    /** Returns the current matrix-mode, one of {@link GLMatrixFunc#GL_MODELVIEW GL_MODELVIEW}, {@link GLMatrixFunc#GL_PROJECTION GL_PROJECTION} or {@link GL#GL_TEXTURE GL_TEXTURE}. */
     public final int  glGetMatrixMode() {
         return matrixMode;
     }
 
+    /** 
+     * Returns the {@link GLMatrixFunc#GL_TEXTURE_MATRIX texture matrix} (T).
+     * <p>
+     * See <a href="#storageDetails"> matrix storage details</a>.
+     * </p>
+     */
     public final FloatBuffer glGetTMatrixf() {
         return matrixTex;
     }
 
+    /** 
+     * Returns the {@link GLMatrixFunc#GL_PROJECTION_MATRIX projection matrix} (P).
+     * <p>
+     * See <a href="#storageDetails"> matrix storage details</a>.
+     * </p>
+     */
     public final FloatBuffer glGetPMatrixf() {
         return matrixP;
     }
 
+    /** 
+     * Returns the {@link GLMatrixFunc#GL_MODELVIEW_MATRIX modelview matrix} (Mv).
+     * <p>
+     * See <a href="#storageDetails"> matrix storage details</a>.
+     * </p>
+     */
     public final FloatBuffer glGetMvMatrixf() {
         return matrixMv;
     }
 
-    public final FloatBuffer glGetPMvMviMatrixf() {
-        usesMviMvit |= 1;
-        return matrixPMvMvi;
+    /** 
+     * Returns the inverse {@link GLMatrixFunc#GL_MODELVIEW_MATRIX modelview matrix} (Mvi).
+     * <p>
+     * Method enables the Mvi matrix update, and performs it's update w/o clearing the modified bits.
+     * </p>
+     * <p>
+     * See {@link #update()} and <a href="#storageDetails"> matrix storage details</a>.
+     * </p>
+     * @see #update()
+     * @see #disableMviMvitUpdate()
+     */
+    public final FloatBuffer glGetMviMatrixf() {
+        requestMask |= DIRTY_INVERSE_MODELVIEW ;
+        updateImpl(false);
+        return matrixMvi;
     }
 
+    /** 
+     * Returns the inverse transposed {@link GLMatrixFunc#GL_MODELVIEW_MATRIX modelview matrix} (Mvit).
+     * <p>
+     * Method enables the Mvit matrix update, and performs it's update w/o clearing the modified bits.
+     * </p>
+     * <p>
+     * See {@link #update()} and <a href="#storageDetails"> matrix storage details</a>.
+     * </p>
+     * @see #update()
+     * @see #disableMviMvitUpdate()
+     */
+    public final FloatBuffer glGetMvitMatrixf() {
+        requestMask |= DIRTY_INVERSE_TRANSPOSED_MODELVIEW ;
+        updateImpl(false);
+        return matrixMvit;
+    }
+    
+    /** 
+     * Returns 2 matrices within one FloatBuffer: {@link #glGetPMatrixf() P} and {@link #glGetMvMatrixf() Mv}.  
+     * <p>
+     * See <a href="#storageDetails"> matrix storage details</a>.
+     * </p>
+     */
     public final FloatBuffer glGetPMvMatrixf() {
         return matrixPMv;
     }
 
-    public final FloatBuffer glGetMviMatrixf() {
-        usesMviMvit |= 1;
-        return matrixMvi;
+    /** 
+     * Returns 3 matrices within one FloatBuffer: {@link #glGetPMatrixf() P}, {@link #glGetMvMatrixf() Mv} and {@link #glGetMviMatrixf() Mvi}.  
+     * <p>
+     * Method enables the Mvi matrix update, and performs it's update w/o clearing the modified bits.
+     * </p>
+     * <p>
+     * See {@link #update()} and <a href="#storageDetails"> matrix storage details</a>.
+     * </p>
+     * @see #update()
+     * @see #disableMviMvitUpdate()
+     */
+    public final FloatBuffer glGetPMvMviMatrixf() {
+        requestMask |= DIRTY_INVERSE_MODELVIEW ;
+        updateImpl(false);
+        return matrixPMvMvi;
     }
-
+    
+    /** 
+     * Returns 4 matrices within one FloatBuffer: {@link #glGetPMatrixf() P}, {@link #glGetMvMatrixf() Mv}, {@link #glGetMviMatrixf() Mvi} and {@link #glGetMvitMatrixf() Mvit}.  
+     * <p>
+     * Method enables the Mvi and Mvit matrix update, and performs it's update w/o clearing the modified bits.
+     * </p>
+     * <p>
+     * See {@link #update()} and <a href="#storageDetails"> matrix storage details</a>.
+     * </p>
+     * @see #update()
+     * @see #disableMviMvitUpdate()
+     */
     public final FloatBuffer glGetPMvMvitMatrixf() {
-        usesMviMvit |= 1 | 2;
+        requestMask |= DIRTY_INVERSE_MODELVIEW | DIRTY_INVERSE_TRANSPOSED_MODELVIEW ;
+        updateImpl(false);
         return matrixPMvMvit;
     }
     
-    public final FloatBuffer glGetMvitMatrixf() {
-        usesMviMvit |= 1 | 2;
-        return matrixMvit;
-    }
-    
-   /*
-    * @return the current matrix
-    */
+    /*
+     * @return the matrix of the current matrix-mode
+     */
     public final FloatBuffer glGetMatrixf() {
         return glGetMatrixf(matrixMode);
     }
 
-  /**
-   * @param matrixName GL_MODELVIEW, GL_PROJECTION or GL.GL_TEXTURE
-   * @return the given matrix
-   */
+    /**
+     * @param matrixName Either a matrix-get-name, i.e. 
+     *                   {@link GLMatrixFunc#GL_MODELVIEW_MATRIX GL_MODELVIEW_MATRIX}, {@link GLMatrixFunc#GL_PROJECTION_MATRIX GL_PROJECTION_MATRIX} or {@link GLMatrixFunc#GL_TEXTURE_MATRIX GL_TEXTURE_MATRIX},
+     *                   or a matrix-mode-name, i.e.
+     *                   {@link GLMatrixFunc#GL_MODELVIEW GL_MODELVIEW}, {@link GLMatrixFunc#GL_PROJECTION GL_PROJECTION} or {@link GL#GL_TEXTURE GL_TEXTURE}
+     * @return the named matrix
+     */
     public final FloatBuffer glGetMatrixf(final int matrixName) {
-        if(matrixName==GL_MODELVIEW) {
-            return matrixMv;
-        } else if(matrixName==GL_PROJECTION) {
-            return matrixP;
-        } else if(matrixName==GL.GL_TEXTURE) {
-            return matrixTex;
-        } else {
-            throw new GLException("unsupported matrixName: "+matrixName);
-        }
+        switch(matrixName) {
+            case GL_MODELVIEW_MATRIX:
+            case GL_MODELVIEW:
+                return matrixMv;
+            case GL_PROJECTION_MATRIX:
+            case GL_PROJECTION:
+                return matrixP;
+            case GL_TEXTURE_MATRIX:
+            case GL.GL_TEXTURE:
+                return matrixTex;
+            default:
+              throw new GLException("unsupported matrixName: "+matrixName);
+        }    
     }
 
     // 
-    // MatrixIf
+    // GLMatrixFunc implementation
     //
 
-    public void glMatrixMode(final int matrixName) {
+    @Override
+    public final void glMatrixMode(final int matrixName) {
         switch(matrixName) {
             case GL_MODELVIEW:
             case GL_PROJECTION:
@@ -344,27 +467,32 @@ public class PMVMatrix implements GLMatrixFunc {
         matrixMode = matrixName;
     }
 
-    public void glGetFloatv(int matrixGetName, FloatBuffer params) {
+    @Override
+    public final void glGetFloatv(int matrixGetName, FloatBuffer params) {
         int pos = params.position();
         if(matrixGetName==GL_MATRIX_MODE) {
             params.put((float)matrixMode);
         } else {
-            FloatBuffer matrix = glGetMatrixf(matrixGetName2MatrixModeName(matrixGetName));
+            FloatBuffer matrix = glGetMatrixf(matrixGetName);
             params.put(matrix); // matrix -> params
             matrix.reset();
         }
         params.position(pos);
     }
-    public void glGetFloatv(int matrixGetName, float[] params, int params_offset) {
+    
+    @Override
+    public final void glGetFloatv(int matrixGetName, float[] params, int params_offset) {
         if(matrixGetName==GL_MATRIX_MODE) {
             params[params_offset]=(float)matrixMode;
         } else {
-            FloatBuffer matrix = glGetMatrixf(matrixGetName2MatrixModeName(matrixGetName));
+            FloatBuffer matrix = glGetMatrixf(matrixGetName);
             matrix.get(params, params_offset, 16); // matrix -> params
             matrix.reset();
         }
     }
-    public void glGetIntegerv(int pname, IntBuffer params) {
+    
+    @Override
+    public final void glGetIntegerv(int pname, IntBuffer params) {
         int pos = params.position();
         if(pname==GL_MATRIX_MODE) {
             params.put(matrixMode);
@@ -373,7 +501,9 @@ public class PMVMatrix implements GLMatrixFunc {
         }
         params.position(pos);
     }
-    public void glGetIntegerv(int pname, int[] params, int params_offset) {
+    
+    @Override
+    public final void glGetIntegerv(int pname, int[] params, int params_offset) {
         if(pname==GL_MATRIX_MODE) {
             params[params_offset]=matrixMode;
         } else {
@@ -381,41 +511,46 @@ public class PMVMatrix implements GLMatrixFunc {
         }
     }
 
+    @Override
     public final void glLoadMatrixf(final float[] values, final int offset) {
         int len = values.length-offset;
         if(matrixMode==GL_MODELVIEW) {
             matrixMv.put(values, offset, len);
             matrixMv.reset();
-            modified |= DIRTY_MODELVIEW ;
+            dirtyBits |= DIRTY_INVERSE_MODELVIEW | DIRTY_INVERSE_TRANSPOSED_MODELVIEW ;
+            modifiedBits |= MODIFIED_MODELVIEW;
         } else if(matrixMode==GL_PROJECTION) {
             matrixP.put(values, offset, len);
             matrixP.reset();
-            modified |= DIRTY_PROJECTION ;
+            modifiedBits |= MODIFIED_PROJECTION;            
         } else if(matrixMode==GL.GL_TEXTURE) {
             matrixTex.put(values, offset, len);
             matrixTex.reset();
-            modified |= DIRTY_TEXTURE ;
+            modifiedBits |= MODIFIED_TEXTURE;
         } 
     }
 
+    @Override
     public final void glLoadMatrixf(java.nio.FloatBuffer m) {
         int spos = m.position();
         if(matrixMode==GL_MODELVIEW) {
             matrixMv.put(m);
             matrixMv.reset();
-            modified |= DIRTY_MODELVIEW ;
+            dirtyBits |= DIRTY_INVERSE_MODELVIEW | DIRTY_INVERSE_TRANSPOSED_MODELVIEW ;
+            modifiedBits |= MODIFIED_MODELVIEW;
         } else if(matrixMode==GL_PROJECTION) {
             matrixP.put(m);
             matrixP.reset();
-            modified |= DIRTY_PROJECTION ;
+            modifiedBits |= MODIFIED_PROJECTION;            
         } else if(matrixMode==GL.GL_TEXTURE) {
             matrixTex.put(m);
             matrixTex.reset();
-            modified |= DIRTY_TEXTURE ;
+            modifiedBits |= MODIFIED_TEXTURE;
         } 
         m.position(spos);
     }
 
+    @Override
     public final void glPopMatrix() {
         float[] stackEntry=null;
         if(matrixMode==GL_MODELVIEW) {
@@ -428,6 +563,7 @@ public class PMVMatrix implements GLMatrixFunc {
         glLoadMatrixf(stackEntry, 0);
     }
 
+    @Override
     public final void glPushMatrix() {
         float[] stackEntry = new float[1*16];
         if(matrixMode==GL_MODELVIEW) {
@@ -445,49 +581,56 @@ public class PMVMatrix implements GLMatrixFunc {
         }
     }
 
+    @Override
     public final void glLoadIdentity() {
         if(matrixMode==GL_MODELVIEW) {
             matrixMv.put(matrixIdent);
             matrixMv.reset();
-            modified |= DIRTY_MODELVIEW ;
+            dirtyBits |= DIRTY_INVERSE_MODELVIEW | DIRTY_INVERSE_TRANSPOSED_MODELVIEW ;
+            modifiedBits |= MODIFIED_MODELVIEW;
         } else if(matrixMode==GL_PROJECTION) {
             matrixP.put(matrixIdent);
             matrixP.reset();
-            modified |= DIRTY_PROJECTION ;
+            modifiedBits |= MODIFIED_PROJECTION;            
         } else if(matrixMode==GL.GL_TEXTURE) {
             matrixTex.put(matrixIdent);
             matrixTex.reset();
-            modified |= DIRTY_TEXTURE ;
+            modifiedBits |= MODIFIED_TEXTURE;
         } 
-        matrixIdent.reset();
+        matrixIdent.reset();        
     }
 
+    @Override
     public final void glMultMatrixf(final FloatBuffer m) {
         if(matrixMode==GL_MODELVIEW) {
             FloatUtil.multMatrixf(matrixMv, m, matrixMv);
-            modified |= DIRTY_MODELVIEW ;
+            dirtyBits |= DIRTY_INVERSE_MODELVIEW | DIRTY_INVERSE_TRANSPOSED_MODELVIEW ;
+            modifiedBits |= MODIFIED_MODELVIEW;
         } else if(matrixMode==GL_PROJECTION) {
             FloatUtil.multMatrixf(matrixP, m, matrixP);
-            modified |= DIRTY_PROJECTION ;
+            modifiedBits |= MODIFIED_PROJECTION;
         } else if(matrixMode==GL.GL_TEXTURE) {
             FloatUtil.multMatrixf(matrixTex, m, matrixTex);
-            modified |= DIRTY_TEXTURE ;
+            modifiedBits |= MODIFIED_TEXTURE;
         } 
     }
 
-    public void glMultMatrixf(float[] m, int m_offset) {
+    @Override
+    public final void glMultMatrixf(float[] m, int m_offset) {
         if(matrixMode==GL_MODELVIEW) {
             FloatUtil.multMatrixf(matrixMv, m, m_offset, matrixMv);
-            modified |= DIRTY_MODELVIEW ;
+            dirtyBits |= DIRTY_INVERSE_MODELVIEW | DIRTY_INVERSE_TRANSPOSED_MODELVIEW ;
+            modifiedBits |= MODIFIED_MODELVIEW;
         } else if(matrixMode==GL_PROJECTION) {
             FloatUtil.multMatrixf(matrixP, m, m_offset, matrixP);
-            modified |= DIRTY_PROJECTION ;
+            modifiedBits |= MODIFIED_PROJECTION;
         } else if(matrixMode==GL.GL_TEXTURE) {
             FloatUtil.multMatrixf(matrixTex, m, m_offset, matrixTex);
-            modified |= DIRTY_TEXTURE ;
+            modifiedBits |= MODIFIED_TEXTURE;
         } 
     }
 
+    @Override
     public final void glTranslatef(final float x, final float y, final float z) {
         // Translation matrix: 
         //  1 0 0 x
@@ -500,6 +643,7 @@ public class PMVMatrix implements GLMatrixFunc {
         glMultMatrixf(matrixTrans, 0);
     }
 
+    @Override
     public final void glRotatef(final float angdeg, float x, float y, float z) {
         final float angrad = angdeg   * (float) Math.PI / 180.0f;
         final float c = (float)Math.cos(angrad);
@@ -536,6 +680,7 @@ public class PMVMatrix implements GLMatrixFunc {
         glMultMatrixf(matrixRot, 0);
     }
 
+    @Override
     public final void glScalef(final float x, final float y, final float z) {
         // Scale matrix: 
         //  x 0 0 0
@@ -549,6 +694,7 @@ public class PMVMatrix implements GLMatrixFunc {
         glMultMatrixf(matrixScale, 0);
     }
 
+    @Override
     public final void glOrthof(final float left, final float right, final float bottom, final float top, final float zNear, final float zFar) {
         // Ortho matrix: 
         //  2/dx  0     0    tx
@@ -572,14 +718,7 @@ public class PMVMatrix implements GLMatrixFunc {
         glMultMatrixf(matrixOrtho, 0);
     }
 
-    public final void gluPerspective(final float fovy, final float aspect, final float zNear, final float zFar) {
-      float top=(float)Math.tan(fovy*((float)Math.PI)/360.0f)*zNear;
-      float bottom=-1.0f*top;
-      float left=aspect*bottom;
-      float right=aspect*top;
-      glFrustumf(left, right, bottom, top, zNear, zFar);
-    }
-
+    @Override
     public final void glFrustumf(final float left, final float right, final float bottom, final float top, final float zNear, final float zFar) {
         if(zNear<=0.0f||zFar<0.0f) {
             throw new GLException("GL_INVALID_VALUE: zNear and zFar must be positive, and zNear>0");
@@ -614,14 +753,33 @@ public class PMVMatrix implements GLMatrixFunc {
         glMultMatrixf(matrixFrustum, 0);
     }
 
-    public void gluLookAt(float eyex, float eyey, float eyez,
+    //
+    // Extra functionality
+    //
+    
+    /**
+     * {@link #glMultMatrixf(FloatBuffer) Multiply} the {@link #glGetMatrixMode() current matrix} with the perspective/frustum matrix.
+     */
+    public final void gluPerspective(final float fovy, final float aspect, final float zNear, final float zFar) {
+      float top=(float)Math.tan(fovy*((float)Math.PI)/360.0f)*zNear;
+      float bottom=-1.0f*top;
+      float left=aspect*bottom;
+      float right=aspect*top;
+      glFrustumf(left, right, bottom, top, zNear, zFar);
+    }
+
+    /**
+     * {@link #glMultMatrixf(FloatBuffer) Multiply} and {@link #glTranslatef(float, float, float) translate} the {@link #glGetMatrixMode() current matrix} 
+     * with the eye, object and orientation.
+     */
+    public final void gluLookAt(float eyex, float eyey, float eyez,
                           float centerx, float centery, float centerz,
                           float upx, float upy, float upz) {
         projectFloat.gluLookAt(this, eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz);
     }
 
     /**
-     * Uses this instance {@link #glGetMvMatrixf()} and {@link #glGetPMatrixf()}
+     * Map object coordinates to window coordinates.
      * 
      * @param objx
      * @param objy
@@ -632,7 +790,7 @@ public class PMVMatrix implements GLMatrixFunc {
      * @param win_pos_offset
      * @return
      */
-    public boolean gluProject(float objx, float objy, float objz,
+    public final boolean gluProject(float objx, float objy, float objz,
                             int[] viewport, int viewport_offset,
                             float[] win_pos, int win_pos_offset ) {
         if(usesBackingArray) {
@@ -651,7 +809,7 @@ public class PMVMatrix implements GLMatrixFunc {
     }
 
     /**
-     * Uses this instance {@link #glGetMvMatrixf()} and {@link #glGetPMatrixf()}
+     * Map window coordinates to object coordinates.
      * 
      * @param winx
      * @param winy
@@ -680,11 +838,189 @@ public class PMVMatrix implements GLMatrixFunc {
         }        
     }
     
-    public void gluPickMatrix(float x, float y,
+    public final void gluPickMatrix(float x, float y,
                               float deltaX, float deltaY,
                               int[] viewport, int viewport_offset) {
         projectFloat.gluPickMatrix(this, x, y, deltaX, deltaY, viewport, viewport_offset);
     }
+        
+    public StringBuilder toString(StringBuilder sb, String f) {
+        if(null == sb) {
+            sb = new StringBuilder();
+        }
+        final boolean mviDirty  = 0 != (DIRTY_INVERSE_MODELVIEW & dirtyBits);
+        final boolean mvitDirty = 0 != (DIRTY_INVERSE_TRANSPOSED_MODELVIEW & dirtyBits);
+        final boolean mviReq = 0 != (DIRTY_INVERSE_MODELVIEW & requestMask);
+        final boolean mvitReq = 0 != (DIRTY_INVERSE_TRANSPOSED_MODELVIEW & requestMask);
+        final boolean modP = 0 != ( MODIFIED_PROJECTION & modifiedBits );
+        final boolean modMv = 0 != ( MODIFIED_MODELVIEW & modifiedBits );
+        final boolean modT = 0 != ( MODIFIED_TEXTURE & modifiedBits );
+        
+        sb.append("PMVMatrix[backingArray ").append(this.usesBackingArray());
+        sb.append(", modified[P ").append(modP).append(", Mv ").append(modMv).append(", T ").append(modT);
+        sb.append("], dirty/req[Mvi ").append(mviDirty).append("/").append(mviReq).append(", Mvit ").append(mvitDirty).append("/").append(mvitReq);
+        sb.append("], Projection").append(Platform.NEWLINE);
+        matrixToString(sb, f, matrixP);
+        sb.append(", Modelview").append(Platform.NEWLINE);
+        matrixToString(sb, f, matrixMv);
+        sb.append(", Texture").append(Platform.NEWLINE);
+        matrixToString(sb, f, matrixTex);
+        if( 0 != ( requestMask & DIRTY_INVERSE_MODELVIEW ) ) {
+            sb.append(", Inverse Modelview").append(Platform.NEWLINE);
+            matrixToString(sb, f, matrixMvi);            
+        }
+        if( 0 != ( requestMask & DIRTY_INVERSE_TRANSPOSED_MODELVIEW ) ) {
+            sb.append(", Inverse Transposed Modelview").append(Platform.NEWLINE);
+            matrixToString(sb, f, matrixMvit);            
+        }
+        sb.append("]");
+        return sb;
+    }
+    
+    public String toString() {
+        return toString(null, "%10.5f").toString();
+    }
+
+    /** 
+     * Returns the modified bits due to mutable operations..
+     * <p>
+     * A modified bit is set, if the corresponding matrix had been modified by a mutable operation
+     * since last {@link #update()} or {@link #getModifiedBits(boolean) getModifiedBits(true)} call.
+     * </p>
+     * @param clear if true, clears the modified bits, otherwise leaves them untouched.
+     * 
+     * @see #MODIFIED_PROJECTION
+     * @see #MODIFIED_MODELVIEW
+     * @see #MODIFIED_TEXTURE
+     */
+    public final int getModifiedBits(boolean clear) {
+        final int r = modifiedBits;
+        if(clear) {
+            modifiedBits = 0;
+        }
+        return r;
+    }
+    
+    /** 
+     * Returns the dirty bits due to mutable operations.
+     * <p>
+     * A dirty bit is set , if the corresponding matrix had been modified by a mutable operation
+     * since last {@link #update()} call. The latter clears the dirty state only if the dirty matrix (Mvi or Mvit)
+     * has been requested by one of the {@link #glGetMviMatrixf() Mvi get} or {@link #glGetMvitMatrixf() Mvit get} methods.
+     * </p>
+     * 
+     * @deprecated Function is exposed for debugging purposes only.
+     * @see #DIRTY_INVERSE_MODELVIEW
+     * @see #DIRTY_INVERSE_TRANSPOSED_MODELVIEW
+     * @see #glGetMviMatrixf()
+     * @see #glGetMvitMatrixf()
+     * @see #glGetPMvMviMatrixf()
+     * @see #glGetPMvMvitMatrixf()
+     */
+    public final int getDirtyBits() {
+        return dirtyBits;
+    }
+
+    /** 
+     * Returns the request bit mask, which uses bit values equal to the dirty mask.
+     * <p>
+     * The request bit mask is set by one of the {@link #glGetMviMatrixf() Mvi get} or {@link #glGetMvitMatrixf() Mvit get} methods.
+     * </p> 
+     *
+     * @deprecated Function is exposed for debugging purposes only.
+     * @see #disableMviMvitUpdate()
+     * @see #DIRTY_INVERSE_MODELVIEW
+     * @see #DIRTY_INVERSE_TRANSPOSED_MODELVIEW
+     * @see #glGetMviMatrixf()
+     * @see #glGetMvitMatrixf()
+     * @see #glGetPMvMviMatrixf()
+     * @see #glGetPMvMvitMatrixf()
+     */
+    public final int getRequestMask() {
+        return requestMask;
+    }
+    
+    
+    /**
+     * Disable {@link #update()} of the Mvi and Mvit matrix
+     * after it has been enabled by one of the {@link #glGetMviMatrixf() Mvi get} or {@link #glGetMvitMatrixf() Mvit get} methods.
+     * <p>
+     * This cleans the request bit mask used internally.
+     * </p>
+     * <p>
+     * Function may be useful to disable subsequent Mvi and Mvit updates if no more required.
+     * </p>  
+     * 
+     * @see #glGetMviMatrixf()
+     * @see #glGetMvitMatrixf()
+     * @see #glGetPMvMviMatrixf()
+     * @see #glGetPMvMvitMatrixf()
+     * @see #getRequestMask()
+     */
+    public final void disableMviMvitUpdate() {
+        requestMask &= ~DIRTY_ALL;        
+    }
+    
+    /**
+     * Update the derived {@link #glGetMviMatrixf() inverse modelview (Mvi)} 
+     * and {@link #glGetMvitMatrixf() inverse transposed modelview (Mvit)} matrices
+     * <b>if</b> they are dirty <b>and</b> their usage/update has been requested 
+     * by one of the {@link #glGetMviMatrixf() Mvi get} or {@link #glGetMvitMatrixf() Mvit get} methods.
+     * <p>
+     * The Mvi and Mvit matrices are considered dirty, if their corresponding
+     * {@link #glGetMvMatrixf() Mv matrix} has been modified since their last update.
+     * </p>
+     * <p>
+     * Method should be called manually in case mutable operations has been called
+     * and caller operates on already fetched references, i.e. not calling
+     * {@link #glGetMviMatrixf() Mvi get} or {@link #glGetMvitMatrixf() Mvit get} etc anymore.
+     * </p>
+     * <p>
+     * This method clears the modified bits like {@link #getModifiedBits(boolean) getModifiedBits(true)},
+     * which are set by any mutable operation. The modified bits have no impact
+     * on this method, but the return value.
+     * </p>
+     * 
+     * @return true if any matrix has been modified since last update call or 
+     *         if the derived matrices Mvi and Mvit were updated, otherwise false.
+     *         In other words, method returns true if any matrix used by the caller must be updated,
+     *         e.g. uniforms in a shader program.
+     * 
+     * @see #getModifiedBits(boolean)
+     * @see #MODIFIED_PROJECTION
+     * @see #MODIFIED_MODELVIEW
+     * @see #MODIFIED_TEXTURE
+     * @see #DIRTY_INVERSE_MODELVIEW
+     * @see #DIRTY_INVERSE_TRANSPOSED_MODELVIEW
+     * @see #glGetMviMatrixf()
+     * @see #glGetMvitMatrixf()
+     * @see #glGetPMvMviMatrixf()
+     * @see #glGetPMvMvitMatrixf()
+     * @see #disableMviMvitUpdate()
+     */
+    public final boolean update() {
+        return updateImpl(true);
+    }
+    private final boolean updateImpl(boolean clearModBits) {
+        final boolean mod = 0 != modifiedBits;
+        if(clearModBits) {
+            modifiedBits = 0;
+        }
+        
+        if( 0 == ( dirtyBits & requestMask ) ) {
+            return mod; // nothing requested which may have been dirty
+        }
+
+        if(nioBackupArraySupported>=0) {
+            try {
+                nioBackupArraySupported = 1;
+                return setMviMvitNIOBackupArray() || mod;
+            } catch(UnsupportedOperationException uoe) {
+                nioBackupArraySupported = -1;
+            }
+        }
+        return setMviMvitNIODirectAccess() || mod;
+    }
     
     //
     // private 
@@ -692,27 +1028,18 @@ public class PMVMatrix implements GLMatrixFunc {
     private int nioBackupArraySupported = 0; // -1 not supported, 0 - TBD, 1 - supported
     private final String msgCantComputeInverse = "Invalid source Mv matrix, can't compute inverse";
 
-    private final void setMviMvit() {
-        if( 0 != (usesMviMvit & 1) ) {
-            if(nioBackupArraySupported>=0) {
-                try {
-                    setMviMvitNIOBackupArray();
-                    nioBackupArraySupported = 1;
-                    return;
-                } catch(UnsupportedOperationException uoe) {
-                    nioBackupArraySupported = -1;
-                }
-            }
-            setMviMvitNIODirectAccess();
-        }
-    }
-    private final void setMviMvitNIOBackupArray() {
+    private final boolean setMviMvitNIOBackupArray() {
         final float[] _matrixMvi = matrixMvi.array();
         final int _matrixMviOffset = matrixMvi.position();
-        if(!projectFloat.gluInvertMatrixf(matrixMv.array(), matrixMv.position(), _matrixMvi, _matrixMviOffset)) {
-            throw new GLException(msgCantComputeInverse);
+        boolean res = false;
+        if( 0 != ( dirtyBits & DIRTY_INVERSE_MODELVIEW ) ) { // only if dirt; always requested at this point, see update()
+            if(!projectFloat.gluInvertMatrixf(matrixMv.array(), matrixMv.position(), _matrixMvi, _matrixMviOffset)) {
+                throw new GLException(msgCantComputeInverse);
+            }
+            dirtyBits &= ~DIRTY_INVERSE_MODELVIEW;
+            res = true;
         }
-        if( 0 != (usesMviMvit & 2) ) {
+        if( 0 != ( requestMask & ( dirtyBits & DIRTY_INVERSE_TRANSPOSED_MODELVIEW ) ) ) { // only if requested & dirty
             // transpose matrix 
             final float[] _matrixMvit = matrixMvit.array();
             final int _matrixMvitOffset = matrixMvit.position();
@@ -721,34 +1048,43 @@ public class PMVMatrix implements GLMatrixFunc {
                     _matrixMvit[_matrixMvitOffset+j+i*4] = _matrixMvi[_matrixMviOffset+i+j*4];
                 }
             }
-        }        
+            dirtyBits &= ~DIRTY_INVERSE_TRANSPOSED_MODELVIEW;
+            res = true;
+        }
+        return res;
     }
     
-    private final void setMviMvitNIODirectAccess() {
-        if(!projectFloat.gluInvertMatrixf(matrixMv, matrixMvi)) {
-            throw new GLException(msgCantComputeInverse);
+    private final boolean setMviMvitNIODirectAccess() {
+        boolean res = false;
+        if( 0 != ( dirtyBits & DIRTY_INVERSE_MODELVIEW ) ) { // only if dirt; always requested at this point, see update()
+            if(!projectFloat.gluInvertMatrixf(matrixMv, matrixMvi)) {
+                throw new GLException(msgCantComputeInverse);
+            }
+            dirtyBits &= ~DIRTY_INVERSE_MODELVIEW;
+            res = true;
         }
-        if( 0 != (usesMviMvit & 2) ) {
+        if( 0 != ( requestMask & ( dirtyBits & DIRTY_INVERSE_TRANSPOSED_MODELVIEW ) ) ) { // only if requested & dirty
             // transpose matrix 
             for (int i = 0; i < 4; i++) {
                 for (int j = 0; j < 4; j++) {
                     matrixMvit.put(j+i*4, matrixMvi.get(i+j*4));
                 }
             }
-        }        
+            dirtyBits &= ~DIRTY_INVERSE_TRANSPOSED_MODELVIEW;
+            res = true;
+        }
+        return res;
     }
 
+    protected final float[] matrixBufferArray;
     protected final boolean usesBackingArray;
     protected Buffer matrixBuffer;
     protected FloatBuffer matrixIdent, matrixPMvMvit, matrixPMvMvi, matrixPMv, matrixP, matrixTex, matrixMv, matrixMvi, matrixMvit;
     protected float[] matrixMult, matrixTrans, matrixRot, matrixScale, matrixOrtho, matrixFrustum, vec3f;
     protected List<float[]> matrixTStack, matrixPStack, matrixMvStack;
     protected int matrixMode = GL_MODELVIEW;
-    protected int modified = 0;
-    protected int usesMviMvit = 0; // 0 - none, 1 - Mvi, 2 - Mvit, 3 - MviMvit (ofc no Mvit w/o Mvi!)
+    protected int modifiedBits = MODIFIED_ALL;
+    protected int dirtyBits = DIRTY_ALL; // contains the dirty bits, i.e. hinting for update operation
+    protected int requestMask = 0; // may contain the requested dirty bits: DIRTY_INVERSE_MODELVIEW | DIRTY_INVERSE_TRANSPOSED_MODELVIEW
     protected ProjectFloat projectFloat;
-
-    public static final int DIRTY_MODELVIEW  = 1 << 0;
-    public static final int DIRTY_PROJECTION = 1 << 1;
-    public static final int DIRTY_TEXTURE    = 1 << 2;
 }
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java
index f6b686d..e6dde32 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java
@@ -46,6 +46,7 @@ import java.util.Set;
 import javax.media.opengl.GL;
 import javax.media.opengl.GL2ES2;
 import javax.media.opengl.GLES2;
+import javax.media.opengl.GLContext;
 import javax.media.opengl.GLException;
 
 import jogamp.opengl.Debug;
@@ -806,6 +807,35 @@ public class ShaderCode {
         }
     }
 
+    // Shall we use: #ifdef GL_FRAGMENT_PRECISION_HIGH .. #endif for using highp in fragment shader if avail ?     
+    /** {@value #es2_default_precision_vp} */
+    public static final String es2_default_precision_vp = "\nprecision highp float;\nprecision highp int;\n";
+    /** {@value #es2_default_precision_fp} */
+    public static final String es2_default_precision_fp = "\nprecision mediump float;\nprecision mediump int;\n/*precision lowp sampler2D;*/\n";
+    
+    /**
+     * Default customization of this shader source code.
+     * <p>
+     * Note: The shader source to be edit must be created using a mutable StringBuilder.
+     * </p>
+     * @param gl a GL context, which must have been made current once 
+     * @param preludeVersion if true {@link GLContext#getGLSLVersionString()} is preluded, otherwise not.
+     * @param es2DefaultPrecision optional default precision source code line(s) preluded if not null and if {@link GL#isGLES()}.
+     *        You may use {@link #es2_default_precision_fp} for fragment shader and {@link #es2_default_precision_vp} for vertex shader.
+     * @return the index after the inserted data, maybe 0 if nothing has be inserted.
+     */
+    public final int defaultShaderCustomization(GL2ES2 gl, boolean preludeVersion, String es2DefaultPrecision) {
+        int pos = 0;
+        if(preludeVersion) {
+            final String glslVersion_prelude = gl.getContext().getGLSLVersionString();
+            pos = insertShaderSource(0, pos, glslVersion_prelude);
+        }
+        if( gl.isGLES() && null != es2DefaultPrecision ) {
+            pos = insertShaderSource(0, pos, es2DefaultPrecision);
+        }
+        return pos;
+    }    
+    
     //----------------------------------------------------------------------
     // Internals only below this point
     //
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderProgram.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderProgram.java
index 14ea7d2..9cade1e 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderProgram.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderProgram.java
@@ -50,6 +50,7 @@ public class ShaderProgram {
         return programInUse;
     }
 
+    /** Returns the shader program name, which is non zero if valid. */
     public int program() { return shaderProgram; }
 
     /**
@@ -96,9 +97,9 @@ public class ShaderProgram {
         }
         allShaderCode.clear();
         attachedShaderCode.clear();
-        if(0<=shaderProgram) {
+        if( 0 != shaderProgram ) {
             gl.glDeleteProgram(shaderProgram);
-            shaderProgram=-1;
+            shaderProgram=0;
         }
     }
 
@@ -140,14 +141,17 @@ public class ShaderProgram {
     //
 
     /**
-     * Creates the empty GL program object using {@link GL2ES2#glCreateProgram()}
+     * Creates the empty GL program object using {@link GL2ES2#glCreateProgram()},
+     * if not already created.
      *  
      * @param gl
+     * @return true if shader program is valid, i.e. not zero 
      */
-    public synchronized final void init(GL2ES2 gl) {
-        if(0>shaderProgram) {
+    public synchronized final boolean init(GL2ES2 gl) {
+        if( 0 == shaderProgram ) {
             shaderProgram = gl.glCreateProgram();
         }
+        return 0 != shaderProgram;
     }
     
     /**
@@ -158,12 +162,12 @@ public class ShaderProgram {
      * @return true if the shader was successfully added, false if compilation failed.
      */
     public synchronized boolean add(GL2ES2 gl, ShaderCode shaderCode, PrintStream verboseOut) {
-        init(gl);
+        if( !init(gl) ) { return false; }
         if( allShaderCode.add(shaderCode) ) {
-            if(!shaderCode.compile(gl, verboseOut)) {
+            if( !shaderCode.compile(gl, verboseOut) ) {
                 return false;
             }
-            if(attachedShaderCode.add(shaderCode)) {
+            if( attachedShaderCode.add(shaderCode) ) {
                 ShaderUtil.attachShader(gl, shaderProgram, shaderCode.shader());
             }
         }
@@ -190,9 +194,7 @@ public class ShaderProgram {
      * @see ShaderState#glResetAllVertexAttributes
      */
     public synchronized boolean replaceShader(GL2ES2 gl, ShaderCode oldShader, ShaderCode newShader, PrintStream verboseOut) {
-        init(gl);
-        
-        if(!newShader.compile(gl, verboseOut)) {
+        if(!init(gl) || !newShader.compile(gl, verboseOut)) {
             return false;
         }
         
@@ -235,11 +237,15 @@ public class ShaderProgram {
      * @see #init(GL2ES2)
      */
     public synchronized boolean link(GL2ES2 gl, PrintStream verboseOut) {
-        init(gl);
+        if( !init(gl) ) { 
+            programLinked = false; // mark unlinked due to user attempt to [re]link
+            return false;
+        }
 
         for(Iterator<ShaderCode> iter=allShaderCode.iterator(); iter.hasNext(); ) {
             final ShaderCode shaderCode = iter.next();
             if(!shaderCode.compile(gl, verboseOut)) {
+                programLinked = false; // mark unlinked due to user attempt to [re]link
                 return false;
             }
             if(attachedShaderCode.add(shaderCode)) {
@@ -295,13 +301,16 @@ public class ShaderProgram {
     public synchronized void useProgram(GL2ES2 gl, boolean on) {
         if(!programLinked) { throw new GLException("Program is not linked"); }
         if(programInUse==on) { return; }
-        gl.glUseProgram(on?shaderProgram:0);
+        if( 0 == shaderProgram ) {
+            on = false;
+        }
+        gl.glUseProgram( on ? shaderProgram : 0 );
         programInUse = on;
     }
 
     protected boolean programLinked = false;
     protected boolean programInUse = false;
-    protected int shaderProgram=-1;
+    protected int shaderProgram = 0; // non zero is valid!
     protected HashSet<ShaderCode> allShaderCode = new HashSet<ShaderCode>();
     protected HashSet<ShaderCode> attachedShaderCode = new HashSet<ShaderCode>();
     protected int id = -1;
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java
index 62082aa..ff8982d 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java
@@ -42,9 +42,20 @@ import javax.media.opengl.GLUniformData;
 import jogamp.opengl.Debug;
 
 import com.jogamp.common.os.Platform;
-import com.jogamp.common.util.IntObjectHashMap;
 import com.jogamp.opengl.util.GLArrayDataEditable;
 
+/**
+ * ShaderState allows to sharing data between shader programs,
+ * while updating the attribute and uniform locations when switching.
+ * <p>
+ * This allows seamless switching of programs using <i>almost</i> same data
+ * but performing different artifacts. 
+ * </p>
+ * <p>
+ * A {@link #useProgram(GL2ES2, boolean) used} ShaderState is attached to the current GL context
+ * and can be retrieved via {@link #getShaderState(GL)}.
+ * </p>
+ */
 public class ShaderState {
     public static final boolean DEBUG = Debug.isPropertyDefined("jogl.debug.GLSLState", true);
     private static final String currentStateKey = "jogamp.opengl.glsl.ShaderState" ;
@@ -54,7 +65,7 @@ public class ShaderState {
 
     public boolean verbose() { return verbose; }
 
-    public void setVerbose(boolean v) { verbose=v; }
+    public void setVerbose(boolean v) { verbose = DEBUG || v; }
 
     /**
      * Fetches the current shader state from this thread (TLS) current GLContext
@@ -123,25 +134,6 @@ public class ShaderState {
     }    
     
     /**
-     * Returns the attached user object for the given name to this ShaderState.
-     */
-    public final Object getAttachedObject(int name) {
-      return attachedObjectsByInt.get(name);
-    }
-
-    /**
-     * Attach user object for the given name to this ShaderState.
-     * Returns the previously set object or null.
-     */
-    public final Object attachObject(int name, Object obj) {
-      return attachedObjectsByInt.put(name, obj);
-    }
-
-    public final Object detachObject(int name) {
-        return attachedObjectsByInt.remove(name);
-    }    
-    
-    /**
      * Turns the shader program on or off.<br>
      * Puts this ShaderState to to the thread local storage (TLS),
      * if <code>on</code> is <code>true</code>.
@@ -200,25 +192,29 @@ public class ShaderState {
      * <p>Use program, {@link #useProgram(GL2ES2, boolean)},
      * if <code>enable</code> is <code>true</code>.</p>
      * 
+     * @return true if shader program was attached, otherwise false (already attached)
+     * 
      * @throws GLException if program was not linked and linking fails
      */
-    public synchronized void attachShaderProgram(GL2ES2 gl, ShaderProgram prog, boolean enable) throws GLException {
-        if(DEBUG) {
+    public synchronized boolean attachShaderProgram(GL2ES2 gl, ShaderProgram prog, boolean enable) throws GLException {
+        if(verbose) {
             int curId = (null!=shaderProgram)?shaderProgram.id():-1;
             int newId = (null!=prog)?prog.id():-1;
-            System.err.println("Info: attachShaderProgram: "+curId+" -> "+newId+" (enable: "+enable+")\n\t"+shaderProgram+"\n\t"+prog);
-            if(verbose) {
-                Throwable tX = new Throwable("Info: attachShaderProgram: Trace");
-                tX.printStackTrace();
-            }
+            System.err.println("ShaderState: attachShaderProgram: "+curId+" -> "+newId+" (enable: "+enable+")\n\t"+shaderProgram+"\n\t"+prog);
+            if(DEBUG) {
+                Thread.dumpStack();
+            }                    
         }
         if(null!=shaderProgram) {
             if(shaderProgram.equals(prog)) {
-                // nothing to do ..
-                if(DEBUG) {
-                    System.err.println("Info: attachShaderProgram: NOP: equal id: "+shaderProgram.id());
+                if(enable) {
+                    useProgram(gl, true);
+                }
+                // nothing else to do ..
+                if(verbose) {
+                    System.err.println("ShaderState: attachShaderProgram: No switch, equal id: "+shaderProgram.id()+", enabling "+enable);
                 }
-                return;
+                return false;
             }
             if(shaderProgram.inUse()) {
                 if(null != prog && enable) {
@@ -248,6 +244,7 @@ public class ShaderState {
         if(DEBUG) {
             System.err.println("Info: attachShaderProgram: END");
         }
+        return true;
     }
 
     public ShaderProgram shaderProgram() { return shaderProgram; }
@@ -262,7 +259,6 @@ public class ShaderState {
     public synchronized void destroy(GL2ES2 gl) {
         release(gl, true, true, true);
         attachedObjectsByString.clear();        
-        attachedObjectsByInt.clear();
     }
 
     /**
@@ -437,11 +433,13 @@ public class ShaderState {
                 Integer idx = new Integer(location);
                 activeAttribLocationMap.put(name, idx);
                 if(DEBUG) {
-                    System.err.println("Info: glGetAttribLocation: "+name+", loc: "+location);
+                    System.err.println("ShaderState: glGetAttribLocation: "+name+", loc: "+location);
                 }
             } else if(verbose) {
-                Throwable tX = new Throwable("Info: glGetAttribLocation failed, no location for: "+name+", loc: "+location);
-                tX.printStackTrace();
+                System.err.println("ShaderState: glGetAttribLocation failed, no location for: "+name+", loc: "+location);
+                if(DEBUG) {
+                    Thread.dumpStack();
+                }                    
             }
         }
         return location;
@@ -498,14 +496,16 @@ public class ShaderState {
             location = getAttribLocation(gl, name);
             if(0>location) {
                 if(verbose) {
-                    Throwable tX = new Throwable("Info: glEnableVertexAttribArray failed, no index for: "+name);
-                    tX.printStackTrace();
+                    System.err.println("ShaderState: glEnableVertexAttribArray failed, no index for: "+name);
+                    if(DEBUG) {
+                        Thread.dumpStack();
+                    }                    
                 }
                 return false;
             }
         }
         if(DEBUG) {
-            System.err.println("Info: glEnableVertexAttribArray: "+name+", loc: "+location);
+            System.err.println("ShaderState: glEnableVertexAttribArray: "+name+", loc: "+location);
         }
         gl.glEnableVertexAttribArray(location);
         return true;
@@ -571,14 +571,16 @@ public class ShaderState {
             location = getAttribLocation(gl, name);
             if(0>location) {
                 if(verbose) {
-                    Throwable tX = new Throwable("Info: glDisableVertexAttribArray failed, no index for: "+name);
-                    tX.printStackTrace();
+                    System.err.println("ShaderState: glDisableVertexAttribArray failed, no index for: "+name);
+                    if(DEBUG) {
+                        Thread.dumpStack();
+                    }
                 }
                 return false;
             }
         }
         if(DEBUG) {
-            System.err.println("Info: glDisableVertexAttribArray: "+name);
+            System.err.println("ShaderState: glDisableVertexAttribArray: "+name);
         }
         gl.glDisableVertexAttribArray(location);
         return true;
@@ -660,7 +662,7 @@ public class ShaderState {
         if(0 <= location) {
             // only pass the data, if the attribute exists in the current shader
             if(DEBUG) {
-                System.err.println("Info: glVertexAttribPointer: "+data);
+                System.err.println("ShaderState: glVertexAttribPointer: "+data);
             }
             gl.glVertexAttribPointer(data);
             return true;
@@ -740,9 +742,11 @@ public class ShaderState {
     
             if( attribute.isVBO() ) {
                 gl.glBindBuffer(GL.GL_ARRAY_BUFFER, attribute.getVBOName());
-            } 
-    
-            gl.glVertexAttribPointer(attribute);
+                gl.glVertexAttribPointer(attribute);
+                gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
+            } else {   
+                gl.glVertexAttribPointer(attribute);
+            }
         }
     }
     
@@ -764,8 +768,8 @@ public class ShaderState {
         if(!shaderProgram.linked()) throw new GLException("Program is not linked");
         activeAttribLocationMap.clear();
         
-        for(Iterator<GLArrayData> iter = managedAttributes.iterator(); iter.hasNext(); ) {
-            iter.next().setLocation(-1);
+        for(int i=0; i<managedAttributes.size(); i++) {
+            ((GLArrayData)managedAttributes.get(i)).setLocation(-1);
         }
         for(Iterator<GLArrayData> iter = activeAttribDataMap.values().iterator(); iter.hasNext(); ) {
             relocateAttribute(gl, iter.next());
@@ -778,7 +782,7 @@ public class ShaderState {
         final int loc = attribute.getLocation();
 
         if(0<=loc) {
-            this.bindAttribLocation(gl, loc, name);
+            bindAttribLocation(gl, loc, name);
             
             if(isVertexAttribArrayEnabled(name)) {
                 // enable attrib, VBO and pass location/data
@@ -787,9 +791,11 @@ public class ShaderState {
     
             if( attribute.isVBO() ) {
                 gl.glBindBuffer(GL.GL_ARRAY_BUFFER, attribute.getVBOName());
-            } 
-    
-            gl.glVertexAttribPointer(attribute);
+                gl.glVertexAttribPointer(attribute);
+                gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
+            } else {   
+                gl.glVertexAttribPointer(attribute);
+            }
         }
     }
     
@@ -872,8 +878,10 @@ public class ShaderState {
                 Integer idx = new Integer(location);
                 activeUniformLocationMap.put(name, idx);
             } else if(verbose) {
-                Throwable tX = new Throwable("Info: glUniform failed, no location for: "+name+", index: "+location);
-                tX.printStackTrace();
+                System.err.println("ShaderState: glUniform failed, no location for: "+name+", index: "+location);
+                if(DEBUG) {
+                    Thread.dumpStack();
+                }
             }
         }
         return location;
@@ -936,7 +944,7 @@ public class ShaderState {
         if(0<=location) {
             // only pass the data, if the uniform exists in the current shader
             if(DEBUG) {
-                System.err.println("Info: glUniform: "+data);
+                System.err.println("ShaderState: glUniform: "+data);
             }
             gl.glUniform(data);
         }
@@ -985,7 +993,7 @@ public class ShaderState {
         }
     }
 
-    public StringBuilder toString(StringBuilder sb) {
+    public StringBuilder toString(StringBuilder sb, boolean alsoUnlocated) {
         if(null==sb) {
             sb = new StringBuilder();
         }
@@ -1008,19 +1016,31 @@ public class ShaderState {
         }
         sb.append(Platform.getNewline()).append(" ],").append(" activeAttributes [");
         for(Iterator<GLArrayData> iter = activeAttribDataMap.values().iterator(); iter.hasNext(); ) {
-            sb.append(Platform.getNewline()).append("  ").append(iter.next());
+            final GLArrayData ad = iter.next();
+            if( alsoUnlocated || 0 <= ad.getLocation() ) {
+                sb.append(Platform.getNewline()).append("  ").append(ad);
+            }
         }
         sb.append(Platform.getNewline()).append(" ],").append(" managedAttributes [");
         for(Iterator<GLArrayData> iter = managedAttributes.iterator(); iter.hasNext(); ) {
-            sb.append(Platform.getNewline()).append("  ").append(iter.next());
+            final GLArrayData ad = iter.next();
+            if( alsoUnlocated || 0 <= ad.getLocation() ) {
+                sb.append(Platform.getNewline()).append("  ").append(ad);
+            }
         }
         sb.append(Platform.getNewline()).append(" ],").append(" activeUniforms [");
         for(Iterator<GLUniformData> iter=activeUniformDataMap.values().iterator(); iter.hasNext(); ) {
-            sb.append(Platform.getNewline()).append("  ").append(iter.next());
+            final GLUniformData ud = iter.next();
+            if( alsoUnlocated || 0 <= ud.getLocation() ) {
+                sb.append(Platform.getNewline()).append("  ").append(ud);
+            }
         }
         sb.append(Platform.getNewline()).append(" ],").append(" managedUniforms [");
         for(Iterator<GLUniformData> iter = managedUniforms.iterator(); iter.hasNext(); ) {
-            sb.append(Platform.getNewline()).append("  ").append(iter.next());
+            final GLUniformData ud = iter.next();
+            if( alsoUnlocated || 0 <= ud.getLocation() ) {
+                sb.append(Platform.getNewline()).append("  ").append(ud);
+            }
         }
         sb.append(Platform.getNewline()).append(" ]").append(Platform.getNewline()).append("]");
         return sb;
@@ -1028,10 +1048,10 @@ public class ShaderState {
     
     @Override
     public String toString() {
-        return toString(null).toString();
+        return toString(null, DEBUG).toString();
     }
     
-    private boolean verbose = DEBUG ? true : false;
+    private boolean verbose = DEBUG;
     private ShaderProgram shaderProgram=null;
     
     private HashMap<String, Boolean> activedAttribEnabledMap = new HashMap<String, Boolean>();
@@ -1044,7 +1064,6 @@ public class ShaderState {
     private ArrayList<GLUniformData> managedUniforms = new ArrayList<GLUniformData>();
     
     private HashMap<String, Object> attachedObjectsByString = new HashMap<String, Object>();    
-    private IntObjectHashMap attachedObjectsByInt = new IntObjectHashMap();   
     private boolean resetAllShaderData = false;
 }
 
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderUtil.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderUtil.java
index 40c0524..5afc5e3 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderUtil.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderUtil.java
@@ -159,16 +159,19 @@ public class ShaderUtil {
         if(null == info.shaderBinaryFormats) {
             info.shaderBinaryFormats = new HashSet<Integer>();
             if (gl.isGLES2Compatible()) {
-                final int[] param = new int[1];
-                gl.glGetIntegerv(GL2ES2.GL_NUM_SHADER_BINARY_FORMATS, param, 0);
-                int numFormats = param[0];
-                if(numFormats>0) {
-                    int[] formats = new int[numFormats];
-                    gl.glGetIntegerv(GL2ES2.GL_SHADER_BINARY_FORMATS, formats, 0);
-                    for(int i=0; i<numFormats; i++) {
-                        info.shaderBinaryFormats.add(new Integer(formats[i]));
+                try {
+                    final int[] param = new int[1];
+                    gl.glGetIntegerv(GL2ES2.GL_NUM_SHADER_BINARY_FORMATS, param, 0);
+                    final int err = gl.glGetError();
+                    final int numFormats = GL.GL_NO_ERROR == err ? param[0] : 0;
+                    if(numFormats>0) {
+                        int[] formats = new int[numFormats];
+                        gl.glGetIntegerv(GL2ES2.GL_SHADER_BINARY_FORMATS, formats, 0);
+                        for(int i=0; i<numFormats; i++) {
+                            info.shaderBinaryFormats.add(new Integer(formats[i]));
+                        }
                     }
-                }
+                } catch (GLException gle) { System.err.println("Catched Exception: "+gle.getMessage()); gle.printStackTrace(); }                    
             }
         }
         return info.shaderBinaryFormats;
@@ -180,17 +183,25 @@ public class ShaderUtil {
         final ProfileInformation info = getProfileInformation(gl);
         if(null==info.shaderCompilerAvailable) {
             if(gl.isGLES2()) {
-                final byte[] param = new byte[1];
-                gl.glGetBooleanv(GL2ES2.GL_SHADER_COMPILER, param, 0);
-                boolean v = param[0]!=(byte)0x00;
-                if(!v) {
-                    final Set<Integer> bfs = getShaderBinaryFormats(gl);
-                    if(bfs.size()==0) {
-                        // no supported binary formats, hence a compiler must be available!
-                        v = true;
+                boolean queryOK = false;
+                try {
+                    final byte[] param = new byte[1];
+                    gl.glGetBooleanv(GL2ES2.GL_SHADER_COMPILER, param, 0);
+                    final int err = gl.glGetError();
+                    boolean v = GL.GL_NO_ERROR == err && param[0]!=(byte)0x00;
+                    if(!v) {
+                        final Set<Integer> bfs = getShaderBinaryFormats(gl);
+                        if(bfs.size()==0) {
+                            // no supported binary formats, hence a compiler must be available!
+                            v = true;
+                        }
                     }
-                }
-                info.shaderCompilerAvailable = new Boolean(v);
+                    info.shaderCompilerAvailable = new Boolean(v);
+                    queryOK = true;
+                } catch (GLException gle) { System.err.println("Catched Exception: "+gle.getMessage()); gle.printStackTrace(); }
+                if(!queryOK) {
+                    info.shaderCompilerAvailable = new Boolean(true);
+                }                
             } else if( gl.isGL2ES2() ) {
                 info.shaderCompilerAvailable = new Boolean(true);
             } else {
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/FixedFuncUtil.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/FixedFuncUtil.java
index d92a7aa..a653bd4 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/FixedFuncUtil.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/FixedFuncUtil.java
@@ -4,26 +4,45 @@
 
 package com.jogamp.opengl.util.glsl.fixedfunc;
 
-import javax.media.opengl.*;
-import javax.media.opengl.fixedfunc.*;
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES1;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLException;
+import javax.media.opengl.fixedfunc.GLPointerFuncUtil;
+
+import jogamp.opengl.util.glsl.fixedfunc.FixedFuncHook;
+import jogamp.opengl.util.glsl.fixedfunc.FixedFuncImpl;
+import jogamp.opengl.util.glsl.fixedfunc.FixedFuncPipeline;
+
+import com.jogamp.opengl.util.PMVMatrix;
 
-import jogamp.opengl.util.glsl.fixedfunc.*;
 
 /**
  * Tool to pipeline GL2ES2 into a fixed function emulation implementing GL2ES1.
  */
 public class FixedFuncUtil {
     /**
+     * @param gl
+     * @param mode one of the {@link ShaderSelectionMode}s 
+     * @param pmvMatrix optional pass through PMVMatrix for the {@link FixedFuncHook} and {@link FixedFuncPipeline}
      * @return If gl is a GL2ES1 and force is false, return the type cast object,
      *         otherwise create a fixed function emulation pipeline using the given GL2ES2 impl
      *         and hook it to the GLContext via {@link GLContext#setGL(GL)}.
      * @throws GLException if the GL object is neither GL2ES1 nor GL2ES2
+     * 
+     * @see ShaderSelectionMode#AUTO
+     * @see ShaderSelectionMode#COLOR
+     * @see ShaderSelectionMode#COLOR_LIGHT_PER_VERTEX
+     * @see ShaderSelectionMode#COLOR_TEXTURE
+     * @see ShaderSelectionMode#COLOR_TEXTURE_LIGHT_PER_VERTEX
      */
-    public static final GL2ES1 wrapFixedFuncEmul(GL gl, boolean force) {
+    public static final GL2ES1 wrapFixedFuncEmul(GL gl, ShaderSelectionMode mode, PMVMatrix pmvMatrix, boolean force, boolean verbose) {
         if(gl.isGL2ES2() && ( !gl.isGL2ES1() || force ) ) {
-            GL2ES2 es2 = gl.getGL2ES2();
-            FixedFuncHook hook = new FixedFuncHook(es2);
-            FixedFuncImpl impl = new FixedFuncImpl(es2, hook);
+            final GL2ES2 es2 = gl.getGL2ES2();
+            final FixedFuncHook hook = new FixedFuncHook(es2, mode, pmvMatrix);
+            hook.setVerbose(verbose);
+            final FixedFuncImpl impl = new FixedFuncImpl(es2, hook);
             gl.getContext().setGL(impl);
             return impl;
         } else if(gl.isGL2ES1()) {
@@ -33,13 +52,22 @@ public class FixedFuncUtil {
     }
 
     /**
+     * @param gl
+     * @param mode one of the {@link ShaderSelectionMode}s 
+     * @param pmvMatrix optional pass through PMVMatrix for the {@link FixedFuncHook} and {@link FixedFuncPipeline}
      * @return If gl is a GL2ES1, return the type cast object,
      *         otherwise create a fixed function emulation pipeline using the GL2ES2 impl.
      *         and hook it to the GLContext via {@link GLContext#setGL(GL)}.
      * @throws GLException if the GL object is neither GL2ES1 nor GL2ES2
+     * 
+     * @see ShaderSelectionMode#AUTO
+     * @see ShaderSelectionMode#COLOR
+     * @see ShaderSelectionMode#COLOR_LIGHT_PER_VERTEX
+     * @see ShaderSelectionMode#COLOR_TEXTURE
+     * @see ShaderSelectionMode#COLOR_TEXTURE_LIGHT_PER_VERTEX
      */
-    public static final GL2ES1 wrapFixedFuncEmul(GL gl) {
-        return wrapFixedFuncEmul(gl, false);
+    public static final GL2ES1 wrapFixedFuncEmul(GL gl, ShaderSelectionMode mode, PMVMatrix pmvMatrix) {
+        return wrapFixedFuncEmul(gl, mode, null, false, false);
     }
 
     /**
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/ShaderSelectionMode.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/ShaderSelectionMode.java
new file mode 100644
index 0000000..e6bdf70
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/ShaderSelectionMode.java
@@ -0,0 +1,27 @@
+package com.jogamp.opengl.util.glsl.fixedfunc;
+
+/** 
+ * Shader selection mode
+ * 
+ * @see ShaderSelectionMode#AUTO
+ * @see ShaderSelectionMode#COLOR
+ * @see ShaderSelectionMode#COLOR_LIGHT_PER_VERTEX
+ * @see ShaderSelectionMode#COLOR_TEXTURE
+ * @see ShaderSelectionMode#COLOR_TEXTURE_LIGHT_PER_VERTEX
+ */
+public enum ShaderSelectionMode {
+    /** Auto shader selection, based upon FFP states. */
+    AUTO, 
+    /** Fixed shader selection: Simple color. */
+    COLOR, 
+    /** Fixed shader selection: Multi-Textured color. 2 texture units. */
+    COLOR_TEXTURE2, 
+    /** Fixed shader selection: Multi-Textured color. 4 texture units. */
+    COLOR_TEXTURE4, 
+    /** Fixed shader selection: Multi-Textured color. 8 texture units. */
+    COLOR_TEXTURE8, 
+    /** Fixed shader selection: Color with vertex-lighting. */
+    COLOR_LIGHT_PER_VERTEX, 
+    /** Fixed shader selection: Multi-Textured color with vertex-lighting. 8 texture units.*/
+    COLOR_TEXTURE8_LIGHT_PER_VERTEX 
+}
\ No newline at end of file
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java b/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java
index e7bf87a..6e66e3d 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java
@@ -833,9 +833,14 @@ public class Texture {
     }
 
     /**
-     * Returns the underlying OpenGL texture object for this texture.
+     * Returns the underlying OpenGL texture object for this texture
+     * and generates it if not done yet.
+     * <p>
      * Most applications will not need to access this, since it is
      * handled automatically by the bind(GL) and destroy(GL) APIs.
+     * </p>
+     * @param gl required to be valid and current in case the texture object has not been generated yet,
+     *           otherwise it may be <code>null</code>.
      */
     public int getTextureObject(GL gl) {
         validateTexID(gl, false);
@@ -1089,7 +1094,7 @@ public class Texture {
         // Prefer GL_ARB_texture_rectangle on ATI hardware on Mac OS X
         // due to software fallbacks
 
-        if (NativeWindowFactory.TYPE_MACOSX.equals(NativeWindowFactory.getNativeWindowType(false))) {
+        if (NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false)) {
             String vendor = gl.glGetString(GL.GL_VENDOR);
             if (vendor != null && vendor.startsWith("ATI")) {
                 return true;
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/LEDataInputStream.java b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/LEDataInputStream.java
index 37dbc54..b7262aa 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/LEDataInputStream.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/LEDataInputStream.java
@@ -180,7 +180,7 @@ public class LEDataInputStream extends FilterInputStream implements DataInput
     {
         int    i1 = readInt();
         int    i2 = readInt();
-        return ((long)(i1) & 0xFFFFFFFFL) +    (i2    << 32);
+        return ((long)i1 & 0xFFFFFFFFL) + ((long)i2 << 32);
     }
 
     public final float readFloat() throws IOException
diff --git a/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java b/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java
index 5fa8ce3..b052769 100644
--- a/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java
+++ b/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java
@@ -87,20 +87,20 @@ import jogamp.opengl.Debug;
 public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser {
   private static final boolean DEBUG = Debug.isPropertyDefined("jogl.debug.CapabilitiesChooser", true);
 
-  final static int NO_SCORE = -9999999;
-  final static int DOUBLE_BUFFER_MISMATCH_PENALTY = 1000;
-  final static int OPAQUE_MISMATCH_PENALTY = 750;
-  final static int STENCIL_MISMATCH_PENALTY = 500;
-  final static int MULTISAMPLE_MISMATCH_PENALTY = 500;
-  final static int MULTISAMPLE_EXTENSION_MISMATCH_PENALTY = 250; // just a little drop, no scale
+  private final static int NO_SCORE = -9999999;
+  private final static int DOUBLE_BUFFER_MISMATCH_PENALTY = 1000;
+  private final static int OPAQUE_MISMATCH_PENALTY = 750;
+  private final static int STENCIL_MISMATCH_PENALTY = 500;
+  private final static int MULTISAMPLE_MISMATCH_PENALTY = 500;
+  private final static int MULTISAMPLE_EXTENSION_MISMATCH_PENALTY = 250; // just a little drop, no scale
   // Pseudo attempt to keep equal rank penalties scale-equivalent
   // (e.g., stencil mismatch is 3 * accum because there are 3 accum
   // components)
-  final static int COLOR_MISMATCH_PENALTY_SCALE     = 36;
-  final static int DEPTH_MISMATCH_PENALTY_SCALE     = 6;
-  final static int ACCUM_MISMATCH_PENALTY_SCALE     = 1;
-  final static int STENCIL_MISMATCH_PENALTY_SCALE   = 3;
-  final static int MULTISAMPLE_MISMATCH_PENALTY_SCALE   = 3;
+  private final static int COLOR_MISMATCH_PENALTY_SCALE     = 36;
+  private final static int DEPTH_MISMATCH_PENALTY_SCALE     = 6;
+  private final static int ACCUM_MISMATCH_PENALTY_SCALE     = 1;
+  private final static int STENCIL_MISMATCH_PENALTY_SCALE   = 3;
+  private final static int MULTISAMPLE_MISMATCH_PENALTY_SCALE   = 3;
   
   @Override
   public int chooseCapabilities(final CapabilitiesImmutable desired,
@@ -150,11 +150,20 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser {
       if (cur == null) {
         continue;
       }
-      if (gldes.isOnscreen() != cur.isOnscreen()) {
-        continue;
+      if (gldes.isOnscreen() && !cur.isOnscreen()) {
+        continue; // requested onscreen, but n/a
       }
-      if (!gldes.isOnscreen() && gldes.isPBuffer() && !cur.isPBuffer()) {
-        continue; // only skip if requested Offscreen && PBuffer, but no PBuffer available
+      if (!gldes.isOnscreen()) {
+          /** FBO is generic ..
+          if (gldes.isFBO() && !cur.isFBO()) {
+            continue; // requested FBO, but n/a
+          }  */
+          if (gldes.isPBuffer() && !cur.isPBuffer()) {
+            continue; // requested pBuffer, but n/a
+          }          
+          if (gldes.isBitmap() && !cur.isBitmap()) {
+            continue; // requested pBuffer, but n/a
+          }          
       }
       if (gldes.getStereo() != cur.getStereo()) {
         continue;
diff --git a/src/jogl/classes/javax/media/opengl/GLArrayData.java b/src/jogl/classes/javax/media/opengl/GLArrayData.java
index 7c56b53..5d17f68 100644
--- a/src/jogl/classes/javax/media/opengl/GLArrayData.java
+++ b/src/jogl/classes/javax/media/opengl/GLArrayData.java
@@ -145,7 +145,11 @@ public interface GLArrayData {
 
     /**
      * True, if GL shall normalize fixed point data while converting 
-     * them into float
+     * them into float.
+     * <p> 
+     * Default behavior (of the fixed function pipeline) is <code>true</code>
+     * for fixed point data type and <code>false</code> for floating point data types.
+     * </p>
      */
     public boolean getNormalized();
 
diff --git a/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java b/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java
index 0b2c664..38f1746 100644
--- a/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java
+++ b/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java
@@ -115,6 +115,12 @@ public interface GLAutoDrawable extends GLDrawable {
   public static final boolean SCREEN_CHANGE_ACTION_ENABLED = Debug.getBooleanProperty("jogl.screenchange.action", true);
 
   /**
+   * If the implementation uses delegation, return the delegated {@link GLDrawable} instance,
+   * otherwise return <code>this</code> instance.
+   */
+  public GLDrawable getDelegatedDrawable();
+  
+  /**
    * Returns the context associated with this drawable. The returned
    * context will be synchronized.
    * Don't rely on it's identity, the context may change.
@@ -124,23 +130,31 @@ public interface GLAutoDrawable extends GLDrawable {
   /**
    * Associate a new context to this drawable and also propagates the context/drawable switch by 
    * calling {@link GLContext#setGLDrawable(GLDrawable, boolean) newCtx.setGLDrawable(drawable, true);}.
-   * <code>drawable</code> might be an inner GLDrawable instance if using such a delegation pattern,
-   * or this GLAutoDrawable itself. 
-   * <p>
-   * If the old context's drawable was an {@link GLAutoDrawable}, it's reference to the given drawable
-   * is being cleared by calling 
-   * {@link GLAutoDrawable#setContext(GLContext) ((GLAutoDrawable)oldCtx.getGLDrawable()).setContext(null)}.
-   * </p>
+   * <code>drawable</code> might be an inner GLDrawable instance if using a delegation pattern,
+   * or this GLAutoDrawable instance.
    * <p>
    * If the old or new context was current on this thread, it is being released before switching the drawable.
    * The new context will be made current afterwards, if it was current before. 
-   * However the user shall take extra care that not other thread
-   * attempts to make this context current. Otherwise a race condition may happen.
+   * However the user shall take extra care that no other thread
+   * attempts to make this context current.
+   * </p>
+   * <p>
+   * Be aware that the old context is still bound to the drawable, 
+   * and that one context can only be bound to one drawable at one time!
    * </p>
    * <p>
-   * <b>Disclaimer</b>: Even though the API may allows this functionality in theory, your mileage may vary 
-   * switching the drawable of an already established GLContext, i.e. which is already made current once.
-   * FIXME: Validate functionality! 
+   * In case you do not intend to use the old context anymore, i.e. 
+   * not assigning it to another drawable, it shall be 
+   * destroyed before setting the new context, i.e.:
+   * <pre>
+            GLContext oldCtx = glad.getContext();
+            if(null != oldCtx) {
+                oldCtx.destroy();
+            }
+            glad.setContext(newCtx);            
+   * </pre> 
+   * This is required, since a context must have a valid drawable at all times
+   * and this API shall not restrict the user in any way. 
    * </p>
    * 
    * @param newCtx the new context
diff --git a/src/jogl/classes/javax/media/opengl/GLBase.java b/src/jogl/classes/javax/media/opengl/GLBase.java
index f5831a7..9bcee81 100644
--- a/src/jogl/classes/javax/media/opengl/GLBase.java
+++ b/src/jogl/classes/javax/media/opengl/GLBase.java
@@ -273,6 +273,42 @@ public interface GLBase {
     */
    public boolean isExtensionAvailable(String glExtensionName);
 
+   /** 
+    * 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
+    * <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>
+    * Basic FBO support may only include one color attachment and no multisampling,
+    * as well as limited internal formats for renderbuffer.
+    * </p>
+    * @see GLContext#hasBasicFBOSupport()
+    */
+   public boolean hasBasicFBOSupport();
+
+   /** 
+    * 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
+    * <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>.
+    * </p>
+    * <p>
+    * Full FBO support includes multiple color attachments and multisampling.
+    * </p>
+    * @see GLContext#hasFullFBOSupport()
+    */
+   public boolean hasFullFBOSupport();
+
+   /**
+    * Returns the maximum number of FBO RENDERBUFFER samples
+    * if {@link #hasFullFBOSupport() full FBO is supported}, otherwise false. 
+    * @see GLContext#getMaxRenderbufferSamples()
+    */
+   public int getMaxRenderbufferSamples();
+
    /**
     * Returns true if the GL context supports non power of two (NPOT) textures,
     * otherwise false.
@@ -284,6 +320,8 @@ public interface GLBase {
     */
    public boolean isNPOTTextureAvailable();
 
+   public boolean isTextureFormatBGRA8888Available();
+   
    /** Provides a platform-independent way to specify the minimum swap
        interval for buffer swaps. An argument of 0 disables
        sync-to-vertical-refresh completely, while an argument of 1
diff --git a/src/jogl/classes/javax/media/opengl/GLCapabilities.java b/src/jogl/classes/javax/media/opengl/GLCapabilities.java
index 8845ec6..9b004a0 100644
--- a/src/jogl/classes/javax/media/opengl/GLCapabilities.java
+++ b/src/jogl/classes/javax/media/opengl/GLCapabilities.java
@@ -102,23 +102,52 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil
     }
   }
 
+  /**
+   * Copies all {@link GLCapabilities} and {@link Capabilities} values 
+   * from <code>source</code> into this instance.
+   * @return this instance
+   */
+  public GLCapabilities copyFrom(GLCapabilitiesImmutable source) {
+    super.copyFrom(source);
+    glProfile = source.getGLProfile();
+    isPBuffer = source.isPBuffer();
+    isFBO = source.isFBO();
+    doubleBuffered = source.getDoubleBuffered();
+    stereo = source.getStereo();
+    hardwareAccelerated = source.getHardwareAccelerated();
+    depthBits = source.getDepthBits();
+    stencilBits = source.getStencilBits();
+    accumRedBits = source.getAccumRedBits();
+    accumGreenBits = source.getAccumGreenBits();
+    accumBlueBits = source.getAccumBlueBits();
+    accumAlphaBits = source.getAccumAlphaBits();
+    sampleBuffers = source.getSampleBuffers();
+    pbufferFloatingPointBuffers = source.getPbufferFloatingPointBuffers();
+    pbufferRenderToTexture = source.getPbufferRenderToTexture();
+    pbufferRenderToTextureRectangle = source.getPbufferRenderToTextureRectangle();
+    numSamples = source.getNumSamples();
+    sampleExtension = source.getSampleExtension();
+    return this;
+  }
+  
   @Override
   public int hashCode() {
     // 31 * x == (x << 5) - x
-    int hash = 31 + this.glProfile.hashCode() ;
+    int hash = super.hashCode(); 
+    hash = ((hash << 5) - hash) + this.glProfile.hashCode() ;
+    hash = ((hash << 5) - hash) + ( this.hardwareAccelerated ? 1 : 0 );
+    hash = ((hash << 5) - hash) + ( this.stereo ? 1 : 0 );
     hash = ((hash << 5) - hash) + ( this.isFBO ? 1 : 0 );
     hash = ((hash << 5) - hash) + ( this.isPBuffer ? 1 : 0 );
-    hash = ((hash << 5) - hash) + ( this.stereo ? 1 : 0 );
-    hash = ((hash << 5) - hash) + ( this.hardwareAccelerated ? 1 : 0 );
+    hash = ((hash << 5) - hash) + ( this.sampleBuffers ? 1 : 0 );
+    hash = ((hash << 5) - hash) + this.getNumSamples();
+    hash = ((hash << 5) - hash) + this.sampleExtension.hashCode();
     hash = ((hash << 5) - hash) + this.depthBits;
     hash = ((hash << 5) - hash) + this.stencilBits;
     hash = ((hash << 5) - hash) + this.accumRedBits;
     hash = ((hash << 5) - hash) + this.accumGreenBits;
     hash = ((hash << 5) - hash) + this.accumBlueBits;
     hash = ((hash << 5) - hash) + this.accumAlphaBits;
-    hash = ((hash << 5) - hash) + ( this.sampleBuffers ? 1 : 0 );
-    hash = ((hash << 5) - hash) + this.numSamples;
-    hash = ((hash << 5) - hash) + this.sampleExtension.hashCode();
     hash = ((hash << 5) - hash) + ( this.pbufferFloatingPointBuffers ? 1 : 0 );
     hash = ((hash << 5) - hash) + ( this.pbufferRenderToTexture ? 1 : 0 );
     hash = ((hash << 5) - hash) + ( this.pbufferRenderToTextureRectangle ? 1 : 0 );
@@ -136,6 +165,7 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil
                   other.getGLProfile()==glProfile &&
                   other.isPBuffer()==isPBuffer &&
                   other.isFBO()==isFBO &&
+                  other.getDoubleBuffered() == doubleBuffered &&
                   other.getStereo()==stereo &&
                   other.getHardwareAccelerated()==hardwareAccelerated &&
                   other.getDepthBits()==depthBits &&
@@ -148,9 +178,8 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil
                   other.getPbufferFloatingPointBuffers()==pbufferFloatingPointBuffers &&
                   other.getPbufferRenderToTexture()==pbufferRenderToTexture &&
                   other.getPbufferRenderToTextureRectangle()==pbufferRenderToTextureRectangle;
-    if(sampleBuffers) {
-        res = res &&
-              other.getNumSamples()==numSamples &&
+    if(res && sampleBuffers) {
+        res = other.getNumSamples()==getNumSamples() &&
               other.getSampleExtension().equals(sampleExtension) ;
     }
     return res;
@@ -222,19 +251,24 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil
   public void setGLProfile(GLProfile profile) {
     glProfile=profile;
   }
-
+  
   @Override
   public final boolean isPBuffer() {
     return isPBuffer;
   }
 
   /**
-   * Enables or disables pbuffer usage.
+   * Requesting offscreen pbuffer mode.
    * <p>
    * If enabled this method also invokes {@link #setOnscreen(int) setOnscreen(false)}.
    * </p>
+   * <p>
    * Defaults to false.
-   */
+   * </p>
+   * <p>
+   * Requesting offscreen pbuffer mode disables the offscreen auto selection.
+   * </p>
+   */  
   public void setPBuffer(boolean enable) {
     if(enable) {
       setOnscreen(false);
@@ -248,11 +282,16 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil
   }
   
   /**
-   * Enables or disables FBO usage.
+   * Requesting offscreen FBO mode.
    * <p>
    * If enabled this method also invokes {@link #setOnscreen(int) setOnscreen(false)}.
    * </p>
+   * <p>
    * Defaults to false.
+   * </p>
+   * <p>
+   * Requesting offscreen FBO mode disables the offscreen auto selection.
+   * </p>
    */
   public void setFBO(boolean enable) {
     if(enable) {
@@ -261,21 +300,6 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil
     isFBO = enable;
   }
 
-  /**
-   * Sets whether the drawable surface supports onscreen.<br>
-   * If enabled this method also invokes {@link #setPBuffer(int) setPBuffer(false)}
-   * and {@link #setFBO(int) setFBO(false)}<br>
-   * Defaults to true.
-  */
-  @Override
-  public void setOnscreen(boolean onscreen) {
-    if(onscreen) {
-        setPBuffer(false);
-        setFBO(false);
-    }
-    super.setOnscreen(onscreen);
-  }
-
   @Override
   public final boolean getDoubleBuffered() {
     return doubleBuffered;
@@ -465,9 +489,9 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil
         sink = new StringBuilder();
     }
 
-    int samples = sampleBuffers ? numSamples : 0 ;
+    final int samples = sampleBuffers ? numSamples : 0 ;
 
-    super.toString(sink);
+    super.toString(sink, false);
 
     sink.append(", accum-rgba ").append(accumRedBits).append("/").append(accumGreenBits).append("/").append(accumBlueBits).append("/").append(accumAlphaBits);
     sink.append(", dp/st/ms: ").append(depthBits).append("/").append(stencilBits).append("/").append(samples);
@@ -490,20 +514,37 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil
         sink.append(", sw, ");
     }
     sink.append(glProfile);
-    if(!isOnscreen()) {
-        if(isFBO) {
-            sink.append(", fbo");
-        } 
-        if(isPBuffer) {
-            sink.append(", pbuffer [r2t ").append(pbufferRenderToTexture?1:0)
-                .append(", r2tr ").append(pbufferRenderToTextureRectangle?1:0)
-                .append(", float ").append(pbufferFloatingPointBuffers?1:0)
-                .append("]");
-        } 
-        if(!isFBO && !isPBuffer) {
-            sink.append(", pixmap");
+    if(isOnscreen()) {
+        sink.append(", on-scr[");
+    } else {
+        sink.append(", offscr[");
+    }
+    boolean ns=false;
+    if(isFBO()) {
+        sink.append("fbo");
+        ns = true;
+    }
+    if(isPBuffer()) {
+        if(ns) { sink.append(", "); }
+        sink.append("pbuffer [r2t ").append(pbufferRenderToTexture?1:0)
+            .append(", r2tr ").append(pbufferRenderToTextureRectangle?1:0)
+            .append(", float ").append(pbufferFloatingPointBuffers?1:0)
+            .append("]");                
+        ns = true;
+    }
+    if(isBitmap()) {
+        if(ns) { sink.append(", "); }
+        sink.append("bitmap");
+        ns = true;
+    }
+    if(!ns) { // !FBO !PBuffer !Bitmap
+        if(isOnscreen()) {
+            sink.append(".");        // no additional off-screen modes besides on-screen
+        } else {
+            sink.append("auto-cfg"); // auto-config off-screen mode            
         }
     }
+    sink.append("]");
 
     return sink;
   }
diff --git a/src/jogl/classes/javax/media/opengl/GLCapabilitiesImmutable.java b/src/jogl/classes/javax/media/opengl/GLCapabilitiesImmutable.java
index 7e0459b..ee261ca 100644
--- a/src/jogl/classes/javax/media/opengl/GLCapabilitiesImmutable.java
+++ b/src/jogl/classes/javax/media/opengl/GLCapabilitiesImmutable.java
@@ -50,7 +50,7 @@ public interface GLCapabilitiesImmutable extends CapabilitiesImmutable {
     GLProfile getGLProfile();
 
     /**
-     * Returns the number of bits requested for the accumulation
+     * Returns the number of bits for the accumulation
      * buffer's alpha component. On some systems only the accumulation
      * buffer depth, which is the sum of the red, green, and blue bits,
      * is considered.
@@ -58,7 +58,7 @@ public interface GLCapabilitiesImmutable extends CapabilitiesImmutable {
     int getAccumAlphaBits();
 
     /**
-     * Returns the number of bits requested for the accumulation
+     * Returns the number of bits for the accumulation
      * buffer's blue component. On some systems only the accumulation
      * buffer depth, which is the sum of the red, green, and blue bits,
      * is considered.
@@ -66,7 +66,7 @@ public interface GLCapabilitiesImmutable extends CapabilitiesImmutable {
     int getAccumBlueBits();
 
     /**
-     * Returns the number of bits requested for the accumulation
+     * Returns the number of bits for the accumulation
      * buffer's green component. On some systems only the accumulation
      * buffer depth, which is the sum of the red, green, and blue bits,
      * is considered.
@@ -74,7 +74,7 @@ public interface GLCapabilitiesImmutable extends CapabilitiesImmutable {
     int getAccumGreenBits();
 
     /**
-     * Returns the number of bits requested for the accumulation
+     * Returns the number of bits for the accumulation
      * buffer's red component. On some systems only the accumulation
      * buffer depth, which is the sum of the red, green, and blue bits,
      * is considered.
@@ -82,74 +82,115 @@ public interface GLCapabilitiesImmutable extends CapabilitiesImmutable {
     int getAccumRedBits();
 
     /**
-     * Returns the number of bits requested for the depth buffer.
+     * Returns the number of depth buffer bits.
      */
     int getDepthBits();
 
     /**
-     * Indicates whether double-buffering is enabled.
+     * Returns whether double-buffering is requested, available or chosen.
+     * <p>
+     * Default is true.
+     * </p>
      */
     boolean getDoubleBuffered();
 
     /**
-     * Indicates whether hardware acceleration is enabled.
+     * Returns whether hardware acceleration is requested, available or chosen.
+     * <p>
+     * Default is true.
+     * </p>
      */
     boolean getHardwareAccelerated();
 
     /**
-     * Returns the used extension for full-scene antialiasing
-     * (FSAA), default is {@link #DEFAULT_SAMPLE_EXTENSION}.
+     * Returns the extension for full-scene antialiasing
+     * (FSAA).
+     * <p>
+     * Default is {@link #DEFAULT_SAMPLE_EXTENSION}.
+     * </p>
      */
     String getSampleExtension();
     
     /**
      * Returns whether sample buffers for full-scene antialiasing
-     * (FSAA) should be allocated for this drawable. Defaults to
-     * false.
+     * (FSAA) should be allocated for this drawable. 
+     * <p>
+     * Default is false.
+     * </p>
      */
     boolean getSampleBuffers();
 
     /**
      * Returns the number of sample buffers to be allocated if sample
-     * buffers are enabled, otherwise returns 0. Defaults to 2.
+     * buffers are enabled, otherwise returns 0.
+     * <p>
+     * Default is 0 due to disable sample buffers per default.
+     * </p>
      */
     int getNumSamples();
 
     /**
      * For pbuffers only, returns whether floating-point buffers should
-     * be used if available. Defaults to false.
+     * be used if available. 
+     * <p>
+     * Default is false.
+     * </p>
      */
     boolean getPbufferFloatingPointBuffers();
 
     /**
      * For pbuffers only, returns whether the render-to-texture
-     * extension should be used if available.  Defaults to false.
+     * extension should be used if available.  
+     * <p>
+     * Default is false.
+     * </p>
      */
     boolean getPbufferRenderToTexture();
 
     /**
      * For pbuffers only, returns whether the render-to-texture
-     * extension should be used. Defaults to false.
+     * extension should be used. 
+     * <p>
+     * Default is false.
+     * </p>
      */
     boolean getPbufferRenderToTextureRectangle();
 
     /**
-     * Returns the number of bits requested for the stencil buffer.
+     * Returns the number of stencil buffer bits.
+     * <p>
+     * Default is 0.
+     * </p>
      */
     int getStencilBits();
 
     /**
-     * Indicates whether stereo is enabled.
+     * Returns whether stereo is requested, available or chosen.
+     * <p>
+     * Default is false.
+     * </p>
      */
     boolean getStereo();
 
     /**
-     * Indicates whether pbuffer offscreen is used/requested.
+     * Returns whether pbuffer offscreen mode is requested, available or chosen.
+     * <p>
+     * Default is false.
+     * </p>
+     * <p>
+     * For chosen capabilities, only the selected offscreen surface is set to <code>true</code>.
+     * </p>
      */
     boolean isPBuffer();
 
     /**
-     * Indicates whether FBO offscreen is used/requested.
+     * Returns whether FBO offscreen mode is requested, available or chosen.
+     * <p>
+     * Default is false.
+     * </p>
+     * <p>
+     * For chosen capabilities, only the selected offscreen surface is set to <code>true</code>.
+     * </p>
      */
     boolean isFBO();
 
diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java
index 63a02ad..de10a28 100644
--- a/src/jogl/classes/javax/media/opengl/GLContext.java
+++ b/src/jogl/classes/javax/media/opengl/GLContext.java
@@ -52,10 +52,11 @@ import jogamp.opengl.Debug;
 import jogamp.opengl.GLContextImpl;
 
 import com.jogamp.common.os.Platform;
-import com.jogamp.common.util.IntObjectHashMap;
+import com.jogamp.common.util.VersionNumber;
 import com.jogamp.common.util.locks.LockFactory;
 import com.jogamp.common.util.locks.RecursiveLock;
 import com.jogamp.opengl.GLExtensions;
+import com.jogamp.opengl.GLRendererQuirks;
 
 /** Abstraction for an OpenGL rendering context. In order to perform
     OpenGL rendering, a context must be "made current" on the current
@@ -97,6 +98,9 @@ public abstract class GLContext {
    */
   public static final boolean PROFILE_ALIASING = !Debug.isPropertyDefined("jogl.debug.GLContext.NoProfileAliasing", true);
   
+  protected static final boolean FORCE_NO_FBO_SUPPORT = Debug.isPropertyDefined("jogl.fbo.force.none", true);
+  protected static final boolean FORCE_MIN_FBO_SUPPORT = Debug.isPropertyDefined("jogl.fbo.force.min", true);
+  
   public static final boolean DEBUG = Debug.debug("GLContext");
   public static final boolean TRACE_SWITCH = Debug.isPropertyDefined("jogl.debug.GLContext.TraceSwitch", true);
 
@@ -128,9 +132,9 @@ public abstract class GLContext {
   /** <code>GL_ARB_ES2_compatibility</code> implementation related: Context is compatible w/ ES2. Not a cache key. See {@link #isGLES2Compatible()}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */
   protected static final int CTX_IMPL_ES2_COMPAT = 1 <<  8;
 
-  /** Context supports basic FBO, details see {@link #hasFBO()}.
+  /** Context supports basic FBO, details see {@link #hasBasicFBOSupport()}.
    * Not a cache key.
-   * @see #hasFBO()
+   * @see #hasBasicFBOSupport()
    * @see #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)
    */
   protected static final int CTX_IMPL_FBO        = 1 <<  9;
@@ -140,8 +144,7 @@ public abstract class GLContext {
 
   private static final ThreadLocal<GLContext> currentContext = new ThreadLocal<GLContext>();
 
-  private final HashMap<String, Object> attachedObjectsByString = new HashMap<String, Object>();
-  private final IntObjectHashMap attachedObjectsByInt = new IntObjectHashMap();
+  private final HashMap<String, Object> attachedObjects = new HashMap<String, Object>();
 
   // RecursiveLock maintains a queue of waiting Threads, ensuring the longest waiting thread will be notified at unlock.
   protected final RecursiveLock lock = LockFactory.createRecursiveLock();
@@ -157,8 +160,13 @@ public abstract class GLContext {
   protected int ctxMinorVersion;
   protected int ctxOptions;
   protected String ctxVersionString;
+  protected VersionNumber ctxGLSLVersion;
   private int currentSwapInterval;
+  protected GLRendererQuirks glRendererQuirks;
 
+  /** Did the drawable association changed ? see {@link GLRendererQuirks#NoSetSwapIntervalPostRetarget} */ 
+  protected boolean drawableRetargeted; 
+    
   protected void resetStates() {
       if (DEBUG) {
         System.err.println(getThreadName() + ": GLContext.resetStates()");
@@ -168,12 +176,36 @@ public abstract class GLContext {
       ctxMinorVersion=-1;
       ctxOptions=0;
       ctxVersionString=null;
-      attachedObjectsByString.clear();
-      attachedObjectsByInt.clear();
+      ctxGLSLVersion=null;
+      attachedObjects.clear();
       contextHandle=0;
       currentSwapInterval = -1;
+      glRendererQuirks = null;
+      drawableRetargeted = false;
   }
 
+  /** 
+   * Returns the instance of {@link GLRendererQuirks}, allowing one to determine workarounds.
+   * @return instance of {@link GLRendererQuirks} if context was made current once, otherwise <code>null</code>.
+   */
+  public final GLRendererQuirks getRendererQuirks() { return glRendererQuirks; }
+  
+  /**
+   * Returns true if the <code>quirk</code> exist in {@link #getRendererQuirks()}, otherwise false.
+   * <p>
+   * Convenience method for:
+   * <pre>
+   *    final GLRendererQuirks glrq = ctx.getRendererQuirks();
+   *    boolean hasQuirk = null != glrq ? glrq.exist(quirk) : false ;
+   * </pre>
+   * </p>
+   * @param quirk the quirk to be tested, e.g. {@link GLRendererQuirks#NoDoubleBufferedPBuffer}.
+   * @throws IllegalArgumentException if the quirk is out of range
+   */
+  public final boolean hasRendererQuirk(int quirk) throws IllegalArgumentException { 
+      return null != glRendererQuirks ? glRendererQuirks.exist(quirk) : false ; 
+  }
+  
   /**
    * Sets the read/write drawable for framebuffer operations.
    * <p>
@@ -181,11 +213,6 @@ public abstract class GLContext {
    * and made current afterwards. However the user shall take extra care that not other thread
    * attempts to make this context current. Otherwise a race condition may happen.
    * </p>
-   * <p>
-   * <b>Disclaimer</b>: Even though the API may allows this functionality in theory, your mileage may vary 
-   * switching the drawable of an already established GLContext, i.e. which is already made current once.
-   * FIXME: Validate functionality! 
-   * </p>
    * @param readWrite the read/write drawable for framebuffer operations.
    * @param setWriteOnly if <code>true</code> and if the current read-drawable differs 
    *        from the write-drawable ({@link #setGLReadDrawable(GLDrawable)}), 
@@ -250,19 +277,23 @@ public abstract class GLContext {
    * Makes this GLContext current on the calling thread.
    * <p>
    * There are two return values that indicate success and one that
-   * indicates failure. A return value of CONTEXT_CURRENT_NEW
-   * indicates that that context has been made current, and that
-   * this is the first time this context has been made current, or
-   * that the state of the underlying context or drawable may have
-   * changed since the last time this context was made current. In
-   * this case, the application may wish to initialize the state.  A
-   * return value of CONTEXT_CURRENT indicates that the context has
+   * indicates failure.
+   * </p>
+   * <p>
+   * A return value of {@link #CONTEXT_CURRENT_NEW}
+   * indicates that that context has been made current for the 1st time, 
+   * or that the state of the underlying context or drawable has
+   * changed since the last time this context was current. 
+   * In this case, the application may wish to initialize the render state.
+   * </p>
+   * <p>
+   * A return value of {@link #CONTEXT_CURRENT} indicates that the context has
    * been made currrent, with its previous state restored.
    * </p>
    * <p>
    * If the context could not be made current (for example, because
    * the underlying drawable has not ben realized on the display) ,
-   * a value of CONTEXT_NOT_CURRENT is returned.
+   * a value of {@link #CONTEXT_NOT_CURRENT} is returned.
    * </p>
    * <p>
    * This method is blocking, i.e. waits until another thread has
@@ -273,11 +304,11 @@ public abstract class GLContext {
    * and unlocked at {@link #release()}
    * </p>
    *
-   * @return CONTEXT_CURRENT if the context was successfully made current
-   * @return CONTEXT_CURRENT_NEW if the context was successfully made
-   * current, but need to be initialized.
-   *
-   * @return CONTEXT_NOT_CURRENT if the context could not be made current.
+   * @return <ul>
+   *           <li>{@link #CONTEXT_CURRENT_NEW} if the context was successfully made current the 1st time,</li> 
+   *           <li>{@link #CONTEXT_CURRENT} if the context was successfully made current,</li>
+   *           <li>{@link #CONTEXT_NOT_CURRENT} if the context could not be made current.</li>
+   *         </ul>
    *
    * @throws GLException if synchronization is disabled and the
    * context is current on another thread, or because the context
@@ -425,27 +456,8 @@ public abstract class GLContext {
   /**
    * Returns the attached user object for the given name to this GLContext.
    */
-  public final Object getAttachedObject(int name) {
-    return attachedObjectsByInt.get(name);
-  }
-
-  /**
-   * Returns the attached user object for the given name to this GLContext.
-   */
   public final Object getAttachedObject(String name) {
-    return attachedObjectsByString.get(name);
-  }
-
-  /**
-   * Sets the attached user object for the given name to this GLContext.
-   * Returns the previously set object or null.
-   */
-  public final Object attachObject(int name, Object obj) {
-    return attachedObjectsByInt.put(name, obj);
-  }
-
-  public final Object detachObject(int name) {
-      return attachedObjectsByInt.remove(name);
+    return attachedObjects.get(name);
   }
 
   /**
@@ -453,11 +465,11 @@ public abstract class GLContext {
    * Returns the previously set object or null.
    */
   public final Object attachObject(String name, Object obj) {
-    return attachedObjectsByString.put(name, obj);
+    return attachedObjects.put(name, obj);
   }
 
   public final Object detachObject(String name) {
-      return attachedObjectsByString.remove(name);
+      return attachedObjects.remove(name);
   }
 
   /**
@@ -488,6 +500,12 @@ public abstract class GLContext {
     sb.append(toHexString(contextHandle));
     sb.append(", ");
     sb.append(getGL());
+    sb.append(",\n\t quirks: ");
+    if(null != glRendererQuirks) {
+        glRendererQuirks.toString(sb);
+    } else {
+        sb.append("n/a");
+    }
     if(getGLDrawable()!=getGLReadDrawable()) {
         sb.append(",\n\tRead Drawable : ");
         sb.append(getGLReadDrawable());
@@ -497,8 +515,6 @@ public abstract class GLContext {
         sb.append(",\n\tDrawable: ");
         sb.append(getGLDrawable());
     }
-    sb.append(", lock ");
-    sb.append(lock.toString());
     return sb;
   }
 
@@ -616,6 +632,78 @@ public abstract class GLContext {
   public final boolean isCreatedWithARBMethod()   { return ( 0 != ( CTX_IS_ARB_CREATED & ctxOptions ) ); }
 
   /**
+   * Returns the matching GLSL version number, queried by this context GL
+   * via {@link GL2ES2#GL_SHADING_LANGUAGE_VERSION} if ≥ ES2.0 or GL2.0,
+   * otherwise a static match is being utilized.
+   * <p>
+   * The context must have been current once, otherwise <code>null</code> is returned. 
+   * </p>
+   * <p>
+   * Examples w/ <code>major.minor</code>: 
+   * <pre>
+   *    1.00 (ES2.0), 1.10 (GL2.0), 1.20 (GL2.1), 1.50 GL(3.2), 
+   *    3.30 (GL3.3), 4.40 (GL4.0)
+   * </pre >
+   * </p>
+   * <p>
+   * <i>Matching</i> could also refer to the maximum GLSL version usable by this context
+   * since <i>normal</i> GL implementations are capable of using a lower GLSL version as well.
+   * The latter is not true on OSX w/ a GL3 context. 
+   * </p>
+   * 
+   * @param GLSL version number if context has been made current at least once, otherwise <code>null</code>.
+   *            
+   * @see #getGLVersionMajor()
+   * @see #getGLVersionMinor()
+   */
+  public final VersionNumber getGLSLVersionNumber() {
+      return ctxGLSLVersion;
+  }
+  
+  /**
+   * Returns the GLSL version string as to be used in a shader program, including a terminating newline '\n',
+   * i.e.:
+   * <pre>
+   *    #version 110
+   * </pre>
+   * <p>
+   * If context has not been made current, <code>null</code> is returned.
+   * </p>
+   * @see #getGLSLVersionNumber()
+   */
+  public final String getGLSLVersionString() {
+      if(null == ctxGLSLVersion) {
+          return null;
+      }
+      final int minor = ctxGLSLVersion.getMinor();
+      return "#version " + ctxGLSLVersion.getMajor() + ( minor < 10 ? "0"+minor : minor ) + "\n" ;
+  }
+  
+  protected static final void getStaticGLSLVersionNumber(int glMajorVersion, int glMinorVersion, int ctxOptions, int[] res) {
+      if( 0 != ( CTX_PROFILE_ES & ctxOptions ) ) {
+          res[0] = 1; res[1] =  0;      // ES 2.0  ->  GLSL 1.00
+      } else if( 1 == glMajorVersion ) {
+          res[0] = 1; res[0] = 10;      // GL 1.x  ->  GLSL 1.10
+      } else if( 2 == glMajorVersion ) {
+          res[0] = 1;
+          switch ( glMinorVersion ) {
+          case 0:  res[1] = 10; break;  // GL 2.0  ->  GLSL 1.10
+          default: res[1] = 20; break;  // GL 2.1  ->  GLSL 1.20
+          }
+      } else if( 3 == glMajorVersion && 2 >= glMajorVersion ) {
+          res[0] = 1;
+          switch ( glMinorVersion ) {
+          case 0:  res[1] = 30; break;  // GL 3.0  ->  GLSL 1.30
+          case 1:  res[1] = 40; break;  // GL 3.1  ->  GLSL 1.40
+          default: res[1] = 50; break;  // GL 3.2  ->  GLSL 1.50 
+          }
+      } else { // >= 3.3
+          res[0] = glMajorVersion;     // GL M.N  ->  GLSL M.N
+          res[1] = glMinorVersion * 10;
+      }
+  }
+  
+  /**
    * @return true if this context is an ES2 context or implements
    *         the extension <code>GL_ARB_ES2_compatibility</code>, otherwise false
    */
@@ -625,12 +713,23 @@ public abstract class GLContext {
 
   /** 
    * @return true if impl. is a hardware rasterizer, otherwise false.
+   * @see #isHardwareRasterizer(AbstractGraphicsDevice, GLProfile)
    * @see GLProfile#isHardwareRasterizer() 
    */
   public final boolean isHardwareRasterizer() {
       return 0 == ( ctxOptions & CTX_IMPL_ACCEL_SOFT ) ;
   }
   
+  /**
+   * @return true if context supports GLSL, i.e. is either {@link #isGLES2()}, {@link #isGL3()} or {@link #isGL2()} <i>and</i> major-version > 1.
+   * @see GLProfile#hasGLSL() 
+   */
+  public final boolean hasGLSL() {
+      return isGLES2() ||
+             isGL3() ||
+             isGL2() && ctxMajorVersion>1 ;
+  }
+
   /** 
    * Returns <code>true</code> if basic FBO support is available, otherwise <code>false</code>.
    * <p>
@@ -642,21 +741,56 @@ public abstract class GLContext {
    * as well as limited internal formats for renderbuffer.
    * </p>
    * @see #CTX_IMPL_FBO
-   * @see com.jogamp.opengl.FBObject#supportsBasicFBO(GL)
-   * @see com.jogamp.opengl.FBObject#supportsFullFBO(GL)
    */
-  public final boolean hasFBO() {
+  public final boolean hasBasicFBOSupport() {
       return 0 != ( ctxOptions & CTX_IMPL_FBO ) ;
   }
 
+  /** 
+   * 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
+   * <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>.
+   * </p>
+   * <p>
+   * Full FBO support includes multiple color attachments and multisampling.
+   * </p>
+   */
+  public final boolean hasFullFBOSupport() {        
+      return !FORCE_MIN_FBO_SUPPORT && hasBasicFBOSupport() &&
+              ( isGL3() ||                                                         // GL >= 3.0                
+                isExtensionAvailable(GLExtensions.ARB_framebuffer_object) ||       // ARB_framebuffer_object
+                ( isExtensionAvailable(GLExtensions.EXT_framebuffer_object) &&     // All EXT_framebuffer_object*
+                  isExtensionAvailable(GLExtensions.EXT_framebuffer_multisample) &&
+                  isExtensionAvailable(GLExtensions.EXT_framebuffer_blit) &&
+                  isExtensionAvailable(GLExtensions.EXT_packed_depth_stencil)
+                )
+              ) ;               
+  }
+  
   /**
-   * @return true if context supports GLSL
-   * @see GLProfile#hasGLSL() 
+   * Returns the maximum number of FBO RENDERBUFFER samples
+   * if {@link #hasFullFBOSupport() full FBO is supported}, otherwise false. 
    */
-  public final boolean hasGLSL() {
-      return isGL2ES2() ;
+  public final int getMaxRenderbufferSamples() {
+      if( hasFullFBOSupport() ) {
+          final GL gl = getGL();
+          final int[] val = new int[] { 0 } ;
+          try {
+              gl.glGetIntegerv(GL2GL3.GL_MAX_SAMPLES, val, 0);
+              final int glerr = gl.glGetError();
+              if(GL.GL_NO_ERROR == glerr) {
+                  return val[0];
+              } else if(DEBUG) {
+                  System.err.println("GLContext.getMaxRenderbufferSamples: GL_MAX_SAMPLES query GL Error 0x"+Integer.toHexString(glerr));
+              }
+          } catch (GLException gle) { gle.printStackTrace(); }
+      }
+      return 0;
   }
-
+  
   /** Note: The GL impl. may return a const value, ie {@link GLES2#isNPOTTextureAvailable()} always returns <code>true</code>. */
   public boolean isNPOTTextureAvailable() {
       return isGL3() || isGLES2Compatible() || isExtensionAvailable(GLExtensions.ARB_texture_non_power_of_two);
@@ -680,6 +814,12 @@ public abstract class GLContext {
                                 && 0 != (ctxOptions & (CTX_PROFILE_COMPAT|CTX_PROFILE_CORE));
   }
 
+  /** Indicates whether this profile is capable of GL4 (core only). <p>Includes [ GL4 ].</p> */
+  public final boolean isGL4core() {
+      return ctxMajorVersion>=4 && 0 != (ctxOptions & CTX_IS_ARB_CREATED)
+                                && 0 != (ctxOptions & CTX_PROFILE_CORE);
+  }
+  
   /** @see GLProfile#isGL3bc() */
   public final boolean isGL3bc() {
       return ( ctxMajorVersion>3 || ctxMajorVersion==3 && ctxMinorVersion>=1 )
@@ -694,6 +834,13 @@ public abstract class GLContext {
              && 0 != (ctxOptions & (CTX_PROFILE_COMPAT|CTX_PROFILE_CORE));
   }
   
+  /** Indicates whether this profile is capable of GL3 (core only). <p>Includes [ GL4, GL3 ].</p> */
+  public final boolean isGL3core() {
+      return ( ctxMajorVersion>3 || ctxMajorVersion==3 && ctxMinorVersion>=1 )
+             && 0 != (ctxOptions & CTX_IS_ARB_CREATED)
+             && 0 != (ctxOptions & CTX_PROFILE_CORE);
+  }
+  
   /** @see GLProfile#isGL2() */
   public final boolean isGL2() {
       return ctxMajorVersion>=1 && 0!=(ctxOptions & CTX_PROFILE_COMPAT);
@@ -730,8 +877,8 @@ public abstract class GLContext {
   }
 
   /**
-   * Set the swap interval if the current context.
-   * @param interval Should be ≥ 0. 0 Disables the vertical synchronisation,
+   * Set the swap interval of the current context and attached drawable.
+   * @param interval Should be ≥ 0. 0 disables the vertical synchronization,
    *                 where ≥ 1 is the number of vertical refreshes before a swap buffer occurs.
    *                 A value < 0 is ignored.
    * @return true if the operation was successful, otherwise false
@@ -741,9 +888,11 @@ public abstract class GLContext {
   public final boolean setSwapInterval(int interval) throws GLException {
     validateCurrent();
     if(0<=interval) {
-        if( setSwapIntervalImpl(interval) ) {
-            currentSwapInterval = interval;
-            return true;
+        if( !drawableRetargeted || !hasRendererQuirk(GLRendererQuirks.NoSetSwapIntervalPostRetarget) ) {
+            if( setSwapIntervalImpl(interval) ) {
+                currentSwapInterval = interval;
+                return true;
+            }
         }
     }
     return false;
@@ -757,15 +906,12 @@ public abstract class GLContext {
    * the default value <code>-1</code> is returned.
    * </p>
    * <p>
-   * The default value for a valid context is <code>1</code> for
-   * an EGL based profile (ES1 or ES2) and <code>-1</code> (undefined)
-   * for desktop.
+   * For a valid context the default value is <code>1</code>
+   * in case of an EGL based profile (ES1 or ES2) and <code>-1</code> 
+   * (undefined) for desktop.
    * </p>
    */
   public final int getSwapInterval() {
-    if(-1 == currentSwapInterval && this.isGLES()) {
-        currentSwapInterval = 1;
-    }
     return currentSwapInterval;
   }
   protected final void setDefaultSwapInterval() {
@@ -1036,6 +1182,9 @@ public abstract class GLContext {
     validateProfileBits(profile, "profile");
     validateProfileBits(resCtp, "resCtp");
 
+    if(FORCE_NO_FBO_SUPPORT) {
+        resCtp &= ~CTX_IMPL_FBO ;
+    }
     if(DEBUG) {
         System.err.println("GLContext.mapAvailableGLVersion: "+device+": "+getGLVersion(reqMajor, 0, profile, null)+" -> "+getGLVersion(resMajor, resMinor, resCtp, null));
         // Thread.dumpStack();
@@ -1141,7 +1290,7 @@ public abstract class GLContext {
   }
 
   /**
-   * Returns the GLProfile's major version number and it's context property (CTP) for availability mapping request.
+   * Returns the GLProfile's major version number at reqMajorCTP[0] and it's context property (CTP) at reqMajorCTP[1] for availability mapping request.
    */
   protected static final void getRequestMajorAndCompat(final GLProfile glp, int[/*2*/] reqMajorCTP) {
     final GLProfile glpImpl = glp.getImpl();
@@ -1149,7 +1298,9 @@ public abstract class GLContext {
         reqMajorCTP[0]=4;
     } else if (glpImpl.isGL3()) {
         reqMajorCTP[0]=3;
-    } else /* if (glpImpl.isGL2()) */ {
+    } else if (glpImpl.isGLES1()) {
+        reqMajorCTP[0]=1;
+    } else /* if (glpImpl.isGL2() || glpImpl.isGLES2()) */ {
         reqMajorCTP[0]=2;
     }
     if( glpImpl.isGLES() ) {
@@ -1217,18 +1368,36 @@ public abstract class GLContext {
    * FBO feature is implemented in OpenGL, hence it is {@link GLProfile} dependent.
    * </p> 
    * <p>
-   * FBO support is queried as described in {@link #hasFBO()}.
+   * FBO support is queried as described in {@link #hasBasicFBOSupport()}.
    * </p>
    *
    * @param device the device to request whether FBO is available for
    * @param glp {@link GLProfile} to check for FBO capabilities
-   * @see GLContext#hasFBO()
+   * @see GLContext#hasBasicFBOSupport()
    */
   public static final boolean isFBOAvailable(AbstractGraphicsDevice device, GLProfile glp) {
       return 0 != ( CTX_IMPL_FBO & getAvailableContextProperties(device, glp) );
   }
   
   /**
+   * @return <code>1</code> if using a hardware rasterizer, <code>0</code> if using a software rasterizer and <code>-1</code> if not determined yet. 
+   * @see GLContext#isHardwareRasterizer()
+   * @see GLProfile#isHardwareRasterizer() 
+   */
+  public static final int isHardwareRasterizer(AbstractGraphicsDevice device, GLProfile glp) {
+      final int r;
+      final int ctp = getAvailableContextProperties(device, glp);
+      if(0 == ctp) { 
+          r = -1;
+      } else if( 0 == ( CTX_IMPL_ACCEL_SOFT & ctp ) ) {
+          r = 1;
+      } else {
+          r = 0;
+      }
+      return r;
+  }
+  
+  /**
    * @param device the device to request whether the profile is available for
    * @param reqMajor Key Value either 1, 2, 3 or 4
    * @param reqProfile Key Value either {@link #CTX_PROFILE_COMPAT}, {@link #CTX_PROFILE_CORE} or {@link #CTX_PROFILE_ES}
@@ -1326,6 +1495,6 @@ public abstract class GLContext {
   protected static String getThreadName() {
     return Thread.currentThread().getName();
   }
-
+  
 }
 
diff --git a/src/jogl/classes/javax/media/opengl/GLDrawable.java b/src/jogl/classes/javax/media/opengl/GLDrawable.java
index 10eea2e..c0910eb 100644
--- a/src/jogl/classes/javax/media/opengl/GLDrawable.java
+++ b/src/jogl/classes/javax/media/opengl/GLDrawable.java
@@ -149,7 +149,7 @@ public interface GLDrawable {
       This object shall be directly associated to the attached {@link NativeSurface}'s
       {@link AbstractGraphicsConfiguration}, and if changes are necessary,
       they should reflect those as well.
-      @return A copy of the queried object.
+      @return The immutable queried instance.
     */
   public GLCapabilitiesImmutable getChosenGLCapabilities();
 
diff --git a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
index 9a0d2cb..70480e7 100644
--- a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
+++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
@@ -48,14 +48,17 @@ import java.util.List;
 import com.jogamp.common.JogampRuntimeException;
 
 import com.jogamp.common.util.ReflectionUtil;
+import com.jogamp.opengl.GLAutoDrawableDelegate;
+import com.jogamp.opengl.GLRendererQuirks;
 
 import javax.media.nativewindow.AbstractGraphicsDevice;
 import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.CapabilitiesImmutable;
 import javax.media.nativewindow.NativeSurface;
 import javax.media.nativewindow.NativeWindowFactory;
 import javax.media.nativewindow.ProxySurface;
-import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook;
-import javax.media.opengl.GLProfile.ShutdownType;
+import javax.media.nativewindow.UpstreamSurfaceHook;
 
 import jogamp.opengl.Debug;
 
@@ -94,9 +97,28 @@ import jogamp.opengl.Debug;
 */
 public abstract class GLDrawableFactory {
 
+  protected static final boolean DEBUG = Debug.debug("GLDrawable");
+  
+  /** 
+   * We have to disable support for ANGLE, the D3D ES2 emulation on Windows provided w/ Firefox and Chrome. 
+   * When run in the mentioned browsers, the eglInitialize(..) implementation crashes.
+   * <p>
+   * This can be overridden by explicitly enabling ANGLE on Windows by setting the property
+   * <code>jogl.enable.ANGLE</code>.
+   * </p> 
+   */
+  protected static final boolean enableANGLE = Debug.isPropertyDefined("jogl.enable.ANGLE", true);
+
+  /** 
+   * In case no OpenGL ES implementation is required
+   * and if the running platform may have a buggy implementation,
+   * setting the property <code>jogl.disable.opengles</code> disables querying a possible existing OpenGL ES implementation. 
+   */
+  protected static final boolean disableOpenGLES = Debug.isPropertyDefined("jogl.disable.opengles", true);
+
   static final String macosxFactoryClassNameCGL = "jogamp.opengl.macosx.cgl.MacOSXCGLDrawableFactory";
   static final String macosxFactoryClassNameAWTCGL = "jogamp.opengl.macosx.cgl.awt.MacOSXAWTCGLDrawableFactory";
-  
+
   private static volatile boolean isInit = false;
   private static GLDrawableFactory eglFactory;
   private static GLDrawableFactory nativeOSFactory;
@@ -106,6 +128,7 @@ public abstract class GLDrawableFactory {
   // Shutdown hook mechanism for the factory
   private static boolean factoryShutdownHookRegistered = false;
   private static Thread factoryShutdownHook = null;
+  private static volatile boolean isJVMShuttingDown = false;
 
   /**
    * Instantiate singleton factories if available, EGLES1, EGLES2 and the OS native ones.
@@ -123,16 +146,16 @@ public abstract class GLDrawableFactory {
   private static final void initSingletonImpl() {
     registerFactoryShutdownHook();
     
-    final String nativeOSType = NativeWindowFactory.getNativeWindowType(true);
+    final String nwt = NativeWindowFactory.getNativeWindowType(true);
     GLDrawableFactory tmp = null;
     String factoryClassName = Debug.getProperty("jogl.gldrawablefactory.class.name", true);
     ClassLoader cl = GLDrawableFactory.class.getClassLoader();
     if (null == factoryClassName) {
-        if ( nativeOSType.equals(NativeWindowFactory.TYPE_X11) ) {
+        if ( nwt == NativeWindowFactory.TYPE_X11 ) {
           factoryClassName = "jogamp.opengl.x11.glx.X11GLXDrawableFactory";
-        } else if ( nativeOSType.equals(NativeWindowFactory.TYPE_WINDOWS) ) {
+        } else if ( nwt == NativeWindowFactory.TYPE_WINDOWS ) {
           factoryClassName = "jogamp.opengl.windows.wgl.WindowsWGLDrawableFactory";
-        } else if ( nativeOSType.equals(NativeWindowFactory.TYPE_MACOSX) ) {
+        } else if ( nwt == NativeWindowFactory.TYPE_MACOSX ) {
             if(ReflectionUtil.isClassAvailable(macosxFactoryClassNameAWTCGL, cl)) {
                 factoryClassName = macosxFactoryClassNameAWTCGL;
             } else {
@@ -140,53 +163,64 @@ public abstract class GLDrawableFactory {
             }
         } else {
           // may use egl*Factory ..
-          if (GLProfile.DEBUG) {
-              System.err.println("GLDrawableFactory.static - No native OS Factory for: "+nativeOSType+"; May use EGLDrawableFactory, if available." );
+          if (DEBUG || GLProfile.DEBUG) {
+              System.err.println("GLDrawableFactory.static - No native Windowing Factory for: "+nwt+"; May use EGLDrawableFactory, if available." );
           }
         }
     }
     if (null != factoryClassName) {
-      if (GLProfile.DEBUG) {
-          System.err.println("GLDrawableFactory.static - Native OS Factory for: "+nativeOSType+": "+factoryClassName);
+      if (DEBUG || GLProfile.DEBUG) {
+          System.err.println("GLDrawableFactory.static - Native OS Factory for: "+nwt+": "+factoryClassName);
       }
       try {
           tmp = (GLDrawableFactory) ReflectionUtil.createInstance(factoryClassName, cl);
       } catch (JogampRuntimeException jre) { 
-          if (GLProfile.DEBUG) {
-              System.err.println("Info: GLDrawableFactory.static - Native Platform: "+nativeOSType+" - not available: "+factoryClassName);
+          if (DEBUG || GLProfile.DEBUG) {
+              System.err.println("Info: GLDrawableFactory.static - Native Platform: "+nwt+" - not available: "+factoryClassName);
               jre.printStackTrace();
           }
       }
     }
-    nativeOSFactory = tmp;
-
+    if(null != tmp && tmp.isComplete()) {
+        nativeOSFactory = tmp;
+    }
     tmp = null;
-    try {
-        tmp = (GLDrawableFactory) ReflectionUtil.createInstance("jogamp.opengl.egl.EGLDrawableFactory", cl);
-    } catch (JogampRuntimeException jre) {
-        if (GLProfile.DEBUG) {
-            System.err.println("Info: GLDrawableFactory.static - EGLDrawableFactory - not available");
-            jre.printStackTrace();
+
+    if(!disableOpenGLES) {
+        try {
+            tmp = (GLDrawableFactory) ReflectionUtil.createInstance("jogamp.opengl.egl.EGLDrawableFactory", cl);
+        } catch (JogampRuntimeException jre) {
+            if (DEBUG || GLProfile.DEBUG) {
+                System.err.println("Info: GLDrawableFactory.static - EGLDrawableFactory - not available");
+                jre.printStackTrace();
+            }
+        }
+        if(null != tmp && tmp.isComplete()) {
+            eglFactory = tmp;
         }
+    } else if( DEBUG || GLProfile.DEBUG ) {
+        System.err.println("Info: GLDrawableFactory.static - EGLDrawableFactory - disabled!");
     }
-    eglFactory = tmp;
   }
 
-  protected static void shutdown(ShutdownType shutdownType) {
+  protected static void shutdown() {
     if (isInit) { // volatile: ok
       synchronized (GLDrawableFactory.class) {
           if (isInit) {
               isInit=false;
-              unregisterFactoryShutdownHook();
-              shutdownImpl(shutdownType);
+              shutdownImpl();
           }
       }
     }
   }
-  private static void shutdownImpl(ShutdownType shutdownType) {
+  
+  private static void shutdownImpl() {
+    // Following code will _always_ remain in shutdown hook
+    // due to special semantics of native utils, i.e. X11Utils.
+    // The latter requires shutdown at JVM-Shutdown only.
     synchronized(glDrawableFactories) {
         for(int i=0; i<glDrawableFactories.size(); i++) {
-            glDrawableFactories.get(i).destroy(shutdownType);
+            glDrawableFactories.get(i).destroy();
         }
         glDrawableFactories.clear();
         
@@ -194,6 +228,8 @@ public abstract class GLDrawableFactory {
         nativeOSFactory = null;
         eglFactory = null;
     }
+    GLContext.shutdown();
+    NativeWindowFactory.shutdown(isJVMShuttingDown);
   }
   
   private static synchronized void registerFactoryShutdownHook() {
@@ -202,7 +238,8 @@ public abstract class GLDrawableFactory {
     }
     factoryShutdownHook = new Thread(new Runnable() {
         public void run() {
-            GLDrawableFactory.shutdownImpl(GLProfile.ShutdownType.COMPLETE);
+            isJVMShuttingDown = true;
+            GLDrawableFactory.shutdownImpl();
         }
     });
     AccessController.doPrivileged(new PrivilegedAction<Object>() {
@@ -214,30 +251,19 @@ public abstract class GLDrawableFactory {
     factoryShutdownHookRegistered = true;
   }
 
-  private static synchronized void unregisterFactoryShutdownHook() {
-    if (!factoryShutdownHookRegistered) {
-        return;
-    }
-    AccessController.doPrivileged(new PrivilegedAction<Object>() {
-        public Object run() {
-            Runtime.getRuntime().removeShutdownHook(factoryShutdownHook);
-            return null;
-        }
-    });
-    factoryShutdownHookRegistered = false;
-  }
-
-
   protected GLDrawableFactory() {
     synchronized(glDrawableFactories) {
         glDrawableFactories.add(this);
     }
   }
+  
+  /** Returns true if this factory is complete, i.e. ready to be used. Otherwise return false. */
+  protected abstract boolean isComplete();
 
   protected void enterThreadCriticalZone() {};
   protected void leaveThreadCriticalZone() {};
 
-  protected abstract void destroy(ShutdownType shutdownType);
+  protected abstract void destroy();
 
   /**
    * Retrieve the default <code>device</code> {@link AbstractGraphicsDevice#getConnection() connection},
@@ -306,6 +332,42 @@ public abstract class GLDrawableFactory {
   protected abstract boolean createSharedResource(AbstractGraphicsDevice device);
   
   /**
+   * Returns true if the <code>quirk</code> exist in the shared resource's context {@link GLRendererQuirks}.
+   * <p>
+   * Convenience method for:
+   * <pre>
+      final GLRendererQuirks glrq = factory.getRendererQuirks(device);
+      return null != glrq ? glrq.exist(quirk) : false;
+   * </pre>
+   * </p>
+   * 
+   * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device.
+   * @param quirk the quirk to be tested, e.g. {@link GLRendererQuirks#NoDoubleBufferedPBuffer}.
+   * @throws IllegalArgumentException if the quirk is out of range
+   * @see #getRendererQuirks()
+   * @see GLRendererQuirks
+   */
+  public final boolean hasRendererQuirk(AbstractGraphicsDevice device, int quirk) {
+      final GLRendererQuirks glrq = getRendererQuirks(device);
+      return null != glrq ? glrq.exist(quirk) : false;
+  }
+  
+  /**
+   * Returns the shared resource's context {@link GLRendererQuirks}.
+   * <p>
+   * Implementation calls {@link GLContext#getRendererQuirks()} on the shared resource context.
+   * </p>
+   * <p>
+   * In case no shared device exist yet or the implementation doesn't support tracking quirks,
+   * the result is always <code>null</code>.
+   * </p>
+   * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device.
+   * @see GLContext#getRendererQuirks()
+   * @see GLRendererQuirks
+   */
+  public abstract GLRendererQuirks getRendererQuirks(AbstractGraphicsDevice device);
+  
+  /**
    * Returns the sole GLDrawableFactory instance for the desktop (X11, WGL, ..) if exist or null
    */
   public static GLDrawableFactory getDesktopFactory() {
@@ -374,44 +436,63 @@ public abstract class GLDrawableFactory {
   // Methods to create high-level objects
 
   /**
-   * Returns a GLDrawable according to it's chosen Capabilities,<br>
+   * Returns a GLDrawable according to it's chosen {@link GLCapabilitiesImmutable},<br>
    * which determines pixel format, on- and offscreen incl. PBuffer type.
    * <p>
-   * The native platform's chosen Capabilties are referenced within the target
-   * NativeSurface's AbstractGraphicsConfiguration.<p>
-   *
-   * In case target's {@link javax.media.nativewindow.Capabilities#isOnscreen()} is true,<br>
-   * an onscreen GLDrawable will be realized.
+   * The chosen {@link GLCapabilitiesImmutable} are referenced within the target
+   * {@link NativeSurface}'s {@link AbstractGraphicsConfiguration}.<p>
+   * </p>
    * <p>
-   * In case target's {@link javax.media.nativewindow.Capabilities#isOnscreen()} is false,<br>
-   * either a Pbuffer drawable is created if target's {@link javax.media.opengl.GLCapabilities#isPBuffer()} is true,<br>
-   * or a simple pixmap/bitmap drawable is created. The latter is unlikely to be hardware accelerated.<br>
+   * An onscreen GLDrawable is created if {@link CapabilitiesImmutable#isOnscreen() caps.isOnscreen()} is true.
+   * </p>
    * <p>
-   *
+   * A FBO drawable is created if both {@link GLCapabilitiesImmutable#isFBO() caps.isFBO()}
+   * and {@link GLContext#isFBOAvailable(AbstractGraphicsDevice, GLProfile) canCreateFBO(device, caps.getGLProfile())} is true.
+   * </p>
+   * <p>
+   * A Pbuffer drawable is created if both {@link GLCapabilitiesImmutable#isPBuffer() caps.isPBuffer()}
+   * and {@link #canCreateGLPbuffer(AbstractGraphicsDevice) canCreateGLPbuffer(device)} is true.
+   * </p>
+   * <p>
+   * If not onscreen and neither FBO nor Pbuffer is available, 
+   * a simple pixmap/bitmap drawable/surface is created, which is unlikely to be hardware accelerated.
+   * </p>
+   * 
    * @throws IllegalArgumentException if the passed target is null
    * @throws GLException if any window system-specific errors caused
    *         the creation of the GLDrawable to fail.
    *
+   * @see #canCreateGLPbuffer(AbstractGraphicsDevice)
+   * @see GLContext#isFBOAvailable(AbstractGraphicsDevice, GLProfile)
+   * @see javax.media.opengl.GLCapabilities#isOnscreen()
+   * @see javax.media.opengl.GLCapabilities#isFBO()
+   * @see javax.media.opengl.GLCapabilities#isPBuffer()
    * @see javax.media.nativewindow.GraphicsConfigurationFactory#chooseGraphicsConfiguration(Capabilities, CapabilitiesChooser, AbstractGraphicsScreen)
    */
   public abstract GLDrawable createGLDrawable(NativeSurface target)
     throws IllegalArgumentException, GLException;
-
+  
   /**
-   * Creates a Offscreen GLDrawable incl it's offscreen {@link javax.media.nativewindow.NativeSurface} with the given capabilites and dimensions.
+   * Creates an {@link GLOffscreenAutoDrawable} incl it's offscreen {@link javax.media.nativewindow.NativeSurface} with the given capabilites and dimensions.
+   * <p>
+   * The {@link GLOffscreenAutoDrawable}'s {@link GLDrawable} is realized and it's {@link GLContext} assigned but not yet made current.
+   * </p>
    * <p>
-   * It's {@link AbstractGraphicsConfiguration} is properly set according to the given {@link GLCapabilitiesImmutable}, see below.
+   * In case the passed {@link GLCapabilitiesImmutable} contains default values, i.e.
+   * {@link GLCapabilitiesImmutable#isOnscreen() caps.isOnscreen()} <code> == true</code>,
+   * it is auto-configured. The latter will set offscreen and also FBO <i>or</i> Pbuffer, whichever is available in that order.
    * </p>
    * <p>
-   * A FBO drawable is created if both {@link javax.media.opengl.GLCapabilities#isFBO() caps.isFBO()}
+   * A FBO based auto drawable, {@link GLOffscreenAutoDrawable.FBO}, is created if both {@link GLCapabilitiesImmutable#isFBO() caps.isFBO()}
    * and {@link GLContext#isFBOAvailable(AbstractGraphicsDevice, GLProfile) canCreateFBO(device, caps.getGLProfile())} is true.
    * </p>
    * <p>
-   * A Pbuffer drawable is created if both {@link javax.media.opengl.GLCapabilities#isPBuffer() caps.isPBuffer()}
-   * and {@link #canCreateGLPbuffer(javax.media.nativewindow.AbstractGraphicsDevice) canCreateGLPbuffer(device)} is true.
+   * A Pbuffer based auto drawable is created if both {@link GLCapabilitiesImmutable#isPBuffer() caps.isPBuffer()}
+   * and {@link #canCreateGLPbuffer(AbstractGraphicsDevice) canCreateGLPbuffer(device)} is true.
    * </p>
    * <p>
-   * If neither FBO nor Pbuffer is available, a simple pixmap/bitmap drawable/surface is created, which is unlikely to be hardware accelerated.
+   * If neither FBO nor Pbuffer is available, 
+   * a simple pixmap/bitmap auto drawable is created, which is unlikely to be hardware accelerated.
    * </p>
    *
    * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared device to be used, may be <code>null</code> for the platform's default device.
@@ -419,17 +500,55 @@ public abstract class GLDrawableFactory {
    * @param chooser the custom chooser, may be null for default
    * @param width the requested offscreen width
    * @param height the requested offscreen height
+   * @return the created and initialized offscreen {@link GLOffscreenAutoDrawable} instance
    *
-   * @return the created offscreen GLDrawable
+   * @throws GLException if any window system-specific errors caused
+   *         the creation of the Offscreen to fail.
+   *         
+   * @see #createOffscreenDrawable(AbstractGraphicsDevice, GLCapabilitiesImmutable, GLCapabilitiesChooser, int, int)
+   */
+  public abstract GLOffscreenAutoDrawable createOffscreenAutoDrawable(AbstractGraphicsDevice device,
+                                                                      GLCapabilitiesImmutable caps,
+                                                                      GLCapabilitiesChooser chooser,
+                                                                      int width, int height,
+                                                                      GLContext shareWith) throws GLException;
+  /**
+   * Creates a offscreen {@link GLDrawable} incl it's offscreen {@link javax.media.nativewindow.NativeSurface} with the given capabilites and dimensions.
+   * <p>
+   * In case the passed {@link GLCapabilitiesImmutable} contains default values, i.e.
+   * {@link GLCapabilitiesImmutable#isOnscreen() caps.isOnscreen()} <code> == true</code>,
+   * it is auto-configured. The latter will set offscreen and also FBO <i>or</i> Pbuffer, whichever is available in that order.
+   * </p>
+   * <p>
+   * A resizeable FBO drawable, {@link GLFBODrawable.Resizeable}, is created if both {@link GLCapabilitiesImmutable#isFBO() caps.isFBO()}
+   * and {@link GLContext#isFBOAvailable(AbstractGraphicsDevice, GLProfile) canCreateFBO(device, caps.getGLProfile())} is true.
+   * </p>
+   * <p>
+   * A Pbuffer drawable is created if both {@link GLCapabilitiesImmutable#isPBuffer() caps.isPBuffer()}
+   * and {@link #canCreateGLPbuffer(AbstractGraphicsDevice) canCreateGLPbuffer(device)} is true.
+   * </p>
+   * <p>
+   * If neither FBO nor Pbuffer is available, 
+   * a simple pixmap/bitmap drawable is created, which is unlikely to be hardware accelerated.
+   * </p>
+   *
+   * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared device to be used, may be <code>null</code> for the platform's default device.
+   * @param caps the requested GLCapabilties
+   * @param chooser the custom chooser, may be null for default
+   * @param width the requested offscreen width
+   * @param height the requested offscreen height
+   *
+   * @return the created offscreen {@link GLDrawable}
    *
    * @throws GLException if any window system-specific errors caused
    *         the creation of the Offscreen to fail.
+   *         
+   * @see #createOffscreenAutoDrawable(AbstractGraphicsDevice, GLCapabilitiesImmutable, GLCapabilitiesChooser, int, int, GLContext)
    */
   public abstract GLDrawable createOffscreenDrawable(AbstractGraphicsDevice device,
-                                                     GLCapabilitiesImmutable capabilities,
+                                                     GLCapabilitiesImmutable caps,
                                                      GLCapabilitiesChooser chooser,
-                                                     int width, int height)
-    throws GLException;
+                                                     int width, int height) throws GLException;
 
   /**
    * Creates a proxy {@link NativeSurface} w/ defined surface handle, i.e. a {@link WrappedSurface} or {@link GDISurface} instance. 
@@ -460,6 +579,21 @@ public abstract class GLDrawableFactory {
                                                   GLCapabilitiesImmutable caps, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream);
 
   /**
+   * Returns true if it is possible to create an <i>framebuffer object</i> (FBO).
+   * <p>
+   * FBO feature is implemented in OpenGL, hence it is {@link GLProfile} dependent.
+   * </p> 
+   * <p>
+   * FBO support is queried as described in {@link GLContext#hasBasicFBOSupport()}.
+   * </p>
+   *
+   * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device.
+   * @param glp {@link GLProfile} to check for FBO capabilities
+   * @see GLContext#hasBasicFBOSupport()
+   */
+  public abstract boolean canCreateFBO(AbstractGraphicsDevice device, GLProfile glp);
+
+  /**
    * Returns true if it is possible to create a GLPbuffer. Some older
    * graphics cards do not have this capability.
    *
@@ -468,7 +602,10 @@ public abstract class GLDrawableFactory {
   public abstract boolean canCreateGLPbuffer(AbstractGraphicsDevice device);
 
   /**
-   * Creates a GLPbuffer with the given capabilites and dimensions. <P>
+   * Creates a GLPbuffer {@link GLAutoDrawable} with the given capabilites and dimensions.
+   * <p>
+   * The GLPbuffer drawable is realized and initialized eagerly.
+   * </p>
    *
    * See the note in the overview documentation on
    * <a href="../../../overview-summary.html#SHARING">context sharing</a>.
@@ -480,10 +617,12 @@ public abstract class GLDrawableFactory {
    * @param initialHeight initial height of pbuffer
    * @param shareWith a shared GLContext this GLPbuffer shall use
    *
-   * @return the new {@link GLPbuffer} specific {@link GLAutoDrawable}
+   * @return the created and initialized {@link GLPbuffer} instance
    *
    * @throws GLException if any window system-specific errors caused
    *         the creation of the GLPbuffer to fail.
+   *         
+   * @deprecated {@link GLPbuffer} is deprecated, use {@link #createOffscreenAutoDrawable(AbstractGraphicsDevice, GLCapabilitiesImmutable, GLCapabilitiesChooser, int, int, GLContext)}
    */
   public abstract GLPbuffer createGLPbuffer(AbstractGraphicsDevice device,
                                             GLCapabilitiesImmutable capabilities,
diff --git a/src/jogl/classes/javax/media/opengl/GLFBODrawable.java b/src/jogl/classes/javax/media/opengl/GLFBODrawable.java
new file mode 100644
index 0000000..079d9af
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLFBODrawable.java
@@ -0,0 +1,175 @@
+/**
+ * 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 javax.media.opengl;
+
+import javax.media.nativewindow.NativeWindowException;
+
+import com.jogamp.opengl.FBObject;
+import com.jogamp.opengl.FBObject.TextureAttachment;
+
+/** 
+ * Platform-independent {@link GLDrawable} specialization,
+ * exposing {@link FBObject} functionality.
+ *
+ * <p>
+ * A {@link GLFBODrawable} is uninitialized until a {@link GLContext} is bound 
+ * and made current the first time, hence only then it's capabilities <i>fully</i> reflect expectations,
+ * i.e. color, depth, stencil and MSAA bits will be <i>valid</i> only after the first {@link GLContext#makeCurrent() makeCurrent()} call.
+ * On-/offscreen bits are <i>valid</i> after {@link #setRealized(boolean) setRealized(true)}.
+ * </p>
+ * 
+ * <p>
+ * MSAA is used if {@link GLCapabilitiesImmutable#getNumSamples() requested}.
+ * </p>
+ * <p>
+ * Double buffering is used if {@link GLCapabilitiesImmutable#getDoubleBuffered() requested}.
+ * </p>
+ * <p>
+ * In MSAA mode, it always uses the implicit 2nd {@link FBObject framebuffer} {@link FBObject#getSamplingSinkFBO() sink}. 
+ * Hence double buffering is always the case w/ MSAA.
+ * </p>
+ * <p>
+ * In non MSAA a second explicit {@link FBObject framebuffer} is being used.
+ * This method allows compliance w/ the spec, i.e. read and draw framebuffer selection
+ * and double buffer usage for e.g. {@link GL#glReadPixels(int, int, int, int, int, int, java.nio.Buffer) glReadPixels(..)}.
+ * This method also allows usage of both textures seperately.
+ * </p>
+ * <p>
+ * It would be possible to implement double buffering simply using 
+ * {@link FBObject.TextureAttachment texture attachment}s with one {@link FBObject framebuffer}.
+ * This would require mode selection and hence complicate the API. Besides, it would
+ * not support differentiation of read and write framebuffer and hence not be spec compliant.
+ * </p>
+ * <p>
+ * Actual swapping of the {@link FBObject.TextureAttachment texture}s or {@link FBObject framebuffer}
+ * is performed either in the {@link #contextMadeCurrent(boolean) context current hook}
+ * or when {@link #swapBuffersImpl(boolean) swapping buffers}, whatever comes first.<br/>
+ * </p>
+ */ 
+public interface GLFBODrawable extends GLDrawable {
+    // public enum DoubleBufferMode { NONE, TEXTURE, FBO }; // TODO: Add or remove TEXTURE (only) DoubleBufferMode support
+    
+    /**
+     * @return <code>true</code> if initialized, i.e. a {@link GLContext} is bound and made current once, otherwise <code>false</code>.
+     */
+    public boolean isInitialized();
+    
+    /**
+     * Notify this instance about upstream size change
+     * to reconfigure the {@link FBObject}.
+     * @param gl GL context object bound to this drawable, will be made current during operation. 
+     *           A prev. current context will be make current after operation. 
+     * @throws GLException if resize operation failed
+     */
+    void resetSize(GL gl) throws GLException;
+    
+    /**
+     * @return the used texture unit
+     */
+    int getTextureUnit();
+    
+    /**
+     * 
+     * @param unit the texture unit to be used
+     */
+    void setTextureUnit(int unit);
+    
+    /**
+     * Set a new sample size
+     * @param gl GL context object bound to this drawable, will be made current during operation. 
+     *           A prev. current context will be make current after operation. 
+     * @param newSamples new sample size
+     * @throws GLException if resetting the FBO failed
+     */
+    void setNumSamples(GL gl, int newSamples) throws GLException;
+    
+    /**
+     * @return the number of sample buffers if using MSAA, otherwise 0
+     */
+    int getNumSamples();
+    
+    /**
+     * @return the used {@link DoubleBufferMode} 
+     */
+    // DoubleBufferMode getDoubleBufferMode(); // TODO: Add or remove TEXTURE (only) DoubleBufferMode support
+    
+    /**
+     * Sets the {@link DoubleBufferMode}. Must be called before {@link #isInitialized() initialization},
+     * otherwise an exception is thrown.
+     * <p>
+     * This call has no effect is MSAA is selected, since MSAA always forces the mode to {@link DoubleBufferMode#FBO FBO}.
+     * Also setting the mode to {@link DoubleBufferMode#NONE NONE} where double buffering is {@link GLCapabilitiesImmutable#getDoubleBuffered() requested}
+     * or setting a double buffering mode w/o {@link GLCapabilitiesImmutable#getDoubleBuffered() request} will be ignored.
+     * </p>
+     * <p>
+     * Since {@link DoubleBufferMode#TEXTURE TEXTURE} mode is currently not implemented, this method has no effect.
+     * </p>
+     * @throws GLException if already initialized, see {@link #isInitialized()}.
+     */
+    // void setDoubleBufferMode(DoubleBufferMode mode) throws GLException; // TODO: Add or remove TEXTURE (only) DoubleBufferMode support
+    
+    /**
+     * If MSAA is being used and {@link GL#GL_FRONT} is requested,
+     * the internal {@link FBObject} {@link FBObject#getSamplingSinkFBO() sample sink} is being returned. 
+     * 
+     * @param bufferName {@link GL#GL_FRONT} and {@link GL#GL_BACK} are valid buffer names
+     * @return the named {@link FBObject}
+     * @throws IllegalArgumentException if an illegal buffer name is being used
+     */
+    FBObject getFBObject(int bufferName) throws IllegalArgumentException;
+
+    /**
+     * Returns the named texture buffer.
+     * <p>
+     * If MSAA is being used, only the {@link GL#GL_FRONT} buffer is accessible 
+     * and an exception is being thrown if {@link GL#GL_BACK} is being requested.
+     * </p>
+     * @param bufferName {@link GL#GL_FRONT} and {@link GL#GL_BACK} are valid buffer names
+     * @return the named {@link TextureAttachment}
+     * @throws IllegalArgumentException if using MSAA and {@link GL#GL_BACK} is requested or an illegal buffer name is being used
+     */
+    FBObject.TextureAttachment getTextureBuffer(int bufferName) throws IllegalArgumentException;
+
+    /** Resizeable {@link GLFBODrawable} specialization */     
+    public interface Resizeable extends GLFBODrawable {
+        /**
+         * Resize this drawable.
+         * <p>
+         * This drawable is being locked during operation.
+         * </p>
+         * @param context the {@link GLContext} bound to this drawable, will be made current during operation 
+         *                A prev. current context will be make current after operation. 
+         * @param newWidth
+         * @param newHeight
+         * @throws NativeWindowException in case the surface could no be locked
+         * @throws GLException in case an error during the resize operation occurred
+         */
+        void setSize(GLContext context, int newWidth, int newHeight) throws NativeWindowException, GLException;                
+    }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/util/AWTKeyAdapter.java b/src/jogl/classes/javax/media/opengl/GLOffscreenAutoDrawable.java
similarity index 57%
copy from src/test/com/jogamp/opengl/test/junit/util/AWTKeyAdapter.java
copy to src/jogl/classes/javax/media/opengl/GLOffscreenAutoDrawable.java
index 6c01561..6fe76a3 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/AWTKeyAdapter.java
+++ b/src/jogl/classes/javax/media/opengl/GLOffscreenAutoDrawable.java
@@ -1,5 +1,5 @@
 /**
- * Copyright 2010 JogAmp Community. All rights reserved.
+ * 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:
@@ -25,50 +25,39 @@
  * 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 java.awt.event.KeyEvent;
+package javax.media.opengl;
 
-public class AWTKeyAdapter extends java.awt.event.KeyAdapter implements InputEventCountAdapter {
+import javax.media.nativewindow.NativeWindowException;
 
-    String prefix;
-    int keyTyped;
-    boolean pressed;
+import com.jogamp.opengl.FBObject;
 
-    public AWTKeyAdapter(String prefix) {
-        this.prefix = prefix;
-        reset();
-    }
-
-    public boolean isPressed() {
-        return pressed;
-    }
+/** 
+ * Platform-independent {@link GLAutoDrawable} specialization,
+ * exposing offscreen functionality.
+ * <p>
+ * This class distinguishes itself from {@link GLAutoDrawable}
+ * with it's {@link #setSize(int, int)} functionality.
+ * </p>
+ */
+public interface GLOffscreenAutoDrawable extends GLAutoDrawable {
     
-    public int getCount() {
-        return keyTyped;
-    }
-
-    public void reset() {
-        keyTyped = 0;
-        pressed = false;
-    }
-
-    public void keyPressed(KeyEvent e) {
-        pressed = true;
-        System.err.println("KEY AWT PRESSED ["+pressed+"]: "+prefix+", "+e);
-    }
-
-    public void keyReleased(KeyEvent e) {
-        pressed = false;
-        System.err.println("KEY AWT RELEASED ["+pressed+"]: "+prefix+", "+e);
-    }
-
-    public void keyTyped(java.awt.event.KeyEvent e) {
-        ++keyTyped;
-        System.err.println("KEY AWT  TYPED ["+keyTyped+"]: "+prefix+", "+e);
-    }
+    /**
+     * Resize this auto drawable.
+     * @param newWidth
+     * @param newHeight
+     * @throws NativeWindowException in case the surface could no be locked
+     * @throws GLException in case of an error during the resize operation
+     */
+    void setSize(int newWidth, int newHeight) throws NativeWindowException, GLException;
+
+    /**
+     * Set the upstream UI toolkit object.
+     * @see #getUpstreamWidget()
+     */
+    void setUpstreamWidget(Object newUpstreamWidget);
     
-    public String toString() { return prefix+"[pressed "+pressed+", typed "+keyTyped+"]"; }
+    /** {@link FBObject} based {@link GLOffscreenAutoDrawable} specialization */ 
+    public interface FBO extends GLOffscreenAutoDrawable, GLFBODrawable {      
+    }    
 }
-
diff --git a/src/jogl/classes/javax/media/opengl/GLPbuffer.java b/src/jogl/classes/javax/media/opengl/GLPbuffer.java
index 273a992..de7731a 100644
--- a/src/jogl/classes/javax/media/opengl/GLPbuffer.java
+++ b/src/jogl/classes/javax/media/opengl/GLPbuffer.java
@@ -45,7 +45,11 @@ package javax.media.opengl;
     contains experimental methods for accessing the pbuffer's contents
     as a texture map and enabling rendering to floating-point frame
     buffers. These methods are not guaranteed to be supported on all
-    platforms and may be deprecated in a future release. */
+    platforms and may be deprecated in a future release.
+    
+    @deprecated Use {@link GLOffscreenAutoDrawable} w/ {@link GLCapabilities#setFBO(boolean)} 
+                via {@link GLDrawableFactory#createOffscreenAutoDrawable(javax.media.nativewindow.AbstractGraphicsDevice, GLCapabilitiesImmutable, GLCapabilitiesChooser, int, int, GLContext) GLDrawableFactory.createOffscreenAutoDrawable(..)}.
+  */
 
 public interface GLPbuffer extends GLAutoDrawable {
   /** Indicates the GL_APPLE_float_pixels extension is being used for this pbuffer. */
diff --git a/src/jogl/classes/javax/media/opengl/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java
index 1e10dc9..f916ab8 100644
--- a/src/jogl/classes/javax/media/opengl/GLProfile.java
+++ b/src/jogl/classes/javax/media/opengl/GLProfile.java
@@ -77,23 +77,6 @@ public class GLProfile {
     
     public static final boolean DEBUG = Debug.debug("GLProfile");
     
-    /** 
-     * We have to disable support for ANGLE, the D3D ES2 emulation on Windows provided w/ Firefox and Chrome. 
-     * When run in the mentioned browsers, the eglInitialize(..) implementation crashes.
-     * <p>
-     * This can be overridden by explicitly enabling ANGLE on Windows by setting the property
-     * <code>jogl.enable.ANGLE</code>.
-     * </p> 
-     */
-    private static final boolean enableANGLE = Debug.isPropertyDefined("jogl.enable.ANGLE", true);
-    
-    /** 
-     * In case no OpenGL ES implementation is required
-     * and if the running platform may have a buggy implementation,
-     * setting the property <code>jogl.disable.opengles</code> disables querying a possible existing OpenGL ES implementation. 
-     */
-    private static final boolean disableOpenGLES = Debug.isPropertyDefined("jogl.disable.opengles", true);
-    
     static {
         // Also initializes TempJarCache if shall be used.
         Platform.initSingleton();
@@ -101,29 +84,29 @@ public class GLProfile {
     
     /**
      * Static initialization of JOGL.
+     *
      * <p>
-     * The parameter <code>firstUIActionOnProcess</code> has an impact on concurrent locking,<br>
-     * see {@link javax.media.nativewindow.NativeWindowFactory#initSingleton(boolean) NativeWindowFactory.initSingleton(firstUIActionOnProcess)}.
+     * This method shall not need to be called for other reasons than having a defined initialization sequence.
      * </p>
-     * <p>
-     * Applications using this method may place it's call before any other UI invocation
-     * in the <code>main class</code>'s static block or within the <code>main function</code>.
-     * In such case, applications may pass <code>firstUIActionOnProcess=true</code> to use native toolkit locking.</P>
-     * <P>
-     * RCP Application (Applet's, Webstart, Netbeans, ..) using JOGL are not be able to initialize JOGL
-     * before the first UI action.
-     * In such case you shall pass <code>firstUIActionOnProcess=false</code>.</P>
+     * 
      * <P>
      * In case this method is not invoked, GLProfile is initialized implicit by
-     * the first call to {@link #getDefault()}, {@link #get(java.lang.String)} passing <code>firstUIActionOnProcess=false</code>.
+     * the first call to {@link #getDefault()}, {@link #get(java.lang.String)}.
      * <P>
-     *
-     * @param firstUIActionOnProcess Should be <code>true</code> if called before the first UI action of the running program,
-     * otherwise <code>false</code>.
      * 
-     * @deprecated Use {@link #initSingleton()}. This method is subject to be removed in future versions of JOGL. 
+     * <p>
+     * To initialize JOGL at startup ASAP, this method may be invoked in the <i>main class</i>'s 
+     * static initializer block, in the <i>static main() method</i> or in the <i>Applet init() method</i>.
+     * </p>
+     * 
+     * <p>
+     * Since JOGL's initialization is complex and involves multi threading, it is <b>not</b> recommended
+     * to be have it invoked on the AWT EDT thread. In case all JOGL usage is performed 
+     * on the AWT EDT, invoke this method outside the AWT EDT - see above.
+     * </p>
+     * 
      */
-    public static void initSingleton(final boolean firstUIActionOnProcess) {
+    public static void initSingleton() {
         final boolean justInitialized; 
         initLock.lock();
         try {
@@ -131,7 +114,7 @@ public class GLProfile {
                 initialized = true;
                 justInitialized = true;
                 if(DEBUG) {
-                    System.err.println("GLProfile.initSingleton(firstUIActionOnProcess: "+firstUIActionOnProcess+") - thread "+Thread.currentThread().getName());
+                    System.err.println("GLProfile.initSingleton() - thread "+Thread.currentThread().getName());
                     Thread.dumpStack();
                 }
     
@@ -171,7 +154,7 @@ public class GLProfile {
                            }
                            JNILibLoaderBase.addNativeJarLibs(classesFromJavaJars, "-all", new String[] { "-noawt", "-mobile", "-core" } );
                         }
-                        initProfilesForDefaultDevices(firstUIActionOnProcess);
+                        initProfilesForDefaultDevices();
                         return null;
                     }
                 });
@@ -189,17 +172,6 @@ public class GLProfile {
     }
     
     /**
-     * Static initialization of JOGL.
-     *
-     * <p>
-     * This method shall not need to be called for other reasons than having a defined initialization sequence.
-     * </p>
-     */
-    public static void initSingleton() {
-        GLProfile.initSingleton(false);
-    }
-
-    /**
      * Trigger eager initialization of GLProfiles for the given device,
      * in case it isn't done yet.
      * 
@@ -209,44 +181,25 @@ public class GLProfile {
         getProfileMap(device, true);
     }
 
-    /** 
-     * Shutdown type for {@link GLProfile#shutdown(ShutdownType)}.
-     * <p>
-     * {@link #SHARED_ONLY} For thread based resources only, suitable for eg. {@link java.applet.Applet Applet} restart.<br>
-     * {@link #COMPLETE} Everything.<br>
-     * </p>
-     */ 
-    public enum ShutdownType {
-        /* Shared thread based resources only, eg. for Applets */ 
-        SHARED_ONLY,
-        /* Everything */
-        COMPLETE;
-    }
-    
     /**
      * Manual shutdown method, may be called after your last JOGL use
      * within the running JVM.<br>
      * It releases all temporary created resources, ie issues {@link javax.media.opengl.GLDrawableFactory#shutdown()}.<br>
      * The shutdown implementation is called via the JVM shutdown hook, if not manually invoked.<br>
      * <p>
-     * This method shall not need to be called for other reasons than issuing a proper shutdown of resources.
+     * This method shall not need to be called for other reasons than issuing a proper shutdown of resources at a defined time.
      * </p>
-     * @param type the shutdown type, see {@link ShutdownType}.
      */
-    public static void shutdown(ShutdownType type) {
+    public static void shutdown() {
         initLock.lock();
         try {
             if(initialized) { // volatile: ok
                 initialized = false;
                 if(DEBUG) {
-                    System.err.println("GLProfile.shutdown(type: "+type+") - thread "+Thread.currentThread().getName());
+                    System.err.println("GLProfile.shutdown() - thread "+Thread.currentThread().getName());
                     Thread.dumpStack();
                 }                    
-                GLDrawableFactory.shutdown(type);
-                if(ShutdownType.COMPLETE == type) {
-                    GLContext.shutdown();
-                }
-                NativeWindowFactory.shutdown();
+                GLDrawableFactory.shutdown();
             }
         } finally {
             initLock.unlock();
@@ -1411,11 +1364,10 @@ public class GLProfile {
     /**
      * Tries the profiles implementation and native libraries.
      */
-    private static void initProfilesForDefaultDevices(boolean firstUIActionOnProcess) {
-        NativeWindowFactory.initSingleton(firstUIActionOnProcess);
+    private static void initProfilesForDefaultDevices() {
+        NativeWindowFactory.initSingleton();
         if(DEBUG) {
-            System.err.println("GLProfile.init firstUIActionOnProcess: "+ firstUIActionOnProcess
-                               + ", thread: " + Thread.currentThread().getName());
+            System.err.println("GLProfile.init - thread: " + Thread.currentThread().getName());
             System.err.println(VersionUtil.getPlatformInfo());
             System.err.println(GlueGenVersion.getInstance());
             System.err.println(NativeWindowVersion.getInstance());
@@ -1476,34 +1428,17 @@ public class GLProfile {
             }
         } else {
             defaultDesktopDevice = desktopFactory.getDefaultDevice();
-            defaultDevice        = defaultDesktopDevice; 
-            if(DEBUG) {
-                System.err.println("Info: GLProfile.init - Default device is desktop derived: "+defaultDevice);
-            }
         }
 
-        if ( !disableOpenGLES && ReflectionUtil.isClassAvailable("jogamp.opengl.egl.EGLDrawableFactory", classloader) ) {
+        if ( ReflectionUtil.isClassAvailable("jogamp.opengl.egl.EGLDrawableFactory", classloader) ) {
             t=null;
             try {
                 eglFactory = (GLDrawableFactoryImpl) GLDrawableFactory.getFactoryImpl(GLES2);
                 if(null != eglFactory) {
-                    final boolean isANGLE = ((jogamp.opengl.egl.EGLDrawableFactory)eglFactory).isANGLE();
-                    if(isANGLE && !enableANGLE) {
-                        if(DEBUG) {
-                            System.err.println("Info: GLProfile.init - EGL/ES2 ANGLE disabled");
-                        }
-                        eglFactory.destroy(ShutdownType.COMPLETE);
-                        eglFactory    = null;
-                        hasEGLFactory = false;
-                    } else {
-                        if(DEBUG && isANGLE) {
-                            System.err.println("Info: GLProfile.init - EGL/ES2 ANGLE enabled");
-                        }
-                        hasEGLFactory = true;
-                        // update hasGLES1Impl, hasGLES2Impl based on EGL
-                        hasGLES2Impl = null!=eglFactory.getGLDynamicLookupHelper(2) && hasGLES2Impl;
-                        hasGLES1Impl = null!=eglFactory.getGLDynamicLookupHelper(1) && hasGLES1Impl;
-                    }
+                    hasEGLFactory = true;
+                    // update hasGLES1Impl, hasGLES2Impl based on EGL
+                    hasGLES2Impl = null!=eglFactory.getGLDynamicLookupHelper(2) && hasGLES2Impl;
+                    hasGLES1Impl = null!=eglFactory.getGLDynamicLookupHelper(1) && hasGLES1Impl;
                 }
             } catch (LinkageError le) {
                 t=le;
@@ -1521,7 +1456,7 @@ public class GLProfile {
             }
         }
 
-        final AbstractGraphicsDevice defaultEGLDevice;        
+        final AbstractGraphicsDevice defaultEGLDevice;
         if(null == eglFactory) {
             hasGLES2Impl     = false;
             hasGLES1Impl     = false;
@@ -1530,25 +1465,33 @@ public class GLProfile {
                 System.err.println("Info: GLProfile.init - EGL GLDrawable factory not available");
             }
         } else {
-            defaultEGLDevice = eglFactory.getDefaultDevice();
-            if(null == defaultDevice) {
-                defaultDevice = defaultEGLDevice;
-                if(DEBUG) {
-                    System.err.println("Info: GLProfile.init - Default device is EGL derived: "+defaultDevice);
-                }
-            }
+            defaultEGLDevice = eglFactory.getDefaultDevice();            
         }
 
-        /** Should not be required .. but keep it here if simple probe on defaultDevice ain't enough. 
-        final boolean addedDesktopProfile = initProfilesForDevice(defaultDesktopDevice); 
-        final boolean addedEGLProfile     = initProfilesForDevice(defaultEGLDevice); 
-        final boolean addedAnyProfile =  addedDesktopProfile || addedEGLProfile ;
-         */
-        final boolean addedAnyProfile =  initProfilesForDevice(defaultDevice);
-
+        if( null != defaultDesktopDevice ) {
+            defaultDevice = defaultDesktopDevice;
+            if(DEBUG) {
+                System.err.println("Info: GLProfile.init - Default device is desktop derived: "+defaultDevice);
+            }            
+        } else if ( null != defaultEGLDevice ) {
+            defaultDevice = defaultEGLDevice;
+            if(DEBUG) {
+                System.err.println("Info: GLProfile.init - Default device is EGL derived: "+defaultDevice);
+            }
+        } else {
+            if(DEBUG) {
+                System.err.println("Info: GLProfile.init - Default device not available");
+            }
+            defaultDevice = null;
+        }
+                
+        // we require to initialize the EGL device 1st, if available
+        final boolean addedEGLProfile     = null != defaultEGLDevice     ? initProfilesForDevice(defaultEGLDevice)     : false;
+        final boolean addedDesktopProfile = null != defaultDesktopDevice ? initProfilesForDevice(defaultDesktopDevice) : false;        
+        final boolean addedAnyProfile     = addedEGLProfile || addedDesktopProfile ;
+            
         if(DEBUG) {
-            // System.err.println("GLProfile.init addedAnyProfile      "+addedAnyProfile+" (desktop: "+addedDesktopProfile+", egl "+addedEGLProfile+")");
-            System.err.println("GLProfile.init addedAnyProfile       "+addedAnyProfile);
+            System.err.println("GLProfile.init addedAnyProfile       "+addedAnyProfile+" (desktop: "+addedDesktopProfile+", egl "+addedEGLProfile+")");
             System.err.println("GLProfile.init isAWTAvailable        "+isAWTAvailable);
             System.err.println("GLProfile.init hasDesktopGLFactory   "+hasDesktopGLFactory);
             System.err.println("GLProfile.init hasGL234Impl          "+hasGL234Impl);
diff --git a/src/test/com/jogamp/opengl/test/junit/util/EventCountAdapter.java b/src/jogl/classes/javax/media/opengl/GLRunnable2.java
similarity index 82%
copy from src/test/com/jogamp/opengl/test/junit/util/EventCountAdapter.java
copy to src/jogl/classes/javax/media/opengl/GLRunnable2.java
index 76a1884..1598a62 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/EventCountAdapter.java
+++ b/src/jogl/classes/javax/media/opengl/GLRunnable2.java
@@ -1,5 +1,5 @@
 /**
- * Copyright 2010 JogAmp Community. All rights reserved.
+ * 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:
@@ -26,9 +26,19 @@
  * or implied, of JogAmp Community.
  */
  
-package com.jogamp.opengl.test.junit.util;
+package javax.media.opengl;
 
-public interface EventCountAdapter {
-    void reset();
+/**
+ * <p>
+ * Declares a one-shot OpenGL command.
+ * </p>
+ */
+public interface GLRunnable2<T,U> { 
+    /**
+     * @param gl a current GL object
+     * @param args custom arguments
+     * @return the desired object 
+     */
+    T run(GL gl, U args);
 }
 
diff --git a/src/jogl/classes/javax/media/opengl/GLUniformData.java b/src/jogl/classes/javax/media/opengl/GLUniformData.java
index 475ff45..9638ba8 100644
--- a/src/jogl/classes/javax/media/opengl/GLUniformData.java
+++ b/src/jogl/classes/javax/media/opengl/GLUniformData.java
@@ -3,6 +3,9 @@ package javax.media.opengl;
 
 import java.nio.*;
 
+import com.jogamp.common.nio.Buffers;
+import com.jogamp.opengl.FloatUtil;
+
 public class GLUniformData {
 
     /**
@@ -69,14 +72,33 @@ public class GLUniformData {
     public IntBuffer intBufferValue()   { return (IntBuffer)data; };
     public FloatBuffer floatBufferValue() { return (FloatBuffer)data; };
 
+    public StringBuilder toString(StringBuilder sb) {
+      if(null == sb) {
+          sb = new StringBuilder();
+      }
+      sb.append("GLUniformData[name ").append(name).
+                       append(", location ").append(location). 
+                       append(", size ").append(rows).append("x").append(columns).
+                       append(", count ").append(count). 
+                       append(", data ");      
+      if(isMatrix() && data instanceof FloatBuffer) {
+          sb.append("\n");
+          final FloatBuffer fb = (FloatBuffer)getBuffer(); 
+          for(int i=0; i<count; i++) {
+              FloatUtil.matrixToString(sb, i+": ", "%10.5f", fb, i*rows*columns, rows, columns, false);
+              sb.append(",\n");              
+          }
+      } else if(isBuffer()) {
+          Buffers.toString(sb, null, getBuffer());
+      } else {
+          sb.append(data);
+      }
+      sb.append("]");
+      return sb;
+    }
+    
     public String toString() {
-      return "GLUniformData[name "+name+
-                       ", location "+location+ 
-                       ", size "+rows+"*"+columns+
-                       ", count "+count+ 
-                       ", matrix "+isMatrix+ 
-                       ", data "+data+ 
-                       "]";
+        return toString(null).toString();
     }
 
     private void init(String name, int rows, int columns, Object data) {
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
index 03fd78a..1e9fcc9 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
@@ -98,6 +98,7 @@ import jogamp.common.awt.AWTEDTExecutor;
 import jogamp.opengl.Debug;
 import jogamp.opengl.GLContextImpl;
 import jogamp.opengl.GLDrawableHelper;
+import jogamp.opengl.GLDrawableImpl;
 
 // FIXME: Subclasses need to call resetGLFunctionAvailability() on their
 // context whenever the displayChanged() function is called on our
@@ -109,6 +110,16 @@ import jogamp.opengl.GLDrawableHelper;
     interfaces when adding a heavyweight doesn't work either because
     of Z-ordering or LayoutManager problems.
  *
+ * <h5><A NAME="java2dgl">Offscreen Layer Remarks</A></h5>
+ * 
+ * {@link OffscreenLayerOption#setShallUseOffscreenLayer(boolean) setShallUseOffscreenLayer(true)}
+ * maybe called to use an offscreen drawable (FBO or PBuffer) allowing 
+ * the underlying JAWT mechanism to composite the image, if supported.
+ * <p>
+ * {@link OffscreenLayerOption#setShallUseOffscreenLayer(boolean) setShallUseOffscreenLayer(true)}
+ * is being called if {@link GLCapabilitiesImmutable#isOnscreen()} is <code>false</code>.
+ * </p>
+ * 
  * <h5><A NAME="java2dgl">Java2D OpenGL Remarks</A></h5>
  *
  * To avoid any conflicts with a potential Java2D OpenGL context,<br>
@@ -145,7 +156,8 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
   private final RecursiveLock lock = LockFactory.createRecursiveLock();
   private final GLDrawableHelper helper = new GLDrawableHelper();
   private AWTGraphicsConfiguration awtConfig;
-  private volatile GLDrawable drawable; // volatile: avoid locking for read-only access
+  private volatile GLDrawableImpl drawable; // volatile: avoid locking for read-only access
+  private volatile JAWTWindow jawtWindow; // the JAWTWindow presentation of this AWT Canvas, bound to the 'drawable' lifecycle
   private GLContextImpl context;
   private volatile boolean sendReshape = false; // volatile: maybe written by EDT w/o locking
 
@@ -236,6 +248,9 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
         // don't allow the user to change data
         capsReqUser = (GLCapabilitiesImmutable) capsReqUser.cloneMutable();
     }
+    if(!capsReqUser.isOnscreen()) {
+        setShallUseOffscreenLayer(true); // trigger offscreen layer - if supported
+    }
 
     if(null==device) {
         GraphicsConfiguration gc = super.getGraphicsConfiguration();
@@ -268,9 +283,9 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
 
   @Override
   public final boolean isOffscreenLayerSurfaceEnabled() {
-      final GLDrawable _drawable = drawable;
-      if(null != _drawable) {
-          return ((JAWTWindow)_drawable.getNativeSurface()).isOffscreenLayerSurfaceEnabled();
+      final JAWTWindow _jawtWindow = jawtWindow;
+      if(null != _jawtWindow) {
+          return _jawtWindow.isOffscreenLayerSurfaceEnabled();
       }
       return false;
   }
@@ -425,6 +440,12 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
 
   @Override
   public void display() {
+    if( !validateGLDrawable() ) {
+        if(DEBUG) {
+            System.err.println(getThreadName()+": Info: GLCanvas display - skipped GL render, drawable not valid yet");
+        }
+        return; // not yet available ..
+    }
     Threading.invoke(true, displayOnEDTAction, getTreeLock());
     awtWindowClosingProtocol.addClosingListenerOneShot();
   }
@@ -450,11 +471,9 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
   /** Overridden to cause OpenGL rendering to be performed during
       repaint cycles. Subclasses which override this method must call
       super.paint() in their paint() method in order to function
-      properly. <P>
-
-      <B>Overrides:</B>
-      <DL><DD><CODE>paint</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */
-    @Override
+      properly.
+    */
+  @Override
   public void paint(Graphics g) {
     if (Beans.isDesignTime()) {
       // Make GLCanvas behave better in NetBeans GUI builder
@@ -476,7 +495,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
                    (int) ((getHeight() + bounds.getHeight()) / 2));
       return;
     }
-    if( ! this.helper.isAnimatorAnimating() ) {
+    if( ! this.helper.isExternalAnimatorAnimating() ) {
         display();
     }
   }
@@ -539,11 +558,11 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
 
   private void createDrawableAndContext() {
     // no lock required, since this resource ain't available yet
-    final JAWTWindow jawtWindow = (JAWTWindow) NativeWindowFactory.getNativeWindow(this, awtConfig);
+    jawtWindow = (JAWTWindow) NativeWindowFactory.getNativeWindow(this, awtConfig);
     jawtWindow.setShallUseOffscreenLayer(shallUseOffscreenLayer);
     jawtWindow.lockSurface();
     try {
-        drawable = GLDrawableFactory.getFactory(capsReqUser.getGLProfile()).createGLDrawable(jawtWindow);
+        drawable = (GLDrawableImpl) GLDrawableFactory.getFactory(capsReqUser.getGLProfile()).createGLDrawable(jawtWindow);
         context = (GLContextImpl) drawable.createContext(shareWith);
         context.setContextCreationFlags(additionalCtxCreationFlags);
     } finally {
@@ -557,24 +576,36 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
         if( _drawable.isRealized() ) {
             return true;
         }
-        if (!Beans.isDesignTime() &&
-             0 < _drawable.getWidth() * _drawable.getHeight() ) {
-            // make sure drawable realization happens on AWT EDT, due to AWTTree lock
-            AWTEDTExecutor.singleton.invoke(true, setRealizedOnEDTAction);
-            sendReshape=true; // ensure a reshape is being send ..
-            if(DEBUG) {
-                System.err.println(getThreadName()+": Realized Drawable: "+_drawable.toString());
-                Thread.dumpStack();
-            }
-            return true;
+        if( Beans.isDesignTime() || !isDisplayable() || 0 >= _drawable.getWidth() || 0 >= _drawable.getHeight() ) {
+            return false; // early out!
         }
+        // make sure drawable realization happens on AWT EDT, due to AWTTree lock
+        AWTEDTExecutor.singleton.invoke(getTreeLock(), true, setRealizedOnEDTAction);
+        final boolean res = _drawable.isRealized();
+        if(DEBUG) {
+            System.err.println(getThreadName()+": Realized Drawable: "+res+", "+_drawable.toString());
+            Thread.dumpStack();
+        }
+        return res;
     }
     return false;
   }
-  private Runnable setRealizedOnEDTAction = new Runnable() {
-      @Override
-    public void run() {
-          drawable.setRealized(true);
+  private Runnable setRealizedOnEDTAction = new Runnable() { 
+      public void run() { 
+          final RecursiveLock _lock = lock;
+          _lock.lock();
+          try {            
+              final GLDrawable _drawable = drawable;
+              if( null == _drawable || 0 >= _drawable.getWidth() || 0 >= _drawable.getHeight() ) {
+                  return; 
+              }
+              _drawable.setRealized(true);
+              if( _drawable.isRealized() ) {
+                  sendReshape=true; // ensure a reshape is being send ..
+              }
+          } finally {
+              _lock.unlock();
+          }
       } };
 
   /** <p>Overridden to track when this component is removed from a
@@ -619,22 +650,40 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
     @SuppressWarnings("deprecation")
     @Override
   public void reshape(int x, int y, int width, int height) {
-    super.reshape(x, y, width, height);
-    final GLDrawable _drawable = drawable;
-    if(null != _drawable && _drawable.isRealized() && !_drawable.getChosenGLCapabilities().isOnscreen()) {
-        dispose(true);
-    } else {
-        sendReshape = true;
+    synchronized (getTreeLock()) { // super.reshape(..) claims tree lock, so we do extend it's lock over reshape
+        super.reshape(x, y, width, height);
+        
+        if(DEBUG) {
+            final NativeSurface ns = getNativeSurface();
+            final long nsH = null != ns ? ns.getSurfaceHandle() : 0;
+            System.err.println("GLCanvas.sizeChanged: ("+Thread.currentThread().getName()+"): "+width+"x"+height+" - surfaceHandle 0x"+Long.toHexString(nsH));
+            // Thread.dumpStack();
+        }            
+        if( validateGLDrawable() ) {
+            final GLDrawableImpl _drawable = drawable;
+            if( ! _drawable.getChosenGLCapabilities().isOnscreen() ) {
+                final RecursiveLock _lock = lock;
+                _lock.lock();
+                try {
+                    final GLDrawableImpl _drawableNew = GLDrawableHelper.resizeOffscreenDrawable(_drawable, context, width, height);
+                    if(_drawable != _drawableNew) {
+                        // write back 
+                        drawable = _drawableNew;
+                    }
+                } finally {
+                   _lock.unlock();
+                }
+            }
+            sendReshape = true; // async if display() doesn't get called below, but avoiding deadlock
+        }
     }
   }
 
-  /** <B>Overrides:</B>
-      <DL><DD><CODE>update</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */
   /**
    * Overridden from Canvas to prevent the AWT's clearing of the
    * canvas from interfering with the OpenGL rendering.
    */
-    @Override
+  @Override
   public void update(Graphics g) {
     paint(g);
   }
@@ -680,7 +729,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
       _lock.lock();
       try {
           final GLContext oldCtx = context;
-          final boolean newCtxCurrent = helper.switchContext(drawable, oldCtx, newCtx, additionalCtxCreationFlags);
+          final boolean newCtxCurrent = GLDrawableHelper.switchContext(drawable, oldCtx, newCtx, additionalCtxCreationFlags);
           context=(GLContextImpl)newCtx;
           if(newCtxCurrent) {
               context.makeCurrent();
@@ -692,6 +741,11 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
   }
 
   @Override
+  public final GLDrawable getDelegatedDrawable() {
+    return drawable;
+  }
+  
+  @Override
   public GLContext getContext() {
     return context;
   }
@@ -811,11 +865,11 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
     public void run() {
       context=null;
       if(null!=drawable) {
-          final JAWTWindow jawtWindow = (JAWTWindow)drawable.getNativeSurface();
           drawable.setRealized(false);
           drawable=null;
           if(null!=jawtWindow) {
             jawtWindow.destroy();
+            jawtWindow=null;
           }
       }
 
@@ -865,7 +919,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
         
             if(!disposeRegenerate) {
                 if(null != awtConfig) {
-                    disposeAbstractGraphicsDevice();
+                    AWTEDTExecutor.singleton.invoke(getTreeLock(), true, disposeAbstractGraphicsDeviceActionOnEDT);
                 }
                 awtConfig=null;
             }
@@ -880,7 +934,13 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
     }
   };
 
-  private final Runnable disposeAbstractGraphicsDeviceAction = new Runnable() {
+  /**
+   * Disposes the AbstractGraphicsDevice within EDT,
+   * since resources created (X11: Display), must be destroyed in the same thread, where they have been created.
+   *
+   * @see #chooseGraphicsConfiguration(javax.media.opengl.GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesChooser, java.awt.GraphicsDevice)
+   */
+  private final Runnable disposeAbstractGraphicsDeviceActionOnEDT = new Runnable() {
     @Override
     public void run() {
       if(null != awtConfig) {
@@ -899,31 +959,11 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
       }
     }
   };
-
-  /**
-   * Disposes the AbstractGraphicsDevice within EDT,
-   * since resources created (X11: Display), must be destroyed in the same thread, where they have been created.
-   *
-   * @see #chooseGraphicsConfiguration(javax.media.opengl.GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesChooser, java.awt.GraphicsDevice)
-   */
-  private void disposeAbstractGraphicsDevice()  {
-    if( EventQueue.isDispatchThread() || Thread.holdsLock(getTreeLock()) ) {
-        disposeAbstractGraphicsDeviceAction.run();
-    } else {
-        try {
-            EventQueue.invokeAndWait(disposeAbstractGraphicsDeviceAction);
-        } catch (InvocationTargetException e) {
-            throw new GLException(e.getTargetException());
-        } catch (InterruptedException e) {
-            throw new GLException(e);
-        }
-    }
-  }
-
+  
   private final Runnable initAction = new Runnable() {
     @Override
     public void run() {
-      helper.init(GLCanvas.this);
+      helper.init(GLCanvas.this, !sendReshape);
     }
   };
 
@@ -944,13 +984,6 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
     }
   };
 
-  private final Runnable swapBuffersAction = new Runnable() {
-    @Override
-    public void run() {
-      drawable.swapBuffers();
-    }
-  };
-
   // Workaround for ATI driver bugs related to multithreading issues
   // like simultaneous rendering via Animators to canvases that are
   // being resized on the AWT event dispatch thread
@@ -960,11 +993,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
         final RecursiveLock _lock = lock;
         _lock.lock();
         try {            
-            if( validateGLDrawable() ) {
-                helper.invokeGL(drawable, context, displayAction, initAction);
-            } else if(DEBUG) {
-                System.err.println(getThreadName()+": Info: GLCanvas display - skipped GL render, drawable not valid yet");
-            }
+            helper.invokeGL(drawable, context, displayAction, initAction);
         } finally {
             _lock.unlock();
         }
@@ -976,8 +1005,10 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
     public void run() {
         final RecursiveLock _lock = lock;
         _lock.lock();
-        try {            
-            helper.invokeGL(drawable, context, swapBuffersAction, initAction);
+        try {
+            if(null != drawable) {
+                drawable.swapBuffers();
+            }
         } finally {
             _lock.unlock();
         }
@@ -1045,7 +1076,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
    * @param device
    * @return the chosen AWTGraphicsConfiguration
    *
-   * @see #disposeAbstractGraphicsDevice()
+   * @see #disposeAbstractGraphicsDeviceActionOnEDT
    */
   private AWTGraphicsConfiguration chooseGraphicsConfiguration(final GLCapabilitiesImmutable capsChosen,
                                                                final GLCapabilitiesImmutable capsRequested,
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
index acb8f21..d0b9fb9 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
@@ -121,7 +121,7 @@ import com.jogamp.opengl.util.GLBuffers;
  *  </P>
 */
 
- at SuppressWarnings("serial")
+ at SuppressWarnings({ "serial", "deprecation" })
 public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosingProtocol {
   private static final boolean DEBUG = Debug.debug("GLJPanel");
 
@@ -396,7 +396,6 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
       their reshape() method in order to function properly. <P>
 
       <DL><DD><CODE>reshape</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */
-  @SuppressWarnings("deprecation")
   @Override
   public void reshape(int x, int y, int width, int height) {
     super.reshape(x, y, width, height);
@@ -471,7 +470,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
           return null;
       }
       final GLContext oldCtx = backend.getContext();
-      final boolean newCtxCurrent = helper.switchContext(backend.getDrawable(), oldCtx, newCtx, additionalCtxCreationFlags);
+      final boolean newCtxCurrent = GLDrawableHelper.switchContext(backend.getDrawable(), oldCtx, newCtx, additionalCtxCreationFlags);
       backend.setContext(newCtx);
       if(newCtxCurrent) {
           newCtx.makeCurrent();
@@ -481,6 +480,14 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
 
 
   @Override
+  public final GLDrawable getDelegatedDrawable() {
+    if (backend == null) {
+      return null;
+    }
+    return backend.getDrawable();
+  }
+  
+  @Override
   public GLContext getContext() {
     if (backend == null) {
       return null;
@@ -672,7 +679,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
       if (!backend.preGL(g)) {
         return;
       }
-      helper.init(GLJPanel.this);
+      helper.init(GLJPanel.this, !sendReshape);
       backend.postGL(g, false);
     }
 
diff --git a/src/jogl/classes/javax/media/opengl/fixedfunc/GLMatrixFunc.java b/src/jogl/classes/javax/media/opengl/fixedfunc/GLMatrixFunc.java
index a34d490..9fee0a2 100644
--- a/src/jogl/classes/javax/media/opengl/fixedfunc/GLMatrixFunc.java
+++ b/src/jogl/classes/javax/media/opengl/fixedfunc/GLMatrixFunc.java
@@ -31,69 +31,122 @@ package javax.media.opengl.fixedfunc;
 
 import java.nio.*;
 
+import javax.media.opengl.GL;
+
+/**
+ * Subset of OpenGL fixed function pipeline's matrix operations.
+ */
 public interface GLMatrixFunc {
 
-  public static final int GL_MATRIX_MODE = 0x0BA0;
-  public static final int GL_MODELVIEW = 0x1700;
-  public static final int GL_PROJECTION = 0x1701;
-  // public static final int GL_TEXTURE = 0x1702; // Use GL.GL_TEXTURE due to ambiguous GL usage
-  public static final int GL_MODELVIEW_MATRIX = 0x0BA6;
-  public static final int GL_PROJECTION_MATRIX = 0x0BA7;
-  public static final int GL_TEXTURE_MATRIX = 0x0BA8;
-
-  /**
-   * glGetFloatv
-   * @param pname GL_MODELVIEW_MATRIX, GL_PROJECTION_MATRIX or GL_TEXTURE_MATRIX
-   * @param params the FloatBuffer's position remains unchanged,
-   *        which is the same behavior than the native JOGL GL impl
-   */
-  public void glGetFloatv(int pname, java.nio.FloatBuffer params);
-  public void glGetFloatv(int pname, float[] params, int params_offset);
-  /**
-   * glGetIntegerv
-   * @param pname GL_MATRIX_MODE
-   * @param params the FloatBuffer's position remains unchanged
-   *        which is the same behavior than the native JOGL GL impl
-   */
-  public void glGetIntegerv(int pname, IntBuffer params);
-  public void glGetIntegerv(int pname, int[] params, int params_offset);
-
-  /**
-   * sets the current matrix
-   * @param pname GL_MODELVIEW, GL_PROJECTION or GL.GL_TEXTURE
-   */
-  public void glMatrixMode(int mode) ;
-
-  public void glPushMatrix();
-  public void glPopMatrix();
-
-  public void glLoadIdentity() ;
-
-  /**
-   * glLoadMatrixf
-   * @param params the FloatBuffer's position remains unchanged,
-   *        which is the same behavior than the native JOGL GL impl
-   */
-  public void glLoadMatrixf(java.nio.FloatBuffer m) ;
-  public void glLoadMatrixf(float[] m, int m_offset);
-
-  /**
-   * glMultMatrixf
-   * @param m the FloatBuffer's position remains unchanged,
-   *        which is the same behavior than the native JOGL GL impl
-   */
-  public void glMultMatrixf(java.nio.FloatBuffer m) ;
-  public void glMultMatrixf(float[] m, int m_offset);
-
-  public void glTranslatef(float x, float y, float z) ;
-
-  public void glRotatef(float angle, float x, float y, float z);
-
-  public void glScalef(float x, float y, float z) ;
-
-  public void glOrthof(float left, float right, float bottom, float top, float zNear, float zFar) ;
-
-  public void glFrustumf(float left, float right, float bottom, float top, float zNear, float zFar);
+    public static final int GL_MATRIX_MODE = 0x0BA0;
+    /** Matrix mode modelview */
+    public static final int GL_MODELVIEW = 0x1700;
+    /** Matrix mode projection */
+    public static final int GL_PROJECTION = 0x1701;
+    // public static final int GL_TEXTURE = 0x1702; // Use GL.GL_TEXTURE due to ambiguous GL usage
+    /** Matrix access name for modelview */
+    public static final int GL_MODELVIEW_MATRIX = 0x0BA6;
+    /** Matrix access name for projection */
+    public static final int GL_PROJECTION_MATRIX = 0x0BA7;
+    /** Matrix access name for texture */
+    public static final int GL_TEXTURE_MATRIX = 0x0BA8;
+
+    /**
+     * Copy the named matrix into the given storage.
+     * @param pname {@link #GL_MODELVIEW_MATRIX}, {@link #GL_PROJECTION_MATRIX} or {@link #GL_TEXTURE_MATRIX}
+     * @param params the FloatBuffer's position remains unchanged,
+     *        which is the same behavior than the native JOGL GL impl
+     */
+    public void glGetFloatv(int pname, java.nio.FloatBuffer params);
+    
+    /**
+     * Copy the named matrix to the given storage at offset.
+     * @param pname {@link #GL_MODELVIEW_MATRIX}, {@link #GL_PROJECTION_MATRIX} or {@link #GL_TEXTURE_MATRIX}
+     * @param params storage
+     * @param params_offset storage offset
+     */ 
+    public void glGetFloatv(int pname, float[] params, int params_offset);
+    
+    /**
+     * glGetIntegerv
+     * @param pname {@link #GL_MATRIX_MODE} to receive the current matrix mode 
+     * @param params the FloatBuffer's position remains unchanged
+     *        which is the same behavior than the native JOGL GL impl
+     */
+    public void glGetIntegerv(int pname, IntBuffer params);
+    public void glGetIntegerv(int pname, int[] params, int params_offset);
+
+    /**
+     * Sets the current matrix mode.
+     * @param mode {@link #GL_MODELVIEW}, {@link #GL_PROJECTION} or {@link GL#GL_TEXTURE GL_TEXTURE}.
+     */
+    public void glMatrixMode(int mode) ;
+
+    /**
+     * Push the current matrix to it's stack, while preserving it's values.
+     * <p>
+     * There exist one stack per matrix mode, i.e. {@link #GL_MODELVIEW}, {@link #GL_PROJECTION} and {@link GL#GL_TEXTURE GL_TEXTURE}.
+     * </p>
+     */
+    public void glPushMatrix();
+    
+    /**
+     * Pop the current matrix from it's stack.
+     * @see #glPushMatrix()
+     */
+    public void glPopMatrix();
+
+    /**
+     * Load the current matrix with the identity matrix 
+     */
+    public void glLoadIdentity() ;
+
+    /**
+     * Load the current matrix w/ the provided one. 
+     * @param params the FloatBuffer's position remains unchanged,
+     *        which is the same behavior than the native JOGL GL impl
+     */
+    public void glLoadMatrixf(java.nio.FloatBuffer m) ;    
+    /**
+     * Load the current matrix w/ the provided one.
+     */ 
+    public void glLoadMatrixf(float[] m, int m_offset);
+
+    /**
+     * Multiply the current matrix
+     * @param m the FloatBuffer's position remains unchanged,
+     *        which is the same behavior than the native JOGL GL impl
+     */
+    public void glMultMatrixf(java.nio.FloatBuffer m) ;
+    /**
+     * Multiply the current matrix
+     */
+    public void glMultMatrixf(float[] m, int m_offset);
+
+    /**
+     * Translate the current matrix.
+     */
+    public void glTranslatef(float x, float y, float z) ;
+
+    /**
+     * Rotate the current matrix.
+     */
+    public void glRotatef(float angle, float x, float y, float z);
+
+    /**
+     * Scale the current matrix.
+     */
+    public void glScalef(float x, float y, float z) ;
+
+    /**
+     * {@link #glMultMatrixf(FloatBuffer) Multiply} the current matrix with the orthogonal matrix.
+     */
+    public void glOrthof(float left, float right, float bottom, float top, float zNear, float zFar) ;
+
+    /**
+     * {@link #glMultMatrixf(FloatBuffer) Multiply} the current matrix with the frustum matrix.
+     */
+    public void glFrustumf(float left, float right, float bottom, float top, float zNear, float zFar);
 
 }
 
diff --git a/src/jogl/classes/javax/media/opengl/fixedfunc/GLPointerFuncUtil.java b/src/jogl/classes/javax/media/opengl/fixedfunc/GLPointerFuncUtil.java
index e52154c..79ec38e 100644
--- a/src/jogl/classes/javax/media/opengl/fixedfunc/GLPointerFuncUtil.java
+++ b/src/jogl/classes/javax/media/opengl/fixedfunc/GLPointerFuncUtil.java
@@ -40,6 +40,15 @@ public class GLPointerFuncUtil {
      * @return default fixed function array name 
      */
     public static String getPredefinedArrayIndexName(int glArrayIndex) {
+        return getPredefinedArrayIndexName(glArrayIndex, -1);
+    }
+    
+    /**
+     * @param glArrayIndex the fixed function array index
+     * @param multiTexCoordIndex index for multiTexCoordIndex  
+     * @return default fixed function array name 
+     */
+    public static String getPredefinedArrayIndexName(int glArrayIndex, int multiTexCoordIndex) {
         switch(glArrayIndex) {
             case GLPointerFunc.GL_VERTEX_ARRAY:
                 return mgl_Vertex;
@@ -48,7 +57,11 @@ public class GLPointerFuncUtil {
             case GLPointerFunc.GL_COLOR_ARRAY:
                 return mgl_Color;
             case GLPointerFunc.GL_TEXTURE_COORD_ARRAY:
-                return mgl_MultiTexCoord;
+                if(0<=multiTexCoordIndex) {
+                    return mgl_MultiTexCoord+multiTexCoordIndex;
+                } else {
+                    return mgl_MultiTexCoord+multiTexCoordIndex;
+                }
         }
         return null;
     }
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/RegionRendererImpl01.java b/src/jogl/classes/jogamp/graph/curve/opengl/RegionRendererImpl01.java
index c34d1cb..2884aca 100755
--- a/src/jogl/classes/jogamp/graph/curve/opengl/RegionRendererImpl01.java
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/RegionRendererImpl01.java
@@ -65,7 +65,9 @@ public class RegionRendererImpl01 extends RegionRenderer {
         sp.add(rsVp);
         sp.add(rsFp);
 
-        sp.init(gl);
+        if( !sp.init(gl) ) { 
+            throw new GLException("RegionRenderer: Couldn't init program: "+sp);
+        }
         st.attachShaderProgram(gl, sp, false);        
         st.bindAttribLocation(gl, AttributeNames.VERTEX_ATTR_IDX, AttributeNames.VERTEX_ATTR_NAME);
         st.bindAttribLocation(gl, AttributeNames.TEXCOORD_ATTR_IDX, AttributeNames.TEXCOORD_ATTR_NAME);        
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/TextRendererImpl01.java b/src/jogl/classes/jogamp/graph/curve/opengl/TextRendererImpl01.java
index 158f024..0cf424c 100644
--- a/src/jogl/classes/jogamp/graph/curve/opengl/TextRendererImpl01.java
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/TextRendererImpl01.java
@@ -58,7 +58,9 @@ public class TextRendererImpl01 extends TextRenderer {
         sp.add(rsVp);
         sp.add(rsFp);
         
-        sp.init(gl);
+        if( !sp.init(gl) ) { 
+            throw new GLException("RegionRenderer: Couldn't init program: "+sp);
+        }
         st.attachShaderProgram(gl, sp, false);        
         st.bindAttribLocation(gl, AttributeNames.VERTEX_ATTR_IDX, AttributeNames.VERTEX_ATTR_NAME);
         st.bindAttribLocation(gl, AttributeNames.TEXCOORD_ATTR_IDX, AttributeNames.TEXCOORD_ATTR_NAME);        
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PES2.java b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PES2.java
index aabef29..85d3ad5 100644
--- a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PES2.java
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PES2.java
@@ -220,14 +220,14 @@ public class VBORegion2PES2  extends GLRegion {
         gl.glActiveTexture(GL.GL_TEXTURE0 + mgl_ActiveTexture.intValue());
         fbo.use(gl, texA);                        
         verticeFboAttr.enableBuffer(gl, true);       
-        texCoordFboAttr.enableBuffer(gl, true);
-        indicesFbo.enableBuffer(gl, true);
+        texCoordFboAttr.enableBuffer(gl, true);        
+        indicesFbo.bindBuffer(gl, true); // keeps VBO binding
         
-        gl.glDrawElements(GL2ES2.GL_TRIANGLES, indicesFbo.getElementCount() * indicesFbo.getComponentCount(), GL2ES2.GL_UNSIGNED_SHORT, 0);         
+        gl.glDrawElements(GL2ES2.GL_TRIANGLES, indicesFbo.getElementCount() * indicesFbo.getComponentCount(), GL2ES2.GL_UNSIGNED_SHORT, 0);
         
-        verticeFboAttr.enableBuffer(gl, false);       
+        indicesFbo.bindBuffer(gl, false);        
         texCoordFboAttr.enableBuffer(gl, false);
-        indicesFbo.enableBuffer(gl, false);        
+        verticeFboAttr.enableBuffer(gl, false);       
         fbo.unuse(gl);
         
         // setback: gl.glActiveTexture(currentActiveTextureEngine[0]);
@@ -287,13 +287,13 @@ public class VBORegion2PES2  extends GLRegion {
     private void renderRegion(GL2ES2 gl) {
         verticeTxtAttr.enableBuffer(gl, true);       
         texCoordTxtAttr.enableBuffer(gl, true);
-        indicesTxt.enableBuffer(gl, true);        
+        indicesTxt.bindBuffer(gl, true); // keeps VBO binding
         
-        gl.glDrawElements(GL2ES2.GL_TRIANGLES, indicesTxt.getElementCount() * indicesTxt.getComponentCount(), GL2ES2.GL_UNSIGNED_SHORT, 0);        
+        gl.glDrawElements(GL2ES2.GL_TRIANGLES, indicesTxt.getElementCount() * indicesTxt.getComponentCount(), GL2ES2.GL_UNSIGNED_SHORT, 0);
         
-        verticeTxtAttr.enableBuffer(gl, false);       
+        indicesTxt.bindBuffer(gl, false);        
         texCoordTxtAttr.enableBuffer(gl, false);
-        indicesTxt.enableBuffer(gl, false);        
+        verticeTxtAttr.enableBuffer(gl, false);       
     }
     
     public void destroy(GL2ES2 gl, RenderState rs) {
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegionSPES2.java b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegionSPES2.java
index 14ff038..0cba444 100644
--- a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegionSPES2.java
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegionSPES2.java
@@ -127,14 +127,14 @@ public class VBORegionSPES2 extends GLRegion {
 
     protected void drawImpl(GL2ES2 gl, RenderState rs, int vp_width, int vp_height, int[/*1*/] texWidth) {
         verticeAttr.enableBuffer(gl, true);       
-        texCoordAttr.enableBuffer(gl, true);
-        indices.enableBuffer(gl, true);
-
-        gl.glDrawElements(GL2ES2.GL_TRIANGLES, indices.getElementCount() * indices.getComponentCount(), GL2ES2.GL_UNSIGNED_SHORT, 0);         
-
-        verticeAttr.enableBuffer(gl, false);       
+        texCoordAttr.enableBuffer(gl, true);        
+        indices.bindBuffer(gl, true); // keeps VBO binding
+        
+        gl.glDrawElements(GL2ES2.GL_TRIANGLES, indices.getElementCount() * indices.getComponentCount(), GL2ES2.GL_UNSIGNED_SHORT, 0);
+        
+        indices.bindBuffer(gl, false);
         texCoordAttr.enableBuffer(gl, false);
-        indices.enableBuffer(gl, false);
+        verticeAttr.enableBuffer(gl, false);       
     }    
 
     public final void destroy(GL2ES2 gl, RenderState rs) {
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-es2-merged.vp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-es2-merged.vp
index 530b24f..8fb985d 100644
--- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-es2-merged.vp
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-es2-merged.vp
@@ -1,8 +1,8 @@
 //Copyright 2010 JogAmp Community. All rights reserved.
 
 #ifdef GL_ES
-  precision lowp float;
-  precision lowp int;
+  precision highp float;
+  precision highp int;
 #endif
 
 uniform mat4    gcu_PMVMatrix[3]; // P, Mv, and Mvi
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-es2.vp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-es2.vp
index 15ce8cc..a5dc158 100644
--- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-es2.vp
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-es2.vp
@@ -2,8 +2,8 @@
 
 #version 100
 
-precision mediump float;
-precision mediump int;
+precision highp float;
+precision highp int;
 
 #include curverenderer01-xxx.vp
 
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01a-es2-merged.fp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01a-es2-merged.fp
index da32df5..a57d8fc 100644
--- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01a-es2-merged.fp
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01a-es2-merged.fp
@@ -1,8 +1,8 @@
 //Copyright 2010 JogAmp Community. All rights reserved.
 
 #ifdef GL_ES
-  precision lowp float;
-  precision lowp int;
+  precision mediump float;
+  precision mediump int;
 #endif
 
 uniform mat4    gcu_PMVMatrix[3]; // P, Mv, and Mvi
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01b-es2.fp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01b-es2.fp
index 2e70963..d474872 100644
--- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01b-es2.fp
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01b-es2.fp
@@ -8,7 +8,7 @@
 
 precision mediump float;
 precision mediump int;
-precision mediump sampler2D;
+precision mediump sampler2D; // default is lowp
 
 #include curverenderer01b-xxx.fp
 
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer02a-es2.fp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer02a-es2.fp
index b524203..240a6c3 100644
--- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer02a-es2.fp
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer02a-es2.fp
@@ -8,7 +8,7 @@
 
 precision mediump float;
 precision mediump int;
-precision mediump sampler2D;
+precision mediump sampler2D; // default is lowp
 
 #include curverenderer02a-xxx.fp
 
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer02b-es2.fp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer02b-es2.fp
index e0486dd..884e756 100644
--- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer02b-es2.fp
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer02b-es2.fp
@@ -8,7 +8,7 @@
 
 precision mediump float;
 precision mediump int;
-precision mediump sampler2D;
+precision mediump sampler2D; // default is lowp
 
 #include curverenderer02b-xxx.fp
 
diff --git a/src/jogl/classes/jogamp/graph/font/JavaFontLoader.java b/src/jogl/classes/jogamp/graph/font/JavaFontLoader.java
index a00e957..3736c5f 100644
--- a/src/jogl/classes/jogamp/graph/font/JavaFontLoader.java
+++ b/src/jogl/classes/jogamp/graph/font/JavaFontLoader.java
@@ -41,7 +41,10 @@ import com.jogamp.graph.font.FontFactory;
 
 public class JavaFontLoader implements FontSet {
     
-    final static FontSet fontLoader = new JavaFontLoader();
+    // FIXME: Add cache size to limit memory usage 
+    private static final IntObjectHashMap fontMap = new IntObjectHashMap();
+    
+    private static final FontSet fontLoader = new JavaFontLoader();
 
     public static FontSet get() {
         return fontLoader;
@@ -74,9 +77,6 @@ public class JavaFontLoader implements FontSet {
         }
     }
 
-    // FIXME: Add cache size to limit memory usage 
-    static final IntObjectHashMap fontMap = new IntObjectHashMap();
-    
     static boolean is(int bits, int bit) {
         return 0 != ( bits & bit ) ;
     }
diff --git a/src/jogl/classes/jogamp/graph/font/UbuntuFontLoader.java b/src/jogl/classes/jogamp/graph/font/UbuntuFontLoader.java
index 0772cc4..c4c5802 100644
--- a/src/jogl/classes/jogamp/graph/font/UbuntuFontLoader.java
+++ b/src/jogl/classes/jogamp/graph/font/UbuntuFontLoader.java
@@ -40,9 +40,14 @@ import java.net.URLConnection;
 
 public class UbuntuFontLoader implements FontSet {
     
-    final static FontSet fontLoader = new UbuntuFontLoader();
+    // FIXME: Add cache size to limit memory usage 
+    private static final IntObjectHashMap fontMap = new IntObjectHashMap();
+        
+    private static final String relPath = "fonts/ubuntu/" ;    
+    
+    private static final FontSet fontLoader = new UbuntuFontLoader();
 
-    public static FontSet get() {
+    public static final FontSet get() {
         return fontLoader;
     }
     
@@ -59,14 +64,9 @@ public class UbuntuFontLoader implements FontSet {
 
     };
         
-    final static String relPath = "fonts/ubuntu/" ;    
-    
     private UbuntuFontLoader() {
     }
 
-    // FIXME: Add cache size to limit memory usage 
-    static final IntObjectHashMap fontMap = new IntObjectHashMap();
-        
     static boolean is(int bits, int bit) {
         return 0 != ( bits & bit ) ;
     }
diff --git a/src/jogl/classes/jogamp/graph/geom/plane/Path2D.java b/src/jogl/classes/jogamp/graph/geom/plane/Path2D.java
index 8082fe4..c895e83 100644
--- a/src/jogl/classes/jogamp/graph/geom/plane/Path2D.java
+++ b/src/jogl/classes/jogamp/graph/geom/plane/Path2D.java
@@ -397,7 +397,7 @@ public final class Path2D implements Cloneable {
     }
 
     public boolean contains(AABBox r) {
-        return contains(r);
+        return contains(r.getMinX(), r.getMinY(), r.getWidth(), r.getHeight());   
     }
 
     public boolean intersects(AABBox r) {
diff --git a/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java b/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java
index cc4e1b4..85156e8 100644
--- a/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java
+++ b/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java
@@ -30,16 +30,15 @@ package jogamp.opengl;
 
 import java.io.PrintStream;
 
-import javax.media.nativewindow.AbstractGraphicsConfiguration;
 import javax.media.nativewindow.AbstractGraphicsDevice;
 import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowException;
 import javax.media.nativewindow.WindowClosingProtocol;
 import javax.media.nativewindow.WindowClosingProtocol.WindowClosingMode;
 import javax.media.opengl.FPSCounter;
 import javax.media.opengl.GL;
 import javax.media.opengl.GLAnimatorControl;
 import javax.media.opengl.GLAutoDrawable;
-import javax.media.opengl.GLAutoDrawableDelegate;
 import javax.media.opengl.GLCapabilitiesImmutable;
 import javax.media.opengl.GLContext;
 import javax.media.opengl.GLDrawable;
@@ -49,6 +48,7 @@ import javax.media.opengl.GLProfile;
 import javax.media.opengl.GLRunnable;
 
 import com.jogamp.common.util.locks.RecursiveLock;
+import com.jogamp.opengl.GLAutoDrawableDelegate;
 import com.jogamp.opengl.util.Animator;
 
 
@@ -61,71 +61,83 @@ import com.jogamp.opengl.util.Animator;
  * @see GLWindow
  */
 public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
-    public static final boolean DEBUG = Debug.debug("GLAutoDrawable");
+    public static final boolean DEBUG = GLDrawableImpl.DEBUG;
     
     protected final GLDrawableHelper helper = new GLDrawableHelper();
     protected final FPSCounterImpl fpsCounter = new FPSCounterImpl();
     
     protected volatile GLDrawableImpl drawable; // volatile: avoid locking for read-only access
     protected GLContextImpl context;
-    protected final boolean ownDevice;
+    protected final boolean ownsDevice;
     protected int additionalCtxCreationFlags = 0;
     protected volatile boolean sendReshape = false; // volatile: maybe written by WindowManager thread w/o locking
     protected volatile boolean sendDestroy = false; // volatile: maybe written by WindowManager thread w/o locking
 
     /**
-     * @param drawable a valid {@link GLDrawableImpl}, may not be realized yet.
-     * @param context a valid {@link GLContextImpl}, may not be made current (created) yet.
-     * @param ownDevice pass <code>true</code> if {@link AbstractGraphicsDevice#close()} shall be issued,
-     *                  otherwise pass <code>false</code>. Closing the device is required in case
-     *                  the drawable is created w/ it's own new instance, e.g. offscreen drawables,
-     *                  and no further lifecycle handling is applied.
+     * @param drawable upstream {@link GLDrawableImpl} instance, may be null for lazy initialization
+     * @param context upstream {@link GLContextImpl} instance, may be null for lazy initialization
+     * @param ownsDevice pass <code>true</code> if {@link AbstractGraphicsDevice#close()} shall be issued,
+     *                   otherwise pass <code>false</code>. Closing the device is required in case
+     *                   the drawable is created w/ it's own new instance, e.g. offscreen drawables,
+     *                   and no further lifecycle handling is applied.
      */
-    public GLAutoDrawableBase(GLDrawableImpl drawable, GLContextImpl context, boolean ownDevice) {
+    public GLAutoDrawableBase(GLDrawableImpl drawable, GLContextImpl context, boolean ownsDevice) {
         this.drawable = drawable;
         this.context = context;
-        this.ownDevice = ownDevice;
+        this.ownsDevice = ownsDevice;
         resetFPSCounter();        
     }
    
+    /** Returns the recursive lock object of the upstream implementation, which synchronizes multithreaded access. */ 
     protected abstract RecursiveLock getLock();
     
-    /** Returns the delegated GLDrawable */
-    public final GLDrawable getDelegatedDrawable() { return drawable; }
-    
     /** Default implementation to handle repaint events from the windowing system */
     protected final void defaultWindowRepaintOp() {
         final GLDrawable _drawable = drawable;
         if( null != _drawable && _drawable.isRealized() ) {
-            if( !_drawable.getNativeSurface().isSurfaceLockedByOtherThread() && !helper.isAnimatorAnimating() ) {
+            if( !_drawable.getNativeSurface().isSurfaceLockedByOtherThread() && !helper.isExternalAnimatorAnimating() ) {
                 display();
             }
         }
     }
     
-    /** Default implementation to handle resize events from the windowing system */
-    protected final void defaultWindowResizedOp() {
-        final GLDrawable _drawable = drawable;
+    /** Default implementation to handle resize events from the windowing system. All required locks are being claimed. */
+    protected final void defaultWindowResizedOp(int newWidth, int newHeight) throws NativeWindowException, GLException {
+        GLDrawableImpl _drawable = drawable;
         if( null!=_drawable ) {
             if(DEBUG) {
-                System.err.println("GLAutoDrawableBase.sizeChanged: ("+Thread.currentThread().getName()+"): "+getWidth()+"x"+getHeight()+" - surfaceHandle 0x"+Long.toHexString(getNativeSurface().getSurfaceHandle()));
+                System.err.println("GLAutoDrawableBase.sizeChanged: ("+Thread.currentThread().getName()+"): "+newWidth+"x"+newHeight+" - surfaceHandle 0x"+Long.toHexString(getNativeSurface().getSurfaceHandle()));
+            }
+            if( ! _drawable.getChosenGLCapabilities().isOnscreen() ) {
+                final RecursiveLock _lock = getLock();
+                _lock.lock();
+                try {
+                    final GLDrawableImpl _drawableNew = GLDrawableHelper.resizeOffscreenDrawable(_drawable, context, newWidth, newHeight);
+                    if(_drawable != _drawableNew) {
+                        // write back 
+                        _drawable = _drawableNew;
+                        drawable = _drawableNew;
+                    }
+                } finally {
+                    _lock.unlock();
+                }
             }
             sendReshape = true; // async if display() doesn't get called below, but avoiding deadlock
             if( _drawable.isRealized() ) {
-                if( !_drawable.getNativeSurface().isSurfaceLockedByOtherThread() && !helper.isAnimatorAnimating() ) {
+                if( !_drawable.getNativeSurface().isSurfaceLockedByOtherThread() && !helper.isExternalAnimatorAnimating() ) {
                     display();
                 }
-            }        
+            }
         }
     }
-
+    
     /** 
      * Default implementation to handle destroy notifications from the windowing system.
      * 
      * <p>
      * If the {@link NativeSurface} does not implement {@link WindowClosingProtocol} 
      * or {@link WindowClosingMode#DISPOSE_ON_CLOSE} is enabled (default),
-     * {@link #defaultDestroy()} is being called.
+     * a thread safe destruction is being induced.
      * </p> 
      */
     protected final void defaultWindowDestroyNotifyOp() {
@@ -174,7 +186,7 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
                 ctrl.resume();
             }
         } else if (null != ns && ns.isSurfaceLockedByOtherThread()) {
-            // surface is locked by another thread
+            // Surface is locked by another thread.
             // Flag that destroy should be performed on the next
             // attempt to display.
             sendDestroy = true; // async, but avoiding deadlock
@@ -225,7 +237,7 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
                 }
                 _drawable.setRealized(false);
             }
-            if( ownDevice ) {
+            if( ownsDevice ) {
                 _drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice().close();
             }
         }
@@ -236,10 +248,9 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
     public final void defaultSwapBuffers() throws GLException {
         final RecursiveLock _lock = getLock();
         _lock.lock();
-        try {            
-            if(drawable!=null && context != null) {
+        try {
+            if(null != drawable) {
                 drawable.swapBuffers();
-                helper.invokeGL(drawable, context, defaultSwapAction, defaultInitAction);
             }
         } finally {
             _lock.unlock();
@@ -254,7 +265,7 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
         @Override
         public final void run() {
             // Lock: Locked Surface/Window by MakeCurrent/Release
-            helper.init(GLAutoDrawableBase.this);
+            helper.init(GLAutoDrawableBase.this, !sendReshape);
             resetFPSCounter();
         } };
 
@@ -276,7 +287,7 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
             destroy();
             return;
         }
-        final RecursiveLock _lock = getLock();        
+        final RecursiveLock _lock = getLock();
         _lock.lock();
         try {
             if( null != context ) {
@@ -288,12 +299,11 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
         }
     }
         
-    protected final Runnable defaultSwapAction = new Runnable() {
-        @Override
-        public final void run() {
-            drawable.swapBuffers();
-        } } ;
-        
+    @Override
+    public final GLDrawable getDelegatedDrawable() {
+        return drawable;
+    }
+    
     @Override
     public final GLContext getContext() {
         return context;
@@ -305,7 +315,7 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
         lock.lock();
         try {
             final GLContext oldCtx = context;
-            final boolean newCtxCurrent = helper.switchContext(drawable, oldCtx, newCtx, additionalCtxCreationFlags);
+            final boolean newCtxCurrent = GLDrawableHelper.switchContext(drawable, oldCtx, newCtx, additionalCtxCreationFlags);
             context=(GLContextImpl)newCtx;
             if(newCtxCurrent) {
                 context.makeCurrent();
@@ -490,8 +500,8 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
     /**
      * @param t the thread for which context release shall be skipped, usually the animation thread,
      *          ie. {@link Animator#getThread()}.
-     * @deprecated this is an experimental feature,
-     *             intended for measuring performance in regards to GL context switch
+     * @deprecated This is an experimental feature,
+     *             intended for measuring performance in regards to GL context switch.
      */
     @Deprecated
     public void setSkipContextReleaseThread(Thread t) {
@@ -529,4 +539,10 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
         final GLDrawable _drawable = drawable;
         return null != _drawable ? _drawable.getHandle() : 0;
     }
+    
+    @Override
+    public String toString() {
+        return getClass().getSimpleName()+"[ \n\tHelper: " + helper + ", \n\tDrawable: " + drawable +
+               ", \n\tContext: " + context + /** ", \n\tWindow: "+window+ ", \n\tFactory: "+factory+ */ "]";
+    }
 }
diff --git a/src/jogl/classes/jogamp/opengl/GLBufferStateTracker.java b/src/jogl/classes/jogamp/opengl/GLBufferStateTracker.java
index 92e27cb..4a1a81b 100644
--- a/src/jogl/classes/jogamp/opengl/GLBufferStateTracker.java
+++ b/src/jogl/classes/jogamp/opengl/GLBufferStateTracker.java
@@ -100,7 +100,6 @@ public class GLBufferStateTracker {
   public final void setBoundBufferObject(int target, int value) {
     bindingMap.put(target, value);
     if (DEBUG) {
-      System.err.println();
       System.err.println("GLBufferStateTracker.setBoundBufferObject() target 0x" + 
                          Integer.toHexString(target) + " -> mapped bound buffer 0x" +
                          Integer.toHexString(value));
@@ -128,11 +127,16 @@ public class GLBufferStateTracker {
         default:                          gotQueryTarget = false; break;
       }
       if (gotQueryTarget) {
+        final int glerrPre = caller.glGetError(); // clear
         caller.glGetIntegerv(queryTarget, bufTmp, 0);
-        value = 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
+        if(GL.GL_NO_ERROR == glerrPost) {
+            value = bufTmp[0];
+        } else {
+            value = 0;
+        }
         if (DEBUG) {
-          System.err.println();
-          System.err.println("GLBufferStateTracker.getBoundBufferObject() [queried value]: target 0x" + 
+          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));
         }
@@ -142,7 +146,6 @@ public class GLBufferStateTracker {
       return 0;
     }
     if (DEBUG) {
-      System.err.println();
       System.err.println("GLBufferStateTracker.getBoundBufferObject() [mapped value]: target 0x" + 
                          Integer.toHexString(target) + " -> mapped bound buffer 0x" +
                          Integer.toHexString(value));
@@ -160,7 +163,6 @@ public class GLBufferStateTracker {
   public final void clearBufferObjectState() {
     bindingMap.clear();
         if (DEBUG) {
-          System.err.println();
           System.err.println("GLBufferStateTracker.clearBufferObjectState()");
           //Thread.dumpStack();
         }
diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
index bf6a0ee..65b5233 100644
--- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
@@ -46,17 +46,21 @@ import java.util.HashMap;
 import java.util.Map;
 
 import com.jogamp.common.os.DynamicLookupHelper;
+import com.jogamp.common.os.Platform;
 import com.jogamp.common.util.ReflectionUtil;
+import com.jogamp.common.util.VersionNumber;
 import com.jogamp.gluegen.runtime.FunctionAddressResolver;
 import com.jogamp.gluegen.runtime.ProcAddressTable;
 import com.jogamp.gluegen.runtime.opengl.GLNameResolver;
 import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
 import com.jogamp.opengl.GLExtensions;
+import com.jogamp.opengl.GLRendererQuirks;
 
 import javax.media.nativewindow.AbstractGraphicsConfiguration;
 import javax.media.nativewindow.AbstractGraphicsDevice;
 import javax.media.nativewindow.NativeSurface;
 import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES2;
 import javax.media.opengl.GL2GL3;
 import javax.media.opengl.GLCapabilitiesImmutable;
 import javax.media.opengl.GLContext;
@@ -85,6 +89,7 @@ public abstract class GLContextImpl extends GLContext {
 
   private String glRenderer;
   private String glRendererLowerCase;
+  private String glVersion;
 
   // Tracks creation and initialization of buffer objects to avoid
   // repeated glGet calls upon glMapBuffer operations
@@ -93,7 +98,8 @@ public abstract class GLContextImpl extends GLContext {
   private final GLStateTracker glStateTracker = new GLStateTracker();
   private GLDebugMessageHandler glDebugHandler = null;
   private final int[] boundFBOTarget = new int[] { 0, 0 }; // { draw, read }
-
+  private int defaultVAO = 0; 
+  
   protected GLDrawableImpl drawable;
   protected GLDrawableImpl drawableRead;
   
@@ -126,6 +132,9 @@ public abstract class GLContextImpl extends GLContext {
     GLContextShareSet.synchronizeBufferObjectSharing(shareWith, this);
 
     this.drawable = drawable;
+    if(null != drawable) {
+        drawable.associateContext(this, true);
+    }
     this.drawableRead = drawable;
 
     this.glDebugHandler = new GLDebugMessageHandler(this);
@@ -157,7 +166,7 @@ public abstract class GLContextImpl extends GLContext {
       additionalCtxCreationFlags = 0;
 
       glRenderer = "";
-      glRendererLowerCase = glRenderer;
+      glRendererLowerCase = glRenderer;       
       
       if (boundFBOTarget != null) { // <init>
           boundFBOTarget[0] = 0; // draw
@@ -205,8 +214,11 @@ public abstract class GLContextImpl extends GLContext {
     if(!setWriteOnly || drawableRead==drawable) { // if !setWriteOnly || !explicitReadDrawable
         drawableRead = (GLDrawableImpl) readWrite;
     }
-    final GLDrawable old = drawable;
+    final GLDrawableImpl old = drawable;
+    old.associateContext(this, false);
+    drawableRetargeted = null != drawable;
     drawable = (GLDrawableImpl) readWrite ;
+    drawable.associateContext(this, true);
     if(lockHeld) {
         makeCurrent();
     }
@@ -261,16 +273,21 @@ public abstract class GLContextImpl extends GLContext {
   }
   private void release(boolean inDestruction) throws GLException {
     if(TRACE_SWITCH) {
-        System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+" - release() - force: "+inDestruction+", "+lock);
+        System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+", surf "+toHexString(drawable.getHandle())+" - release() - force: "+inDestruction+", "+lock);
     }
     if ( !lock.isOwner(Thread.currentThread()) ) {
         throw new GLException("Context not current on current thread "+Thread.currentThread().getName()+": "+this);
     }
+    Throwable drawableContextMadeCurrentException = null;
     final boolean actualRelease = ( inDestruction || lock.getHoldCount() == 1 ) && 0 != contextHandle;
     try {
         if( actualRelease ) {
             if( !inDestruction ) {
-                drawable.contextMadeCurrent(this, false);
+                try {
+                    contextMadeCurrent(false);
+                } catch (Throwable t) {
+                    drawableContextMadeCurrentException = t;
+                }
             }
             releaseImpl();
         }
@@ -282,9 +299,13 @@ public abstract class GLContextImpl extends GLContext {
       drawable.unlockSurface();
       lock.unlock();
       if(TRACE_SWITCH) {
-          System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+" - "+(actualRelease?"switch":"keep  ")+" - CONTEXT_RELEASE - "+lock);
+          System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+", surf "+toHexString(drawable.getHandle())+" - "+(actualRelease?"switch":"keep  ")+" - CONTEXT_RELEASE - "+lock);
       }
     }
+    if(null != drawableContextMadeCurrentException) {
+      throw new GLException("GLContext.release(false) during GLDrawableImpl.contextMadeCurrent(this, false)", drawableContextMadeCurrentException);
+    }
+    
   }
   protected abstract void releaseImpl() throws GLException;
 
@@ -292,7 +313,7 @@ public abstract class GLContextImpl extends GLContext {
   public final void destroy() {
       if (DEBUG || TRACE_SWITCH) {
           System.err.println(getThreadName() + ": GLContextImpl.destroy.0: obj " + toHexString(hashCode()) + ", ctx " + toHexString(contextHandle) +
-                  ", isShared "+GLContextShareSet.isShared(this)+" - "+lock);
+                  ", surf "+toHexString(drawable.getHandle())+", isShared "+GLContextShareSet.isShared(this)+" - "+lock);
       }
       if (contextHandle != 0) {
           int lockRes = drawable.lockSurface();
@@ -300,6 +321,7 @@ public abstract class GLContextImpl extends GLContext {
                 // this would be odd ..
                 throw new GLException("Surface not ready to lock: "+drawable);
           }
+          Throwable drawableContextRealizedException = null;
           try {
               // Must hold the lock around the destroy operation to make sure we
               // don't destroy the context while another thread renders to it.
@@ -320,7 +342,18 @@ public abstract class GLContextImpl extends GLContext {
                       // needs current context to disable debug handler
                       makeCurrent();
                   }
-                  drawable.contextRealized(this, false);
+                  try {
+                      contextRealized(false);
+                      drawable.associateContext(this, false);
+                  } catch (Throwable t) {
+                      drawableContextRealizedException = t;
+                  }
+                  if(0 != defaultVAO) {
+                      int[] tmp = new int[] { defaultVAO };
+                      gl.getGL2GL3().glBindVertexArray(0);
+                      gl.getGL2GL3().glDeleteVertexArrays(1, tmp, 0);
+                      defaultVAO = 0;
+                  }
                   glDebugHandler.enable(false);
                   if(lock.getHoldCount() > 1) {
                       // pending release() after makeCurrent()
@@ -343,6 +376,9 @@ public abstract class GLContextImpl extends GLContext {
           } finally {
               drawable.unlockSurface();
           }
+          if(null != drawableContextRealizedException) {
+              throw new GLException("GLContext.destroy() during GLDrawableImpl.contextRealized(this, false)", drawableContextRealizedException);
+          }
       }
       resetStates();
   }
@@ -436,7 +472,7 @@ public abstract class GLContextImpl extends GLContext {
                     // For Mac OS X, however, we need to update the context to track resizes
                     drawableUpdatedNotify();
                     if(TRACE_SWITCH) {
-                        System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+" - keep   - CONTEXT_CURRENT - "+lock);                        
+                        System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+", surf "+toHexString(drawable.getHandle())+" - keep   - CONTEXT_CURRENT - "+lock);                        
                     }
                     return CONTEXT_CURRENT;
                 } else {
@@ -476,7 +512,7 @@ public abstract class GLContextImpl extends GLContext {
 
     if (res == CONTEXT_NOT_CURRENT) {
       if(TRACE_SWITCH) {
-          System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+" - switch - CONTEXT_NOT_CURRENT - "+lock);
+          System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+", surf "+toHexString(drawable.getHandle())+" - switch - CONTEXT_NOT_CURRENT - "+lock);
       }
     } else {
       setCurrent(this);
@@ -497,19 +533,17 @@ public abstract class GLContextImpl extends GLContext {
             gl = gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Trace", null, gl, new Object[] { System.err } ) );
         }
         
-        drawable.contextRealized(this, true);
+        contextRealized(true);
         
         if(DEBUG || TRACE_SWITCH) {
-            System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+" - switch - CONTEXT_CURRENT_NEW - "+lock);
-        }
-      } else {
-        drawable.contextMadeCurrent(this, true);
-        
-        if(TRACE_SWITCH) {
-            System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+" - switch - CONTEXT_CURRENT - "+lock);
+            System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+", surf "+toHexString(drawable.getHandle())+" - switch - CONTEXT_CURRENT_NEW - "+lock);
         }
+      } else if(TRACE_SWITCH) {
+         System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+", surf "+toHexString(drawable.getHandle())+" - switch - CONTEXT_CURRENT - "+lock);
       }
 
+      contextMadeCurrent(true);
+      
       /* FIXME: refactor dependence on Java 2D / JOGL bridge
 
       // Try cleaning up any stale server-side OpenGL objects
@@ -536,6 +570,16 @@ public abstract class GLContextImpl extends GLContext {
         final boolean created;
         try {
             created = createImpl(shareWith); // may throws exception if fails!
+            if( created && isGL3core() && ( ctxMajorVersion>3 || ctxMajorVersion==3 && ctxMinorVersion>=2 ) ) {
+                // Due to GL 3.2 core spec: E.2. DEPRECATED AND REMOVED FEATURES (p 331)
+                // There is no more default VAO buffer 0 bound, hence generating and binding one
+                // to avoid INVALID_OPERATION at VertexAttribPointer. 
+                // More clear is GL 4.3 core spec: 10.4 (p 307).
+                final int[] tmp = new int[1];
+                gl.getGL2GL3().glGenVertexArrays(1, tmp, 0);
+                defaultVAO = tmp[0];
+                gl.getGL2GL3().glBindVertexArray(defaultVAO);
+            }
         } finally {
             if (null != shareWith) {
                 shareWith.getDrawableImpl().unlockSurface();
@@ -543,10 +587,10 @@ public abstract class GLContextImpl extends GLContext {
         }
         if (DEBUG || TRACE_SWITCH) {
             if(created) {
-                System.err.println(getThreadName() + ": Create GL context OK: obj " + toHexString(hashCode()) + ", ctx " + toHexString(contextHandle) + " for " + getClass().getName()+" - "+getGLVersion());
+                System.err.println(getThreadName() + ": Create GL context OK: obj " + toHexString(hashCode()) + ", ctx " + toHexString(contextHandle) + ", surf "+toHexString(drawable.getHandle())+" for " + getClass().getName()+" - "+getGLVersion());
                 // Thread.dumpStack();
             } else {
-                System.err.println(getThreadName() + ": Create GL context FAILED obj " + toHexString(hashCode()) + ", for " + getClass().getName());
+                System.err.println(getThreadName() + ": Create GL context FAILED obj " + toHexString(hashCode()) + ", surf "+toHexString(drawable.getHandle())+" for " + getClass().getName());
             }
         }
         if(!created) {
@@ -592,6 +636,20 @@ public abstract class GLContextImpl extends GLContext {
   protected abstract void makeCurrentImpl() throws GLException;
 
   /**
+   * @see GLDrawableImpl#contextRealized(GLContext, boolean) 
+   */ 
+  protected void contextRealized(boolean realized) {
+      drawable.contextRealized(this, realized);
+  }
+  
+  /**
+   * @see GLDrawableImpl#contextMadeCurrent(GLContext, boolean) 
+   */ 
+  protected void contextMadeCurrent(boolean current) {
+      drawable.contextMadeCurrent(this, current);      
+  }
+
+  /**
    * Platform dependent entry point for context creation.<br>
    *
    * This method is called from {@link #makeCurrentWithinLock()} .. {@link #makeCurrent()} .<br>
@@ -917,52 +975,58 @@ public abstract class GLContextImpl extends GLContext {
 
   /**
    * If major > 0 || minor > 0 : Use passed values, determined at creation time
-   * If major==0 && minor == 0 : Use GL_VERSION
    * Otherwise .. don't touch ..
    */
   private final void setContextVersion(int major, int minor, int ctp, boolean setVersionString) {
-      if (0==ctp) {
+      if ( 0 == ctp ) {
         throw new GLException("Invalid GL Version "+major+"."+minor+", ctp "+toHexString(ctp));
       }
-      if(major>0 || minor>0) {
-          if (!GLContext.isValidGLVersion(major, minor)) {
-            GLException e = new GLException("Invalid GL Version "+major+"."+minor+", ctp "+toHexString(ctp));
-            throw e;
-          }
-          ctxMajorVersion = major;
-          ctxMinorVersion = minor;
-          ctxOptions = ctp;
-          if(setVersionString) {
-              ctxVersionString = getGLVersion(ctxMajorVersion, ctxMinorVersion, ctxOptions, getGL().glGetString(GL.GL_VERSION));
-          }
-          return;
+      
+      if (!GLContext.isValidGLVersion(major, minor)) {
+        throw new GLException("Invalid GL Version "+major+"."+minor+", ctp "+toHexString(ctp));
       }
-
-      if(major==0 && minor==0) {
-          String versionStr = getGL().glGetString(GL.GL_VERSION);
-          if(null==versionStr) {
-            throw new GLException("GL_VERSION is NULL: "+this);
+      ctxMajorVersion = major;
+      ctxMinorVersion = minor;
+      ctxOptions = ctp;
+      if(setVersionString) {
+          ctxVersionString = getGLVersion(ctxMajorVersion, ctxMinorVersion, ctxOptions, gl.glGetString(GL.GL_VERSION));
+          ctxGLSLVersion = null;
+          if(ctxMajorVersion >= 2) { // >= ES2 || GL2.0
+              final String glslVersion = gl.glGetString(GL2ES2.GL_SHADING_LANGUAGE_VERSION);
+              if( null != glslVersion ) {
+                  ctxGLSLVersion = new VersionNumber(glslVersion, ".");
+                  if( ctxGLSLVersion.getMajor() < 1 ) {
+                      ctxGLSLVersion = null; // failed ..
+                  }
+              }
+          } 
+          if( null == ctxGLSLVersion ){
+              final int[] sver = new int[2];
+              getStaticGLSLVersionNumber(ctxMajorVersion, ctxMinorVersion, ctxOptions, sver);
+              ctxGLSLVersion = new VersionNumber(sver[0], sver[1], 0);
           }
-          ctxOptions = ctp;
-
-          // Set version
-          GLVersionNumber version = new GLVersionNumber(versionStr);
+      }
+  }
+  
+  private static final VersionNumber getGLVersionNumber(int ctp, String glVersionStr) {
+      if( null != glVersionStr ) {
+          final GLVersionNumber version = new GLVersionNumber(glVersionStr);
           if (version.isValid()) {
-            ctxMajorVersion = version.getMajor();
-            ctxMinorVersion = version.getMinor();
-            // We cannot promote a non ARB context to >= 3.1,
-            // reduce it to 3.0 then.
-            if ( ( ctxMajorVersion>3 || ctxMajorVersion==3 && ctxMinorVersion>=1 )
-                 && 0 == (ctxOptions & CTX_IS_ARB_CREATED) ) {
-                ctxMajorVersion = 3;
-                ctxMinorVersion = 0;
-            }
-            if(setVersionString) {
-                ctxVersionString = getGLVersion(ctxMajorVersion, ctxMinorVersion, ctxOptions, versionStr);
-            }
-            return;
+              int major = version.getMajor();
+              int minor = version.getMinor();
+              // We cannot promote a non ARB context to >= 3.1,
+              // reduce it to 3.0 then.
+              if ( 0 == (ctp & CTX_IS_ARB_CREATED) && 
+                   ( major > 3 || major == 3 && minor >= 1 ) ) {
+                  major = 3;
+                  minor = 0;
+              }
+              if ( GLContext.isValidGLVersion(major, minor) ) {
+                  return new VersionNumber(major, minor, 0);
+              }
           }
       }
+      return null;      
   }
 
   //----------------------------------------------------------------------
@@ -1002,14 +1066,18 @@ public abstract class GLContextImpl extends GLContext {
   /**
    * Pbuffer support; given that this is a GLContext associated with a
    * pbuffer, binds this pbuffer to its texture target.
+   * @throws GLException if not implemented (default)
+   * @deprecated use FBO/GLOffscreenAutoDrawable instead of pbuffer
    */
-  public abstract void bindPbufferToTexture();
+  public void bindPbufferToTexture() { throw new GLException("not implemented"); }
 
   /**
    * Pbuffer support; given that this is a GLContext associated with a
    * pbuffer, releases this pbuffer from its texture target.
+   * @throws GLException if not implemented (default)
+   * @deprecated use FBO/GLOffscreenAutoDrawable instead of pbuffer
    */
-  public abstract void releasePbufferFromTexture();
+  public void releasePbufferFromTexture() { throw new GLException("not implemented"); }
 
   public abstract ByteBuffer glAllocateMemoryNV(int arg0, float arg1, float arg2, float arg3);
 
@@ -1047,7 +1115,7 @@ public abstract class GLContextImpl extends GLContext {
     table.reset(getDrawableImpl().getGLDynamicLookupHelper() );
   }
 
-  private final boolean initGLRendererStrings()  {
+  private final boolean initGLRendererAndGLVersionStrings()  {
     final GLDynamicLookupHelper glDynLookupHelper = getDrawableImpl().getGLDynamicLookupHelper();
     final long _glGetString = glDynLookupHelper.dynamicLookupFunction("glGetString");
     if(0 == _glGetString) {
@@ -1066,18 +1134,24 @@ public abstract class GLContextImpl extends GLContext {
                 Thread.dumpStack();
             }
             return false;
-        } else {
-            glRenderer = _glRenderer;
-            glRendererLowerCase = glRenderer.toLowerCase();
-            return true;
         }
+        glRenderer = _glRenderer;
+        glRendererLowerCase = glRenderer.toLowerCase();
+        
+        final String _glVersion = glGetStringInt(GL.GL_VERSION, _glGetString);
+        if(null == _glVersion) {
+            // FIXME
+            if(DEBUG) {
+                System.err.println("Warning: GL_VERSION is NULL.");
+                Thread.dumpStack();
+            }
+            return false;
+        }
+        glVersion = _glVersion;
+        return true;
     }
   }
 
-  protected final String getGLRendererString(boolean lowerCase) {
-      return lowerCase ? glRendererLowerCase : glRenderer;
-  }
-
   /**
    * Sets the OpenGL implementation class and
    * the cache of which GL functions are available for calling through this
@@ -1111,17 +1185,44 @@ public abstract class GLContextImpl extends GLContext {
     final AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration();
     final AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
     
-    if( !initGLRendererStrings() && DEBUG) {
-        System.err.println("Warning: intialization of GL renderer strings failed. "+adevice+" - "+GLContext.getGLVersion(major, minor, ctxProfileBits, null));
+    {
+        final boolean initGLRendererAndGLVersionStringsOK = initGLRendererAndGLVersionStrings();
+        if(DEBUG) {
+            if( !initGLRendererAndGLVersionStringsOK ) {
+                System.err.println("Warning: setGLFunctionAvailability: intialization of GL renderer strings failed. "+adevice+" - "+GLContext.getGLVersion(major, minor, ctxProfileBits, null));
+            } else {
+                System.err.println(getThreadName() + ": GLContext.setGLFuncAvail: Given "+adevice+" - "+GLContext.getGLVersion(major, minor, ctxProfileBits, glVersion));
+            }
+        }
     }
 
     if(!isCurrentContextHardwareRasterizer()) {
         ctxProfileBits |= GLContext.CTX_IMPL_ACCEL_SOFT;
     }
-
+    
+    // Pick the version from the GL-version string, 
+    // if smaller _or_ given major == 0.
+    final VersionNumber glVersionNumber;
+    {
+        final VersionNumber setGLVersionNumber = new VersionNumber(major, minor, 0);
+        final VersionNumber strGLVersionNumber = getGLVersionNumber(ctxProfileBits, glVersion);
+        if( null != strGLVersionNumber && ( strGLVersionNumber.compareTo(setGLVersionNumber) <= 0 || 0 == major ) ) {
+            glVersionNumber = strGLVersionNumber;
+            major = glVersionNumber.getMajor();
+            minor = glVersionNumber.getMinor();
+        } else {
+            glVersionNumber = setGLVersionNumber;
+        }
+    }
+    if ( !GLContext.isValidGLVersion(major, minor) ) {
+        throw new GLException("Invalid GL Version "+major+"."+minor+", ctp "+toHexString(ctxProfileBits)+", "+glVersion+", "+glVersionNumber);
+    }
+    if( 2 > major ) { // there is no ES2-compat for a profile w/ major < 2
+        ctxProfileBits &= ~GLContext.CTX_IMPL_ES2_COMPAT;
+    }
     contextFQN = getContextFQN(adevice, major, minor, ctxProfileBits);
     if (DEBUG) {
-      System.err.println(getThreadName() + ": GLContext.setGLFuncAvail.0 FQN: "+contextFQN+" - "+GLContext.getGLVersion(major, minor, ctxProfileBits, null));
+        System.err.println(getThreadName() + ": GLContext.setGLFuncAvail.0 validated FQN: "+contextFQN+" - "+GLContext.getGLVersion(major, minor, ctxProfileBits, glVersion) + ", "+glVersionNumber);
     }
 
     //
@@ -1184,10 +1285,16 @@ public abstract class GLContextImpl extends GLContext {
         ctxProfileBits |= CTX_IMPL_FBO;
     }
     
+    if(FORCE_NO_FBO_SUPPORT) {
+        ctxProfileBits &= ~CTX_IMPL_FBO ;
+    }      
+    
     //
     // Set GL Version (complete w/ version string)
     //
     setContextVersion(major, minor, ctxProfileBits, true);
+    
+    setRendererQuirks( 0 == ( ctxProfileBits & GLContext.CTX_IMPL_ACCEL_SOFT ) );
 
     setDefaultSwapInterval();
     
@@ -1196,7 +1303,55 @@ public abstract class GLContextImpl extends GLContext {
     }
   }
   
-  protected static final boolean hasFBOImpl(int major, int ctp, ExtensionAvailabilityCache extCache) {
+  private final void setRendererQuirks(boolean hwAccel) {
+    int[] quirks = new int[GLRendererQuirks.COUNT];
+    int i = 0;
+    
+    // OS related quirks
+    if( Platform.getOSType() == Platform.OSType.MACOS ) {
+        final int quirk1 = GLRendererQuirks.NoOffscreenBitmap;
+        if(DEBUG) {
+            System.err.println("Quirk: "+GLRendererQuirks.toString(quirk1)+": cause: OS "+Platform.getOSType());
+        }
+        quirks[i++] = quirk1;
+    } else if( Platform.getOSType() == Platform.OSType.WINDOWS ) {
+        final int quirk = GLRendererQuirks.NoDoubleBufferedBitmap;
+        if(DEBUG) {
+            System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: OS "+Platform.getOSType());
+        }
+        quirks[i++] = quirk;
+    }
+    
+    // Renderer related quirks, may also involve OS
+    if( Platform.OSType.ANDROID == Platform.getOSType() && glRendererLowerCase.contains("powervr") ) {
+        final int quirk = GLRendererQuirks.NoSetSwapInterval;
+        if(DEBUG) {
+            System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: OS "+Platform.getOSType() + " / Renderer " + glRenderer);
+        }
+        quirks[i++] = quirk;
+    }
+    if( glRendererLowerCase.contains("mesa") || glRendererLowerCase.contains("gallium") ) {
+        {
+            final int quirk = GLRendererQuirks.NoSetSwapIntervalPostRetarget;
+            if(DEBUG) {
+                System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: Renderer " + glRenderer);
+            }
+            quirks[i++] = quirk;            
+        }
+        if( hwAccel /* glRendererLowerCase.contains("intel(r)") || glRendererLowerCase.contains("amd") */ )
+        {
+            final int quirk = GLRendererQuirks.NoDoubleBufferedPBuffer;
+            if(DEBUG) {
+                System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: Renderer " + glRenderer);
+            }
+            quirks[i++] = quirk;
+        }
+    }
+    glRendererQuirks = new GLRendererQuirks(quirks, 0, i);
+  }
+  
+  
+  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                       
@@ -1212,7 +1367,7 @@ public abstract class GLContextImpl extends GLContext {
                extCache.isExtensionAvailable(GLExtensions.OES_framebuffer_object) ) ;        // OES_framebuffer_object excluded               
   }
   
-  protected final void removeCachedVersion(int major, int minor, int ctxProfileBits) {
+  private final void removeCachedVersion(int major, int minor, int ctxProfileBits) {
     if(!isCurrentContextHardwareRasterizer()) {
         ctxProfileBits |= GLContext.CTX_IMPL_ACCEL_SOFT;
     }
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
index f780829..2bb22f7 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
@@ -48,7 +48,7 @@ import javax.media.nativewindow.NativeWindowFactory;
 import javax.media.nativewindow.OffscreenLayerSurface;
 import javax.media.nativewindow.ProxySurface;
 import javax.media.nativewindow.MutableSurface;
-import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook;
+import javax.media.nativewindow.UpstreamSurfaceHook;
 import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLCapabilitiesChooser;
 import javax.media.opengl.GLCapabilitiesImmutable;
@@ -56,10 +56,15 @@ import javax.media.opengl.GLContext;
 import javax.media.opengl.GLDrawable;
 import javax.media.opengl.GLDrawableFactory;
 import javax.media.opengl.GLException;
+import javax.media.opengl.GLFBODrawable;
+import javax.media.opengl.GLOffscreenAutoDrawable;
 import javax.media.opengl.GLPbuffer;
 import javax.media.opengl.GLProfile;
 
 import com.jogamp.nativewindow.MutableGraphicsConfiguration;
+import com.jogamp.nativewindow.DelegatedUpstreamSurfaceHookWithSurfaceSize;
+import com.jogamp.nativewindow.UpstreamSurfaceHookMutableSize;
+import com.jogamp.opengl.GLRendererQuirks;
 
 
 /** Extends GLDrawableFactory with a few methods for handling
@@ -67,13 +72,23 @@ import com.jogamp.nativewindow.MutableGraphicsConfiguration;
     Independent Bitmaps on Windows, pixmaps on X11). Direct access to
     these GLDrawables is not supplied directly to end users, though
     they may be instantiated by the GLJPanel implementation. */
+ at SuppressWarnings("deprecation")
 public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
-  protected static final boolean DEBUG = GLDrawableImpl.DEBUG;
+  protected static final boolean DEBUG = GLDrawableFactory.DEBUG; // allow package access
 
   protected GLDrawableFactoryImpl() {
     super();
   }
 
+  @Override
+  public GLRendererQuirks getRendererQuirks(AbstractGraphicsDevice device) {
+      final GLContext ctx = getOrCreateSharedContextImpl(device);
+      if(null != ctx) {
+          return ctx.getRendererQuirks();
+      }
+      return null;
+  }
+
   /**
    * Returns the shared context mapped to the <code>device</code> {@link AbstractGraphicsDevice#getConnection()},
    * either a pre-existing or newly created, or <code>null</code> if creation failed or not supported.<br>
@@ -98,24 +113,15 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
    * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared device to be used, may be <code>null</code> for the platform's default device.
    */
   protected final AbstractGraphicsDevice getOrCreateSharedDevice(AbstractGraphicsDevice device) {
-      if(null==device) {
-          device = getDefaultDevice();
-          if(null==device) {
-              throw new InternalError("no default device");
-          }
-          if (GLProfile.DEBUG) {
-              System.err.println("Info: GLDrawableFactoryImpl.getOrCreateSharedContext: using default device : "+device);
-          }
-      } else if( !getIsDeviceCompatible(device) ) {
-          if (GLProfile.DEBUG) {
-              System.err.println("Info: GLDrawableFactoryImpl.getOrCreateSharedContext: device not compatible : "+device);
-          }
-          return null;
+      device = validateDevice(device);
+      if( null != device) {
+          return getOrCreateSharedDeviceImpl(device);
       }
-      return getOrCreateSharedDeviceImpl(device);
+      return null;
   }
   protected abstract AbstractGraphicsDevice getOrCreateSharedDeviceImpl(AbstractGraphicsDevice device);
 
+  
   /**
    * Returns the GLDynamicLookupHelper
    * @param profile if EGL/ES, profile <code>1</code> refers to ES1 and <code>2</code> to ES2,
@@ -140,34 +146,34 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
     try {
         final OffscreenLayerSurface ols = NativeWindowFactory.getOffscreenLayerSurface(target, true);
         if(null != ols) {
+            final GLCapabilitiesImmutable chosenCapsMod = GLGraphicsConfigurationUtil.fixOffscreenGLCapabilities(chosenCaps, this, adevice);
             // layered surface -> Offscreen/[FBO|PBuffer]
-            final GLCapabilities chosenCapsMod = (GLCapabilities) chosenCaps.cloneMutable();
-            chosenCapsMod.setOnscreen(false);
-            /* if( isFBOAvailable ) { // FIXME JAU: FBO n/a yet
-                chosenCapsMod.setFBO(true);
-            } else */ 
-            if( canCreateGLPbuffer(adevice) ) {
-                chosenCapsMod.setPBuffer(true);
-            } else {
-                chosenCapsMod.setFBO(false);
-                chosenCapsMod.setPBuffer(false);
+            if( !chosenCapsMod.isFBO() && !chosenCapsMod.isPBuffer() ) {
+                throw new GLException("Neither FBO nor Pbuffer is available for "+chosenCapsMod+", "+target);
             }
             config.setChosenCapabilities(chosenCapsMod);
+            ols.setChosenCapabilities(chosenCapsMod);
             if(DEBUG) {
-                System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OnscreenDrawable -> Offscreen-Layer: "+target);
+                System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OnscreenDrawable -> Offscreen-Layer");
+                System.err.println("chosenCaps: "+chosenCaps);
+                System.err.println("chosenCapsMod: "+chosenCapsMod);
+                System.err.println("OffscreenLayerSurface: **** "+ols);
+                System.err.println("Target: **** "+target);
+                Thread.dumpStack();
             }
             if( ! ( target instanceof MutableSurface ) ) {
                 throw new IllegalArgumentException("Passed NativeSurface must implement SurfaceChangeable for offscreen layered surface: "+target);
             }            
-            if( ((GLCapabilitiesImmutable)config.getRequestedCapabilities()).isFBO() && isFBOAvailable ) {
-                // FIXME JAU: Need to revise passed MutableSurface to work w/ FBO ..
-                final GLDrawableImpl dummyDrawable = createOnscreenDrawableImpl(target);                
-                result = new GLFBODrawableImpl(this, dummyDrawable, target, target.getWidth(), target.getHeight(), 0 /* textureUnit */);
+            if( chosenCapsMod.isFBO() ) {
+                // target surface is already a native one
+                result = createFBODrawableImpl(target, chosenCapsMod, 0);
             } else {            
                 result = createOffscreenDrawableImpl(target);
             }
         } else if(chosenCaps.isOnscreen()) {
             // onscreen
+            final GLCapabilitiesImmutable chosenCapsMod = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(chosenCaps);
+            config.setChosenCapabilities(chosenCapsMod);
             if(DEBUG) {
                 System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OnscreenDrawable: "+target);
             }
@@ -175,15 +181,17 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
         } else {
             // offscreen
             if(DEBUG) {
-                System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OffScreenDrawable, FBO-chosen(-avail)/PBuffer: "+chosenCaps.isFBO()+"("+isFBOAvailable+")/"+chosenCaps.isPBuffer()+": "+target);
+                System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OffScreenDrawable, FBO chosen / avail, PBuffer: "+
+                                   chosenCaps.isFBO()+" / "+isFBOAvailable+", "+chosenCaps.isPBuffer()+": "+target);
             }
             if( ! ( target instanceof MutableSurface ) ) {
-                throw new IllegalArgumentException("Passed NativeSurface must implement SurfaceChangeable for offscreen: "+target);
+                throw new IllegalArgumentException("Passed NativeSurface must implement MutableSurface for offscreen: "+target);
             }
-            if( ((GLCapabilitiesImmutable)config.getRequestedCapabilities()).isFBO() && isFBOAvailable ) {
-                // FIXME JAU: Need to revise passed MutableSurface to work w/ FBO ..
-                final GLDrawableImpl dummyDrawable = createOnscreenDrawableImpl(target);                
-                result = new GLFBODrawableImpl(this, dummyDrawable, target, target.getWidth(), target.getHeight(), 0 /* textureUnit */);
+            if( chosenCaps.isFBO() && isFBOAvailable ) {
+                // need to hook-up a native dummy surface since source may not have & use minimum GLCapabilities for it w/ same profile 
+                final ProxySurface dummySurface = createDummySurfaceImpl(adevice, false, new GLCapabilities(chosenCaps.getGLProfile()), (GLCapabilitiesImmutable)config.getRequestedCapabilities(), null, 64, 64);
+                dummySurface.setUpstreamSurfaceHook(new DelegatedUpstreamSurfaceHookWithSurfaceSize(dummySurface.getUpstreamSurfaceHook(), target));
+                result = createFBODrawableImpl(dummySurface, chosenCaps, 0);
             } else {
                 result = createOffscreenDrawableImpl(target);
             }
@@ -206,7 +214,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
 
   //---------------------------------------------------------------------------
   //
-  // PBuffer Offscreen GLDrawable construction
+  // PBuffer Offscreen GLAutoDrawable construction
   //
   
   @Override
@@ -234,7 +242,8 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
     GLDrawableImpl drawable = null;
     device.lock();
     try {
-        drawable = (GLDrawableImpl) createGLDrawable( createMutableSurfaceImpl(device, true, capsChosen, capsRequested, chooser, width, height, null) );
+        drawable = createOffscreenDrawableImpl( createMutableSurfaceImpl(device, true, capsChosen, capsRequested, chooser, 
+                                                                     new UpstreamSurfaceHookMutableSize(width, height) ) );
         if(null != drawable) {
             drawable.setRealized(true);
         }
@@ -242,10 +251,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
         device.unlock();
     }
 
-    if(null==drawable) {
-        throw new GLException("Could not create Pbuffer drawable for: "+device+", "+capsChosen+", "+width+"x"+height);
-    }
-    return new GLPbufferImpl( drawable, shareWith, true);
+    return new GLPbufferImpl( drawable, (GLContextImpl) drawable.createContext(shareWith) );
   }
 
   //---------------------------------------------------------------------------
@@ -253,6 +259,29 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
   // Offscreen GLDrawable construction
   //
 
+  public final boolean canCreateFBO(AbstractGraphicsDevice deviceReq, GLProfile glp) {
+    AbstractGraphicsDevice device = getOrCreateSharedDevice(deviceReq);
+    if(null == device) {
+        throw new GLException("No shared device for requested: "+deviceReq);
+    }
+    return GLContext.isFBOAvailable(device, glp);      
+  }
+  
+  @Override
+  public GLOffscreenAutoDrawable createOffscreenAutoDrawable(AbstractGraphicsDevice deviceReq,
+                                                             GLCapabilitiesImmutable capsRequested,
+                                                             GLCapabilitiesChooser chooser,
+                                                             int width, int height,
+                                                             GLContext shareWith) {
+    final GLDrawable drawable = createOffscreenDrawable( deviceReq, capsRequested, chooser, width, height ); 
+    drawable.setRealized(true);
+    final GLContext context = drawable.createContext(shareWith);
+    if(drawable instanceof GLFBODrawableImpl) {
+        return new GLOffscreenAutoDrawableImpl.FBOImpl( (GLFBODrawableImpl)drawable, context, null, null );
+    }
+    return new GLOffscreenAutoDrawableImpl( drawable, context, null, null);
+  }
+  
   @Override
   public GLDrawable createOffscreenDrawable(AbstractGraphicsDevice deviceReq,
                                             GLCapabilitiesImmutable capsRequested,
@@ -266,32 +295,33 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
         throw new GLException("No shared device for requested: "+deviceReq);
     }
     
-    if( capsRequested.isFBO() && GLContext.isFBOAvailable(device, capsRequested.getGLProfile()) ) {
+    final GLCapabilitiesImmutable capsChosen = GLGraphicsConfigurationUtil.fixOffscreenGLCapabilities(capsRequested, this, device);
+
+    if( capsChosen.isFBO() ) {
         device.lock();
         try {
-            return createFBODrawableImpl(device, capsRequested, chooser, width, height);
+            // Use minimum GLCapabilities for the dummy surface w/ same profile 
+            final ProxySurface dummySurface = createDummySurfaceImpl(device, true, new GLCapabilities(capsChosen.getGLProfile()), capsRequested, null, width, height);
+            final GLDrawableImpl dummyDrawable = createOnscreenDrawableImpl(dummySurface);
+            return new GLFBODrawableImpl.ResizeableImpl(this, dummyDrawable, dummySurface, capsChosen, 0);
         } finally {
             device.unlock();
         }
     }
     
-    final GLCapabilitiesImmutable capsChosen = GLGraphicsConfigurationUtil.fixOffscreenGLCapabilities(capsRequested, false, canCreateGLPbuffer(device));
     device.lock();
     try {
-        return createOffscreenDrawableImpl( createMutableSurfaceImpl(device, true, capsChosen, capsRequested, chooser, width, height, null) );
+        return createOffscreenDrawableImpl( createMutableSurfaceImpl(device, true, capsChosen, capsRequested, chooser, 
+                                                                     new UpstreamSurfaceHookMutableSize(width, height) ) );
     } finally {
         device.unlock();
     }
   }
 
-  /** Creates a platform independent offscreen FBO GLDrawable implementation */  
-  protected GLDrawable createFBODrawableImpl(AbstractGraphicsDevice device, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, 
-                                            int initialWidth, int initialHeight) {    
-    final GLCapabilitiesImmutable dummyCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(requestedCaps);
-    final NativeSurface dummySurface = createDummySurfaceImpl(device, true, dummyCaps, null, 64, 64);
+  /** Creates a platform independent FBO offscreen GLDrawable */ 
+  protected GLFBODrawable createFBODrawableImpl(NativeSurface dummySurface, GLCapabilitiesImmutable fboCaps, int textureUnit) {
     final GLDrawableImpl dummyDrawable = createOnscreenDrawableImpl(dummySurface);
-    
-    return new GLFBODrawableImpl(this, dummyDrawable, dummySurface, initialWidth, initialHeight, 0 /* textureUnit */);
+    return new GLFBODrawableImpl(this, dummyDrawable, dummySurface, fboCaps, textureUnit);
   }
   
   /** Creates a platform dependent offscreen pbuffer/pixmap GLDrawable implementation */  
@@ -311,15 +341,13 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
    * @param capsChosen
    * @param capsRequested
    * @param chooser the custom chooser, may be null for default
-   * @param width the initial width
-   * @param height the initial height
-   * @param lifecycleHook optional control of the surface's lifecycle 
+   * @param upstreamHook surface size information and optional control of the surface's lifecycle 
    * @return the created {@link MutableSurface} instance w/o defined surface handle
    */
   protected abstract ProxySurface createMutableSurfaceImpl(AbstractGraphicsDevice device, boolean createNewDevice, 
                                                            GLCapabilitiesImmutable capsChosen,
                                                            GLCapabilitiesImmutable capsRequested,
-                                                           GLCapabilitiesChooser chooser, int width, int height, UpstreamSurfaceHook lifecycleHook);
+                                                           GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstreamHook);
 
   /**
    * A dummy surface is not visible on screen and will not be used to render directly to,
@@ -334,9 +362,9 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
    * @param width the initial width
    * @param height the initial height
    *
-   * @return the created {@link MutableSurface} instance w/o defined surface handle
+   * @return the created {@link ProxySurface} instance w/o defined surface handle but platform specific {@link UpstreamSurfaceHook}.
    */
-  public NativeSurface createDummySurface(AbstractGraphicsDevice deviceReq, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser,
+  public ProxySurface createDummySurface(AbstractGraphicsDevice deviceReq, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser,
                                           int width, int height) {
     final AbstractGraphicsDevice device = getOrCreateSharedDevice(deviceReq);
     if(null == device) {
@@ -344,7 +372,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
     }
     device.lock();
     try {
-        return createDummySurfaceImpl(device, true, requestedCaps, chooser, width, height);
+        return createDummySurfaceImpl(device, true, requestedCaps, requestedCaps, chooser, width, height);
     } finally {
         device.unlock();
     }
@@ -360,14 +388,17 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
    * @param device a valid platform dependent target device.
    * @param createNewDevice if <code>true</code> a new device instance is created using <code>device</code> details,
    *                        otherwise <code>device</code> instance is used as-is.
+   * @param chosenCaps
    * @param requestedCaps
    * @param chooser the custom chooser, may be null for default
-   * @param width the initial width
-   * @param height the initial height
-   * @return the created {@link MutableSurface} instance w/o defined surface handle
+   * @param width the initial width as returned by {@link NativeSurface#getWidth()}, not the actual dummy surface width. 
+   *        The latter is platform specific and small
+   * @param height the initial height as returned by {@link NativeSurface#getHeight()}, not the actual dummy surface height,
+   *        The latter is platform specific and small
+   * @return the created {@link ProxySurface} instance w/o defined surface handle but platform specific {@link UpstreamSurfaceHook}.
    */
   public abstract ProxySurface createDummySurfaceImpl(AbstractGraphicsDevice device, boolean createNewDevice, 
-                                                      GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height);
+                                                      GLCapabilitiesImmutable chosenCaps, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height);
 
   //---------------------------------------------------------------------------
   //
@@ -412,24 +443,14 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
 
   @Override
   public GLContext createExternalGLContext() {
-    NativeWindowFactory.getDefaultToolkitLock().lock();
-    try {
-        return createExternalGLContextImpl();
-    } finally {
-        NativeWindowFactory.getDefaultToolkitLock().unlock();
-    }
+    return createExternalGLContextImpl();
   }
 
   protected abstract GLDrawable createExternalGLDrawableImpl();
 
   @Override
   public GLDrawable createExternalGLDrawable() {
-    NativeWindowFactory.getDefaultToolkitLock().lock();
-    try {
-        return createExternalGLDrawableImpl();
-    } finally {
-        NativeWindowFactory.getDefaultToolkitLock().unlock();
-    }
+    return createExternalGLDrawableImpl();
   }
 
 
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java
index 090c5fe..d4ff970 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java
@@ -43,12 +43,18 @@ package jogamp.opengl;
 import java.util.ArrayList;
 import java.util.HashSet;
 
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
 import javax.media.opengl.GLAnimatorControl;
 import javax.media.opengl.GLAutoDrawable;
 import javax.media.opengl.GLContext;
 import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLDrawableFactory;
 import javax.media.opengl.GLEventListener;
 import javax.media.opengl.GLException;
+import javax.media.opengl.GLFBODrawable;
 import javax.media.opengl.GLRunnable;
 
 import com.jogamp.opengl.util.Animator;
@@ -108,24 +114,27 @@ public class GLDrawableHelper {
   /**
    * Associate a new context to the drawable and also propagates the context/drawable switch by 
    * calling {@link GLContext#setGLDrawable(GLDrawable, boolean) newCtx.setGLDrawable(drawable, true);}.
-   * <p>
-   * If the old context's drawable was an {@link GLAutoDrawable}, it's reference to the given drawable
-   * is being cleared by calling 
-   * {@link GLAutoDrawable#setContext(GLContext) ((GLAutoDrawable)oldCtx.getGLDrawable()).setContext(null)}.
-   * </p>
    * <p> 
    * If the old or new context was current on this thread, it is being released before switching the drawable.
    * </p>
+   * <p>
+   * Be aware that the old context is still bound to the drawable, 
+   * and that one context can only bound to one drawable at one time! 
+   * </p>
+   * <p>
+   * No locking is being performed on the drawable, caller is required to take care of it.
+   * </p>
    * 
    * @param drawable the drawable which context is changed
-   * @param newCtx the new context
    * @param oldCtx the old context
-   * @return true if the newt context was current, otherwise false
+   * @param newCtx the new context
+   * @param newCtxCreationFlags additional creation flags if newCtx is not null and not been created yet, see {@link GLContext#setContextCreationFlags(int)}
+   * @return true if the new context was current, otherwise false
    *  
    * @see GLAutoDrawable#setContext(GLContext)
    */
-  public final boolean switchContext(GLDrawable drawable, GLContext oldCtx, GLContext newCtx, int additionalCtxCreationFlags) {
-      if(null != oldCtx && oldCtx.isCurrent()) {
+  public static final boolean switchContext(GLDrawable drawable, GLContext oldCtx, GLContext newCtx, int newCtxCreationFlags) {
+      if( null != oldCtx && oldCtx.isCurrent() ) {
           oldCtx.release();
       }
       final boolean newCtxCurrent;
@@ -134,17 +143,140 @@ public class GLDrawableHelper {
           if(newCtxCurrent) {
               newCtx.release();
           }
-          newCtx.setContextCreationFlags(additionalCtxCreationFlags);
+          newCtx.setContextCreationFlags(newCtxCreationFlags);
           newCtx.setGLDrawable(drawable, true); // propagate context/drawable switch
       } else {
           newCtxCurrent = false;
       }
-      if(null!=oldCtx && oldCtx.getGLDrawable() instanceof GLAutoDrawable) {
-          ((GLAutoDrawable)oldCtx.getGLDrawable()).setContext(null);
-      }
       return newCtxCurrent;
   }
   
+  /**
+   * If the drawable is not realized, OP is a NOP.
+   * <ul> 
+   *  <li>release context if current</li>
+   *  <li>destroy old drawable</li>
+   *  <li>create new drawable</li>
+   *  <li>attach new drawable to context</li>
+   *  <li>make context current, if it was current</li>
+   * </ul>
+   * <p>
+   * No locking is being performed, caller is required to take care of it.
+   * </p>
+   * 
+   * @param drawable
+   * @param context maybe null
+   * @return the new drawable
+   */
+  public static final GLDrawableImpl recreateGLDrawable(GLDrawableImpl drawable, GLContext context) {      
+      if( ! drawable.isRealized() ) {
+          return drawable;
+      }
+      final boolean contextCurrent = null != context && context.isCurrent();
+      final GLDrawableFactory factory = drawable.getFactory();
+      final NativeSurface surface = drawable.getNativeSurface();
+      final ProxySurface proxySurface = (surface instanceof ProxySurface) ? (ProxySurface)surface : null;
+      
+      if(contextCurrent) {
+          context.release();
+      }
+      
+      if(null != proxySurface) {
+          proxySurface.enableUpstreamSurfaceHookLifecycle(false);
+      }
+      try {
+          drawable.setRealized(false);
+          drawable = (GLDrawableImpl) factory.createGLDrawable(surface); // [2]
+          drawable.setRealized(true);
+      } finally {
+          if(null != proxySurface) {
+              proxySurface.enableUpstreamSurfaceHookLifecycle(true);
+          }
+      }
+
+      if(null != context) {
+          context.setGLDrawable(drawable, true); // re-association
+      }
+      
+      if(contextCurrent) {
+          context.makeCurrent();
+      }
+      return drawable;
+  }
+   
+  /**
+   * Performs resize operation on the given drawable, assuming it is offscreen.
+   * <p>
+   * The {@link GLDrawableImpl}'s {@link NativeSurface} is being locked during operation.
+   * In case the holder is an auto drawable or similar, it's lock shall be claimed by the caller. 
+   * </p>
+   * <p>
+   * May recreate the drawable via {@link #recreateGLDrawable(GLDrawableImpl, GLContext)}
+   * in case of a a pbuffer- or pixmap-drawable.
+   * </p>
+   * <p>
+   * FBO drawables are resized w/o drawable destruction.
+   * </p>
+   * <p>
+   * Offscreen resize operation is validated w/ drawable size in the end. 
+   * An exception is thrown if not successful.
+   * </p>
+   * 
+   * @param drawable
+   * @param context
+   * @param newWidth the new width, it's minimum is capped to 1
+   * @param newHeight the new height, it's minimum is capped to 1
+   * @return the new drawable in case of an pbuffer/pixmap drawable, otherwise the passed drawable is being returned.
+   * @throws NativeWindowException is drawable is not offscreen or it's surface lock couldn't be claimed
+   * @throws GLException may be thrown a resize operation
+   */
+  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) {
+          throw new NativeWindowException("Could not lock surface of drawable: "+drawable);
+      }
+      boolean validateSize = true;
+      try {
+          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; }
+          // propagate new size 
+          if(ns instanceof ProxySurface) {
+              final ProxySurface ps = (ProxySurface) ns;
+              final UpstreamSurfaceHook ush = ps.getUpstreamSurfaceHook();
+              if(ush instanceof UpstreamSurfaceHook.MutableSize) {
+                  ((UpstreamSurfaceHook.MutableSize)ush).setSize(newWidth, newHeight);
+              } else if(DEBUG) { // we have to assume UpstreamSurfaceHook contains the new size already, hence size check @ bottom
+                  System.err.println("GLDrawableHelper.resizeOffscreenDrawable: Drawable's offscreen ProxySurface n.a. UpstreamSurfaceHook.MutableSize, but "+ush.getClass().getName()+": "+ush);
+              }
+          } 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( null != context && context.isCreated() ) {                      
+                  ((GLFBODrawable) drawable).resetSize(context.getGL());
+              }
+          } else {
+              drawable = GLDrawableHelper.recreateGLDrawable(drawable, context);
+          }
+      } finally {
+          ns.unlockSurface();
+      }
+      if( validateSize && ( drawable.getWidth() != newWidth || drawable.getHeight() != newHeight ) ) {
+          throw new InternalError("Incomplete resize operation: expected "+newWidth+"x"+newHeight+", has: "+drawable);
+      }
+      return drawable;
+  }
+    
   public final void addGLEventListener(GLEventListener listener) {
     addGLEventListener(-1, listener);
   }
@@ -196,32 +328,28 @@ public class GLDrawableHelper {
     }
   }
 
-  private final boolean init(GLEventListener l, GLAutoDrawable drawable, boolean sendReshape) {
-      if(listenersToBeInit.remove(l)) {
-          l.init(drawable);
-          if(sendReshape) {
-              reshape(l, drawable, 0, 0, drawable.getWidth(), drawable.getHeight(), true /* setViewport */, false /* checkInit */);
-          }
-          return true;
+  private final void init(GLEventListener l, GLAutoDrawable drawable, boolean sendReshape) {
+      l.init(drawable);
+      if(sendReshape) {
+          reshape(l, drawable, 0, 0, drawable.getWidth(), drawable.getHeight(), true /* setViewport */, false /* checkInit */);
       }
-      return false;
   }
 
-  /** The default init action to be called once after ctx is being created @ 1st makeCurrent(). */
-  public final void init(GLAutoDrawable drawable) {
+  /** 
+   * The default init action to be called once after ctx is being created @ 1st makeCurrent(). 
+   * @param sendReshape set to true if the subsequent display call won't reshape, otherwise false to avoid double reshape.
+   **/
+  public final void init(GLAutoDrawable drawable, boolean sendReshape) {
     synchronized(listenersLock) {
         final ArrayList<GLEventListener> _listeners = listeners;
         for (int i=0; i < _listeners.size(); i++) {
           final GLEventListener listener = _listeners.get(i) ;
 
-          // If make current ctx, invoked by invokGL(..), results in a new ctx, init gets called.
+          // If make ctx current, invoked by invokGL(..), results in a new ctx, init gets called.
           // This may happen not just for initial setup, but for ctx recreation due to resource change (drawable/window),
-          // hence the must always be initialized unconditional.
-          listenersToBeInit.add(listener);
-
-          if ( ! init( listener, drawable, true /* sendReshape */) ) {
-            throw new GLException("GLEventListener "+listener+" already initialized: "+drawable);
-          }
+          // hence it must be called unconditional, always.
+          listenersToBeInit.remove(listener); // remove if exist, avoiding dbl init
+          init( listener, drawable, sendReshape);
         }
     }
   }
@@ -239,7 +367,9 @@ public class GLDrawableHelper {
             final GLEventListener listener = _listeners.get(i) ;
             // GLEventListener may need to be init, 
             // in case this one is added after the realization of the GLAutoDrawable
-            init( listener, drawable, true /* sendReshape */) ; 
+            if( listenersToBeInit.remove(listener) ) {
+                init( listener, drawable, true /* sendReshape */) ;
+            }
             listener.display(drawable);
           }
       }
@@ -251,7 +381,9 @@ public class GLDrawableHelper {
         // GLEventListener may need to be init, 
         // in case this one is added after the realization of the GLAutoDrawable
         synchronized(listenersLock) {
-            init( listener, drawable, false /* sendReshape */) ;
+            if( listenersToBeInit.remove(listener) ) {
+                init( listener, drawable, false /* sendReshape */) ;
+            }
         }
     }
     if(setViewport) {
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
index abf2bf5..df7f742 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
@@ -43,6 +43,7 @@ package jogamp.opengl;
 import javax.media.nativewindow.AbstractGraphicsDevice;
 import javax.media.nativewindow.NativeSurface;
 import javax.media.nativewindow.ProxySurface;
+import javax.media.opengl.GL;
 import javax.media.opengl.GLCapabilitiesImmutable;
 import javax.media.opengl.GLContext;
 import javax.media.opengl.GLDrawable;
@@ -51,15 +52,17 @@ import javax.media.opengl.GLException;
 import javax.media.opengl.GLProfile;
 
 public abstract class GLDrawableImpl implements GLDrawable {
-  protected static final boolean DEBUG = Debug.debug("GLDrawable");
-
-  protected GLDrawableImpl(GLDrawableFactory factory,
-                           NativeSurface comp,
-                           boolean realized) {
+  protected static final boolean DEBUG = GLDrawableFactoryImpl.DEBUG;
+  
+  protected GLDrawableImpl(GLDrawableFactory factory, NativeSurface comp, boolean realized) {
+      this(factory, comp, (GLCapabilitiesImmutable) comp.getGraphicsConfiguration().getRequestedCapabilities(), realized);
+  }
+  
+  protected GLDrawableImpl(GLDrawableFactory factory, NativeSurface comp, GLCapabilitiesImmutable requestedCapabilities, boolean realized) {
       this.factory = factory;
       this.surface = comp;
       this.realized = realized;
-      this.requestedCapabilities = (GLCapabilitiesImmutable) surface.getGraphicsConfiguration().getRequestedCapabilities();
+      this.requestedCapabilities = requestedCapabilities;
   }
 
   /**
@@ -76,31 +79,46 @@ public abstract class GLDrawableImpl implements GLDrawable {
     if( !realized ) {
         return; // destroyed already
     }
-    final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable)surface.getGraphicsConfiguration().getChosenCapabilities();
-    if ( caps.getDoubleBuffered() ) {
-        if(!surface.surfaceSwap()) {
-            int lockRes = lockSurface(); // it's recursive, so it's ok within [makeCurrent .. release]
-            if (NativeSurface.LOCK_SURFACE_NOT_READY == lockRes) {
-                return;
+    int lockRes = lockSurface(); // it's recursive, so it's ok within [makeCurrent .. release]
+    if (NativeSurface.LOCK_SURFACE_NOT_READY == lockRes) {
+        return;
+    }
+    try {
+        if (NativeSurface.LOCK_SURFACE_CHANGED == lockRes) {
+            updateHandle();
+        }
+        final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable)surface.getGraphicsConfiguration().getChosenCapabilities();
+        if ( caps.getDoubleBuffered() ) {
+            if(!surface.surfaceSwap()) {
+                swapBuffersImpl(true);
             }
-            try {
-                if (NativeSurface.LOCK_SURFACE_CHANGED == lockRes) {
-                    updateHandle();
-                }
-                swapBuffersImpl();
-            } finally {
-                unlockSurface();
+        } else {
+            final GLContext ctx = GLContext.getCurrent();
+            if(null!=ctx && ctx.getGLDrawable()==this) {
+                ctx.getGL().glFlush();
             }
+            swapBuffersImpl(false);
         }
-    } else {
-        GLContext ctx = GLContext.getCurrent();
-        if(null!=ctx && ctx.getGLDrawable()==this) {
-            ctx.getGL().glFinish();
-        }
-    }
+    } finally {
+        unlockSurface();
+    }        
     surface.surfaceUpdated(this, surface, System.currentTimeMillis());
   }
-  protected abstract void swapBuffersImpl();
+  
+  /**
+   * Platform and implementation depending surface swap.
+   * <p>The surface is locked.</p>
+   * <p>
+   * If <code>doubleBuffered</code> is <code>true</code>, 
+   * an actual platform dependent surface swap shall be executed.
+   * </p>
+   * <p>
+   * If <code>doubleBuffered</code> is <code>false</code>, 
+   * {@link GL#glFlush()} has been called already and 
+   * the implementation may execute implementation specific code.
+   * </p>
+   */
+  protected abstract void swapBuffersImpl(boolean doubleBuffered);
 
   public final static String toHexString(long hex) {
     return "0x" + Long.toHexString(hex);
@@ -181,6 +199,9 @@ public abstract class GLDrawableImpl implements GLDrawable {
         System.err.println(getThreadName() + ": setRealized: "+getClass().getName()+" "+this.realized+" == "+realizedArg);
     }
   }
+  /**
+   * Platform specific realization of drawable 
+   */
   protected abstract void setRealizedImpl();
 
   /** 
@@ -189,7 +210,7 @@ public abstract class GLDrawableImpl implements GLDrawable {
    * If <code>realized</code> is <code>true</code>, the context has just been created and made current.
    * </p>
    * <p>
-   * If <code>realized</code> is <code>false</code>, the context is still current and will be release and destroyed after this method returns.
+   * If <code>realized</code> is <code>false</code>, the context is still current and will be released and destroyed after this method returns.
    * </p>
    * <p>
    * @see #contextMadeCurrent(GLContext, boolean)
@@ -199,18 +220,27 @@ public abstract class GLDrawableImpl implements GLDrawable {
   /** 
    * Callback for special implementations, allowing GLContext to trigger GL related lifecycle: <code>makeCurrent</code>, <code>release</code>.
    * <p>
-   * Will not be called if {@link #contextRealized(GLContext, boolean)} has been triggered.
-   * </p>
-   * <p>
    * If <code>current</code> is <code>true</code>, the context has just been made current.
    * </p>
    * <p>
    * If <code>current</code> is <code>false</code>, the context is still current and will be release after this method returns.
    * </p>
+   * <p>
+   * Note: Will also be called after {@link #contextRealized(GLContext, boolean) contextRealized(ctx, true)}
+   * but not at context destruction, i.e. {@link #contextRealized(GLContext, boolean) contextRealized(ctx, false)}.
+   * </p>
    * @see #contextRealized(GLContext, boolean)
    */ 
   protected void contextMadeCurrent(GLContext glc, boolean current) { }
 
+  /**
+   * Callback for special implementations, allowing to associate bound context to this drawable (bound == true) 
+   * or to remove such association (bound == false).
+   * @param ctx the just bounded or unbounded context
+   * @param bound if <code>true</code> create an association, otherwise remove it
+   */
+  protected void associateContext(GLContext ctx, boolean bound) { }
+  
   /** Callback for special implementations, allowing GLContext to fetch a custom default render framebuffer. Defaults to zero.*/
   protected int getDefaultDrawFramebuffer() { return 0; }
   /** Callback for special implementations, allowing GLContext to fetch a custom default read framebuffer. Defaults to zero. */
@@ -245,8 +275,8 @@ public abstract class GLDrawableImpl implements GLDrawable {
   public String toString() {
     return getClass().getSimpleName()+"[Realized "+isRealized()+
                 ",\n\tFactory   "+getFactory()+
-                ",\n\thandle    "+toHexString(getHandle())+
-                ",\n\tWindow    "+getNativeSurface()+"]";
+                ",\n\tHandle    "+toHexString(getHandle())+
+                ",\n\tSurface   "+getNativeSurface()+"]";
   }
 
   protected static String getThreadName() {
diff --git a/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java
index b7ea4f8..b5b723f 100644
--- a/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java
@@ -1,138 +1,551 @@
 package jogamp.opengl;
 
 import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
 import javax.media.opengl.GL;
-import javax.media.opengl.GL2GL3;
+import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLCapabilitiesImmutable;
 import javax.media.opengl.GLContext;
 import javax.media.opengl.GLException;
+import javax.media.opengl.GLFBODrawable;
 
+import com.jogamp.common.os.Platform;
+import com.jogamp.common.util.VersionUtil;
 import com.jogamp.nativewindow.MutableGraphicsConfiguration;
 import com.jogamp.opengl.FBObject;
 import com.jogamp.opengl.FBObject.Attachment;
+import com.jogamp.opengl.FBObject.Colorbuffer;
 import com.jogamp.opengl.FBObject.TextureAttachment;
+import com.jogamp.opengl.JoglVersion;
 
 /**
- * Offscreen GLDrawable implementation using framebuffer object (FBO)
- * as it's offscreen rendering mechanism.
+ * {@link FBObject} offscreen GLDrawable implementation, i.e. {@link GLFBODrawable}.
+ * <p>
+ * It utilizes the context lifecycle hook {@link #contextRealized(GLContext, boolean)}
+ * to initialize the {@link FBObject} instance.
+ * </p>
+ * <p>
+ * It utilizes the context current hook {@link #contextMadeCurrent(GLContext, boolean) contextMadeCurrent(context, true)} 
+ * to {@link FBObject#bind(GL) bind} the FBO.
+ * </p>
+ * See {@link GLFBODrawable} for double buffering details.
  * 
  * @see GLDrawableImpl#contextRealized(GLContext, boolean)
  * @see GLDrawableImpl#contextMadeCurrent(GLContext, boolean)
  * @see GLDrawableImpl#getDefaultDrawFramebuffer()
  * @see GLDrawableImpl#getDefaultReadFramebuffer()
  */
-public class GLFBODrawableImpl extends GLDrawableImpl {
-    final GLDrawableImpl parent;
-    final FBObject fbo;
-    int texUnit;
-    int samplesTexUnit = 0;
-    int width=0, height=0, samples=0;
-    
-    protected GLFBODrawableImpl(GLDrawableFactoryImpl factory, GLDrawableImpl parent, 
-                                NativeSurface surface, int initialWidth, int initialHeight, int textureUnit) {
-        super(factory, surface, false);
+public class GLFBODrawableImpl extends GLDrawableImpl implements GLFBODrawable {
+    protected static final boolean DEBUG = GLDrawableImpl.DEBUG || Debug.debug("FBObject");
+    
+    private final GLDrawableImpl parent;
+    private GLCapabilitiesImmutable origParentChosenCaps;
+    
+    private boolean initialized;
+    private int texUnit;
+    private int samples;
+    private boolean fboResetQuirk;
+    
+    private FBObject[] fbos;
+    private int fboIBack;  // points to GL_BACK buffer
+    private int fboIFront; // points to GL_FRONT buffer
+    private int pendingFBOReset = -1;
+    private boolean fboBound;
+
+    private static volatile boolean resetQuirkInfoDumped = false;
+    private static final int bufferCount = 2; // number of FBOs for double buffering. TODO: Possible to configure!
+    
+    // private DoubleBufferMode doubleBufferMode; // TODO: Add or remove TEXTURE (only) DoubleBufferMode support
+    
+    private SwapBufferContext swapBufferContext;
+    
+    public static interface SwapBufferContext {
+        public void swapBuffers(boolean doubleBuffered);
+    }
+    
+    /**
+     * @param factory
+     * @param parent
+     * @param surface
+     * @param fboCaps the requested FBO capabilities
+     * @param textureUnit
+     */
+    protected GLFBODrawableImpl(GLDrawableFactoryImpl factory, GLDrawableImpl parent, NativeSurface surface, 
+                                GLCapabilitiesImmutable fboCaps, int textureUnit) {
+        super(factory, surface, fboCaps, false);
+        this.initialized = false;
+
         this.parent = parent;
+        this.origParentChosenCaps = (GLCapabilitiesImmutable) getChosenGLCapabilities(); // just to avoid null, will be reset at initialize(..)
         this.texUnit = textureUnit;
-        final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) surface.getGraphicsConfiguration().getChosenCapabilities();
-        this.width = initialWidth;
-        this.height = initialHeight;
-        this.samples = caps.getNumSamples();
-        this.fbo = new FBObject();
+        this.samples = fboCaps.getNumSamples();
+        fboResetQuirk = false;
+        
+        // default .. // TODO: Add or remove TEXTURE (only) DoubleBufferMode support
+        // this.doubleBufferMode = ( samples > 0 || fboCaps.getDoubleBuffered() ) ? DoubleBufferMode.FBO : DoubleBufferMode.NONE ;
+        
+        this.swapBufferContext = null;
     }
     
-    @Override
-    protected void contextRealized(GLContext glc, boolean realized) {
-        final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) surface.getGraphicsConfiguration().getChosenCapabilities();
-        final GL gl = glc.getGL();
-        if(realized) {                   
-            fbo.reset(gl, width, height, samples);
-            samples = fbo.getNumSamples(); // update, maybe capped
+    private final void initialize(boolean realize, GL gl) {
+        if(realize) {
+            final GLCapabilities chosenFBOCaps = (GLCapabilities) getChosenGLCapabilities(); // cloned at setRealized(true)
+            
+            final int maxSamples = gl.getMaxRenderbufferSamples();
+            {
+                final int newSamples = samples <= maxSamples ? samples : maxSamples;
+                if(DEBUG) {
+                    System.err.println("GLFBODrawableImpl.initialize(): samples "+samples+" -> "+newSamples+"/"+maxSamples);
+                }
+                samples = newSamples;
+            }
+            
+            final int fbosN;
             if(samples > 0) {
-                fbo.attachColorbuffer(gl, 0, caps.getAlphaBits()>0);
+                fbosN = 1;
+            } else if( chosenFBOCaps.getDoubleBuffered() ) {
+                fbosN = bufferCount;
             } else {
-                fbo.attachTexture2D(gl, 0, caps.getAlphaBits()>0);
+                fbosN = 1;
             }
-            if( caps.getStencilBits() > 0 ) {
-                fbo.attachRenderbuffer(gl, Attachment.Type.DEPTH_STENCIL, 24);
-            } else {
-                fbo.attachRenderbuffer(gl, Attachment.Type.DEPTH, 24);
+
+            fbos = new FBObject[fbosN];
+            fboIBack = 0;                // head
+            fboIFront = fbos.length - 1; // tail
+            
+            for(int i=0; i<fbosN; i++) {
+                fbos[i] = new FBObject();
+                fbos[i].reset(gl, getWidth(), getHeight(), samples, false);
+                if(fbos[i].getNumSamples() != samples) {
+                    throw new InternalError("Sample number mismatch: "+samples+", fbos["+i+"] "+fbos[i]);
+                }
+                if(samples > 0) {
+                    fbos[i].attachColorbuffer(gl, 0, chosenFBOCaps.getAlphaBits()>0);
+                } else {
+                    fbos[i].attachTexture2D(gl, 0, chosenFBOCaps.getAlphaBits()>0);
+                }
+                if( chosenFBOCaps.getStencilBits() > 0 ) {
+                    fbos[i].attachRenderbuffer(gl, Attachment.Type.DEPTH_STENCIL, 24);
+                } else {
+                    fbos[i].attachRenderbuffer(gl, Attachment.Type.DEPTH, 24);
+                }
             }
-        } else if(null != fbo) {
-            fbo.destroy(gl);
-        }
-    }
-    
-    @Override
-    protected void contextMadeCurrent(GLContext glc, boolean current) {
-        final GL gl = glc.getGL();
-        if(current) {
-            fbo.bind(gl);
+            fbos[fboIFront].resetSamplingSink(gl);
+            fboBound = false;
+            fbos[0].formatToGLCapabilities(chosenFBOCaps);
+            chosenFBOCaps.setDoubleBuffered( chosenFBOCaps.getDoubleBuffered() || samples > 0 );
+            
+            initialized = true;            
         } else {
-            fbo.unbind(gl);
-            gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit);
-            fbo.use(gl, samples > 0 ? fbo.getSamplingSink() : (TextureAttachment) fbo.getColorbuffer(0) );
-            if( samples > 0) {
-                gl.glBindFramebuffer(GL2GL3.GL_READ_FRAMEBUFFER, fbo.getReadFramebuffer());
+            initialized = false;
+            
+            for(int i=0; i<fbos.length; i++) {
+                fbos[i].destroy(gl);
             }
+            fbos=null;
+            fboBound = false;   
+            pendingFBOReset = -1;
+        }
+        if(DEBUG) {
+            System.err.println("GLFBODrawableImpl.initialize("+realize+"): "+this);
+            Thread.dumpStack();
         }
     }
     
-    @Override
-    protected int getDefaultDrawFramebuffer() { return fbo.getWriteFramebuffer(); }
-    
-    @Override
-    protected int getDefaultReadFramebuffer() { return fbo.getReadFramebuffer(); }
-    
-    public FBObject getFBObject() { return fbo; }
-    
-    public void setSize(GL gl, int newWidth, int newHeight) throws GLException {
-        width = newWidth;
-        height = newHeight;        
-        fbo.reset(gl, width, height, samples);
-        samples = fbo.getNumSamples(); // update, maybe capped
+    public final void setSwapBufferContext(SwapBufferContext sbc) {
+        swapBufferContext = sbc;
     }
-    
-    public void setSamples(GL gl, int newSamples) throws GLException {
-        samples = newSamples;
-        fbo.reset(gl, width, height, samples);
-        samples = fbo.getNumSamples(); // update, maybe capped
+
+    private final void reset(GL gl, int idx, int width, int height, int samples, int alphaBits, int stencilBits) {
+        if( !fboResetQuirk ) {
+            try {
+                fbos[idx].reset(gl, width, height, samples, false);
+                if(fbos[idx].getNumSamples() != samples) {
+                    throw new InternalError("Sample number mismatch: "+samples+", fbos["+idx+"] "+fbos[idx]);
+                }
+                return;
+            } catch (GLException e) {
+                if(DEBUG) {
+                    e.printStackTrace();
+                }
+                if(!resetQuirkInfoDumped) { // dump info only once
+                    resetQuirkInfoDumped = true;
+                    System.err.println("GLFBODrawable: FBO Reset failed: "+e.getMessage());
+                    System.err.println("GLFBODrawable: Enabling FBOResetQuirk, due to GL driver bug.");
+                    final JoglVersion joglVersion = JoglVersion.getInstance();
+                    if(DEBUG) {
+                        System.err.println(VersionUtil.getPlatformInfo());
+                        System.err.println(joglVersion.toString());
+                        System.err.println(JoglVersion.getGLInfo(gl, null));
+                    } else {
+                        System.err.println(joglVersion.getBriefOSGLBuildInfo(gl, null));                        
+                    }
+                }
+                fboResetQuirk = true;
+                // 'fallthrough' intended
+            }
+        }
+        // resetQuirk fallback
+        fbos[idx].destroy(gl);
+        fbos[idx] = new FBObject();
+        fbos[idx].reset(gl, getWidth(), getHeight(), samples, false);
+        if(fbos[idx].getNumSamples() != samples) {
+            throw new InternalError("Sample number mismatch: "+samples+", fbos["+idx+"] "+fbos[idx]);
+        }
+        if(samples > 0) {
+            fbos[idx].attachColorbuffer(gl, 0, alphaBits>0);
+        } else {
+            fbos[idx].attachTexture2D(gl, 0, alphaBits>0);
+        }
+        if( stencilBits > 0 ) {
+            fbos[idx].attachRenderbuffer(gl, Attachment.Type.DEPTH_STENCIL, 24);
+        } else {
+            fbos[idx].attachRenderbuffer(gl, Attachment.Type.DEPTH, 24);
+        }
+    }
+        
+    private final void reset(GL gl, int newSamples) throws GLException {
+        if(!initialized) {
+            // NOP if not yet initializes
+            return;
+        }
+                
+        final GLContext curContext = GLContext.getCurrent();
+        final GLContext ourContext = gl.getContext();
+        final boolean ctxSwitch = null != curContext && curContext != ourContext; 
+        if(DEBUG) {
+            System.err.println("GLFBODrawableImpl.reset(newSamples "+newSamples+"): BEGIN - ctxSwitch "+ctxSwitch+", "+this);
+            Thread.dumpStack();
+        }
+        Throwable tFBO = null;
+        Throwable tGL = null;
+        ourContext.makeCurrent();
+        fboBound = false; // clear bound-flag immediatly, caused by contextMadeCurrent(..) - otherwise we would swap @ release
+        try {
+            final int maxSamples = gl.getMaxRenderbufferSamples();        
+            newSamples = newSamples <= maxSamples ? newSamples : maxSamples;
+            
+            if(0==samples && 0<newSamples || 0<samples && 0==newSamples) {
+                // MSAA on/off switch
+                if(DEBUG) {
+                    System.err.println("GLFBODrawableImpl.reset(): samples [on/off] reconfig: "+samples+" -> "+newSamples+"/"+maxSamples);
+                }
+                initialize(false, gl);
+                samples = newSamples;
+                initialize(true, gl);
+            } else {            
+                if(DEBUG) {
+                    System.err.println("GLFBODrawableImpl.reset(): simple reconfig: "+samples+" -> "+newSamples+"/"+maxSamples);
+                }
+                final int nWidth = getWidth();
+                final int nHeight = getHeight();
+                samples = newSamples;
+                pendingFBOReset = ( 1 < fbos.length ) ? fboIFront : -1; // pending-front reset only w/ double buffering (or zero samples)
+                final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) surface.getGraphicsConfiguration().getChosenCapabilities();
+                for(int i=0; i<fbos.length; i++) {
+                    if( pendingFBOReset != i ) {
+                        reset(gl, i, nWidth, nHeight, samples, caps.getAlphaBits(), caps.getStencilBits());
+                    }
+                }
+                final GLCapabilities fboCapsNative = (GLCapabilities) surface.getGraphicsConfiguration().getChosenCapabilities();
+                fbos[0].formatToGLCapabilities(fboCapsNative);
+            }
+        } catch (Throwable t) {
+            tFBO = t;
+        } finally {
+            try {
+                ourContext.release();
+                if(ctxSwitch) {
+                    curContext.makeCurrent();
+                }
+            } catch (Throwable t) {
+                tGL = t;
+            }
+        }
+        if(null != tFBO) {
+            throw new GLException("GLFBODrawableImpl.reset(..) FBObject.reset(..) exception", tFBO);
+        }
+        if(null != tGL) {
+            throw new GLException("GLFBODrawableImpl.reset(..) GLContext.release() exception", tGL);
+        }
+        if(DEBUG) {
+            System.err.println("GLFBODrawableImpl.reset(newSamples "+newSamples+"): END "+this);
+        }
     }
     
+    //
+    // GLDrawable
+    //
     
     @Override
-    public GLContext createContext(GLContext shareWith) {
+    public final GLContext createContext(GLContext shareWith) {
         final GLContext ctx = parent.createContext(shareWith);
         ctx.setGLDrawable(this, false);
         return ctx;
     }
 
+    //
+    // GLDrawableImpl
+    //
+    
     @Override
-    public GLDynamicLookupHelper getGLDynamicLookupHelper() {
+    public final GLDynamicLookupHelper getGLDynamicLookupHelper() {
         return parent.getGLDynamicLookupHelper();
     }
 
     @Override
-    protected void swapBuffersImpl() {
-    }
+    protected final int getDefaultDrawFramebuffer() { return initialized ? fbos[fboIBack].getWriteFramebuffer() : 0; }
+    
+    @Override
+    protected final int getDefaultReadFramebuffer() { return initialized ? fbos[fboIFront].getReadFramebuffer() : 0; }
 
     @Override
-    protected void setRealizedImpl() {
-        parent.setRealized(realized);
-        if(realized) {    
-            final MutableGraphicsConfiguration msConfig = (MutableGraphicsConfiguration) surface.getGraphicsConfiguration();
-            final GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable) msConfig.getChosenCapabilities();
-            final GLCapabilitiesImmutable chosenFBOCaps = GLGraphicsConfigurationUtil.fixOffscreenGLCapabilities(chosenCaps, true /*FBO*/, false /*PBO*/);    
+    protected final void setRealizedImpl() {
+        final MutableGraphicsConfiguration msConfig = (MutableGraphicsConfiguration) surface.getGraphicsConfiguration();
+        if(realized) {
+            parent.setRealized(true);
+            origParentChosenCaps = (GLCapabilitiesImmutable) msConfig.getChosenCapabilities();
+            final GLCapabilities chosenFBOCaps = (GLCapabilities) origParentChosenCaps.cloneMutable();
+            chosenFBOCaps.copyFrom(getRequestedGLCapabilities());
             msConfig.setChosenCapabilities(chosenFBOCaps);
+        } else {
+            msConfig.setChosenCapabilities(origParentChosenCaps);
+            parent.setRealized(false);
         }
     }
-
+    
     @Override
-    public int getWidth() {
-        return width;
+    protected final void contextRealized(GLContext glc, boolean realized) {
+        initialize(realized, glc.getGL());
+    }
+    
+    @Override
+    protected final void contextMadeCurrent(GLContext glc, boolean current) {
+        final GL gl = glc.getGL();
+        if(current) {
+            fbos[fboIBack].bind(gl);
+            fboBound = true;
+        } else {
+            if(fboBound) {
+                swapFBOImpl(glc);
+                swapFBOImplPost(glc);
+                fboBound=false;
+                if(DEBUG) {
+                    System.err.println("Post FBO swap(@release): done");
+                }
+            }
+        }
+    }
+        
+    @Override
+    protected void swapBuffersImpl(boolean doubleBuffered) {
+        final GLContext ctx = GLContext.getCurrent();
+        boolean doPostSwap = false;
+        if(null!=ctx && ctx.getGLDrawable()==this) {
+            if(fboBound) {
+                swapFBOImpl(ctx);
+                doPostSwap = true;
+                fboBound=false;
+                if(DEBUG) {
+                    System.err.println("Post FBO swap(@swap): done");
+                }
+            }
+        }
+        if(null != swapBufferContext) {
+            swapBufferContext.swapBuffers(doubleBuffered);
+        }
+        if(doPostSwap) {
+            swapFBOImplPost(ctx);
+        }
+    }
+    
+    private final void swapFBOImplPost(GLContext glc) {
+        // Safely reset the previous front FBO - after completing propagating swap
+        if(0 <= pendingFBOReset) {
+            final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) surface.getGraphicsConfiguration().getChosenCapabilities();
+            reset(glc.getGL(), pendingFBOReset, getWidth(), getHeight(), samples, caps.getAlphaBits(), caps.getStencilBits());
+            pendingFBOReset = -1;
+        }
+    }
+    
+    private final void swapFBOImpl(GLContext glc) {
+        final GL gl = glc.getGL();
+        fbos[fboIBack].markUnbound(); // fast path, use(gl,..) is called below
+        
+        if(DEBUG) {
+            int _fboIFront = ( fboIFront + 1 ) % fbos.length;
+            if(_fboIFront != fboIBack) { throw new InternalError("XXX: "+_fboIFront+"!="+fboIBack); }
+        }
+        fboIFront = fboIBack;
+        fboIBack  = ( fboIBack  + 1 ) % fbos.length;
+        
+        final Colorbuffer colorbuffer = samples > 0 ? fbos[fboIFront].getSamplingSink() : fbos[fboIFront].getColorbuffer(0);
+        final TextureAttachment texAttachment;
+        if(colorbuffer instanceof TextureAttachment) {
+            texAttachment = (TextureAttachment) colorbuffer;
+        } else {
+            if(null == colorbuffer) {
+                throw new GLException("Front colorbuffer is null: samples "+samples+", "+this);
+            } else {
+                throw new GLException("Front colorbuffer is not a texture: "+colorbuffer.getClass().getName()+": samples "+samples+", "+colorbuffer+", "+this);
+            }
+        }
+        gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit);
+        fbos[fboIFront].use(gl, texAttachment);
+        
+        /* Included in above use command:  
+                gl.glBindFramebuffer(GL2GL3.GL_DRAW_FRAMEBUFFER, fbos[fboIBack].getDrawFramebuffer());
+                gl.glBindFramebuffer(GL2GL3.GL_READ_FRAMEBUFFER, fbos[fboIFront].getReadFramebuffer());
+        } */
+        
+        if(DEBUG) {
+            System.err.println("Post FBO swap(X): fboI back "+fboIBack+", front "+fboIFront+", num "+fbos.length);
+        }
     }
 
+    //
+    // GLFBODrawable
+    // 
+    
     @Override
-    public int getHeight() {
-        return height;
+    public final boolean isInitialized() {
+        return initialized;
+    }
+    
+    @Override
+    public final void resetSize(GL gl) throws GLException {
+        reset(gl, samples);
     }    
+    
+    @Override
+    public final int getTextureUnit() { return texUnit; }
+    
+    @Override
+    public final void setTextureUnit(int u) { texUnit = u; }
+    
+    @Override
+    public final int getNumSamples() { return samples; }
+    
+    @Override
+    public void setNumSamples(GL gl, int newSamples) throws GLException {
+        if(samples != newSamples) {
+            reset(gl, newSamples);
+        }
+    }
+    
+    /** // TODO: Add or remove TEXTURE (only) DoubleBufferMode support
+    @Override
+    public final DoubleBufferMode getDoubleBufferMode() {
+        return doubleBufferMode;
+    }
+    
+    @Override
+    public final void setDoubleBufferMode(DoubleBufferMode mode) throws GLException {
+        if(initialized) {
+            throw new GLException("Not allowed past initialization: "+this);
+        }        
+        final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) surface.getGraphicsConfiguration().getChosenCapabilities();
+        if(0 == samples && caps.getDoubleBuffered() && DoubleBufferMode.NONE != mode) {
+            doubleBufferMode = mode;
+        }
+    } */
+    
+    @Override
+    public FBObject getFBObject(int bufferName) throws IllegalArgumentException {
+        if(!initialized) {
+            return null;
+        }
+        final FBObject res;
+        switch(bufferName) {
+            case GL.GL_FRONT:
+                if( samples > 0 ) {
+                    res = fbos[0].getSamplingSinkFBO();
+                } else {
+                    res = fbos[fboIFront];
+                }
+                break;
+            case GL.GL_BACK:
+                res = fbos[fboIBack];
+                break;
+            default: 
+                throw new IllegalArgumentException(illegalBufferName+toHexString(bufferName));
+        }        
+        return res;  
+    }
+    
+    @Override
+    public final TextureAttachment getTextureBuffer(int bufferName) throws IllegalArgumentException {
+        if(!initialized) {
+            return null;
+        }
+        final TextureAttachment res;
+        switch(bufferName) {
+            case GL.GL_FRONT:
+                if( samples > 0 ) {
+                    res = fbos[0].getSamplingSink();
+                } else {
+                    res = (TextureAttachment) fbos[fboIFront].getColorbuffer(0);
+                }
+                break;
+            case GL.GL_BACK:
+                if( samples > 0 ) {
+                    throw new IllegalArgumentException("Cannot access GL_BACK buffer of MSAA FBO: "+this);
+                } else {
+                    res = (TextureAttachment) fbos[fboIBack].getColorbuffer(0);
+                }
+                break;
+            default: 
+                throw new IllegalArgumentException(illegalBufferName+toHexString(bufferName));
+        }        
+        return res;  
+    }
+    private static final String illegalBufferName = "Only GL_FRONT and GL_BACK buffer are allowed, passed ";
+    
+    @Override
+    public String toString() {
+        return getClass().getSimpleName()+"[Initialized "+initialized+", realized "+isRealized()+", texUnit "+texUnit+", samples "+samples+
+                ",\n\tFactory   "+getFactory()+
+                ",\n\tHandle    "+toHexString(getHandle())+
+                ",\n\tCaps      "+surface.getGraphicsConfiguration().getChosenCapabilities()+
+                ",\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()+
+                "]";
+    }
+    
+    public static class ResizeableImpl extends GLFBODrawableImpl implements GLFBODrawable.Resizeable {
+        protected ResizeableImpl(GLDrawableFactoryImpl factory, GLDrawableImpl parent, ProxySurface surface, 
+                                 GLCapabilitiesImmutable fboCaps, int textureUnit) {
+            super(factory, parent, surface, fboCaps, textureUnit);
+        }
+        
+        @Override
+        public final void setSize(GLContext context, int newWidth, int newHeight) throws NativeWindowException, GLException {
+            if(DEBUG) {
+                System.err.println("GLFBODrawableImpl.ResizeableImpl setSize: ("+Thread.currentThread().getName()+"): "+newWidth+"x"+newHeight+" - surfaceHandle 0x"+Long.toHexString(getNativeSurface().getSurfaceHandle()));
+            }
+            int lockRes = lockSurface();
+            if (NativeSurface.LOCK_SURFACE_NOT_READY >= lockRes) {
+                throw new NativeWindowException("Could not lock surface: "+this);
+            }
+            try {
+                // propagate new size 
+                final ProxySurface ps = (ProxySurface) getNativeSurface();
+                final UpstreamSurfaceHook ush = ps.getUpstreamSurfaceHook();
+                if(ush instanceof UpstreamSurfaceHook.MutableSize) {
+                    ((UpstreamSurfaceHook.MutableSize)ush).setSize(newWidth, newHeight);
+                } else {
+                    throw new InternalError("GLFBODrawableImpl.ResizableImpl's ProxySurface doesn't hold a UpstreamSurfaceHookMutableSize but "+ush.getClass().getName()+", "+ps+", ush");
+                }
+                if( null != context && context.isCreated() ) {
+                    resetSize(context.getGL());
+                }
+            } finally {
+                unlockSurface();
+            }
+        }
+    }
 }
diff --git a/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java b/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java
index 3f38f33..31e52b8 100644
--- a/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java
+++ b/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java
@@ -28,17 +28,20 @@
 
 package jogamp.opengl;
 
-import java.util.List;
-
+import javax.media.nativewindow.AbstractGraphicsDevice;
 import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawableFactory;
+
+import com.jogamp.opengl.GLRendererQuirks;
 
 public class GLGraphicsConfigurationUtil {
     public static final String NV_coverage_sample = "NV_coverage_sample";
     public static final int WINDOW_BIT  = 1 << 0;
     public static final int BITMAP_BIT  = 1 << 1;
     public static final int PBUFFER_BIT = 1 << 2;
-    public static final int FBO_BIT     = 1 << 3;
+    public static final int FBO_BIT     = 1 << 3; // generic bit must be mapped to native one at impl. level
     public static final int ALL_BITS    = WINDOW_BIT | BITMAP_BIT | PBUFFER_BIT | FBO_BIT ;
 
     public static final StringBuilder winAttributeBits2String(StringBuilder sb, int winattrbits) {
@@ -74,90 +77,173 @@ public class GLGraphicsConfigurationUtil {
     }
 
     /**
-     * @param isFBO TODO
-     * @return bitmask representing the input boolean in exclusive or logic, ie only one bit will be set
+    public static final int getWinAttributeBits(boolean isOnscreen, boolean isFBO, boolean isPBuffer, boolean isBitmap) {
+        int winattrbits = 0;
+        if(isOnscreen) {
+            winattrbits |= WINDOW_BIT;
+        }
+        if(isFBO) {
+            winattrbits |= FBO_BIT;
+        } 
+        if(isPBuffer ){
+            winattrbits |= PBUFFER_BIT;
+        } 
+        if(isBitmap) {
+            winattrbits |= BITMAP_BIT;                
+        }
+        return winattrbits;
+    }
+    public static final int getWinAttributeBits(GLCapabilitiesImmutable caps) {
+        return getWinAttributeBits(caps.isOnscreen(), caps.isFBO(), caps.isPBuffer(), caps.isBitmap());
+    } */
+
+    /**
+     * @return bitmask representing the input boolean in exclusive or logic, ie only one bit will be set.
      */
-    public static final int getWinAttributeBits(boolean isOnscreen, boolean isPBuffer, boolean isFBO) {
+    public static final int getExclusiveWinAttributeBits(boolean isOnscreen, boolean isFBO, boolean isPBuffer, boolean isBitmap) {
         int winattrbits = 0;
         if(isOnscreen) {
             winattrbits |= WINDOW_BIT;
-        } else {
-            if(isFBO) {
-                winattrbits |= FBO_BIT;
-            }
-            if (!isPBuffer) {
-                winattrbits |= BITMAP_BIT;
-            } else {
-                winattrbits |= PBUFFER_BIT;
-            }
+        } else if(isFBO) {
+            winattrbits |= FBO_BIT;
+        } else if(isPBuffer ){
+            winattrbits |= PBUFFER_BIT;
+        } else if(isBitmap) {
+            winattrbits |= BITMAP_BIT;                
+        }
+        if(0 == winattrbits) {
+            throw new InternalError("Empty bitmask");
         }
         return winattrbits;
     }
 
     /**
-     * @see #getWinAttributeBits(boolean, boolean, boolean)
+     * @see #getExclusiveWinAttributeBits(boolean, boolean, boolean, boolean)
      */
-    public static final int getWinAttributeBits(GLCapabilitiesImmutable caps) {
-        return getWinAttributeBits(caps.isOnscreen(), caps.isPBuffer(), false);
+    public static final int getExclusiveWinAttributeBits(GLCapabilitiesImmutable caps) {
+        return getExclusiveWinAttributeBits(caps.isOnscreen(), caps.isFBO(), caps.isPBuffer(), caps.isBitmap());
     }
 
-    public static final boolean addGLCapabilitiesPermutations(List<GLCapabilitiesImmutable> capsBucket, GLCapabilitiesImmutable temp, int winattrbits) {
-        int preSize = capsBucket.size();
-        if( 0 != ( WINDOW_BIT & winattrbits )  )  {
-            GLCapabilities cpy  = (GLCapabilities) temp.cloneMutable();
-            cpy.setOnscreen(true);
-            cpy.setPBuffer(false);
-            cpy.setFBO(false);
-            capsBucket.add(cpy);
-        }
-        if( 0 != ( PBUFFER_BIT & winattrbits ) || 0 != ( FBO_BIT & winattrbits )  )  {
-            GLCapabilities cpy  = (GLCapabilities) temp.cloneMutable();
-            cpy.setFBO(0 != ( FBO_BIT & winattrbits ));
-            cpy.setPBuffer(0 != ( PBUFFER_BIT & winattrbits ));
-            capsBucket.add(cpy);
-        }
-        if( 0 != ( BITMAP_BIT & winattrbits )  )  {
-            GLCapabilities cpy  = (GLCapabilities) temp.cloneMutable();
-            cpy.setOnscreen(false);
-            cpy.setPBuffer(false);
-            cpy.setFBO(false);
-            capsBucket.add(cpy);
+    public static final GLCapabilities fixWinAttribBitsAndHwAccel(AbstractGraphicsDevice device, int winattrbits, GLCapabilities caps) {
+        caps.setBitmap  ( 0 != ( BITMAP_BIT  & winattrbits ) );
+        caps.setPBuffer ( 0 != ( PBUFFER_BIT & winattrbits ) );
+        caps.setFBO     ( 0 != ( FBO_BIT     & winattrbits ) );
+        // we reflect availability semantics, hence setting onscreen at last (maybe overwritten above)!
+        caps.setOnscreen( 0 != ( WINDOW_BIT  & winattrbits ) );
+
+        final int accel = GLContext.isHardwareRasterizer( device, caps.getGLProfile() );
+        if(0 == accel && caps.getHardwareAccelerated() ) {
+            caps.setHardwareAccelerated(false);
         }
-        return capsBucket.size() > preSize;
-    }
 
-    public static GLCapabilitiesImmutable fixGLCapabilities(GLCapabilitiesImmutable capsRequested, boolean fboAvailable, boolean pbufferAvailable)
-    {
+        return caps;        
+    }
+    
+    /**
+     * Fixes the requested  {@link GLCapabilitiesImmutable} according to on- and offscreen usage.
+     * <p>
+     * No modification will be made for onscreen usage, for offscreen usage see
+     * {@link #fixOffscreenGLCapabilities(GLCapabilitiesImmutable, GLDrawableFactory, AbstractGraphicsDevice)}.
+     * </p>
+     * @param capsRequested the requested {@link GLCapabilitiesImmutable}
+     * @param factory the {@link GLDrawableFactory} used to validate the requested capabilities and later used to create the drawable.
+     * @param device the device on which the drawable will be created, maybe null for the {@link GLDrawableFactory#getDefaultDevice() default device}.
+     * @return either the given requested {@link GLCapabilitiesImmutable} instance if no modifications were required, or a modified {@link GLCapabilitiesImmutable} instance.
+     */
+    public static GLCapabilitiesImmutable fixGLCapabilities(GLCapabilitiesImmutable capsRequested, 
+                                                            GLDrawableFactory factory, AbstractGraphicsDevice device) {
         if( !capsRequested.isOnscreen() ) {
-            return fixOffscreenGLCapabilities(capsRequested, fboAvailable, pbufferAvailable);
+            return fixOffscreenGLCapabilities(capsRequested, factory, device);
         }
-        return fixOnscreenGLCapabilities(capsRequested);
+        return capsRequested;
     }
-
+    
     public static GLCapabilitiesImmutable fixOnscreenGLCapabilities(GLCapabilitiesImmutable capsRequested)
     {
-        if( !capsRequested.isOnscreen() ) {
+        if( !capsRequested.isOnscreen() || capsRequested.isFBO() || capsRequested.isPBuffer() || capsRequested.isBitmap() ) { 
             // fix caps ..
-            GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
+            final GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
+            caps2.setBitmap  (false);
+            caps2.setPBuffer (false);
+            caps2.setFBO     (false);
             caps2.setOnscreen(true);
             return caps2;
         }
         return capsRequested;
     }
-    
-    public static GLCapabilitiesImmutable fixOffscreenGLCapabilities(GLCapabilitiesImmutable capsRequested, boolean fboAvailable, boolean pbufferAvailable)
+
+    public static GLCapabilitiesImmutable fixOffscreenBitOnly(GLCapabilitiesImmutable capsRequested)
     {
-        if( capsRequested.getDoubleBuffered() ||
-            capsRequested.isOnscreen() ||
-            ( fboAvailable != capsRequested.isFBO() ) || 
-            ( pbufferAvailable != capsRequested.isPBuffer() ) )
+        if( capsRequested.isOnscreen() ) { 
+            // fix caps ..
+            final GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
+            caps2.setOnscreen(false);
+            return caps2;
+        }
+        return capsRequested;
+    }
+    
+    /**
+     * Fixes the requested  {@link GLCapabilitiesImmutable} according to:
+     * <ul>
+     *   <li>offscreen usage</li>
+     *   <li>availability of FBO, PBuffer, Bitmap</li>
+     *   <li>{@link GLRendererQuirks}</li>
+     * </ul>
+     * @param capsRequested the requested {@link GLCapabilitiesImmutable}
+     * @param factory the {@link GLDrawableFactory} used to validate the requested capabilities and later used to create the drawable.
+     * @param device the device on which the drawable will be created, maybe null for the {@link GLDrawableFactory#getDefaultDevice() default device}.
+     * @return either the given requested {@link GLCapabilitiesImmutable} instance if no modifications were required, or a modified {@link GLCapabilitiesImmutable} instance.
+     */
+    public static GLCapabilitiesImmutable fixOffscreenGLCapabilities(GLCapabilitiesImmutable capsRequested,
+                                                                     GLDrawableFactory factory, AbstractGraphicsDevice device) {
+        if(null == device) {
+            device = factory.getDefaultDevice();
+        }
+        final boolean fboAvailable = GLContext.isFBOAvailable(device, capsRequested.getGLProfile());
+        final boolean pbufferAvailable = factory.canCreateGLPbuffer(device);
+        
+        final GLRendererQuirks glrq = factory.getRendererQuirks(device);
+        final boolean bitmapAvailable;
+        final boolean doubleBufferAvailable;
+        
+        if(null != glrq) {
+            bitmapAvailable = !glrq.exist(GLRendererQuirks.NoOffscreenBitmap);
+            if( capsRequested.getDoubleBuffered() &&
+                ( capsRequested.isPBuffer() && glrq.exist(GLRendererQuirks.NoDoubleBufferedPBuffer) ) || 
+                ( capsRequested.isBitmap() && glrq.exist(GLRendererQuirks.NoDoubleBufferedBitmap) ) ) {
+                doubleBufferAvailable = false;
+            } else {
+                doubleBufferAvailable = true;
+            }
+        } else {
+            bitmapAvailable = true;
+            doubleBufferAvailable = true;
+        }
+        
+        final boolean auto = !( fboAvailable     && capsRequested.isFBO()     ) && 
+                             !( pbufferAvailable && capsRequested.isPBuffer() ) && 
+                             !( bitmapAvailable  && capsRequested.isBitmap()  ) ;
+
+        final boolean useFBO     =                           fboAvailable     && ( auto || capsRequested.isFBO()     ) ;
+        final boolean usePbuffer = !useFBO                && pbufferAvailable && ( auto || capsRequested.isPBuffer() ) ;
+        final boolean useBitmap  = !useFBO && !usePbuffer && bitmapAvailable  && ( auto || capsRequested.isBitmap()  ) ;
+        
+        if( capsRequested.isOnscreen() ||
+            useFBO != capsRequested.isFBO() || 
+            usePbuffer != capsRequested.isPBuffer() || 
+            useBitmap != capsRequested.isBitmap() ||
+            !doubleBufferAvailable && capsRequested.getDoubleBuffered() )
         {
             // fix caps ..
-            GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
-            caps2.setDoubleBuffered(false); // FIXME DBLBUFOFFSCRN
+            final GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
             caps2.setOnscreen(false);
-            caps2.setFBO( fboAvailable ); 
-            caps2.setPBuffer( pbufferAvailable );
+            caps2.setFBO( useFBO ); 
+            caps2.setPBuffer( usePbuffer );
+            caps2.setBitmap( useBitmap );
+            if( !doubleBufferAvailable ) {
+                caps2.setDoubleBuffered(false);
+            }
             return caps2;
         }
         return capsRequested;
@@ -165,31 +251,40 @@ public class GLGraphicsConfigurationUtil {
 
     public static GLCapabilitiesImmutable fixGLPBufferGLCapabilities(GLCapabilitiesImmutable capsRequested)
     {
-        if( capsRequested.getDoubleBuffered() || capsRequested.isOnscreen() || !capsRequested.isPBuffer() || capsRequested.isFBO() ) {
+        if( capsRequested.isOnscreen() ||
+            !capsRequested.isPBuffer() || 
+            capsRequested.isFBO() ) 
+        {
             // fix caps ..
-            GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
-            caps2.setDoubleBuffered(false); // FIXME DBLBUFOFFSCRN - we don't need to be single buffered ..
+            final GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
             caps2.setOnscreen(false);
-            caps2.setPBuffer(true);
             caps2.setFBO(false);
+            caps2.setPBuffer(true);
+            caps2.setBitmap(false);
             return caps2;
         }
         return capsRequested;
     }
 
     /** Fix opaque setting while preserve alpha bits */
-    public static GLCapabilitiesImmutable fixOpaqueGLCapabilities(GLCapabilitiesImmutable capsRequested, boolean isOpaque)
+    public static GLCapabilities fixOpaqueGLCapabilities(GLCapabilities capsRequested, boolean isOpaque)
     {
-        GLCapabilities caps2 = null;
-        
         if( capsRequested.isBackgroundOpaque() != isOpaque) {
             final int alphaBits = capsRequested.getAlphaBits();
-            caps2 = (GLCapabilities) capsRequested.cloneMutable();
-            caps2.setBackgroundOpaque(isOpaque);
-            caps2.setAlphaBits(alphaBits);
-            return caps2;
+            capsRequested.setBackgroundOpaque(isOpaque);
+            capsRequested.setAlphaBits(alphaBits);
         }
         return capsRequested;
     }
     
+    /** Fix double buffered setting */
+    public static GLCapabilitiesImmutable fixDoubleBufferedGLCapabilities(GLCapabilitiesImmutable capsRequested, boolean doubleBuffered)
+    {
+        if( capsRequested.getDoubleBuffered() != doubleBuffered) {
+            final GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
+            caps2.setDoubleBuffered(doubleBuffered);
+            return caps2;
+        }
+        return capsRequested;
+    }
 }
diff --git a/src/jogl/classes/jogamp/opengl/GLOffscreenAutoDrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLOffscreenAutoDrawableImpl.java
new file mode 100644
index 0000000..7701f20
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/GLOffscreenAutoDrawableImpl.java
@@ -0,0 +1,123 @@
+/**
+ * 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 jogamp.opengl;
+
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.opengl.GL;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLOffscreenAutoDrawable;
+
+import com.jogamp.common.util.locks.RecursiveLock;
+import com.jogamp.opengl.FBObject;
+import com.jogamp.opengl.GLAutoDrawableDelegate;
+
+import jogamp.opengl.GLFBODrawableImpl;
+
+public class GLOffscreenAutoDrawableImpl extends GLAutoDrawableDelegate implements GLOffscreenAutoDrawable {
+  
+    /**
+     * @param drawable a valid and already realized {@link GLDrawable}
+     * @param context a valid {@link GLContext}, may not be made current (created) yet.
+     * @param upstreamWidget optional UI element holding this instance, see {@link #getUpstreamWidget()}.
+     * @param lock optional upstream lock, may be null
+     */
+    public GLOffscreenAutoDrawableImpl(GLDrawable drawable, GLContext context, Object upstreamWidget, RecursiveLock lock) {
+        super(drawable, context, upstreamWidget, true, lock);
+    }
+    
+    @Override
+    public void setSize(int newWidth, int newHeight) throws NativeWindowException, GLException {
+        this.defaultWindowResizedOp(newWidth, newHeight);
+    }
+    
+    public static class FBOImpl extends GLOffscreenAutoDrawableImpl implements GLOffscreenAutoDrawable.FBO {      
+        /**
+         * @param drawable a valid and already realized {@link GLDrawable}
+         * @param context a valid {@link GLContext}, may not be made current (created) yet.
+         * @param upstreamWidget optional UI element holding this instance, see {@link #getUpstreamWidget()}.
+         * @param lock optional upstream lock, may be null
+         */
+        public FBOImpl(GLFBODrawableImpl drawable, GLContext context, Object upstreamWidget, RecursiveLock lock) {
+            super(drawable, context, upstreamWidget, lock);
+        }
+        
+        @Override
+        public boolean isInitialized() {
+            return ((GLFBODrawableImpl)drawable).isInitialized();
+        }
+
+        @Override
+        public final int getTextureUnit() {
+            return ((GLFBODrawableImpl)drawable).getTextureUnit();
+        }
+        
+        @Override
+        public final void setTextureUnit(int unit) {
+            ((GLFBODrawableImpl)drawable).setTextureUnit(unit);
+        }
+
+        @Override
+        public final int getNumSamples() {
+            return ((GLFBODrawableImpl)drawable).getNumSamples();
+        }
+        
+        @Override
+        public final void setNumSamples(GL gl, int newSamples) throws GLException {
+            ((GLFBODrawableImpl)drawable).setNumSamples(gl, newSamples);
+            windowRepaintOp();
+        }
+        
+        /** // TODO: Add or remove TEXTURE (only) DoubleBufferMode support
+        @Override
+        public DoubleBufferMode getDoubleBufferMode() {
+            return ((GLFBODrawableImpl)drawable).getDoubleBufferMode();
+        }
+
+        @Override
+        public void setDoubleBufferMode(DoubleBufferMode mode) throws GLException {
+            ((GLFBODrawableImpl)drawable).setDoubleBufferMode(mode);            
+        } */
+        
+        @Override
+        public final FBObject getFBObject(int bufferName) { 
+            return ((GLFBODrawableImpl)drawable).getFBObject(bufferName);
+        }
+        
+        public final FBObject.TextureAttachment getTextureBuffer(int bufferName) {
+            return ((GLFBODrawableImpl)drawable).getTextureBuffer(bufferName);
+        }
+
+        @Override
+        public void resetSize(GL gl) throws GLException {
+            ((GLFBODrawableImpl)drawable).resetSize(gl);
+        }        
+    }
+}
diff --git a/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java b/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java
index 32f4cb6..b438131 100644
--- a/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java
@@ -40,9 +40,6 @@
 
 package jogamp.opengl;
 
-import javax.media.opengl.GLCapabilitiesImmutable;
-import javax.media.opengl.GLContext;
-import javax.media.opengl.GLDrawable;
 import javax.media.opengl.GLDrawableFactory;
 import javax.media.opengl.GLException;
 import javax.media.opengl.GLPbuffer;
@@ -50,36 +47,18 @@ import javax.media.opengl.GLPbuffer;
 import com.jogamp.common.util.locks.LockFactory;
 import com.jogamp.common.util.locks.RecursiveLock;
 
-/** Platform-independent class exposing pbuffer functionality to
-    applications. This class is not exposed in the public API as it
-    would probably add no value; however it implements the GLDrawable
-    interface so can be interacted with via its display() method. */
-
+ at SuppressWarnings("deprecation")
 public class GLPbufferImpl extends GLAutoDrawableBase implements GLPbuffer {
   private int floatMode;
 
-  public GLPbufferImpl(GLDrawableImpl pbufferDrawable, GLContext sharedContext, boolean ownDevice) {
-    super(pbufferDrawable, null, ownDevice); // drawable := pbufferDrawable 
-    
-    GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable)
-         drawable.getNativeSurface().getGraphicsConfiguration().getChosenCapabilities();
-    if(caps.isOnscreen()) {
-        if(caps.isPBuffer()) {
-            throw new IllegalArgumentException("Error: Given drawable is Onscreen and Pbuffer: "+pbufferDrawable);
-        }
-        throw new IllegalArgumentException("Error: Given drawable is Onscreen: "+pbufferDrawable);
-    } else {
-        if(!caps.isPBuffer()) {
-            throw new IllegalArgumentException("Error: Given drawable is not Pbuffer: "+pbufferDrawable);
-        }
-    }
-    context = (GLContextImpl) drawable.createContext(sharedContext);
+  public GLPbufferImpl(GLDrawableImpl pbufferDrawable, GLContextImpl pbufferContext) {
+    super(pbufferDrawable, pbufferContext, true); // drawable := pbufferDrawable, context := pbufferContext  
   }
 
   //
   // pbuffer specifics
-  // 
-  
+  //
+
   @Override
   public void bindTexture() {
     // Doesn't make much sense to try to do this on the event dispatch
diff --git a/src/jogl/classes/jogamp/opengl/GLVersionNumber.java b/src/jogl/classes/jogamp/opengl/GLVersionNumber.java
index 5bd008f..1004f04 100644
--- a/src/jogl/classes/jogamp/opengl/GLVersionNumber.java
+++ b/src/jogl/classes/jogamp/opengl/GLVersionNumber.java
@@ -53,26 +53,26 @@ class GLVersionNumber extends VersionNumber {
                 tok.nextToken(); // GL_
                 tok.nextToken(); // VERSION_
                 if (!tok.hasMoreTokens()) {
-                    major = 0;
+                    val[0] = 0;
                     return;
                 }
-                major = Integer.valueOf(tok.nextToken()).intValue();
+                val[0] = Integer.valueOf(tok.nextToken()).intValue();
                 if (!tok.hasMoreTokens()) {
-                    minor = 0;
+                    val[1] = 0;
                     return;
                 }
-                minor = Integer.valueOf(tok.nextToken()).intValue();
+                val[1] = Integer.valueOf(tok.nextToken()).intValue();
                 if (!tok.hasMoreTokens()) {
-                    sub = 0;
+                    val[2] = 0;
                     return;
                 }
-                sub = Integer.valueOf(tok.nextToken()).intValue();
+                val[2] = Integer.valueOf(tok.nextToken()).intValue();
             } else {
                 int radix = 10;
                 if (versionString.length() > 2) {
                     if (Character.isDigit(versionString.charAt(0)) && versionString.charAt(1) == '.' && Character.isDigit(versionString.charAt(2))) {
-                        major = Character.digit(versionString.charAt(0), radix);
-                        minor = Character.digit(versionString.charAt(2), radix);
+                        val[0] = Character.digit(versionString.charAt(0), radix);
+                        val[1] = Character.digit(versionString.charAt(2), radix);
                         // See if there's version-specific information which might
                         // imply a more recent OpenGL version
                         StringTokenizer tok = new StringTokenizer(versionString, " ");
@@ -90,9 +90,9 @@ class GLVersionNumber extends VersionNumber {
                                     // Avoid possibly confusing situations by putting some
                                     // constraints on the upgrades we do to the major and
                                     // minor versions
-                                    if ((altMajor == major && altMinor > minor) || altMajor == major + 1) {
-                                        major = altMajor;
-                                        minor = altMinor;
+                                    if ((altMajor == val[0] && altMinor > val[1]) || altMajor == val[0] + 1) {
+                                        val[0] = altMajor;
+                                        val[1] = altMinor;
                                     }
                                 }
                             }
@@ -106,8 +106,8 @@ class GLVersionNumber extends VersionNumber {
             // FIXME: refactor desktop OpenGL dependencies and make this
             // class work properly for OpenGL ES
             System.err.println("Info: ExtensionAvailabilityCache: FunctionAvailabilityCache.Version.<init>: " + e);
-            major = 1;
-            minor = 0;
+            val[0] = 1;
+            val[1] = 0;
             /*
             throw (IllegalArgumentException)
             new IllegalArgumentException(
diff --git a/src/test/com/jogamp/opengl/test/junit/util/InputEventCountAdapter.java b/src/jogl/classes/jogamp/opengl/GLXExtensions.java
similarity index 75%
copy from src/test/com/jogamp/opengl/test/junit/util/InputEventCountAdapter.java
copy to src/jogl/classes/jogamp/opengl/GLXExtensions.java
index 27f3d7e..36c6c46 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/InputEventCountAdapter.java
+++ b/src/jogl/classes/jogamp/opengl/GLXExtensions.java
@@ -1,16 +1,16 @@
 /**
- * Copyright 2010 JogAmp Community. All rights reserved.
+ * 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
@@ -20,16 +20,18 @@
  * 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;
+package jogamp.opengl;
 
-public interface InputEventCountAdapter extends  EventCountAdapter {
-    int getCount();
-    boolean isPressed();
+/**
+ * Class holding GLX/WGL/.. extension strings, commonly used by JOGL's implementation. 
+ */
+public class GLXExtensions {   
+  public static final String GLX_MESA_swap_control           = "GLX_MESA_swap_control";
+  public static final String GLX_SGI_swap_control            = "GLX_SGI_swap_control";
+  public static final String GLX_NV_swap_group               = "GLX_NV_swap_group";
 }
-
diff --git a/src/jogl/classes/jogamp/opengl/ProjectFloat.java b/src/jogl/classes/jogamp/opengl/ProjectFloat.java
index ce8405f..18fe3e7 100644
--- a/src/jogl/classes/jogamp/opengl/ProjectFloat.java
+++ b/src/jogl/classes/jogamp/opengl/ProjectFloat.java
@@ -135,7 +135,7 @@ import com.jogamp.opengl.FloatUtil;
  * @author Sven Gothel
  */
 public class ProjectFloat {
-  public static final int getRequiredFloatBufferSize() { return 2*16+2*4+3*3; }
+  public static final int getRequiredFloatBufferSize() { return 1*16; }
   
   // Note that we have cloned parts of the implementation in order to
   // support incoming Buffers. The reason for this is to avoid loading
@@ -153,18 +153,14 @@ public class ProjectFloat {
   private final float[] out = new float[4];
 
   // Buffer-based implementation
-  private FloatBuffer matrixBuf;
-  private FloatBuffer tempInvertMatrixBuf;
+  private FloatBuffer matrixBuf; // 4x4
 
-  private FloatBuffer inBuf;
-  private FloatBuffer outBuf;
-
-  private FloatBuffer forwardBuf;
-  private FloatBuffer sideBuf;
-  private FloatBuffer upBuf;
+  private final float[] forward = new float[3];  // 3
+  private final float[] side    = new float[3];  // 3
+  private final float[] up      = new float[3];  // 3
 
   public ProjectFloat() {
-      this(false);
+      this(true);
   }
   
   public ProjectFloat(boolean useBackingArray) {
@@ -182,33 +178,11 @@ public class ProjectFloat {
    * @param floatOffset Offset for either of the given sources (buffer or array)
    */
   public ProjectFloat(Buffer floatBuffer, float[] floatArray, int floatOffset) {    
-    int floatPos = floatOffset;
-    int floatSize = 16;
-    matrixBuf = Buffers.slice2Float(floatBuffer, floatArray, floatPos, floatSize);
-    floatPos += floatSize;
-    tempInvertMatrixBuf = Buffers.slice2Float(floatBuffer, floatArray, floatPos, floatSize);
-    floatPos += floatSize;
-    floatSize = 4;
-    inBuf = Buffers.slice2Float(floatBuffer, floatArray, floatPos, floatSize);
-    floatPos += floatSize;
-    outBuf = Buffers.slice2Float(floatBuffer, floatArray, floatPos, floatSize);
-    floatPos += floatSize;
-    floatSize = 3;
-    forwardBuf = Buffers.slice2Float(floatBuffer, floatArray, floatPos, floatSize);
-    floatPos += floatSize;
-    sideBuf = Buffers.slice2Float(floatBuffer, floatArray, floatPos, floatSize);
-    floatPos += floatSize;
-    upBuf = Buffers.slice2Float(floatBuffer, floatArray, floatPos, floatSize);
+    matrixBuf = Buffers.slice2Float(floatBuffer, floatArray, floatOffset, 16);
   }
 
   public void destroy() {
     matrixBuf = null;
-    tempInvertMatrixBuf = null;
-    inBuf = null;
-    outBuf = null;
-    forwardBuf = null;
-    sideBuf = null;
-    upBuf = null;
   }
 
   /**
@@ -221,7 +195,7 @@ public class ProjectFloat {
   public boolean gluInvertMatrixf(float[] src, int srcOffset, float[] inverse, int inverseOffset) {
     int i, j, k, swap;
     float t;
-    float[][] temp = tempInvertMatrix;
+    final float[][] temp = tempInvertMatrix;
 
     for (i = 0; i < 4; i++) {
       for (j = 0; j < 4; j++) {
@@ -292,14 +266,14 @@ public class ProjectFloat {
     int i, j, k, swap;
     float t;
 
-    int srcPos = src.position();
-    int invPos = inverse.position();
-
-    FloatBuffer temp = tempInvertMatrixBuf;
+    final int srcPos = src.position();
+    final int invPos = inverse.position();
+    
+    final float[][] temp = tempInvertMatrix;
 
     for (i = 0; i < 4; i++) {
       for (j = 0; j < 4; j++) {
-        temp.put(i*4+j, src.get(i*4+j + srcPos));
+        temp[i][j] = src.get(i*4+j + srcPos);
       }
     }
     FloatUtil.makeIdentityf(inverse);
@@ -310,7 +284,7 @@ public class ProjectFloat {
       //
       swap = i;
       for (j = i + 1; j < 4; j++) {
-        if (Math.abs(temp.get(j*4+i)) > Math.abs(temp.get(i*4+i))) {
+        if (Math.abs(temp[j][i]) > Math.abs(temp[i][i])) {
           swap = j;
         }
       }
@@ -320,17 +294,17 @@ public class ProjectFloat {
         // Swap rows.
         //
         for (k = 0; k < 4; k++) {
-          t = temp.get(i*4+k);
-          temp.put(i*4+k, temp.get(swap*4+k));
-          temp.put(swap*4+k, t);
-
+          t = temp[i][k];
+          temp[i][k] = temp[swap][k];
+          temp[swap][k] = t;
+          
           t = inverse.get(i*4+k + invPos);
           inverse.put(i*4+k + invPos, inverse.get(swap*4+k + invPos));
           inverse.put(swap*4+k + invPos, t);
         }
       }
 
-      if (temp.get(i*4+i) == 0) {
+      if (temp[i][i] == 0) {
         //
         // No non-zero pivot. The matrix is singular, which shouldn't
         // happen. This means the user gave us a bad matrix.
@@ -338,17 +312,19 @@ public class ProjectFloat {
         return false;
       }
 
-      t = temp.get(i*4+i);
+      t = temp[i][i];
       for (k = 0; k < 4; k++) {
-        temp.put(i*4+k, temp.get(i*4+k) / t);
-        inverse.put(i*4+k + invPos, inverse.get(i*4+k + invPos) / t);
+        temp[i][k] /= t;
+        final int z = i*4+k + invPos;
+        inverse.put(z, inverse.get(z) / t);
       }
       for (j = 0; j < 4; j++) {
         if (j != i) {
-          t = temp.get(j*4+i);
+          t = temp[j][i];
           for (k = 0; k < 4; k++) {
-            temp.put(j*4+k, temp.get(j*4+k) - temp.get(i*4+k) * t);
-            inverse.put(j*4+k + invPos, inverse.get(j*4+k + invPos) - inverse.get(i*4+k + invPos) * t);
+            temp[j][k] -= temp[i][k] * t;
+            final int z = j*4+k + invPos;
+            inverse.put(z, inverse.get(z) - inverse.get(i*4+k + invPos) * t);
           }
         }
       }
@@ -378,8 +354,8 @@ public class ProjectFloat {
    * @param zFar
    */
   public void gluPerspective(GLMatrixFunc gl, float fovy, float aspect, float zNear, float zFar) {
+    final float radians = fovy / 2 * (float) Math.PI / 180;
     float sine, cotangent, deltaZ;
-    float radians = fovy / 2 * (float) Math.PI / 180;
 
     deltaZ = zFar - zNear;
     sine = (float) Math.sin(radians);
@@ -391,13 +367,13 @@ public class ProjectFloat {
     cotangent = (float) Math.cos(radians) / sine;
 
     FloatUtil.makeIdentityf(matrixBuf);
-
-    matrixBuf.put(0 * 4 + 0, cotangent / aspect);
-    matrixBuf.put(1 * 4 + 1, cotangent);
-    matrixBuf.put(2 * 4 + 2, - (zFar + zNear) / deltaZ);
-    matrixBuf.put(2 * 4 + 3, -1);
-    matrixBuf.put(3 * 4 + 2, -2 * zNear * zFar / deltaZ);
-    matrixBuf.put(3 * 4 + 3, 0);
+    final int mPos = matrixBuf.position();
+    matrixBuf.put(0 * 4 + 0 + mPos, cotangent / aspect);
+    matrixBuf.put(1 * 4 + 1 + mPos, cotangent);
+    matrixBuf.put(2 * 4 + 2 + mPos, - (zFar + zNear) / deltaZ);
+    matrixBuf.put(2 * 4 + 3 + mPos, -1);
+    matrixBuf.put(3 * 4 + 2 + mPos, -2 * zNear * zFar / deltaZ);
+    matrixBuf.put(3 * 4 + 3 + mPos, 0);
 
     gl.glMultMatrixf(matrixBuf);
   }
@@ -419,17 +395,17 @@ public class ProjectFloat {
                         float eyex, float eyey, float eyez,
                         float centerx, float centery, float centerz,
                         float upx, float upy, float upz) {
-    FloatBuffer forward = this.forwardBuf;
-    FloatBuffer side = this.sideBuf;
-    FloatBuffer up = this.upBuf;
+    final float[] forward = this.forward;
+    final float[] side = this.side;
+    final float[] up = this.up;
 
-    forward.put(0, centerx - eyex);
-    forward.put(1, centery - eyey);
-    forward.put(2, centerz - eyez);
+    forward[0] = centerx - eyex;
+    forward[1] = centery - eyey;
+    forward[2] = centerz - eyez;
 
-    up.put(0, upx);
-    up.put(1, upy);
-    up.put(2, upz);
+    up[0] = upx;
+    up[1] = upy;
+    up[2] = upz;
 
     FloatUtil.normalize(forward);
 
@@ -441,24 +417,25 @@ public class ProjectFloat {
     FloatUtil.cross(side, forward, up);
 
     FloatUtil.makeIdentityf(matrixBuf);
-    matrixBuf.put(0 * 4 + 0, side.get(0));
-    matrixBuf.put(1 * 4 + 0, side.get(1));
-    matrixBuf.put(2 * 4 + 0, side.get(2));
+    final int mPos = matrixBuf.position();
+    matrixBuf.put(0 * 4 + 0 + mPos, side[0]);
+    matrixBuf.put(1 * 4 + 0 + mPos, side[1]);
+    matrixBuf.put(2 * 4 + 0 + mPos, side[2]);
 
-    matrixBuf.put(0 * 4 + 1, up.get(0));
-    matrixBuf.put(1 * 4 + 1, up.get(1));
-    matrixBuf.put(2 * 4 + 1, up.get(2));
+    matrixBuf.put(0 * 4 + 1 + mPos, up[0]);
+    matrixBuf.put(1 * 4 + 1 + mPos, up[1]);
+    matrixBuf.put(2 * 4 + 1 + mPos, up[2]);
 
-    matrixBuf.put(0 * 4 + 2, -forward.get(0));
-    matrixBuf.put(1 * 4 + 2, -forward.get(1));
-    matrixBuf.put(2 * 4 + 2, -forward.get(2));
+    matrixBuf.put(0 * 4 + 2 + mPos, -forward[0]);
+    matrixBuf.put(1 * 4 + 2 + mPos, -forward[1]);
+    matrixBuf.put(2 * 4 + 2 + mPos, -forward[2]);
 
     gl.glMultMatrixf(matrixBuf);
     gl.glTranslatef(-eyex, -eyey, -eyez);
   }
 
   /**
-   * Method gluProject
+   * Map object coordinates to window coordinates.
    * 
    * @param objx
    * @param objy
@@ -476,16 +453,16 @@ public class ProjectFloat {
                             int[] viewport, int viewport_offset,
                             float[] win_pos, int win_pos_offset ) {
 
-    float[] in = this.in;
-    float[] out = this.out;
+    final float[] in = this.in;
+    final float[] out = this.out;
 
     in[0] = objx;
     in[1] = objy;
     in[2] = objz;
     in[3] = 1.0f;
 
-    FloatUtil.multMatrixVecf(modelMatrix, modelMatrix_offset, in, 0, out);
-    FloatUtil.multMatrixVecf(projMatrix, projMatrix_offset, out, 0, in);
+    FloatUtil.multMatrixVecf(modelMatrix, modelMatrix_offset, in, 0, out, 0);
+    FloatUtil.multMatrixVecf(projMatrix, projMatrix_offset, out, 0, in, 0);
 
     if (in[3] == 0.0f) {
       return false;
@@ -506,44 +483,47 @@ public class ProjectFloat {
     return true;
   }
 
+  /**
+   * Map object coordinates to window coordinates.
+   */
   public boolean gluProject(float objx, float objy, float objz,
                             FloatBuffer modelMatrix,
                             FloatBuffer projMatrix,
                             int[] viewport, int viewport_offset,
                             float[] win_pos, int win_pos_offset ) {
 
-    FloatBuffer in = this.inBuf;
-    FloatBuffer out = this.outBuf;
+    final float[] in = this.in;
+    final float[] out = this.out;
 
-    in.put(0, objx);
-    in.put(1, objy);
-    in.put(2, objz);
-    in.put(3, 1.0f);
+    in[0] = objx;
+    in[1] = objy;
+    in[2] = objz;
+    in[3] = 1.0f;
 
     FloatUtil.multMatrixVecf(modelMatrix, in, out);
     FloatUtil.multMatrixVecf(projMatrix, out, in);
 
-    if (in.get(3) == 0.0f) {
+    if (in[3] == 0.0f) {
       return false;
     }
 
-    in.put(3, (1.0f / in.get(3)) * 0.5f);
+    in[3] = (1.0f / in[3]) * 0.5f;
 
     // Map x, y and z to range 0-1
-    in.put(0, in.get(0) * in.get(3) + 0.5f);
-    in.put(1, in.get(1) * in.get(3) + 0.5f);
-    in.put(2, in.get(2) * in.get(3) + 0.5f);
+    in[0] = in[0] * in[3] + 0.5f;
+    in[1] = in[1] * in[3] + 0.5f;
+    in[2] = in[2] * in[3] + 0.5f;
 
     // Map x,y to viewport
-    win_pos[0+win_pos_offset] = in.get(0) * viewport[2+viewport_offset] + viewport[0+viewport_offset];
-    win_pos[1+win_pos_offset] = in.get(1) * viewport[3+viewport_offset] + viewport[1+viewport_offset];
-    win_pos[2+win_pos_offset] = in.get(2);
-
+    win_pos[0+win_pos_offset] = in[0] * viewport[2+viewport_offset] + viewport[0+viewport_offset];
+    win_pos[1+win_pos_offset] = in[1] * viewport[3+viewport_offset] + viewport[1+viewport_offset];
+    win_pos[2+win_pos_offset] = in[2];
+    
     return true;
   }
   
   /**
-   * Method gluProject
+   * Map object coordinates to window coordinates.
    * 
    * @param objx
    * @param objy
@@ -561,41 +541,41 @@ public class ProjectFloat {
                             IntBuffer viewport,
                             FloatBuffer win_pos) {
 
-    FloatBuffer in = this.inBuf;
-    FloatBuffer out = this.outBuf;
+    final float[] in = this.in;
+    final float[] out = this.out;
 
-    in.put(0, objx);
-    in.put(1, objy);
-    in.put(2, objz);
-    in.put(3, 1.0f);
+    in[0] = objx;
+    in[1] = objy;
+    in[2] = objz;
+    in[3] = 1.0f;
 
     FloatUtil.multMatrixVecf(modelMatrix, in, out);
     FloatUtil.multMatrixVecf(projMatrix, out, in);
 
-    if (in.get(3) == 0.0f) {
+    if (in[3] == 0.0f) {
       return false;
     }
 
-    in.put(3, (1.0f / in.get(3)) * 0.5f);
+    in[3] = (1.0f / in[3]) * 0.5f;
 
     // Map x, y and z to range 0-1
-    in.put(0, in.get(0) * in.get(3) + 0.5f);
-    in.put(1, in.get(1) * in.get(3) + 0.5f);
-    in.put(2, in.get(2) * in.get(3) + 0.5f);
+    in[0] = in[0] * in[3] + 0.5f;
+    in[1] = in[1] * in[3] + 0.5f;
+    in[2] = in[2] * in[3] + 0.5f;
 
     // Map x,y to viewport
-    int vPos = viewport.position();
-    int wPos = win_pos.position();
-    win_pos.put(0+wPos, in.get(0) * viewport.get(2+vPos) + viewport.get(0+vPos));
-    win_pos.put(1+wPos, in.get(1) * viewport.get(3+vPos) + viewport.get(1+vPos));
-    win_pos.put(2+wPos, in.get(2));
+    final int vPos = viewport.position();
+    final int wPos = win_pos.position();
+    win_pos.put(0+wPos, in[0] * viewport.get(2+vPos) + viewport.get(0+vPos));
+    win_pos.put(1+wPos, in[1] * viewport.get(3+vPos) + viewport.get(1+vPos));
+    win_pos.put(2+wPos, in[2]);
 
     return true;
   }
 
 
   /**
-   * Method gluUnproject
+   * Map window coordinates to object coordinates.
    * 
    * @param winx
    * @param winy
@@ -612,8 +592,8 @@ public class ProjectFloat {
                               float[] projMatrix, int projMatrix_offset,
                               int[] viewport, int viewport_offset,
                               float[] obj_pos, int obj_pos_offset) {
-    float[] in = this.in;
-    float[] out = this.out;
+    final float[] in = this.in;
+    final float[] out = this.out;
 
     FloatUtil.multMatrixf(projMatrix, projMatrix_offset, modelMatrix, modelMatrix_offset, matrix, 0);
 
@@ -651,13 +631,27 @@ public class ProjectFloat {
   }
 
 
+  /**
+   * Map window coordinates to object coordinates.
+   * 
+   * @param winx
+   * @param winy
+   * @param winz
+   * @param modelMatrix
+   * @param projMatrix
+   * @param viewport
+   * @param viewport_offset
+   * @param obj_pos
+   * @param obj_pos_offset
+   * @return
+   */
   public boolean gluUnProject(float winx, float winy, float winz,
                               FloatBuffer modelMatrix, 
                               FloatBuffer projMatrix,
                               int[] viewport, int viewport_offset,
                               float[] obj_pos, int obj_pos_offset) {
-    FloatBuffer in = this.inBuf;
-    FloatBuffer out = this.outBuf;
+    final float[] in = this.in;
+    final float[] out = this.out;
 
     FloatUtil.multMatrixf(projMatrix, modelMatrix, matrixBuf);
 
@@ -665,37 +659,37 @@ public class ProjectFloat {
       return false;
     }
 
-    in.put(0, winx);
-    in.put(1, winy);
-    in.put(2, winz);
-    in.put(3, 1.0f);
+    in[0] = winx;
+    in[1] = winy;
+    in[2] = winz;
+    in[3] = 1.0f;
 
     // Map x and y from window coordinates
-    in.put(0, (in.get(0) - viewport[0+viewport_offset]) / viewport[2+viewport_offset]);
-    in.put(1, (in.get(1) - viewport[1+viewport_offset]) / viewport[3+viewport_offset]);
-    
+    in[0] = (in[0] - viewport[0+viewport_offset]) / viewport[2+viewport_offset];
+    in[1] = (in[1] - viewport[1+viewport_offset]) / viewport[3+viewport_offset];
+
     // Map to range -1 to 1
-    in.put(0, in.get(0) * 2 - 1);
-    in.put(1, in.get(1) * 2 - 1);
-    in.put(2, in.get(2) * 2 - 1);
+    in[0] = in[0] * 2 - 1;
+    in[1] = in[1] * 2 - 1;
+    in[2] = in[2] * 2 - 1;
 
     FloatUtil.multMatrixVecf(matrixBuf, in, out);
-
-    if (out.get(3) == 0.0f) {
+    
+    if (out[3] == 0.0) {
       return false;
     }
 
-    out.put(3, 1.0f / out.get(3));
+    out[3] = 1.0f / out[3];
 
-    obj_pos[0+obj_pos_offset] = out.get(0) * out.get(3);
-    obj_pos[1+obj_pos_offset] = out.get(1) * out.get(3);
-    obj_pos[2+obj_pos_offset] = out.get(2) * out.get(3);
+    obj_pos[0+obj_pos_offset] = out[0] * out[3];
+    obj_pos[1+obj_pos_offset] = out[1] * out[3];
+    obj_pos[2+obj_pos_offset] = out[2] * out[3];
 
     return true;
   }
   
   /**
-   * Method gluUnproject
+   * Map window coordinates to object coordinates.
    * 
    * @param winx
    * @param winy
@@ -712,8 +706,8 @@ public class ProjectFloat {
                               FloatBuffer projMatrix,
                               IntBuffer viewport,
                               FloatBuffer obj_pos) {
-    FloatBuffer in = this.inBuf;
-    FloatBuffer out = this.outBuf;
+    final float[] in = this.in;
+    final float[] out = this.out;
 
     FloatUtil.multMatrixf(projMatrix, modelMatrix, matrixBuf);
 
@@ -721,40 +715,40 @@ public class ProjectFloat {
       return false;
     }
 
-    in.put(0, winx);
-    in.put(1, winy);
-    in.put(2, winz);
-    in.put(3, 1.0f);
+    in[0] = winx;
+    in[1] = winy;
+    in[2] = winz;
+    in[3] = 1.0f;
 
     // Map x and y from window coordinates
-    int vPos = viewport.position();
-    int oPos = obj_pos.position();
-    in.put(0, (in.get(0) - viewport.get(0+vPos)) / viewport.get(2+vPos));
-    in.put(1, (in.get(1) - viewport.get(1+vPos)) / viewport.get(3+vPos));
+    final int vPos = viewport.position();
+    final int oPos = obj_pos.position();    
+    in[0] = (in[0] - viewport.get(0+vPos)) / viewport.get(2+vPos);
+    in[1] = (in[1] - viewport.get(1+vPos)) / viewport.get(3+vPos);
 
     // Map to range -1 to 1
-    in.put(0, in.get(0) * 2 - 1);
-    in.put(1, in.get(1) * 2 - 1);
-    in.put(2, in.get(2) * 2 - 1);
+    in[0] = in[0] * 2 - 1;
+    in[1] = in[1] * 2 - 1;
+    in[2] = in[2] * 2 - 1;
 
     FloatUtil.multMatrixVecf(matrixBuf, in, out);
 
-    if (out.get(3) == 0.0f) {
+    if (out[3] == 0.0) {
       return false;
     }
 
-    out.put(3, 1.0f / out.get(3));
+    out[3] = 1.0f / out[3];
 
-    obj_pos.put(0+oPos, out.get(0) * out.get(3));
-    obj_pos.put(1+oPos, out.get(1) * out.get(3));
-    obj_pos.put(2+oPos, out.get(2) * out.get(3));
+    obj_pos.put(0+oPos, out[0] * out[3]);
+    obj_pos.put(1+oPos, out[1] * out[3]);
+    obj_pos.put(2+oPos, out[2] * out[3]);
 
     return true;
   }
 
 
   /**
-   * Method gluUnproject4
+   * Map window coordinates to object coordinates.
    * 
    * @param winx
    * @param winy
@@ -783,8 +777,8 @@ public class ProjectFloat {
                                float far,
                                float[] obj_pos,
                                int obj_pos_offset ) {
-    float[] in = this.in;
-    float[] out = this.out;
+    final float[] in = this.in;
+    final float[] out = this.out;
 
     FloatUtil.multMatrixf(projMatrix, projMatrix_offset, modelMatrix, modelMatrix_offset, matrix, 0);
 
@@ -808,8 +802,9 @@ public class ProjectFloat {
 
     FloatUtil.multMatrixVecf(matrix, in, out);
 
-    if (out[3] == 0.0f)
+    if (out[3] == 0.0f) {
       return false;
+    }
 
     obj_pos[0+obj_pos_offset] = out[0];
     obj_pos[1+obj_pos_offset] = out[1];
@@ -819,7 +814,7 @@ public class ProjectFloat {
   }
 
   /**
-   * Method gluUnproject4
+   * Map window coordinates to object coordinates.
    * 
    * @param winx
    * @param winy
@@ -844,40 +839,41 @@ public class ProjectFloat {
                                float near,
                                float far,
                                FloatBuffer obj_pos) {
-    FloatBuffer in = this.inBuf;
-    FloatBuffer out = this.outBuf;
+    final float[] in = this.in;
+    final float[] out = this.out;
 
     FloatUtil.multMatrixf(projMatrix, modelMatrix, matrixBuf);
 
     if (!gluInvertMatrixf(matrixBuf, matrixBuf))
       return false;
 
-    in.put(0, winx);
-    in.put(1, winy);
-    in.put(2, winz);
-    in.put(3, clipw);
+    in[0] = winx;
+    in[1] = winy;
+    in[2] = winz;
+    in[3] = clipw;
 
     // Map x and y from window coordinates
-    int vPos = viewport.position();
-    in.put(0, (in.get(0) - viewport.get(0+vPos)) / viewport.get(2+vPos));
-    in.put(1, (in.get(1) - viewport.get(1+vPos)) / viewport.get(3+vPos));
-    in.put(2, (in.get(2) - near) / (far - near));
-
+    final int vPos = viewport.position();
+    in[0] = (in[0] - viewport.get(0+vPos)) / viewport.get(2+vPos);
+    in[1] = (in[1] - viewport.get(1+vPos)) / viewport.get(3+vPos);
+    in[2] = (in[2] - near) / (far - near);
+    
     // Map to range -1 to 1
-    in.put(0, in.get(0) * 2 - 1);
-    in.put(1, in.get(1) * 2 - 1);
-    in.put(2, in.get(2) * 2 - 1);
+    in[0] = in[0] * 2 - 1;
+    in[1] = in[1] * 2 - 1;
+    in[2] = in[2] * 2 - 1;
 
     FloatUtil.multMatrixVecf(matrixBuf, in, out);
 
-    if (out.get(3) == 0.0f)
+    if (out[3] == 0.0f) {
       return false;
+    }
 
-    int oPos = obj_pos.position();
-    obj_pos.put(0+oPos, out.get(0));
-    obj_pos.put(1+oPos, out.get(1));
-    obj_pos.put(2+oPos, out.get(2));
-    obj_pos.put(3+oPos, out.get(3));
+    final int oPos = obj_pos.position();
+    obj_pos.put(0+oPos, out[0]);
+    obj_pos.put(1+oPos, out[1]);
+    obj_pos.put(2+oPos, out[2]);
+    obj_pos.put(3+oPos, out[3]);    
     return true;
   }
 
@@ -902,7 +898,7 @@ public class ProjectFloat {
     }
 
     /* Translate and scale the picked region to the entire window */
-    int vPos = viewport.position();
+    final int vPos = viewport.position();
     gl.glTranslatef((viewport.get(2+vPos) - 2 * (x - viewport.get(0+vPos))) / deltaX,
                     (viewport.get(3+vPos) - 2 * (y - viewport.get(1+vPos))) / deltaY,
                     0);
diff --git a/src/jogl/classes/jogamp/opengl/ThreadingImpl.java b/src/jogl/classes/jogamp/opengl/ThreadingImpl.java
index 61a4767..d55a2c9 100644
--- a/src/jogl/classes/jogamp/opengl/ThreadingImpl.java
+++ b/src/jogl/classes/jogamp/opengl/ThreadingImpl.java
@@ -89,8 +89,7 @@ public class ThreadingImpl {
                         // problems.
                         hasAWT = GLProfile.isAWTAvailable();
 
-                        String osType = NativeWindowFactory.getNativeWindowType(false);
-                        _isX11 = NativeWindowFactory.TYPE_X11.equals(osType);
+                        _isX11 = NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(false);
 
                         // default setting
                         singleThreaded = true;
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
index c5d0df6..84aeaa9 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
@@ -42,6 +42,7 @@ import java.util.Map;
 
 import javax.media.nativewindow.AbstractGraphicsConfiguration;
 import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.opengl.GLCapabilitiesImmutable;
 import javax.media.opengl.GLContext;
 import javax.media.opengl.GLException;
 import javax.media.opengl.GLProfile;
@@ -50,9 +51,10 @@ import jogamp.opengl.GLContextImpl;
 import jogamp.opengl.GLDrawableImpl;
 
 import com.jogamp.common.nio.Buffers;
-import com.jogamp.common.os.Platform;
 import com.jogamp.gluegen.runtime.ProcAddressTable;
 import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
+import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
+import com.jogamp.opengl.GLRendererQuirks;
 
 public abstract class EGLContext extends GLContextImpl {
     private boolean eglQueryStringInitialized;
@@ -209,8 +211,8 @@ public abstract class EGLContext extends GLContextImpl {
                                ",\n\tsharing with 0x" + Long.toHexString(shareWithHandle));
         }
         if (!EGL.eglMakeCurrent(eglDisplay, drawable.getHandle(), drawableRead.getHandle(), contextHandle)) {
-            throw new GLException("Error making context 0x" +
-                                  Long.toHexString(contextHandle) + " current: error code " + EGL.eglGetError());
+            throw new GLException("Error making context " +
+                                  toHexString(contextHandle) + " current: error code " + toHexString(EGL.eglGetError()));
         }
         setGLFunctionAvailability(true, glProfile.usesNativeGLES2() ? 2 : 1, 0, CTX_PROFILE_ES);
         return true;
@@ -268,56 +270,51 @@ public abstract class EGLContext extends GLContextImpl {
 
     @Override
     protected boolean setSwapIntervalImpl(int interval) {
-        // FIXME !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-        // eglSwapInterval(..) issued:
-        //   Android 4.0.3 / Pandaboard ES / PowerVR SGX 540: crashes
-        // FIXME !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-        if( Platform.OSType.ANDROID == Platform.getOSType() && getGLRendererString(true).contains("powervr") ) {
-            if(DEBUG) {
-                System.err.println("Ignored: eglSwapInterval("+interval+") - cause: OS "+Platform.getOSType() + " / Renderer " + getGLRendererString(false));
-            }
+        if( hasRendererQuirk(GLRendererQuirks.NoSetSwapInterval) ) {
             return false;
         }
         return EGL.eglSwapInterval(drawable.getNativeSurface().getDisplayHandle(), interval);
     }
 
-    @Override
-    public abstract void bindPbufferToTexture();
-
-    @Override
-    public abstract void releasePbufferFromTexture();
-
     //
     // Accessible ..
     //
     
-    /**
-     * If context is an ES profile, map it to the given device 
-     * via {@link GLContext#mapAvailableGLVersion(AbstractGraphicsDevice, int, int, int, int, int)}.
-     * <p>
-     * We intentionally override a non native EGL device ES profile mapping,
-     * i.e. this will override/modify an already 'set' X11/WGL/.. mapping.
-     * </p> 
-     * 
-     * @param device
-     */
-    protected void mapCurrentAvailableGLVersion(AbstractGraphicsDevice device) {
-        mapCurrentAvailableGLVersionImpl(device, ctxMajorVersion, ctxMinorVersion, ctxOptions);
+    /* pp */ void mapCurrentAvailableGLVersion(AbstractGraphicsDevice device) {
+        mapStaticGLVersion(device, ctxMajorVersion, ctxMinorVersion, ctxOptions);
     }
-        
-    protected static void mapStaticGLESVersion(AbstractGraphicsDevice device, int major) {
+    /* pp */ int getContextOptions() { return ctxOptions; }    
+    /* pp */ static void mapStaticGLESVersion(AbstractGraphicsDevice device, GLCapabilitiesImmutable caps) {
+        final GLProfile glp = caps.getGLProfile();
+        final int[] reqMajorCTP = new int[2];
+        GLContext.getRequestMajorAndCompat(glp, reqMajorCTP);
+        if(glp.isGLES() && reqMajorCTP[0] >= 2) {
+            reqMajorCTP[1] |= GLContext.CTX_IMPL_ES2_COMPAT | GLContext.CTX_IMPL_FBO ;
+        }
+        if(!caps.getHardwareAccelerated()) {
+            reqMajorCTP[1] |= GLContext.CTX_IMPL_ACCEL_SOFT;
+        }
+        mapStaticGLVersion(device, reqMajorCTP[0], 0, reqMajorCTP[1]);
+    }    
+    /* pp */ static void mapStaticGLESVersion(AbstractGraphicsDevice device, int major) {
         int ctp = ( 2 == major ) ? ( GLContext.CTX_PROFILE_ES | GLContext.CTX_IMPL_ES2_COMPAT | GLContext.CTX_IMPL_FBO ) : ( GLContext.CTX_PROFILE_ES );  
-        mapCurrentAvailableGLVersionImpl(device, major, 0, ctp);
+        mapStaticGLVersion(device, major, 0, ctp);
     }
-    private static void mapCurrentAvailableGLVersionImpl(AbstractGraphicsDevice device, int major, int minor, int 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);
+            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);
+            }            
         }
     }
+    protected static String getGLVersion(int major, int minor, int ctp, String gl_version) {
+        return GLContext.getGLVersion(major, minor, ctp, gl_version);
+    }
     
     protected static boolean getAvailableGLVersionsSet(AbstractGraphicsDevice device) {
         return GLContext.getAvailableGLVersionsSet(device);
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java b/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
index 432010f..1f6f49f 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
@@ -29,6 +29,7 @@
 package jogamp.opengl.egl;
 
 import java.nio.IntBuffer;
+import java.util.Iterator;
 
 import javax.media.nativewindow.AbstractGraphicsDevice;
 import javax.media.nativewindow.NativeSurface;
@@ -51,7 +52,7 @@ import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
  * </p>
  */
 public class EGLDisplayUtil {
-    protected static final boolean DEBUG = Debug.debug("EGL");
+    protected static final boolean DEBUG = Debug.debug("EGLDisplayUtil");
     
     static LongIntHashMap eglDisplayCounter;
     
@@ -60,6 +61,31 @@ public class EGLDisplayUtil {
         eglDisplayCounter.setKeyNotFoundValue(0);
     }
 
+    /** 
+     * @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) {
+                Thread.dumpStack();
+            }
+            if( eglDisplayCounter.size() > 0) {
+                dumpOpenDisplayConnections();
+            }
+        }
+        return eglDisplayCounter.size();
+    }
+    
+    public static void dumpOpenDisplayConnections() {
+        System.err.println("EGLDisplayUtil: Open EGL Display Connections: "+eglDisplayCounter.size());
+        int i=0;
+        for(Iterator<LongIntHashMap.Entry> iter = eglDisplayCounter.iterator(); iter.hasNext(); i++) {
+            final LongIntHashMap.Entry e = iter.next();
+            System.err.println("EGLDisplayUtil: Open["+i+"]: 0x"+Long.toHexString(e.key)+": refCnt "+e.value);
+        }
+    }
+    
     public static long eglGetDisplay(long nativeDisplay_id)  {
         final long eglDisplay = EGL.eglGetDisplay(nativeDisplay_id);
         if(DEBUG) {
@@ -70,29 +96,13 @@ public class EGLDisplayUtil {
         return eglDisplay;
     }
     
-    public static synchronized boolean eglInitialize(long eglDisplay, int[] major, int major_offset, int[] minor, int minor_offset)  {
-        final boolean res;    
-        final int refCnt = eglDisplayCounter.get(eglDisplay) + 1; // 0 + 1 = 1 -> 1st init
-        if(1==refCnt) {
-            res = EGL.eglInitialize(eglDisplay, major, major_offset, minor, minor_offset);
-        } else {
-            res = true;
-        }
-        eglDisplayCounter.put(eglDisplay, refCnt);
-        if(DEBUG) {
-            System.err.println("EGL.eglInitialize(0x"+Long.toHexString(eglDisplay)+" ...): #"+refCnt+" = "+res);
-        }
-        return res;
-    }
-    
     /**
-     * 
      * @param eglDisplay
      * @param major
      * @param minor
-     * @return true if the eglDisplay is valid and it's reference counter becomes one and {@link EGL#eglTerminate(long)} was successful, otherwise false
+     * @return true if the eglDisplay is valid and it's reference counter becomes one and {@link EGL#eglInitialize(long, IntBuffer, IntBuffer)} was successful, otherwise false
      * 
-     * @see EGL#eglInitialize(long, int[], int, int[], int)}
+     * @see EGL#eglInitialize(long, IntBuffer, IntBuffer)
      */
     public static synchronized boolean eglInitialize(long eglDisplay, IntBuffer major, IntBuffer minor)  {    
         if( EGL.EGL_NO_DISPLAY == eglDisplay) {
@@ -104,15 +114,70 @@ public class EGLDisplayUtil {
             res = EGL.eglInitialize(eglDisplay, major, minor);
         } else {
             res = true;
+        }        
+        if(res) { // map if successfully initialized, only  
+            eglDisplayCounter.put(eglDisplay, refCnt);
         }
-        eglDisplayCounter.put(eglDisplay, refCnt);
         if(DEBUG) {
-            System.err.println("EGL.eglInitialize(0x"+Long.toHexString(eglDisplay)+" ...): #"+refCnt+" = "+res);
+            System.err.println("EGLDisplayUtil.eglInitialize2("+EGLContext.toHexString(eglDisplay)+" ...): #"+refCnt+" = "+res);
+            // Thread.dumpStack();
         }
         return res;
     }
     
     /**
+     * @param nativeDisplayID
+     * @param eglDisplay array of size 1 holding return value if successful, otherwise {@link EGL#EGL_NO_DISPLAY}.
+     * @param eglErr array of size 1 holding the EGL error value as retrieved by {@link EGL#eglGetError()} if not successful.  
+     * @param major
+     * @param minor
+     * @return {@link EGL#EGL_SUCCESS} if successful, otherwise {@link EGL#EGL_BAD_DISPLAY} if {@link #eglGetDisplay(long)} failed 
+     *         or {@link EGL#EGL_NOT_INITIALIZED} if {@link #eglInitialize(long, IntBuffer, IntBuffer)} failed.
+     * 
+     * @see #eglGetDisplay(long)
+     * @see #eglInitialize(long, IntBuffer, IntBuffer)
+     */
+    public 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 );
+        if ( EGL.EGL_NO_DISPLAY == _eglDisplay ) {
+            eglErr[0] = EGL.eglGetError();
+            return EGL.EGL_BAD_DISPLAY;
+        }
+        if ( !EGLDisplayUtil.eglInitialize( _eglDisplay, major, minor) ) {
+            eglErr[0] = EGL.eglGetError();
+            return EGL.EGL_NOT_INITIALIZED;
+        }
+        eglDisplay[0] = _eglDisplay;
+        return EGL.EGL_SUCCESS;
+    }
+        
+    /**
+     * @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) {
+        final long[] eglDisplay = new long[1];
+        final int[] eglError = new int[1];
+        int eglRes = EGLDisplayUtil.eglGetDisplayAndInitialize(nativeDisplayID[0], eglDisplay, eglError, null, null);
+        if( EGL.EGL_SUCCESS == eglRes ) {
+            return eglDisplay[0];
+        }
+        if( EGL.EGL_DEFAULT_DISPLAY != nativeDisplayID[0] ) { // fallback to DEGAULT_DISPLAY
+            if(DEBUG) {
+                System.err.println("EGLDisplayUtil.eglGetAndInitDisplay failed with native "+EGLContext.toHexString(nativeDisplayID[0])+", error "+EGLContext.toHexString(eglRes)+"/"+EGLContext.toHexString(eglError[0])+" - fallback!");
+            }
+            eglRes = EGLDisplayUtil.eglGetDisplayAndInitialize(EGL.EGL_DEFAULT_DISPLAY, eglDisplay, eglError, null, null);
+            if( EGL.EGL_SUCCESS == eglRes ) {
+                nativeDisplayID[0] = EGL.EGL_DEFAULT_DISPLAY;
+                return eglDisplay[0];
+            }
+        }
+        throw new GLException("Failed to created/initialize EGL display incl. fallback default: native "+EGLContext.toHexString(nativeDisplayID[0])+", error "+EGLContext.toHexString(eglRes)+"/"+EGLContext.toHexString(eglError[0]));
+    }
+        
+    /**
      * @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
      */
@@ -124,28 +189,23 @@ public class EGLDisplayUtil {
         final int refCnt = eglDisplayCounter.get(eglDisplay) - 1; // 1 - 1 = 0 -> final terminate
         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
+                eglDisplayCounter.put(eglDisplay, refCnt);
+            } 
             res = true;
         }
-        if(0<=refCnt) { // no negative refCount
-            eglDisplayCounter.put(eglDisplay, refCnt);
-        }
         if(DEBUG) {
-            System.err.println("EGL.eglTerminate(0x"+Long.toHexString(eglDisplay)+" ...): #"+refCnt+" = "+res);
+            System.err.println("EGLDisplayUtil.eglTerminate("+EGLContext.toHexString(eglDisplay)+" ...): #"+refCnt+" = "+res);
+            // Thread.dumpStack();
         }
         return res;
     }
     
     public static final EGLGraphicsDevice.EGLDisplayLifecycleCallback eglLifecycleCallback = new EGLGraphicsDevice.EGLDisplayLifecycleCallback() {
-        public long eglGetAndInitDisplay(long nativeDisplayID) {
-            long eglDisplay = EGLDisplayUtil.eglGetDisplay(nativeDisplayID);
-            if (eglDisplay == EGL.EGL_NO_DISPLAY) {
-                throw new GLException("Failed to created EGL display: 0x"+Long.toHexString(nativeDisplayID)+", error 0x"+Integer.toHexString(EGL.eglGetError()));
-            }
-            if (!EGLDisplayUtil.eglInitialize(eglDisplay, null, null)) {
-                throw new GLException("eglInitialize failed"+", error 0x"+Integer.toHexString(EGL.eglGetError()));
-            }
-            return eglDisplay;
+        public long eglGetAndInitDisplay(long[] nativeDisplayID) {
+            return eglGetDisplayAndInitialize(nativeDisplayID);
         }
         public void eglTerminate(long eglDisplayHandle) {
             EGLDisplayUtil.eglTerminate(eglDisplayHandle);
@@ -161,39 +221,26 @@ public class EGLDisplayUtil {
      * @see EGLGraphicsDevice#EGLGraphicsDevice(long, long, String, int, com.jogamp.nativewindow.egl.EGLGraphicsDevice.EGLDisplayLifecycleCallback) 
      */
     public static EGLGraphicsDevice eglCreateEGLGraphicsDevice(long nativeDisplayID, String connection, int unitID)  {
-        final EGLGraphicsDevice eglDisplay = new EGLGraphicsDevice(nativeDisplayID, 0, connection, unitID, eglLifecycleCallback);
+        final EGLGraphicsDevice eglDisplay = new EGLGraphicsDevice(nativeDisplayID, EGL.EGL_NO_DISPLAY, connection, unitID, eglLifecycleCallback);
         eglDisplay.open();
         return eglDisplay;
     }
     
     /**
      * @param surface
-     * @param allowFallBackToDefault
      * @return an initialized EGLGraphicsDevice 
-     * @throws GLException if {@link EGL#eglGetDisplay(long)} or {@link EGL#eglInitialize(long, int[], int, int[], int)} fails 
+     * @throws GLException if {@link EGL#eglGetDisplay(long)} or {@link EGL#eglInitialize(long, int[], int, int[], int)} fails incl fallback 
      */
-    public static EGLGraphicsDevice eglCreateEGLGraphicsDevice(NativeSurface surface, boolean allowFallBackToDefault)  {
-        long nativeDisplayID;
-        if( NativeWindowFactory.TYPE_WINDOWS.equals(NativeWindowFactory.getNativeWindowType(false)) ) {
+    public static EGLGraphicsDevice eglCreateEGLGraphicsDevice(NativeSurface surface)  {
+        final long nativeDisplayID;
+        if( NativeWindowFactory.TYPE_WINDOWS == NativeWindowFactory.getNativeWindowType(false) ) {
             nativeDisplayID = surface.getSurfaceHandle(); // don't even ask ..
         } else {
             nativeDisplayID = surface.getDisplayHandle(); // 0 == EGL.EGL_DEFAULT_DISPLAY
         }
-        long eglDisplay = EGLDisplayUtil.eglGetDisplay(nativeDisplayID);
-        if (eglDisplay == EGL.EGL_NO_DISPLAY && nativeDisplayID != EGL.EGL_DEFAULT_DISPLAY && allowFallBackToDefault) {
-            if(DEBUG) {
-                System.err.println("EGLDisplayUtil.eglGetDisplay(): Fall back to EGL_DEFAULT_DISPLAY");
-            }
-            nativeDisplayID = EGL.EGL_DEFAULT_DISPLAY;
-            eglDisplay = EGLDisplayUtil.eglGetDisplay(nativeDisplayID);
-        }
-        if (eglDisplay == EGL.EGL_NO_DISPLAY) {
-            throw new GLException("Failed to created EGL display: "+surface+", error 0x"+Integer.toHexString(EGL.eglGetError()));
-        }
-        if (!EGLDisplayUtil.eglInitialize(eglDisplay, null, null)) {
-            throw new GLException("eglInitialize failed"+", error 0x"+Integer.toHexString(EGL.eglGetError()));
-        }
         final AbstractGraphicsDevice adevice = surface.getGraphicsConfiguration().getScreen().getDevice();
-        return new EGLGraphicsDevice(nativeDisplayID, eglDisplay, adevice.getConnection(), adevice.getUnitID(), eglLifecycleCallback);                                            
+        final EGLGraphicsDevice eglDevice = new EGLGraphicsDevice(nativeDisplayID, EGL.EGL_NO_DISPLAY, adevice.getConnection(), adevice.getUnitID(), eglLifecycleCallback);
+        eglDevice.open();
+        return eglDevice;
     }
 }
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
index 383b61f..167eebf 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
@@ -36,7 +36,8 @@
 
 package jogamp.opengl.egl;
 
-import javax.media.nativewindow.MutableSurface;
+import java.nio.IntBuffer;
+
 import javax.media.nativewindow.NativeSurface;
 import javax.media.nativewindow.NativeWindow;
 import javax.media.nativewindow.ProxySurface;
@@ -46,10 +47,10 @@ import javax.media.opengl.GLException;
 import jogamp.opengl.GLDrawableImpl;
 import jogamp.opengl.GLDynamicLookupHelper;
 
+import com.jogamp.common.nio.Buffers;
 import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
 
 public abstract class EGLDrawable extends GLDrawableImpl {
-    private boolean ownEGLSurface = false; // for destruction
 
     protected EGLDrawable(EGLDrawableFactory factory, NativeSurface component) throws GLException {
         super(factory, component, false);
@@ -58,21 +59,14 @@ public abstract class EGLDrawable extends GLDrawableImpl {
     @Override
     public abstract GLContext createContext(GLContext shareWith);
 
-    protected abstract long createSurface(EGLGraphicsConfiguration config, long nativeSurfaceHandle);
+    protected abstract long createSurface(EGLGraphicsConfiguration config, int width, int height, long nativeSurfaceHandle);    
 
-    private final void recreateSurface() {
-        final EGLGraphicsConfiguration eglConfig = (EGLGraphicsConfiguration) surface.getGraphicsConfiguration();
-        final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) eglConfig.getScreen().getDevice();
-        if(DEBUG) {
-            System.err.println(getThreadName() + ": createSurface using "+eglConfig);
-        }        
-        if( EGL.EGL_NO_SURFACE != surface.getSurfaceHandle() ) {
-            EGL.eglDestroySurface(eglDevice.getHandle(), surface.getSurfaceHandle());
-        }
+    private final long createEGLSurface() {
+        final EGLWrappedSurface eglws = (EGLWrappedSurface) surface;
+        final EGLGraphicsConfiguration eglConfig = (EGLGraphicsConfiguration) eglws.getGraphicsConfiguration();        
+        final NativeSurface upstreamSurface = eglws.getUpstreamSurface();
         
-        final EGLUpstreamSurfaceHook upstreamHook = (EGLUpstreamSurfaceHook) ((ProxySurface)surface).getUpstreamSurfaceHook();
-        final NativeSurface upstreamSurface = upstreamHook.getUpstreamSurface();
-        long eglSurface = createSurface(eglConfig, upstreamSurface.getSurfaceHandle());
+        long eglSurface = createSurface(eglConfig, eglws.getWidth(), eglws.getHeight(), upstreamSurface.getSurfaceHandle());
         
         int eglError0;
         if (EGL.EGL_NO_SURFACE == eglSurface) {
@@ -86,7 +80,7 @@ public abstract class EGLDrawable extends GLDrawableImpl {
                         if(DEBUG) {
                             System.err.println(getThreadName() + ": Info: Creation of window surface w/ surface handle failed: "+eglConfig+", error "+toHexString(eglError0)+", retry w/ windowHandle");
                         }
-                        eglSurface = createSurface(eglConfig, nw.getWindowHandle());
+                        eglSurface = createSurface(eglConfig, eglws.getWidth(), eglws.getHeight(), nw.getWindowHandle());
                         if (EGL.EGL_NO_SURFACE == eglSurface) {
                             eglError0 = EGL.eglGetError();
                         }
@@ -99,85 +93,73 @@ public abstract class EGLDrawable extends GLDrawableImpl {
         if (EGL.EGL_NO_SURFACE == eglSurface) {
             throw new GLException("Creation of window surface failed: "+eglConfig+", "+surface+", error "+toHexString(eglError0));
         }
-
         if(DEBUG) {
-            System.err.println(getThreadName() + ": setSurface using component: handle "+toHexString(surface.getSurfaceHandle())+" -> "+toHexString(eglSurface));
+            System.err.println(getThreadName() + ": createEGLSurface handle "+toHexString(eglSurface));
         }
-        
-        ((MutableSurface)surface).setSurfaceHandle(eglSurface);
+        return eglSurface;
     }
 
     @Override
     protected final void updateHandle() {
-        if(ownEGLSurface) {
-            recreateSurface();
+        final EGLWrappedSurface eglws = (EGLWrappedSurface) surface;
+        if(DEBUG) {
+            System.err.println(getThreadName() + ": updateHandle of "+eglws);
+        }        
+        if( eglws.containsUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE ) ) {
+            if( EGL.EGL_NO_SURFACE != eglws.getSurfaceHandle() ) {
+                throw new InternalError("Set surface but claimed to be invalid: "+eglws);
+            }
+            eglws.setSurfaceHandle( createEGLSurface() );
+        } else if( EGL.EGL_NO_SURFACE == eglws.getSurfaceHandle() ) {
+            throw new InternalError("Nil surface but claimed to be valid: "+eglws);
+        }
+    }
+    
+    protected void destroyHandle() {    
+        final EGLWrappedSurface eglws = (EGLWrappedSurface) surface;
+        if(DEBUG) {
+            System.err.println(getThreadName() + ": destroyHandle of "+eglws);
+        }        
+        if( EGL.EGL_NO_SURFACE == eglws.getSurfaceHandle() ) {
+            throw new InternalError("Nil surface but claimed to be valid: "+eglws);
+        }
+        final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) eglws.getGraphicsConfiguration().getScreen().getDevice();
+        if( eglws.containsUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE ) ) {
+            EGL.eglDestroySurface(eglDevice.getHandle(), eglws.getSurfaceHandle());
+            eglws.setSurfaceHandle(EGL.EGL_NO_SURFACE);
         }
     }
 
-    @Override
-    protected final void setRealizedImpl() {
-        final EGLGraphicsConfiguration eglConfig = (EGLGraphicsConfiguration) surface.getGraphicsConfiguration();
-        final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) eglConfig.getScreen().getDevice();
-        if (realized) {
-            final long eglDisplayHandle = eglDevice.getHandle();
-            if (EGL.EGL_NO_DISPLAY == eglDisplayHandle) {
-                throw new GLException("Invalid EGL display in EGLGraphicsDevice "+eglDevice);
-            }
-            int[] tmp = new int[1];
-            boolean eglSurfaceValid = 0 != surface.getSurfaceHandle();
-            if(eglSurfaceValid) {
-                eglSurfaceValid = EGL.eglQuerySurface(eglDisplayHandle, surface.getSurfaceHandle(), EGL.EGL_CONFIG_ID, tmp, 0);
-                if(!eglSurfaceValid) {
-                    if(DEBUG) {
-                        System.err.println(getThreadName() + ": EGLDrawable.setRealizedImpl eglQuerySuface failed: "+toHexString(EGL.eglGetError())+", "+surface);
-                    }                    
-                }
-            }
-            if(eglSurfaceValid) {
-                // surface holds valid EGLSurface
-                if(DEBUG) {
-                    System.err.println(getThreadName() + ": EGLDrawable.setRealizedImpl re-using component's EGLSurface: handle "+toHexString(surface.getSurfaceHandle()));
-                }
-                ownEGLSurface=false;
-            } else {
-                // EGLSurface is ours - subsequent updateHandle() will issue recreateSurface();
-                // However .. let's validate the surface object first
-                if( ! (surface instanceof ProxySurface) ) {
-                    throw new InternalError("surface not ProxySurface: "+surface.getClass().getName()+", "+surface);
-                }
-                final ProxySurface.UpstreamSurfaceHook upstreamHook = ((ProxySurface)surface).getUpstreamSurfaceHook();
-                if( null == upstreamHook ) {
-                    throw new InternalError("null upstreamHook of: "+surface);
-                }
-                if( ! (upstreamHook instanceof EGLUpstreamSurfaceHook) ) {
-                    throw new InternalError("upstreamHook not EGLUpstreamSurfaceHook: Surface: "+surface.getClass().getName()+", "+surface+"; UpstreamHook: "+upstreamHook.getClass().getName()+", "+upstreamHook);
-                }
-                if( null == ((EGLUpstreamSurfaceHook)upstreamHook).getUpstreamSurface() ) {
-                    throw new InternalError("null upstream surface");
-                }
-                ownEGLSurface=true;
-                if(DEBUG) {
-                    System.err.println(getThreadName() + ": EGLDrawable.setRealizedImpl owning EGLSurface");
-                }
-            }
-        } else if (ownEGLSurface && surface.getSurfaceHandle() != EGL.EGL_NO_SURFACE) {
+    protected static boolean isValidEGLSurface(long eglDisplayHandle, long surfaceHandle) {
+        if( 0 == surfaceHandle ) {
+            return false;
+        }
+        final IntBuffer val = Buffers.newDirectIntBuffer(1);        
+        final boolean eglSurfaceValid = EGL.eglQuerySurface(eglDisplayHandle, surfaceHandle, EGL.EGL_CONFIG_ID, val);
+        if( !eglSurfaceValid ) {
+            final int eglErr = EGL.eglGetError();
             if(DEBUG) {
-                System.err.println(getThreadName() + ": EGLDrawable.setRealized(false): ownSurface "+ownEGLSurface+", "+eglDevice+", eglSurface: "+toHexString(surface.getSurfaceHandle()));
-            }
-            // Destroy the window surface
-            if (!EGL.eglDestroySurface(eglDevice.getHandle(), surface.getSurfaceHandle())) {
-                throw new GLException("Error destroying window surface (eglDestroySurface)");
+                System.err.println(getThreadName() + ": EGLDrawable.isValidEGLSurface eglQuerySuface failed: error "+toHexString(eglErr)+", "+toHexString(surfaceHandle));
             }
-            ((MutableSurface)surface).setSurfaceHandle(EGL.EGL_NO_SURFACE);
+        }
+        return eglSurfaceValid;
+    }
+    
+    @Override
+    protected final void setRealizedImpl() {
+        if(DEBUG) {
+            System.err.println(getThreadName() + ": EGLDrawable.setRealized("+realized+"): NOP - "+surface);
         }
     }
 
     @Override
-    protected final void swapBuffersImpl() {
-        final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) surface.getGraphicsConfiguration().getScreen().getDevice();
-        // single-buffer is already filtered out @ GLDrawableImpl#swapBuffers()
-        if(!EGL.eglSwapBuffers(eglDevice.getHandle(), surface.getSurfaceHandle())) {
-            throw new GLException("Error swapping buffers, eglError "+toHexString(EGL.eglGetError())+", "+this);
+    protected final void swapBuffersImpl(boolean doubleBuffered) {
+        if(doubleBuffered) {
+            final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) surface.getGraphicsConfiguration().getScreen().getDevice();
+            // single-buffer is already filtered out @ GLDrawableImpl#swapBuffers()
+            if(!EGL.eglSwapBuffers(eglDevice.getHandle(), surface.getSurfaceHandle())) {
+                throw new GLException("Error swapping buffers, eglError "+toHexString(EGL.eglGetError())+", "+this);
+            }
         }
     }
 
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
index c848e3e..ad305ab 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
@@ -36,11 +36,14 @@
 
 package jogamp.opengl.egl;
 
+import java.nio.IntBuffer;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Set;
 
 import javax.media.nativewindow.AbstractGraphicsConfiguration;
 import javax.media.nativewindow.AbstractGraphicsDevice;
@@ -50,8 +53,7 @@ import javax.media.nativewindow.MutableSurface;
 import javax.media.nativewindow.NativeSurface;
 import javax.media.nativewindow.NativeWindowFactory;
 import javax.media.nativewindow.ProxySurface;
-import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook;
-import javax.media.nativewindow.VisualIDHolder.VIDType;
+import javax.media.nativewindow.UpstreamSurfaceHook;
 import javax.media.nativewindow.VisualIDHolder;
 import javax.media.opengl.GL;
 import javax.media.opengl.GLCapabilities;
@@ -62,8 +64,8 @@ import javax.media.opengl.GLDrawable;
 import javax.media.opengl.GLDrawableFactory;
 import javax.media.opengl.GLException;
 import javax.media.opengl.GLProfile;
-import javax.media.opengl.GLProfile.ShutdownType;
 
+import jogamp.nativewindow.WrappedSurface;
 import jogamp.opengl.Debug;
 import jogamp.opengl.GLDrawableFactoryImpl;
 import jogamp.opengl.GLDrawableImpl;
@@ -71,18 +73,20 @@ import jogamp.opengl.GLDynamicLookupHelper;
 import jogamp.opengl.GLGraphicsConfigurationUtil;
 
 import com.jogamp.common.JogampRuntimeException;
+import com.jogamp.common.nio.Buffers;
+import com.jogamp.common.nio.PointerBuffer;
 import com.jogamp.common.os.Platform;
 import com.jogamp.common.util.ReflectionUtil;
-import com.jogamp.nativewindow.WrappedSurface;
 import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
+import com.jogamp.opengl.GLRendererQuirks;
 
 public class EGLDrawableFactory extends GLDrawableFactoryImpl {
-    /* package */ static final boolean QUERY_EGL_ES = !Debug.isPropertyDefined("jogl.debug.EGLDrawableFactory.DontQuery", true);
+    protected static final boolean DEBUG = GLDrawableFactoryImpl.DEBUG; // allow package access
+    
     /* package */ static final boolean QUERY_EGL_ES_NATIVE_TK = Debug.isPropertyDefined("jogl.debug.EGLDrawableFactory.QueryNativeTK", true);
     
     private static GLDynamicLookupHelper eglES1DynamicLookupHelper = null;
     private static GLDynamicLookupHelper eglES2DynamicLookupHelper = null;
-    private static boolean isANGLE = false;
 
     private static final boolean isANGLE(GLDynamicLookupHelper dl) {
         if(Platform.OSType.WINDOWS == Platform.OS_TYPE) {
@@ -95,6 +99,12 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
         }
     }
 
+    private static final boolean includesES1(GLDynamicLookupHelper dl) {
+        return 0 != dl.dynamicLookupFunction("glLoadIdentity") &&
+               0 != dl.dynamicLookupFunction("glEnableClientState") &&
+               0 != dl.dynamicLookupFunction("glColorPointer");
+    }
+    
     public EGLDrawableFactory() {
         super();
 
@@ -103,42 +113,17 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
         EGLGraphicsConfigurationFactory.registerFactory();
 
         // Check for other underlying stuff ..
-        if(NativeWindowFactory.TYPE_X11.equals(NativeWindowFactory.getNativeWindowType(true))) {
+        if(NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(true)) {
             try {
                 ReflectionUtil.createInstance("jogamp.opengl.x11.glx.X11GLXGraphicsConfigurationFactory", EGLDrawableFactory.class.getClassLoader());
             } catch (JogampRuntimeException jre) { /* n/a .. */ }
         }
 
-        defaultDevice = new EGLGraphicsDevice(AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
-
         // FIXME: Probably need to move EGL from a static model
         // to a dynamic one, where there can be 2 instances
         // for each ES profile with their own ProcAddressTable.
 
         synchronized(EGLDrawableFactory.class) {
-            /**
-             * Currently AMD's EGL impl. crashes at eglGetDisplay(EGL_DEFAULT_DISPLAY)
-             *
-            // Check Desktop ES2 Availability first (AMD, ..)
-            if(null==eglES2DynamicLookupHelper) {
-                GLDynamicLookupHelper tmp=null;
-                try {
-                    tmp = new GLDynamicLookupHelper(new DesktopES2DynamicLibraryBundleInfo());
-                } catch (GLException gle) {
-                    if(DEBUG) {
-                        gle.printStackTrace();
-                    }
-                }
-                if(null!=tmp && tmp.isLibComplete()) {
-                    eglES2DynamicLookupHelper = tmp;
-                    EGL.resetProcAddressTable(eglES2DynamicLookupHelper);
-                    if (GLProfile.DEBUG) {
-                        System.err.println("Info: EGLDrawableFactory: Desktop ES2 - OK");
-                    }
-                } else if (GLProfile.DEBUG) {
-                    System.err.println("Info: EGLDrawableFactory: Desktop ES2 - NOPE");
-                }
-            } */
             final boolean hasDesktopES2 = null != eglES2DynamicLookupHelper;
 
             if(!hasDesktopES2 && null==eglES1DynamicLookupHelper) {
@@ -155,11 +140,11 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
                     EGL.resetProcAddressTable(eglES1DynamicLookupHelper);
                     final boolean isANGLEES1 = isANGLE(eglES1DynamicLookupHelper);
                     isANGLE |= isANGLEES1;
-                    if (GLProfile.DEBUG) {
+                    if (DEBUG || GLProfile.DEBUG) {
                         System.err.println("Info: EGLDrawableFactory: EGL ES1 - OK, isANGLE: "+isANGLEES1);
                     }
-                } else if (GLProfile.DEBUG) {
-                    System.err.println("Info: EGLDrawableFactory: EGL ES1 - NOPE");
+                } else if (DEBUG || GLProfile.DEBUG) {
+                    System.err.println("Info: EGLDrawableFactory: EGL ES1 - NOPE (ES1 lib)");
                 }
             }
             if(!hasDesktopES2 && null==eglES2DynamicLookupHelper) {
@@ -174,75 +159,150 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
                 if(null!=tmp && tmp.isLibComplete()) {
                     eglES2DynamicLookupHelper = tmp;
                     EGL.resetProcAddressTable(eglES2DynamicLookupHelper);
+                    final boolean includesES1 = null == eglES1DynamicLookupHelper && includesES1(eglES2DynamicLookupHelper);
+                    if(includesES1) {
+                        eglES1DynamicLookupHelper = tmp;
+                    }
                     final boolean isANGLEES2 = isANGLE(eglES2DynamicLookupHelper);
                     isANGLE |= isANGLEES2;
-                    if (GLProfile.DEBUG) {
-                        System.err.println("Info: EGLDrawableFactory: EGL ES2 - OK, isANGLE: "+isANGLEES2);
+                    if (DEBUG || GLProfile.DEBUG) {
+                        System.err.println("Info: EGLDrawableFactory: EGL ES2 - OK (includesES1 "+includesES1+", isANGLE: "+isANGLEES2+")");
+                        if(includesES1) {
+                            System.err.println("Info: EGLDrawableFactory: EGL ES1 - OK (ES2 lib)");
+                        }
                     }
-                } else if (GLProfile.DEBUG) {
+                } else if (DEBUG || GLProfile.DEBUG) {
                     System.err.println("Info: EGLDrawableFactory: EGL ES2 - NOPE");
                 }
             }
+            if( null != eglES2DynamicLookupHelper || null != eglES1DynamicLookupHelper ) {
+                if(isANGLE && !enableANGLE) {
+                    if(DEBUG || GLProfile.DEBUG) {
+                        System.err.println("Info: EGLDrawableFactory.init - EGL/ES2 ANGLE disabled");
+                    }
+                } else {
+                    if( isANGLE && ( DEBUG || GLProfile.DEBUG ) ) {
+                        System.err.println("Info: EGLDrawableFactory.init - EGL/ES2 ANGLE enabled");
+                    }                    
+                    sharedMap = new HashMap<String /*uniqueKey*/, SharedResource>();
+                    sharedMapCreateAttempt = new HashSet<String>();
+                    
+                    // FIXME: Following triggers eglInitialize(..) which crashed on Windows w/ Chrome/Angle, FF/Angle!
+                    defaultDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
+                }
+            }
         }
     }
 
     @Override
-    protected final void destroy(ShutdownType shutdownType) {
+    protected final boolean isComplete() {
+        return null != sharedMap; // null != eglES2DynamicLookupHelper || null != eglES1DynamicLookupHelper;
+    }
+  
+    
+    @Override
+    protected final void destroy() {
         if(null != sharedMap) {
+            if(DEBUG) {
+                System.err.println("EGLDrawableFactory.destroy() .. ");
+                dumpMap();
+            }
             Collection<SharedResource> srl = sharedMap.values();
             for(Iterator<SharedResource> sri = srl.iterator(); sri.hasNext(); ) {
                 SharedResource sr = sri.next();
                 if(DEBUG) {
-                    System.err.println("EGLDrawableFactory.destroy("+shutdownType+"): "+sr.device.toString());
+                    System.err.println("EGLDrawableFactory.destroy(): "+sr.device.toString());
                 }
                 sr.device.close();
             }
             sharedMap.clear();
+            sharedMapCreateAttempt.clear();
             sharedMap = null;
+            sharedMapCreateAttempt = null;
+        }
+        if(null != defaultSharedResource) {
+            defaultSharedResource = null;
+        }
+        if(null != defaultDevice) {
+            defaultDevice.close();
+            defaultDevice = null;
         }
-        defaultDevice = null;
         /**
          * Pulling away the native library may cause havoc ..
          */
-        if(ShutdownType.COMPLETE == shutdownType) {
-            if(null != eglES1DynamicLookupHelper) {
-                // eglES1DynamicLookupHelper.destroy();
-                eglES1DynamicLookupHelper = null;
-            }
-            if(null != eglES2DynamicLookupHelper) {
-                // eglES2DynamicLookupHelper.destroy();
-                eglES2DynamicLookupHelper = null;
-            }
+        if(null != eglES1DynamicLookupHelper) {
+            // eglES1DynamicLookupHelper.destroy();
+            eglES1DynamicLookupHelper = null;
+        }
+        if(null != eglES2DynamicLookupHelper) {
+            // eglES2DynamicLookupHelper.destroy();
+            eglES2DynamicLookupHelper = null;
         }
         EGLGraphicsConfigurationFactory.unregisterFactory();
+        EGLDisplayUtil.shutdown(DEBUG);
+    }
+    
+    private void dumpMap() {
+        synchronized(sharedMap) {
+            System.err.println("EGLDrawableFactory.map "+sharedMap.size());
+            int i=0;
+            Set<String> keys = sharedMap.keySet();
+            for(Iterator<String> keyI = keys.iterator(); keyI.hasNext(); i++) {
+                String key = keyI.next();
+                SharedResource sr = sharedMap.get(key);
+                System.err.println("EGLDrawableFactory.map["+i+"] "+key+" -> "+sr.getDevice()+", "+
+                                   "es1 [avail "+sr.wasES1ContextAvailable()+", pbuffer "+sr.hasES1PBuffer()+", quirks "+sr.getGLRendererQuirksES1()+", ctp "+EGLContext.getGLVersion(1, 0, sr.getCtpES1(), null)+"], "+
+                                   "es2 [avail "+sr.wasES2ContextAvailable()+", pbuffer "+sr.hasES2PBuffer()+", quirks "+sr.getGLRendererQuirksES1()+", ctp "+EGLContext.getGLVersion(2, 0, sr.getCtpES2(), null)+"]");
+            }
+            ;
+        }
     }
 
-    private HashMap<String /*connection*/, SharedResource> sharedMap = new HashMap<String /*connection*/, SharedResource>();
-    private EGLGraphicsDevice defaultDevice;
+    private HashMap<String /*uniqueKey*/, SharedResource> sharedMap = null;
+    private HashSet<String> sharedMapCreateAttempt = null;    
+    private EGLGraphicsDevice defaultDevice = null;
+    private SharedResource defaultSharedResource = null;
+    private boolean isANGLE = false;
 
     static class SharedResource {
       private final EGLGraphicsDevice device;
-      // private final EGLDrawable drawable;
       // private final EGLContext contextES1;
       // private final EGLContext contextES2;
+      private final GLRendererQuirks rendererQuirksES1;
+      private final GLRendererQuirks rendererQuirksES2;
+      private final int ctpES1;
+      private final int ctpES2;
       private final boolean wasES1ContextCreated;
       private final boolean wasES2ContextCreated;
+      private final boolean hasPBufferES1;
+      private final boolean hasPBufferES2;
 
-      SharedResource(EGLGraphicsDevice dev, boolean wasContextES1Created, boolean wasContextES2Created
-                     /*EGLDrawable draw, EGLContext ctxES1, EGLContext ctxES2 */) {
+      SharedResource(EGLGraphicsDevice dev, 
+                     boolean wasContextES1Created, boolean hasPBufferES1, GLRendererQuirks rendererQuirksES1, int ctpES1,  
+                     boolean wasContextES2Created, boolean hasPBufferES2, GLRendererQuirks rendererQuirksES2, int ctpES2) {
           this.device = dev;
-          // this.drawable = draw;
           // this.contextES1 = ctxES1;
           // this.contextES2 = ctxES2;
+          this.rendererQuirksES1 = rendererQuirksES1;
+          this.rendererQuirksES2 = rendererQuirksES2;
+          this.ctpES1 = ctpES1;
+          this.ctpES2 = ctpES2;
           this.wasES1ContextCreated = wasContextES1Created;
           this.wasES2ContextCreated = wasContextES2Created;
+          this.hasPBufferES1= hasPBufferES1;
+          this.hasPBufferES2= hasPBufferES2;
       }
       final EGLGraphicsDevice getDevice() { return device; }
-      // final EGLDrawable getDrawable() { return drawable; }
       // final EGLContext getContextES1() { return contextES1; }
       // final EGLContext getContextES2() { return contextES2; }
+      final GLRendererQuirks getGLRendererQuirksES1() { return rendererQuirksES1; }
+      final GLRendererQuirks getGLRendererQuirksES2() { return rendererQuirksES2; }
+      final int getCtpES1() { return ctpES1; }
+      final int getCtpES2() { return ctpES2; }
       final boolean wasES1ContextAvailable() { return wasES1ContextCreated; }
-      final boolean wasES2ContextAvailable() { return wasES2ContextCreated; }      
+      final boolean wasES2ContextAvailable() { return wasES2ContextCreated; }
+      final boolean hasES1PBuffer() { return hasPBufferES1; }
+      final boolean hasES2PBuffer() { return hasPBufferES2; }
     }
 
     @Override
@@ -253,72 +313,148 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
     @Override
     public final boolean getIsDeviceCompatible(AbstractGraphicsDevice device) {
       // via mappings (X11/WGL/.. -> EGL) we shall be able to handle all types.
-      return null!=eglES2DynamicLookupHelper || null!=eglES1DynamicLookupHelper;
+      return null != sharedMap ; // null!=eglES2DynamicLookupHelper || null!=eglES1DynamicLookupHelper;
     }
 
-    private boolean isEGLContextAvailable(AbstractGraphicsDevice adevice, EGLGraphicsDevice sharedEGLDevice, String profileString) {
-        if( !GLProfile.isAvailable(adevice, profileString) ) {
+    private static List<GLCapabilitiesImmutable> getAvailableEGLConfigs(EGLGraphicsDevice eglDisplay, GLCapabilitiesImmutable caps) {
+        final IntBuffer numConfigs = Buffers.newDirectIntBuffer(1);
+        if(!EGL.eglGetConfigs(eglDisplay.getHandle(), null, 0, numConfigs)) {
+            throw new GLException("EGLDrawableFactory.getAvailableEGLConfigs: Get maxConfigs (eglGetConfigs) call failed, error "+EGLContext.toHexString(EGL.eglGetError()));
+        }
+        if(0 < numConfigs.get(0)) {
+            final PointerBuffer configs = PointerBuffer.allocateDirect(numConfigs.get(0));
+            final IntBuffer attrs = EGLGraphicsConfiguration.GLCapabilities2AttribList(caps);
+            final int winattrmask = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(caps);
+            if( EGL.eglChooseConfig(eglDisplay.getHandle(), attrs, configs, configs.capacity(), numConfigs) && numConfigs.get(0) > 0) {
+                return EGLGraphicsConfigurationFactory.eglConfigs2GLCaps(eglDisplay, caps.getGLProfile(), configs, numConfigs.get(0), winattrmask, false /* forceTransparentFlag */);
+            }
+        }
+        return new ArrayList<GLCapabilitiesImmutable>(0);
+    }
+    
+    private boolean mapAvailableEGLESConfig(AbstractGraphicsDevice adevice, int esProfile, 
+                                            boolean[] hasPBuffer, GLRendererQuirks[] rendererQuirks, int[] ctp) {
+        final String profileString;
+        switch( esProfile ) {
+            case 1: 
+                profileString = GLProfile.GLES1; break;
+            case 2: 
+            default: 
+                profileString = GLProfile.GLES2; break; 
+        }
+        if ( !GLProfile.isAvailable(adevice, profileString) ) {
             return false;
         }
         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 ;
+
         EGLGraphicsDevice eglDevice = null;
         NativeSurface surface = null;
         ProxySurface upstreamSurface = null; // X11, GLX, ..
         boolean success = false;
         boolean deviceFromUpstreamSurface = false;
         try {            
-            final GLCapabilities caps = new GLCapabilities(glp);
-            caps.setRedBits(5); caps.setGreenBits(5); caps.setBlueBits(5); caps.setAlphaBits(0);
-            if(adevice instanceof EGLGraphicsDevice || null == desktopFactory || !QUERY_EGL_ES_NATIVE_TK) {
-                eglDevice = sharedEGLDevice; // reuse
-                surface = createDummySurfaceImpl(eglDevice, false, caps, null, 64, 64); // egl pbuffer offscreen
-                upstreamSurface = (ProxySurface)surface;
-                upstreamSurface.createNotify();
-                deviceFromUpstreamSurface = false;
+            final GLCapabilities reqCapsAny = new GLCapabilities(glp);
+            reqCapsAny.setRedBits(5); reqCapsAny.setGreenBits(5); reqCapsAny.setBlueBits(5); reqCapsAny.setAlphaBits(0);
+            reqCapsAny.setDoubleBuffered(false);
+            
+            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. 
+                final GLCapabilitiesImmutable reqCapsPBuffer = GLGraphicsConfigurationUtil.fixGLPBufferGLCapabilities(reqCapsAny);
+                final List<GLCapabilitiesImmutable> availablePBufferCapsL = getAvailableEGLConfigs(defaultDevice, reqCapsPBuffer);
+                hasPBuffer[0] = availablePBufferCapsL.size() > 0;
+                
+                // 1st case: adevice is not the EGL default device, map default shared resources
+                if( adevice != defaultDevice ) {
+                    if(null == defaultSharedResource) {
+                        return false;
+                    }
+                    switch(esProfile) {
+                        case 1: 
+                            rendererQuirks[0] = defaultSharedResource.rendererQuirksES1;
+                            ctp[0] = defaultSharedResource.ctpES1;
+                            break;
+                        case 2: 
+                            rendererQuirks[0] = defaultSharedResource.rendererQuirksES2;
+                            ctp[0] = defaultSharedResource.ctpES2;
+                            break;
+                    }
+                    EGLContext.mapStaticGLVersion(adevice, esProfile, 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;
+                } else {
+                    // 3rd case fake creation of defaultDevice shared resource, no pbuffer available
+                    final List<GLCapabilitiesImmutable> capsAnyL = getAvailableEGLConfigs(eglDevice, reqCapsAny);
+                    if(capsAnyL.size() > 0) {
+                        final GLCapabilitiesImmutable chosenCaps = capsAnyL.get(0);
+                        EGLContext.mapStaticGLESVersion(eglDevice, chosenCaps);
+                        success = true;
+                    }
+                    if(DEBUG) {
+                        System.err.println("EGLDrawableFactory.isEGLContextAvailable() no pbuffer config available, detected !pbuffer config: "+success);
+                        EGLGraphicsConfigurationFactory.printCaps("!PBufferCaps", capsAnyL, System.err);
+                    }                    
+                }                
             } else {
-                surface = desktopFactory.createDummySurface(adevice, caps, null, 64, 64); // X11, WGL, .. dummy window
+                // 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 ;
                 if(null != upstreamSurface) {
                     upstreamSurface.createNotify();
                 }                    
-                eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(surface, true);
+                eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(surface);
                 deviceFromUpstreamSurface = true;
+                hasPBuffer[0] = true;
             }
-            
-            final EGLDrawable drawable = (EGLDrawable) createOnscreenDrawableImpl ( surface );
-            drawable.setRealized(true);
-            final EGLContext context = (EGLContext) drawable.createContext(null);
-            if (null != context) {
-                try {
-                    context.makeCurrent(); // could cause exception
-                    success = context.isCurrent();
-                    if(success) {
-                        final String glVersion = context.getGL().glGetString(GL.GL_VERSION);
-                        if(null == glVersion) {
-                            // Oops .. something is wrong
-                            if(DEBUG) {
-                                System.err.println("EGLDrawableFactory.isEGLContextAvailable: "+eglDevice+", "+context.getGLVersion()+" - VERSION is null, dropping availability!");                                
+
+            if(null != surface) {
+                final EGLDrawable drawable = (EGLDrawable) createOnscreenDrawableImpl ( surface ); // works w/ implicit pbuffer surface via proxy-hook
+                drawable.setRealized(true);
+                final EGLContext context = (EGLContext) drawable.createContext(null);
+                if (null != context) {
+                    try {
+                        context.makeCurrent(); // could cause exception
+                        if(context.isCurrent()) {
+                            final String glVersion = context.getGL().glGetString(GL.GL_VERSION);
+                            if(null != glVersion) {                                
+                                context.mapCurrentAvailableGLVersion(eglDevice);
+                                if(eglDevice != adevice) {
+                                    context.mapCurrentAvailableGLVersion(adevice);
+                                }
+                                rendererQuirks[0] = context.getRendererQuirks();
+                                ctp[0] = context.getContextOptions();
+                                success = true;
+                            } else {
+                                // Oops .. something is wrong
+                                if(DEBUG) {
+                                    System.err.println("EGLDrawableFactory.isEGLContextAvailable: "+eglDevice+", "+context.getGLVersion()+" - VERSION is null, dropping availability!");                                
+                                }
                             }
-                            success = false;
                         }
-                    }
-                    if(success) {
-                        context.mapCurrentAvailableGLVersion(eglDevice);
-                        if(eglDevice != adevice) {
-                            context.mapCurrentAvailableGLVersion(adevice);
+                    } catch (GLException gle) {
+                        if (DEBUG) {
+                            System.err.println("EGLDrawableFactory.createShared: INFO: context create/makeCurrent failed");
+                            gle.printStackTrace();
                         }
+                    } finally {
+                        context.destroy();
                     }
-                } catch (GLException gle) {
-                    if (DEBUG) {
-                        System.err.println("EGLDrawableFactory.createShared: INFO: context create/makeCurrent failed");
-                        gle.printStackTrace();
-                    }
-                } finally {
-                    context.destroy();
                 }
+                drawable.setRealized(false);
             }
-            drawable.setRealized(false);
         } catch (Throwable t) {
             if(DEBUG) {
                 System.err.println("Catched Exception:");
@@ -326,7 +462,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
             }
             success = false;
         } finally {
-            if(eglDevice == sharedEGLDevice) {
+            if(eglDevice == defaultDevice) {
                 if(null != upstreamSurface) {
                     upstreamSurface.destroyNotify();
                 }                
@@ -349,54 +485,101 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
         return success;
     }
 
-    /* package */ SharedResource getOrCreateEGLSharedResource(AbstractGraphicsDevice adevice) {
-        if(null == eglES1DynamicLookupHelper && null == eglES2DynamicLookupHelper) {
-            return null;
-        }
-        final String connection = adevice.getConnection();
-        SharedResource sr;
+    private final boolean needsToCreateSharedResource(String key, SharedResource[] existing) {
         synchronized(sharedMap) {
-            sr = sharedMap.get(connection);
-        }
-        if(null==sr) {
-            final boolean madeCurrentES1;            
-            final boolean madeCurrentES2;
-            final EGLGraphicsDevice sharedDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
-            
-            if(QUERY_EGL_ES) {
-                madeCurrentES1 = isEGLContextAvailable(adevice, sharedDevice, GLProfile.GLES1);
-                madeCurrentES2 = isEGLContextAvailable(adevice, sharedDevice, GLProfile.GLES2);                
-            } else {            
-                madeCurrentES1 = true;            
-                madeCurrentES2 = true;
-                EGLContext.mapStaticGLESVersion(sharedDevice, 1);
-                if(sharedDevice != adevice) {
-                    EGLContext.mapStaticGLESVersion(adevice, 1);
+            final SharedResource sr = sharedMap.get(key);
+            if( null == sr ) {
+                final boolean createAttempted = sharedMapCreateAttempt.contains(key);
+                if(!createAttempted) {
+                    sharedMapCreateAttempt.add(key);
                 }
-                EGLContext.mapStaticGLESVersion(sharedDevice, 2);
-                if(sharedDevice != adevice) {
-                    EGLContext.mapStaticGLESVersion(adevice, 2);
+                return !createAttempted;
+            } else {
+                if(null != existing) {
+                    existing[0] = sr;
                 }
+                return false;
             }
-            
-            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. 
-                EGLContext.setAvailableGLVersionsSet(adevice);
+        }        
+    }
+    
+    /* package */ SharedResource getOrCreateEGLSharedResource(AbstractGraphicsDevice adevice) {
+        if(null == sharedMap) { // null == eglES1DynamicLookupHelper && null == eglES2DynamicLookupHelper
+            return null;
+        }
+
+        if( needsToCreateSharedResource(defaultDevice.getUniqueID(), null) ) {
+            if (DEBUG) {
+                System.err.println("EGLDrawableFactory.createShared: (defaultDevice): req. device: "+adevice+", defaultDevice "+defaultDevice);
+                Thread.dumpStack();
             }
-            sr = new SharedResource(sharedDevice, madeCurrentES1, madeCurrentES2);
-            
-            synchronized(sharedMap) {
-                sharedMap.put(connection, sr);
-                if(adevice != sharedDevice) {
-                    sharedMap.put(sharedDevice.getConnection(), sr);
-                }
+            if(null != defaultSharedResource) {
+                dumpMap();
+                throw new InternalError("defaultSharedResource already exist: "+defaultSharedResource);
             }
-            if (DEBUG) {
-                System.err.println("EGLDrawableFactory.createShared: devices:  queried " + QUERY_EGL_ES + "[nativeTK "+QUERY_EGL_ES_NATIVE_TK+"], " + adevice + ", " + sharedDevice);
-                System.err.println("EGLDrawableFactory.createShared: context ES1: " + madeCurrentES1);
-                System.err.println("EGLDrawableFactory.createShared: context ES2: " + madeCurrentES2);
+            defaultSharedResource = createEGLSharedResourceImpl(defaultDevice);            
+        }
+        
+        final String key = adevice.getUniqueID();
+        if( defaultDevice.getUniqueID().equals(key) ) {
+            return defaultSharedResource;
+        } else {
+            if( null == defaultSharedResource) { // defaultDevice must be initialized before host-device 
+                dumpMap();
+                throw new InternalError("defaultSharedResource does not exist");            
             }
+            final SharedResource[] existing = new SharedResource[] { null };
+            if ( !needsToCreateSharedResource(key, existing) ) {
+                return existing[0];
+            }            
+            return createEGLSharedResourceImpl(adevice);
+        }
+    }
+    
+    private SharedResource createEGLSharedResourceImpl(AbstractGraphicsDevice adevice) {
+        final boolean madeCurrentES1;            
+        final boolean madeCurrentES2;
+        boolean[] hasPBufferES1 = new boolean[] { false };
+        boolean[] hasPBufferES2 = new boolean[] { false };
+        // EGLContext[] eglCtxES1 = new EGLContext[] { null };
+        // EGLContext[] eglCtxES2 = new EGLContext[] { null };
+        GLRendererQuirks[] rendererQuirksES1 = new GLRendererQuirks[] { null };
+        GLRendererQuirks[] rendererQuirksES2 = new GLRendererQuirks[] { null };
+        int[] ctpES1 = new int[] { -1 };
+        int[] ctpES2 = new int[] { -1 };
+        
+        
+        if (DEBUG) {
+            System.err.println("EGLDrawableFactory.createShared(): device "+adevice);
+        }
+        
+        if( null != eglES1DynamicLookupHelper ) {
+            madeCurrentES1 = mapAvailableEGLESConfig(adevice, 1, hasPBufferES1, rendererQuirksES1, ctpES1);
+        } else {
+            madeCurrentES1 = false;
+        }
+        if( null != eglES2DynamicLookupHelper ) {
+            madeCurrentES2 = mapAvailableEGLESConfig(adevice, 2, hasPBufferES2, rendererQuirksES2, ctpES2);
+        } else {
+            madeCurrentES2 = false;
+        }
+        
+        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. 
+            EGLContext.setAvailableGLVersionsSet(adevice);
+        }
+        final SharedResource sr = new SharedResource(defaultDevice, madeCurrentES1, hasPBufferES1[0], rendererQuirksES1[0], ctpES1[0],
+                                                                    madeCurrentES2, hasPBufferES2[0], rendererQuirksES2[0], ctpES2[0]);
+        
+        synchronized(sharedMap) {
+            sharedMap.put(adevice.getUniqueID(), sr);
+        }
+        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 "+hasPBufferES2[0]);
+            dumpMap();
         }
         return sr;
     }
@@ -424,9 +607,18 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
 
     @Override
     protected final GLContext getOrCreateSharedContextImpl(AbstractGraphicsDevice device) {
-        return null; // n/a for EGL .. since we don't keep the resources
+        return null; // FIXME: n/a ..
     }
-
+    
+    @Override
+    public GLRendererQuirks getRendererQuirks(AbstractGraphicsDevice device) {
+        SharedResource sr = getOrCreateEGLSharedResource(device);
+        if(null!=sr) {
+            return null != sr.getGLRendererQuirksES2() ? sr.getGLRendererQuirksES2() : sr.getGLRendererQuirksES1() ; 
+        }
+        return null;
+    }
+    
     @Override
     protected AbstractGraphicsDevice getOrCreateSharedDeviceImpl(AbstractGraphicsDevice device) {
         SharedResource sr = getOrCreateEGLSharedResource(device);
@@ -453,7 +645,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
 
     @Override
     protected List<GLCapabilitiesImmutable> getAvailableCapabilitiesImpl(AbstractGraphicsDevice device) {
-        if(null == eglES1DynamicLookupHelper && null == eglES2DynamicLookupHelper) {
+        if(null == sharedMap) { // null == eglES1DynamicLookupHelper && null == eglES2DynamicLookupHelper
             return new ArrayList<GLCapabilitiesImmutable>(); // null
         }
         return EGLGraphicsConfigurationFactory.getAvailableCapabilities(this, device);
@@ -464,50 +656,9 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
         if (target == null) {
           throw new IllegalArgumentException("Null target");
         }
-        return new EGLOnscreenDrawable(this, getEGLSurface(target));
+        return new EGLOnscreenDrawable(this, EGLWrappedSurface.get(target));
     }
     
-    protected static NativeSurface getEGLSurface(NativeSurface surface) {
-        AbstractGraphicsConfiguration aConfig = surface.getGraphicsConfiguration();
-        AbstractGraphicsDevice aDevice = aConfig.getScreen().getDevice();
-        if( aDevice instanceof EGLGraphicsDevice && aConfig instanceof EGLGraphicsConfiguration ) {
-            // already in native EGL format
-            if(DEBUG) {
-                System.err.println(getThreadName() + ": getEGLSurface - already in EGL format - use as-is: "+aConfig);
-            }
-            return surface;
-        }
-        // create EGL instance out of platform native types
-        final EGLGraphicsDevice eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(surface, true);
-        final AbstractGraphicsScreen eglScreen = new DefaultGraphicsScreen(eglDevice, aConfig.getScreen().getIndex());
-        final GLCapabilitiesImmutable capsRequested = (GLCapabilitiesImmutable) aConfig.getRequestedCapabilities();
-        final EGLGraphicsConfiguration eglConfig;
-        if( aConfig instanceof EGLGraphicsConfiguration ) {
-            // Config is already in EGL type - reuse ..
-            final EGLGLCapabilities capsChosen = (EGLGLCapabilities) aConfig.getChosenCapabilities();
-            if( 0 == capsChosen.getEGLConfig() ) {
-                // 'refresh' the native EGLConfig handle
-                capsChosen.setEGLConfig(EGLGraphicsConfiguration.EGLConfigId2EGLConfig(eglDevice.getHandle(), capsChosen.getEGLConfigID()));
-                if( 0 == capsChosen.getEGLConfig() ) {
-                    throw new GLException("Refreshing native EGLConfig handle failed: "+capsChosen+" of "+aConfig);
-                }
-            }
-            eglConfig  = new EGLGraphicsConfiguration(eglScreen, capsChosen, capsRequested, null);
-            if(DEBUG) {
-                System.err.println(getThreadName() + ": getEGLSurface - Reusing chosenCaps: "+eglConfig);
-            }
-        } else {
-            eglConfig = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(
-                    capsRequested, capsRequested, null, eglScreen, aConfig.getVisualID(VIDType.NATIVE), false);
-
-            if (null == eglConfig) {
-                throw new GLException("Couldn't create EGLGraphicsConfiguration from "+eglScreen);
-            } else if(DEBUG) {
-                System.err.println(getThreadName() + ": getEGLSurface - Chosen eglConfig: "+eglConfig);
-            }
-        }
-        return new WrappedSurface(eglConfig, EGL.EGL_NO_SURFACE, surface.getWidth(), surface.getHeight(), new EGLUpstreamSurfaceHook(surface));
-    }
     static String getThreadName() { return Thread.currentThread().getName(); }
 
     @Override
@@ -521,83 +672,45 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
             throw new GLException("Non pbuffer not yet implemented");
         }
         // PBuffer GLDrawable Creation
-        return new EGLPbufferDrawable(this, target);
+        return new EGLPbufferDrawable(this, EGLWrappedSurface.get(target));
     }
 
     @Override
     public boolean canCreateGLPbuffer(AbstractGraphicsDevice device) {
+        // SharedResource sr = getOrCreateEGLSharedResource(device);
+        // return sr.hasES1PBuffer() || sr.hasES2PBuffer();
         return true;
     }
 
     @Override
     protected ProxySurface createMutableSurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice, 
                                                     GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, 
-                                                    GLCapabilitiesChooser chooser, int width, int height, UpstreamSurfaceHook lifecycleHook) {
+                                                    GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstreamHook) {
+        final boolean ownDevice;
         final EGLGraphicsDevice device;
-        if(createNewDevice) {
-            final EGLGraphicsDevice eglDeviceReq = (EGLGraphicsDevice) deviceReq;
-            device = EGLDisplayUtil.eglCreateEGLGraphicsDevice(eglDeviceReq.getNativeDisplayID(), deviceReq.getConnection(), deviceReq.getUnitID());
+        if( createNewDevice || ! (deviceReq instanceof EGLGraphicsDevice) ) {
+            final long nativeDisplayID = ( deviceReq instanceof EGLGraphicsDevice) ?
+                    ( (EGLGraphicsDevice) deviceReq ).getNativeDisplayID() : deviceReq.getHandle() ;
+            device = EGLDisplayUtil.eglCreateEGLGraphicsDevice(nativeDisplayID, deviceReq.getConnection(), deviceReq.getUnitID());
+            ownDevice = true;
         } else {
             device = (EGLGraphicsDevice) deviceReq;
+            ownDevice = false;
         }
         final DefaultGraphicsScreen screen = new DefaultGraphicsScreen(device, 0);
         final EGLGraphicsConfiguration config = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, screen, VisualIDHolder.VID_UNDEFINED, false);
         if(null == config) {
             throw new GLException("Choosing GraphicsConfiguration failed w/ "+capsChosen+" on "+screen); 
         }    
-        return new WrappedSurface(config, 0, width, height, lifecycleHook);
+        return new WrappedSurface(config, 0, upstreamHook, ownDevice);
     }
     
     @Override
     public final ProxySurface createDummySurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice, 
-                                                     GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) {
-        final GLCapabilitiesImmutable chosenCaps = GLGraphicsConfigurationUtil.fixOffscreenGLCapabilities(requestedCaps, false, canCreateGLPbuffer(deviceReq));        
-        return createMutableSurfaceImpl(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, width, height, dummySurfaceLifecycleHook);
-    }
-    private static final ProxySurface.UpstreamSurfaceHook dummySurfaceLifecycleHook = new ProxySurface.UpstreamSurfaceHook() {
-        @Override
-        public final void create(ProxySurface s) {
-            if( EGL.EGL_NO_SURFACE == s.getSurfaceHandle() ) {
-                final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) s.getGraphicsConfiguration().getScreen().getDevice();
-                if(0 == eglDevice.getHandle()) {
-                    eglDevice.open();
-                    s.setImplBitfield(ProxySurface.OWN_DEVICE);
-                }
-                createPBufferSurfaceImpl(s, false);
-                if(DEBUG) {
-                    System.err.println("EGLDrawableFactory.dummySurfaceLifecycleHook.create: "+s);
-                }
-            }
-        }
-        @Override
-        public final void destroy(ProxySurface s) {
-            if( EGL.EGL_NO_SURFACE != s.getSurfaceHandle() ) {
-                final EGLGraphicsConfiguration config = (EGLGraphicsConfiguration) s.getGraphicsConfiguration();
-                final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) config.getScreen().getDevice();
-                EGL.eglDestroySurface(eglDevice.getHandle(), s.getSurfaceHandle());
-                s.setSurfaceHandle(EGL.EGL_NO_SURFACE);
-                if( 0 != ( ProxySurface.OWN_DEVICE & s.getImplBitfield() ) ) {
-                    eglDevice.close();
-                }
-                if(DEBUG) {
-                    System.err.println("EGLDrawableFactory.dummySurfaceLifecycleHook.create: "+s);
-                }
-            }
-        }
-        @Override
-        public final int getWidth(ProxySurface s) {
-            return s.initialWidth;
-        }
-        @Override
-        public final int getHeight(ProxySurface s) {
-            return s.initialHeight;
-        }
-        @Override
-        public String toString() {
-            return "EGLSurfaceLifecycleHook[]";
-        }
-        
-    };
+                                                     GLCapabilitiesImmutable chosenCaps, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) {
+        chosenCaps = GLGraphicsConfigurationUtil.fixOffscreenBitOnly(chosenCaps); // complete validation in EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(..) above         
+        return createMutableSurfaceImpl(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, new EGLDummyUpstreamSurfaceHook(width, height));
+    }
     
     /**
      * @param ms {@link MutableSurface} which dimensions and config are being used to create the pbuffer surface. 
@@ -606,7 +719,9 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
      * @return the passed {@link MutableSurface} which now has the EGL pbuffer surface set as it's handle
      */
     protected static MutableSurface createPBufferSurfaceImpl(MutableSurface ms, boolean useTexture) {
-        final EGLGraphicsConfiguration config = (EGLGraphicsConfiguration) ms.getGraphicsConfiguration();
+        return null;
+    }
+    protected static long createPBufferSurfaceImpl(EGLGraphicsConfiguration config, int width, int height, boolean useTexture) {
         final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) config.getScreen().getDevice();
         final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
         final int texFormat;
@@ -621,15 +736,14 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
           System.out.println("Pbuffer config: " + config);
         }
 
-        final int[] attrs = EGLGraphicsConfiguration.CreatePBufferSurfaceAttribList(ms.getWidth(), ms.getHeight(), texFormat);
-        final long surf = EGL.eglCreatePbufferSurface(eglDevice.getHandle(), config.getNativeConfig(), attrs, 0);
+        final IntBuffer attrs = EGLGraphicsConfiguration.CreatePBufferSurfaceAttribList(width, height, texFormat);
+        final long surf = EGL.eglCreatePbufferSurface(eglDevice.getHandle(), config.getNativeConfig(), attrs);
         if (EGL.EGL_NO_SURFACE==surf) {
-            throw new GLException("Creation of window surface (eglCreatePbufferSurface) failed, dim "+ms.getWidth()+"x"+ms.getHeight()+", error 0x"+Integer.toHexString(EGL.eglGetError()));
+            throw new GLException("Creation of window surface (eglCreatePbufferSurface) failed, dim "+width+"x"+height+", "+eglDevice+", "+config+", error 0x"+Integer.toHexString(EGL.eglGetError()));
         } else if(DEBUG) {
             System.err.println("PBuffer setSurface result: eglSurface 0x"+Long.toHexString(surf));
         }
-        ms.setSurfaceHandle(surf);
-        return ms;
+        return surf;
     }
 
     @Override
@@ -638,7 +752,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
         final EGLGraphicsDevice device = EGLDisplayUtil.eglCreateEGLGraphicsDevice(eglDeviceReq.getNativeDisplayID(), deviceReq.getConnection(), deviceReq.getUnitID());
         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, 0, 0, upstream);
+        return new WrappedSurface(cfg, windowHandle, upstream, true);
     }
 
     @Override
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDummyUpstreamSurfaceHook.java b/src/jogl/classes/jogamp/opengl/egl/EGLDummyUpstreamSurfaceHook.java
new file mode 100644
index 0000000..162e716
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDummyUpstreamSurfaceHook.java
@@ -0,0 +1,59 @@
+package jogamp.opengl.egl;
+
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
+
+import com.jogamp.nativewindow.UpstreamSurfaceHookMutableSize;
+import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
+
+public class EGLDummyUpstreamSurfaceHook extends UpstreamSurfaceHookMutableSize {
+    /**
+     * @param width the initial width as returned by {@link NativeSurface#getWidth()} via {@link UpstreamSurfaceHook#getWidth(ProxySurface)}, 
+     *        not the actual dummy surface width. 
+     *        The latter is platform specific and small
+     * @param height the initial height as returned by {@link NativeSurface#getHeight()} via {@link UpstreamSurfaceHook#getHeight(ProxySurface)}, 
+     *        not the actual dummy surface height,
+     *        The latter is platform specific and small
+     */
+    public EGLDummyUpstreamSurfaceHook(int width, int height) {
+        super(width, height);
+    }
+    
+    @Override
+    public final void create(ProxySurface s) {
+        final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) s.getGraphicsConfiguration().getScreen().getDevice();
+        eglDevice.lock();
+        try {
+            if(0 == eglDevice.getHandle()) {
+                eglDevice.open();
+                s.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE );
+            }
+            if( EGL.EGL_NO_SURFACE == s.getSurfaceHandle() ) {
+                s.setSurfaceHandle( EGLDrawableFactory.createPBufferSurfaceImpl((EGLGraphicsConfiguration)s.getGraphicsConfiguration(), 64, 64, false) );
+                s.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );            
+            }
+            s.addUpstreamOptionBits(ProxySurface.OPT_UPSTREAM_WINDOW_INVISIBLE);
+        } finally {
+            eglDevice.unlock();
+        }
+    }
+    
+    @Override
+    public final void destroy(ProxySurface s) {
+        if( s.containsUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE ) ) {
+            final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) s.getGraphicsConfiguration().getScreen().getDevice();
+            if( EGL.EGL_NO_SURFACE == s.getSurfaceHandle() ) {
+                throw new InternalError("Owns upstream surface, but no EGL surface: "+s);
+            }
+            eglDevice.lock();
+            try {
+                EGL.eglDestroySurface(eglDevice.getHandle(), s.getSurfaceHandle());
+                s.setSurfaceHandle(EGL.EGL_NO_SURFACE);
+                s.clearUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
+            } finally {
+                eglDevice.unlock();
+            }
+        }
+    }
+}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLExternalContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLExternalContext.java
index 585638d..84bd705 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLExternalContext.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLExternalContext.java
@@ -79,15 +79,4 @@ public class EGLExternalContext extends EGLContext {
     @Override
     protected void destroyImpl() throws GLException {
     }
-
-    @Override
-    public void bindPbufferToTexture() {
-        throw new GLException("Should not call this");
-    }
-
-    @Override
-    public void releasePbufferFromTexture() {
-        throw new GLException("Should not call this");
-    }
-
 }
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGLCapabilities.java b/src/jogl/classes/jogamp/opengl/egl/EGLGLCapabilities.java
index 70a5701..f857c6b 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGLCapabilities.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGLCapabilities.java
@@ -33,6 +33,8 @@ import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLException;
 import javax.media.opengl.GLProfile;
 
+import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
+
 
 public class EGLGLCapabilities extends GLCapabilities {
   private long eglcfg;
@@ -45,18 +47,18 @@ public class EGLGLCapabilities extends GLCapabilities {
    * @param eglcfg
    * @param eglcfgid
    * @param visualID native visualID if valid, otherwise VisualIDHolder.VID_UNDEFINED
-   * @param glp desired GLProfile, or null if determined by renderableType
+   * @param glp desired GLProfile
    * @param renderableType actual EGL renderableType
    *
    * May throw GLException if given GLProfile is not compatible w/ renderableType
    */
   public EGLGLCapabilities(long eglcfg, int eglcfgid, int visualID, GLProfile glp, int renderableType) {
-      super( ( null != glp ) ? glp : getCompatible(renderableType) );
+      super( glp );
       this.eglcfg = eglcfg;
       this.eglcfgid = eglcfgid;
       if(!isCompatible(glp, renderableType)) {
-          throw new GLException("Incompatible "+glp+
-                                " with EGL-RenderableType["+renderableTypeToString(null, renderableType)+"]");
+          throw new GLException("Requested GLProfile "+glp+
+                                " not compatible with EGL-RenderableType["+renderableTypeToString(null, renderableType)+"]");
       }
       this.renderableType = renderableType;
       this.nativeVisualID = visualID;
@@ -111,15 +113,15 @@ public class EGLGLCapabilities extends GLCapabilities {
     return false;
   }
 
-  public static GLProfile getCompatible(int renderableType) {
-    if(0 != (renderableType & EGL.EGL_OPENGL_ES2_BIT) && GLProfile.isAvailable(GLProfile.GLES2)) {
-        return GLProfile.get(GLProfile.GLES2);
+  public static GLProfile getCompatible(EGLGraphicsDevice device, int renderableType) {
+    if(0 != (renderableType & EGL.EGL_OPENGL_ES2_BIT) && GLProfile.isAvailable(device, GLProfile.GLES2)) {
+        return GLProfile.get(device, GLProfile.GLES2);
     }
-    if(0 != (renderableType & EGL.EGL_OPENGL_ES_BIT) && GLProfile.isAvailable(GLProfile.GLES1)) {
-        return GLProfile.get(GLProfile.GLES1);
+    if(0 != (renderableType & EGL.EGL_OPENGL_ES_BIT) && GLProfile.isAvailable(device, GLProfile.GLES1)) {
+        return GLProfile.get(device, GLProfile.GLES1);
     }
     if(0 != (renderableType & EGL.EGL_OPENGL_BIT)) {
-        return GLProfile.getDefault();
+        return GLProfile.getDefault(device);
     }
     return null;
   }
@@ -129,6 +131,7 @@ public class EGLGLCapabilities extends GLCapabilities {
         sink = new StringBuilder();
     }
     boolean first=true;
+    sink.append("0x").append(Integer.toHexString(renderableType)).append(": ");
     if(0 != (renderableType & EGL.EGL_OPENGL_BIT)) {
         sink.append("GL"); first=false;
     }
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
index 716a6e6..71dfe1d 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
@@ -37,8 +37,6 @@
 package jogamp.opengl.egl;
 
 import java.nio.IntBuffer;
-import java.util.ArrayList;
-import java.util.List;
 
 import javax.media.nativewindow.AbstractGraphicsDevice;
 import javax.media.nativewindow.AbstractGraphicsScreen;
@@ -85,7 +83,8 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
         }
         final long cfg = EGLConfigId2EGLConfig(dpy, cfgID);
         if(0 < cfg) {
-            final EGLGLCapabilities caps = EGLConfig2Capabilities(capsRequested.getGLProfile(), dpy, cfg, false, capsRequested.isOnscreen(), capsRequested.isPBuffer(), false);
+            final int winattrmask = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(capsRequested);
+            final EGLGLCapabilities caps = EGLConfig2Capabilities((EGLGraphicsDevice)absDevice, capsRequested.getGLProfile(), cfg, winattrmask, false);
             return new EGLGraphicsConfiguration(absScreen, caps, capsRequested, new DefaultGLCapabilitiesChooser());
         }
         return null;
@@ -111,67 +110,74 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
     }
 
     public static long EGLConfigId2EGLConfig(long display, int configID) {
-        int[] attrs = new int[] {
+        final IntBuffer attrs = Buffers.newDirectIntBuffer(new int[] {
                 EGL.EGL_CONFIG_ID, configID,
                 EGL.EGL_NONE
-            };
-        PointerBuffer configs = PointerBuffer.allocateDirect(1);
-        int[] numConfigs = new int[1];
+            });
+        final PointerBuffer configs = PointerBuffer.allocateDirect(1);
+        final IntBuffer numConfigs = Buffers.newDirectIntBuffer(1);
         if (!EGL.eglChooseConfig(display,
-                                 attrs, 0,
+                                 attrs,
                                  configs, 1,
-                                 numConfigs, 0)) {
+                                 numConfigs)) {
             return 0;
         }
-        if (numConfigs[0] == 0) {
+        if (numConfigs.get(0) == 0) {
             return 0;
         }
         return configs.get(0);
     }
 
-    static int EGLConfigDrawableTypeBits(final long display, final long config) {
+    public static boolean isEGLConfigValid(long display, long config) {
+        if(0 == config) {
+            return false;
+        }
+        final IntBuffer val = Buffers.newDirectIntBuffer(1);
+        
+        // get the configID
+        if(!EGL.eglGetConfigAttrib(display, config, EGL.EGL_CONFIG_ID, val)) {
+            final int eglErr = EGL.eglGetError();
+            if(DEBUG) {
+                System.err.println("Info: Couldn't retrieve EGL ConfigID for config "+toHexString(config)+", error "+toHexString(eglErr));
+            }
+            return false;
+        }
+        return true;
+    }
+
+    static int EGLConfigDrawableTypeBits(final EGLGraphicsDevice device, final long config) {
         int val = 0;
 
-        int[] stype = new int[1];
-        if(! EGL.eglGetConfigAttrib(display, config, EGL.EGL_SURFACE_TYPE, stype, 0)) {
+        final IntBuffer stype = Buffers.newDirectIntBuffer(1);
+        if(! EGL.eglGetConfigAttrib(device.getHandle(), config, EGL.EGL_SURFACE_TYPE, stype)) {
             throw new GLException("Could not determine EGL_SURFACE_TYPE");
         }
 
-        if ( 0 != ( stype[0] & EGL.EGL_WINDOW_BIT ) ) {
+        final int _stype = stype.get(0);
+        if ( 0 != ( _stype & EGL.EGL_WINDOW_BIT ) ) {
             val |= GLGraphicsConfigurationUtil.WINDOW_BIT;
         }
-        if ( 0 != ( stype[0] & EGL.EGL_PIXMAP_BIT ) ) {
+        if ( 0 != ( _stype & EGL.EGL_PIXMAP_BIT ) ) {
             val |= GLGraphicsConfigurationUtil.BITMAP_BIT;
         }
-        if ( 0 != ( stype[0] & EGL.EGL_PBUFFER_BIT ) ) {
-            val |= GLGraphicsConfigurationUtil.PBUFFER_BIT;
+        if ( 0 != ( _stype & EGL.EGL_PBUFFER_BIT ) ) {
+            val |= GLGraphicsConfigurationUtil.PBUFFER_BIT |
+                   GLGraphicsConfigurationUtil.FBO_BIT;     
         }
-
         return val;
     }
 
-    public static EGLGLCapabilities EGLConfig2Capabilities(GLProfile glp, long display, long config,
-                                                           boolean relaxed, boolean onscreen, boolean usePBuffer, boolean forceTransparentFlag) {
-        List<GLCapabilitiesImmutable> bucket = new ArrayList<GLCapabilitiesImmutable>();
-        final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer, false);
-        if( EGLConfig2Capabilities(bucket, glp, display, config, winattrmask, forceTransparentFlag) ) {
-            return (EGLGLCapabilities) bucket.get(0);
-        } else if ( relaxed && EGLConfig2Capabilities(bucket, glp, display, config, GLGraphicsConfigurationUtil.ALL_BITS, forceTransparentFlag) ) {
-            return (EGLGLCapabilities) bucket.get(0);
-        }
-        return null;
-    }
-
-    public static boolean EGLConfig2Capabilities(List<GLCapabilitiesImmutable> capsBucket,
-                                                 GLProfile glp, long display, long config,
-                                                 int winattrmask, boolean forceTransparentFlag) {
-        final int allDrawableTypeBits = EGLConfigDrawableTypeBits(display, config);
-        final int drawableTypeBits = winattrmask & allDrawableTypeBits;
-
-        if( 0 == drawableTypeBits ) {
-            return false;
-        }
-
+    /**
+     * @param device
+     * @param glp desired GLProfile, may be null
+     * @param config
+     * @param winattrmask
+     * @param forceTransparentFlag
+     * @return
+     */
+    public static EGLGLCapabilities EGLConfig2Capabilities(EGLGraphicsDevice device, GLProfile glp, long config,
+                                                           int winattrmask, boolean forceTransparentFlag) {
+        final long display = device.getHandle();
         final IntBuffer val = Buffers.newDirectIntBuffer(1);
         final int cfgID;
         final int rType;
@@ -183,7 +189,7 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
                 // FIXME: this happens on a ATI PC Emulation ..
                 System.err.println("EGL couldn't retrieve ConfigID for config "+toHexString(config)+", error "+toHexString(EGL.eglGetError()));
             }
-            return false;
+            return null;
         }
         cfgID = val.get(0);
         
@@ -191,10 +197,10 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
             if(DEBUG) {
                 System.err.println("EGL couldn't retrieve EGL_RENDERABLE_TYPE for config "+toHexString(config)+", error "+toHexString(EGL.eglGetError()));
             }
-            return false;
+            return null;
         }
         rType = val.get(0);
-                       
+
         if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_NATIVE_VISUAL_ID, val)) {
             visualID = val.get(0);
         } else {
@@ -203,14 +209,29 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
         
         EGLGLCapabilities caps = null;        
         try {
+            if(null == glp) {
+                glp = EGLGLCapabilities.getCompatible(device, rType);
+            }
+            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)+"]");
+                }
+                return null;
+            }
             caps = new EGLGLCapabilities(config, cfgID, visualID, glp, rType);
         } catch (GLException gle) {
             if(DEBUG) {
                 System.err.println("config "+toHexString(config)+": "+gle);
             }
-            return false;
+            return null;
         }        
                 
+        if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_CONFIG_CAVEAT, val)) {
+            if( EGL.EGL_SLOW_CONFIG == val.get(0) ) {
+                caps.setHardwareAccelerated(false);
+            }
+        }
         if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_SAMPLES, val)) {
             caps.setSampleBuffers(val.get(0)>0?true:false);
             caps.setNumSamples(val.get(0));
@@ -265,107 +286,129 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
         if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_DEPTH_SIZE, val)) {
             caps.setDepthBits(val.get(0));
         }
-        return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, caps, drawableTypeBits );
+
+        // Since the passed GLProfile may be null, 
+        // we use EGL_RENDERABLE_TYPE derived profile as created in the EGLGLCapabilities constructor.
+        final int availableTypeBits = EGLConfigDrawableTypeBits(device, config);        
+        final int drawableTypeBits = winattrmask & availableTypeBits;
+
+        if( 0 == drawableTypeBits ) {
+            return null;
+        }
+        
+        return (EGLGLCapabilities) GLGraphicsConfigurationUtil.fixWinAttribBitsAndHwAccel(device, drawableTypeBits, caps); 
     }
 
-    public static int[] GLCapabilities2AttribList(GLCapabilitiesImmutable caps) {
-        int[] attrs = new int[32];
+    public static IntBuffer GLCapabilities2AttribList(GLCapabilitiesImmutable caps) {
+        final IntBuffer attrs = Buffers.newDirectIntBuffer(32);
         int idx=0;
 
-        attrs[idx++] = EGL.EGL_SURFACE_TYPE;
-        attrs[idx++] = caps.isOnscreen() ? ( EGL.EGL_WINDOW_BIT ) : ( caps.isPBuffer() ? EGL.EGL_PBUFFER_BIT : EGL.EGL_PIXMAP_BIT ) ;
+        attrs.put(idx++, EGL.EGL_SURFACE_TYPE);
+        final int surfaceType;
+        if( caps.isOnscreen() ) {
+            surfaceType = EGL.EGL_WINDOW_BIT;            
+        } else if( caps.isFBO() ) {
+            surfaceType = EGL.EGL_PBUFFER_BIT;  // native replacement!
+        } else if( caps.isPBuffer() ) {
+            surfaceType = EGL.EGL_PBUFFER_BIT;
+        } else if( caps.isBitmap() ) {
+            surfaceType = EGL.EGL_PIXMAP_BIT;
+        } else {
+            throw new GLException("no surface type set in caps: "+caps);
+        }
+        attrs.put(idx++, surfaceType);
 
-        attrs[idx++] = EGL.EGL_RED_SIZE;
-        attrs[idx++] = caps.getRedBits();
+        attrs.put(idx++, EGL.EGL_RED_SIZE);
+        attrs.put(idx++, caps.getRedBits());
 
-        attrs[idx++] = EGL.EGL_GREEN_SIZE;
-        attrs[idx++] = caps.getGreenBits();
+        attrs.put(idx++, EGL.EGL_GREEN_SIZE);
+        attrs.put(idx++, caps.getGreenBits());
 
-        attrs[idx++] = EGL.EGL_BLUE_SIZE;
-        attrs[idx++] = caps.getBlueBits();
+        attrs.put(idx++, EGL.EGL_BLUE_SIZE);
+        attrs.put(idx++, caps.getBlueBits());
 
         if(caps.getAlphaBits()>0) {
-            attrs[idx++] = EGL.EGL_ALPHA_SIZE;
-            attrs[idx++] = caps.getAlphaBits();
+            attrs.put(idx++, EGL.EGL_ALPHA_SIZE);
+            attrs.put(idx++, caps.getAlphaBits());
         }
         
         if(caps.getStencilBits()>0) {
-            attrs[idx++] = EGL.EGL_STENCIL_SIZE;
-            attrs[idx++] = caps.getStencilBits();
+            attrs.put(idx++, EGL.EGL_STENCIL_SIZE);
+            attrs.put(idx++, caps.getStencilBits());
         }
 
-        attrs[idx++] = EGL.EGL_DEPTH_SIZE;
-        attrs[idx++] = caps.getDepthBits();
+        attrs.put(idx++, EGL.EGL_DEPTH_SIZE);
+        attrs.put(idx++, caps.getDepthBits());
 
         if(caps.getSampleBuffers()) {
             if(caps.getSampleExtension().equals(GLGraphicsConfigurationUtil.NV_coverage_sample)) {
-                attrs[idx++] = EGLExt.EGL_COVERAGE_BUFFERS_NV;
-                attrs[idx++] = 1;
-                attrs[idx++] = EGLExt.EGL_COVERAGE_SAMPLES_NV;
-                attrs[idx++] = caps.getNumSamples();
+                attrs.put(idx++, EGLExt.EGL_COVERAGE_BUFFERS_NV);
+                attrs.put(idx++, 1);
+                attrs.put(idx++, EGLExt.EGL_COVERAGE_SAMPLES_NV);
+                attrs.put(idx++, caps.getNumSamples());
             } else {
                 // try default ..
-                attrs[idx++] = EGL.EGL_SAMPLE_BUFFERS;
-                attrs[idx++] = 1;
-                attrs[idx++] = EGL.EGL_SAMPLES;
-                attrs[idx++] = caps.getNumSamples();
+                attrs.put(idx++, EGL.EGL_SAMPLE_BUFFERS);
+                attrs.put(idx++, 1);
+                attrs.put(idx++, EGL.EGL_SAMPLES);
+                attrs.put(idx++, caps.getNumSamples());
             }
         }
 
-        attrs[idx++] = EGL.EGL_TRANSPARENT_TYPE;
-        attrs[idx++] = caps.isBackgroundOpaque() ? EGL.EGL_NONE : EGL.EGL_TRANSPARENT_TYPE;
+        attrs.put(idx++, EGL.EGL_TRANSPARENT_TYPE);
+        attrs.put(idx++, caps.isBackgroundOpaque() ? EGL.EGL_NONE : EGL.EGL_TRANSPARENT_TYPE);
 
         // 22
 
         if(!caps.isBackgroundOpaque()) {
-            attrs[idx++] = EGL.EGL_TRANSPARENT_RED_VALUE;
-            attrs[idx++] = caps.getTransparentRedValue()>=0?caps.getTransparentRedValue():EGL.EGL_DONT_CARE;
+            attrs.put(idx++, EGL.EGL_TRANSPARENT_RED_VALUE);
+            attrs.put(idx++, caps.getTransparentRedValue()>=0?caps.getTransparentRedValue():EGL.EGL_DONT_CARE);
 
-            attrs[idx++] = EGL.EGL_TRANSPARENT_GREEN_VALUE;
-            attrs[idx++] = caps.getTransparentGreenValue()>=0?caps.getTransparentGreenValue():EGL.EGL_DONT_CARE;
+            attrs.put(idx++, EGL.EGL_TRANSPARENT_GREEN_VALUE);
+            attrs.put(idx++, caps.getTransparentGreenValue()>=0?caps.getTransparentGreenValue():EGL.EGL_DONT_CARE);
 
-            attrs[idx++] = EGL.EGL_TRANSPARENT_BLUE_VALUE;
-            attrs[idx++] = caps.getTransparentBlueValue()>=0?caps.getTransparentBlueValue():EGL.EGL_DONT_CARE;
+            attrs.put(idx++, EGL.EGL_TRANSPARENT_BLUE_VALUE);
+            attrs.put(idx++, caps.getTransparentBlueValue()>=0?caps.getTransparentBlueValue():EGL.EGL_DONT_CARE);
 
             /** Not define in EGL
-            attrs[idx++] = EGL.EGL_TRANSPARENT_ALPHA_VALUE;
-            attrs[idx++] = caps.getTransparentAlphaValue()>=0?caps.getTransparentAlphaValue():EGL.EGL_DONT_CARE; */
+            attrs.put(idx++, EGL.EGL_TRANSPARENT_ALPHA_VALUE;
+            attrs.put(idx++, caps.getTransparentAlphaValue()>=0?caps.getTransparentAlphaValue():EGL.EGL_DONT_CARE; */
         }
 
         // 28 
-        attrs[idx++] = EGL.EGL_RENDERABLE_TYPE;
+        attrs.put(idx++, EGL.EGL_RENDERABLE_TYPE);
         if(caps.getGLProfile().usesNativeGLES1()) {
-            attrs[idx++] = EGL.EGL_OPENGL_ES_BIT;
+            attrs.put(idx++, EGL.EGL_OPENGL_ES_BIT);
         } else if(caps.getGLProfile().usesNativeGLES2()) {
-            attrs[idx++] = EGL.EGL_OPENGL_ES2_BIT;
+            attrs.put(idx++, EGL.EGL_OPENGL_ES2_BIT);
         } else {
-            attrs[idx++] = EGL.EGL_OPENGL_BIT;
+            attrs.put(idx++, EGL.EGL_OPENGL_BIT);
         }
 
         // 30
 
-        attrs[idx++] = EGL.EGL_NONE;
+        attrs.put(idx++, EGL.EGL_NONE);
 
         return attrs;
     }
 
-    public static int[] CreatePBufferSurfaceAttribList(int width, int height, int texFormat) {
-        int[] attrs = new int[16];
+    public static IntBuffer CreatePBufferSurfaceAttribList(int width, int height, int texFormat) {
+        IntBuffer attrs = Buffers.newDirectIntBuffer(16);
         int idx=0;
 
-        attrs[idx++] = EGL.EGL_WIDTH;
-        attrs[idx++] = width;
+        attrs.put(idx++, EGL.EGL_WIDTH);
+        attrs.put(idx++, width);
 
-        attrs[idx++] = EGL.EGL_HEIGHT;
-        attrs[idx++] = height;
+        attrs.put(idx++, EGL.EGL_HEIGHT);
+        attrs.put(idx++, height);
 
-        attrs[idx++] = EGL.EGL_TEXTURE_FORMAT;
-        attrs[idx++] = texFormat;
+        attrs.put(idx++, EGL.EGL_TEXTURE_FORMAT);
+        attrs.put(idx++, texFormat);
 
-        attrs[idx++] = EGL.EGL_TEXTURE_TARGET;
-        attrs[idx++] = EGL.EGL_NO_TEXTURE==texFormat ? EGL.EGL_NO_TEXTURE : EGL.EGL_TEXTURE_2D;
+        attrs.put(idx++, EGL.EGL_TEXTURE_TARGET);
+        attrs.put(idx++, EGL.EGL_NO_TEXTURE==texFormat ? EGL.EGL_NO_TEXTURE : EGL.EGL_TEXTURE_2D);
 
-        attrs[idx++] = EGL.EGL_NONE;
+        attrs.put(idx++, EGL.EGL_NONE);
 
         return attrs;
     }
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
index 0b21d20..f638ef8 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
@@ -74,6 +74,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
     static VisualIDHolder.VIDComparator EglCfgIDComparator = new VisualIDHolder.VIDComparator(VisualIDHolder.VIDType.EGL_CONFIG);
     static GraphicsConfigurationFactory nativeGraphicsConfigurationFactory = null;
     static GraphicsConfigurationFactory kdeglGraphicsConfigurationFactory = null;
+    static GraphicsConfigurationFactory fallbackGraphicsConfigurationFactory = null;
     
     static void registerFactory() {
         GraphicsConfigurationFactory eglFactory = new EGLGraphicsConfigurationFactory();
@@ -82,13 +83,18 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
         final String nwType = NativeWindowFactory.getNativeWindowType(false);
         if(NativeWindowFactory.TYPE_X11 == nwType) {
             nativeGraphicsConfigurationFactory = GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.x11.X11GraphicsDevice.class, GLCapabilitiesImmutable.class, eglFactory);
+            if(null != nativeGraphicsConfigurationFactory) {
+                fallbackGraphicsConfigurationFactory = nativeGraphicsConfigurationFactory;
+            } else {
+                fallbackGraphicsConfigurationFactory = GraphicsConfigurationFactory.getFactory(com.jogamp.nativewindow.x11.X11GraphicsDevice.class, CapabilitiesImmutable.class);                
+            }
         } /* else if(NativeWindowFactory.TYPE_WINDOWS == NativeWindowFactory.getNativeWindowType(false)) {
             nativeGraphicsConfigurationFactory = GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.windows.WindowsGraphicsDevice.class, eglFactory);
         } else if(NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false)) {            
         } */
         
         // become the selector for KD/EGL ..
-        kdeglGraphicsConfigurationFactory = GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.egl.EGLGraphicsDevice.class, GLCapabilitiesImmutable.class, eglFactory);
+        kdeglGraphicsConfigurationFactory = GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.egl.EGLGraphicsDevice.class, GLCapabilitiesImmutable.class, eglFactory);                
     }
     
     static void unregisterFactory() {
@@ -100,6 +106,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
         } else if(NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false)) {            
         } */
         nativeGraphicsConfigurationFactory = null;
+        fallbackGraphicsConfigurationFactory = null;
         
         GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.egl.EGLGraphicsDevice.class, GLCapabilitiesImmutable.class, kdeglGraphicsConfigurationFactory);
         kdeglGraphicsConfigurationFactory = null;
@@ -143,8 +150,8 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
                                                     absScreen, nativeVisualID, false);            
         } else {
             // handle non native cases (X11, ..) 
-            if(null == nativeGraphicsConfigurationFactory) {
-                throw new InternalError("Native GraphicsConfigurationFactory is null, but call issued for device: "+absDevice+" of type "+absDevice.getClass().getSimpleName());
+            if(null == fallbackGraphicsConfigurationFactory) {
+                throw new InternalError("Native fallback GraphicsConfigurationFactory is null, but call issued for device: "+absDevice+" of type "+absDevice.getClass().getSimpleName());
             }
             
             if(glCapsChosen.getGLProfile().usesNativeGLES()) {
@@ -165,9 +172,9 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
             if(null == cfg) {
                 // fwd to native config factory (only X11 for now)
                 if(DEBUG) {
-                    System.err.println("EGLGraphicsConfigurationFactory.choose..: Delegate to "+nativeGraphicsConfigurationFactory.getClass().getSimpleName());
+                    System.err.println("EGLGraphicsConfigurationFactory.choose..: Delegate to "+fallbackGraphicsConfigurationFactory.getClass().getSimpleName());
                 }
-                cfg = nativeGraphicsConfigurationFactory.chooseGraphicsConfiguration(capsChosen, capsRequested, chooser, absScreen, nativeVisualID);
+                cfg = fallbackGraphicsConfigurationFactory.chooseGraphicsConfiguration(capsChosen, capsRequested, chooser, absScreen, nativeVisualID);
             }            
         }
         return cfg;
@@ -200,7 +207,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
             throw new GLException("Graphics configuration get all configs (eglGetConfigs) call failed, error "+toHexString(EGL.eglGetError()));
         }
         if (numConfigs.get(0) > 0) {
-            availableCaps = eglConfigs2GLCaps(null, eglDisplay, configs, numConfigs.get(0), GLGraphicsConfigurationUtil.ALL_BITS, false);
+            availableCaps = eglConfigs2GLCaps(eglDevice, null, configs, numConfigs.get(0), GLGraphicsConfigurationUtil.ALL_BITS, false);
             if( null != availableCaps && availableCaps.size() > 1) {
                 Collections.sort(availableCaps, EglCfgIDComparator);
             }
@@ -240,10 +247,8 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
         }
 
         final GLProfile glp = capsChosen.getGLProfile();
-        final EGLDrawableFactory factory = (EGLDrawableFactory) GLDrawableFactory.getEGLFactory();
-        capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, GLContext.isFBOAvailable(absDevice, glp), factory.canCreateGLPbuffer(absDevice) );
-
-        EGLGraphicsConfiguration res = eglChooseConfig(eglDevice.getHandle(), capsChosen, capsReq, chooser, absScreen, nativeVisualID, forceTransparentFlag);
+        capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, GLDrawableFactory.getEGLFactory(), absDevice);
+        EGLGraphicsConfiguration res = eglChooseConfig(eglDevice, capsChosen, capsReq, chooser, absScreen, nativeVisualID, forceTransparentFlag);
         if(null==res) {
             if(DEBUG) {
                 System.err.println("eglChooseConfig failed with given capabilities "+capsChosen);
@@ -267,7 +272,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
             if(DEBUG) {
                 System.err.println("trying fixed caps (1): "+fixedCaps);
             }
-            res = eglChooseConfig(eglDevice.getHandle(), fixedCaps, capsReq, chooser, absScreen, nativeVisualID, false);
+            res = eglChooseConfig(eglDevice, fixedCaps, capsReq, chooser, absScreen, nativeVisualID, false);
         }
         if(null==res) {
             //
@@ -285,7 +290,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
             if(DEBUG) {
                 System.err.println("trying fixed caps (2): "+fixedCaps);
             }
-            res = eglChooseConfig(eglDevice.getHandle(), fixedCaps, capsReq, chooser, absScreen, nativeVisualID, false);
+            res = eglChooseConfig(eglDevice, fixedCaps, capsReq, chooser, absScreen, nativeVisualID, false);
         }
         if(null==res) {
             //
@@ -305,7 +310,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
             if(DEBUG) {
                 System.err.println("trying fixed caps (3): "+fixedCaps);
             }
-            res = eglChooseConfig(eglDevice.getHandle(), fixedCaps, capsReq, chooser, absScreen, nativeVisualID, false);
+            res = eglChooseConfig(eglDevice, fixedCaps, capsReq, chooser, absScreen, nativeVisualID, false);
         }
         if(null==res) {
             throw new GLException("Graphics configuration failed [direct caps, eglGetConfig/chooser and fixed-caps(1-3)]");
@@ -317,15 +322,15 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
         return res;
     }
 
-    static EGLGraphicsConfiguration eglChooseConfig(long eglDisplay, 
+    
+    static EGLGraphicsConfiguration eglChooseConfig(EGLGraphicsDevice device, 
                                                     GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested,
                                                     GLCapabilitiesChooser chooser,
                                                     AbstractGraphicsScreen absScreen,
                                                     int nativeVisualID, boolean forceTransparentFlag) {
+        final long eglDisplay = device.getHandle();
         final GLProfile glp = capsChosen.getGLProfile();
-        final boolean onscreen = capsChosen.isOnscreen();
-        final boolean usePBuffer = capsChosen.isPBuffer();
-        final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer, false);
+        final int winattrmask = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(capsChosen);
         List<GLCapabilitiesImmutable> availableCaps = null;
         int recommendedIndex = -1;
         long recommendedEGLConfig = -1;
@@ -338,10 +343,15 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
             throw new GLException("EGLGraphicsConfiguration.eglChooseConfig: Get maxConfigs (eglGetConfigs) no configs");
         }
         if (DEBUG) {
-            System.err.println("EGLGraphicsConfiguration.eglChooseConfig: eglChooseConfig eglDisplay "+toHexString(eglDisplay)+", nativeVisualID "+toHexString(nativeVisualID)+", onscreen "+onscreen+", usePBuffer "+usePBuffer+", "+capsChosen+", numConfigs "+numConfigs.get(0));
+            System.err.println("EGLGraphicsConfiguration.eglChooseConfig: eglChooseConfig eglDisplay "+toHexString(eglDisplay)+
+                               ", nativeVisualID "+toHexString(nativeVisualID)+
+                               ", capsChosen "+capsChosen+", winbits "+GLGraphicsConfigurationUtil.winAttributeBits2String(null, winattrmask).toString()+
+                               ", fboAvail "+GLContext.isFBOAvailable(device, glp)+
+                               ", device "+device+", "+device.getUniqueID()+
+                               ", numConfigs "+numConfigs.get(0));
         }
 
-        final IntBuffer attrs = Buffers.newDirectIntBuffer(EGLGraphicsConfiguration.GLCapabilities2AttribList(capsChosen));
+        final IntBuffer attrs = EGLGraphicsConfiguration.GLCapabilities2AttribList(capsChosen);
         PointerBuffer configs = PointerBuffer.allocateDirect(numConfigs.get(0));
 
         // 1st choice: get GLCapabilities based on users GLCapabilities 
@@ -352,7 +362,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
                 System.err.println("EGLGraphicsConfiguration.eglChooseConfig: #1 eglChooseConfig: false");
             }
         } else  if (numConfigs.get(0) > 0) {
-            availableCaps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs.get(0), winattrmask, forceTransparentFlag);
+            availableCaps = eglConfigs2GLCaps(device, glp, configs, numConfigs.get(0), winattrmask, forceTransparentFlag);
             if(availableCaps.size() > 0) {
                 recommendedEGLConfig =  configs.get(0);
                 recommendedIndex = 0;
@@ -377,7 +387,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
                 throw new GLException("EGLGraphicsConfiguration.eglChooseConfig: #2 Get all configs (eglGetConfigs) call failed, error "+toHexString(EGL.eglGetError()));
             }
             if (numConfigs.get(0) > 0) {
-                availableCaps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs.get(0), winattrmask, forceTransparentFlag);                
+                availableCaps = eglConfigs2GLCaps(device, glp, configs, numConfigs.get(0), winattrmask, forceTransparentFlag);                
             }
         }
 
@@ -385,7 +395,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
             if(DEBUG) {
                 // FIXME: this happens on a ATI PC Emulation ..
                 System.err.println("EGLGraphicsConfiguration.eglChooseConfig: #2 Graphics configuration 1st choice and 2nd choice failed - no configs");
-                availableCaps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs.get(0), GLGraphicsConfigurationUtil.ALL_BITS, forceTransparentFlag);
+                availableCaps = eglConfigs2GLCaps(device, glp, configs, numConfigs.get(0), GLGraphicsConfigurationUtil.ALL_BITS, forceTransparentFlag);
                 printCaps("AllCaps", availableCaps, System.err);
             }
             return null;
@@ -426,18 +436,22 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
             return null;
         }
         final EGLGLCapabilities chosenCaps = (EGLGLCapabilities) availableCaps.get(chosenIndex);
+        final EGLGraphicsConfiguration res = new EGLGraphicsConfiguration(absScreen, chosenCaps, capsRequested, chooser);
         if (DEBUG) {
-            System.err.println("EGLGraphicsConfiguration.eglChooseConfig: X chosen :"+chosenIndex+", eglConfig: "+toHexString(chosenCaps.getEGLConfig())+", "+chosenCaps);
+            System.err.println("EGLGraphicsConfiguration.eglChooseConfig: X chosen :"+chosenIndex+", eglConfig: "+toHexString(chosenCaps.getEGLConfig())+": "+res);
         }
-        return new EGLGraphicsConfiguration(absScreen, chosenCaps, capsRequested, chooser);
+        return res;
     }
 
-    static List<GLCapabilitiesImmutable> eglConfigs2GLCaps(GLProfile glp, long eglDisplay, PointerBuffer configs, int num, int winattrmask, boolean forceTransparentFlag) {
-        List<GLCapabilitiesImmutable> caps = new ArrayList<GLCapabilitiesImmutable>(num);
+    static List<GLCapabilitiesImmutable> eglConfigs2GLCaps(EGLGraphicsDevice device, GLProfile glp, PointerBuffer configs, int num, int winattrmask, boolean forceTransparentFlag) {
+        List<GLCapabilitiesImmutable> bucket = new ArrayList<GLCapabilitiesImmutable>(num);
         for(int i=0; i<num; i++) {
-            EGLGraphicsConfiguration.EGLConfig2Capabilities(caps, glp, eglDisplay, configs.get(i), winattrmask, forceTransparentFlag);
+            final GLCapabilitiesImmutable caps = EGLGraphicsConfiguration.EGLConfig2Capabilities(device, glp, configs.get(i), winattrmask, forceTransparentFlag);
+            if(null != caps) {
+                bucket.add(caps);
+            }
         }
-        return caps;
+        return bucket;
     }
 
     static void printCaps(String prefix, List<GLCapabilitiesImmutable> caps, PrintStream out) {
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenContext.java
index eae47fa..325ad61 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenContext.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenContext.java
@@ -41,16 +41,5 @@ public class EGLOnscreenContext extends EGLContext {
     public EGLOnscreenContext(EGLOnscreenDrawable drawable, GLContext shareWith) {
         super(drawable, shareWith);
     }
-
-    @Override
-    public void bindPbufferToTexture() {
-        throw new GLException("Should not call this");
-    }
-
-    @Override
-    public void releasePbufferFromTexture() {
-        throw new GLException("Should not call this");
-    }
-
 }
 
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java
index d540577..6440cf1 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java
@@ -54,8 +54,8 @@ public class EGLOnscreenDrawable extends EGLDrawable {
     }
 
     @Override
-    protected long createSurface(EGLGraphicsConfiguration config, long nativeSurfaceHandle) {
+    protected long createSurface(EGLGraphicsConfiguration config, int width, int height, long nativeSurfaceHandle) {    
         return EGL.eglCreateWindowSurface(config.getScreen().getDevice().getHandle(), config.getNativeConfig(), nativeSurfaceHandle, null);
-    }
+    }    
 }
 
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLPbufferContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLPbufferContext.java
index 7175d51..bb9eeb8 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLPbufferContext.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLPbufferContext.java
@@ -46,15 +46,5 @@ public class EGLPbufferContext extends EGLContext {
     public int getFloatingPointMode() {
         return 0; // FIXME ??
     }
-
-    @Override
-    public void bindPbufferToTexture() {
-        throw new GLException("Not yet implemented");
-    }
-
-    @Override
-    public void releasePbufferFromTexture() {
-        throw new GLException("Not yet implemented");
-    }
 }
 
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java
index 4a36625..eb7e320 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java
@@ -52,12 +52,8 @@ public class EGLPbufferDrawable extends EGLDrawable {
     }
 
     @Override
-    protected long createSurface(EGLGraphicsConfiguration config, long nativeSurfaceHandle) {
-        final MutableSurface ms = (MutableSurface)getNativeSurface();
-        if(config != ms.getGraphicsConfiguration()) {
-            throw new InternalError("Not same: "+config.hashCode()+", "+ms.getGraphicsConfiguration()+": "+config+", "+ms.getGraphicsConfiguration());
-        }
-        return EGLDrawableFactory.createPBufferSurfaceImpl(ms, useTexture).getSurfaceHandle();
+    protected long createSurface(EGLGraphicsConfiguration config, int width, int height, long nativeSurfaceHandle) {
+        return EGLDrawableFactory.createPBufferSurfaceImpl(config, width, height, false);
     }
 
     @Override
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java b/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java
index 42c6e10..342c4c4 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java
@@ -1,38 +1,163 @@
 package jogamp.opengl.egl;
 
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.DefaultGraphicsScreen;
 import javax.media.nativewindow.NativeSurface;
 import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
+import javax.media.nativewindow.VisualIDHolder.VIDType;
+import javax.media.opengl.GLCapabilitiesImmutable;
 import javax.media.opengl.GLException;
 
 import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
 
-public class EGLUpstreamSurfaceHook implements ProxySurface.UpstreamSurfaceHook {
+public class EGLUpstreamSurfaceHook implements UpstreamSurfaceHook.MutableSize {
+    protected static final boolean DEBUG = EGLDrawableFactory.DEBUG;
     private final NativeSurface upstreamSurface;
+    private final UpstreamSurfaceHook.MutableSize upstreamSurfaceHookMutableSize; 
     
     public EGLUpstreamSurfaceHook(NativeSurface upstream) {
         upstreamSurface = upstream;
+        if(upstreamSurface instanceof ProxySurface) {
+            final UpstreamSurfaceHook ush = ((ProxySurface)upstreamSurface).getUpstreamSurfaceHook();
+            if(ush instanceof UpstreamSurfaceHook.MutableSize) {
+                // offscreen NativeSurface w/ MutableSize (default)
+                upstreamSurfaceHookMutableSize = (UpstreamSurfaceHook.MutableSize) ush;
+            } else {
+                upstreamSurfaceHookMutableSize = null;
+            }
+        } else {
+            upstreamSurfaceHookMutableSize = null;
+        }
     }
     
     public final NativeSurface getUpstreamSurface() { return upstreamSurface; }
     
+    static String getThreadName() { return Thread.currentThread().getName(); }
+    
+    public final void setSize(int width, int height) {
+        if(null != upstreamSurfaceHookMutableSize) {
+            upstreamSurfaceHookMutableSize.setSize(width, height);
+        }        
+    }
+    
     @Override
     public final void create(ProxySurface surface) {
+        final String dbgPrefix;
+        if(DEBUG) {
+            dbgPrefix = getThreadName() + ": EGLUpstreamSurfaceHook.create("+surface.getClass().getSimpleName()+"): "; 
+            System.err.println(dbgPrefix+this);            
+        } else {
+            dbgPrefix = null;
+        }
+        
         if(upstreamSurface instanceof ProxySurface) {
+            // propagate createNotify(..) so upstreamSurface will be created 
             ((ProxySurface)upstreamSurface).createNotify();
-            if(NativeSurface.LOCK_SURFACE_NOT_READY >= upstreamSurface.lockSurface()) {
-                throw new GLException("Could not lock: "+upstreamSurface);
+        }
+        
+        // lock upstreamSurface, so it can be used in case EGLDisplay is derived from it!
+        if(NativeSurface.LOCK_SURFACE_NOT_READY >= upstreamSurface.lockSurface()) {
+            throw new GLException("Could not lock: "+upstreamSurface);
+        }
+        try {
+            evalUpstreamSurface(dbgPrefix, surface);
+        } finally {
+            upstreamSurface.unlockSurface();
+        }        
+    }
+    
+    private final void evalUpstreamSurface(String dbgPrefix, ProxySurface surface) {
+        //
+        // evaluate nature of upstreamSurface, may create EGL instances if required
+        //
+        
+        boolean isEGLSurfaceValid = true; // assume yes
+        
+        final AbstractGraphicsConfiguration aConfig = upstreamSurface.getGraphicsConfiguration();        
+        final AbstractGraphicsDevice aDevice = aConfig.getScreen().getDevice();
+        
+        final EGLGraphicsDevice eglDevice;
+        if( aDevice instanceof EGLGraphicsDevice ) {
+            eglDevice = (EGLGraphicsDevice) aDevice;
+            if(DEBUG) {
+                System.err.println(dbgPrefix+"Reusing eglDevice: "+eglDevice);
+            }
+            if(EGL.EGL_NO_DISPLAY == eglDevice.getHandle()) {
+                eglDevice.open();
+                isEGLSurfaceValid = false;
+                surface.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE );
+            }
+        } else {
+            eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(upstreamSurface);
+            isEGLSurfaceValid = false;
+            surface.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE );                
+        }
+        
+        final GLCapabilitiesImmutable capsRequested = (GLCapabilitiesImmutable) aConfig.getRequestedCapabilities();
+        final EGLGraphicsConfiguration eglConfig;
+        if( aConfig instanceof EGLGraphicsConfiguration ) {
+            // Config is already in EGL type - reuse ..
+            final EGLGLCapabilities capsChosen = (EGLGLCapabilities) aConfig.getChosenCapabilities();
+            if( !isEGLSurfaceValid || !EGLGraphicsConfiguration.isEGLConfigValid(eglDevice.getHandle(), capsChosen.getEGLConfig()) ) { 
+                // 'refresh' the native EGLConfig handle
+                capsChosen.setEGLConfig(EGLGraphicsConfiguration.EGLConfigId2EGLConfig(eglDevice.getHandle(), capsChosen.getEGLConfigID()));
+                if( 0 == capsChosen.getEGLConfig() ) {
+                    throw new GLException("Refreshing native EGLConfig handle failed with error "+EGLContext.toHexString(EGL.eglGetError())+": "+eglDevice+", "+capsChosen+" of "+aConfig);
+                }
+                final AbstractGraphicsScreen eglScreen = new DefaultGraphicsScreen(eglDevice, aConfig.getScreen().getIndex());
+                eglConfig  = new EGLGraphicsConfiguration(eglScreen, capsChosen, capsRequested, null);
+                if(DEBUG) {
+                    System.err.println(dbgPrefix+"Refreshing eglConfig: "+eglConfig);
+                }
+                isEGLSurfaceValid = false;
+            } else {
+                eglConfig = (EGLGraphicsConfiguration) aConfig;
+                if(DEBUG) {
+                    System.err.println(dbgPrefix+"Reusing eglConfig: "+eglConfig);
+                }
+            }
+        } else {
+            final AbstractGraphicsScreen eglScreen = new DefaultGraphicsScreen(eglDevice, aConfig.getScreen().getIndex());
+            eglConfig = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(
+                    capsRequested, capsRequested, null, eglScreen, aConfig.getVisualID(VIDType.NATIVE), false);
+
+            if (null == eglConfig) {
+                throw new GLException("Couldn't create EGLGraphicsConfiguration from "+eglScreen);
+            } else if(DEBUG) {
+                System.err.println(dbgPrefix+"Chosen eglConfig: "+eglConfig);
             }
+            isEGLSurfaceValid = false;
         }
-        final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) surface.getGraphicsConfiguration().getScreen().getDevice();
-        eglDevice.open();
+        surface.setGraphicsConfiguration(eglConfig);
+        
+        if(isEGLSurfaceValid) {
+            isEGLSurfaceValid = EGLDrawable.isValidEGLSurface(eglDevice.getHandle(), upstreamSurface.getSurfaceHandle());
+        }
+        if(isEGLSurfaceValid) {
+            surface.setSurfaceHandle(upstreamSurface.getSurfaceHandle());
+            surface.clearUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
+            if(DEBUG) {
+                System.err.println(dbgPrefix+"Fin: Already valid EGL surface - use as-is: "+upstreamSurface);
+            }
+        } else {
+            surface.setSurfaceHandle(EGL.EGL_NO_SURFACE);
+            surface.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE ); // create/destroy in EGLDrawable
+            if(DEBUG) {
+                System.err.println(dbgPrefix+"Fin: EGL surface n/a - TBD: "+upstreamSurface);
+            }
+        }        
     }
 
     @Override
     public final void destroy(ProxySurface surface) {
-        final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) surface.getGraphicsConfiguration().getScreen().getDevice();
-        eglDevice.close();
+        if(EGLDrawableFactory.DEBUG) {
+            System.err.println("EGLUpstreamSurfaceHook.destroy("+surface.getClass().getSimpleName()+"): "+this);            
+        }
+        surface.clearUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );            
         if(upstreamSurface instanceof ProxySurface) {
-            upstreamSurface.unlockSurface();
             ((ProxySurface)upstreamSurface).destroyNotify();
         }
     }
@@ -49,8 +174,8 @@ public class EGLUpstreamSurfaceHook implements ProxySurface.UpstreamSurfaceHook
     
     @Override
     public String toString() {
-        final String us_s = null != upstreamSurface ? ( upstreamSurface.getClass().getName() + ": " + upstreamSurface ) : "nil"; 
-        return "EGLUpstreamSurfaceHook[upstream: "+us_s+"]";
+        final String us_s = null != upstreamSurface ? ( upstreamSurface.getClass().getName() + ": 0x" + Long.toHexString(upstreamSurface.getSurfaceHandle()) ) : "nil";
+        return "EGLUpstreamSurfaceHook[ "+ upstreamSurface.getWidth() + "x" + upstreamSurface.getHeight() + ", " + us_s+ "]";
     }
 
 }
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLWrappedSurface.java b/src/jogl/classes/jogamp/opengl/egl/EGLWrappedSurface.java
new file mode 100644
index 0000000..b363033
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLWrappedSurface.java
@@ -0,0 +1,26 @@
+package jogamp.opengl.egl;
+
+import javax.media.nativewindow.NativeSurface;
+
+import jogamp.nativewindow.WrappedSurface;
+
+public class EGLWrappedSurface extends WrappedSurface {
+
+    public static EGLWrappedSurface get(NativeSurface surface) {
+        if(surface instanceof EGLWrappedSurface) {
+            return (EGLWrappedSurface)surface;
+        }
+        return new EGLWrappedSurface(surface);
+    }
+    
+    public EGLWrappedSurface(NativeSurface surface) {
+        super(surface.getGraphicsConfiguration(), EGL.EGL_NO_SURFACE, new EGLUpstreamSurfaceHook(surface), false /* tbd in UpstreamSurfaceHook */);
+        if(EGLDrawableFactory.DEBUG) {
+            System.err.println("EGLWrappedSurface.ctor(): "+this);            
+        }
+    }
+
+    public final NativeSurface getUpstreamSurface() { 
+        return ((EGLUpstreamSurfaceHook)super.getUpstreamSurfaceHook()).getUpstreamSurface(); 
+    }    
+}
diff --git a/src/jogl/classes/jogamp/opengl/glu/GLUquadricImpl.java b/src/jogl/classes/jogamp/opengl/glu/GLUquadricImpl.java
index 3f8a765..62ff3aa 100644
--- a/src/jogl/classes/jogamp/opengl/glu/GLUquadricImpl.java
+++ b/src/jogl/classes/jogamp/opengl/glu/GLUquadricImpl.java
@@ -115,10 +115,11 @@
 
 package jogamp.opengl.glu;
 
-import javax.media.opengl.*;
-import javax.media.opengl.glu.*;
+import javax.media.opengl.GL;
+import javax.media.opengl.glu.GLU;
+import javax.media.opengl.glu.GLUquadric;
+
 import com.jogamp.opengl.util.ImmModeSink;
-import java.nio.*;
 
 /**
  * GLUquadricImpl.java
@@ -190,17 +191,19 @@ public class GLUquadricImpl implements GLUquadric {
 
     ImmModeSink res = immModeSink;
     if(useGLSL) {
-        immModeSink = ImmModeSink.createGLSL (gl, GL.GL_STATIC_DRAW, 32, 
-                                              3, GL.GL_FLOAT,  // vertex
-                                              0, GL.GL_FLOAT,  // color
-                                              USE_NORM?3:0, normalType,// normal
-                                              USE_TEXT?2:0, GL.GL_FLOAT); // texture
+        immModeSink = ImmModeSink.createGLSL (32, 
+                                              3, GL.GL_FLOAT,             // vertex 
+                                              0, GL.GL_FLOAT,             // color
+                                              USE_NORM?3:0, normalType,   // normal
+                                              USE_TEXT?2:0, GL.GL_FLOAT,  // texCoords
+                                              GL.GL_STATIC_DRAW);
     } else {
-        immModeSink = ImmModeSink.createFixed(gl, GL.GL_STATIC_DRAW, 32, 
-                                              3, GL.GL_FLOAT,  // vertex
-                                              0, GL.GL_FLOAT,  // color
-                                              USE_NORM?3:0, normalType,// normal
-                                              USE_TEXT?2:0, GL.GL_FLOAT); // texture
+        immModeSink = ImmModeSink.createFixed(32,
+                                              3, GL.GL_FLOAT,             // vertex
+                                              0, GL.GL_FLOAT,             // color
+                                              USE_NORM?3:0, normalType,   // normal
+                                              USE_TEXT?2:0, GL.GL_FLOAT,  // texCoords
+                                              GL.GL_STATIC_DRAW);
     }
     return res;
   }
@@ -430,7 +433,7 @@ public class GLUquadricImpl implements GLUquadric {
       r = baseRadius;
       for (j = 0; j < stacks; j++) {
         float s = 0.0f;
-        glBegin(gl, immModeSink.GL_QUAD_STRIP);
+        glBegin(gl, ImmModeSink.GL_QUAD_STRIP);
         for (i = 0; i <= slices; i++) {
           if (i == slices) {
             x = sin(0.0f);
@@ -514,7 +517,7 @@ public class GLUquadricImpl implements GLUquadric {
           float r2 = r1 + dr;
           if (orientation == GLU.GLU_OUTSIDE) {
             int s;
-            glBegin(gl, immModeSink.GL_QUAD_STRIP);
+            glBegin(gl, ImmModeSink.GL_QUAD_STRIP);
             for (s = 0; s <= slices; s++) {
               float a;
               if (s == slices)
@@ -532,7 +535,7 @@ public class GLUquadricImpl implements GLUquadric {
           }
           else {
             int s;
-            glBegin(gl, immModeSink.GL_QUAD_STRIP);
+            glBegin(gl, ImmModeSink.GL_QUAD_STRIP);
             for (s = slices; s >= 0; s--) {
               float a;
               if (s == slices)
@@ -655,11 +658,10 @@ public class GLUquadricImpl implements GLUquadric {
                               int loops,
                               float startAngle,
                               float sweepAngle) {
-    int i, j, max;
+    int i, j;
     float[] sinCache = new float[CACHE_SIZE];
     float[] cosCache = new float[CACHE_SIZE];
     float angle;
-    float x, y;
     float sintemp, costemp;
     float deltaRadius;
     float radiusLow, radiusHigh;
@@ -770,7 +772,7 @@ public class GLUquadricImpl implements GLUquadric {
           texHigh = radiusHigh / outerRadius / 2;
         }
 
-        glBegin(gl, immModeSink.GL_QUAD_STRIP);
+        glBegin(gl, ImmModeSink.GL_QUAD_STRIP);
         for (i = 0; i <= slices; i++) {
           if (orientation == GLU.GLU_OUTSIDE) {
             if (textureFlag) {
@@ -984,7 +986,7 @@ public class GLUquadricImpl implements GLUquadric {
       // draw intermediate stacks as quad strips
       for (i = imin; i < imax; i++) {
         rho = i * drho;
-        glBegin(gl, immModeSink.GL_QUAD_STRIP);
+        glBegin(gl, ImmModeSink.GL_QUAD_STRIP);
         s = 0.0f;
         for (j = 0; j <= slices; j++) {
           theta = (j == slices) ? 0.0f : j * dtheta;
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
index 82525cf..360b745 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
@@ -41,6 +41,7 @@
 package jogamp.opengl.macosx.cgl;
 
 import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
 import java.util.Map;
 
 import javax.media.nativewindow.AbstractGraphicsConfiguration;
@@ -49,23 +50,33 @@ import javax.media.nativewindow.NativeSurface;
 import javax.media.nativewindow.NativeWindowFactory;
 import javax.media.nativewindow.OffscreenLayerSurface;
 import javax.media.nativewindow.ProxySurface;
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GL3;
+import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLCapabilitiesImmutable;
 import javax.media.opengl.GLContext;
 import javax.media.opengl.GLException;
 import javax.media.opengl.GLProfile;
+import javax.media.opengl.GLUniformData;
 
 import jogamp.nativewindow.macosx.OSXUtil;
 import jogamp.opengl.GLContextImpl;
 import jogamp.opengl.GLDrawableImpl;
+import jogamp.opengl.GLFBODrawableImpl;
 import jogamp.opengl.GLGraphicsConfigurationUtil;
 import jogamp.opengl.macosx.cgl.MacOSXCGLDrawable.GLBackendType;
 
+import com.jogamp.common.nio.Buffers;
 import com.jogamp.common.nio.PointerBuffer;
 import com.jogamp.common.os.Platform;
 import com.jogamp.common.util.VersionNumber;
 import com.jogamp.gluegen.runtime.ProcAddressTable;
 import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
 import com.jogamp.opengl.GLExtensions;
+import com.jogamp.opengl.util.PMVMatrix;
+import com.jogamp.opengl.util.glsl.ShaderCode;
+import com.jogamp.opengl.util.glsl.ShaderProgram;
 
 public abstract class MacOSXCGLContext extends GLContextImpl
 {
@@ -75,9 +86,11 @@ public abstract class MacOSXCGLContext extends GLContextImpl
         boolean isNSContext();
         long create(long share, int ctp, int major, int minor);
         boolean destroy(long ctx);
+        boolean contextRealized(boolean realized);
         boolean copyImpl(long src, int mask);
         boolean makeCurrent(long ctx);
         boolean release(long ctx);
+        boolean detachPBuffer();
         boolean setSwapInterval(int interval);
         boolean swapBuffers();
   }
@@ -125,6 +138,39 @@ public abstract class MacOSXCGLContext extends GLContextImpl
     }
   }
 
+  private static final String shaderBasename = "texture01_xxx";
+  
+  private static ShaderProgram createCALayerShader(GL3 gl) {
+      // Create & Link the shader program
+      final ShaderProgram sp = new ShaderProgram();
+      final ShaderCode vp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, MacOSXCGLContext.class, 
+                                              "../../shader", "../../shader/bin", shaderBasename, true);
+      final ShaderCode fp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, MacOSXCGLContext.class, 
+                                              "../../shader", "../../shader/bin", shaderBasename, true);
+      vp.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_vp);
+      fp.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_fp);
+      sp.add(vp);
+      sp.add(fp);
+      if(!sp.link(gl, System.err)) {
+          throw new GLException("Couldn't link program: "+sp);
+      }
+      sp.useProgram(gl, true);
+
+      // setup mgl_PMVMatrix
+      final PMVMatrix pmvMatrix = new PMVMatrix();
+      pmvMatrix.glMatrixMode(PMVMatrix.GL_PROJECTION);
+      pmvMatrix.glLoadIdentity();
+      pmvMatrix.glMatrixMode(PMVMatrix.GL_MODELVIEW);
+      pmvMatrix.glLoadIdentity();       
+      final GLUniformData pmvMatrixUniform = new GLUniformData("mgl_PMVMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf()); // P, Mv
+      pmvMatrixUniform.setLocation( gl.glGetUniformLocation( sp.program(), pmvMatrixUniform.getName() ) );
+      gl.glUniform(pmvMatrixUniform);
+
+      sp.useProgram(gl, false);
+      return sp;
+  }
+      
+  
   private boolean haveSetOpenGLMode = false;
   private GLBackendType openGLMode = GLBackendType.NSOPENGL;
 
@@ -278,7 +324,24 @@ public abstract class MacOSXCGLContext extends GLContextImpl
         throw new GLException("Error destroying OpenGL Context: "+this);
     }
   }
+  
+  @Override
+  protected void contextRealized(boolean realized) {
+      // context stuff depends on drawable stuff
+      if(realized) {
+          super.contextRealized(true);   // 1) init drawable stuff
+          impl.contextRealized(true);    // 2) init context stuff
+      } else {
+          impl.contextRealized(false);   // 1) free context stuff
+          super.contextRealized(false);  // 2) free drawable stuff
+      }
+  }
 
+  /* pp */ void detachPBuffer() {
+      impl.detachPBuffer();
+  }
+
+  
   @Override
   protected void copyImpl(GLContext source, int mask) throws GLException {
     if( isNSContext() != ((MacOSXCGLContext)source).isNSContext() ) {
@@ -364,16 +427,6 @@ public abstract class MacOSXCGLContext extends GLContextImpl
     throw new GLException("Should not call this");
   }
 
-  @Override
-  public void bindPbufferToTexture() {
-    throw new GLException("Should not call this");
-  }
-
-  @Override
-  public void releasePbufferFromTexture() {
-    throw new GLException("Should not call this");
-  }
-
   // Support for "mode switching" as described in MacOSXCGLDrawable
   public void setOpenGLMode(GLBackendType mode) {
       if (mode == openGLMode) {
@@ -420,317 +473,495 @@ public abstract class MacOSXCGLContext extends GLContextImpl
 
   // NSOpenGLContext-based implementation
   class NSOpenGLImpl implements GLBackendImpl {
-    long nsOpenGLLayer = 0;
-    long nsOpenGLLayerPFmt = 0;
-    float screenVSyncTimeout; // microSec
-    int vsyncTimeout;    // microSec - for nsOpenGLLayer mode
-
-    @Override
-    public boolean isNSContext() { return true; }
-
-    @Override
-    public long create(long share, int ctp, int major, int minor) {
-        long ctx = 0;
-        final long nsViewHandle;
-        if(drawable instanceof MacOSXCGLDrawable) {
-            // we allow null here! (special pbuffer case)
-            nsViewHandle = ((MacOSXCGLDrawable)MacOSXCGLContext.this.drawable).getNSViewHandle();
-        } else {
-            // we only allow a valid NSView here
-            final long aHandle = drawable.getHandle();
-            if( OSXUtil.isNSView(aHandle) ) {
-                nsViewHandle = aHandle;
-            } else {
-                throw new RuntimeException("Anonymous drawable instance's handle not of type NSView: "+drawable.getClass().getName()+", "+drawable);
-            }
-        }
-        final NativeSurface surface = drawable.getNativeSurface();        
-        final MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) surface.getGraphicsConfiguration();
-        final OffscreenLayerSurface backingLayerHost = NativeWindowFactory.getOffscreenLayerSurface(surface, true);
-        
-        boolean allowIncompleteView = null != backingLayerHost;
-        if( !allowIncompleteView && surface instanceof ProxySurface ) {
-            allowIncompleteView = 0 != ( ProxySurface.INVISIBLE_WINDOW & ((ProxySurface)surface).getImplBitfield() ) ;
-        }
-        final GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
-        long pixelFormat = MacOSXCGLGraphicsConfiguration.GLCapabilities2NSPixelFormat(chosenCaps, ctp, major, minor);
-        if (pixelFormat == 0) {
-          if(DEBUG) {
-                System.err.println("Unable to allocate pixel format with requested GLCapabilities: "+chosenCaps);
-          }
-          return 0;
-        }
-        config.setChosenPixelFormat(pixelFormat);
-        int sRefreshRate = CGL.getScreenRefreshRate(drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getIndex());
-        screenVSyncTimeout = 1000000f / sRefreshRate;
-        if(DEBUG) {
-            System.err.println("NS create OSX>=lion "+isLionOrLater);
-            System.err.println("NS create allowIncompleteView: "+allowIncompleteView);
-            System.err.println("NS create backingLayerHost: "+backingLayerHost);
-            System.err.println("NS create share: "+share);
-            System.err.println("NS create chosenCaps: "+chosenCaps);
-            System.err.println("NS create pixelFormat: "+toHexString(pixelFormat));
-            System.err.println("NS create drawable native-handle: "+toHexString(drawable.getHandle()));
-            System.err.println("NS create drawable NSView-handle: "+toHexString(nsViewHandle));
-            System.err.println("NS create screen refresh-rate: "+sRefreshRate+" hz, "+screenVSyncTimeout+" micros");
-            // Thread.dumpStack();
-        }
-        try {
-          int[] viewNotReady = new int[1];
-          // Try to allocate a context with this
-          ctx = CGL.createContext(share,
-                                  nsViewHandle, allowIncompleteView,
-                                  pixelFormat,
-                                  chosenCaps.isBackgroundOpaque(),
-                                  viewNotReady, 0);
-          if (0 == ctx) {
-            if(DEBUG) {
-                System.err.println("NS create failed: viewNotReady: "+ (1 == viewNotReady[0]));
-            }
-            return 0;
-          }
+      private OffscreenLayerSurface backingLayerHost = null;
+      private long nsOpenGLLayer = 0;
+      private long nsOpenGLLayerPFmt = 0;
+      private float screenVSyncTimeout; // microSec
+      private int vsyncTimeout;    // microSec - for nsOpenGLLayer mode
+      private int lastWidth=0, lastHeight=0; // allowing to detect size change
+      private boolean needsSetContextPBuffer = false;
+      private ShaderProgram gl3ShaderProgram = null;
+      
+      @Override
+      public boolean isNSContext() { return true; }
+
+      @Override
+      public long create(long share, int ctp, int major, int minor) {
+          long ctx = 0;
+          final NativeSurface surface = drawable.getNativeSurface();        
+          final MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) surface.getGraphicsConfiguration();
+          final GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
+          final long nsViewHandle;
+          final boolean isPBuffer;
+          final boolean isFBO;
+          if(drawable instanceof GLFBODrawableImpl) {
+              nsViewHandle = 0;
+              isPBuffer = false;
+              isFBO = true;
+              if(DEBUG) {
+                  System.err.println("NS create GLFBODrawableImpl drawable: isFBO "+isFBO+", isPBuffer "+isPBuffer+", "+drawable.getClass().getName()+",\n\t"+drawable);
+              }
+          } else if(drawable instanceof MacOSXCGLDrawable) {
+              // we allow null here! (special pbuffer case)
+              nsViewHandle = ((MacOSXCGLDrawable)MacOSXCGLContext.this.drawable).getNSViewHandle();
+              isPBuffer = CGL.isNSOpenGLPixelBuffer(drawable.getHandle());
+              isFBO = false;
+              if(DEBUG) {
+                  System.err.println("NS create MacOSXCGLDrawable drawable handle isFBO "+isFBO+", isPBuffer "+isPBuffer+", "+drawable.getClass().getName()+",\n\t"+drawable);
+              }
+          } else {
+              // we only allow a valid NSView here
+              final long drawableHandle = drawable.getHandle();
+              final boolean isNSView = OSXUtil.isNSView(drawableHandle);
+              final boolean isNSWindow = OSXUtil.isNSWindow(drawableHandle);
+              isPBuffer = CGL.isNSOpenGLPixelBuffer(drawableHandle);
+              isFBO = false;
 
-          if (!chosenCaps.isPBuffer() && !chosenCaps.isBackgroundOpaque()) {
-              // Set the context opacity
-              CGL.setContextOpacity(ctx, 0);
+              if(DEBUG) {
+                  System.err.println("NS create Anonymous drawable handle "+toHexString(drawableHandle)+": isNSView "+isNSView+", isNSWindow "+isNSWindow+", isFBO "+isFBO+", isPBuffer "+isPBuffer+", "+drawable.getClass().getName()+",\n\t"+drawable);
+              }
+              if( isNSView ) {
+                  nsViewHandle = drawableHandle;
+              } else if( isNSWindow ) {
+                  nsViewHandle = OSXUtil.GetNSView(drawableHandle);
+              } else if( isPBuffer ) {
+                  nsViewHandle = 0;
+              } else {
+                  throw new RuntimeException("Anonymous drawable instance's handle neither NSView, NSWindow nor PBuffer: "+toHexString(drawableHandle)+", "+drawable.getClass().getName()+",\n\t"+drawable);
+              }
           }
+          needsSetContextPBuffer = isPBuffer;
+          backingLayerHost = NativeWindowFactory.getOffscreenLayerSurface(surface, true);
 
-          GLCapabilitiesImmutable fixedCaps = MacOSXCGLGraphicsConfiguration.NSPixelFormat2GLCapabilities(chosenCaps.getGLProfile(), pixelFormat);
+          boolean incompleteView = null != backingLayerHost;
+          if( !incompleteView && surface instanceof ProxySurface ) {
+              incompleteView = ((ProxySurface)surface).containsUpstreamOptionBits( ProxySurface.OPT_UPSTREAM_WINDOW_INVISIBLE );
+          }
+          long pixelFormat = MacOSXCGLGraphicsConfiguration.GLCapabilities2NSPixelFormat(chosenCaps, ctp, major, minor);
+          if (pixelFormat == 0) {
+              if(DEBUG) {
+                  System.err.println("Unable to allocate pixel format with requested GLCapabilities: "+chosenCaps);
+              }
+              return 0;
+          }
+          GLCapabilities fixedCaps = MacOSXCGLGraphicsConfiguration.NSPixelFormat2GLCapabilities(chosenCaps.getGLProfile(), pixelFormat);
+          if( !fixedCaps.isPBuffer() && isPBuffer ) {
+              throw new InternalError("handle is PBuffer, fixedCaps not: "+drawable);
+          }
+          { // determine on-/offscreen caps, since pformat is ambiguous 
+              fixedCaps.setFBO( isFBO );         // exclusive 
+              fixedCaps.setPBuffer( isPBuffer ); // exclusive
+              fixedCaps.setBitmap( false );      // n/a in our OSX impl.
+              fixedCaps.setOnscreen( !isFBO && !isPBuffer );
+          }
           fixedCaps = GLGraphicsConfigurationUtil.fixOpaqueGLCapabilities(fixedCaps, chosenCaps.isBackgroundOpaque());
-          config.setChosenCapabilities(fixedCaps);
+          int sRefreshRate = OSXUtil.GetScreenRefreshRate(drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getIndex());
+          screenVSyncTimeout = 1000000f / sRefreshRate;
           if(DEBUG) {
+              System.err.println("NS create OSX>=lion "+isLionOrLater);
+              System.err.println("NS create incompleteView: "+incompleteView);
+              System.err.println("NS create backingLayerHost: "+backingLayerHost);
+              System.err.println("NS create share: "+share);
+              System.err.println("NS create drawable type: "+drawable.getClass().getName());
+              System.err.println("NS create drawable handle: isPBuffer "+isPBuffer+", isFBO "+isFBO);
+              System.err.println("NS create pixelFormat: "+toHexString(pixelFormat));
+              System.err.println("NS create chosenCaps: "+chosenCaps);
               System.err.println("NS create fixedCaps: "+fixedCaps);
+              System.err.println("NS create drawable native-handle: "+toHexString(drawable.getHandle()));
+              System.err.println("NS create drawable NSView-handle: "+toHexString(nsViewHandle));
+              System.err.println("NS create screen refresh-rate: "+sRefreshRate+" hz, "+screenVSyncTimeout+" micros");
+              // Thread.dumpStack();
           }
-          if(fixedCaps.isPBuffer()) {
-              // Must now associate the pbuffer with our newly-created context
-              CGL.setContextPBuffer(ctx, drawable.getHandle());
-          }
-          //
-          // handled layered surface
-          //
+          config.setChosenCapabilities(fixedCaps);
+          /**
           if(null != backingLayerHost) {
-              nsOpenGLLayerPFmt = pixelFormat;
-              pixelFormat = 0;
-              final int texWidth, texHeight;
-              if(drawable instanceof MacOSXPbufferCGLDrawable) {
-                  final MacOSXPbufferCGLDrawable osxPDrawable = (MacOSXPbufferCGLDrawable)drawable;
-                  texWidth = osxPDrawable.getTextureWidth();
-                  texHeight = osxPDrawable.getTextureHeight();
-              } else {
-                  texWidth = drawable.getWidth();
-                  texHeight = drawable.getHeight();
+              backingLayerHost.setChosenCapabilities(fixedCaps);
+          }  */                  
+          
+          try {
+              final IntBuffer viewNotReady = Buffers.newDirectIntBuffer(1);
+              // Try to allocate a context with this
+              ctx = CGL.createContext(share,
+                      nsViewHandle, incompleteView,
+                      pixelFormat,
+                      chosenCaps.isBackgroundOpaque(),
+                      viewNotReady);
+              if (0 == ctx) {
+                  if(DEBUG) {
+                      System.err.println("NS create failed: viewNotReady: "+ (1 == viewNotReady.get(0)));
+                  }
+                  return 0;
               }
-              if(0>=texWidth || 0>=texHeight || !drawable.isRealized()) {
-                  throw new GLException("Drawable not realized yet or invalid texture size, texSize "+texWidth+"x"+texHeight+", "+drawable);
+
+              if(null != backingLayerHost) {
+                  nsOpenGLLayerPFmt = pixelFormat;
+                  pixelFormat = 0;
               }
-              nsOpenGLLayer = CGL.createNSOpenGLLayer(ctx, nsOpenGLLayerPFmt, drawable.getHandle(), fixedCaps.isBackgroundOpaque(), texWidth, texHeight);
-              if (DEBUG) {
-                  System.err.println("NS create nsOpenGLLayer "+toHexString(nsOpenGLLayer)+", texSize "+texWidth+"x"+texHeight+", "+drawable);
+              
+              if (chosenCaps.isOnscreen() && !chosenCaps.isBackgroundOpaque()) {
+                  // Set the context opacity
+                  CGL.setContextOpacity(ctx, 0);
+              }
+          } finally {
+              if(0!=pixelFormat) {
+                  CGL.deletePixelFormat(pixelFormat);
+                  pixelFormat = 0;
               }
-              backingLayerHost.attachSurfaceLayer(nsOpenGLLayer);
-              setSwapInterval(1); // enabled per default in layered surface
-          }
-        } finally {
-          if(0!=pixelFormat) {
-              CGL.deletePixelFormat(pixelFormat);
-          }
-        }
-        return ctx;
-    }
-
-    @Override
-    public boolean destroy(long ctx) {
-      if(0 != nsOpenGLLayer) {
-          final NativeSurface surface = drawable.getNativeSurface();
-          if (DEBUG) {
-              System.err.println("NS destroy nsOpenGLLayer "+toHexString(nsOpenGLLayer));
-          }
-          final OffscreenLayerSurface ols = NativeWindowFactory.getOffscreenLayerSurface(surface, true);
-          if(null != ols && ols.isSurfaceLayerAttached()) {
-              // still having a valid OLS attached to surface (parent OLS could have been removed)
-              ols.detachSurfaceLayer();
           }
-          CGL.releaseNSOpenGLLayer(nsOpenGLLayer); 
-          CGL.deletePixelFormat(nsOpenGLLayerPFmt);
-          nsOpenGLLayerPFmt = 0;
-          nsOpenGLLayer = 0;
+          return ctx;
       }
-      return CGL.deleteContext(ctx, true);
-    }
-
-    @Override
-    public boolean copyImpl(long src, int mask) {
-        CGL.copyContext(contextHandle, src, mask);
-        return true;
-    }
 
-    @Override
-    public boolean makeCurrent(long ctx) {
-      final long cglCtx = CGL.getCGLContext(ctx);
-      if(0 == cglCtx) {
-          throw new InternalError("Null CGLContext for: "+this);
+      @Override
+      public boolean destroy(long ctx) {
+          return CGL.deleteContext(ctx, true);
       }
-      int err = CGL.CGLLockContext(cglCtx);
-      if(CGL.kCGLNoError == err) {
-          return CGL.makeCurrentContext(ctx);
-      } else if(DEBUG) {
-          System.err.println("NSGL: Could not lock context: err 0x"+Integer.toHexString(err)+": "+this);
+
+      @Override
+      public boolean contextRealized(boolean realized) {
+          if( realized ) {
+              if( null != backingLayerHost ) {
+                  //
+                  // handled layered surface
+                  //
+                  final GLCapabilitiesImmutable chosenCaps = drawable.getChosenGLCapabilities();
+                  final long ctx = MacOSXCGLContext.this.getHandle();
+                  final int texID;
+                  final long drawableHandle = drawable.getHandle();
+                  final long pbufferHandle;
+                  if(drawable instanceof GLFBODrawableImpl) {
+                      final GLFBODrawableImpl fbod = (GLFBODrawableImpl)drawable;
+                      texID = fbod.getTextureBuffer(GL.GL_FRONT).getName();
+                      pbufferHandle = 0;
+                      fbod.setSwapBufferContext(new GLFBODrawableImpl.SwapBufferContext() {
+                          public void swapBuffers(boolean doubleBuffered) {
+                              MacOSXCGLContext.NSOpenGLImpl.this.swapBuffers();                            
+                          } } ) ;                    
+                  } else if( CGL.isNSOpenGLPixelBuffer(drawableHandle) ) {
+                      texID = 0;
+                      pbufferHandle = drawableHandle;
+                      if(0 != drawableHandle) { // complete 'validatePBufferConfig(..)' procedure
+                          CGL.setContextPBuffer(ctx, pbufferHandle);
+                          needsSetContextPBuffer = false;
+                      }
+                  } else {
+                      throw new GLException("BackingLayerHost w/ unknown handle (!FBO, !PBuffer): "+drawable);
+                  }
+                  lastWidth = drawable.getWidth();
+                  lastHeight = drawable.getHeight();
+                  if(0>=lastWidth || 0>=lastHeight || !drawable.isRealized()) {
+                      throw new GLException("Drawable not realized yet or invalid texture size, texSize "+lastWidth+"x"+lastHeight+", "+drawable);
+                  }
+                  final int gl3ShaderProgramName;
+                  if( MacOSXCGLContext.this.isGL3core() ) {
+                      if( null == gl3ShaderProgram) {
+                          gl3ShaderProgram = createCALayerShader(MacOSXCGLContext.this.gl.getGL3());
+                      }
+                      gl3ShaderProgramName = gl3ShaderProgram.program();
+                  } else {
+                      gl3ShaderProgramName = 0;
+                  }
+                  nsOpenGLLayer = CGL.createNSOpenGLLayer(ctx, gl3ShaderProgramName, nsOpenGLLayerPFmt, pbufferHandle, texID, chosenCaps.isBackgroundOpaque(), lastWidth, lastHeight);
+                  if (DEBUG) {
+                      System.err.println("NS create nsOpenGLLayer "+toHexString(nsOpenGLLayer)+" w/ pbuffer "+toHexString(pbufferHandle)+", texID "+texID+", texSize "+lastWidth+"x"+lastHeight+", "+drawable);
+                  }
+                  backingLayerHost.attachSurfaceLayer(nsOpenGLLayer);
+                  setSwapInterval(1); // enabled per default in layered surface                
+              } else {
+                  lastWidth = drawable.getWidth();
+                  lastHeight = drawable.getHeight();                  
+              }
+          } else {
+              if( 0 != nsOpenGLLayer ) {
+                  final NativeSurface surface = drawable.getNativeSurface();
+                  if (DEBUG) {
+                      System.err.println("NS destroy nsOpenGLLayer "+toHexString(nsOpenGLLayer)+", "+drawable);
+                  }
+                  final OffscreenLayerSurface ols = NativeWindowFactory.getOffscreenLayerSurface(surface, true);
+                  if(null != ols && ols.isSurfaceLayerAttached()) {
+                      // still having a valid OLS attached to surface (parent OLS could have been removed)
+                      ols.detachSurfaceLayer();
+                  }
+                  CGL.releaseNSOpenGLLayer(nsOpenGLLayer);
+                  if( null != gl3ShaderProgram ) {
+                      gl3ShaderProgram.destroy(MacOSXCGLContext.this.gl.getGL3());
+                      gl3ShaderProgram = null;
+                  }
+                  nsOpenGLLayer = 0;
+              }
+              if(0 != nsOpenGLLayerPFmt) {
+                  CGL.deletePixelFormat(nsOpenGLLayerPFmt);
+                  nsOpenGLLayerPFmt = 0;
+              }
+          }
+          backingLayerHost = null;
+          return true;
       }
-      return false;
-    }
 
-    @Override
-    public boolean release(long ctx) {
-      try {
-          gl.glFlush(); // w/o glFlush()/glFinish() OSX < 10.7 (NVidia driver) may freeze
-      } catch (GLException gle) {
-          if(DEBUG) {
-            System.err.println("MacOSXCGLContext.NSOpenGLImpl.release: INFO: glFlush() catched exception:");
-            gle.printStackTrace();
+      private final void validatePBufferConfig(long ctx) {
+          final long drawableHandle = drawable.getHandle();
+          if( needsSetContextPBuffer && 0 != drawableHandle && CGL.isNSOpenGLPixelBuffer(drawableHandle) ) {
+              // Must associate the pbuffer with our newly-created context
+              needsSetContextPBuffer = false;
+              CGL.setContextPBuffer(ctx, drawableHandle);
+              if(DEBUG) {
+                  System.err.println("NS.validateDrawableConfig bind pbuffer "+toHexString(drawableHandle)+" -> ctx "+toHexString(ctx)); 
+              }
           }
       }
-      final boolean res = CGL.clearCurrentContext(ctx);
-      final long cglCtx = CGL.getCGLContext(ctx);
-      if(0 == cglCtx) {
-          throw new InternalError("Null CGLContext for: "+this);
+      
+      /** Returns true if size has been updated, otherwise false (same size). */
+      private final boolean validateDrawableSizeConfig(long ctx) {
+          final int width = drawable.getWidth();
+          final int height = drawable.getHeight();
+          if( lastWidth != width || lastHeight != height ) {
+              lastWidth = drawable.getWidth();
+              lastHeight = drawable.getHeight();
+              if(DEBUG) {
+                  System.err.println("NS.validateDrawableConfig size changed"); 
+              }
+              return true;
+          }
+          return false;
       }
-      final int err = CGL.CGLUnlockContext(cglCtx);
-      if(DEBUG && CGL.kCGLNoError != err) {
-          System.err.println("CGL: Could not unlock context: err 0x"+Integer.toHexString(err)+": "+this);
+      
+      @Override
+      public boolean copyImpl(long src, int mask) {
+          CGL.copyContext(contextHandle, src, mask);
+          return true;
       }
-      return res && CGL.kCGLNoError == err;
-    }
 
-    @Override
-    public boolean setSwapInterval(int interval) {
-      if(0 != nsOpenGLLayer) {
-        CGL.setNSOpenGLLayerSwapInterval(nsOpenGLLayer, interval);
-        vsyncTimeout = interval * (int)screenVSyncTimeout;
-        if(DEBUG) { System.err.println("NS setSwapInterval: "+vsyncTimeout+" micros"); }
+      @Override
+      public boolean makeCurrent(long ctx) {
+          final long cglCtx = CGL.getCGLContext(ctx);
+          if(0 == cglCtx) {
+              throw new InternalError("Null CGLContext for: "+this);
+          }
+          int err = CGL.CGLLockContext(cglCtx);
+          if(CGL.kCGLNoError == err) {
+              validatePBufferConfig(ctx); // required to handle pbuffer change ASAP
+              return CGL.makeCurrentContext(ctx);
+          } else if(DEBUG) {
+              System.err.println("NSGL: Could not lock context: err 0x"+Integer.toHexString(err)+": "+this);
+          }
+          return false;
       }
-      CGL.setSwapInterval(contextHandle, interval);
-      return true;
-    }
 
-    @Override
-    public boolean swapBuffers() {
-      if( 0 != nsOpenGLLayer ) {
-        // If v-sync is disabled, frames will be drawn as quickly as possible
-        // w/o delay but in sync w/ CALayer. Otherwise wait until next swap interval (v-sync).
-        CGL.waitUntilNSOpenGLLayerIsReady(nsOpenGLLayer, vsyncTimeout);
+      @Override
+      public boolean release(long ctx) {
+          try {
+              gl.glFlush(); // w/o glFlush()/glFinish() OSX < 10.7 (NVidia driver) may freeze
+          } catch (GLException gle) {
+              if(DEBUG) {
+                  System.err.println("MacOSXCGLContext.NSOpenGLImpl.release: INFO: glFlush() catched exception:");
+                  gle.printStackTrace();
+              }
+          }
+          final boolean res = CGL.clearCurrentContext(ctx);
+          final long cglCtx = CGL.getCGLContext(ctx);
+          if(0 == cglCtx) {
+              throw new InternalError("Null CGLContext for: "+this);
+          }
+          final int err = CGL.CGLUnlockContext(cglCtx);
+          if(DEBUG && CGL.kCGLNoError != err) {
+              System.err.println("CGL: Could not unlock context: err 0x"+Integer.toHexString(err)+": "+this);
+          }
+          return res && CGL.kCGLNoError == err;
+      }
+
+      @Override
+      public boolean detachPBuffer() {
+          needsSetContextPBuffer = true;
+          // CGL.setContextPBuffer(contextHandle, 0); // doesn't work, i.e. not taking nil
+          return true;
       }
-      if(CGL.flushBuffer(contextHandle)) {
+      
+      @Override
+      public boolean setSwapInterval(int interval) {
           if(0 != nsOpenGLLayer) {
-              // trigger CALayer to update
-              CGL.setNSOpenGLLayerNeedsDisplay(nsOpenGLLayer);
+              CGL.setNSOpenGLLayerSwapInterval(nsOpenGLLayer, interval);
+              vsyncTimeout = interval * (int)screenVSyncTimeout + 1000; // +1ms
+              if(DEBUG) { System.err.println("NS setSwapInterval: "+vsyncTimeout+" micros"); }
           }
+          CGL.setSwapInterval(contextHandle, interval);
           return true;
       }
-      return false;
-    }
+
+      private int skipSync=0;
+      
+      @Override
+      public boolean swapBuffers() {
+          final boolean res;
+          if( 0 != nsOpenGLLayer ) {
+              if( validateDrawableSizeConfig(contextHandle) ) {
+                  // skip wait-for-vsync for a few frames if size has changed,
+                  // allowing to update the texture IDs ASAP.
+                  skipSync = 10;
+              }
+              
+              final int texID;
+              final boolean valid;
+              final boolean isFBO = drawable instanceof GLFBODrawableImpl;
+              if( isFBO ){
+                  texID = ((GLFBODrawableImpl)drawable).getTextureBuffer(GL.GL_FRONT).getName();
+                  valid = 0 != texID;
+              } else {
+                  texID = 0;
+                  valid = 0 != drawable.getHandle();
+              }
+              if(valid) {
+                  if(0 == skipSync) {
+                      // If v-sync is disabled, frames will be drawn as quickly as possible
+                      // w/o delay but in sync w/ CALayer. Otherwise wait until next swap interval (v-sync).
+                      CGL.waitUntilNSOpenGLLayerIsReady(nsOpenGLLayer, vsyncTimeout);
+                  } else {
+                      skipSync--;
+                  }
+                  res = CGL.flushBuffer(contextHandle);
+                  if(res) {
+                      if(isFBO) {
+                          // trigger CALayer to update incl. possible surface change (texture)
+                          CGL.setNSOpenGLLayerNeedsDisplayFBO(nsOpenGLLayer, texID);                          
+                      } else {
+                          // trigger CALayer to update incl. possible surface change (new pbuffer handle)
+                          CGL.setNSOpenGLLayerNeedsDisplayPBuffer(nsOpenGLLayer, drawable.getHandle());                          
+                      }
+                  }
+              } else {
+                  res = true;
+              }
+          } else {
+              res = CGL.flushBuffer(contextHandle);
+          }
+          return res;
+      }
+
   }
 
   class CGLImpl implements GLBackendImpl {
-    @Override
-    public boolean isNSContext() { return false; }
-
-    @Override
-    public long create(long share, int ctp, int major, int minor) {
-      long ctx = 0;
-      MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration();
-      GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable)config.getChosenCapabilities();
-      long pixelFormat = MacOSXCGLGraphicsConfiguration.GLCapabilities2CGLPixelFormat(chosenCaps, ctp, major, minor);
-      if (pixelFormat == 0) {
-        throw new GLException("Unable to allocate pixel format with requested GLCapabilities");
-      }
-      config.setChosenPixelFormat(pixelFormat);
-      try {
-          // Create new context
-          PointerBuffer ctxPB = PointerBuffer.allocateDirect(1);
-          if (DEBUG) {
-            System.err.println("Share context for CGL-based pbuffer context is " + toHexString(share));
-          }
-          int res = CGL.CGLCreateContext(pixelFormat, share, ctxPB);
-          if (res != CGL.kCGLNoError) {
-            throw new GLException("Error code " + res + " while creating context");
+      @Override
+      public boolean isNSContext() { return false; }
+
+      @Override
+      public long create(long share, int ctp, int major, int minor) {
+          long ctx = 0;
+          MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration();
+          GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable)config.getChosenCapabilities();
+          long pixelFormat = MacOSXCGLGraphicsConfiguration.GLCapabilities2CGLPixelFormat(chosenCaps, ctp, major, minor);
+          if (pixelFormat == 0) {
+              throw new GLException("Unable to allocate pixel format with requested GLCapabilities");
           }
-          if(chosenCaps.isPBuffer()) {
-              // Attach newly-created context to the pbuffer
-              res = CGL.CGLSetPBuffer(ctxPB.get(0), drawable.getHandle(), 0, 0, 0);
+          try {
+              // Create new context
+              PointerBuffer ctxPB = PointerBuffer.allocateDirect(1);
+              if (DEBUG) {
+                  System.err.println("Share context for CGL-based pbuffer context is " + toHexString(share));
+              }
+              int res = CGL.CGLCreateContext(pixelFormat, share, ctxPB);
               if (res != CGL.kCGLNoError) {
-                throw new GLException("Error code " + res + " while attaching context to pbuffer");
+                  throw new GLException("Error code " + res + " while creating context");
               }
-          }
-          ctx = ctxPB.get(0);
-          if(0!=ctx) {
-              if(DEBUG) {
-                  GLCapabilitiesImmutable caps0 = MacOSXCGLGraphicsConfiguration.CGLPixelFormat2GLCapabilities(pixelFormat);
-                  System.err.println("NS created: "+caps0);
+              ctx = ctxPB.get(0);
+
+              if (0 != ctx) {
+                  GLCapabilities fixedCaps = MacOSXCGLGraphicsConfiguration.CGLPixelFormat2GLCapabilities(pixelFormat);
+                  fixedCaps = GLGraphicsConfigurationUtil.fixOpaqueGLCapabilities(fixedCaps, chosenCaps.isBackgroundOpaque());
+                  { // determine on-/offscreen caps, since pformat is ambiguous 
+                      fixedCaps.setFBO( false );         // n/a for CGLImpl 
+                      fixedCaps.setPBuffer( fixedCaps.isPBuffer() && !chosenCaps.isOnscreen() );
+                      fixedCaps.setBitmap( false );      // n/a in our OSX impl.
+                      fixedCaps.setOnscreen( !fixedCaps.isPBuffer() );
+                  }
+                  config.setChosenCapabilities(fixedCaps);
+                  if(DEBUG) {
+                      System.err.println("CGL create fixedCaps: "+fixedCaps);
+                  }
+                  if(fixedCaps.isPBuffer()) {
+                      // Must now associate the pbuffer with our newly-created context
+                      res = CGL.CGLSetPBuffer(ctx, drawable.getHandle(), 0, 0, 0);
+                      if (res != CGL.kCGLNoError) {
+                          throw new GLException("Error code " + res + " while attaching context to pbuffer");
+                      }
+                  }              
               }
+          } finally {
+              CGL.CGLDestroyPixelFormat(pixelFormat);
           }
-      } finally {
-          CGL.CGLDestroyPixelFormat(pixelFormat);
+          return ctx;
       }
-      return ctx;
-    }
 
-    @Override
-    public boolean destroy(long ctx) {
-      return CGL.CGLDestroyContext(ctx) == CGL.kCGLNoError;
-    }
+      @Override
+      public boolean destroy(long ctx) {
+          return CGL.CGLDestroyContext(ctx) == CGL.kCGLNoError;
+      }
 
-    @Override
-    public boolean copyImpl(long src, int mask) {
-        CGL.CGLCopyContext(src, contextHandle, mask);
-        return true;
-    }
+      @Override
+      public boolean contextRealized(boolean realized) {
+          return true;
+      }
+
+      @Override
+      public boolean copyImpl(long src, int mask) {
+          CGL.CGLCopyContext(src, contextHandle, mask);
+          return true;
+      }
 
-    @Override
-    public boolean makeCurrent(long ctx) {
-      int err = CGL.CGLLockContext(ctx);
-      if(CGL.kCGLNoError == err) {
-          err = CGL.CGLSetCurrentContext(ctx);
+      @Override
+      public boolean makeCurrent(long ctx) {
+          int err = CGL.CGLLockContext(ctx);
           if(CGL.kCGLNoError == err) {
-              return true;
+              err = CGL.CGLSetCurrentContext(ctx);
+              if(CGL.kCGLNoError == err) {
+                  return true;
+              } else if(DEBUG) {
+                  System.err.println("CGL: Could not make context current: err 0x"+Integer.toHexString(err)+": "+this);
+              }
           } else if(DEBUG) {
-              System.err.println("CGL: Could not make context current: err 0x"+Integer.toHexString(err)+": "+this);
+              System.err.println("CGL: Could not lock context: err 0x"+Integer.toHexString(err)+": "+this);
           }
-      } else if(DEBUG) {
-          System.err.println("CGL: Could not lock context: err 0x"+Integer.toHexString(err)+": "+this);
+          return false;
       }
-      return false;
-    }
 
-    @Override
-    public boolean release(long ctx) {
-      try {
-          gl.glFlush(); // w/o glFlush()/glFinish() OSX < 10.7 (NVidia driver) may freeze
-      } catch (GLException gle) {
-          if(DEBUG) {
-            System.err.println("MacOSXCGLContext.CGLImpl.release: INFO: glFlush() catched exception:");
-            gle.printStackTrace();
+      @Override
+      public boolean release(long ctx) {
+          try {
+              gl.glFlush(); // w/o glFlush()/glFinish() OSX < 10.7 (NVidia driver) may freeze
+          } catch (GLException gle) {
+              if(DEBUG) {
+                  System.err.println("MacOSXCGLContext.CGLImpl.release: INFO: glFlush() catched exception:");
+                  gle.printStackTrace();
+              }
           }
+          int err = CGL.CGLSetCurrentContext(0);
+          if(DEBUG && CGL.kCGLNoError != err) {
+              System.err.println("CGL: Could not release current context: err 0x"+Integer.toHexString(err)+": "+this);
+          }
+          int err2 = CGL.CGLUnlockContext(ctx);
+          if(DEBUG && CGL.kCGLNoError != err2) {
+              System.err.println("CGL: Could not unlock context: err 0x"+Integer.toHexString(err2)+": "+this);
+          }
+          return CGL.kCGLNoError == err && CGL.kCGLNoError == err2;
+      }
+
+      @Override
+      public boolean detachPBuffer() {
+          /* Doesn't work, i.e. not taking NULL
+          final int res = CGL.CGLSetPBuffer(contextHandle, 0, 0, 0, 0);
+          if (res != CGL.kCGLNoError) {
+              throw new GLException("Error code " + res + " while detaching context from pbuffer");
+          } */
+          return true;
       }
-      int err = CGL.CGLSetCurrentContext(0);
-      if(DEBUG && CGL.kCGLNoError != err) {
-          System.err.println("CGL: Could not release current context: err 0x"+Integer.toHexString(err)+": "+this);
+      
+      @Override
+      public boolean setSwapInterval(int interval) {
+          final IntBuffer lval = Buffers.newDirectIntBuffer(1);
+          lval.put(0, interval);
+          CGL.CGLSetParameter(contextHandle, CGL.kCGLCPSwapInterval, lval);
+          return true;
       }
-      int err2 = CGL.CGLUnlockContext(ctx);
-      if(DEBUG && CGL.kCGLNoError != err2) {
-          System.err.println("CGL: Could not unlock context: err 0x"+Integer.toHexString(err2)+": "+this);
+      @Override
+      public boolean swapBuffers() {
+          return CGL.kCGLNoError == CGL.CGLFlushDrawable(contextHandle);
       }
-      return CGL.kCGLNoError == err && CGL.kCGLNoError == err2;
-    }
-
-    @Override
-    public boolean setSwapInterval(int interval) {
-        int[] lval = new int[] { interval } ;
-        CGL.CGLSetParameter(contextHandle, CGL.kCGLCPSwapInterval, lval, 0);
-        return true;
-    }
-    @Override
-    public boolean swapBuffers() {
-        return CGL.kCGLNoError == CGL.CGLFlushDrawable(contextHandle);
-    }
   }
 }
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java
index af767f0..cc727c8 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java
@@ -42,10 +42,10 @@ package jogamp.opengl.macosx.cgl;
 
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 
 import javax.media.nativewindow.NativeSurface;
+import javax.media.opengl.GLContext;
 import javax.media.opengl.GLDrawableFactory;
 import javax.media.opengl.GLException;
 
@@ -92,7 +92,7 @@ public abstract class MacOSXCGLDrawable extends GLDrawableImpl {
         this.id = id;
     }
   }
-  private List<WeakReference<MacOSXCGLContext>> createdContexts = new ArrayList<WeakReference<MacOSXCGLContext>>();
+  /* pp */ List<WeakReference<MacOSXCGLContext>> createdContexts = new ArrayList<WeakReference<MacOSXCGLContext>>();
 
   private boolean haveSetOpenGLMode = false;
   private GLBackendType openGLMode = GLBackendType.NSOPENGL;
@@ -110,26 +110,42 @@ public abstract class MacOSXCGLDrawable extends GLDrawableImpl {
       return GLBackendType.NSOPENGL == openGLMode ? getHandle() : 0;
   }
 
-  protected void registerContext(MacOSXCGLContext ctx) {
+  @Override
+  protected void associateContext(GLContext ctx, boolean bound) {
     // NOTE: we need to keep track of the created contexts in order to
     // implement swapBuffers() because of how Mac OS X implements its
     // OpenGL window interface
     synchronized (createdContexts) {
-      createdContexts.add(new WeakReference<MacOSXCGLContext>(ctx));
-    }
+        if(bound) {
+            createdContexts.add(new WeakReference<MacOSXCGLContext>((MacOSXCGLContext)ctx));
+        } else {
+            for(int i=0; i<createdContexts.size(); ) {
+                final WeakReference<MacOSXCGLContext> ref = createdContexts.get(i); 
+                final MacOSXCGLContext _ctx = ref.get();
+                if( _ctx == null || _ctx == ctx) {
+                    createdContexts.remove(i);
+                } else {
+                    i++;
+                }
+            }            
+        }
+    }      
   }
+  
   @Override
-  protected final void swapBuffersImpl() {
-    // single-buffer is already filtered out @ GLDrawableImpl#swapBuffers()
-    synchronized (createdContexts) {
-        for (Iterator<WeakReference<MacOSXCGLContext>> iter = createdContexts.iterator(); iter.hasNext(); ) {
-          WeakReference<MacOSXCGLContext> ref = iter.next();
-          MacOSXCGLContext ctx = ref.get();
-          if (ctx != null) {
-            ctx.swapBuffers();
-          } else {
-            iter.remove();
-          }
+  protected final void swapBuffersImpl(boolean doubleBuffered) {
+    if(doubleBuffered) { 
+        synchronized (createdContexts) {
+            for(int i=0; i<createdContexts.size(); ) {
+                final WeakReference<MacOSXCGLContext> ref = createdContexts.get(i); 
+                final MacOSXCGLContext ctx = ref.get();
+                if (ctx != null) {
+                    ctx.swapBuffers();
+                    i++;
+                } else {
+                    createdContexts.remove(i);
+                }
+            }
         }
     }
   }
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
index 9689d9f..ae2082d 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
@@ -41,17 +41,17 @@
 package jogamp.opengl.macosx.cgl;
 
 import java.nio.Buffer;
+import java.nio.FloatBuffer;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 
-import javax.media.nativewindow.AbstractGraphicsConfiguration;
 import javax.media.nativewindow.AbstractGraphicsDevice;
 import javax.media.nativewindow.AbstractGraphicsScreen;
 import javax.media.nativewindow.DefaultGraphicsScreen;
 import javax.media.nativewindow.NativeSurface;
 import javax.media.nativewindow.ProxySurface;
-import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook;
+import javax.media.nativewindow.UpstreamSurfaceHook;
 import javax.media.opengl.GL;
 import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLCapabilitiesChooser;
@@ -60,21 +60,22 @@ import javax.media.opengl.GLContext;
 import javax.media.opengl.GLDrawable;
 import javax.media.opengl.GLException;
 import javax.media.opengl.GLProfile;
-import javax.media.opengl.GLProfile.ShutdownType;
 
-import jogamp.nativewindow.macosx.OSXUtil;
+import jogamp.nativewindow.WrappedSurface;
+import jogamp.nativewindow.macosx.OSXDummyUpstreamSurfaceHook;
 import jogamp.opengl.DesktopGLDynamicLookupHelper;
-import jogamp.opengl.GLContextImpl;
 import jogamp.opengl.GLDrawableFactoryImpl;
 import jogamp.opengl.GLDrawableImpl;
 import jogamp.opengl.GLDynamicLookupHelper;
 import jogamp.opengl.GLGraphicsConfigurationUtil;
 
 import com.jogamp.common.JogampRuntimeException;
+import com.jogamp.common.nio.Buffers;
 import com.jogamp.common.util.ReflectionUtil;
-import com.jogamp.nativewindow.WrappedSurface;
+import com.jogamp.nativewindow.MutableGraphicsConfiguration;
 import com.jogamp.nativewindow.macosx.MacOSXGraphicsDevice;
 import com.jogamp.opengl.GLExtensions;
+import com.jogamp.opengl.GLRendererQuirks;
 
 public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
   private static DesktopGLDynamicLookupHelper macOSXCGLDynamicLookupHelper = null;
@@ -119,7 +120,12 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
   }
 
   @Override
-  protected final void destroy(ShutdownType shutdownType) {
+  protected final boolean isComplete() {
+      return null != macOSXCGLDynamicLookupHelper;
+  }
+    
+  @Override
+  protected final void destroy() {
     if(null != sharedMap) {
         sharedMap.clear();
         sharedMap = null;
@@ -128,10 +134,9 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
     /**
      * Pulling away the native library may cause havoc ..
      *
-    if(ShutdownType.COMPLETE == shutdownType && null != macOSXCGLDynamicLookupHelper) {
-        macOSXCGLDynamicLookupHelper.destroy();
-        macOSXCGLDynamicLookupHelper = null;
-    } */
+      macOSXCGLDynamicLookupHelper.destroy();
+     */
+    macOSXCGLDynamicLookupHelper = null;
   }
 
   @Override
@@ -145,6 +150,7 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
   static class SharedResource {
       // private MacOSXCGLDrawable drawable;
       // private MacOSXCGLContext context;
+      private GLRendererQuirks glRendererQuirks;
       MacOSXGraphicsDevice device;
       boolean wasContextCreated;
       boolean hasNPOTTextures;
@@ -153,9 +159,10 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
 
       SharedResource(MacOSXGraphicsDevice device, boolean wasContextCreated,
                      boolean hasNPOTTextures, boolean hasRECTTextures, boolean hasAppletFloatPixels
-                     /* MacOSXCGLDrawable draw, MacOSXCGLContext ctx */) {
+                     /* MacOSXCGLDrawable draw, MacOSXCGLContext ctx */, GLRendererQuirks glRendererQuirks) {
           // drawable = draw;
-          // context = ctx;
+          // this.context = ctx;
+          this.glRendererQuirks = glRendererQuirks;
           this.device = device;
           this.wasContextCreated = wasContextCreated;
           this.hasNPOTTextures = hasNPOTTextures;
@@ -163,6 +170,8 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
           this.hasAppleFloatPixels = hasAppletFloatPixels;
       }
       final MacOSXGraphicsDevice getDevice() { return device; }
+      // final MacOSXCGLContext getContext() { return context; }
+      final GLRendererQuirks getGLRendererQuirks() { return glRendererQuirks; }
       final boolean wasContextAvailable() { return wasContextCreated; }
       final boolean isNPOTTextureAvailable() { return hasNPOTTextures; }
       final boolean isRECTTextureAvailable() { return hasRECTTextures; }
@@ -209,6 +218,7 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
     if(null==sr && !getDeviceTried(connection)) {
         addDeviceTried(connection);
         final MacOSXGraphicsDevice sharedDevice = new MacOSXGraphicsDevice(adevice.getUnitID());
+        GLRendererQuirks glRendererQuirks = null;
         boolean madeCurrent = false;
         boolean hasNPOTTextures = false;
         boolean hasRECTTextures = false;
@@ -218,10 +228,11 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
             if (null == glp) {
                 throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice);
             }
-            final GLDrawableImpl sharedDrawable = createOnscreenDrawableImpl(createDummySurfaceImpl(sharedDevice, false, new GLCapabilities(glp), null, 64, 64));
+            final GLCapabilitiesImmutable caps = new GLCapabilities(glp);
+            final GLDrawableImpl sharedDrawable = createOnscreenDrawableImpl(createDummySurfaceImpl(sharedDevice, false, caps, caps, null, 64, 64));
             sharedDrawable.setRealized(true);
             
-            final GLContextImpl sharedContext  = (GLContextImpl) sharedDrawable.createContext(null);
+            final MacOSXCGLContext sharedContext = (MacOSXCGLContext) sharedDrawable.createContext(null);
             if (null == sharedContext) {
                 throw new GLException("Couldn't create shared context for drawable: "+sharedDrawable);
             }
@@ -234,6 +245,7 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
                     hasNPOTTextures = gl.isNPOTTextureAvailable();
                     hasRECTTextures = gl.isExtensionAvailable(GLExtensions.EXT_texture_rectangle);
                     hasAppleFloatPixels = gl.isExtensionAvailable(GLExtensions.APPLE_float_pixels);
+                    glRendererQuirks = sharedContext.getRendererQuirks();
                 }
             } catch (GLException gle) {
                 if (DEBUG) {
@@ -252,7 +264,7 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
             }
             sharedDrawable.setRealized(false);
         }
-        sr = new SharedResource(sharedDevice, madeCurrent, hasNPOTTextures, hasRECTTextures, hasAppleFloatPixels);
+        sr = new SharedResource(sharedDevice, madeCurrent, hasNPOTTextures, hasRECTTextures, hasAppleFloatPixels, glRendererQuirks);
         synchronized(sharedMap) {
             sharedMap.put(connection, sr);
         }
@@ -260,7 +272,7 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
         if (DEBUG) {
             System.err.println("MacOSXCGLDrawableFactory.createShared: device:  " + sharedDevice);
             System.err.println("MacOSXCGLDrawableFactory.createShared: context: madeCurrent " + madeCurrent + ", NPOT "+hasNPOTTextures+
-                               ", RECT "+hasRECTTextures+", FloatPixels "+hasAppleFloatPixels);
+                               ", RECT "+hasRECTTextures+", FloatPixels "+hasAppleFloatPixels+", "+glRendererQuirks);
         }
     }
     return sr;
@@ -289,11 +301,20 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
 
   @Override
   protected final GLContext getOrCreateSharedContextImpl(AbstractGraphicsDevice device) {
-      // FIXME: not implemented .. needs a dummy OSX surface
+      // FIXME: no more available
       return null;
   }
 
   @Override
+  public GLRendererQuirks getRendererQuirks(AbstractGraphicsDevice device) {
+      SharedResource sr = getOrCreateOSXSharedResource(device);
+      if(null!=sr) {
+          return sr.getGLRendererQuirks(); 
+      }
+      return null;
+  }
+  
+  @Override
   protected AbstractGraphicsDevice getOrCreateSharedDeviceImpl(AbstractGraphicsDevice device) {
       SharedResource sr = getOrCreateOSXSharedResource(device);
       if(null!=sr) {
@@ -317,9 +338,14 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
 
   @Override
   protected GLDrawableImpl createOffscreenDrawableImpl(NativeSurface target) {
-    AbstractGraphicsConfiguration config = target.getGraphicsConfiguration();
-    GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
+    final MutableGraphicsConfiguration config = (MutableGraphicsConfiguration) target.getGraphicsConfiguration();
+    final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
     if(!caps.isPBuffer()) {
+        // Actual implementation is using PBuffer ...
+        final GLCapabilities modCaps = (GLCapabilities) caps.cloneMutable();
+        modCaps.setPBuffer(true);
+        modCaps.setBitmap(false);
+        config.setChosenCapabilities(modCaps);
         return new MacOSXOffscreenCGLDrawable(this, target);
     }
     return new MacOSXPbufferCGLDrawable(this, target);
@@ -333,9 +359,9 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
   @Override
   protected ProxySurface createMutableSurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice, 
                                                   GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, 
-                                                  GLCapabilitiesChooser chooser, int width, int height, UpstreamSurfaceHook lifecycleHook) {
+                                                  GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstreamHook) {
     final MacOSXGraphicsDevice device;
-    if(createNewDevice) {
+    if( createNewDevice || !(deviceReq instanceof MacOSXGraphicsDevice) ) {
         device = new MacOSXGraphicsDevice(deviceReq.getUnitID());
     } else {
         device = (MacOSXGraphicsDevice)deviceReq;
@@ -345,68 +371,23 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
     if(null == config) {
         throw new GLException("Choosing GraphicsConfiguration failed w/ "+capsChosen+" on "+screen); 
     }    
-    return new WrappedSurface(config, 0, width, height, lifecycleHook);
+    return new WrappedSurface(config, 0, upstreamHook, createNewDevice);
   }
 
   @Override
   public final ProxySurface createDummySurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice, 
-                                                   GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) {
-    final GLCapabilitiesImmutable chosenCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(requestedCaps);
-    return createMutableSurfaceImpl(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, width, height, dummySurfaceLifecycleHook); 
+                                                   GLCapabilitiesImmutable chosenCaps, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) {
+    chosenCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(chosenCaps);
+    return createMutableSurfaceImpl(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, 
+                                    new OSXDummyUpstreamSurfaceHook(width, height)); 
   }  
-  private static final ProxySurface.UpstreamSurfaceHook dummySurfaceLifecycleHook = new ProxySurface.UpstreamSurfaceHook() {
-    long nsWindow = 0;
-    @Override
-    public final void create(ProxySurface s) {
-        if(0 == nsWindow && 0 == s.getSurfaceHandle()) {
-            nsWindow = OSXUtil.CreateNSWindow(0, 0, s.getWidth(), s.getHeight());
-            if(0 == nsWindow) {
-                throw new GLException("Error NS window 0");
-            }
-            long nsView = OSXUtil.GetNSView(nsWindow);
-            if(0 == nsView) {
-                throw new GLException("Error NS view 0");
-            }
-            s.setSurfaceHandle(nsView);
-            s.setImplBitfield(ProxySurface.INVISIBLE_WINDOW);
-            if(DEBUG) {
-                System.err.println("MacOSXCGLDrawableFactory.dummySurfaceLifecycleHook.create: "+s);
-            }
-        }
-    }
-    @Override
-    public final void destroy(ProxySurface s) {
-        if(0 != nsWindow && 0 != s.getSurfaceHandle()) {
-            OSXUtil.DestroyNSWindow(nsWindow);
-            nsWindow = 0;
-            s.setSurfaceHandle(0);
-            if(DEBUG) {
-                System.err.println("MacOSXCGLDrawableFactory.dummySurfaceLifecycleHook.destroy: "+s);
-            }
-        }
-    }
-    @Override
-    public final int getWidth(ProxySurface s) {
-        return s.initialWidth;
-    }
-    @Override
-    public final int getHeight(ProxySurface s) {
-        return s.initialHeight;
-    }
-    
-    @Override
-    public String toString() {
-       return "MacOSXLSurfaceLifecycleHook[]";
-    }
-    
-  };
   
   @Override
   protected ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice deviceReq, int screenIdx, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream) {
     final MacOSXGraphicsDevice device = new MacOSXGraphicsDevice(deviceReq.getUnitID());
     final AbstractGraphicsScreen screen = new DefaultGraphicsScreen(device, screenIdx);
     final MacOSXCGLGraphicsConfiguration config = MacOSXCGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsRequested, capsRequested, chooser, screen, true); 
-    return new WrappedSurface(config, windowHandle, 0, 0, upstream);
+    return new WrappedSurface(config, windowHandle, upstream, true);
   }
 
   @Override
@@ -451,10 +432,9 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
 
   @Override
   protected boolean setGammaRamp(float[] ramp) {
-    return CGL.setGammaRamp(ramp.length,
-                            ramp, 0,
-                            ramp, 0,
-                            ramp, 0);
+    final FloatBuffer rampNIO = Buffers.newDirectFloatBuffer(ramp);
+
+    return CGL.setGammaRamp(ramp.length, rampNIO, rampNIO, rampNIO);
   }
 
   @Override
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java
index 202644b..fa8e8d4 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java
@@ -36,6 +36,7 @@
 
 package jogamp.opengl.macosx.cgl;
 
+import java.nio.IntBuffer;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -47,27 +48,21 @@ import javax.media.opengl.GLException;
 import javax.media.opengl.GLProfile;
 
 
+import com.jogamp.common.nio.Buffers;
 import com.jogamp.common.nio.PointerBuffer;
 import com.jogamp.nativewindow.MutableGraphicsConfiguration;
 
 public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration implements Cloneable {
-    long pixelformat;
 
     MacOSXCGLGraphicsConfiguration(AbstractGraphicsScreen screen, 
-                                   GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested,
-                                   long pixelformat) {
+                                   GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested) {
         super(screen, capsChosen, capsRequested);
-        this.pixelformat=pixelformat;
     }
 
     public Object clone() {
         return super.clone();
     }
 
-    void setChosenPixelFormat(long pixelformat) {
-        this.pixelformat=pixelformat;
-    }
-
     protected static List<GLCapabilitiesImmutable> getAvailableCapabilities(MacOSXCGLDrawableFactory factory, AbstractGraphicsDevice device) {
         MacOSXCGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateOSXSharedResource(device);
         if(null == sharedResource) {
@@ -77,7 +72,7 @@ public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration
         return new ArrayList<GLCapabilitiesImmutable>(0);
     }
     
-    static final int[] cglInternalAttributeToken = new int[] {
+    static final IntBuffer cglInternalAttributeToken = Buffers.newDirectIntBuffer(new int[] {
         CGL.kCGLPFAOpenGLProfile,    // >= lion
         CGL.NSOpenGLPFAAccelerated,  // query only (prefer accelerated, but allow non accelerated), ignored for createPixelformat 
         CGL.NSOpenGLPFANoRecovery,
@@ -91,70 +86,65 @@ public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration
         CGL.NSOpenGLPFAAccumSize,
         CGL.NSOpenGLPFAStencilSize,
         CGL.NSOpenGLPFASampleBuffers,
-        CGL.NSOpenGLPFASamples };
+        CGL.NSOpenGLPFASamples });
 
-    static int[] GLCapabilities2NSAttribList(GLCapabilitiesImmutable caps, int ctp, int major, int minor) {
-        int len = cglInternalAttributeToken.length;
-        int off = 0;
-        if ( !MacOSXCGLContext.isLionOrLater ) {
-            // no OpenGLProfile
-            off++;
-            len--;
-        }        
-        int[] ivalues = new int[len];
+    static IntBuffer GLCapabilities2NSAttribList(IntBuffer attrToken, GLCapabilitiesImmutable caps, int ctp, int major, int minor) {
+        final int len = attrToken.remaining();
+        final int off = attrToken.position();
+        final IntBuffer ivalues = Buffers.newDirectIntBuffer(len);
 
         for (int idx = 0; idx < len; idx++) {
-          final int attr = cglInternalAttributeToken[idx+off];
+          final int attr = attrToken.get(idx+off);
           switch (attr) {
               case CGL.kCGLPFAOpenGLProfile: 
-                ivalues[idx] = MacOSXCGLContext.GLProfile2CGLOGLProfileValue(ctp, major, minor);
+                ivalues.put(idx, MacOSXCGLContext.GLProfile2CGLOGLProfileValue(ctp, major, minor));
                 break;
               case CGL.NSOpenGLPFANoRecovery:
-                ivalues[idx] = caps.getHardwareAccelerated() ? 1 : 0;
+                ivalues.put(idx, caps.getHardwareAccelerated() ? 1 : 0);
                 break;
                   
               case CGL.kCGLPFAColorFloat:
-                ivalues[idx] = caps.getPbufferFloatingPointBuffers() ? 1 : 0;
+                ivalues.put(idx, ( !caps.isOnscreen() && caps.isPBuffer() && caps.getPbufferFloatingPointBuffers() ) ? 1 : 0);
                 break;
 
               case CGL.NSOpenGLPFAPixelBuffer:
-                ivalues[idx] = caps.isPBuffer() ? 1 : 0;
+                ivalues.put(idx, ( !caps.isOnscreen() && caps.isPBuffer() ) ? 1 : 0);
                 break;
 
               case CGL.NSOpenGLPFADoubleBuffer:
-                ivalues[idx] = (caps.getDoubleBuffered() ? 1 : 0);
+                ivalues.put(idx, (caps.getDoubleBuffered() ? 1 : 0));
                 break;
 
               case CGL.NSOpenGLPFAStereo:
-                ivalues[idx] = (caps.getStereo() ? 1 : 0);
+                ivalues.put(idx, (caps.getStereo() ? 1 : 0));
                 break;
 
               case CGL.NSOpenGLPFAColorSize:
-                ivalues[idx] = (caps.getRedBits() + caps.getGreenBits() + caps.getBlueBits());
+                ivalues.put(idx, (caps.getRedBits() + caps.getGreenBits() + caps.getBlueBits()));
                 break;
 
               case CGL.NSOpenGLPFAAlphaSize:
-                ivalues[idx] = caps.getAlphaBits();
+                ivalues.put(idx, caps.getAlphaBits());
                 break;
 
               case CGL.NSOpenGLPFADepthSize:
-                ivalues[idx] = caps.getDepthBits();
+                ivalues.put(idx, caps.getDepthBits());
                 break;
 
               case CGL.NSOpenGLPFAAccumSize:
-                ivalues[idx] = (caps.getAccumRedBits() + caps.getAccumGreenBits() + caps.getAccumBlueBits() + caps.getAccumAlphaBits());
+                ivalues.put(idx, (caps.getAccumRedBits() + caps.getAccumGreenBits() + caps.getAccumBlueBits() + caps.getAccumAlphaBits()));
                 break;
 
               case CGL.NSOpenGLPFAStencilSize:
-                ivalues[idx] = caps.getStencilBits();
+                ivalues.put(idx, caps.getStencilBits());
                 break;
 
               case CGL.NSOpenGLPFASampleBuffers:
-                ivalues[idx] = caps.getSampleBuffers() ? 1 : 0;
+                ivalues.put(idx, caps.getSampleBuffers() ? 1 : 0);
                 break;
 
               case CGL.NSOpenGLPFASamples:
-                ivalues[idx] = caps.getNumSamples() ;
+                ivalues.put(idx, caps.getNumSamples());
                 break;
 
               default:
@@ -165,87 +155,88 @@ public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration
     }
 
     static long GLCapabilities2NSPixelFormat(GLCapabilitiesImmutable caps, int ctp, int major, int minor) {
-        int len = cglInternalAttributeToken.length;
-        int off = 0;
+        final IntBuffer attrToken = cglInternalAttributeToken.duplicate();
         if ( !MacOSXCGLContext.isLionOrLater ) {
             // no OpenGLProfile
-            off++;
-            len--;
+            attrToken.position(1);
         }        
-        int[] ivalues = GLCapabilities2NSAttribList(caps, ctp, major, minor);
-        return CGL.createPixelFormat(cglInternalAttributeToken, off, len, ivalues, 0);
+        final IntBuffer ivalues = GLCapabilities2NSAttribList(attrToken, caps, ctp, major, minor);
+        return CGL.createPixelFormat(attrToken, attrToken.remaining(), ivalues);
     }
 
-    static GLCapabilitiesImmutable NSPixelFormat2GLCapabilities(GLProfile glp, long pixelFormat) {
+    static GLCapabilities NSPixelFormat2GLCapabilities(GLProfile glp, long pixelFormat) {
         return PixelFormat2GLCapabilities(glp, pixelFormat, true);
     }
 
     static long GLCapabilities2CGLPixelFormat(GLCapabilitiesImmutable caps, int ctp, int major, int minor) {
       // Set up pixel format attributes
-      int[] attrs = new int[256];
+      final IntBuffer attrs = Buffers.newDirectIntBuffer(256);
       int i = 0;
       if(MacOSXCGLContext.isLionOrLater) {
-          attrs[i++] = CGL.kCGLPFAOpenGLProfile; 
-          attrs[i++] = MacOSXCGLContext.GLProfile2CGLOGLProfileValue(ctp, major, minor);
+          attrs.put(i++, CGL.kCGLPFAOpenGLProfile); 
+          attrs.put(i++, MacOSXCGLContext.GLProfile2CGLOGLProfileValue(ctp, major, minor));
       }
-      if(caps.isPBuffer()) {
-        attrs[i++] = CGL.kCGLPFAPBuffer;
-      }
-      if (caps.getPbufferFloatingPointBuffers()) {
-        attrs[i++] = CGL.kCGLPFAColorFloat;
+      if(!caps.isOnscreen() && caps.isPBuffer()) {
+        attrs.put(i++, CGL.kCGLPFAPBuffer);
+        if (caps.getPbufferFloatingPointBuffers()) {
+          attrs.put(i++, CGL.kCGLPFAColorFloat);
+        }
       }
       if (caps.getDoubleBuffered()) {
-        attrs[i++] = CGL.kCGLPFADoubleBuffer;
+        attrs.put(i++, CGL.kCGLPFADoubleBuffer);
       }
       if (caps.getStereo()) {
-        attrs[i++] = CGL.kCGLPFAStereo;
+        attrs.put(i++, CGL.kCGLPFAStereo);
       }
-      attrs[i++] = CGL.kCGLPFAColorSize;
-      attrs[i++] = (caps.getRedBits() +
-                    caps.getGreenBits() +
-                    caps.getBlueBits());
-      attrs[i++] = CGL.kCGLPFAAlphaSize;
-      attrs[i++] = caps.getAlphaBits();
-      attrs[i++] = CGL.kCGLPFADepthSize;
-      attrs[i++] = caps.getDepthBits();
+      attrs.put(i++, CGL.kCGLPFAColorSize);
+      attrs.put(i++, ( caps.getRedBits() +
+                       caps.getGreenBits() +
+                       caps.getBlueBits() ) );
+      attrs.put(i++, CGL.kCGLPFAAlphaSize);
+      attrs.put(i++, caps.getAlphaBits());
+      attrs.put(i++, CGL.kCGLPFADepthSize);
+      attrs.put(i++, caps.getDepthBits());
       // FIXME: should validate stencil size as is done in MacOSXWindowSystemInterface.m
-      attrs[i++] = CGL.kCGLPFAStencilSize;
-      attrs[i++] = caps.getStencilBits();
-      attrs[i++] = CGL.kCGLPFAAccumSize;
-      attrs[i++] = (caps.getAccumRedBits() +
-                    caps.getAccumGreenBits() +
-                    caps.getAccumBlueBits() +
-                    caps.getAccumAlphaBits());
+      attrs.put(i++, CGL.kCGLPFAStencilSize);
+      attrs.put(i++, caps.getStencilBits());
+      attrs.put(i++, CGL.kCGLPFAAccumSize);
+      attrs.put(i++, ( caps.getAccumRedBits() +
+                       caps.getAccumGreenBits() +
+                       caps.getAccumBlueBits() +
+                       caps.getAccumAlphaBits() ) );
       if (caps.getSampleBuffers()) {
-        attrs[i++] = CGL.kCGLPFASampleBuffers;
-        attrs[i++] = 1;
-        attrs[i++] = CGL.kCGLPFASamples;
-        attrs[i++] = caps.getNumSamples();
+        attrs.put(i++, CGL.kCGLPFASampleBuffers);
+        attrs.put(i++, 1);
+        attrs.put(i++, CGL.kCGLPFASamples);
+        attrs.put(i++, caps.getNumSamples());
       }
 
       // Use attribute array to select pixel format
       PointerBuffer fmt = PointerBuffer.allocateDirect(1);
-      int[] numScreens = new int[1];
-      int res = CGL.CGLChoosePixelFormat(attrs, 0, fmt, numScreens, 0);
+      IntBuffer numScreens = Buffers.newDirectIntBuffer(1);
+      int res = CGL.CGLChoosePixelFormat(attrs, fmt, numScreens);
       if (res != CGL.kCGLNoError) {
         throw new GLException("Error code " + res + " while choosing pixel format");
       }
       return fmt.get(0);
     }
     
-    static GLCapabilitiesImmutable CGLPixelFormat2GLCapabilities(long pixelFormat) {        
+    static GLCapabilities CGLPixelFormat2GLCapabilities(long pixelFormat) {        
         return PixelFormat2GLCapabilities(null, pixelFormat, false);
     }
 
-    private static GLCapabilitiesImmutable PixelFormat2GLCapabilities(GLProfile glp, long pixelFormat, boolean nsUsage) {
-        int len = cglInternalAttributeToken.length;
-        int off = 0;
+    private static GLCapabilities PixelFormat2GLCapabilities(GLProfile glp, long pixelFormat, boolean nsUsage) {
+        final IntBuffer attrToken = cglInternalAttributeToken.duplicate();
+        final int off;
         if ( !MacOSXCGLContext.isLionOrLater ) {
             // no OpenGLProfile
-            off++;
-            len--;
+            off = 1;
+        } else {
+            off = 0;
         }        
-        int[] ivalues = new int[len];
+        attrToken.position(off);
+        final int len = attrToken.remaining();
+        final IntBuffer ivalues = Buffers.newDirectIntBuffer(len);
 
         // On this platform the pixel format is associated with the
         // context and not the drawable. However it's a reasonable
@@ -256,15 +247,17 @@ public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration
 
         // Figure out what attributes we really got
         if(nsUsage) {
-            CGL.queryPixelFormat(pixelFormat, cglInternalAttributeToken, off, len, ivalues, 0);
+            CGL.queryPixelFormat(pixelFormat, attrToken, len, ivalues);
         } else {
-            CGL.CGLQueryPixelFormat(pixelFormat, cglInternalAttributeToken, off, len, ivalues, 0);
+            CGL.CGLQueryPixelFormat(pixelFormat, attrToken, len, ivalues);
         }
+        
         if(null == glp && MacOSXCGLContext.isLionOrLater) {
             // pre-scan for OpenGL Profile
             for (int i = 0; i < len; i++) {
-                if(CGL.kCGLPFAOpenGLProfile == cglInternalAttributeToken[i+off]) {
-                    switch(ivalues[i]) {
+                final int ivalue = ivalues.get(i);
+                if(CGL.kCGLPFAOpenGLProfile == attrToken.get(i+off)) {
+                    switch(ivalue) {
                         case CGL.kCGLOGLPVersion_3_2_Core:
                             glp = GLProfile.get(GLProfile.GL3);
                             break;
@@ -272,7 +265,7 @@ public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration
                             glp = GLProfile.get(GLProfile.GL2);
                             break;                            
                         default:
-                            throw new RuntimeException("Unhandled OSX OpenGL Profile: 0x"+Integer.toHexString(ivalues[i]));
+                            throw new RuntimeException("Unhandled OSX OpenGL Profile: 0x"+Integer.toHexString(ivalue));
                     }
                 }            
             }
@@ -280,37 +273,35 @@ public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration
         if(null == glp) {
             glp = GLProfile.get(GLProfile.GL2);
         }
-        GLCapabilities caps = new GLCapabilities(glp);
+        final GLCapabilities caps = new GLCapabilities(glp);
         int alphaBits = 0;
         for (int i = 0; i < len; i++) {
-          int attr = cglInternalAttributeToken[i+off];
+          final int attr = attrToken.get(i+off);
+          final int ivalue = ivalues.get(i);
           switch (attr) {
               case CGL.NSOpenGLPFAAccelerated:
-                caps.setHardwareAccelerated(ivalues[i] != 0);
+                caps.setHardwareAccelerated(ivalue != 0);
                 break;
                 
               case CGL.kCGLPFAColorFloat:
-                caps.setPbufferFloatingPointBuffers(ivalues[i] != 0);
+                caps.setPbufferFloatingPointBuffers(ivalue != 0);
                 break;
 
               case CGL.NSOpenGLPFAPixelBuffer:
-                caps.setPBuffer(ivalues[i] != 0);
+                caps.setPBuffer(ivalue != 0);
                 break;
 
               case CGL.NSOpenGLPFADoubleBuffer:
-                caps.setDoubleBuffered(ivalues[i] != 0);
+                caps.setDoubleBuffered(ivalue != 0);
                 break;
 
               case CGL.NSOpenGLPFAStereo:
-                caps.setStereo(ivalues[i] != 0);
+                caps.setStereo(ivalue != 0);
                 break;
 
               case CGL.NSOpenGLPFAColorSize:
                 {
-                  int bitSize = ivalues[i];
-                  if (bitSize == 32)
-                    bitSize = 24;
-                  bitSize /= 3;
+                  final int bitSize = ( 32 == ivalue ? 24 : ivalue ) / 3;
                   caps.setRedBits(bitSize);
                   caps.setGreenBits(bitSize);
                   caps.setBlueBits(bitSize);
@@ -319,16 +310,16 @@ public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration
 
               case CGL.NSOpenGLPFAAlphaSize:
                 // ALPHA shall be set at last - due to it's auto setting by !opaque / samples
-                alphaBits = ivalues[i];
+                alphaBits = ivalue;
                 break;
 
               case CGL.NSOpenGLPFADepthSize:
-                caps.setDepthBits(ivalues[i]);
+                caps.setDepthBits(ivalue);
                 break;
 
               case CGL.NSOpenGLPFAAccumSize:
                 {
-                  int bitSize = ivalues[i] / 4;
+                  final int bitSize = ivalue / 4;
                   caps.setAccumRedBits(bitSize);
                   caps.setAccumGreenBits(bitSize);
                   caps.setAccumBlueBits(bitSize);
@@ -337,15 +328,15 @@ public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration
                 break;
 
               case CGL.NSOpenGLPFAStencilSize:
-                caps.setStencilBits(ivalues[i]);
+                caps.setStencilBits(ivalue);
                 break;
 
               case CGL.NSOpenGLPFASampleBuffers:
-                caps.setSampleBuffers(ivalues[i] != 0);
+                caps.setSampleBuffers(ivalue != 0);
                 break;
 
               case CGL.NSOpenGLPFASamples:
-                caps.setNumSamples(ivalues[i]);
+                caps.setNumSamples(ivalue);
                 break;
 
               default:
@@ -353,7 +344,7 @@ public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration
           }
         }
         caps.setAlphaBits(alphaBits);
-
+        
         return caps;
       }
 }
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java
index f138e75..3bbba2c 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java
@@ -34,13 +34,17 @@
 package jogamp.opengl.macosx.cgl;
 
 import jogamp.opengl.GLGraphicsConfigurationFactory;
+import jogamp.opengl.GLGraphicsConfigurationUtil;
+
 import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsDevice;
 import javax.media.nativewindow.AbstractGraphicsScreen;
 import javax.media.nativewindow.CapabilitiesChooser;
 import javax.media.nativewindow.CapabilitiesImmutable;
 import javax.media.nativewindow.GraphicsConfigurationFactory;
 import javax.media.opengl.GLCapabilitiesChooser;
 import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLDrawableFactory;
 
 
 /** Subclass of GraphicsConfigurationFactory used when non-AWT tookits
@@ -58,13 +62,7 @@ public class MacOSXCGLGraphicsConfigurationFactory extends GLGraphicsConfigurati
     protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl(
             CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested,
             CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen, int nativeVisualID) {
-        return chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, absScreen, false);
-    }
-
-    static MacOSXCGLGraphicsConfiguration chooseGraphicsConfigurationStatic(CapabilitiesImmutable capsChosen,
-                                                                            CapabilitiesImmutable capsRequested,
-                                                                            CapabilitiesChooser chooser,
-                                                                            AbstractGraphicsScreen absScreen, boolean usePBuffer) {
+        
         if (absScreen == null) {
             throw new IllegalArgumentException("AbstractGraphicsScreen is null");
         }
@@ -77,11 +75,23 @@ public class MacOSXCGLGraphicsConfigurationFactory extends GLGraphicsConfigurati
             throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilities objects - requested");
         }
 
-        if (chooser != null &&
-            !(chooser instanceof GLCapabilitiesChooser)) {
+        if (chooser != null && !(chooser instanceof GLCapabilitiesChooser)) {
             throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilitiesChooser objects");
         }
+        
+        return chooseGraphicsConfigurationStatic((GLCapabilitiesImmutable)capsChosen, (GLCapabilitiesImmutable)capsRequested, (GLCapabilitiesChooser)chooser, absScreen, false);
+    }
 
-        return new MacOSXCGLGraphicsConfiguration(absScreen, (GLCapabilitiesImmutable)capsChosen, (GLCapabilitiesImmutable)capsRequested, 0);
+    static MacOSXCGLGraphicsConfiguration chooseGraphicsConfigurationStatic(GLCapabilitiesImmutable capsChosen,
+                                                                            GLCapabilitiesImmutable capsRequested,
+                                                                            GLCapabilitiesChooser chooser,
+                                                                            AbstractGraphicsScreen absScreen, boolean usePBuffer) {
+        if (absScreen == null) {
+            throw new IllegalArgumentException("AbstractGraphicsScreen is null");
+        }
+        final AbstractGraphicsDevice device = absScreen.getDevice();
+        capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, GLDrawableFactory.getDesktopFactory(), device);
+        
+        return new MacOSXCGLGraphicsConfiguration(absScreen, (GLCapabilitiesImmutable)capsChosen, (GLCapabilitiesImmutable)capsRequested);
     }
 }
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java
index 6be9e38..65ed5fc 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java
@@ -49,8 +49,8 @@ import javax.media.opengl.GLContext;
 import javax.media.opengl.GLDrawableFactory;
 import javax.media.opengl.GLException;
 
-import com.jogamp.nativewindow.WrappedSurface;
 
+import jogamp.nativewindow.WrappedSurface;
 import jogamp.opengl.GLContextImpl;
 import jogamp.opengl.GLContextShareSet;
 import jogamp.opengl.macosx.cgl.MacOSXCGLDrawable.GLBackendType;
@@ -62,7 +62,6 @@ public class MacOSXExternalCGLContext extends MacOSXCGLContext {
   private MacOSXExternalCGLContext(Drawable drawable, boolean isNSContext, long handle) {
     super(drawable, null);
     setOpenGLMode(isNSContext ? GLBackendType.NSOPENGL : GLBackendType.CGL );
-    drawable.registerContext(this);
     this.contextHandle = handle;
     GLContextShareSet.contextCreated(this);
     setGLFunctionAvailability(false, 0, 0, CTX_PROFILE_COMPAT);
@@ -108,13 +107,13 @@ public class MacOSXExternalCGLContext extends MacOSXCGLContext {
     }
 
     AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_MACOSX);
-    MacOSXCGLGraphicsConfiguration cfg = new MacOSXCGLGraphicsConfiguration(aScreen, caps, caps, pixelFormat);
+    MacOSXCGLGraphicsConfiguration cfg = new MacOSXCGLGraphicsConfiguration(aScreen, caps, caps);
 
     if(0 == currentDrawable) {
         // set a fake marker stating a valid drawable
         currentDrawable = 1;
     }
-    WrappedSurface ns = new WrappedSurface(cfg, currentDrawable, 64, 64, null);
+    WrappedSurface ns = new WrappedSurface(cfg, currentDrawable, 64, 64, true);
     return new MacOSXExternalCGLContext(new Drawable(factory, ns), isNSContext, contextHandle);
   }
 
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLContext.java
index e344fd4..447d18f 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLContext.java
@@ -39,6 +39,8 @@
 
 package jogamp.opengl.macosx.cgl;
 
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.ProxySurface;
 import javax.media.opengl.GLContext;
 import javax.media.opengl.GLException;
 
@@ -60,7 +62,7 @@ public class MacOSXOnscreenCGLContext extends MacOSXCGLContext {
   @Override
   protected void drawableUpdatedNotify() throws GLException {
     final int w = drawable.getWidth();
-    final int h = drawable.getHeight();
+    final int h = drawable.getHeight();    
     final boolean updateContext = ( 0!=updateHandle && CGL.updateContextNeedsUpdate(updateHandle) ) ||
                                   w != lastWidth || h != lastHeight;
     if(updateContext) {
@@ -82,9 +84,18 @@ public class MacOSXOnscreenCGLContext extends MacOSXCGLContext {
         if(0 != updateHandle) {
             throw new InternalError("XXX1");
         }
-        updateHandle = CGL.updateContextRegister(contextHandle, drawable.getHandle());
-        if(0 == updateHandle) {
-            throw new InternalError("XXX2");
+        final boolean incompleteView;
+        final NativeSurface surface = drawable.getNativeSurface();
+        if( surface instanceof ProxySurface ) {
+          incompleteView = ((ProxySurface)surface).containsUpstreamOptionBits( ProxySurface.OPT_UPSTREAM_WINDOW_INVISIBLE );
+        } else {
+          incompleteView = false;
+        }
+        if(!incompleteView) {        
+            updateHandle = CGL.updateContextRegister(contextHandle, drawable.getHandle());
+            if(0 == updateHandle) {
+                throw new InternalError("XXX2");
+            }
         }
     }
     return res;
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLDrawable.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLDrawable.java
index b1e283e..ec96280 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLDrawable.java
@@ -52,9 +52,7 @@ public class MacOSXOnscreenCGLDrawable extends MacOSXCGLDrawable {
 
   @Override
   public GLContext createContext(GLContext shareWith) {
-    final MacOSXOnscreenCGLContext ctx= new MacOSXOnscreenCGLContext(this, shareWith);
-    registerContext(ctx);
-    return ctx;
+    return new MacOSXOnscreenCGLContext(this, shareWith);
   }
 
 }
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLContext.java
index 88886dd..7e2d8cf 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLContext.java
@@ -39,6 +39,7 @@ import javax.media.opengl.GLPbuffer;
 
 import jogamp.opengl.GLContextImpl;
 
+ at SuppressWarnings("deprecation")
 public class MacOSXPbufferCGLContext extends MacOSXCGLContext {
 
   // State for render-to-texture and render-to-texture-rectangle support
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java
index 8f2f386..668e463 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java
@@ -40,6 +40,8 @@
 
 package jogamp.opengl.macosx.cgl;
 
+import java.lang.ref.WeakReference;
+
 import javax.media.nativewindow.DefaultGraphicsConfiguration;
 import javax.media.nativewindow.NativeSurface;
 import javax.media.nativewindow.MutableSurface;
@@ -70,9 +72,6 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable {
   // private int textureTarget; // e.g. GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_NV
   // private int texture;       // actual texture object
 
-  // Note that we can not store this in the NativeSurface because the
-  // semantic is that contains an NSView
-  protected long pBuffer;
   protected int pBufferTexTarget, pBufferTexWidth, pBufferTexHeight;
 
   public MacOSXPbufferCGLDrawable(GLDrawableFactory factory, NativeSurface target) {
@@ -90,9 +89,7 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable {
 
   @Override
   public GLContext createContext(GLContext shareWith) {
-    final MacOSXPbufferCGLContext ctx = new MacOSXPbufferCGLContext(this, shareWith);
-    registerContext(ctx);
-    return ctx;
+    return new MacOSXPbufferCGLContext(this, shareWith);
   }
   
   @Override
@@ -101,27 +98,34 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable {
     return 0;
   }
 
-  @Override
-  public long getHandle() {
-    return pBuffer;
-  }
-
   protected int getTextureTarget() { return pBufferTexTarget;  }
   protected int getTextureWidth() { return pBufferTexWidth; }
   protected int getTextureHeight() { return pBufferTexHeight; }
 
   protected void destroyPbuffer() {
-    if (this.pBuffer != 0) {
-      NativeSurface ns = getNativeSurface();
+    final MutableSurface ms = (MutableSurface) getNativeSurface();
+    final long pBuffer = ms.getSurfaceHandle();
+    if (0 != pBuffer) {
+      synchronized (createdContexts) {
+        for(int i=0; i<createdContexts.size(); ) {
+          final WeakReference<MacOSXCGLContext> ref = createdContexts.get(i); 
+          final MacOSXCGLContext ctx = ref.get();
+          if (ctx != null) {
+            ctx.detachPBuffer();
+            i++;
+          } else {
+            createdContexts.remove(i);
+          }
+        }
+      }
       impl.destroy(pBuffer);
-      this.pBuffer = 0;
-      ((MutableSurface)ns).setSurfaceHandle(0);
+      ms.setSurfaceHandle(0);
     }
   }
 
   private void createPbuffer() {
-    final NativeSurface ns = getNativeSurface();
-    final DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) ns.getGraphicsConfiguration();
+    final MutableSurface ms = (MutableSurface) getNativeSurface();
+    final DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) ms.getGraphicsConfiguration();
     final GLCapabilitiesImmutable capabilities = (GLCapabilitiesImmutable)config.getChosenCapabilities();
     final GLProfile glProfile = capabilities.getGLProfile();
     MacOSXCGLDrawableFactory.SharedResource sr = ((MacOSXCGLDrawableFactory)factory).getOrCreateOSXSharedResource(config.getScreen().getDevice());
@@ -161,7 +165,7 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable {
       }
     }
 
-    pBuffer = impl.create(pBufferTexTarget, internalFormat, getWidth(), getHeight());
+    final long pBuffer = impl.create(pBufferTexTarget, internalFormat, getWidth(), getHeight());
     if(DEBUG) {
         System.err.println("MacOSXPbufferCGLDrawable tex: target "+toHexString(pBufferTexTarget)+
                             ", pbufferSize "+getWidth()+"x"+getHeight()+
@@ -174,7 +178,7 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable {
       throw new GLException("pbuffer creation error: CGL.createPBuffer() failed");
     }
 
-    ((MutableSurface)ns).setSurfaceHandle(pBuffer);
+    ms.setSurfaceHandle(pBuffer);
   }
 
   @Override
diff --git a/src/jogl/classes/jogamp/opengl/shader/texture01_xxx.fp b/src/jogl/classes/jogamp/opengl/shader/texture01_xxx.fp
new file mode 100644
index 0000000..8b30b65
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/shader/texture01_xxx.fp
@@ -0,0 +1,19 @@
+// Copyright 2012 JogAmp Community. All rights reserved.
+
+#if __VERSION__ >= 130
+  #define varying in
+  out vec4 mgl_FragColor;
+  #define texture2D texture
+#else
+  #define mgl_FragColor gl_FragColor   
+#endif
+
+varying  vec2          mgl_texCoord;
+
+uniform sampler2D      mgl_Texture0;
+
+void main (void)
+{
+  mgl_FragColor = texture2D(mgl_Texture0, mgl_texCoord);
+}
+
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texture01_xxx.vp b/src/jogl/classes/jogamp/opengl/shader/texture01_xxx.vp
similarity index 64%
copy from src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texture01_xxx.vp
copy to src/jogl/classes/jogamp/opengl/shader/texture01_xxx.vp
index c521e37..d9ef6b4 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texture01_xxx.vp
+++ b/src/jogl/classes/jogamp/opengl/shader/texture01_xxx.vp
@@ -1,17 +1,19 @@
 // Copyright 2012 JogAmp Community. All rights reserved.
 
+#if __VERSION__ >= 130
+  #define attribute in
+  #define varying out
+#endif
+
 uniform   mat4    mgl_PMVMatrix[2];
-// uniform  mat4  mgl_STMatrix;
+
 attribute vec4    mgl_Vertex;
-attribute vec4    mgl_Color;
 attribute vec4    mgl_MultiTexCoord;
-varying   vec4    frontColor;
+
 varying   vec2    mgl_texCoord;
 
 void main(void)
 {
-  frontColor=mgl_Color;
-  // mgl_texCoord = (mgl_STMatrix * mgl_MultiTexCoord).st;
   mgl_texCoord = mgl_MultiTexCoord.st;
   gl_Position = mgl_PMVMatrix[0] * mgl_PMVMatrix[1] * mgl_Vertex;
 }
diff --git a/src/jogl/classes/jogamp/opengl/util/GLArrayHandler.java b/src/jogl/classes/jogamp/opengl/util/GLArrayHandler.java
index 22690b0..a6314a2 100644
--- a/src/jogl/classes/jogamp/opengl/util/GLArrayHandler.java
+++ b/src/jogl/classes/jogamp/opengl/util/GLArrayHandler.java
@@ -37,18 +37,29 @@ import javax.media.opengl.*;
  */
 public interface GLArrayHandler {
 
+    
   /**
-   * Implementation shall associate the data with the array
-   * and synchronize the data with the GPU.
+   * if <code>bind</code> is true and the data uses VBO, 
+   * the latter will be bound and data written to the GPU if required.
+   * <p>
+   * If  <code>bind</code> is false and the data uses VBO,
+   * the latter will be unbound.
+   * </p>
    * 
    * @param gl current GL object
-   * @param enable true if array data shall be valid, otherwise false.
-   * @param ext extension object allowing passing of an implementation detail 
+   * @param bind true if VBO shall be bound and data written, 
+   *        otherwise clear VBO binding.
+   * @return true if data uses VBO and action was performed, otherwise false 
    */
-  public void syncData(GL gl, boolean enable, Object ext);
+  public boolean bindBuffer(GL gl, boolean bind);
   
   /**
    * Implementation shall enable or disable the array state.
+   * <p>
+   * Before enabling the array state,
+   * implementation shall synchronize the data with the GPU
+   * and associate the data with the array.
+   * </p>
    * 
    * @param gl current GL object
    * @param enable true if array shall be enabled, otherwise false.
diff --git a/src/jogl/classes/jogamp/opengl/util/GLArrayHandlerFlat.java b/src/jogl/classes/jogamp/opengl/util/GLArrayHandlerFlat.java
index dca9129..4a8f406 100644
--- a/src/jogl/classes/jogamp/opengl/util/GLArrayHandlerFlat.java
+++ b/src/jogl/classes/jogamp/opengl/util/GLArrayHandlerFlat.java
@@ -41,11 +41,9 @@ public interface GLArrayHandlerFlat {
    * Implementation shall associate the data with the array
    * 
    * @param gl current GL object
-   * @param enable true if array data shall be valid, otherwise false.
-   * @param force true force data association, bypassing optimization
    * @param ext extension object allowing passing of an implementation detail 
    */
-  public void syncData(GL gl, boolean enable, boolean force, Object ext);
+  public void syncData(GL gl, Object ext);
   
   /**
    * Implementation shall enable or disable the array state.
diff --git a/src/jogl/classes/jogamp/opengl/util/GLArrayHandlerInterleaved.java b/src/jogl/classes/jogamp/opengl/util/GLArrayHandlerInterleaved.java
index d31b415..98f711b 100644
--- a/src/jogl/classes/jogamp/opengl/util/GLArrayHandlerInterleaved.java
+++ b/src/jogl/classes/jogamp/opengl/util/GLArrayHandlerInterleaved.java
@@ -28,8 +28,6 @@
 
 package jogamp.opengl.util;
 
-
-import java.nio.Buffer;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -41,12 +39,11 @@ import com.jogamp.opengl.util.GLArrayDataEditable;
  * Interleaved fixed function arrays, i.e. where this buffer data 
  * represents many arrays. 
  */
-public class GLArrayHandlerInterleaved implements GLArrayHandler {
-  private GLArrayDataEditable ad;
+public class GLArrayHandlerInterleaved extends GLVBOArrayHandler implements GLArrayHandler {
   private List<GLArrayHandlerFlat> subArrays = new ArrayList<GLArrayHandlerFlat>();
 
   public GLArrayHandlerInterleaved(GLArrayDataEditable ad) {
-    this.ad = ad;
+    super(ad);
   }
   
   public final void setSubArrayVBOName(int vboName) {
@@ -59,37 +56,20 @@ public class GLArrayHandlerInterleaved implements GLArrayHandler {
       subArrays.add(handler);
   }
 
-  private final void syncSubData(GL gl, boolean enable, boolean force, Object ext) {
+  private final void syncSubData(GL gl, Object ext) {
       for(int i=0; i<subArrays.size(); i++) {
-          subArrays.get(i).syncData(gl, enable, force, ext);
+          subArrays.get(i).syncData(gl, ext);
       }      
   }  
   
-  public final void syncData(GL gl, boolean enable, Object ext) {
+  public final void enableState(GL gl, boolean enable, Object ext) {
     if(enable) {
-        final Buffer buffer = ad.getBuffer();
-
-        if(ad.isVBO()) {
-            // always bind and refresh the VBO mgr, 
-            // in case more than one gl*Pointer objects are in use
-            gl.glBindBuffer(ad.getVBOTarget(), ad.getVBOName());
-            if(!ad.isVBOWritten()) {
-                if(null!=buffer) {
-                    gl.glBufferData(ad.getVBOTarget(), buffer.limit() * ad.getComponentSizeInBytes(), buffer, ad.getVBOUsage());
-                }
-                ad.setVBOWritten(true);
-            }
-        }
-        syncSubData(gl, true, true, ext);
-    } else {
-        syncSubData(gl, false, true, ext);
-        if(ad.isVBO()) {
-            gl.glBindBuffer(ad.getVBOTarget(), 0);
-        }
+        final boolean vboBound = bindBuffer(gl, true);
+        syncSubData(gl, ext);
+        if(vboBound) {
+            bindBuffer(gl, false);
+        }        
     }
-  }
-  
-  public final void enableState(GL gl, boolean enable, Object ext) {
     for(int i=0; i<subArrays.size(); i++) {
         subArrays.get(i).enableState(gl, enable, ext);
     }      
diff --git a/src/jogl/classes/jogamp/opengl/util/GLDataArrayHandler.java b/src/jogl/classes/jogamp/opengl/util/GLDataArrayHandler.java
index 6c8e2e7..862d49d 100644
--- a/src/jogl/classes/jogamp/opengl/util/GLDataArrayHandler.java
+++ b/src/jogl/classes/jogamp/opengl/util/GLDataArrayHandler.java
@@ -28,21 +28,20 @@
 
 package jogamp.opengl.util;
 
-import javax.media.opengl.*;
+import javax.media.opengl.GL;
+import javax.media.opengl.GLException;
 
-import com.jogamp.opengl.util.*;
+import com.jogamp.opengl.util.GLArrayDataEditable;
 
-import java.nio.*;
 
 /**
  * Used for pure VBO data arrays, i.e. where the buffer data 
  * does not represents a specific array name. 
  */
-public class GLDataArrayHandler implements GLArrayHandler {
-  private GLArrayDataEditable ad;
+public class GLDataArrayHandler extends GLVBOArrayHandler implements GLArrayHandler {
 
   public GLDataArrayHandler(GLArrayDataEditable ad) {
-    this.ad = ad;
+    super(ad);
   }
 
   public final void setSubArrayVBOName(int vboName) {
@@ -53,30 +52,16 @@ public class GLDataArrayHandler implements GLArrayHandler {
       throw new UnsupportedOperationException();
   }
   
-  public final void syncData(GL gl, boolean enable, Object ext) {
-    if(!ad.isVBO()) {
-        // makes no sense otherwise
-        throw new GLException("GLDataArrayHandler can only handle VBOs.");
-    }
+  public final void enableState(GL gl, boolean enable, Object ext) { 
     if(enable) {
-        Buffer buffer = ad.getBuffer();
-
-        // always bind and refresh the VBO mgr, 
-        // in case more than one gl*Pointer objects are in use
-        gl.glBindBuffer(ad.getVBOTarget(), ad.getVBOName());
-        if(!ad.isVBOWritten()) {
-            if(null!=buffer) {
-                gl.glBufferData(ad.getVBOTarget(), buffer.limit() * ad.getComponentSizeInBytes(), buffer, ad.getVBOUsage());
-            }
-            ad.setVBOWritten(true);
+        if(!ad.isVBO()) {
+            // makes no sense otherwise
+            throw new GLException("GLDataArrayHandler can only handle VBOs.");
         }
-    } else {
-        gl.glBindBuffer(ad.getVBOTarget(), 0);
-    }      
-  }
-  
-  public final void enableState(GL gl, boolean enable, Object ext) { 
-      // no array association
+        bindBuffer(gl, true);
+        bindBuffer(gl, false);
+    }
+    // no array association
   }
 }
 
diff --git a/src/jogl/classes/jogamp/opengl/util/GLFixedArrayHandler.java b/src/jogl/classes/jogamp/opengl/util/GLFixedArrayHandler.java
index d8939dc..32bba89 100644
--- a/src/jogl/classes/jogamp/opengl/util/GLFixedArrayHandler.java
+++ b/src/jogl/classes/jogamp/opengl/util/GLFixedArrayHandler.java
@@ -28,22 +28,19 @@
 
 package jogamp.opengl.util;
 
-import javax.media.opengl.*;
-import javax.media.opengl.fixedfunc.*;
+import javax.media.opengl.GL;
+import javax.media.opengl.GLException;
+import javax.media.opengl.fixedfunc.GLPointerFunc;
 
 import com.jogamp.opengl.util.GLArrayDataEditable;
 
-import java.nio.*;
-
 /**
  * Used for 1:1 fixed function arrays, i.e. where the buffer data 
  * represents this array only. 
  */
-public class GLFixedArrayHandler implements GLArrayHandler {
-  private GLArrayDataEditable ad;
-
+public class GLFixedArrayHandler extends GLVBOArrayHandler implements GLArrayHandler {
   public GLFixedArrayHandler(GLArrayDataEditable ad) {
-    this.ad = ad;
+    super(ad);
   }
   
   public final void setSubArrayVBOName(int vboName) {
@@ -54,21 +51,10 @@ public class GLFixedArrayHandler implements GLArrayHandler {
       throw new UnsupportedOperationException();
   }
   
-  public final void syncData(GL gl, boolean enable, Object ext) {
+  public final void enableState(GL gl, boolean enable, Object ext) {
+    final GLPointerFunc glp = gl.getGL2ES1();
     if(enable) {
-        final Buffer buffer = ad.getBuffer();
-        if(ad.isVBO()) {
-            // always bind and refresh the VBO mgr, 
-            // in case more than one gl*Pointer objects are in use
-            gl.glBindBuffer(ad.getVBOTarget(), ad.getVBOName());
-            if(!ad.isVBOWritten()) {
-                if(null!=buffer) {
-                    gl.glBufferData(ad.getVBOTarget(), buffer.limit() * ad.getComponentSizeInBytes(), buffer, ad.getVBOUsage());
-                }
-                ad.setVBOWritten(true);
-            }
-        }
-        final GLPointerFunc glp = gl.getGL2ES1();
+        final boolean vboBound = bindBuffer(gl, true);
         switch(ad.getIndex()) {
             case GLPointerFunc.GL_VERTEX_ARRAY:
                 glp.glVertexPointer(ad);
@@ -85,14 +71,9 @@ public class GLFixedArrayHandler implements GLArrayHandler {
             default:
                 throw new GLException("invalid glArrayIndex: "+ad.getIndex()+":\n\t"+ad); 
         }
-    } else if(ad.isVBO()) {
-        gl.glBindBuffer(ad.getVBOTarget(), 0);
-    }
-  }
-  
-  public final void enableState(GL gl, boolean enable, Object ext) {
-    final GLPointerFunc glp = gl.getGL2ES1();
-    if(enable) {
+        if(vboBound) {
+            bindBuffer(gl, false);
+        }        
         glp.glEnableClientState(ad.getIndex());        
     } else {
         glp.glDisableClientState(ad.getIndex());
diff --git a/src/jogl/classes/jogamp/opengl/util/GLFixedArrayHandlerFlat.java b/src/jogl/classes/jogamp/opengl/util/GLFixedArrayHandlerFlat.java
index 2937cc7..ff1813b 100644
--- a/src/jogl/classes/jogamp/opengl/util/GLFixedArrayHandlerFlat.java
+++ b/src/jogl/classes/jogamp/opengl/util/GLFixedArrayHandlerFlat.java
@@ -49,25 +49,23 @@ public class GLFixedArrayHandlerFlat implements GLArrayHandlerFlat {
       return ad;
   }
   
-  public final void syncData(GL gl, boolean enable, boolean force, Object ext) {
-    if(enable) {
-        final GLPointerFunc glp = gl.getGL2ES1();
-        switch(ad.getIndex()) {
-            case GLPointerFunc.GL_VERTEX_ARRAY:
-                glp.glVertexPointer(ad);
-                break;
-            case GLPointerFunc.GL_NORMAL_ARRAY:
-                glp.glNormalPointer(ad);
-                break;
-            case GLPointerFunc.GL_COLOR_ARRAY:
-                glp.glColorPointer(ad);
-                break;
-            case GLPointerFunc.GL_TEXTURE_COORD_ARRAY:
-                glp.glTexCoordPointer(ad);
-                break;
-            default:
-                throw new GLException("invalid glArrayIndex: "+ad.getIndex()+":\n\t"+ad); 
-        }
+  public final void syncData(GL gl, Object ext) {
+    final GLPointerFunc glp = gl.getGL2ES1();
+    switch(ad.getIndex()) {
+        case GLPointerFunc.GL_VERTEX_ARRAY:
+            glp.glVertexPointer(ad);
+            break;
+        case GLPointerFunc.GL_NORMAL_ARRAY:
+            glp.glNormalPointer(ad);
+            break;
+        case GLPointerFunc.GL_COLOR_ARRAY:
+            glp.glColorPointer(ad);
+            break;
+        case GLPointerFunc.GL_TEXTURE_COORD_ARRAY:
+            glp.glTexCoordPointer(ad);
+            break;
+        default:
+            throw new GLException("invalid glArrayIndex: "+ad.getIndex()+":\n\t"+ad); 
     }
   }
 
diff --git a/src/jogl/classes/jogamp/opengl/util/GLDataArrayHandler.java b/src/jogl/classes/jogamp/opengl/util/GLVBOArrayHandler.java
similarity index 69%
copy from src/jogl/classes/jogamp/opengl/util/GLDataArrayHandler.java
copy to src/jogl/classes/jogamp/opengl/util/GLVBOArrayHandler.java
index 6c8e2e7..ad88a70 100644
--- a/src/jogl/classes/jogamp/opengl/util/GLDataArrayHandler.java
+++ b/src/jogl/classes/jogamp/opengl/util/GLVBOArrayHandler.java
@@ -28,43 +28,36 @@
 
 package jogamp.opengl.util;
 
-import javax.media.opengl.*;
 
-import com.jogamp.opengl.util.*;
+import java.nio.Buffer;
+import java.util.ArrayList;
+import java.util.List;
 
-import java.nio.*;
+import javax.media.opengl.GL;
+
+import com.jogamp.opengl.util.GLArrayDataEditable;
 
 /**
- * Used for pure VBO data arrays, i.e. where the buffer data 
- * does not represents a specific array name. 
+ * Interleaved fixed function arrays, i.e. where this buffer data 
+ * represents many arrays. 
  */
-public class GLDataArrayHandler implements GLArrayHandler {
-  private GLArrayDataEditable ad;
+public abstract class GLVBOArrayHandler implements GLArrayHandler {
+  protected GLArrayDataEditable ad;
 
-  public GLDataArrayHandler(GLArrayDataEditable ad) {
+  public GLVBOArrayHandler(GLArrayDataEditable ad) {
     this.ad = ad;
   }
-
-  public final void setSubArrayVBOName(int vboName) {
-      throw new UnsupportedOperationException();
-  }
-  
-  public final void addSubHandler(GLArrayHandlerFlat handler) {
-      throw new UnsupportedOperationException();
-  }
   
-  public final void syncData(GL gl, boolean enable, Object ext) {
-    if(!ad.isVBO()) {
-        // makes no sense otherwise
-        throw new GLException("GLDataArrayHandler can only handle VBOs.");
+  public final boolean bindBuffer(GL gl, boolean bind) {
+    if( !ad.isVBO() ) {
+        return false;
     }
-    if(enable) {
-        Buffer buffer = ad.getBuffer();
-
+    if(bind) {
         // always bind and refresh the VBO mgr, 
         // in case more than one gl*Pointer objects are in use
         gl.glBindBuffer(ad.getVBOTarget(), ad.getVBOName());
         if(!ad.isVBOWritten()) {
+            final Buffer buffer = ad.getBuffer();
             if(null!=buffer) {
                 gl.glBufferData(ad.getVBOTarget(), buffer.limit() * ad.getComponentSizeInBytes(), buffer, ad.getVBOUsage());
             }
@@ -72,11 +65,9 @@ public class GLDataArrayHandler implements GLArrayHandler {
         }
     } else {
         gl.glBindBuffer(ad.getVBOTarget(), 0);
-    }      
+    }
+    return true;
   }
   
-  public final void enableState(GL gl, boolean enable, Object ext) { 
-      // no array association
-  }
 }
 
diff --git a/src/jogl/classes/jogamp/opengl/util/av/EGLMediaPlayerImpl.java b/src/jogl/classes/jogamp/opengl/util/av/EGLMediaPlayerImpl.java
index 6bf8839..274ccff 100644
--- a/src/jogl/classes/jogamp/opengl/util/av/EGLMediaPlayerImpl.java
+++ b/src/jogl/classes/jogamp/opengl/util/av/EGLMediaPlayerImpl.java
@@ -125,12 +125,12 @@ public abstract class EGLMediaPlayerImpl extends GLMediaPlayerImpl {
         }
 
         if(useKHRSync) {
-            int[] tmp = new int[1];
+            IntBuffer tmp = Buffers.newDirectIntBuffer(1);
             // Create sync object so that we can be sure that gl has finished
             // rendering the EGLImage texture before we tell OpenMAX to fill
             // it with a new frame.
-            tmp[0] = EGL.EGL_NONE;
-            sync = eglExt.eglCreateSyncKHR(eglDrawable.getNativeSurface().getDisplayHandle(), EGLExt.EGL_SYNC_FENCE_KHR, tmp, 0);
+            tmp.put(0, EGL.EGL_NONE);
+            sync = eglExt.eglCreateSyncKHR(eglDrawable.getNativeSurface().getDisplayHandle(), EGLExt.EGL_SYNC_FENCE_KHR, tmp);
             if (0==sync) {
                 throw new RuntimeException("EGLSync creation failed: "+EGL.eglGetError()+", ctx "+eglCtx+", err "+toHexString(EGL.eglGetError()));
             }
diff --git a/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java b/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java
index d3d45e6..27c9267 100644
--- a/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java
+++ b/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java
@@ -62,6 +62,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
     protected int textureCount;
     protected int textureTarget;
     protected int textureFormat;
+    protected int textureInternalFormat; 
     protected int textureType;
     protected int texUnit;
     
@@ -104,6 +105,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
         this.textureCount=3;
         this.textureTarget=GL.GL_TEXTURE_2D;
         this.textureFormat = GL.GL_RGBA;
+        this.textureInternalFormat = GL.GL_RGBA;
         this.textureType = GL.GL_UNSIGNED_BYTE;        
         this.texUnit = 0;
         this.state = State.Uninitialized;
@@ -122,7 +124,10 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
     public final int getTextureCount() { return textureCount; }
     
     protected final void setTextureTarget(int target) { textureTarget=target; }
-    protected final void setTextureFormat(int f) { textureFormat=f; }    
+    protected final void setTextureFormat(int internalFormat, int format) { 
+        textureInternalFormat=internalFormat; 
+        textureFormat=format; 
+    }    
     protected final void setTextureType(int t) { textureType=t; }
 
     public final void setTextureMinMagFilter(int[] minMagFilter) { texMinMagFilter[0] = minMagFilter[0]; texMinMagFilter[1] = minMagFilter[1];}
@@ -361,9 +366,9 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
             gl.glTexImage2D(
                     textureTarget,    // target
                     0,                // level
-                    GL.GL_RGBA,       // internal format
-                    tWidth,            // width
-                    tHeight,           // height
+                    textureInternalFormat, // internal format
+                    tWidth,           // width
+                    tHeight,          // height
                     0,                // border
                     textureFormat,
                     textureType,
diff --git a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGDynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGDynamicLibraryBundleInfo.java
index ce9df21..32c8635 100644
--- a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGDynamicLibraryBundleInfo.java
+++ b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGDynamicLibraryBundleInfo.java
@@ -222,6 +222,11 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo  {
 
         final List<String> avutil = new ArrayList<String>();
         avutil.add("avutil");        // default
+
+        avutil.add("libavutil.so.52");     // dummy future proof
+        avutil.add("libavutil.so.51");     // 0.8
+        avutil.add("libavutil.so.50");     // 0.7
+        
         avutil.add("avutil-52");     // dummy future proof
         avutil.add("avutil-51");     // 0.8
         avutil.add("avutil-50");     // 0.7
@@ -229,6 +234,12 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo  {
         
         final List<String> avformat = new ArrayList<String>();
         avformat.add("avformat");    // default
+
+        avformat.add("libavformat.so.55"); // dummy future proof
+        avformat.add("libavformat.so.54"); // 0.?
+        avformat.add("libavformat.so.53"); // 0.8
+        avformat.add("libavformat.so.52"); // 0.7
+        
         avformat.add("avformat-55"); // dummy future proof
         avformat.add("avformat-54"); // 0.?
         avformat.add("avformat-53"); // 0.8
@@ -237,6 +248,12 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo  {
         
         final List<String> avcodec = new ArrayList<String>();
         avcodec.add("avcodec");      // default
+
+        avcodec.add("libavcodec.so.55");   // dummy future proof
+        avcodec.add("libavcodec.so.54");   // 0.?
+        avcodec.add("libavcodec.so.53");   // 0.8
+        avcodec.add("libavcodec.so.52");   // 0.7        
+        
         avcodec.add("avcodec-55");   // dummy future proof
         avcodec.add("avcodec-54");   // 0.?
         avcodec.add("avcodec-53");   // 0.8
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 7d10cff..4be2bcb 100644
--- a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java
+++ b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java
@@ -192,14 +192,14 @@ public class FFMPEGMediaPlayer extends EGLMediaPlayerImpl {
         System.out.println("setURL: p1 "+this);
         setStream0(moviePtr, urlS, -1, -1);
         System.out.println("setURL: p2 "+this);
-        int tf;
+        int tf, tif=GL.GL_RGBA; // texture format and internal format
         switch(vBytesPerPixelPerPlane) {
-            case 1: tf = GL2ES2.GL_RED; break;
-            case 3: tf = GL2ES2.GL_RGB; break;
-            case 4: tf = GL2ES2.GL_RGBA; break;
+            case 1: tf = GL2ES2.GL_ALPHA; tif=GL.GL_ALPHA; break;
+            case 3: tf = GL2ES2.GL_RGB;   tif=GL.GL_RGB;   break;
+            case 4: tf = GL2ES2.GL_RGBA;  tif=GL.GL_RGBA;  break;
             default: throw new RuntimeException("Unsupported bytes-per-pixel / plane "+vBytesPerPixelPerPlane);
         }        
-        setTextureFormat(tf);
+        setTextureFormat(tif, tf);
         setTextureType(GL.GL_UNSIGNED_BYTE);
         GLContextImpl ctx = (GLContextImpl)gl.getContext();
         ProcAddressTable pt = ctx.getGLProcAddressTable();
@@ -296,9 +296,9 @@ public class FFMPEGMediaPlayer extends EGLMediaPlayerImpl {
               "  vec2 v_off = vec2("+tc_w_1+", 0.5);\n"+
               "  vec2 tc_half = texCoord*0.5;\n"+
               "  float y,u,v,r,g,b;\n"+
-              "  y = texture2D(image, texCoord).r;\n"+
-              "  u = texture2D(image, u_off+tc_half).r;\n"+
-              "  v = texture2D(image, v_off+tc_half).r;\n"+              
+              "  y = texture2D(image, texCoord).a;\n"+
+              "  u = texture2D(image, u_off+tc_half).a;\n"+
+              "  v = texture2D(image, v_off+tc_half).a;\n"+              
               "  y = 1.1643*(y-0.0625);\n"+
               "  u = u-0.5;\n"+
               "  v = v-0.5;\n"+
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandler.java b/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandler.java
index 602d283..79bed90 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandler.java
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandler.java
@@ -35,6 +35,7 @@ import javax.media.opengl.GL2ES2;
 
 import jogamp.opengl.util.GLArrayHandler;
 import jogamp.opengl.util.GLArrayHandlerFlat;
+import jogamp.opengl.util.GLVBOArrayHandler;
 
 import com.jogamp.opengl.util.GLArrayDataEditable;
 import com.jogamp.opengl.util.glsl.ShaderState;
@@ -43,11 +44,10 @@ import com.jogamp.opengl.util.glsl.ShaderState;
  * Used for 1:1 GLSL arrays, i.e. where the buffer data 
  * represents this array only. 
  */
-public class GLSLArrayHandler implements GLArrayHandler {
-  private GLArrayDataEditable ad;
-
+public class GLSLArrayHandler extends GLVBOArrayHandler implements GLArrayHandler {
+    
   public GLSLArrayHandler(GLArrayDataEditable ad) {
-    this.ad = ad;
+    super(ad);
   }
   
   public final void setSubArrayVBOName(int vboName) {
@@ -58,12 +58,11 @@ public class GLSLArrayHandler implements GLArrayHandler {
       throw new UnsupportedOperationException();
   }
   
-  public final void syncData(GL gl, boolean enable, Object ext) {
+  public final void enableState(GL gl, boolean enable, Object ext) {
     final GL2ES2 glsl = gl.getGL2ES2();
-    final ShaderState st = (ShaderState) ext;
+    final ShaderState st = (ShaderState) ext;    
     
     if(enable) {
-        final Buffer buffer = ad.getBuffer();
         /*
          * This would be the non optimized code path:
          * 
@@ -78,6 +77,7 @@ public class GLSLArrayHandler implements GLArrayHandler {
         }
         st.vertexAttribPointer(glsl, ad);
         */
+        final Buffer buffer = ad.getBuffer();
         if(ad.isVBO()) {
             // bind and refresh the VBO / vertex-attr only if necessary
             if(!ad.isVBOWritten()) {
@@ -87,6 +87,7 @@ public class GLSLArrayHandler implements GLArrayHandler {
                 }
                 ad.setVBOWritten(true);
                 st.vertexAttribPointer(glsl, ad);
+                glsl.glBindBuffer(ad.getVBOTarget(), 0);
             } else if(st.getAttribLocation(glsl, ad) >= 0) {
                 // didn't experience a performance hit on this query ..
                 // (using ShaderState's location query above to validate the location)
@@ -95,26 +96,17 @@ public class GLSLArrayHandler implements GLArrayHandler {
                 if(ad.getVBOName() != qi[0]) {
                     glsl.glBindBuffer(ad.getVBOTarget(), ad.getVBOName());
                     st.vertexAttribPointer(glsl, ad);
+                    glsl.glBindBuffer(ad.getVBOTarget(), 0);
                 }
             }
         } else if(null!=buffer) {
             st.vertexAttribPointer(glsl, ad);
         }
-    } else if(ad.isVBO()) {
-        glsl.glBindBuffer(ad.getVBOTarget(), 0);
-    }      
-  }
-  
-  public final void enableState(GL gl, boolean enable, Object ext) {
-    final GL2ES2 glsl = gl.getGL2ES2();
-    final ShaderState st = (ShaderState) ext;
-    
-    if(enable) {
+        
         st.enableVertexAttribArray(glsl, ad);
     } else {
         st.disableVertexAttribArray(glsl, ad);
     }
   }
-
 }
 
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandlerFlat.java b/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandlerFlat.java
index c4b761b..c5beb7d 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandlerFlat.java
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandlerFlat.java
@@ -51,28 +51,26 @@ public class GLSLArrayHandlerFlat implements GLArrayHandlerFlat {
       return ad;
   }
     
-  public final void syncData(GL gl, boolean enable, boolean force, Object ext) {
-    if(enable) {
-        final GL2ES2 glsl = gl.getGL2ES2();
-        final ShaderState st = (ShaderState) ext;
+  public final void syncData(GL gl, Object ext) {
+    final GL2ES2 glsl = gl.getGL2ES2();
+    final ShaderState st = (ShaderState) ext;
 
+    st.vertexAttribPointer(glsl, ad);
+    /**
+     * Due to probable application VBO switching, this might not make any sense ..
+     * 
+    if(!written) {
         st.vertexAttribPointer(glsl, ad);
-        /**
-         * Due to probable application VBO switching, this might not make any sense ..
-         * 
-        if(force) {
+    } else if(st.getAttribLocation(glsl, ad) >= 0) {
+        final int[] qi = new int[1];
+        glsl.glGetVertexAttribiv(ad.getLocation(), GL2ES2.GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, qi, 0);
+        if(ad.getVBOName() != qi[0]) {
+            System.err.println("XXX1: "+ad.getName()+", vbo ad "+ad.getVBOName()+", gl "+qi[0]+", "+ad);
             st.vertexAttribPointer(glsl, ad);
-        } else if(st.getAttribLocation(glsl, ad) >= 0) {
-            final int[] qi = new int[1];
-            glsl.glGetVertexAttribiv(ad.getLocation(), GL2ES2.GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, qi, 0);
-            if(ad.getVBOName() != qi[0]) {
-                System.err.println("XXX1: "+ad.getName()+", vbo ad "+ad.getVBOName()+", gl "+qi[0]+", "+ad);
-                st.vertexAttribPointer(glsl, ad);
-            } else {
-                System.err.println("XXX0: "+ad.getName()+", vbo ad "+ad.getVBOName()+", gl "+qi[0]+", "+ad);
-            }
-        }*/
-    }
+        } else {
+            System.err.println("XXX0: "+ad.getName()+", vbo ad "+ad.getVBOName()+", gl "+qi[0]+", "+ad);
+        }
+    }*/
   }
 
   public final void enableState(GL gl, boolean enable, Object ext) {
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandlerInterleaved.java b/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandlerInterleaved.java
index f504296..f36693e 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandlerInterleaved.java
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandlerInterleaved.java
@@ -28,7 +28,6 @@
 
 package jogamp.opengl.util.glsl;
 
-import java.nio.Buffer;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -36,6 +35,7 @@ import javax.media.opengl.GL;
 
 import jogamp.opengl.util.GLArrayHandler;
 import jogamp.opengl.util.GLArrayHandlerFlat;
+import jogamp.opengl.util.GLVBOArrayHandler;
 
 import com.jogamp.opengl.util.GLArrayDataEditable;
 
@@ -43,12 +43,11 @@ import com.jogamp.opengl.util.GLArrayDataEditable;
  * Interleaved fixed function arrays, i.e. where this buffer data 
  * represents many arrays. 
  */
-public class GLSLArrayHandlerInterleaved implements GLArrayHandler {
-  private GLArrayDataEditable ad;
+public class GLSLArrayHandlerInterleaved extends GLVBOArrayHandler implements GLArrayHandler {
   private List<GLArrayHandlerFlat> subArrays = new ArrayList<GLArrayHandlerFlat>();
 
   public GLSLArrayHandlerInterleaved(GLArrayDataEditable ad) {
-    this.ad = ad;
+    super(ad);
   }
   
   public final void setSubArrayVBOName(int vboName) {
@@ -61,39 +60,22 @@ public class GLSLArrayHandlerInterleaved implements GLArrayHandler {
       subArrays.add(handler);
   }
 
-  private final void syncSubData(GL gl, boolean enable, boolean force, Object ext) {
+  private final void syncSubData(GL gl, Object ext) {
       for(int i=0; i<subArrays.size(); i++) {
-          subArrays.get(i).syncData(gl, enable, force, ext);
+          subArrays.get(i).syncData(gl, ext);
       }      
   }  
   
-  public final void syncData(GL gl, boolean enable, Object ext) {    
-    if(!ad.isVBO()) {
-        throw new InternalError("Interleaved handle is not VBO: "+ad);
-    }
-    
+  public final void enableState(GL gl, boolean enable, Object ext) {
     if(enable) {
-        final Buffer buffer = ad.getBuffer();
-        final boolean vboWritten = ad.isVBOWritten();
-        
-        // always bind and refresh the VBO mgr, 
-        // in case more than one gl*Pointer objects are in use
-        gl.glBindBuffer(ad.getVBOTarget(), ad.getVBOName());
-        if(!vboWritten) {
-            if(null!=buffer) {
-                gl.glBufferData(ad.getVBOTarget(), buffer.limit() * ad.getComponentSizeInBytes(), buffer, ad.getVBOUsage());
-            }
-            ad.setVBOWritten(true);
+        if(!ad.isVBO()) {
+            throw new InternalError("Interleaved handle is not VBO: "+ad);
         }
+        bindBuffer(gl, true);
         // sub data will decide weather to update the vertex attrib pointer
-        syncSubData(gl, true, !vboWritten, ext);
-    } else {
-        // NOP on GLSL: syncSubData(gl, false, ext);
-        gl.glBindBuffer(ad.getVBOTarget(), 0);
+        syncSubData(gl, ext);
+        bindBuffer(gl, false);
     }
-  }
-  
-  public final void enableState(GL gl, boolean enable, Object ext) {
     for(int i=0; i<subArrays.size(); i++) {
         subArrays.get(i).enableState(gl, enable, ext);
     }      
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 897967f..351d7a1 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/FixedFuncHook.java
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/FixedFuncHook.java
@@ -29,48 +29,83 @@
 
 package jogamp.opengl.util.glsl.fixedfunc;
 
-import javax.media.opengl.*;
-import javax.media.opengl.fixedfunc.*;
-import com.jogamp.common.nio.Buffers;
-import com.jogamp.opengl.util.*;
+import java.nio.Buffer;
+import java.nio.IntBuffer;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLArrayData;
+import javax.media.opengl.GLException;
+import javax.media.opengl.fixedfunc.GLLightingFunc;
+import javax.media.opengl.fixedfunc.GLMatrixFunc;
+import javax.media.opengl.fixedfunc.GLPointerFunc;
 
-import java.nio.*;
+import com.jogamp.common.nio.Buffers;
+import com.jogamp.common.util.ValueConv;
+import com.jogamp.opengl.util.GLArrayDataWrapper;
+import com.jogamp.opengl.util.GLBuffers;
+import com.jogamp.opengl.util.PMVMatrix;
+import com.jogamp.opengl.util.glsl.fixedfunc.ShaderSelectionMode;
 
 public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFunc {
     public static final int MAX_TEXTURE_UNITS = 8;
 
-    protected FixedFuncPipeline fixedFunction=null;
-    protected PMVMatrix pmvMatrix=null;
-    protected GL2ES2 gl=null;
-
-    public FixedFuncHook (GL2ES2 gl) {
-        this(gl, null);
-    }
+    protected FixedFuncPipeline fixedFunction;
+    protected PMVMatrix pmvMatrix;
+    protected boolean ownsPMVMatrix;
+    protected GL2ES2 gl;
 
-    public FixedFuncHook (GL2ES2 gl, PMVMatrix matrix) {
+    /**
+     * @param gl
+     * @param mode TODO
+     * @param pmvMatrix optional pass through PMVMatrix for the {@link FixedFuncHook} and {@link FixedFuncPipeline}
+     */
+    public FixedFuncHook (GL2ES2 gl, ShaderSelectionMode mode, PMVMatrix pmvMatrix) {
         this.gl = gl;
-        pmvMatrix = (null!=matrix)?matrix:new PMVMatrix();
-
-        fixedFunction = new FixedFuncPipeline(gl, pmvMatrix);
+        if(null != pmvMatrix) {
+            this.ownsPMVMatrix = false;
+            this.pmvMatrix = pmvMatrix;
+        } else {
+            this.ownsPMVMatrix = true;
+            this.pmvMatrix = new PMVMatrix();
+        }
+        fixedFunction = new FixedFuncPipeline(this.gl, mode, this.pmvMatrix);
     }
 
-    public FixedFuncHook(GL2ES2 gl, PMVMatrix matrix, 
-                       Class<?> shaderRootClass, String shaderSrcRoot, String shaderBinRoot, 
-                       String vertexColorFile,
-                       String vertexColorLightFile,
-                       String fragmentColorFile,
-                       String fragmentColorTextureFile) {
+    /**
+     * @param gl
+     * @param mode TODO
+     * @param pmvMatrix optional pass through PMVMatrix for the {@link FixedFuncHook} and {@link FixedFuncPipeline}
+     */
+    public FixedFuncHook(GL2ES2 gl, ShaderSelectionMode mode, PMVMatrix pmvMatrix, 
+                         Class<?> shaderRootClass, String shaderSrcRoot, String shaderBinRoot,
+                         String vertexColorFile, String vertexColorLightFile,
+                         String fragmentColorFile, String fragmentColorTextureFile) {
         this.gl = gl;
-        pmvMatrix = matrix;
+        if(null != pmvMatrix) {
+            this.ownsPMVMatrix = false;
+            this.pmvMatrix = pmvMatrix;
+        } else {
+            this.ownsPMVMatrix = true;
+            this.pmvMatrix = new PMVMatrix();
+        }
 
-        fixedFunction = new FixedFuncPipeline(gl, pmvMatrix,
-                                              shaderRootClass, shaderSrcRoot, shaderBinRoot, 
-                                              vertexColorFile, vertexColorLightFile, fragmentColorFile, fragmentColorTextureFile);
+        fixedFunction = new FixedFuncPipeline(this.gl, mode, this.pmvMatrix, shaderRootClass, shaderSrcRoot, 
+                                              shaderBinRoot, vertexColorFile, vertexColorLightFile, fragmentColorFile, fragmentColorTextureFile);
     }
 
+    public boolean verbose() { return fixedFunction.verbose(); }
+
+    public void setVerbose(boolean v) { fixedFunction.setVerbose(v); }
+    
     public void destroy() {
         fixedFunction.destroy(gl);
         fixedFunction = null;
+        if(ownsPMVMatrix) {
+            pmvMatrix.destroy();
+        }
+        pmvMatrix=null;
+        gl=null;
     }
 
     public PMVMatrix getMatrix() { return pmvMatrix; }
@@ -79,37 +114,29 @@ public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFun
     // FixedFuncHookIf - hooks 
     //
     public void glDrawArrays(int mode, int first, int count) {
-        fixedFunction.validate(gl); 
-        gl.glDrawArrays(mode, first, count);
+        fixedFunction.glDrawArrays(gl, mode, first, count);
     }
     public void glDrawElements(int mode, int count, int type, java.nio.Buffer indices) {
-        fixedFunction.validate(gl); 
-        gl.glDrawElements(mode, count, type, indices);
+        fixedFunction.glDrawElements(gl, mode, count, type, indices);        
     }
     public void glDrawElements(int mode, int count, int type, long indices_buffer_offset) {
-        fixedFunction.validate(gl); 
-        gl.glDrawElements(mode, count, type, indices_buffer_offset);
+        fixedFunction.glDrawElements(gl, mode, count, type, indices_buffer_offset); 
     }
 
     public void glActiveTexture(int texture) {
-        fixedFunction.glActiveTexture(gl, texture);
+        fixedFunction.glActiveTexture(texture);
         gl.glActiveTexture(texture);
     }
     public void glEnable(int cap) {
-        if(fixedFunction.glEnable(gl, cap, true)) {
+        if(fixedFunction.glEnable(cap, true)) {
             gl.glEnable(cap);
         }
     }
     public void glDisable(int cap) {
-        if(fixedFunction.glEnable(gl, cap, false)) {
+        if(fixedFunction.glEnable(cap, false)) {
             gl.glDisable(cap);
         }
-    }
-    public void glCullFace(int faceName) {
-        fixedFunction.glCullFace(gl, faceName);
-        gl.glCullFace(faceName);
-    }
-
+    }    
     public void glGetFloatv(int pname, java.nio.FloatBuffer params) {
         if(PMVMatrix.isMatrixGetName(pname)) {
             pmvMatrix.glGetFloatv(pname, params);
@@ -138,7 +165,54 @@ public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFun
         }
         gl.glGetIntegerv(pname, params, params_offset);
     }
+    
+    public void glTexEnvi(int target, int pname, int value) {
+        fixedFunction.glTexEnvi(target, pname, value);
+    }
+    public void glGetTexEnviv(int target, int pname,  IntBuffer params) {
+        fixedFunction.glGetTexEnviv(target, pname, params);
+    }
+    public void glGetTexEnviv(int target, int pname,  int[] params, int params_offset) {
+        fixedFunction.glGetTexEnviv(target, pname, params, params_offset);
+    }
+    public void glBindTexture(int target, int texture) {
+        fixedFunction.glBindTexture(target, texture);
+        gl.glBindTexture(target, texture);
+    }
+    public void glTexImage2D(int target, int level, int internalformat, int width, int height, int border, 
+                             int format, int type,  Buffer pixels) {
+        // align internalformat w/ format, an ES2 requirement
+        switch(internalformat) {
+            case 3: internalformat= ( GL.GL_RGBA == format ) ? GL.GL_RGBA : GL.GL_RGB; break;
+            case 4: internalformat= ( GL.GL_RGB  == format ) ? GL.GL_RGB  : GL.GL_RGBA; break;
+        }
+        fixedFunction.glTexImage2D(target, /* level, */ internalformat, /*width, height, border, */ format /*, type, pixels*/);
+        gl.glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
+    }
+    public void glTexImage2D(int target, int level, int internalformat, int width, int height, int border,
+                             int format, int type,  long pixels_buffer_offset) {
+        // align internalformat w/ format, an ES2 requirement
+        switch(internalformat) {
+            case 3: internalformat= ( GL.GL_RGBA == format ) ? GL.GL_RGBA : GL.GL_RGB; break;
+            case 4: internalformat= ( GL.GL_RGB  == format ) ? GL.GL_RGB  : GL.GL_RGBA; break;
+        }
+        fixedFunction.glTexImage2D(target, /* level, */ internalformat, /*width, height, border, */ format /*, type, pixels*/);
+        gl.glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels_buffer_offset);
+    }
 
+    public void glPointSize(float size) {
+        fixedFunction.glPointSize(size);
+    }
+    public  void glPointParameterf(int pname, float param) {
+        fixedFunction.glPointParameterf(pname, param);
+    }
+    public  void glPointParameterfv(int pname, float[] params, int params_offset) {
+        fixedFunction.glPointParameterfv(pname, params, params_offset);
+    }
+    public  void glPointParameterfv(int pname, java.nio.FloatBuffer params) {
+        fixedFunction.glPointParameterfv(pname, params);
+    }
+    
     // 
     // MatrixIf
     //
@@ -178,9 +252,15 @@ public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFun
     public void glScalef(float x, float y, float z) {
         pmvMatrix.glScalef(x, y, z);
     }
+    public void glOrtho(double left, double right, double bottom, double top, double near_val, double far_val) {
+        glOrthof((float) left, (float) right, (float) bottom, (float) top, (float) near_val, (float) far_val); 
+    }
     public void glOrthof(float left, float right, float bottom, float top, float zNear, float zFar) {
         pmvMatrix.glOrthof(left, right, bottom, top, zNear, zFar);
     }
+    public void glFrustum(double left, double right, double bottom, double top, double zNear, double zFar) {
+        glFrustumf((float) left, (float) right, (float) bottom, (float) top, (float) zNear, (float) zFar); 
+    }
     public void glFrustumf(float left, float right, float bottom, float top, float zNear, float zFar) {
         pmvMatrix.glFrustumf(left, right, bottom, top, zNear, zFar);
     }
@@ -189,9 +269,15 @@ public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFun
     // LightingIf
     //
     public void glColor4f(float red, float green, float blue, float alpha) {
-      fixedFunction.glColor4fv(gl, GLBuffers.newDirectFloatBuffer(new float[] { red, green, blue, alpha }));
+      fixedFunction.glColor4f(gl, red, green, blue, alpha);
+    }
+    
+    public  void glColor4ub(byte red, byte green, byte blue, byte alpha) {
+      glColor4f(ValueConv.byte_to_float(red, false), 
+                ValueConv.byte_to_float(green, false), 
+                ValueConv.byte_to_float(blue, false), 
+                ValueConv.byte_to_float(alpha, false) );
     }
-
     public void glLightfv(int light, int pname, java.nio.FloatBuffer params) {
       fixedFunction.glLightfv(gl, light, pname, params);
     }
@@ -207,13 +293,29 @@ public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFun
     public void glMaterialf(int face, int pname, float param) {
         glMaterialfv(face, pname, GLBuffers.newDirectFloatBuffer(new float[] { param }));
     }
+
+    //
+    // Misc Simple States
+    //
     public void glShadeModel(int mode) {
       fixedFunction.glShadeModel(gl, mode);
+    }    
+    public  void glAlphaFunc(int func, float ref) {
+        fixedFunction.glAlphaFunc(func, ref);
     }
-
+    
+    /** ES2 supports CullFace implicit 
+    public void glCullFace(int faceName) {
+        fixedFunction.glCullFace(faceName);
+        gl.glCullFace(faceName);
+    } */
+    
     //
     // PointerIf
     //
+    public void glClientActiveTexture(int textureUnit) {
+      fixedFunction.glClientActiveTexture(textureUnit);
+    }
     public void glEnableClientState(int glArrayIndex) {
       fixedFunction.glEnableClientState(gl, glArrayIndex);
     }
@@ -238,14 +340,15 @@ public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFun
     }
 
     public void glVertexPointer(int size, int type, int stride, java.nio.Buffer pointer) {
-      glVertexPointer(GLArrayDataWrapper.createFixed(GL_VERTEX_ARRAY, size, type, false, stride, pointer, 0, 0, 0, GL.GL_ARRAY_BUFFER));
+      glVertexPointer(GLArrayDataWrapper.createFixed(GL_VERTEX_ARRAY, size, type, GLBuffers.isGLTypeFixedPoint(type), stride, 
+                                                     pointer, 0, 0, 0, GL.GL_ARRAY_BUFFER));
     }
     public void glVertexPointer(int size, int type, int stride, long pointer_buffer_offset) {
       int vboName = gl.glGetBoundBuffer(GL.GL_ARRAY_BUFFER);
       if(vboName==0) {
         throw new GLException("no GL_ARRAY_BUFFER VBO bound");
       }
-      glVertexPointer(GLArrayDataWrapper.createFixed(GL_VERTEX_ARRAY, size, type, false, stride, 
+      glVertexPointer(GLArrayDataWrapper.createFixed(GL_VERTEX_ARRAY, size, type, GLBuffers.isGLTypeFixedPoint(type), stride, 
                                                      null, vboName, pointer_buffer_offset, GL.GL_STATIC_DRAW, GL.GL_ARRAY_BUFFER));
     }
 
@@ -265,7 +368,7 @@ public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFun
       fixedFunction.glColorPointer(gl, array);
     }
     public void glColorPointer(int size, int type, int stride, java.nio.Buffer pointer) {
-      glColorPointer(GLArrayDataWrapper.createFixed(GL_COLOR_ARRAY, size, type, false, stride, 
+      glColorPointer(GLArrayDataWrapper.createFixed(GL_COLOR_ARRAY, size, type, GLBuffers.isGLTypeFixedPoint(type), stride, 
                                                     pointer, 0, 0, 0, GL.GL_ARRAY_BUFFER));
     }
     public void glColorPointer(int size, int type, int stride, long pointer_buffer_offset) {
@@ -273,7 +376,7 @@ public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFun
       if(vboName==0) {
         throw new GLException("no GL_ARRAY_BUFFER VBO bound");
       }
-      glColorPointer(GLArrayDataWrapper.createFixed(GL_COLOR_ARRAY, size, type, false, stride, 
+      glColorPointer(GLArrayDataWrapper.createFixed(GL_COLOR_ARRAY, size, type, GLBuffers.isGLTypeFixedPoint(type), stride, 
                                                    null, vboName, pointer_buffer_offset, GL.GL_STATIC_DRAW, GL.GL_ARRAY_BUFFER));
     }
 
@@ -296,7 +399,7 @@ public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFun
       fixedFunction.glNormalPointer(gl, array);
     }
     public void glNormalPointer(int type, int stride, java.nio.Buffer pointer) {
-      glNormalPointer(GLArrayDataWrapper.createFixed(GL_NORMAL_ARRAY, 3, type, false, stride, 
+      glNormalPointer(GLArrayDataWrapper.createFixed(GL_NORMAL_ARRAY, 3, type, GLBuffers.isGLTypeFixedPoint(type), stride, 
                                                      pointer, 0, 0, 0, GL.GL_ARRAY_BUFFER));
     }
     public void glNormalPointer(int type, int stride, long pointer_buffer_offset) {
@@ -304,7 +407,7 @@ public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFun
       if(vboName==0) {
         throw new GLException("no GL_ARRAY_BUFFER VBO bound");
       }
-      glNormalPointer(GLArrayDataWrapper.createFixed(GL_NORMAL_ARRAY, 3, type, false, stride, 
+      glNormalPointer(GLArrayDataWrapper.createFixed(GL_NORMAL_ARRAY, 3, type, GLBuffers.isGLTypeFixedPoint(type), stride, 
                                                      null, vboName, pointer_buffer_offset, GL.GL_STATIC_DRAW, GL.GL_ARRAY_BUFFER));
     }
 
@@ -325,7 +428,8 @@ public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFun
     }
     public void glTexCoordPointer(int size, int type, int stride, java.nio.Buffer pointer) {
       glTexCoordPointer(
-        GLArrayDataWrapper.createFixed(GL_TEXTURE_COORD_ARRAY, size, type, false, stride, pointer, 0, 0, 0, GL.GL_ARRAY_BUFFER));
+        GLArrayDataWrapper.createFixed(GL_TEXTURE_COORD_ARRAY, size, type, GLBuffers.isGLTypeFixedPoint(type), stride, 
+                                       pointer, 0, 0, 0, GL.GL_ARRAY_BUFFER));
     }
     public void glTexCoordPointer(int size, int type, int stride, long pointer_buffer_offset) {
       int vboName = gl.glGetBoundBuffer(GL.GL_ARRAY_BUFFER);
@@ -333,7 +437,7 @@ public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFun
         throw new GLException("no GL_ARRAY_BUFFER VBO bound");
       }
       glTexCoordPointer(
-        GLArrayDataWrapper.createFixed(GL_TEXTURE_COORD_ARRAY, size, type, false, stride, 
+        GLArrayDataWrapper.createFixed(GL_TEXTURE_COORD_ARRAY, size, type, GLBuffers.isGLTypeFixedPoint(type), stride, 
                                        null, vboName, pointer_buffer_offset, GL.GL_STATIC_DRAW, GL.GL_ARRAY_BUFFER) );
     }
 
@@ -341,7 +445,7 @@ public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFun
           StringBuilder buf = new StringBuilder();
           buf.append(getClass().getName()+" (");
           if(null!=pmvMatrix) {
-              buf.append(", matrixDirty: "+pmvMatrix.isDirty());
+              buf.append(", matrixDirty: "+ (0 != pmvMatrix.getModifiedBits(false)));
           }
           buf.append("\n\t, FixedFunction: "+fixedFunction);
           buf.append(gl);
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/FixedFuncPipeline.java b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/FixedFuncPipeline.java
index bfe2e13..cc58f23 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/FixedFuncPipeline.java
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/FixedFuncPipeline.java
@@ -29,33 +29,80 @@
 
 package jogamp.opengl.util.glsl.fixedfunc;
 
+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.GL2;
+import javax.media.opengl.GL2ES1;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GL2GL3;
+import javax.media.opengl.GLArrayData;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLRunnable2;
+import javax.media.opengl.GLUniformData;
+import javax.media.opengl.fixedfunc.GLLightingFunc;
+import javax.media.opengl.fixedfunc.GLPointerFunc;
+import javax.media.opengl.fixedfunc.GLPointerFuncUtil;
+
+import jogamp.opengl.Debug;
+
 import com.jogamp.common.nio.Buffers;
-import javax.media.opengl.*;
-import javax.media.opengl.fixedfunc.*;
-import com.jogamp.opengl.util.*;
-import com.jogamp.opengl.util.glsl.*;
-import java.nio.*;
+import com.jogamp.common.util.IntIntHashMap;
+import com.jogamp.opengl.util.PMVMatrix;
+import com.jogamp.opengl.util.glsl.ShaderCode;
+import com.jogamp.opengl.util.glsl.ShaderProgram;
+import com.jogamp.opengl.util.glsl.ShaderState;
+import com.jogamp.opengl.util.glsl.fixedfunc.ShaderSelectionMode;
 
+/**
+ * 
+ * <p>
+ * Note: Certain GL FFP state values (e.g.: alphaTestFunc and cullFace) 
+ *       are mapped to a lower number range so they can be stored in low precision storage, 
+ *       i.e. in a 'lowp int' (GL ES2).
+ * </p>
+ */
 public class FixedFuncPipeline {
+    protected static final boolean DEBUG = Debug.isPropertyDefined("jogl.debug.FixedFuncPipeline", true);
+    /** The maximum texture units which could be used, depending on {@link ShaderSelectionMode}. */
     public static final int MAX_TEXTURE_UNITS = 8;
     public static final int MAX_LIGHTS        = 8;
-
-    public FixedFuncPipeline(GL2ES2 gl, PMVMatrix pmvMatrix) {
-        init(gl, pmvMatrix, FixedFuncPipeline.class, shaderSrcRootDef, shaderBinRootDef, 
-             vertexColorFileDef, vertexColorLightFileDef, fragmentColorFileDef, fragmentColorTextureFileDef);
+    
+    public FixedFuncPipeline(GL2ES2 gl, ShaderSelectionMode mode, PMVMatrix pmvMatrix) {
+        shaderRootClass = FixedFuncPipeline.class;
+        shaderSrcRoot = shaderSrcRootDef;
+        shaderBinRoot = shaderBinRootDef;
+        vertexColorFile = vertexColorFileDef;
+        vertexColorLightFile = vertexColorLightFileDef;
+        fragmentColorFile = fragmentColorFileDef;
+        fragmentColorTextureFile = fragmentColorTextureFileDef;
+        init(gl, mode, pmvMatrix);
     }
-    public FixedFuncPipeline(GL2ES2 gl, PMVMatrix pmvMatrix, Class shaderRootClass, String shaderSrcRoot, String shaderBinRoot, 
-                       String vertexColorFile,
-                       String vertexColorLightFile,
-                       String fragmentColorFile,
-                       String fragmentColorTextureFile) {
-        init(gl, pmvMatrix, shaderRootClass, shaderSrcRoot, shaderBinRoot, 
-             vertexColorFile, vertexColorLightFile, fragmentColorFile, fragmentColorTextureFile);
+    public FixedFuncPipeline(GL2ES2 gl, ShaderSelectionMode mode, PMVMatrix pmvMatrix, 
+                             Class<?> shaderRootClass, String shaderSrcRoot, 
+                             String shaderBinRoot,
+                             String vertexColorFile, String vertexColorLightFile,
+                             String fragmentColorFile, String fragmentColorTextureFile) {
+        this.shaderRootClass = shaderRootClass;
+        this.shaderSrcRoot = shaderSrcRoot;
+        this.shaderBinRoot = shaderBinRoot;
+        this.vertexColorFile = vertexColorFile;
+        this.vertexColorLightFile = vertexColorLightFile;
+        this.fragmentColorFile = fragmentColorFile;
+        this.fragmentColorTextureFile = fragmentColorTextureFile;
+        init(gl, mode, pmvMatrix); 
     }
+    
+    public ShaderSelectionMode getShaderSelectionMode() { return requestedShaderSelectionMode; }
+    public void setShaderSelectionMode(ShaderSelectionMode mode) { requestedShaderSelectionMode=mode; }
+    public ShaderSelectionMode getCurrentShaderSelectionMode() { return currentShaderSelectionMode; }
 
     public boolean verbose() { return verbose; }
 
-    public void setVerbose(boolean v) { verbose=v; }
+    public void setVerbose(boolean v) { verbose = DEBUG || v; }
 
     public boolean isValid() {
         return shaderState.linked();
@@ -69,49 +116,86 @@ public class FixedFuncPipeline {
         return activeTextureUnit;
     }
 
-    public String getArrayIndexName(int glArrayIndex) {
-      String name = GLPointerFuncUtil.getPredefinedArrayIndexName(glArrayIndex); 
-      switch(glArrayIndex) {
-          case GLPointerFunc.GL_VERTEX_ARRAY:
-          case GLPointerFunc.GL_NORMAL_ARRAY:
-          case GLPointerFunc.GL_COLOR_ARRAY:
-              break;
-          case GLPointerFunc.GL_TEXTURE_COORD_ARRAY:
-              name = name + activeTextureUnit;
-      }
-      return name;
-    }
-
     public void destroy(GL2ES2 gl) {
-        shaderProgramColor.release(gl, true);
-        shaderProgramColorLight.release(gl, true);
-        shaderProgramColorTexture.release(gl, true);
-        shaderProgramColorTextureLight.release(gl, true);
+        if(null != shaderProgramColor) {
+            shaderProgramColor.release(gl, true);
+        }
+        if(null != shaderProgramColorLight) {
+            shaderProgramColorLight.release(gl, true);
+        }
+        if(null != shaderProgramColorTexture2) {
+            shaderProgramColorTexture2.release(gl, true);
+        }
+        if(null != shaderProgramColorTexture4) {
+            shaderProgramColorTexture4.release(gl, true);
+        }
+        if(null != shaderProgramColorTexture4) {
+            shaderProgramColorTexture4.release(gl, true);
+        }
+        if(null != shaderProgramColorTexture8Light) {
+            shaderProgramColorTexture8Light.release(gl, true);
+        }
         shaderState.destroy(gl);
     }
 
-    public void glEnableClientState(GL2ES2 gl, int glArrayIndex) {
+    //
+    // Simple Globals
+    //
+    public void glColor4f(GL2ES2 gl, float red, float green, float blue, float alpha) {
+        colorStatic.put(0, red);
+        colorStatic.put(1, green);
+        colorStatic.put(2, blue);
+        colorStatic.put(3, alpha);
+        
         shaderState.useProgram(gl, true);
-
-        shaderState.enableVertexAttribArray(gl, getArrayIndexName(glArrayIndex));
-        // textureCoordsEnabled |=  (1 << activeTextureUnit);
-        if ( textureCoordsEnabled.get(activeTextureUnit) != 1 ) {
-            textureCoordsEnabled.put(activeTextureUnit, 1);
-            textureCoordsEnabledDirty = true;
-        }
+        final GLUniformData ud = shaderState.getUniform(mgl_ColorStatic);        
+        if(null!=ud) {
+            // same data object ..
+            shaderState.uniform(gl, ud);
+        } else {
+            throw new GLException("Failed to update: mgl_ColorStatic");
+        }        
+    }
+    
+    //
+    // Arrays / States
+    //
+    
+    public void glEnableClientState(GL2ES2 gl, int glArrayIndex) {
+        glToggleClientState(gl, glArrayIndex, true);
     }
 
     public void glDisableClientState(GL2ES2 gl, int glArrayIndex) {
-        shaderState.useProgram(gl, true);
+        glToggleClientState(gl, glArrayIndex, false);
+    }
 
-        shaderState.disableVertexAttribArray(gl, getArrayIndexName(glArrayIndex));
-        // textureCoordsEnabled &= ~(1 << activeTextureUnit);
-        if ( textureCoordsEnabled.get(activeTextureUnit) != 0 ) {
-            textureCoordsEnabled.put(activeTextureUnit, 0);
-            textureCoordsEnabledDirty = true;
+    private void glToggleClientState(GL2ES2 gl, int glArrayIndex, boolean enable) {
+        final String arrayName = GLPointerFuncUtil.getPredefinedArrayIndexName(glArrayIndex, clientActiveTextureUnit);
+        if(null == arrayName) {
+            throw new GLException("arrayIndex "+toHexString(glArrayIndex)+" unknown");
+        }
+        shaderState.useProgram(gl, true);
+        if(enable) {
+            shaderState.enableVertexAttribArray(gl, arrayName );
+        } else {
+            shaderState.disableVertexAttribArray(gl, arrayName );
+        }
+        switch( glArrayIndex ) {
+            case GLPointerFunc.GL_TEXTURE_COORD_ARRAY:
+                final int enableV = enable ? 1 : 0;
+                // enable-bitwise:  textureCoordsEnabled |=  (1 << clientActiveTextureUnit);
+                // disable-bitwise: textureCoordsEnabled &= ~(1 << clientActiveTextureUnit);
+                if ( textureCoordEnabled.get(clientActiveTextureUnit) != enableV) {
+                    textureCoordEnabled.put(clientActiveTextureUnit, enableV);
+                    textureCoordEnabledDirty = true;
+                }
+                break;
+            case GLPointerFunc.GL_COLOR_ARRAY:
+                colorVAEnabledDirty = true;
+                break;
         }
     }
-
+    
     public void glVertexPointer(GL2ES2 gl, GLArrayData data) {
         shaderState.useProgram(gl, true);
         shaderState.vertexAttribPointer(gl, data);
@@ -122,27 +206,236 @@ public class FixedFuncPipeline {
         shaderState.vertexAttribPointer(gl, data);
     }
 
-    public void glColor4fv(GL2ES2 gl, FloatBuffer data ) {
-        shaderState.useProgram(gl, true);
-        GLUniformData ud = shaderState.getUniform(mgl_ColorStatic);
-        if(null!=ud) {
-            ud.setData(data);
-            shaderState.uniform(gl, ud);
-        }
-    }
-
     public void glNormalPointer(GL2ES2 gl, GLArrayData data) {
         shaderState.useProgram(gl, true);
         shaderState.vertexAttribPointer(gl, data);
     }
+    
+    //
+    // MULTI-TEXTURE
+    //
+
+    /** Enables/Disables the named texture unit (if changed), returns previous state */
+    private boolean glEnableTexture(boolean enable, int unit) {
+        final boolean isEnabled = 0 != ( textureEnabledBits & ( 1 << activeTextureUnit ) );  
+        if( isEnabled != enable ) {
+            if(enable) {
+                textureEnabledBits |=  ( 1 << unit );
+                textureEnabled.put(unit, 1);
+            } else {
+                textureEnabledBits &= ~( 1 << unit );
+                textureEnabled.put(unit, 0);
+            }
+            textureEnabledDirty=true;
+        }
+        return isEnabled;
+    }
+    
+    public void glClientActiveTexture(int textureUnit) {
+        textureUnit -= GL.GL_TEXTURE0;
+        if(0 <= textureUnit && textureUnit<MAX_TEXTURE_UNITS) {
+            clientActiveTextureUnit = textureUnit;
+        } else {
+            throw new GLException("glClientActiveTexture textureUnit not within GL_TEXTURE0 + [0.."+MAX_TEXTURE_UNITS+"]: "+textureUnit);
+        }
+    }
+    
+    public void glActiveTexture(int textureUnit) {
+        textureUnit -= GL.GL_TEXTURE0;
+        if(0 <= textureUnit && textureUnit<MAX_TEXTURE_UNITS) {
+            activeTextureUnit = textureUnit;
+        } else {
+            throw new GLException("glActivateTexture textureUnit not within GL_TEXTURE0 + [0.."+MAX_TEXTURE_UNITS+"]: "+textureUnit);
+        }
+    }
 
     public void glTexCoordPointer(GL2ES2 gl, GLArrayData data) {
+        if( GLPointerFunc.GL_TEXTURE_COORD_ARRAY != data.getIndex() ) {
+            throw new GLException("Invalid GLArrayData Index "+toHexString(data.getIndex())+", "+data);
+        }
         shaderState.useProgram(gl, true);
-        data.setName( getArrayIndexName(data.getIndex()) );
+        data.setName( GLPointerFuncUtil.getPredefinedArrayIndexName(data.getIndex(), clientActiveTextureUnit) ) ;
         shaderState.vertexAttribPointer(gl, data);
     }
+    
+    public void glBindTexture(int target, int texture) {
+        if(GL.GL_TEXTURE_2D == target) {
+            if( texture != boundTextureObject[activeTextureUnit] ) {
+                boundTextureObject[activeTextureUnit] = texture;
+                textureFormatDirty = true;
+            }
+        } else {
+            System.err.println("FixedFuncPipeline: Unimplemented glBindTexture for target "+toHexString(target)+". Texture name "+toHexString(texture));            
+        }
+    }
+    
+    public void glTexImage2D(int target, /* int level, */ int internalformat, /*, int width, int height, int border, */
+                             int format /*, int type,  Buffer pixels */) {
+        final int ifmt;
+        if(GL.GL_TEXTURE_2D == target) {
+            switch(internalformat) {            
+            case 3:
+            case GL.GL_RGB:
+            case GL.GL_RGB565:
+            case GL.GL_RGB8:
+            case GL.GL_RGB10:
+                ifmt = 3;
+                break;
+            case 4:
+            case GL.GL_RGBA:
+            case GL.GL_RGB5_A1:
+            case GL.GL_RGBA4:
+            case GL.GL_RGBA8:
+            case GL.GL_RGB10_A2:
+                ifmt = 4;
+                break;
+            default:
+                System.err.println("FixedFuncPipeline: glTexImage2D TEXTURE_2D: Unimplemented internalformat "+toHexString(internalformat));
+                ifmt = 4;
+                break;
+            }
+            if( ifmt != texID2Format.put(boundTextureObject[activeTextureUnit], ifmt) ) {
+                textureFormatDirty = true;
+                // System.err.println("glTexImage2D TEXTURE_2D: internalformat ifmt "+toHexString(internalformat)+" fmt "+toHexString(format)+" -> "+toHexString(ifmt));
+            }
+        } else {
+            System.err.println("FixedFuncPipeline: Unimplemented glTexImage2D: target "+toHexString(target)+", internalformat "+toHexString(internalformat));            
+        }
+    }
+    /*
+    public void glTexImage2D(int target, int level, int internalformat, int width, int height, int border,
+                             int format, int type,  long pixels_buffer_offset) {        
+        textureFormat.put(activeTextureUnit, internalformat);
+        textureFormatDirty = true;
+    }*/
+         
+    public void glTexEnvi(int target, int pname, int value) {
+        if(GL2ES1.GL_TEXTURE_ENV == target && GL2ES1.GL_TEXTURE_ENV_MODE == pname) {
+            final int mode;
+            switch( value ) {
+                case GL2ES1.GL_ADD:
+                    mode = 1;
+                    break;
+                case GL2ES1.GL_MODULATE:
+                    mode = 2;
+                    break;
+                case GL2ES1.GL_DECAL:
+                    mode = 3;
+                    break;
+                case GL2ES1.GL_BLEND:
+                    mode = 4;
+                    break;
+                case GL2ES1.GL_REPLACE:
+                    mode = 5;
+                    break;
+                case GL2ES1.GL_COMBINE:
+                    mode = 2; // FIXME
+                    System.err.println("FixedFuncPipeline: glTexEnv GL_TEXTURE_ENV_MODE: unimplemented mode: "+toHexString(value));
+                    break;
+                default:
+                    throw new GLException("glTexEnv GL_TEXTURE_ENV_MODE: invalid mode: "+toHexString(value));
+            }
+            setTextureEnvMode(mode);
+        } else if(verbose) {
+            System.err.println("FixedFuncPipeline: Unimplemented TexEnv: target "+toHexString(target)+", pname "+toHexString(pname)+", mode: "+toHexString(value));
+        }
+    }
+    private void setTextureEnvMode(int value) {
+        if( value != textureEnvMode.get(activeTextureUnit) ) {
+            textureEnvMode.put(activeTextureUnit, value);
+            textureEnvModeDirty = true;
+        }        
+    }
+    public void glGetTexEnviv(int target, int pname,  IntBuffer params) { // FIXME
+        System.err.println("FixedFuncPipeline: Unimplemented glGetTexEnviv: target "+toHexString(target)+", pname "+toHexString(pname));
+    }
+    public void glGetTexEnviv(int target, int pname,  int[] params, int params_offset) { // FIXME
+        System.err.println("FixedFuncPipeline: Unimplemented glGetTexEnviv: target "+toHexString(target)+", pname "+toHexString(pname));
+    }
+    
+    //
+    // Point Sprites
+    //
+    public void glPointSize(float size) {
+        pointParams.put(0, size);
+        pointParamsDirty = true;                
+    }
+    public  void glPointParameterf(int pname, float param) {
+        switch(pname) {
+            case GL2ES1.GL_POINT_SIZE_MIN:
+                pointParams.put(2, param);
+                break;
+            case GL2ES1.GL_POINT_SIZE_MAX:
+                pointParams.put(3, param);
+                break;
+            case GL2ES2.GL_POINT_FADE_THRESHOLD_SIZE:
+                pointParams.put(4+3, param);
+                break;
+        }
+        pointParamsDirty = true;                
+    }
+    public  void glPointParameterfv(int pname, float[] params, int params_offset) {
+        switch(pname) {
+            case GL2ES1.GL_POINT_DISTANCE_ATTENUATION:
+                pointParams.put(4+0, params[params_offset + 0]);
+                pointParams.put(4+1, params[params_offset + 1]);
+                pointParams.put(4+2, params[params_offset + 2]);
+                break;
+        }
+        pointParamsDirty = true;                
+    }
+    public  void glPointParameterfv(int pname, java.nio.FloatBuffer params) {
+        final int o = params.position();
+        switch(pname) {
+            case GL2ES1.GL_POINT_DISTANCE_ATTENUATION:
+                pointParams.put(4+0, params.get(o + 0));
+                pointParams.put(4+1, params.get(o + 1));
+                pointParams.put(4+2, params.get(o + 2));
+                break;
+        }
+        pointParamsDirty = true;                
+    }
+
+    // private int[] pointTexObj = new int[] { 0 };
+    
+    private void glDrawPoints(GL2ES2 gl, GLRunnable2<Object,Object> glDrawAction, Object args) {
+        if(gl.isGL2GL3()) {
+            gl.glEnable(GL2GL3.GL_VERTEX_PROGRAM_POINT_SIZE);
+        }
+        if(gl.isGL2ES1()) {
+            gl.glEnable(GL2ES1.GL_POINT_SPRITE);
+        }        
+        loadShaderPoints(gl);
+        shaderState.attachShaderProgram(gl, shaderProgramPoints, true);
+        validate(gl, false); // sync uniforms
+
+        glDrawAction.run(gl, args);
+                
+        if(gl.isGL2ES1()) {
+            gl.glDisable(GL2ES1.GL_POINT_SPRITE);
+        }
+        if(gl.isGL2GL3()) {
+            gl.glDisable(GL2GL3.GL_VERTEX_PROGRAM_POINT_SIZE);
+        }
+        shaderState.attachShaderProgram(gl, selectShaderProgram(gl, currentShaderSelectionMode), true);
+    }
+    private static final GLRunnable2<Object, Object> glDrawArraysAction = new GLRunnable2<Object,Object>() {
+        @Override
+        public Object run(GL gl, Object args) {
+            int[] _args = (int[])args;
+            gl.glDrawArrays(GL.GL_POINTS, _args[0], _args[1]);
+            return null;
+        }        
+    };    
+    private final void glDrawPointArrays(GL2ES2 gl, int first, int count) {
+        glDrawPoints(gl, glDrawArraysAction, new int[] { first, count });        
+    }
+    
+    //
+    // Lighting
+    // 
 
-    public void glLightfv(GL2ES2 gl, int light, int pname, java.nio.FloatBuffer params) {
+    public void glLightfv(GL2ES2 gl, int light, int pname, java.nio.FloatBuffer params) {        
         shaderState.useProgram(gl, true);
         light -=GLLightingFunc.GL_LIGHT0;
         if(0 <= light && light < MAX_LIGHTS) {
@@ -179,17 +472,14 @@ public class FixedFuncPipeline {
                     ud = shaderState.getUniform(mgl_LightSource+"["+light+"].quadraticAttenuation");
                     break;
                 default:
-                    if(verbose) {
-                        System.err.println("glLightfv pname not within [GL_AMBIENT GL_DIFFUSE GL_SPECULAR GL_POSITION GL_SPOT_DIRECTION]: "+pname);
-                    }
-                    return;
+                    throw new GLException("glLightfv invalid pname: "+toHexString(pname));
             }
             if(null!=ud) {
                 ud.setData(params);
                 shaderState.uniform(gl, ud);
             }
-        } else if(verbose) {
-            System.err.println("glLightfv light not within [0.."+MAX_LIGHTS+"]: "+light);
+        } else {
+            throw new GLException("glLightfv light not within [0.."+MAX_LIGHTS+"]: "+light);
         }
     }
 
@@ -201,10 +491,8 @@ public class FixedFuncPipeline {
             case GL.GL_FRONT_AND_BACK:
                 break;
             case GL.GL_BACK:
-                if(verbose) {
-                    System.err.println("glMaterialfv face GL_BACK currently not supported");
-                }
-                break;
+                System.err.println("FixedFuncPipeline: Unimplemented glMaterialfv GL_BACK face");
+                return;
             default:
         }
 
@@ -214,7 +502,13 @@ public class FixedFuncPipeline {
                 ud = shaderState.getUniform(mgl_FrontMaterial+".ambient");
                 break;
             case  GLLightingFunc.GL_AMBIENT_AND_DIFFUSE:
-                glMaterialfv(gl, face, GLLightingFunc.GL_AMBIENT, params);
+                {
+                    ud = shaderState.getUniform(mgl_FrontMaterial+".ambient");
+                    if(null!=ud) {
+                        ud.setData(params);
+                        shaderState.uniform(gl, ud);
+                    }
+                }
                 // fall through intended ..
             case  GLLightingFunc.GL_DIFFUSE:
                 ud = shaderState.getUniform(mgl_FrontMaterial+".diffuse");
@@ -229,17 +523,20 @@ public class FixedFuncPipeline {
                 ud = shaderState.getUniform(mgl_FrontMaterial+".shininess");
                 break;
             default:
-                if(verbose) {
-                    System.err.println("glMaterialfv pname not within [GL_AMBIENT GL_DIFFUSE GL_SPECULAR GL_EMISSION GL_SHININESS]: "+pname);
-                }
-                return;
+                throw new GLException("glMaterialfv invalid pname: "+toHexString(pname));
         }
         if(null!=ud) {
             ud.setData(params);
             shaderState.uniform(gl, ud);
+        } else if(verbose) {
+            
         }
     }
 
+    //
+    // Misc States
+    //
+    
     public void glShadeModel(GL2ES2 gl, int mode) {
         shaderState.useProgram(gl, true);
         GLUniformData ud = shaderState.getUniform(mgl_ShadeModel);
@@ -249,24 +546,72 @@ public class FixedFuncPipeline {
         }
     }
 
-    public void glActiveTexture(GL2ES2 gl, int textureUnit) {
-        textureUnit -= GL.GL_TEXTURE0;
-        if(0 <= textureUnit && textureUnit<MAX_TEXTURE_UNITS) {
-            shaderState.useProgram(gl, true);
-            GLUniformData ud;
-            ud = shaderState.getUniform(mgl_ActiveTexture);
-            if(null!=ud) {
-                ud.setData(textureUnit);
-                shaderState.uniform(gl, ud);
+    /** ES2 supports CullFace implicit
+    public void glCullFace(int faceName) {
+        int _cullFace;
+        switch(faceName) {
+            case GL.GL_FRONT:
+                _cullFace = 1;
+                break;
+            case GL.GL_BACK:
+                _cullFace = 2;
+                break;
+            case GL.GL_FRONT_AND_BACK:
+                _cullFace = 3;
+                break;
+            default:
+                throw new GLException("glCullFace invalid faceName: "+toHexString(faceName));
+        }
+        if(0 < _cullFace) {
+            if(0>cullFace) {
+                _cullFace *= -1;
             }
-            ud = shaderState.getUniform(mgl_ActiveTextureIdx);
-            if(null!=ud) {
-                ud.setData(textureUnit);
-                shaderState.uniform(gl, ud);
+            if(cullFace != _cullFace) {
+                cullFace = _cullFace;
+                cullFaceDirty=true;
+            }
+        }
+    } */
+
+    public  void glAlphaFunc(int func, float ref) {
+        int _func;
+        switch(func) {
+            case GL.GL_NEVER:
+                _func = 1;
+                break;
+            case GL.GL_LESS:
+                _func = 2;
+                break;
+            case GL.GL_EQUAL:
+                _func = 3;
+                break;
+            case GL.GL_LEQUAL:
+                _func = 4;
+                break;
+            case GL.GL_GREATER:
+                _func = 5;
+                break;
+            case GL.GL_NOTEQUAL:
+                _func = 6;
+                break;
+            case GL.GL_GEQUAL:
+                _func = 7;
+                break;
+            case GL.GL_ALWAYS:
+                _func = 8;
+                break;
+            default:
+                throw new GLException("glAlphaFunc invalid func: "+toHexString(func));                    
+        }
+        if(0 < _func) {
+            if(0>alphaTestFunc) {
+                _func *= -1;
+            }
+            if( alphaTestFunc != _func || alphaTestRef != ref ) {
+                alphaTestFunc = _func;
+                alphaTestRef = ref;
+                alphaTestDirty=true;
             }
-            activeTextureUnit = textureUnit;
-        } else {
-            throw new GLException("glActivateTexture textureUnit not within GL_TEXTURE0 + [0.."+MAX_TEXTURE_UNITS+"]: "+textureUnit);
         }
     }
 
@@ -275,20 +620,61 @@ public class FixedFuncPipeline {
      *         eg this call must not be passed to an underlying ES2 implementation.
      *         true if this call shall be passed to an underlying GL2ES2/ES2 implementation as well.
      */
-    public boolean glEnable(GL2ES2 gl, int cap, boolean enable) {
+    public boolean glEnable(int cap, boolean enable) {
         switch(cap) {
-            case GL.GL_TEXTURE_2D:
-                textureEnabled=enable;
+            case GL.GL_BLEND:
+            case GL.GL_DEPTH_TEST:
+            case GL.GL_DITHER:   
+            case GL.GL_POLYGON_OFFSET_FILL:
+            case GL.GL_SAMPLE_ALPHA_TO_COVERAGE:
+            case GL.GL_SAMPLE_COVERAGE:
+            case GL.GL_SCISSOR_TEST:
+            case GL.GL_STENCIL_TEST:
+                return true;
+                
+            case GL.GL_CULL_FACE:
+                /** ES2 supports CullFace implicit 
+                final int _cullFace;
+                if(0>cullFace && enable || 0<cullFace && !enable) {
+                    _cullFace = cullFace * -1;
+                } else {
+                    _cullFace = cullFace;
+                }
+                if(_cullFace != cullFace) {
+                    cullFaceDirty=true;
+                    cullFace=_cullFace;
+                } */
                 return true;
+                
+            case GL.GL_TEXTURE_2D:
+                glEnableTexture(enable, activeTextureUnit);
+                return false;
+                
             case GLLightingFunc.GL_LIGHTING:
                 lightingEnabled=enable;
                 return false;
-            case GL.GL_CULL_FACE:
-                cullFace=Math.abs(cullFace);
-                if(!enable) {
-                    cullFace*=-1;
+                
+            case GL2ES1.GL_ALPHA_TEST:
+                final int _alphaTestFunc;
+                if(0>alphaTestFunc && enable || 0<alphaTestFunc && !enable) {
+                    _alphaTestFunc = alphaTestFunc * -1;
+                } else {
+                    _alphaTestFunc = alphaTestFunc;
                 }
-                return true;
+                if(_alphaTestFunc != alphaTestFunc) {
+                    alphaTestDirty=true;
+                    alphaTestFunc=_alphaTestFunc;
+                }
+                return false;
+                
+            case GL2ES1.GL_POINT_SMOOTH:
+                pointParams.put(1, enable ? 1.0f : 0.0f);
+                pointParamsDirty = true;
+                return false;
+                
+            case GL2ES1.GL_POINT_SPRITE:
+                // gl_PointCoord always enabled
+                return false;
         }
 
         int light = cap - GLLightingFunc.GL_LIGHT0;
@@ -299,52 +685,182 @@ public class FixedFuncPipeline {
                 return false;
             }
         }
-        return true; // pass it on ..
+        System.err.println("FixedFunctionPipeline: "+(enable ? "glEnable" : "glDisable")+" "+toHexString(cap)+" not handled in emulation and not supported in ES2");
+        return false; // ignore!
     }
 
-    public void glCullFace(GL2ES2 gl, int faceName) {
-        switch(faceName) {
-            case GL.GL_FRONT:
-                faceName = 1; break;
-            case GL.GL_BACK:
-                faceName = 2; break;
-            case GL.GL_FRONT_AND_BACK:
-                faceName = 3; break;
+    //
+    // Draw
+    //
+    
+    public void glDrawArrays(GL2ES2 gl, int mode, int first, int count) {
+        switch(mode) {
+            case GL2.GL_QUAD_STRIP:
+                mode=GL.GL_TRIANGLE_STRIP;
+                break;
+            case GL2.GL_POLYGON:
+                mode=GL.GL_TRIANGLE_FAN;
+                break;
+            case GL2ES1.GL_POINTS:
+                glDrawPointArrays(gl, first, count);
+                return;
         }
-        if(0>cullFace) {
-            faceName *= -1;
+        validate(gl, true);
+        if ( GL2.GL_QUADS == mode && !gl.isGL2() ) {
+            for (int j = first; j < count - 3; j += 4) {
+                gl.glDrawArrays(GL.GL_TRIANGLE_FAN, j, 4);
+            }
+        } else {            
+            gl.glDrawArrays(mode, first, count);
         }
-        cullFace = faceName;
     }
-
-    public void validate(GL2ES2 gl) {
-        shaderState.useProgram(gl, true);
+    public void glDrawElements(GL2ES2 gl, int mode, int count, int type, java.nio.Buffer indices) {
+        validate(gl, true); 
+        if ( GL2.GL_QUADS == mode && !gl.isGL2() ) {
+            final int idx0 = indices.position();
+            
+            if( GL.GL_UNSIGNED_BYTE == type ) {
+                final ByteBuffer b = (ByteBuffer) indices;
+                for (int j = 0; j < count; j++) {
+                    gl.glDrawArrays(GL.GL_TRIANGLE_FAN, (int)(0x000000ff & b.get(idx0+j)), 4);
+                }                        
+            } else if( GL.GL_UNSIGNED_SHORT == type ){
+                final ShortBuffer b = (ShortBuffer) indices;
+                for (int j = 0; j < count; j++) {
+                    gl.glDrawArrays(GL.GL_TRIANGLE_FAN, (int)(0x0000ffff & b.get(idx0+j)), 4);
+                }                                                
+            } else {
+                final IntBuffer b = (IntBuffer) indices;
+                for (int j = 0; j < count; j++) {
+                    gl.glDrawArrays(GL.GL_TRIANGLE_FAN, (int)(0xffffffff & b.get(idx0+j)), 4);
+                }                                                
+            }
+        } else if( GL2ES1.GL_POINTS != mode ) {            
+            gl.glDrawElements(mode, count, type, indices);
+        } else {
+            // FIXME GL_POINTS !
+            gl.glDrawElements(mode, count, type, indices);
+        }
+    }
+    public void glDrawElements(GL2ES2 gl, int mode, int count, int type, long indices_buffer_offset) {
+        validate(gl, true); 
+        if ( GL2.GL_QUADS == mode && !gl.isGL2() ) {
+            throw new GLException("Cannot handle indexed QUADS on !GL2 w/ VBO due to lack of CPU index access");
+        } else if( GL2ES1.GL_POINTS != mode ) {            
+            // FIXME GL_POINTS !
+            gl.glDrawElements(mode, count, type, indices_buffer_offset);
+        } else {
+            gl.glDrawElements(mode, count, type, indices_buffer_offset);
+        }
+    }
+    
+    private final int textureEnabledCount() {
+        int n=0;
+        for(int i=MAX_TEXTURE_UNITS-1; i>=0; i--) {
+            if( 0 != textureEnabled.get(i) ) {
+                n++;
+            }
+        }
+        return n;
+    }
+    
+    public void validate(GL2ES2 gl, boolean selectShader) {
+        if( selectShader ) {
+            if( ShaderSelectionMode.AUTO == requestedShaderSelectionMode) {
+                final ShaderSelectionMode newMode;
+                
+                // pre-validate shader switch
+                if( 0 != textureEnabledBits ) {
+                    if(lightingEnabled) {
+                        newMode = ShaderSelectionMode.COLOR_TEXTURE8_LIGHT_PER_VERTEX;
+                    } else {
+                        final int n = textureEnabledCount();
+                        if( 4 < n ) {
+                            newMode = ShaderSelectionMode.COLOR_TEXTURE8;
+                        } else if ( 2 < n ) {
+                            newMode = ShaderSelectionMode.COLOR_TEXTURE4;
+                        } else {
+                            newMode = ShaderSelectionMode.COLOR_TEXTURE2;
+                        }
+                    }
+                } else {
+                    if(lightingEnabled) {
+                        newMode = ShaderSelectionMode.COLOR_LIGHT_PER_VERTEX;
+                    } else {
+                        newMode = ShaderSelectionMode.COLOR;
+                    }
+                }
+                shaderState.attachShaderProgram(gl, selectShaderProgram(gl, newMode), true); // enables shader-program implicit
+            } else {
+                shaderState.useProgram(gl, true);
+            }
+        }
+        
         GLUniformData ud;
-        if(pmvMatrix.update()) {
+        if( pmvMatrix.update() ) {            
             ud = shaderState.getUniform(mgl_PMVMatrix);
             if(null!=ud) {
+                final FloatBuffer m;
+                if(ShaderSelectionMode.COLOR_TEXTURE8_LIGHT_PER_VERTEX == currentShaderSelectionMode ||
+                   ShaderSelectionMode.COLOR_LIGHT_PER_VERTEX== currentShaderSelectionMode ) {
+                    m = pmvMatrix.glGetPMvMvitMatrixf();
+                } else {
+                    m = pmvMatrix.glGetPMvMatrixf();                    
+                }
+                if(m != ud.getBuffer()) {
+                    ud.setData(m);
+                }
                 // same data object ..
                 shaderState.uniform(gl, ud);
             } else {
                 throw new GLException("Failed to update: mgl_PMVMatrix");
             }
         }
-        ud = shaderState.getUniform(mgl_ColorEnabled);
-        if(null!=ud) {
-            int ca = (shaderState.isVertexAttribArrayEnabled(GLPointerFuncUtil.mgl_Color)==true)?1:0;
-            if(ca!=ud.intValue()) {
-                ud.setData(ca);
-                shaderState.uniform(gl, ud);
+        if(colorVAEnabledDirty) { 
+            ud = shaderState.getUniform(mgl_ColorEnabled);
+            if(null!=ud) {
+                int ca = true == shaderState.isVertexAttribArrayEnabled(GLPointerFuncUtil.mgl_Color) ? 1 : 0 ;
+                if(ca!=ud.intValue()) {
+                    ud.setData(ca);
+                    shaderState.uniform(gl, ud);
+                }
+            } else {
+                throw new GLException("Failed to update: mgl_ColorEnabled");                
             }
+            colorVAEnabledDirty = false;
         }
-        ud = shaderState.getUniform(mgl_CullFace);
-        if(null!=ud) {
-            if(cullFace!=ud.intValue()) {
+        /** ES2 supports CullFace implicit
+        if(cullFaceDirty) {
+            ud = shaderState.getUniform(mgl_CullFace);
+            if(null!=ud) {
                 ud.setData(cullFace);
                 shaderState.uniform(gl, ud);
             }
-        }
+            cullFaceDirty = false;
+        } */
 
+        if(alphaTestDirty) {
+            ud = shaderState.getUniform(mgl_AlphaTestFunc);
+            if(null!=ud) {
+                ud.setData(alphaTestFunc);
+                shaderState.uniform(gl, ud);
+            }
+            ud = shaderState.getUniform(mgl_AlphaTestRef);
+            if(null!=ud) {
+                ud.setData(alphaTestRef);
+                shaderState.uniform(gl, ud);
+            }
+            alphaTestDirty = false;
+        }
+        if(pointParamsDirty) {
+            ud = shaderState.getUniform(mgl_PointParams);
+            if(null!=ud) {
+                // same data object 
+                shaderState.uniform(gl, ud);
+            }
+            pointParamsDirty = false;
+        }
+        
         if(lightsEnabledDirty) {
             ud = shaderState.getUniform(mgl_LightsEnabled);
             if(null!=ud) {
@@ -354,102 +870,230 @@ public class FixedFuncPipeline {
             lightsEnabledDirty=false;
         }
 
-        if(textureCoordsEnabledDirty) {
+        if(textureCoordEnabledDirty) {
             ud = shaderState.getUniform(mgl_TexCoordEnabled);
             if(null!=ud) {
                 // same data object 
                 shaderState.uniform(gl, ud);
             }
-            textureCoordsEnabledDirty=false;
-        }
+            textureCoordEnabledDirty=false;
+        }        
 
-        if(textureEnabled) {
-            if(lightingEnabled) {
-                shaderState.attachShaderProgram(gl, shaderProgramColorTextureLight, true);
-            } else {
-                shaderState.attachShaderProgram(gl, shaderProgramColorTexture, true);
+        if(textureEnvModeDirty) {
+            ud = shaderState.getUniform(mgl_TexEnvMode);
+            if(null!=ud) {
+                // same data object 
+                shaderState.uniform(gl, ud);
             }
-        } else {
-            if(lightingEnabled) {
-                shaderState.attachShaderProgram(gl, shaderProgramColorLight, true);
-            } else {
-                shaderState.attachShaderProgram(gl, shaderProgramColor, true);
+            textureEnvModeDirty = false;
+        }
+        
+        if(textureFormatDirty) {
+            for(int i = 0; i<MAX_TEXTURE_UNITS; i++) {
+                textureFormat.put(i, texID2Format.get(boundTextureObject[i]));
+            }
+            ud = shaderState.getUniform(mgl_TexFormat);
+            if(null!=ud) {
+                // same data object 
+                shaderState.uniform(gl, ud);
+            }            
+            textureFormatDirty = false;
+        }            
+        if(textureEnabledDirty) {
+            ud = shaderState.getUniform(mgl_TextureEnabled);
+            if(null!=ud) {
+                // same data object 
+                shaderState.uniform(gl, ud);
             }
+            textureEnabledDirty=false;
         }
-        if(DEBUG) {
-            System.err.println("validate: "+this);
+        
+        if(verbose) {
+            System.err.println("validate: "+toString(null, DEBUG).toString());
         }
     }
 
-    public String toString() {
-        return "FixedFuncPipeline[pmv: "+pmvMatrix+
-               ", textureEnabled: "+textureEnabled+
-               ", textureCoordsEnabled: "+textureCoordsEnabled+
-               ", lightingEnabled: "+lightingEnabled+
-               ", lightsEnabled: "+lightsEnabled+
-               "\n\t, shaderProgramColor: "+shaderProgramColor+
-               "\n\t, shaderProgramColorTexture: "+shaderProgramColorTexture+
-               "\n\t, shaderProgramColorLight: "+shaderProgramColorLight+
-               "\n\t, shaderProgramColorTextureLight: "+shaderProgramColorTextureLight+
-               "\n\t, ShaderState: "+shaderState+
-               "]";
-    }
-
-    protected void init(GL2ES2 gl, PMVMatrix pmvMatrix, Class shaderRootClass, String shaderSrcRoot, String shaderBinRoot, 
-                       String vertexColorFile,
-                       String vertexColorLightFile,
-                       String fragmentColorFile,
-                       String fragmentColorTextureFile) 
-   {
-        if(null==pmvMatrix) {
-            throw new GLException("PMVMatrix is null");
+    public StringBuilder toString(StringBuilder sb, boolean alsoUnlocated) {
+        if(null == sb) {
+            sb = new StringBuilder();
         }
-        this.pmvMatrix=pmvMatrix;
-        this.shaderState=new ShaderState();
-        this.shaderState.setVerbose(verbose);
-        ShaderCode vertexColor, vertexColorLight, fragmentColor, fragmentColorTexture;
-
-        vertexColor = ShaderCode.create( gl, gl.GL_VERTEX_SHADER, shaderRootClass, shaderSrcRoot,
-                                         shaderBinRoot, vertexColorFile, false);
-
-        vertexColorLight = ShaderCode.create( gl, gl.GL_VERTEX_SHADER, shaderRootClass, shaderSrcRoot,
-                                           shaderBinRoot, vertexColorLightFile, false);
-
-        fragmentColor = ShaderCode.create( gl, gl.GL_FRAGMENT_SHADER, shaderRootClass, shaderSrcRoot,
-                                           shaderBinRoot, fragmentColorFile, false);
+        sb.append("FixedFuncPipeline[");
+        sb.append(", textureEnabled: "+toHexString(textureEnabledBits)+", "); Buffers.toString(sb, null, textureEnabled);
+        sb.append("\n\t, textureCoordEnabled: "); Buffers.toString(sb, null, textureCoordEnabled);
+        sb.append("\n\t lightingEnabled: "+lightingEnabled);
+        sb.append(", lightsEnabled: "); Buffers.toString(sb, null, lightsEnabled);
+        sb.append("\n\t, shaderProgramColor: "+shaderProgramColor);
+        sb.append("\n\t, shaderProgramColorTexture2: "+shaderProgramColorTexture2);
+        sb.append("\n\t, shaderProgramColorTexture4: "+shaderProgramColorTexture4);
+        sb.append("\n\t, shaderProgramColorTexture8: "+shaderProgramColorTexture8);
+        sb.append("\n\t, shaderProgramColorLight: "+shaderProgramColorLight);
+        sb.append("\n\t, shaderProgramColorTexture8Light: "+shaderProgramColorTexture8Light);
+        sb.append("\n\t, ShaderState: ");
+        shaderState.toString(sb, alsoUnlocated);
+        sb.append("]");
+        return sb;        
+    }
+    public String toString() {
+        return toString(null, DEBUG).toString();
+    }
 
-        fragmentColorTexture = ShaderCode.create( gl, gl.GL_FRAGMENT_SHADER, shaderRootClass, shaderSrcRoot,
-                                                  shaderBinRoot, fragmentColorTextureFile, false);
+    private static final String constMaxTextures0 = "#define MAX_TEXTURE_UNITS 0\n";
+    private static final String constMaxTextures2 = "#define MAX_TEXTURE_UNITS 2\n";
+    private static final String constMaxTextures4 = "#define MAX_TEXTURE_UNITS 4\n";
+    private static final String constMaxTextures8 = "#define MAX_TEXTURE_UNITS 8\n";
+    
+    private final void customizeShader(GL2ES2 gl, ShaderCode vp, ShaderCode fp, String maxTextureDefine) {
+        int rsVpPos = vp.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_vp);
+        int rsFpPos = fp.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_fp);        
+        vp.insertShaderSource(0, rsVpPos, maxTextureDefine);
+        fp.insertShaderSource(0, rsFpPos, maxTextureDefine); 
+    }
 
-        shaderProgramColor = new ShaderProgram();
-        shaderProgramColor.add(vertexColor);
-        shaderProgramColor.add(fragmentColor);
-        if(!shaderProgramColor.link(gl, System.err)) {
-            throw new GLException("Couldn't link VertexColor program: "+shaderProgramColor);
+    private final void loadShaderPoints(GL2ES2 gl) {
+        if( null != shaderProgramPoints ) {
+            return;
         }
-
-        shaderProgramColorTexture = new ShaderProgram();
-        shaderProgramColorTexture.add(vertexColor);
-        shaderProgramColorTexture.add(fragmentColorTexture);
-        if(!shaderProgramColorTexture.link(gl, System.err)) {
-            throw new GLException("Couldn't link VertexColorTexture program: "+shaderProgramColorTexture);
+        
+        final ShaderCode vp = ShaderCode.create( gl, GL2ES2.GL_VERTEX_SHADER, shaderRootClass, shaderSrcRoot,
+                                         shaderBinRoot, shaderPointFileDef, true);
+        final ShaderCode fp = ShaderCode.create( gl, GL2ES2.GL_FRAGMENT_SHADER, shaderRootClass, shaderSrcRoot,
+                                           shaderBinRoot, shaderPointFileDef, true);
+        customizeShader(gl, vp, fp, constMaxTextures2);
+        shaderProgramPoints = new ShaderProgram();
+        shaderProgramPoints.add(vp);
+        shaderProgramPoints.add(fp);
+        if(!shaderProgramPoints.link(gl, System.err)) {
+            throw new GLException("Couldn't link VertexColor program: "+shaderProgramPoints);
+        }        
+    }
+    
+    private final void loadShader(GL2ES2 gl, ShaderSelectionMode mode) {
+        final boolean loadColor = ShaderSelectionMode.COLOR == mode;
+        final boolean loadColorTexture2 = ShaderSelectionMode.COLOR_TEXTURE2 == mode;
+        final boolean loadColorTexture4 = ShaderSelectionMode.COLOR_TEXTURE4 == mode;
+        final boolean loadColorTexture8 = ShaderSelectionMode.COLOR_TEXTURE8 == mode;
+        final boolean loadColorTexture = loadColorTexture2 || loadColorTexture4 || loadColorTexture8 ; 
+        final boolean loadColorLightPerVertex = ShaderSelectionMode.COLOR_LIGHT_PER_VERTEX == mode;
+        final boolean loadColorTexture8LightPerVertex = ShaderSelectionMode.COLOR_TEXTURE8_LIGHT_PER_VERTEX == mode;
+        
+        if( null != shaderProgramColor && loadColor ||
+            null != shaderProgramColorTexture2 && loadColorTexture2 ||
+            null != shaderProgramColorTexture4 && loadColorTexture4 ||
+            null != shaderProgramColorTexture8 && loadColorTexture8 ||
+            null != shaderProgramColorLight && loadColorLightPerVertex ||
+            null != shaderProgramColorTexture8Light && loadColorTexture8LightPerVertex ) {
+            return;
         }
-
-        shaderProgramColorLight = new ShaderProgram();
-        shaderProgramColorLight.add(vertexColorLight);
-        shaderProgramColorLight.add(fragmentColor);
-        if(!shaderProgramColorLight.link(gl, System.err)) {
-            throw new GLException("Couldn't link VertexColorLight program: "+shaderProgramColorLight);
+        
+        if( loadColor ) {
+            final ShaderCode vp = ShaderCode.create( gl, GL2ES2.GL_VERTEX_SHADER, shaderRootClass, shaderSrcRoot,
+                                             shaderBinRoot, vertexColorFile, true);
+            final ShaderCode fp = ShaderCode.create( gl, GL2ES2.GL_FRAGMENT_SHADER, shaderRootClass, shaderSrcRoot,
+                                               shaderBinRoot, fragmentColorFile, true);
+            customizeShader(gl, vp, fp, constMaxTextures0);
+            shaderProgramColor = new ShaderProgram();
+            shaderProgramColor.add(vp);
+            shaderProgramColor.add(fp);
+            if(!shaderProgramColor.link(gl, System.err)) {
+                throw new GLException("Couldn't link VertexColor program: "+shaderProgramColor);
+            }
+        } else  if( loadColorTexture ) {
+            final ShaderCode vp = ShaderCode.create( gl, GL2ES2.GL_VERTEX_SHADER, shaderRootClass, shaderSrcRoot, shaderBinRoot, vertexColorFile, true);
+            final ShaderCode fp = ShaderCode.create( gl, GL2ES2.GL_FRAGMENT_SHADER, shaderRootClass, shaderSrcRoot,
+                                                     shaderBinRoot, fragmentColorTextureFile, true);
+            
+            if( loadColorTexture2 ) {
+                customizeShader(gl, vp, fp, constMaxTextures2);
+                shaderProgramColorTexture2 = new ShaderProgram();
+                shaderProgramColorTexture2.add(vp);
+                shaderProgramColorTexture2.add(fp);
+                if(!shaderProgramColorTexture2.link(gl, System.err)) {
+                    throw new GLException("Couldn't link VertexColorTexture2 program: "+shaderProgramColorTexture2);
+                }
+            } else if( loadColorTexture4 ) {
+                customizeShader(gl, vp, fp, constMaxTextures4);
+                shaderProgramColorTexture4 = new ShaderProgram();
+                shaderProgramColorTexture4.add(vp);
+                shaderProgramColorTexture4.add(fp);
+                if(!shaderProgramColorTexture4.link(gl, System.err)) {
+                    throw new GLException("Couldn't link VertexColorTexture4 program: "+shaderProgramColorTexture4);
+                }
+            } else if( loadColorTexture8 ) {
+                customizeShader(gl, vp, fp, constMaxTextures8);
+                shaderProgramColorTexture8 = new ShaderProgram();
+                shaderProgramColorTexture8.add(vp);
+                shaderProgramColorTexture8.add(fp);
+                if(!shaderProgramColorTexture8.link(gl, System.err)) {
+                    throw new GLException("Couldn't link VertexColorTexture8 program: "+shaderProgramColorTexture8);
+                }
+            }
+        } else if( loadColorLightPerVertex ) {
+            final ShaderCode vp = ShaderCode.create( gl, GL2ES2.GL_VERTEX_SHADER, shaderRootClass, shaderSrcRoot,
+                                               shaderBinRoot, vertexColorLightFile, true);
+            final ShaderCode fp = ShaderCode.create( gl, GL2ES2.GL_FRAGMENT_SHADER, shaderRootClass, shaderSrcRoot,
+                                               shaderBinRoot, fragmentColorFile, true);
+            customizeShader(gl, vp, fp, constMaxTextures0);
+            shaderProgramColorLight = new ShaderProgram();
+            shaderProgramColorLight.add(vp);
+            shaderProgramColorLight.add(fp);
+            if(!shaderProgramColorLight.link(gl, System.err)) {
+                throw new GLException("Couldn't link VertexColorLight program: "+shaderProgramColorLight);
+            }
+        }  else if( loadColorTexture8LightPerVertex ) {
+            final ShaderCode vp = ShaderCode.create( gl, GL2ES2.GL_VERTEX_SHADER, shaderRootClass, shaderSrcRoot,
+                                               shaderBinRoot, vertexColorLightFile, true);
+            final ShaderCode fp = ShaderCode.create( gl, GL2ES2.GL_FRAGMENT_SHADER, shaderRootClass, shaderSrcRoot,
+                                                     shaderBinRoot, fragmentColorTextureFile, true);
+            customizeShader(gl, vp, fp, constMaxTextures8);
+            shaderProgramColorTexture8Light = new ShaderProgram();
+            shaderProgramColorTexture8Light.add(vp);
+            shaderProgramColorTexture8Light.add(fp);
+            if(!shaderProgramColorTexture8Light.link(gl, System.err)) {
+                throw new GLException("Couldn't link VertexColorLight program: "+shaderProgramColorTexture8Light);
+            }
         }
-
-        shaderProgramColorTextureLight = new ShaderProgram();
-        shaderProgramColorTextureLight.add(vertexColorLight);
-        shaderProgramColorTextureLight.add(fragmentColorTexture);
-        if(!shaderProgramColorTextureLight.link(gl, System.err)) {
-            throw new GLException("Couldn't link VertexColorLight program: "+shaderProgramColorTextureLight);
+    }
+    
+    private ShaderProgram selectShaderProgram(GL2ES2 gl, ShaderSelectionMode newMode) {
+        if(ShaderSelectionMode.AUTO == newMode) {
+            newMode = ShaderSelectionMode.COLOR;
+        }
+        loadShader(gl, newMode);
+        final ShaderProgram sp;
+        switch(newMode) {
+            case COLOR_LIGHT_PER_VERTEX:
+                sp = shaderProgramColorLight;
+                break;
+            case COLOR_TEXTURE2:
+                sp = shaderProgramColorTexture2;
+                break;
+            case COLOR_TEXTURE4:
+                sp = shaderProgramColorTexture4;
+                break;
+            case COLOR_TEXTURE8:
+                sp = shaderProgramColorTexture8;
+                break;
+            case COLOR_TEXTURE8_LIGHT_PER_VERTEX:
+                sp = shaderProgramColorTexture8Light;
+                break;
+            case COLOR:
+            default:
+                sp = shaderProgramColor;
         }
+        currentShaderSelectionMode = newMode;
+        return sp;
+    }
+    
+    private void init(GL2ES2 gl, ShaderSelectionMode mode, PMVMatrix pmvMatrix) { 
+        if(null==pmvMatrix) {
+            throw new GLException("PMVMatrix is null");
+        }
+        this.pmvMatrix=pmvMatrix;
+        this.requestedShaderSelectionMode = mode;        
+        this.shaderState=new ShaderState();
+        this.shaderState.setVerbose(verbose);
 
-        shaderState.attachShaderProgram(gl, shaderProgramColor, true);
+        shaderState.attachShaderProgram(gl, selectShaderProgram(gl, requestedShaderSelectionMode), true);
 
         // mandatory ..
         if(!shaderState.uniform(gl, new GLUniformData(mgl_PMVMatrix, 4, 4, pmvMatrix.glGetPMvMvitMatrixf()))) {
@@ -457,16 +1101,26 @@ public class FixedFuncPipeline {
         }
 
         shaderState.uniform(gl, new GLUniformData(mgl_ColorEnabled,  0));
-        shaderState.uniform(gl, new GLUniformData(mgl_ColorStatic, 4, zero4f));
-        shaderState.uniform(gl, new GLUniformData(mgl_TexCoordEnabled,  1, textureCoordsEnabled));
-        shaderState.uniform(gl, new GLUniformData(mgl_ActiveTexture, activeTextureUnit));
-        shaderState.uniform(gl, new GLUniformData(mgl_ActiveTextureIdx, activeTextureUnit));
+        shaderState.uniform(gl, new GLUniformData(mgl_ColorStatic, 4, colorStatic));
+        
+        texID2Format.setKeyNotFoundValue(0);        
+        shaderState.uniform(gl, new GLUniformData(mgl_TexCoordEnabled,  1, textureCoordEnabled));
+        shaderState.uniform(gl, new GLUniformData(mgl_TexEnvMode, 1, textureEnvMode));
+        shaderState.uniform(gl, new GLUniformData(mgl_TexFormat, 1, textureFormat));        
+        shaderState.uniform(gl, new GLUniformData(mgl_TextureEnabled, 1, textureEnabled));
+        for(int i=0; i<MAX_TEXTURE_UNITS; i++) {
+            shaderState.uniform(gl, new GLUniformData(mgl_Texture+i, i));
+        }
         shaderState.uniform(gl, new GLUniformData(mgl_ShadeModel, 0));
-        shaderState.uniform(gl, new GLUniformData(mgl_CullFace, cullFace));
+        /** ES2 supports CullFace implicit
+        shaderState.uniform(gl, new GLUniformData(mgl_CullFace, cullFace)); */
+        shaderState.uniform(gl, new GLUniformData(mgl_AlphaTestFunc, alphaTestFunc));
+        shaderState.uniform(gl, new GLUniformData(mgl_AlphaTestRef, alphaTestRef));   
+        shaderState.uniform(gl, new GLUniformData(mgl_PointParams, 4, pointParams));
         for(int i=0; i<MAX_LIGHTS; i++) {
             shaderState.uniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].ambient", 4, defAmbient));
-            shaderState.uniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].diffuse", 4, defDiffuse));
-            shaderState.uniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].specular", 4, defSpecular));
+            shaderState.uniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].diffuse", 4, 0==i ? one4f : defDiffuseN));
+            shaderState.uniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].specular", 4, 0==i ? one4f : defSpecularN));
             shaderState.uniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].position", 4, defPosition));
             shaderState.uniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].spotDirection", 3, defSpotDir));
             shaderState.uniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].spotExponent", defSpotExponent));
@@ -474,7 +1128,8 @@ public class FixedFuncPipeline {
             shaderState.uniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].constantAttenuation", defConstantAtten));
             shaderState.uniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].linearAttenuation", defLinearAtten));
             shaderState.uniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].quadraticAttenuation", defQuadraticAtten));
-        }
+        }        
+        shaderState.uniform(gl, new GLUniformData(mgl_LightModel+".ambient", 4, defLightModelAmbient));
         shaderState.uniform(gl, new GLUniformData(mgl_LightsEnabled,  1, lightsEnabled));
         shaderState.uniform(gl, new GLUniformData(mgl_FrontMaterial+".ambient", 4, defMatAmbient));
         shaderState.uniform(gl, new GLUniformData(mgl_FrontMaterial+".diffuse", 4, defMatDiffuse));
@@ -483,70 +1138,121 @@ public class FixedFuncPipeline {
         shaderState.uniform(gl, new GLUniformData(mgl_FrontMaterial+".shininess", defMatShininess));
 
         shaderState.useProgram(gl, false);
+        if(verbose) {
+            System.err.println("init: "+toString(null, DEBUG).toString());
+        }
     }
 
-    protected static final boolean DEBUG=false;
-    protected boolean verbose=false;
+    private String toHexString(int i) {
+        return "0x"+Integer.toHexString(i);
+    }
+    
+    protected boolean verbose = DEBUG;
 
-    protected boolean textureEnabled=false;
-    protected IntBuffer textureCoordsEnabled = Buffers.newDirectIntBuffer(new int[] { 0, 0, 0, 0, 0, 0, 0, 0 });
-    protected boolean textureCoordsEnabledDirty = false;
-    protected int     activeTextureUnit=0;
+    private final FloatBuffer colorStatic = Buffers.copyFloatBuffer(one4f);
+    
+    private int activeTextureUnit=0;
+    private int clientActiveTextureUnit=0;
+    private final IntIntHashMap texID2Format = new IntIntHashMap();
+    private final int[] boundTextureObject = new int[] { 0, 0, 0, 0, 0, 0, 0, 0 }; // per unit
+    private int textureEnabledBits = 0;
+    private final IntBuffer textureEnabled = Buffers.newDirectIntBuffer(new int[] { 0, 0, 0, 0, 0, 0, 0, 0 }); // per unit
+    private boolean textureEnabledDirty = false;
+    private final IntBuffer textureCoordEnabled = Buffers.newDirectIntBuffer(new int[] { 0, 0, 0, 0, 0, 0, 0, 0 }); // per unit
+    private boolean textureCoordEnabledDirty = false;    
+    // textureEnvMode: 1 GL_ADD, 2 GL_MODULATE (default), 3 GL_DECAL, 4 GL_BLEND, 5 GL_REPLACE, 6 GL_COMBINE
+    private final IntBuffer textureEnvMode = Buffers.newDirectIntBuffer(new int[] { 2, 2, 2, 2, 2, 2, 2, 2 });    
+    private boolean textureEnvModeDirty = false;
+    private final IntBuffer textureFormat = Buffers.newDirectIntBuffer(new int[] { 0, 0, 0, 0, 0, 0, 0, 0 }); // per unit
+    private boolean textureFormatDirty = false;
 
-    protected int cullFace=-2; // <=0 disabled, 1: front, 2: back (default, but disabled), 3: front & back
+    /** ES2 supports CullFace implicit
+    private int cullFace=-2; // <=0 disabled, 1 GL_FRONT, 2 GL_BACK (default) and 3 GL_FRONT_AND_BACK
+    private boolean cullFaceDirty = false;
+    private static final String mgl_CullFace         = "mgl_CullFace";        //  1i (lowp int) */
 
-    protected boolean lightingEnabled=false;
-    protected IntBuffer lightsEnabled = Buffers.newDirectIntBuffer(new int[] { 0, 0, 0, 0, 0, 0, 0, 0 });
-    protected boolean   lightsEnabledDirty = false;
+    private boolean colorVAEnabledDirty = false;
+    private boolean lightingEnabled=false;
+    private final IntBuffer lightsEnabled = Buffers.newDirectIntBuffer(new int[] { 0, 0, 0, 0, 0, 0, 0, 0 });
+    private boolean   lightsEnabledDirty = false;
 
-    protected PMVMatrix pmvMatrix;
-    protected ShaderState shaderState;
-    protected ShaderProgram shaderProgramColor;
-    protected ShaderProgram shaderProgramColorTexture;
-    protected ShaderProgram shaderProgramColorLight;
-    protected ShaderProgram shaderProgramColorTextureLight;
+    private boolean alphaTestDirty=false;
+    private int alphaTestFunc=-8; // <=0 disabled; 1 GL_NEVER, 2 GL_LESS, 3 GL_EQUAL, 4 GL_LEQUAL, 5 GL_GREATER, 6 GL_NOTEQUAL, 7 GL_GEQUAL, and 8 GL_ALWAYS (default)
+    private float alphaTestRef=0f;
+    
+    private boolean pointParamsDirty = false;
+    /** ( pointSize, pointSmooth, attn. pointMinSize, attn. pointMaxSize ) , ( attenuation coefficients 1f 0f 0f, attenuation fade theshold 1f )   */
+    private final FloatBuffer pointParams = Buffers.newDirectFloatBuffer(new float[] {  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f }); 
+    
+    private PMVMatrix pmvMatrix;
+    private ShaderState shaderState;
+    private ShaderProgram shaderProgramColor;
+    private ShaderProgram shaderProgramColorTexture2, shaderProgramColorTexture4, shaderProgramColorTexture8;
+    private ShaderProgram shaderProgramColorLight;
+    private ShaderProgram shaderProgramColorTexture8Light;
+    private ShaderProgram shaderProgramPoints;
+    
+    private ShaderSelectionMode requestedShaderSelectionMode = ShaderSelectionMode.AUTO;
+    private ShaderSelectionMode currentShaderSelectionMode = requestedShaderSelectionMode;
 
     // uniforms ..
-    protected static final String mgl_PMVMatrix        = "mgl_PMVMatrix";       // m4fv[4] - P, Mv, Mvi and Mvit
-    protected static final String mgl_ColorEnabled     = "mgl_ColorEnabled";    //  1i
-    protected static final String mgl_ColorStatic      = "mgl_ColorStatic";     //  4fv
-
-    protected static final String mgl_LightSource      = "mgl_LightSource";     //  struct mgl_LightSourceParameters[MAX_LIGHTS]
-    protected static final String mgl_FrontMaterial    = "mgl_FrontMaterial";   //  struct mgl_MaterialParameters
-    protected static final String mgl_LightsEnabled    = "mgl_LightsEnabled";   //  int mgl_LightsEnabled[MAX_LIGHTS];
-
-    protected static final String mgl_ShadeModel       = "mgl_ShadeModel";      //  1i
-
-    protected static final String mgl_TexCoordEnabled  = "mgl_TexCoordEnabled"; //  int mgl_TexCoordEnabled[MAX_TEXTURE_UNITS];
-    protected static final String mgl_ActiveTexture    = "mgl_ActiveTexture";   //  1i
-    protected static final String mgl_ActiveTextureIdx = "mgl_ActiveTextureIdx";//  1i
-
-    protected static final String mgl_CullFace         = "mgl_CullFace";   //  1i
-
-    protected static final FloatBuffer zero4f     = Buffers.newDirectFloatBuffer(new float[] { 0.0f, 0.0f, 0.0f, 0.0f });
-
-    public static final FloatBuffer defAmbient = Buffers.newDirectFloatBuffer(new float[] { 0f, 0f, 0f, 1f });
-    public static final FloatBuffer defDiffuse = zero4f;
-    public static final FloatBuffer defSpecular= zero4f;
-    public static final FloatBuffer defPosition= Buffers.newDirectFloatBuffer(new float[] { 0f, 0f, 1f, 0f });
-    public static final FloatBuffer defSpotDir = Buffers.newDirectFloatBuffer(new float[] { 0f, 0f, -1f });
-    public static final float defSpotExponent  = 0f;
-    public static final float defSpotCutoff    = 180f;
-    public static final float defConstantAtten = 1f;
-    public static final float defLinearAtten   = 0f;
-    public static final float defQuadraticAtten= 0f;
-
-    public static final FloatBuffer defMatAmbient = Buffers.newDirectFloatBuffer(new float[] { 0.2f, 0.2f, 0.2f, 1.0f });
-    public static final FloatBuffer defMatDiffuse = Buffers.newDirectFloatBuffer(new float[] { 0.8f, 0.8f, 0.8f, 1.0f });
-    public static final FloatBuffer defMatSpecular= Buffers.newDirectFloatBuffer(new float[] { 0f, 0f, 0f, 1f});
-    public static final FloatBuffer defMatEmission= Buffers.newDirectFloatBuffer(new float[] { 0f, 0f, 0f, 1f});
+    private static final String mgl_PMVMatrix        = "mgl_PMVMatrix";       // m4fv[4] - P, Mv, Mvi and Mvit
+    private static final String mgl_ColorEnabled     = "mgl_ColorEnabled";    //  1i
+    private static final String mgl_ColorStatic      = "mgl_ColorStatic";     //  4fv
+
+    private static final String mgl_LightModel       = "mgl_LightModel";      //  struct mgl_LightModelParameters
+    private static final String mgl_LightSource      = "mgl_LightSource";     //  struct mgl_LightSourceParameters[MAX_LIGHTS]
+    private static final String mgl_FrontMaterial    = "mgl_FrontMaterial";   //  struct mgl_MaterialParameters
+    private static final String mgl_LightsEnabled    = "mgl_LightsEnabled";   //  int mgl_LightsEnabled[MAX_LIGHTS];
+
+    private static final String mgl_AlphaTestFunc    = "mgl_AlphaTestFunc";   //  1i (lowp int)
+    private static final String mgl_AlphaTestRef     = "mgl_AlphaTestRef";    //  1f    
+    private static final String mgl_ShadeModel       = "mgl_ShadeModel";      //  1i
+    private static final String mgl_PointParams      = "mgl_PointParams";     //  vec4[2]: { (sz, smooth, attnMinSz, attnMaxSz), (attnCoeff(3), attnFadeTs) }
+
+    private static final String mgl_TextureEnabled   = "mgl_TextureEnabled";  //  int mgl_TextureEnabled[MAX_TEXTURE_UNITS];
+    private static final String mgl_Texture          = "mgl_Texture";         //  sampler2D mgl_Texture<0..7>
+    private static final String mgl_TexCoordEnabled  = "mgl_TexCoordEnabled"; //  int mgl_TexCoordEnabled[MAX_TEXTURE_UNITS];
+    private static final String mgl_TexEnvMode       = "mgl_TexEnvMode";      //  int mgl_TexEnvMode[MAX_TEXTURE_UNITS];
+    private static final String mgl_TexFormat        = "mgl_TexFormat";       //  int mgl_TexFormat[MAX_TEXTURE_UNITS];
+
+    // private static final FloatBuffer zero4f = Buffers.newDirectFloatBuffer(new float[] { 0.0f, 0.0f, 0.0f, 0.0f });
+    private static final FloatBuffer neut4f = Buffers.newDirectFloatBuffer(new float[] { 0.0f, 0.0f, 0.0f, 1.0f });
+    private static final FloatBuffer one4f  = Buffers.newDirectFloatBuffer(new float[] { 1.0f, 1.0f, 1.0f, 1.0f });    
+
+    public static final FloatBuffer defAmbient   = neut4f;
+    public static final FloatBuffer defDiffuseN  = neut4f;
+    public static final FloatBuffer defSpecularN = neut4f;
+    public static final FloatBuffer defPosition  = Buffers.newDirectFloatBuffer(new float[] { 0f, 0f, 1f, 0f });
+    public static final FloatBuffer defSpotDir   = Buffers.newDirectFloatBuffer(new float[] { 0f, 0f, -1f });
+    public static final float defSpotExponent    = 0f;
+    public static final float defSpotCutoff      = 180f;
+    public static final float defConstantAtten   = 1f;
+    public static final float defLinearAtten     = 0f;
+    public static final float defQuadraticAtten  = 0f;
+
+    public static final FloatBuffer defLightModelAmbient = Buffers.newDirectFloatBuffer(new float[] { 0.2f, 0.2f, 0.2f, 1.0f });
+    
+    public static final FloatBuffer defMatAmbient   = Buffers.newDirectFloatBuffer(new float[] { 0.2f, 0.2f, 0.2f, 1.0f });
+    public static final FloatBuffer defMatDiffuse   = Buffers.newDirectFloatBuffer(new float[] { 0.8f, 0.8f, 0.8f, 1.0f });
+    public static final FloatBuffer defMatSpecular  = neut4f;
+    public static final FloatBuffer defMatEmission  = neut4f;
     public static final float       defMatShininess = 0f;
 
-    protected static final String vertexColorFileDef          = "FixedFuncColor";
-    protected static final String vertexColorLightFileDef    = "FixedFuncColorLight";
-    protected static final String fragmentColorFileDef        = "FixedFuncColor";
-    protected static final String fragmentColorTextureFileDef = "FixedFuncColorTexture";
-    protected static final String shaderSrcRootDef = "shaders" ;
-    protected static final String shaderBinRootDef = "shaders/bin" ;
+    private static final String vertexColorFileDef           = "FixedFuncColor";
+    private static final String vertexColorLightFileDef      = "FixedFuncColorLight";
+    private static final String fragmentColorFileDef         = "FixedFuncColor";
+    private static final String fragmentColorTextureFileDef  = "FixedFuncColorTexture";
+    private static final String shaderPointFileDef           = "FixedFuncPoints";
+    private static final String shaderSrcRootDef             = "shaders" ;
+    private static final String shaderBinRootDef             = "shaders/bin" ;
+    
+    private final Class<?> shaderRootClass;
+    private final String shaderSrcRoot; 
+    private final String shaderBinRoot;
+    private final String vertexColorFile;
+    private final String vertexColorLightFile;
+    private final String fragmentColorFile;
+    private final String fragmentColorTextureFile;     
 }
 
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColor.fp b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColor.fp
index 408ff72..22dd1e6 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColor.fp
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColor.fp
@@ -1,16 +1,32 @@
+
+#if __VERSION__ >= 130
+  #define varying in
+  out vec4 mgl_FragColor;
+#else
+  #define mgl_FragColor gl_FragColor   
+#endif
+
 #include es_precision.glsl
 
 #include mgl_uniform.glsl
 #include mgl_varying.glsl
 
+#include mgl_alphatest.fp
+
 void main (void)
 {
-  if( mgl_CullFace > 0 && 
-      ( ( mgl_CullFace == 1 && gl_FrontFacing ) ||
-        ( mgl_CullFace == 2 && !gl_FrontFacing ) ||
-        ( mgl_CullFace == 3 ) ) ) {
-    discard;
+  vec4 color = frontColor;
+
+  /** ES2 supports CullFace implicit ..
+  if( mgl_CullFace > 0 &&
+      ( ( MGL_FRONT          == mgl_CullFace &&  gl_FrontFacing ) ||
+        ( MGL_BACK           == mgl_CullFace && !gl_FrontFacing ) ||
+        ( MGL_FRONT_AND_BACK == mgl_CullFace ) ) ) {
+      DISCARD(color);
+  } */
+  if( mgl_AlphaTestFunc > 0 ) {
+      alphaTest(color);
   }
-  gl_FragColor = frontColor;
+  mgl_FragColor = color;
 }
 
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColor.vp b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColor.vp
index 346e401..f39fcfb 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColor.vp
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColor.vp
@@ -1,3 +1,9 @@
+
+#if __VERSION__ >= 130
+  #define attribute in
+  #define varying out
+#endif
+
 #include es_precision.glsl
 
 #include mgl_const.glsl
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColorLight.vp b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColorLight.vp
index 7ce1eed..942a540 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColorLight.vp
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColorLight.vp
@@ -1,3 +1,9 @@
+
+#if __VERSION__ >= 130
+  #define attribute in
+  #define varying out
+#endif
+
 #include es_precision.glsl
 #include mgl_lightdef.glsl
 
@@ -50,16 +56,18 @@ void main(void)
       }
     }
   }
-  ambient  *= mgl_FrontMaterial.ambient;
-  diffuse  *= mgl_FrontMaterial.diffuse;
-  specular *= mgl_FrontMaterial.specular;
-
   if(mgl_ColorEnabled>0) {
     frontColor=mgl_Color;
   } else {
     frontColor=mgl_ColorStatic;
   }
   if( lightEnabled ) {
+    //                   light-ambient                               +                 global-ambient
+    // ( mgl_LightSource[0..n].ambient * mgl_FrontMaterial.ambient ) + ( mgl_LightModel.ambient * mgl_FrontMaterial.ambient )
+    ambient   = ( ambient + mgl_LightModel.ambient ) * mgl_FrontMaterial.ambient;
+    diffuse  *= mgl_FrontMaterial.diffuse;
+    specular *= mgl_FrontMaterial.specular;
+
     frontColor *= ambient + diffuse + specular;
   }
 
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColorTexture.fp b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColorTexture.fp
index 86e6ace..130711e 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColorTexture.fp
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColorTexture.fp
@@ -1,4 +1,13 @@
 
+#if __VERSION__ >= 130
+  #define varying in
+  out vec4 mgl_FragColor;
+  #define texture2D texture
+#else
+  #define mgl_FragColor gl_FragColor   
+#endif
+
+
 #include es_precision.glsl
 #include mgl_lightdef.glsl
 
@@ -6,42 +15,103 @@
 #include mgl_uniform.glsl
 #include mgl_varying.glsl
 
-vec4 getTexColor(in sampler2D tex, in int idx) {
-    vec4 coord;
-    if(idx==0) {
-        coord= mgl_TexCoords[0];
-    } else if(idx==1) {
-        coord= mgl_TexCoords[1];
-    } else if(idx==2) {
-        coord= mgl_TexCoords[2];
-    } else if(idx==3) {
-        coord= mgl_TexCoords[3];
-    } else if(idx==4) {
-        coord= mgl_TexCoords[4];
-    } else if(idx==5) {
-        coord= mgl_TexCoords[5];
-    } else if(idx==6) {
-        coord= mgl_TexCoords[6];
-    } else {
-        coord= mgl_TexCoords[7];
+#include mgl_alphatest.fp
+
+const float gamma = 1.5; // FIXME
+const vec3 igammav = vec3(1.0 / gamma); // FIXME
+const vec4 texEnvColor = vec4(0.0); // FIXME
+
+const vec4 zerov4 = vec4(0.0);
+const vec4 onev4 = vec4(1.0);
+
+void calcTexColor(inout vec4 color, vec4 texColor, in int texFormat, in int texEnvMode) {
+    if(MGL_MODULATE == texEnvMode) { // default
+        if( 4 == texFormat ) {
+            color *= texColor;
+        } else {
+            color.rgb *= texColor.rgb;
+        }
+    } else if(MGL_REPLACE == texEnvMode) {
+        if( 4 == texFormat ) {
+            color = texColor;
+        } else {
+            color.rgb = texColor.rgb;
+        }
+    } else if(MGL_ADD == texEnvMode) {
+        if( 4 == texFormat ) {
+            color += texColor;
+        } else {
+            color.rgb += texColor.rgb;
+        }
+    } else if(MGL_BLEND == texEnvMode) {
+        color.rgb = mix(color.rgb, texEnvColor.rgb, texColor.rgb);
+        if( 4 == texFormat ) {
+            color.a *= texColor.a;
+        }
+    } else if(MGL_DECAL == texEnvMode) {
+        if( 4 == texFormat ) {
+            color.rgb = mix(color.rgb, texColor.rgb, texColor.a);
+        } else {
+            color.rgb = texColor.rgb;
+        }
     }
-    return texture2D(tex, coord.st);
+    color = clamp(color, zerov4, onev4);
 }
 
 void main (void)
-{
-  if( mgl_CullFace > 0 && 
-      ( ( mgl_CullFace == 1 && gl_FrontFacing ) ||
-        ( mgl_CullFace == 2 && !gl_FrontFacing ) ||
-        ( mgl_CullFace == 3 ) ) ) {
-    discard;
-  }
-
-  vec4 texColor = getTexColor(mgl_ActiveTexture,mgl_ActiveTextureIdx);
-
-  if(length(texColor.rgb)>0.0) {
-    gl_FragColor = vec4(frontColor.rgb*texColor.rgb, frontColor.a) ;
+{ 
+  vec4 color = frontColor;
+
+  /** ES2 supports CullFace implicit ..
+  if( mgl_CullFace > 0 &&
+      ( ( MGL_FRONT          == mgl_CullFace &&  gl_FrontFacing ) ||
+        ( MGL_BACK           == mgl_CullFace && !gl_FrontFacing ) ||
+        ( MGL_FRONT_AND_BACK == mgl_CullFace ) ) ) {
+      DISCARD(color);
+  } else { */
+      #if MAX_TEXTURE_UNITS >= 2
+      if( 0 != mgl_TextureEnabled[0] ) {
+        calcTexColor(color, texture2D(mgl_Texture0, mgl_TexCoords[0].st), mgl_TexFormat[0], mgl_TexEnvMode[0]);
+      }
+      if( 0 != mgl_TextureEnabled[1] ) {
+        calcTexColor(color, texture2D(mgl_Texture1, mgl_TexCoords[1].st), mgl_TexFormat[1], mgl_TexEnvMode[1]);
+      }
+      #endif
+      #if MAX_TEXTURE_UNITS >= 4
+      if( 0 != mgl_TextureEnabled[2] ) {
+        calcTexColor(color, texture2D(mgl_Texture2, mgl_TexCoords[2].st), mgl_TexFormat[2], mgl_TexEnvMode[2]);
+      }
+      if( 0 != mgl_TextureEnabled[3] ) {
+        calcTexColor(color, texture2D(mgl_Texture3, mgl_TexCoords[3].st), mgl_TexFormat[3], mgl_TexEnvMode[3]);
+      }
+      #endif
+      #if MAX_TEXTURE_UNITS >= 8
+      if( 0 != mgl_TextureEnabled[4] ) {
+        calcTexColor(color, texture2D(mgl_Texture4, mgl_TexCoords[4].st), mgl_TexFormat[4], mgl_TexEnvMode[4]);
+      }
+      if( 0 != mgl_TextureEnabled[5] ) {
+        calcTexColor(color, texture2D(mgl_Texture5, mgl_TexCoords[5].st), mgl_TexFormat[5], mgl_TexEnvMode[5]);
+      }
+      if( 0 != mgl_TextureEnabled[6] ) {
+        calcTexColor(color, texture2D(mgl_Texture6, mgl_TexCoords[6].st), mgl_TexFormat[6], mgl_TexEnvMode[6]);
+      }
+      if( 0 != mgl_TextureEnabled[7] ) {
+        calcTexColor(color, texture2D(mgl_Texture7, mgl_TexCoords[7].st), mgl_TexFormat[7], mgl_TexEnvMode[7]);
+      }
+      #endif
+      if( mgl_AlphaTestFunc > 0 ) {
+        alphaTest(color);
+      }
+  // } /* CullFace */
+
+  mgl_FragColor = color;
+  /**
+  // simple alpha check
+  if (color.a != 0.0) {
+      mgl_FragColor = vec4(pow(color.rgb, igammav), color.a);
   } else {
-    gl_FragColor = frontColor;
-  }
+      // discard; // freezes NV tegra2 compiler
+      mgl_FragColor = color;
+  } */
 }
+
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncPoints.fp b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncPoints.fp
new file mode 100644
index 0000000..2d58f23
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncPoints.fp
@@ -0,0 +1,47 @@
+
+#if __VERSION__ >= 130
+  #define varying in
+  out vec4 mgl_FragColor;
+#else
+  #define mgl_FragColor gl_FragColor   
+#endif
+
+
+#include es_precision.glsl
+#include mgl_lightdef.glsl
+
+#include mgl_const.glsl
+#include mgl_uniform.glsl
+#include mgl_varying.glsl
+
+// #define TEST 1
+
+void main (void)
+{ 
+  mgl_FragColor = frontColor;
+
+  if( pointSmooth > 0.5 ) {
+      // smooth (AA)
+      const float border = 0.90; // take/give 10% for AA
+
+      // origin to 0/0, [-1/-1 .. 1/1]
+      vec2 pointPos = 2.0 * gl_PointCoord - 1.0 ;
+      float r = length( pointPos ); // one-circle sqrt(x * x + y * y), range: in-circle [0..1], out >1
+      float r1 = 1.0 - ( step(border, r) * 10.0 * ( r - border ) ) ; // [0..1]
+      #ifndef TEST
+          if( r1 < 0.0 ) {
+            discard;
+          }
+      #endif
+
+      #ifndef TEST
+          mgl_FragColor.a *= r1;
+      #else
+          mgl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
+          mgl_FragColor.r = r1 < 0.0 ? 1.0 : 0.0;
+          mgl_FragColor.g = r > 1.0 ? 1.0 : 0.0;
+          mgl_FragColor.b = r > border ? 1.0 : 0.0;
+      #endif
+  }
+}
+
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncPoints.vp b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncPoints.vp
new file mode 100644
index 0000000..4a5d93a
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncPoints.vp
@@ -0,0 +1,40 @@
+
+#if __VERSION__ >= 130
+  #define attribute in
+  #define varying out
+#endif
+
+#include es_precision.glsl
+
+#include mgl_const.glsl
+#include mgl_uniform.glsl
+#include mgl_attribute.glsl
+#include mgl_varying.glsl
+
+#include mgl_settexcoord.vp
+
+void main(void)
+{
+  if( mgl_ColorEnabled > 0 ) {
+    frontColor = mgl_Color;
+  } else {
+    frontColor = mgl_ColorStatic;
+  }
+
+  vec4 eyeCoord = mgl_PMVMatrix[1] * mgl_Vertex;
+  gl_Position = mgl_PMVMatrix[0] * eyeCoord;
+
+  float dist = distance(eyeCoord, vec4(0.0, 0.0, 0.0, 1.0));
+  float atten = sqrt( 1.0 / ( pointDistanceConstantAtten +
+                              ( pointDistanceLinearAtten +
+                                pointDistanceQuadraticAtten * dist
+                              ) * dist
+                            )
+                    );
+  float size = clamp(pointSize * atten, pointSizeMin, pointSizeMax);
+  gl_PointSize = max(size, pointFadeThresholdSize);
+
+  float fade = min(size, pointFadeThresholdSize) / pointFadeThresholdSize;
+  frontColor.a *= fade * fade;
+}
+
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_alphatest.fp b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_alphatest.fp
new file mode 100644
index 0000000..2b64cde
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_alphatest.fp
@@ -0,0 +1,33 @@
+
+void alphaTest(inout vec4 color) {
+    if( MGL_GREATER == mgl_AlphaTestFunc ) {
+        if ( color.a <= mgl_AlphaTestRef ) {
+            DISCARD(color);
+        }
+    } else if( MGL_LESS == mgl_AlphaTestFunc ) {
+        if ( color.a >= mgl_AlphaTestRef ) {
+            DISCARD(color);
+        }
+    } else if( MGL_LEQUAL == mgl_AlphaTestFunc ) {
+        if ( color.a > mgl_AlphaTestRef ) {
+            DISCARD(color);
+        }
+    } else if( MGL_GEQUAL == mgl_AlphaTestFunc ) {
+        if ( color.a < mgl_AlphaTestRef ) {
+            DISCARD(color);
+        }
+    } else if( MGL_EQUAL == mgl_AlphaTestFunc ) {
+        if ( abs( color.a - mgl_AlphaTestRef ) > EPSILON ) {
+            DISCARD(color);
+        }
+    } else if( MGL_NOTEQUAL == mgl_AlphaTestFunc ) {
+        if ( abs( color.a - mgl_AlphaTestRef ) <= EPSILON ) {
+            DISCARD(color);
+        }
+    } else if( MGL_NEVER == mgl_AlphaTestFunc ) {
+        DISCARD(color);
+    } /* else if( MGL_ALWAYS == mgl_AlphaTestFunc ) {
+      // NOP
+    } */
+}
+
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_attribute.glsl b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_attribute.glsl
index 09a11ec..f670f7b 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_attribute.glsl
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_attribute.glsl
@@ -4,16 +4,22 @@
 
 #include es_precision.glsl
 
-attribute HIGHP vec4    mgl_Vertex;
-attribute HIGHP vec4    mgl_Normal;
-attribute HIGHP vec4    mgl_Color;
-attribute HIGHP vec4    mgl_MultiTexCoord0;
-attribute HIGHP vec4    mgl_MultiTexCoord1;
-attribute HIGHP vec4    mgl_MultiTexCoord2;
-attribute HIGHP vec4    mgl_MultiTexCoord3;
-attribute HIGHP vec4    mgl_MultiTexCoord4;
-attribute HIGHP vec4    mgl_MultiTexCoord5;
-attribute HIGHP vec4    mgl_MultiTexCoord6;
-attribute HIGHP vec4    mgl_MultiTexCoord7;
+attribute vec4    mgl_Vertex;
+attribute vec4    mgl_Normal;
+attribute vec4    mgl_Color;
+#if MAX_TEXTURE_UNITS >= 2
+attribute vec4    mgl_MultiTexCoord0;
+attribute vec4    mgl_MultiTexCoord1;
+#endif
+#if MAX_TEXTURE_UNITS >= 4
+attribute vec4    mgl_MultiTexCoord2;
+attribute vec4    mgl_MultiTexCoord3;
+#endif
+#if MAX_TEXTURE_UNITS >= 8
+attribute vec4    mgl_MultiTexCoord4;
+attribute vec4    mgl_MultiTexCoord5;
+attribute vec4    mgl_MultiTexCoord6;
+attribute vec4    mgl_MultiTexCoord7;
+#endif
 
 #endif // mgl_attribute_glsl
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_const.glsl b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_const.glsl
index 1a464a1..4f97292 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_const.glsl
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_const.glsl
@@ -4,7 +4,36 @@
 
 #include es_precision.glsl
 
-const   LOWP int     MAX_TEXTURE_UNITS = 8; // <=gl_MaxTextureImageUnits 
+// will be defined at runtime: MAX_TEXTURE_UNITS [0|2|4|8]
 const   LOWP int     MAX_LIGHTS = 8; 
 
+const        float   EPSILON =  0.0000001;  // FIXME: determine proper hw-precision
+
+// discard freezes NV tegra2 compiler (STILL TRUE?)
+// #define DISCARD(c) (c.a = 0.0)
+#define DISCARD(c) discard
+
+// Texture Environment / Multi Texturing
+#define MGL_ADD      1
+#define MGL_MODULATE 2
+#define MGL_DECAL    3
+#define MGL_BLEND    4
+#define MGL_REPLACE  5
+#define MGL_COMBINE  6
+
+// Alpha Test
+#define MGL_NEVER    1
+#define MGL_LESS     2
+#define MGL_EQUAL    3
+#define MGL_LEQUAL   4
+#define MGL_GREATER  5
+#define MGL_NOTEQUAL 6
+#define MGL_GEQUAL   7
+#define MGL_ALWAYS   8
+
+// Cull Face
+#define MGL_FRONT            1
+#define MGL_BACK             2
+#define MGL_FRONT_AND_BACK   3
+
 #endif // mgl_const_glsl
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_lightdef.glsl b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_lightdef.glsl
index 98e2141..deaf954 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_lightdef.glsl
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_lightdef.glsl
@@ -1,6 +1,9 @@
 #ifndef mgl_lightdef_glsl
 #define mgl_lightdef_glsl
 
+struct mgl_LightModelParameters {
+   vec4 ambient; 
+};
 struct mgl_LightSourceParameters {
    vec4 ambient; 
    vec4 diffuse; 
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_settexcoord.vp b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_settexcoord.vp
index 1efe328..cbf0db6 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_settexcoord.vp
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_settexcoord.vp
@@ -22,14 +22,20 @@ void setTexCoord(in vec4 defpos) {
   mgl_TexCoords[7] = ( 0 != (mgl_TexCoordEnabled & 128) ) ? mgl_MultiTexCoord7 : defpos;
    */
   
+  #if MAX_TEXTURE_UNITS >= 2
   mgl_TexCoords[0] = ( 0 != mgl_TexCoordEnabled[0] ) ? mgl_MultiTexCoord0 : defpos;
   mgl_TexCoords[1] = ( 0 != mgl_TexCoordEnabled[1] ) ? mgl_MultiTexCoord1 : defpos;
+  #endif
+  #if MAX_TEXTURE_UNITS >= 4
   mgl_TexCoords[2] = ( 0 != mgl_TexCoordEnabled[2] ) ? mgl_MultiTexCoord2 : defpos;
   mgl_TexCoords[3] = ( 0 != mgl_TexCoordEnabled[3] ) ? mgl_MultiTexCoord3 : defpos;
+  #endif
+  #if MAX_TEXTURE_UNITS >= 8
   mgl_TexCoords[4] = ( 0 != mgl_TexCoordEnabled[4] ) ? mgl_MultiTexCoord4 : defpos;
   mgl_TexCoords[5] = ( 0 != mgl_TexCoordEnabled[5] ) ? mgl_MultiTexCoord5 : defpos;
   mgl_TexCoords[6] = ( 0 != mgl_TexCoordEnabled[6] ) ? mgl_MultiTexCoord6 : defpos;
   mgl_TexCoords[7] = ( 0 != mgl_TexCoordEnabled[7] ) ? mgl_MultiTexCoord7 : defpos;
+  #endif
 }
 
 #endif // mgl_settexcoord_vp
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_uniform.glsl b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_uniform.glsl
index 4c4000d..5029e4b 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_uniform.glsl
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_uniform.glsl
@@ -6,12 +6,45 @@
 
 #include mgl_const.glsl
 
-uniform HIGHP   mat4    mgl_PMVMatrix[4]; // P, Mv, Mvi and Mvit (transpose(inverse(ModelView)) == normalMatrix)
+uniform         mat4    mgl_PMVMatrix[4]; // P, Mv, Mvi and Mvit (transpose(inverse(ModelView)) == normalMatrix)
 uniform LOWP    int     mgl_ColorEnabled;
-uniform HIGHP   vec4    mgl_ColorStatic;
+uniform         vec4    mgl_ColorStatic;
+uniform LOWP    int     mgl_AlphaTestFunc;
+uniform         float   mgl_AlphaTestRef;
+
+// [0].rgba: size, smooth, attnMinSz, attnMaxSz
+// [1].rgba: attnCoeff(3), attnFadeTs
+uniform MEDIUMP vec4    mgl_PointParams[2];
+
+#define pointSize                   (mgl_PointParams[0].r)
+#define pointSmooth                 (mgl_PointParams[0].g)
+#define pointSizeMin                (mgl_PointParams[0].b)
+#define pointSizeMax                (mgl_PointParams[0].a)
+#define pointDistanceConstantAtten  (mgl_PointParams[1].r)
+#define pointDistanceLinearAtten    (mgl_PointParams[1].g)
+#define pointDistanceQuadraticAtten (mgl_PointParams[1].b)
+#define pointFadeThresholdSize      (mgl_PointParams[1].a)
+
+// uniform LOWP int    mgl_CullFace; // ES2 supports CullFace implicit ..
+#if MAX_TEXTURE_UNITS > 0
+uniform LOWP    int     mgl_TextureEnabled[MAX_TEXTURE_UNITS];
 uniform LOWP    int     mgl_TexCoordEnabled[MAX_TEXTURE_UNITS];
-uniform       sampler2D mgl_ActiveTexture;
-uniform LOWP    int     mgl_ActiveTextureIdx;
-uniform LOWP    int     mgl_CullFace;
+uniform LOWP    int     mgl_TexEnvMode[MAX_TEXTURE_UNITS];
+uniform LOWP    int     mgl_TexFormat[MAX_TEXTURE_UNITS];
+#if MAX_TEXTURE_UNITS >= 2
+uniform   sampler2D     mgl_Texture0;
+uniform   sampler2D     mgl_Texture1;
+#endif
+#if MAX_TEXTURE_UNITS >= 4
+uniform   sampler2D     mgl_Texture2;
+uniform   sampler2D     mgl_Texture3;
+#endif
+#if MAX_TEXTURE_UNITS >= 8
+uniform   sampler2D     mgl_Texture4;
+uniform   sampler2D     mgl_Texture5;
+uniform   sampler2D     mgl_Texture6;
+uniform   sampler2D     mgl_Texture7;
+#endif
+#endif
 
 #endif // mgl_uniform_glsl
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_uniform_light.glsl b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_uniform_light.glsl
index 0dedb5d..5b34fd9 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_uniform_light.glsl
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_uniform_light.glsl
@@ -9,6 +9,7 @@
 
 uniform LOWP    int     mgl_LightsEnabled[MAX_LIGHTS];
 
+uniform mgl_LightModelParameters  mgl_LightModel;
 uniform mgl_LightSourceParameters mgl_LightSource[MAX_LIGHTS];
 uniform mgl_MaterialParameters    mgl_FrontMaterial;
 
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_varying.glsl b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_varying.glsl
index fc9f735..599ac4a 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_varying.glsl
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_varying.glsl
@@ -7,6 +7,8 @@
 #include mgl_const.glsl
 
 varying   vec4    frontColor;
+#if MAX_TEXTURE_UNITS > 0
 varying   vec4    mgl_TexCoords[MAX_TEXTURE_UNITS];
+#endif
 
 #endif // mgl_varying_glsl
diff --git a/src/jogl/classes/jogamp/opengl/util/pngj/chunks/PngChunkTIME.java b/src/jogl/classes/jogamp/opengl/util/pngj/chunks/PngChunkTIME.java
index 37e617a..fa61f62 100644
--- a/src/jogl/classes/jogamp/opengl/util/pngj/chunks/PngChunkTIME.java
+++ b/src/jogl/classes/jogamp/opengl/util/pngj/chunks/PngChunkTIME.java
@@ -75,7 +75,7 @@ public class PngChunkTIME extends PngChunk {
 
 	/** format YYYY/MM/DD HH:mm:SS */
 	public String getAsString() {
-		return String.format("%04/%02d/%02d %02d:%02d:%02d", year, mon, day, hour, min, sec);
+		return String.format("%04d/%02d/%02d %02d:%02d:%02d", year, mon, day, hour, min, sec);
 	}
 
 	
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WGLGLCapabilities.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WGLGLCapabilities.java
index 6a4ce5a..99064b1 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WGLGLCapabilities.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WGLGLCapabilities.java
@@ -28,6 +28,8 @@
 
 package jogamp.opengl.windows.wgl;
 
+import java.nio.IntBuffer;
+
 import jogamp.nativewindow.windows.GDI;
 import jogamp.nativewindow.windows.PIXELFORMATDESCRIPTOR;
 
@@ -75,12 +77,13 @@ public class WGLGLCapabilities extends GLCapabilities {
       return true;
   }
 
-  public boolean setValuesByARB(final int[] iattribs, final int niattribs, final int[] iresults) {
+  public boolean setValuesByARB(final IntBuffer iattribs, final int niattribs, final IntBuffer iresults) {
       arb_pixelformat = 1;
 
       int alphaBits = 0;
       for (int i = 0; i < niattribs; i++) {
-          int attr = iattribs[i];
+          final int attr = iattribs.get(i);
+          final int res = iresults.get(i);
           switch (attr) {
               case WGLExt.WGL_DRAW_TO_WINDOW_ARB:
               case WGLExt.WGL_DRAW_TO_BITMAP_ARB:
@@ -88,37 +91,37 @@ public class WGLGLCapabilities extends GLCapabilities {
                   break;
 
               case WGLExt.WGL_ACCELERATION_ARB:
-                  setHardwareAccelerated(iresults[i] == WGLExt.WGL_FULL_ACCELERATION_ARB);
+                  setHardwareAccelerated(res == WGLExt.WGL_FULL_ACCELERATION_ARB);
                   break;
 
               case WGLExt.WGL_SUPPORT_OPENGL_ARB:
-                  if (iresults[i] != GL.GL_TRUE) {
+                  if (res != GL.GL_TRUE) {
                       return false;
                   }
                   break;
 
               case WGLExt.WGL_DEPTH_BITS_ARB:
-                  setDepthBits(iresults[i]);
+                  setDepthBits(res);
                   break;
 
               case WGLExt.WGL_STENCIL_BITS_ARB:
-                  setStencilBits(iresults[i]);
+                  setStencilBits(res);
                   break;
 
               case WGLExt.WGL_DOUBLE_BUFFER_ARB:
-                  setDoubleBuffered(iresults[i] == GL.GL_TRUE);
+                  setDoubleBuffered(res == GL.GL_TRUE);
                   break;
 
               case WGLExt.WGL_STEREO_ARB:
-                  setStereo(iresults[i] == GL.GL_TRUE);
+                  setStereo(res == GL.GL_TRUE);
                   break;
 
               case WGLExt.WGL_PIXEL_TYPE_ARB:
-                  if(iresults[i] == WGLExt.WGL_TYPE_COLORINDEX_ARB) {
+                  if(res == WGLExt.WGL_TYPE_COLORINDEX_ARB) {
                       return false; // color index not supported
                   }
 
-                  if (iresults[i] == WGLExt.WGL_TYPE_RGBA_FLOAT_ARB) {
+                  if (res == WGLExt.WGL_TYPE_RGBA_FLOAT_ARB) {
                       setPbufferFloatingPointBuffers(true);
                   }
 
@@ -127,54 +130,54 @@ public class WGLGLCapabilities extends GLCapabilities {
                   break;
 
               case WGLExt.WGL_FLOAT_COMPONENTS_NV:
-                  if (iresults[i] != 0) {
+                  if (res != 0) {
                       setPbufferFloatingPointBuffers(true);
                   }
                   break;
 
               case WGLExt.WGL_RED_BITS_ARB:
-                  setRedBits(iresults[i]);
+                  setRedBits(res);
                   break;
 
               case WGLExt.WGL_GREEN_BITS_ARB:
-                  setGreenBits(iresults[i]);
+                  setGreenBits(res);
                   break;
 
               case WGLExt.WGL_BLUE_BITS_ARB:
-                  setBlueBits(iresults[i]);
+                  setBlueBits(res);
                   break;
 
               case WGLExt.WGL_ALPHA_BITS_ARB:
                   // ALPHA shall be set at last - due to it's auto setting by !opaque / samples
-                  alphaBits = iresults[i];
+                  alphaBits = res;
                   break;
 
               case WGLExt.WGL_ACCUM_RED_BITS_ARB:
-                  setAccumRedBits(iresults[i]);
+                  setAccumRedBits(res);
                   break;
 
               case WGLExt.WGL_ACCUM_GREEN_BITS_ARB:
-                  setAccumGreenBits(iresults[i]);
+                  setAccumGreenBits(res);
                   break;
 
               case WGLExt.WGL_ACCUM_BLUE_BITS_ARB:
-                  setAccumBlueBits(iresults[i]);
+                  setAccumBlueBits(res);
                   break;
 
               case WGLExt.WGL_ACCUM_ALPHA_BITS_ARB:
-                  setAccumAlphaBits(iresults[i]);
+                  setAccumAlphaBits(res);
                   break;
 
               case WGLExt.WGL_SAMPLE_BUFFERS_ARB:
-                  setSampleBuffers(iresults[i] != 0);
+                  setSampleBuffers(res != 0);
                   break;
 
               case WGLExt.WGL_SAMPLES_ARB:
-                  setNumSamples(iresults[i]);
+                  setNumSamples(res);
                   break;
 
               default:
-                  throw new GLException("Unknown pixel format attribute " + iattribs[i]);
+                  throw new GLException("Unknown pixel format attribute " + attr);
           }
       }
       setAlphaBits(alphaBits);
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java
index 96c1187..f6cc295 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java
@@ -50,8 +50,8 @@ import javax.media.opengl.GLDrawableFactory;
 import javax.media.opengl.GLException;
 import javax.media.opengl.GLProfile;
 
-import com.jogamp.nativewindow.WrappedSurface;
 
+import jogamp.nativewindow.WrappedSurface;
 import jogamp.nativewindow.windows.GDI;
 import jogamp.opengl.GLContextShareSet;
 
@@ -102,7 +102,7 @@ public class WindowsExternalWGLContext extends WindowsWGLContext {
             System.err.println("WindowsExternalWGLContext valid hdc/pfd, retrieved cfg: " + cfg);
         }
     }
-    return new WindowsExternalWGLContext(new Drawable(factory, new WrappedSurface(cfg, hdc, 64, 64, null)), ctx, cfg);
+    return new WindowsExternalWGLContext(new Drawable(factory, new WrappedSurface(cfg, hdc, 64, 64, true)), ctx, cfg);
   }
 
   @Override
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLDrawable.java
index 15bd005..f8c237c 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLDrawable.java
@@ -49,10 +49,10 @@ import javax.media.opengl.GLDrawableFactory;
 import javax.media.opengl.GLException;
 import javax.media.opengl.GLProfile;
 
+import jogamp.nativewindow.WrappedSurface;
 import jogamp.nativewindow.windows.GDI;
 import jogamp.nativewindow.windows.GDIUtil;
 
-import com.jogamp.nativewindow.WrappedSurface;
 
 public class WindowsExternalWGLDrawable extends WindowsWGLDrawable {
 
@@ -72,7 +72,7 @@ public class WindowsExternalWGLDrawable extends WindowsWGLDrawable {
 
     final AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS);
     final WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfiguration.createFromExternal(factory, hdc, pfdID, glp, aScreen, true);
-    return new WindowsExternalWGLDrawable(factory, new WrappedSurface(cfg, hdc, 64, 64, null));
+    return new WindowsExternalWGLDrawable(factory, new WrappedSurface(cfg, hdc, 64, 64, true));
   }
 
 
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java
index 1756223..7a512c8 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java
@@ -40,6 +40,10 @@
 
 package jogamp.opengl.windows.wgl;
 
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+
+import javax.media.nativewindow.AbstractGraphicsDevice;
 import javax.media.nativewindow.NativeSurface;
 import javax.media.nativewindow.NativeWindowException;
 import javax.media.nativewindow.MutableSurface;
@@ -50,8 +54,11 @@ import javax.media.opengl.GLDrawableFactory;
 import javax.media.opengl.GLException;
 import javax.media.opengl.GLProfile;
 
+import com.jogamp.common.nio.Buffers;
+
 import jogamp.nativewindow.windows.GDI;
 import jogamp.opengl.GLDrawableImpl;
+import jogamp.opengl.GLGraphicsConfigurationUtil;
 import jogamp.opengl.windows.wgl.WindowsWGLDrawableFactory.SharedResource;
 // import javax.media.opengl.GLPbuffer;
 
@@ -127,13 +134,16 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
             System.out.println("Pbuffer config: " + config);
         }
 
-        int[]   iattributes = new int  [2*WindowsWGLGraphicsConfiguration.MAX_ATTRIBS];
-        float[] fattributes = new float[1];
+        final int winattrPbuffer = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(false /* onscreen */, false /* fbo */, true /* pbuffer */, false /* bitmap */);
+        
+        final IntBuffer iattributes = Buffers.newDirectIntBuffer(2*WindowsWGLGraphicsConfiguration.MAX_ATTRIBS);
+        final FloatBuffer fattributes = Buffers.newDirectFloatBuffer(1);
         int[]   floatModeTmp = new int[1];
         int     niattribs   = 0;
 
-        GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable)config.getChosenCapabilities();
-        GLProfile glProfile = chosenCaps.getGLProfile();
+        final GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable)config.getChosenCapabilities();
+        final GLProfile glProfile = chosenCaps.getGLProfile();
+        final AbstractGraphicsDevice device = config.getScreen().getDevice();
 
         if (DEBUG) {
           System.out.println("Pbuffer parentHdc = " + toHexString(sharedHdc));
@@ -156,18 +166,14 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
           ati = (floatMode == GLPbuffer.ATI_FLOAT);
         } */
 
-        int[] pformats = new int[WindowsWGLGraphicsConfiguration.MAX_PFORMATS];
-        int   nformats;
-        int[] nformatsTmp = new int[1];
+        final IntBuffer pformats = Buffers.newDirectIntBuffer(WindowsWGLGraphicsConfiguration.MAX_PFORMATS);
+        final IntBuffer nformatsTmp = Buffers.newDirectIntBuffer(1);
         if (!wglExt.wglChoosePixelFormatARB(sharedHdc,
-                                            iattributes, 0,
-                                            fattributes, 0,
-                                            WindowsWGLGraphicsConfiguration.MAX_PFORMATS,
-                                            pformats, 0,
-                                            nformatsTmp, 0)) {
+                                            iattributes, fattributes, WindowsWGLGraphicsConfiguration.MAX_PFORMATS,
+                                            pformats, nformatsTmp)) {
           throw new GLException("pbuffer creation error: wglChoosePixelFormat() failed");
         }
-        nformats = nformatsTmp[0];
+        final int nformats = nformatsTmp.get(0);
         if (nformats <= 0) {
           throw new GLException("pbuffer creation error: Couldn't find a suitable pixel format");
         }
@@ -175,8 +181,9 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
         if (DEBUG) {
           System.err.println("" + nformats + " suitable pixel formats found");
           for (int i = 0; i < nformats; i++) {
-            WGLGLCapabilities dbgCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedResource, sharedHdc, pformats[i], glProfile, false, true);
-            System.err.println("pixel format " + pformats[i] + " (index " + i + "): " + dbgCaps);
+            WGLGLCapabilities dbgCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedResource, device, glProfile, 
+                                          sharedHdc, pformats.get(i), winattrPbuffer);
+            System.err.println("pixel format " + pformats.get(i) + " (index " + i + "): " + dbgCaps);
           }
         }
 
@@ -186,32 +193,32 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
             int whichFormat;
             // Loop is a workaround for bugs in NVidia's recent drivers
             for (whichFormat = 0; whichFormat < nformats; whichFormat++) {
-              int format = pformats[whichFormat];
+              int format = pformats.get(whichFormat);
 
               // Create the p-buffer.
               niattribs = 0;
 
               if (rtt) {
-                iattributes[niattribs++]   = WGLExt.WGL_TEXTURE_FORMAT_ARB;
+                iattributes.put(niattribs++, WGLExt.WGL_TEXTURE_FORMAT_ARB);
                 if (useFloat) {
-                  iattributes[niattribs++] = WGLExt.WGL_TEXTURE_FLOAT_RGB_NV;
+                  iattributes.put(niattribs++, WGLExt.WGL_TEXTURE_FLOAT_RGB_NV);
                 } else {
-                  iattributes[niattribs++] = WGLExt.WGL_TEXTURE_RGBA_ARB;
+                  iattributes.put(niattribs++, WGLExt.WGL_TEXTURE_RGBA_ARB);
                 }
 
-                iattributes[niattribs++] = WGLExt.WGL_TEXTURE_TARGET_ARB;
-                iattributes[niattribs++] = rect ? WGLExt.WGL_TEXTURE_RECTANGLE_NV : WGLExt.WGL_TEXTURE_2D_ARB;
+                iattributes.put(niattribs++, WGLExt.WGL_TEXTURE_TARGET_ARB);
+                iattributes.put(niattribs++, rect ? WGLExt.WGL_TEXTURE_RECTANGLE_NV : WGLExt.WGL_TEXTURE_2D_ARB);
 
-                iattributes[niattribs++] = WGLExt.WGL_MIPMAP_TEXTURE_ARB;
-                iattributes[niattribs++] = GL.GL_FALSE;
+                iattributes.put(niattribs++, WGLExt.WGL_MIPMAP_TEXTURE_ARB);
+                iattributes.put(niattribs++, GL.GL_FALSE);
 
-                iattributes[niattribs++] = WGLExt.WGL_PBUFFER_LARGEST_ARB; // exact
-                iattributes[niattribs++] = GL.GL_FALSE;
+                iattributes.put(niattribs++, WGLExt.WGL_PBUFFER_LARGEST_ARB); // exact
+                iattributes.put(niattribs++, GL.GL_FALSE);
               }
 
-              iattributes[niattribs++] = 0;
+              iattributes.put(niattribs++, 0);
 
-              tmpBuffer = wglExt.wglCreatePbufferARB(sharedHdc, format, getWidth(), getHeight(), iattributes, 0);
+              tmpBuffer = wglExt.wglCreatePbufferARB(sharedHdc, format, getWidth(), getHeight(), iattributes);
               if (tmpBuffer != 0) {
                 // Done
                 break;
@@ -222,7 +229,7 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
               throw new GLException("pbuffer creation error: wglCreatePbuffer() failed: tried " + nformats +
                                     " pixel formats, last error was: " + wglGetLastError());
             }
-            pfdid = pformats[whichFormat];
+            pfdid = pformats.get(whichFormat);
         }
 
         // Get the device context.
@@ -239,7 +246,8 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
 
         // Re-query chosen pixel format
         {
-          WGLGLCapabilities newCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedResource, sharedHdc, pfdid, glProfile, false, true);
+          WGLGLCapabilities newCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedResource, device, glProfile, 
+                                          sharedHdc, pfdid, winattrPbuffer);
           if(null == newCaps) {
             throw new GLException("pbuffer creation error: unable to re-query chosen PFD ID: " + pfdid + ", hdc " + GLDrawableImpl.toHexString(tmpHdc));
           }
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
index 8825bad..57f1652 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
@@ -41,6 +41,7 @@
 package jogamp.opengl.windows.wgl;
 
 import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -51,6 +52,7 @@ import javax.media.opengl.GLContext;
 import javax.media.opengl.GLException;
 import javax.media.opengl.GLCapabilitiesImmutable;
 
+import com.jogamp.common.nio.Buffers;
 import com.jogamp.gluegen.runtime.ProcAddressTable;
 import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
 import com.jogamp.opengl.GLExtensions;
@@ -235,7 +237,8 @@ public class WindowsWGLContext extends GLContextImpl {
     }
 
     try {
-        ctx = _wglExt.wglCreateContextAttribsARB(drawable.getHandle(), share, attribs, 0);
+        final IntBuffer attribsNIO = Buffers.newDirectIntBuffer(attribs);
+        ctx = _wglExt.wglCreateContextAttribsARB(drawable.getHandle(), share, attribsNIO);
     } catch (RuntimeException re) {
         if(DEBUG) {
           Throwable t = new Throwable("Info: WindowWGLContext.createContextARBImpl wglCreateContextAttribsARB failed with "+getGLVersion(major, minor, ctp, "@creation"), re);
@@ -487,9 +490,12 @@ public class WindowsWGLContext extends GLContextImpl {
       if (initSwapGroupImpl(wglExt)>0) {
         final NativeSurface ns = drawable.getNativeSurface();
         try {
-            if( wglExt.wglQueryMaxSwapGroupsNV(ns.getDisplayHandle(),
-                                               maxGroups, maxGroups_offset,
-                                               maxBarriers, maxBarriers_offset) ) {
+            final IntBuffer maxGroupsNIO = Buffers.newDirectIntBuffer(maxGroups.length - maxGroups_offset);
+            final IntBuffer maxBarriersNIO = Buffers.newDirectIntBuffer(maxBarriers.length - maxBarriers_offset);
+
+            if( wglExt.wglQueryMaxSwapGroupsNV(ns.getDisplayHandle(), maxGroupsNIO, maxBarriersNIO) ) {
+                maxGroupsNIO.get(maxGroups, maxGroups_offset, maxGroupsNIO.remaining());
+                maxBarriersNIO.get(maxGroups, maxGroups_offset, maxBarriersNIO.remaining());
                 res = true;
             }
         } catch (Throwable t) { hasSwapGroupNV=-1; }
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java
index ca7886e..3b3f0c1 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java
@@ -73,27 +73,28 @@ public abstract class WindowsWGLDrawable extends GLDrawableImpl {
   }
 
   @Override
-  protected final void swapBuffersImpl() {
-    // single-buffer is already filtered out @ GLDrawableImpl#swapBuffers()
-    final long t0;
-    if (PROFILING) {
-      t0 = System.currentTimeMillis();
-    } else {
-      t0 = 0;
-    }
-
-    if (!WGLUtil.SwapBuffers(getHandle()) && (GDI.GetLastError() != GDI.ERROR_SUCCESS)) {
-      throw new GLException("Error swapping buffers");
-    }
-
-    if (PROFILING) {
-      profilingSwapBuffersTime += System.currentTimeMillis() - t0;
-      if (++profilingSwapBuffersTicks == PROFILING_TICKS) {
-        System.err.println("SwapBuffers calls: " + profilingSwapBuffersTime + " ms / " + PROFILING_TICKS + "  calls (" +
-                           ((float) profilingSwapBuffersTime / (float) PROFILING_TICKS) + " ms/call)");
-        profilingSwapBuffersTime = 0;
-        profilingSwapBuffersTicks = 0;
-      }
+  protected final void swapBuffersImpl(boolean doubleBuffered) {
+    if(doubleBuffered) {
+        final long t0;
+        if (PROFILING) {
+          t0 = System.currentTimeMillis();
+        } else {
+          t0 = 0;
+        }
+    
+        if (!WGLUtil.SwapBuffers(getHandle()) && (GDI.GetLastError() != GDI.ERROR_SUCCESS)) {
+          throw new GLException("Error swapping buffers");
+        }
+    
+        if (PROFILING) {
+          profilingSwapBuffersTime += System.currentTimeMillis() - t0;
+          if (++profilingSwapBuffersTicks == PROFILING_TICKS) {
+            System.err.println("SwapBuffers calls: " + profilingSwapBuffersTime + " ms / " + PROFILING_TICKS + "  calls (" +
+                               ((float) profilingSwapBuffersTime / (float) PROFILING_TICKS) + " ms/call)");
+            profilingSwapBuffersTime = 0;
+            profilingSwapBuffersTicks = 0;
+          }
+        }
     }
   }
 
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
index 09e97ff..c6bc61a 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
@@ -52,7 +52,7 @@ import javax.media.nativewindow.AbstractGraphicsScreen;
 import javax.media.nativewindow.DefaultGraphicsScreen;
 import javax.media.nativewindow.NativeSurface;
 import javax.media.nativewindow.ProxySurface;
-import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook;
+import javax.media.nativewindow.UpstreamSurfaceHook;
 import javax.media.opengl.GL;
 import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLCapabilitiesChooser;
@@ -61,11 +61,11 @@ import javax.media.opengl.GLContext;
 import javax.media.opengl.GLDrawable;
 import javax.media.opengl.GLException;
 import javax.media.opengl.GLProfile;
-import javax.media.opengl.GLProfile.ShutdownType;
 
+import jogamp.nativewindow.WrappedSurface;
 import jogamp.nativewindow.windows.GDI;
+import jogamp.nativewindow.windows.GDIDummyUpstreamSurfaceHook;
 import jogamp.nativewindow.windows.GDISurface;
-import jogamp.nativewindow.windows.GDIUtil;
 import jogamp.nativewindow.windows.RegisteredClassFactory;
 import jogamp.opengl.DesktopGLDynamicLookupHelper;
 import jogamp.opengl.GLContextImpl;
@@ -80,7 +80,6 @@ import com.jogamp.common.nio.PointerBuffer;
 import com.jogamp.common.os.Platform;
 import com.jogamp.common.util.ReflectionUtil;
 import com.jogamp.common.util.VersionNumber;
-import com.jogamp.nativewindow.WrappedSurface;
 import com.jogamp.nativewindow.windows.WindowsGraphicsDevice;
 import com.jogamp.opengl.GLExtensions;
 
@@ -130,7 +129,13 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
   }
 
   @Override
-  protected final void destroy(ShutdownType shutdownType) {
+  protected final boolean isComplete() {
+      return null != windowsWGLDynamicLookupHelper;
+  }
+  
+  
+  @Override
+  protected final void destroy() {
     if(null != sharedResourceRunner) {
         sharedResourceRunner.stop();
         sharedResourceRunner = null;
@@ -143,10 +148,9 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
     /**
      * Pulling away the native library may cause havoc ..
      *
-    if(ShutdownType.COMPLETE == shutdownType && null != windowsWGLDynamicLookupHelper) {
-        windowsWGLDynamicLookupHelper.destroy();
-        windowsWGLDynamicLookupHelper = null;
-    } */
+       windowsWGLDynamicLookupHelper.destroy();
+     */
+    windowsWGLDynamicLookupHelper = null;
 
     RegisteredClassFactory.shutdownSharedClasses();
   }
@@ -314,7 +318,8 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
                 if (null == glp) {
                     throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice);
                 }
-                final GLDrawableImpl sharedDrawable = createOnscreenDrawableImpl(createDummySurfaceImpl(sharedDevice, false, new GLCapabilities(glp), null, 64, 64));
+                final GLCapabilitiesImmutable caps = new GLCapabilities(glp);
+                final GLDrawableImpl sharedDrawable = createOnscreenDrawableImpl(createDummySurfaceImpl(sharedDevice, false, caps, caps, null, 64, 64));
                 sharedDrawable.setRealized(true);
                                 
                 final GLContextImpl sharedContext  = (GLContextImpl) sharedDrawable.createContext(null);
@@ -537,9 +542,9 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
   @Override
   protected final ProxySurface createMutableSurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice, 
                                                         GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, 
-                                                        GLCapabilitiesChooser chooser, int width, int height, UpstreamSurfaceHook lifecycleHook) {
+                                                        GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstreamHook) {
     final WindowsGraphicsDevice device;
-    if(createNewDevice) {
+    if(createNewDevice || !(deviceReq instanceof WindowsGraphicsDevice)) {
         device = new WindowsGraphicsDevice(deviceReq.getConnection(), deviceReq.getUnitID());
     } else {
         device = (WindowsGraphicsDevice)deviceReq;
@@ -549,75 +554,33 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
     if(null == config) {
         throw new GLException("Choosing GraphicsConfiguration failed w/ "+capsChosen+" on "+screen); 
     }    
-    return new WrappedSurface(config, 0, width, height, lifecycleHook);
+    return new WrappedSurface(config, 0, upstreamHook, createNewDevice);
   }
 
   @Override
   public final ProxySurface createDummySurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice, 
-                                                   GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) {
+                                                   GLCapabilitiesImmutable chosenCaps, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) {
     final WindowsGraphicsDevice device;
-    if(createNewDevice) {
+    if( createNewDevice || !(deviceReq instanceof WindowsGraphicsDevice) ) {
         device = new WindowsGraphicsDevice(deviceReq.getConnection(), deviceReq.getUnitID());
     } else {
         device = (WindowsGraphicsDevice)deviceReq;
     }
     final AbstractGraphicsScreen screen = new DefaultGraphicsScreen(device, 0);
-    final GLCapabilitiesImmutable chosenCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(requestedCaps);
+    chosenCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(chosenCaps);
     final WindowsWGLGraphicsConfiguration config = WindowsWGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(chosenCaps, requestedCaps, chooser, screen);
     if(null == config) { 
-        throw new GLException("Choosing GraphicsConfiguration failed w/ "+requestedCaps+" on "+screen);
+        throw new GLException("Choosing GraphicsConfiguration failed w/ "+chosenCaps+" on "+screen);
     }    
-    return new GDISurface(config, 0, width, height, dummySurfaceLifecycleHook);
-  }  
-  private static final ProxySurface.UpstreamSurfaceHook dummySurfaceLifecycleHook = new ProxySurface.UpstreamSurfaceHook() {
-    @Override
-    public final void create(ProxySurface s) {
-        final GDISurface ms = (GDISurface)s;
-        if(0 == ms.getWindowHandle()) {            
-            final long windowHandle = GDIUtil.CreateDummyWindow(0, 0, s.getWidth(), s.getHeight());
-            if(0 == windowHandle) {
-                throw new GLException("Error windowHandle 0, werr: "+GDI.GetLastError());
-            }    
-            ms.setWindowHandle(windowHandle);
-            if(DEBUG) {
-                System.err.println("WindowsWGLDrawableFactory.dummySurfaceLifecycleHook.create: "+ms);
-            }
-        }
-    }
-    @Override
-    public final void destroy(ProxySurface s) {
-        final GDISurface ms = (GDISurface)s;
-        if(0 != ms.getWindowHandle()) {
-            GDI.ShowWindow(ms.getWindowHandle(), GDI.SW_HIDE);
-            GDIUtil.DestroyDummyWindow(ms.getWindowHandle());
-            ms.setWindowHandle(0);
-            if(DEBUG) {
-                System.err.println("WindowsWGLDrawableFactory.dummySurfaceLifecycleHook.destroy: "+ms);
-            }
-        }
-    }
-    @Override
-    public final int getWidth(ProxySurface s) {
-        return s.initialWidth;
-    }
-    @Override
-    public final int getHeight(ProxySurface s) {
-        return s.initialHeight;
-    }
-    
-    @Override
-    public String toString() {
-       return "GDISurfaceLifecycleHook[]";
-    }
-  };
-  
+    return new GDISurface(config, 0, new GDIDummyUpstreamSurfaceHook(width, height), createNewDevice);
+  }    
   
   @Override
   protected final ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice deviceReq, int screenIdx, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream) {
     final WindowsGraphicsDevice device = new WindowsGraphicsDevice(deviceReq.getConnection(), deviceReq.getUnitID());
     final AbstractGraphicsScreen screen = new DefaultGraphicsScreen(device, screenIdx);
     final WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsRequested, capsRequested, chooser, screen);
-    return new GDISurface(cfg, windowHandle, 0, 0, upstream);
+    return new GDISurface(cfg, windowHandle, upstream, true);
   }
 
   @Override
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java
index 209589b..70da113 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java
@@ -33,6 +33,8 @@
 
 package jogamp.opengl.windows.wgl;
 
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -47,6 +49,7 @@ import javax.media.opengl.GLException;
 import javax.media.opengl.GLPbuffer;
 import javax.media.opengl.GLProfile;
 
+import com.jogamp.common.nio.Buffers;
 import com.jogamp.nativewindow.MutableGraphicsConfiguration;
 import com.jogamp.opengl.GLExtensions;
 
@@ -57,6 +60,7 @@ import jogamp.nativewindow.windows.PIXELFORMATDESCRIPTOR;
 import jogamp.opengl.GLContextImpl;
 import jogamp.opengl.GLGraphicsConfigurationUtil;
 
+ at SuppressWarnings("deprecation")
 public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguration implements Cloneable {    
     protected static final int MAX_PFORMATS = 256;
     protected static final int MAX_ATTRIBS  = 256;
@@ -104,9 +108,9 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
         WGLGLCapabilities caps = null;
 
         if(hasARB) {
-            caps = wglARBPFID2GLCapabilities(sharedResource, hdc, pfdID, glp, onscreen, true /* pbuffer */);
+            caps = wglARBPFID2GLCapabilities(sharedResource, device, glp, hdc, pfdID, GLGraphicsConfigurationUtil.ALL_BITS);
         } else {
-            caps = PFD2GLCapabilities(glp, hdc, pfdID, onscreen);
+            caps = PFD2GLCapabilities(device, glp, hdc, pfdID, GLGraphicsConfigurationUtil.ALL_BITS);
         }
         if(null==caps) {
             throw new GLException("Couldn't choose Capabilities by: HDC 0x"+Long.toHexString(hdc)+
@@ -185,7 +189,7 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
             }
         }
         if (DEBUG) {
-            System.err.println("setPixelFormat (ARB): hdc "+toHexString(hdc) +", "+caps);
+            System.err.println("setPixelFormat: hdc "+toHexString(hdc) +", "+caps);
         }
         setCapsPFD(caps);
     }
@@ -224,38 +228,38 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
     public final int getPixelFormatID() { return isDetermined ? ((WGLGLCapabilities)capabilitiesChosen).getPFDID() : 0; }
     public final boolean isChoosenByARB() { return isDetermined ? ((WGLGLCapabilities)capabilitiesChosen).isSetByARB() : false; }
 
-    static int fillAttribsForGeneralWGLARBQuery(WindowsWGLDrawableFactory.SharedResource sharedResource, int[] iattributes) {
+    static int fillAttribsForGeneralWGLARBQuery(WindowsWGLDrawableFactory.SharedResource sharedResource, IntBuffer iattributes) {
         int niattribs = 0;
-        iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_WINDOW_ARB;
+        iattributes.put(niattribs++, WGLExt.WGL_DRAW_TO_WINDOW_ARB);
         if(sharedResource.hasARBPBuffer()) {
-            iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_PBUFFER_ARB;
-        }
-        iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_BITMAP_ARB;
-        iattributes[niattribs++] = WGLExt.WGL_ACCELERATION_ARB;
-        iattributes[niattribs++] = WGLExt.WGL_SUPPORT_OPENGL_ARB;
-        iattributes[niattribs++] = WGLExt.WGL_DEPTH_BITS_ARB;
-        iattributes[niattribs++] = WGLExt.WGL_STENCIL_BITS_ARB;
-        iattributes[niattribs++] = WGLExt.WGL_DOUBLE_BUFFER_ARB;
-        iattributes[niattribs++] = WGLExt.WGL_STEREO_ARB;
-        iattributes[niattribs++] = WGLExt.WGL_PIXEL_TYPE_ARB;
-        iattributes[niattribs++] = WGLExt.WGL_RED_BITS_ARB;
-        iattributes[niattribs++] = WGLExt.WGL_GREEN_BITS_ARB;
-        iattributes[niattribs++] = WGLExt.WGL_BLUE_BITS_ARB;
-        iattributes[niattribs++] = WGLExt.WGL_ALPHA_BITS_ARB;
-        iattributes[niattribs++] = WGLExt.WGL_ACCUM_RED_BITS_ARB;
-        iattributes[niattribs++] = WGLExt.WGL_ACCUM_GREEN_BITS_ARB;
-        iattributes[niattribs++] = WGLExt.WGL_ACCUM_BLUE_BITS_ARB;
-        iattributes[niattribs++] = WGLExt.WGL_ACCUM_ALPHA_BITS_ARB;
+            iattributes.put(niattribs++, WGLExt.WGL_DRAW_TO_PBUFFER_ARB);
+        }
+        iattributes.put(niattribs++, WGLExt.WGL_DRAW_TO_BITMAP_ARB);
+        iattributes.put(niattribs++, WGLExt.WGL_ACCELERATION_ARB);
+        iattributes.put(niattribs++, WGLExt.WGL_SUPPORT_OPENGL_ARB);
+        iattributes.put(niattribs++, WGLExt.WGL_DEPTH_BITS_ARB);
+        iattributes.put(niattribs++, WGLExt.WGL_STENCIL_BITS_ARB);
+        iattributes.put(niattribs++, WGLExt.WGL_DOUBLE_BUFFER_ARB);
+        iattributes.put(niattribs++, WGLExt.WGL_STEREO_ARB);
+        iattributes.put(niattribs++, WGLExt.WGL_PIXEL_TYPE_ARB);
+        iattributes.put(niattribs++, WGLExt.WGL_RED_BITS_ARB);
+        iattributes.put(niattribs++, WGLExt.WGL_GREEN_BITS_ARB);
+        iattributes.put(niattribs++, WGLExt.WGL_BLUE_BITS_ARB);
+        iattributes.put(niattribs++, WGLExt.WGL_ALPHA_BITS_ARB);
+        iattributes.put(niattribs++, WGLExt.WGL_ACCUM_RED_BITS_ARB);
+        iattributes.put(niattribs++, WGLExt.WGL_ACCUM_GREEN_BITS_ARB);
+        iattributes.put(niattribs++, WGLExt.WGL_ACCUM_BLUE_BITS_ARB);
+        iattributes.put(niattribs++, WGLExt.WGL_ACCUM_ALPHA_BITS_ARB);
         if(sharedResource.hasARBMultisample()) {
-            iattributes[niattribs++] = WGLExt.WGL_SAMPLE_BUFFERS_ARB;
-            iattributes[niattribs++] = WGLExt.WGL_SAMPLES_ARB;
+            iattributes.put(niattribs++, WGLExt.WGL_SAMPLE_BUFFERS_ARB);
+            iattributes.put(niattribs++, WGLExt.WGL_SAMPLES_ARB);
         }
             
         if(sharedResource.hasARBPBuffer()) {
             GLContextImpl sharedCtx = sharedResource.getContext();
             if(null != sharedCtx && sharedCtx.isExtensionAvailable(WindowsWGLDrawableFactory.WGL_NV_float_buffer)) {
                 // pbo float buffer
-                iattributes[niattribs++] = WGLExt.WGL_FLOAT_COMPONENTS_NV; // nvidia
+                iattributes.put(niattribs++, WGLExt.WGL_FLOAT_COMPONENTS_NV); // nvidia
             }
         }
 
@@ -263,73 +267,72 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
     }
     
     static boolean wglARBPFIDValid(WindowsWGLContext sharedCtx, long hdc, int pfdID) {
-        int[] in = new int[1];
-        int[] out = new int[1];
-        in[0] = WGLExt.WGL_COLOR_BITS_ARB;
-        if (!sharedCtx.getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdID, 0, 1, in, 0, out, 0)) {
+        final IntBuffer out = Buffers.newDirectIntBuffer(1);
+        final IntBuffer in = Buffers.newDirectIntBuffer(1);
+        in.put(0, WGLExt.WGL_COLOR_BITS_ARB);
+        if (!sharedCtx.getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdID, 0, 1, in, out)) {
             // Some GPU's falsely fails with a zero error code (success)
             return GDI.GetLastError() == GDI.ERROR_SUCCESS ;
         }
         return true;
     }
 
-    static int[] wglAllARBPFIDs(WindowsWGLContext sharedCtx, long hdc) {
-        int[] iattributes = new int[1];
-        int[] iresults = new int[1];
+    static int wglARBPFDIDCount(WindowsWGLContext sharedCtx, long hdc) {
+        final IntBuffer iresults = Buffers.newDirectIntBuffer(1);
+        final IntBuffer iattributes = Buffers.newDirectIntBuffer(1);
+        iattributes.put(0, WGLExt.WGL_NUMBER_PIXEL_FORMATS_ARB); 
 
         WGLExt wglExt = sharedCtx.getWGLExt();
-        iattributes[0] = WGLExt.WGL_NUMBER_PIXEL_FORMATS_ARB;
-        if (!wglExt.wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, iattributes, 0, iresults, 0)) {
+        // pfdID shall be ignored here (spec), however, pass a valid pdf index '1' below (possible driver bug)
+        if (!wglExt.wglGetPixelFormatAttribivARB(hdc, 1 /* pfdID */, 0, 1, iattributes, iresults)) {
             if(DEBUG) {
                 System.err.println("GetPixelFormatAttribivARB: Failed - HDC 0x" + Long.toHexString(hdc) +
+                                  ", value "+iresults.get(0)+
                                   ", LastError: " + GDI.GetLastError());
                 Thread.dumpStack();
             }
-            return null;
+            return 0;
         }
-        int numFormats = iresults[0];
-        if(0 == numFormats) {
+        final int pfdIDCount = iresults.get(0);
+        if(0 == pfdIDCount) {
             if(DEBUG) {
                 System.err.println("GetPixelFormatAttribivARB: No formats - HDC 0x" + Long.toHexString(hdc) +
                                   ", LastError: " + GDI.GetLastError());
                 Thread.dumpStack();
             }
-            return null;
         }
-        int[] pfdIDs = new int[numFormats];
-        for (int i = 0; i < numFormats; i++) {
+        return pfdIDCount;
+    }
+    
+    static int[] wglAllARBPFDIDs(int pfdIDCount) {
+        int[] pfdIDs = new int[pfdIDCount];
+        for (int i = 0; i < pfdIDCount; i++) {
             pfdIDs[i] = 1 + i;
         }
         return pfdIDs;
     }
-
+    
     static WGLGLCapabilities wglARBPFID2GLCapabilities(WindowsWGLDrawableFactory.SharedResource sharedResource,
-                                                       long hdc, int pfdID,
-                                                       GLProfile glp, boolean onscreen, boolean usePBuffer) {
+                                                       AbstractGraphicsDevice device, GLProfile glp,
+                                                       long hdc, int pfdID, int winattrbits) {
         if (!sharedResource.hasARBPixelFormat()) {
             return null;
         }
 
-        int[] iattributes = new int  [2*MAX_ATTRIBS];
-        int[] iresults    = new int  [2*MAX_ATTRIBS];
-
-        int niattribs = fillAttribsForGeneralWGLARBQuery(sharedResource, iattributes);
+        final IntBuffer iattributes = Buffers.newDirectIntBuffer(2*MAX_ATTRIBS);
+        final IntBuffer iresults = Buffers.newDirectIntBuffer(2*MAX_ATTRIBS);
+        final int niattribs = fillAttribsForGeneralWGLARBQuery(sharedResource, iattributes);
 
-        if (!((WindowsWGLContext)sharedResource.getContext()).getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdID, 0, niattribs, iattributes, 0, iresults, 0)) {
+        if (!((WindowsWGLContext)sharedResource.getContext()).getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdID, 0, niattribs, iattributes, iresults)) {
             throw new GLException("wglARBPFID2GLCapabilities: Error getting pixel format attributes for pixel format " + pfdID + 
                                   " of device context " + toHexString(hdc) + ", werr " + GDI.GetLastError());
         }
-        List<GLCapabilitiesImmutable> bucket = new ArrayList<GLCapabilitiesImmutable>(1);
-        final int winattrbits = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer, false);
-        if(AttribList2GLCapabilities(bucket, glp, hdc, pfdID, iattributes, niattribs, iresults, winattrbits)) {
-            return (WGLGLCapabilities) bucket.get(0);
-        }
-        return null;
+        return AttribList2GLCapabilities(device, glp, hdc, pfdID, iattributes, niattribs, iresults, winattrbits);
     }
 
-    static int[] wglChoosePixelFormatARB(long hdc, WindowsWGLDrawableFactory.SharedResource sharedResource,
+    static int[] wglChoosePixelFormatARB(WindowsWGLDrawableFactory.SharedResource sharedResource, AbstractGraphicsDevice device,
                                          GLCapabilitiesImmutable capabilities,
-                                         int[] iattributes, int accelerationMode, float[] fattributes)
+                                         long hdc, IntBuffer iattributes, int accelerationMode, FloatBuffer fattributes)
     {
 
         if ( !WindowsWGLGraphicsConfiguration.GLCapabilities2AttribList(capabilities,
@@ -342,160 +345,167 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
             return null;
         }
 
-        int[] pformatsTmp = new int[WindowsWGLGraphicsConfiguration.MAX_PFORMATS];
-        int[] numFormatsTmp = new int[1];
-        if ( !((WindowsWGLContext)sharedResource.getContext()).getWGLExt().wglChoosePixelFormatARB(hdc, iattributes, 0,
-                                                                fattributes, 0,
-                                                                WindowsWGLGraphicsConfiguration.MAX_PFORMATS,
-                                                                pformatsTmp, 0, numFormatsTmp, 0))
-        {
+        final WGLExt wglExt = ((WindowsWGLContext)sharedResource.getContext()).getWGLExt();
+        final IntBuffer pformatsTmp = Buffers.newDirectIntBuffer(WindowsWGLGraphicsConfiguration.MAX_PFORMATS);
+        final IntBuffer numFormatsTmp = Buffers.newDirectIntBuffer(1);
+        
+        if ( !wglExt.wglChoosePixelFormatARB(hdc, iattributes, fattributes,
+                                             WindowsWGLGraphicsConfiguration.MAX_PFORMATS,
+                                             pformatsTmp, numFormatsTmp) ) {
             if (DEBUG) {
                 System.err.println("wglChoosePixelFormatARB: wglChoosePixelFormatARB failed: " + GDI.GetLastError());
                 Thread.dumpStack();
             }
             return null;
         }
-        int numFormats = numFormatsTmp[0];
-        int[] pformats = null;
+        final int numFormats = numFormatsTmp.get(0);
+        final int[] pformats;
         if( 0 < numFormats ) {
             pformats = new int[numFormats];
-            System.arraycopy(pformatsTmp, 0, pformats, 0, numFormats);
+            pformatsTmp.get(pformats, 0, numFormats);
+        } else {
+            pformats = null;
         }
         if (DEBUG) {
             System.err.println("wglChoosePixelFormatARB: NumFormats (wglChoosePixelFormatARB) accelMode 0x"
                     + Integer.toHexString(accelerationMode) + ": " + numFormats);
             for (int i = 0; i < numFormats; i++) {
                 WGLGLCapabilities dbgCaps0 = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(
-                                                sharedResource, hdc, pformats[i],
-                                                capabilities.getGLProfile(), capabilities.isOnscreen(), capabilities.isPBuffer());
+                                                sharedResource, device, capabilities.getGLProfile(), hdc, pformats[i], GLGraphicsConfigurationUtil.ALL_BITS);
                 System.err.println("pixel format " + pformats[i] + " (index " + i + "): " + dbgCaps0);
             }
         }
         return pformats;
     }
 
-    static List<GLCapabilitiesImmutable> wglARBPFIDs2GLCapabilities(WindowsWGLDrawableFactory.SharedResource sharedResource,
-                                                                    long hdc, int[] pfdIDs, GLProfile glp, boolean onscreen, boolean usePBuffer) {
-        final int winattrbits = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer, false);
-        return wglARBPFIDs2GLCapabilitiesImpl(sharedResource, hdc, pfdIDs, glp, winattrbits);
-    }
-
-    static List <GLCapabilitiesImmutable> wglARBPFIDs2AllGLCapabilities(WindowsWGLDrawableFactory.SharedResource sharedResource,
-                                                                                  long hdc, int[] pfdIDs, GLProfile glp) {
-        return wglARBPFIDs2GLCapabilitiesImpl(sharedResource, hdc, pfdIDs, glp, GLGraphicsConfigurationUtil.ALL_BITS);
-    }
-    
-    private static List <GLCapabilitiesImmutable> wglARBPFIDs2GLCapabilitiesImpl(WindowsWGLDrawableFactory.SharedResource sharedResource,
-                                                                                 long hdc, int[] pfdIDs, GLProfile glp, int winattrbits) {
+    static List <GLCapabilitiesImmutable> wglARBPFIDs2GLCapabilities(WindowsWGLDrawableFactory.SharedResource sharedResource,
+                                                                     AbstractGraphicsDevice device, GLProfile glp, long hdc, int[] pfdIDs, int winattrbits) {
         if (!sharedResource.hasARBPixelFormat()) {
             return null;
         }
         final int numFormats = pfdIDs.length;
 
-        int[] iattributes = new int [2*MAX_ATTRIBS];
-        int[] iresults    = new int [2*MAX_ATTRIBS];
-        int niattribs = fillAttribsForGeneralWGLARBQuery(sharedResource, iattributes);
+        final IntBuffer iattributes = Buffers.newDirectIntBuffer(2*MAX_ATTRIBS);
+        final IntBuffer iresults = Buffers.newDirectIntBuffer(2*MAX_ATTRIBS);
+        final int niattribs = fillAttribsForGeneralWGLARBQuery(sharedResource, iattributes);
 
         ArrayList<GLCapabilitiesImmutable> bucket = new ArrayList<GLCapabilitiesImmutable>();
 
         for(int i = 0; i<numFormats; i++) {
             if ( pfdIDs[i] >= 1 &&
-                 ((WindowsWGLContext)sharedResource.getContext()).getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdIDs[i], 0, niattribs, iattributes, 0, iresults, 0) ) {
-                AttribList2GLCapabilities(bucket, glp, hdc, pfdIDs[i], iattributes, niattribs, iresults, winattrbits);
+                 ((WindowsWGLContext)sharedResource.getContext()).getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdIDs[i], 0, niattribs, iattributes, iresults) ) {
+                final GLCapabilitiesImmutable caps = AttribList2GLCapabilities(device, glp, hdc, pfdIDs[i], iattributes, niattribs, iresults, winattrbits);
+                if(null != caps) {
+                    bucket.add(caps);
+                    if(DEBUG) {
+                        final int j = bucket.size() - 1; 
+                        System.err.println("wglARBPFIDs2GLCapabilities: bucket["+i+" -> "+j+"]: "+caps);
+                    }
+                } else if(DEBUG) {
+                    GLCapabilitiesImmutable skipped = AttribList2GLCapabilities(device, glp, hdc, pfdIDs[i], iattributes, niattribs, iresults, GLGraphicsConfigurationUtil.ALL_BITS);
+                    System.err.println("wglARBPFIDs2GLCapabilities: bucket["+i+" -> skip]: pfdID "+pfdIDs[i]+", "+skipped+", winattr "+GLGraphicsConfigurationUtil.winAttributeBits2String(null, winattrbits).toString());
+                }
             } else if (DEBUG) {
-                System.err.println("wglARBPFIDs2GLCapabilities: Cannot get pixel format attributes for pixel format " +
-                                   i + "/" + numFormats + ": " + pfdIDs[i] + ", " +
-                                   GLGraphicsConfigurationUtil.winAttributeBits2String(null, winattrbits).toString());
+                if( 1 > pfdIDs[i] ) {
+                    System.err.println("wglARBPFIDs2GLCapabilities: Invalid pfdID " + i + "/" + numFormats + ": " + pfdIDs[i]);
+                } else {
+                    System.err.println("wglARBPFIDs2GLCapabilities: Cannot get pixel format attributes for pixel format " +
+                                       i + "/" + numFormats + ": " + pfdIDs[i] + ", hdc " + toHexString(hdc));
+                }
             }
         }
         return bucket;
     }
 
     static boolean GLCapabilities2AttribList(GLCapabilitiesImmutable caps,
-                                             int[] iattributes,
+                                             IntBuffer iattributes,
                                              WindowsWGLDrawableFactory.SharedResource sharedResource,
                                              int accelerationValue,
-                                             int[] floatMode) throws GLException {
+                                             int[] floatMode) throws GLException {    
         if (!sharedResource.hasARBPixelFormat()) {
           return false;
         }
 
-        boolean onscreen = caps.isOnscreen();
-        boolean pbuffer = caps.isPBuffer();
-
         int niattribs = 0;
 
-        iattributes[niattribs++] = WGLExt.WGL_SUPPORT_OPENGL_ARB;
-        iattributes[niattribs++] = GL.GL_TRUE;
+        iattributes.put(niattribs++, WGLExt.WGL_SUPPORT_OPENGL_ARB);
+        iattributes.put(niattribs++, GL.GL_TRUE);
         if(accelerationValue>0) {
-            iattributes[niattribs++] = WGLExt.WGL_ACCELERATION_ARB;
-            iattributes[niattribs++] = accelerationValue;
-        }
-        if (onscreen) {
-          iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_WINDOW_ARB;
-          iattributes[niattribs++] = GL.GL_TRUE;
-        } else if (pbuffer && sharedResource.hasARBPBuffer()) {
-          iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_PBUFFER_ARB;
-          iattributes[niattribs++] = GL.GL_TRUE;
-        } else {
-          iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_BITMAP_ARB;
-          iattributes[niattribs++] = GL.GL_TRUE;
+            iattributes.put(niattribs++, WGLExt.WGL_ACCELERATION_ARB);
+            iattributes.put(niattribs++, accelerationValue);
         }
 
-        iattributes[niattribs++] = WGLExt.WGL_DOUBLE_BUFFER_ARB;
+        final boolean usePBuffer = caps.isPBuffer() && sharedResource.hasARBPBuffer() ;
+        
+        final int surfaceType;
+        if( caps.isOnscreen() ) {
+            surfaceType = WGLExt.WGL_DRAW_TO_WINDOW_ARB;            
+        } else if( caps.isFBO() ) {
+            surfaceType = WGLExt.WGL_DRAW_TO_WINDOW_ARB;  // native replacement!
+        } else if( usePBuffer ) {
+            surfaceType = WGLExt.WGL_DRAW_TO_PBUFFER_ARB;
+        } else if( caps.isBitmap() ) {
+            surfaceType = WGLExt.WGL_DRAW_TO_BITMAP_ARB;
+        } else {
+            throw new GLException("no surface type set in caps: "+caps);
+        }
+        iattributes.put(niattribs++, surfaceType);
+        iattributes.put(niattribs++, GL.GL_TRUE);
+        
+        iattributes.put(niattribs++, WGLExt.WGL_DOUBLE_BUFFER_ARB);
         if (caps.getDoubleBuffered()) {
-          iattributes[niattribs++] = GL.GL_TRUE;
+          iattributes.put(niattribs++, GL.GL_TRUE);
         } else {
-          iattributes[niattribs++] = GL.GL_FALSE;
+          iattributes.put(niattribs++, GL.GL_FALSE);
         }
 
-        iattributes[niattribs++] = WGLExt.WGL_STEREO_ARB;
+        iattributes.put(niattribs++, WGLExt.WGL_STEREO_ARB);
         if (caps.getStereo()) {
-          iattributes[niattribs++] = GL.GL_TRUE;
+          iattributes.put(niattribs++, GL.GL_TRUE);
         } else {
-          iattributes[niattribs++] = GL.GL_FALSE;
+          iattributes.put(niattribs++, GL.GL_FALSE);
         }
         
-        iattributes[niattribs++] = WGLExt.WGL_RED_BITS_ARB;
-        iattributes[niattribs++] = caps.getRedBits();
-        iattributes[niattribs++] = WGLExt.WGL_GREEN_BITS_ARB;
-        iattributes[niattribs++] = caps.getGreenBits();
-        iattributes[niattribs++] = WGLExt.WGL_BLUE_BITS_ARB;
-        iattributes[niattribs++] = caps.getBlueBits();
+        iattributes.put(niattribs++, WGLExt.WGL_RED_BITS_ARB);
+        iattributes.put(niattribs++, caps.getRedBits());
+        iattributes.put(niattribs++, WGLExt.WGL_GREEN_BITS_ARB);
+        iattributes.put(niattribs++, caps.getGreenBits());
+        iattributes.put(niattribs++, WGLExt.WGL_BLUE_BITS_ARB);
+        iattributes.put(niattribs++, caps.getBlueBits());
         if(caps.getAlphaBits()>0) {
-            iattributes[niattribs++] = WGLExt.WGL_ALPHA_BITS_ARB;
-            iattributes[niattribs++] = caps.getAlphaBits();
+            iattributes.put(niattribs++, WGLExt.WGL_ALPHA_BITS_ARB);
+            iattributes.put(niattribs++, caps.getAlphaBits());
         }
         if(caps.getStencilBits()>0) {
-            iattributes[niattribs++] = WGLExt.WGL_STENCIL_BITS_ARB;
-            iattributes[niattribs++] = caps.getStencilBits();
+            iattributes.put(niattribs++, WGLExt.WGL_STENCIL_BITS_ARB);
+            iattributes.put(niattribs++, caps.getStencilBits());
         }
-        iattributes[niattribs++] = WGLExt.WGL_DEPTH_BITS_ARB;
-        iattributes[niattribs++] = caps.getDepthBits();
+        iattributes.put(niattribs++, WGLExt.WGL_DEPTH_BITS_ARB);
+        iattributes.put(niattribs++, caps.getDepthBits());
         if (caps.getAccumRedBits()   > 0 ||
             caps.getAccumGreenBits() > 0 ||
             caps.getAccumBlueBits()  > 0 ||
             caps.getAccumAlphaBits() > 0) {
-          iattributes[niattribs++] = WGLExt.WGL_ACCUM_BITS_ARB;
-          iattributes[niattribs++] = (caps.getAccumRedBits() +
-                                      caps.getAccumGreenBits() +
-                                      caps.getAccumBlueBits() +
-                                      caps.getAccumAlphaBits());
-          iattributes[niattribs++] = WGLExt.WGL_ACCUM_RED_BITS_ARB;
-          iattributes[niattribs++] = caps.getAccumRedBits();
-          iattributes[niattribs++] = WGLExt.WGL_ACCUM_GREEN_BITS_ARB;
-          iattributes[niattribs++] = caps.getAccumGreenBits();
-          iattributes[niattribs++] = WGLExt.WGL_ACCUM_BLUE_BITS_ARB;
-          iattributes[niattribs++] = caps.getAccumBlueBits();
-          iattributes[niattribs++] = WGLExt.WGL_ACCUM_ALPHA_BITS_ARB;
-          iattributes[niattribs++] = caps.getAccumAlphaBits();
+          iattributes.put(niattribs++, WGLExt.WGL_ACCUM_BITS_ARB);
+          iattributes.put(niattribs++, ( caps.getAccumRedBits() +
+                                         caps.getAccumGreenBits() +
+                                         caps.getAccumBlueBits() +
+                                         caps.getAccumAlphaBits() ) );
+          iattributes.put(niattribs++, WGLExt.WGL_ACCUM_RED_BITS_ARB);
+          iattributes.put(niattribs++, caps.getAccumRedBits());
+          iattributes.put(niattribs++, WGLExt.WGL_ACCUM_GREEN_BITS_ARB);
+          iattributes.put(niattribs++, caps.getAccumGreenBits());
+          iattributes.put(niattribs++, WGLExt.WGL_ACCUM_BLUE_BITS_ARB);
+          iattributes.put(niattribs++, caps.getAccumBlueBits());
+          iattributes.put(niattribs++, WGLExt.WGL_ACCUM_ALPHA_BITS_ARB);
+          iattributes.put(niattribs++, caps.getAccumAlphaBits());
         }
 
         if (caps.getSampleBuffers() && sharedResource.hasARBMultisample()) {
-            iattributes[niattribs++] = WGLExt.WGL_SAMPLE_BUFFERS_ARB;
-            iattributes[niattribs++] = GL.GL_TRUE;
-            iattributes[niattribs++] = WGLExt.WGL_SAMPLES_ARB;
-            iattributes[niattribs++] = caps.getNumSamples();
+            iattributes.put(niattribs++, WGLExt.WGL_SAMPLE_BUFFERS_ARB);
+            iattributes.put(niattribs++, GL.GL_TRUE);
+            iattributes.put(niattribs++, WGLExt.WGL_SAMPLES_ARB);
+            iattributes.put(niattribs++, caps.getNumSamples());
         }
 
         boolean rtt      = caps.getPbufferRenderToTexture();
@@ -503,7 +513,7 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
         boolean useFloat = caps.getPbufferFloatingPointBuffers();
         boolean ati      = false;
         boolean nvidia   = false;
-        if (pbuffer && sharedResource.hasARBPBuffer()) {
+        if ( usePBuffer ) {
           // Check some invariants and set up some state
           if (rect && !rtt) {
             throw new GLException("Render-to-texture-rectangle requires render-to-texture to be specified");
@@ -541,22 +551,22 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
             if (rtt) {
               throw new GLException("Render-to-floating-point-texture not supported on ATI hardware");
             } else {
-              iattributes[niattribs++] = WGLExt.WGL_PIXEL_TYPE_ARB;
-              iattributes[niattribs++] = WGLExt.WGL_TYPE_RGBA_FLOAT_ARB;
+              iattributes.put(niattribs++, WGLExt.WGL_PIXEL_TYPE_ARB);
+              iattributes.put(niattribs++, WGLExt.WGL_TYPE_RGBA_FLOAT_ARB);
             }
           } else {
             if (!rtt) {
               // Currently we don't support non-truecolor visuals in the
               // GLCapabilities, so we don't offer the option of making
               // color-index pbuffers.
-              iattributes[niattribs++] = WGLExt.WGL_PIXEL_TYPE_ARB;
-              iattributes[niattribs++] = WGLExt.WGL_TYPE_RGBA_ARB;
+              iattributes.put(niattribs++, WGLExt.WGL_PIXEL_TYPE_ARB);
+              iattributes.put(niattribs++, WGLExt.WGL_TYPE_RGBA_ARB);
             }
           }
 
           if (useFloat && nvidia) {
-            iattributes[niattribs++] = WGLExt.WGL_FLOAT_COMPONENTS_NV;
-            iattributes[niattribs++] = GL.GL_TRUE;
+            iattributes.put(niattribs++, WGLExt.WGL_FLOAT_COMPONENTS_NV);
+            iattributes.put(niattribs++, GL.GL_TRUE);
           }
 
           if (rtt) {
@@ -566,66 +576,72 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
               if (!rect) {
                 throw new GLException("Render-to-floating-point-texture only supported on NVidia hardware with render-to-texture-rectangle");
               }
-              iattributes[niattribs++] = WGLExt.WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV;
-              iattributes[niattribs++] = GL.GL_TRUE;
+              iattributes.put(niattribs++, WGLExt.WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV);
+              iattributes.put(niattribs++, GL.GL_TRUE);
             } else {
-              iattributes[niattribs++] = rect ? WGLExt.WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV : WGLExt.WGL_BIND_TO_TEXTURE_RGB_ARB;
-              iattributes[niattribs++] = GL.GL_TRUE;
+              iattributes.put(niattribs++, rect ? WGLExt.WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV : WGLExt.WGL_BIND_TO_TEXTURE_RGB_ARB);
+              iattributes.put(niattribs++, GL.GL_TRUE);
             }
           }
         } else {
-          iattributes[niattribs++] = WGLExt.WGL_PIXEL_TYPE_ARB;
-          iattributes[niattribs++] = WGLExt.WGL_TYPE_RGBA_ARB;
+          iattributes.put(niattribs++, WGLExt.WGL_PIXEL_TYPE_ARB);
+          iattributes.put(niattribs++, WGLExt.WGL_TYPE_RGBA_ARB);
         }
-        iattributes[niattribs++] = 0;
+        iattributes.put(niattribs++, 0);
 
         return true;
     }
 
-    static int AttribList2DrawableTypeBits(final int[] iattribs, final int niattribs, final int[] iresults) {
+    static int AttribList2DrawableTypeBits(final IntBuffer iattribs, 
+                                           final int niattribs, final IntBuffer iresults) {
         int val = 0;
 
         for (int i = 0; i < niattribs; i++) {
-          int attr = iattribs[i];
+          final int attr = iattribs.get(i);
           switch (attr) {
             case WGLExt.WGL_DRAW_TO_WINDOW_ARB:
-                if(iresults[i] == GL.GL_TRUE) val |= GLGraphicsConfigurationUtil.WINDOW_BIT;
+                if(iresults.get(i) == GL.GL_TRUE) {
+                    val |= GLGraphicsConfigurationUtil.WINDOW_BIT |
+                           GLGraphicsConfigurationUtil.FBO_BIT;
+                }
                 break;
             case WGLExt.WGL_DRAW_TO_BITMAP_ARB:
-                if(iresults[i] == GL.GL_TRUE) val |= GLGraphicsConfigurationUtil.BITMAP_BIT;
+                if(iresults.get(i) == GL.GL_TRUE) {
+                    val |= GLGraphicsConfigurationUtil.BITMAP_BIT;
+                }
                 break;
             case WGLExt.WGL_DRAW_TO_PBUFFER_ARB:
-                if(iresults[i] == GL.GL_TRUE) val |= GLGraphicsConfigurationUtil.PBUFFER_BIT;
+                if(iresults.get(i) == GL.GL_TRUE) {
+                    val |= GLGraphicsConfigurationUtil.PBUFFER_BIT;
+                }
                 break;
             }
         }
         return val;
     }
 
-    static boolean AttribList2GLCapabilities( List<GLCapabilitiesImmutable> capsBucket,
-                                              final GLProfile glp, final long hdc, final int pfdID, final int[] iattribs,
-                                              final int niattribs,
-                                              final int[] iresults, final int winattrmask) {
+    static WGLGLCapabilities AttribList2GLCapabilities(final AbstractGraphicsDevice device, 
+                                                       final GLProfile glp, final long hdc, final int pfdID,
+                                                       final IntBuffer iattribs, final int niattribs, IntBuffer iresults, final int winattrmask) {
         final int allDrawableTypeBits = AttribList2DrawableTypeBits(iattribs, niattribs, iresults);
         int drawableTypeBits = winattrmask & allDrawableTypeBits;
 
         if( 0 == drawableTypeBits ) {
-            return false;
+            return null;
         }
         PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor();
 
         if (WGLUtil.DescribePixelFormat(hdc, pfdID, PIXELFORMATDESCRIPTOR.size(), pfd) == 0) {
             // remove displayable bits, since pfdID is non displayable
-            drawableTypeBits = drawableTypeBits & ~(GLGraphicsConfigurationUtil.WINDOW_BIT | GLGraphicsConfigurationUtil.BITMAP_BIT);
+            drawableTypeBits = drawableTypeBits & ~(GLGraphicsConfigurationUtil.WINDOW_BIT | GLGraphicsConfigurationUtil.BITMAP_BIT | GLGraphicsConfigurationUtil.FBO_BIT );
             if( 0 == drawableTypeBits ) {
-                return false;
+                return null;
             }
             // non displayable requested (pbuffer)
         }
-        WGLGLCapabilities res = new WGLGLCapabilities(pfd, pfdID, glp);
+        final WGLGLCapabilities res = new WGLGLCapabilities(pfd, pfdID, glp);
         res.setValuesByARB(iattribs, niattribs, iresults);
-
-        return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, res, drawableTypeBits );
+        return (WGLGLCapabilities) GLGraphicsConfigurationUtil.fixWinAttribBitsAndHwAccel(device, drawableTypeBits, res); 
     }
 
     //
@@ -651,7 +667,8 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
         int dwFlags = pfd.getDwFlags();
 
         if( 0 != (GDI.PFD_DRAW_TO_WINDOW & dwFlags ) ) {
-            val |= GLGraphicsConfigurationUtil.WINDOW_BIT;
+            val |= GLGraphicsConfigurationUtil.WINDOW_BIT |
+                   GLGraphicsConfigurationUtil.FBO_BIT;
         }
         if( 0 != (GDI.PFD_DRAW_TO_BITMAP & dwFlags ) ) {
             val |= GLGraphicsConfigurationUtil.BITMAP_BIT;
@@ -659,107 +676,124 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
         return val;
     }
 
-    static WGLGLCapabilities PFD2GLCapabilities(GLProfile glp, long hdc, int pfdID, boolean onscreen) {
-        final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, false, false);
-        List<GLCapabilitiesImmutable> capsBucket = new ArrayList<GLCapabilitiesImmutable>(1);
-        if( PFD2GLCapabilities(capsBucket, glp, hdc, pfdID, winattrmask) ) {
-            return (WGLGLCapabilities) capsBucket.get(0);
-        }
-        return null;
-    }
-
-    static boolean  PFD2GLCapabilities(List<GLCapabilitiesImmutable> capsBucket, final GLProfile glp, final long hdc, final int pfdID, final int winattrmask) {
+    static WGLGLCapabilities PFD2GLCapabilities(AbstractGraphicsDevice device, final GLProfile glp, final long hdc, final int pfdID, final int winattrmask) {
         PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor(hdc, pfdID);
         if(null == pfd) {
-            return false;
+            return null;
         }
         if ((pfd.getDwFlags() & GDI.PFD_SUPPORT_OPENGL) == 0) {
-          return false;
+            return null;
         }
         final int allDrawableTypeBits = PFD2DrawableTypeBits(pfd);
         final int drawableTypeBits = winattrmask & allDrawableTypeBits;
 
         if( 0 == drawableTypeBits ) {
-            return false;
+            return null;
         }
 
-        WGLGLCapabilities res = new WGLGLCapabilities(pfd, pfdID, glp);
+        final WGLGLCapabilities res = new WGLGLCapabilities(pfd, pfdID, glp);
         res.setValuesByGDI();
+        return (WGLGLCapabilities) GLGraphicsConfigurationUtil.fixWinAttribBitsAndHwAccel(device, drawableTypeBits, res); 
+   }
 
-        return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, res, drawableTypeBits );
-  }
-
-  static PIXELFORMATDESCRIPTOR GLCapabilities2PFD(GLCapabilitiesImmutable caps, PIXELFORMATDESCRIPTOR pfd) {
-    int colorDepth = (caps.getRedBits() +
-                      caps.getGreenBits() +
-                      caps.getBlueBits());
-    if (colorDepth < 15) {
-      throw new GLException("Bit depths < 15 (i.e., non-true-color) not supported");
-    }
-    int pfdFlags = (GDI.PFD_SUPPORT_OPENGL |
-                    GDI.PFD_GENERIC_ACCELERATED);
-    if (caps.getDoubleBuffered()) {
-      pfdFlags |= GDI.PFD_DOUBLEBUFFER;
-    }
-    if (caps.isOnscreen()) {
-      pfdFlags |= GDI.PFD_DRAW_TO_WINDOW;
-    } else {
-      pfdFlags |= GDI.PFD_DRAW_TO_BITMAP;
-    }
-    if (caps.getStereo()) {
-      pfdFlags |= GDI.PFD_STEREO;
-    }
-    pfd.setDwFlags(pfdFlags);
-    pfd.setIPixelType((byte) GDI.PFD_TYPE_RGBA);
-    pfd.setCColorBits((byte) colorDepth);
-    pfd.setCRedBits  ((byte) caps.getRedBits());
-    pfd.setCGreenBits((byte) caps.getGreenBits());
-    pfd.setCBlueBits ((byte) caps.getBlueBits());
-    pfd.setCAlphaBits((byte) caps.getAlphaBits());
-    int accumDepth = (caps.getAccumRedBits() +
-                      caps.getAccumGreenBits() +
-                      caps.getAccumBlueBits());
-    pfd.setCAccumBits     ((byte) accumDepth);
-    pfd.setCAccumRedBits  ((byte) caps.getAccumRedBits());
-    pfd.setCAccumGreenBits((byte) caps.getAccumGreenBits());
-    pfd.setCAccumBlueBits ((byte) caps.getAccumBlueBits());
-    pfd.setCAccumAlphaBits((byte) caps.getAccumAlphaBits());
-    pfd.setCDepthBits((byte) caps.getDepthBits());
-    pfd.setCStencilBits((byte) caps.getStencilBits());
-    pfd.setILayerType((byte) GDI.PFD_MAIN_PLANE);
-
-    // n/a with non ARB/GDI method:
-    //       multisample
-    //       opaque
-    //       pbuffer
-    return pfd;
-  }
-
-  static PIXELFORMATDESCRIPTOR createPixelFormatDescriptor(long hdc, int pfdID) {
-    PIXELFORMATDESCRIPTOR pfd = PIXELFORMATDESCRIPTOR.create();
-    pfd.setNSize((short) PIXELFORMATDESCRIPTOR.size());
-    pfd.setNVersion((short) 1);
-    if(0 != hdc && 1 <= pfdID) {
-        if (WGLUtil.DescribePixelFormat(hdc, pfdID, PIXELFORMATDESCRIPTOR.size(), pfd) == 0) {
-            // Accelerated pixel formats that are non displayable
-            if(DEBUG) {
-                System.err.println("Info: Non displayable pixel format " + pfdID + " of device context: error code " + GDI.GetLastError());
-            }
+    static WGLGLCapabilities PFD2GLCapabilitiesNoCheck(AbstractGraphicsDevice device, final GLProfile glp, final long hdc, final int pfdID) {
+        PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor(hdc, pfdID);
+        return PFD2GLCapabilitiesNoCheck(device, glp, pfd, pfdID);
+   }
+    
+   static WGLGLCapabilities PFD2GLCapabilitiesNoCheck(AbstractGraphicsDevice device, GLProfile glp, PIXELFORMATDESCRIPTOR pfd, int pfdID) {
+        if(null == pfd) {
             return null;
         }
-    }
-    return pfd;
-  }
-
-  static PIXELFORMATDESCRIPTOR createPixelFormatDescriptor() {
-    return createPixelFormatDescriptor(0, 0);
-  }
-  
-  public String toString() {
-    return "WindowsWGLGraphicsConfiguration["+getScreen()+", pfdID " + getPixelFormatID() + ", ARB-Choosen " + isChoosenByARB() +
-                                            ",\n\trequested " + getRequestedCapabilities() +
-                                            ",\n\tchosen    " + getChosenCapabilities() +
-                                            "]";
-  }
+        final WGLGLCapabilities res = new WGLGLCapabilities(pfd, pfdID, glp);
+        res.setValuesByGDI();
+        
+        return (WGLGLCapabilities) GLGraphicsConfigurationUtil.fixWinAttribBitsAndHwAccel(device, PFD2DrawableTypeBits(pfd), res); 
+   }
+    
+   static PIXELFORMATDESCRIPTOR GLCapabilities2PFD(GLCapabilitiesImmutable caps, PIXELFORMATDESCRIPTOR pfd) {
+       int colorDepth = (caps.getRedBits() +
+               caps.getGreenBits() +
+               caps.getBlueBits());
+       if (colorDepth < 15) {
+           throw new GLException("Bit depths < 15 (i.e., non-true-color) not supported");
+       }
+       int pfdFlags = ( GDI.PFD_SUPPORT_OPENGL | GDI.PFD_GENERIC_ACCELERATED );
+
+       if( caps.isOnscreen() ) {
+           pfdFlags |= GDI.PFD_DRAW_TO_WINDOW;
+       } else if( caps.isFBO() ) {
+           pfdFlags |= GDI.PFD_DRAW_TO_WINDOW; // native replacement!
+       } else if( caps.isPBuffer() ) {
+           pfdFlags |= GDI.PFD_DRAW_TO_BITMAP; // pbuffer n/a, use bitmap
+       } else if( caps.isBitmap() ) {
+           pfdFlags |= GDI.PFD_DRAW_TO_BITMAP;
+       } else {
+           throw new GLException("no surface type set in caps: "+caps);
+       }
+
+       if ( caps.getDoubleBuffered() ) {
+           if( caps.isBitmap() || caps.isPBuffer() ) {
+               pfdFlags |= GDI.PFD_DOUBLEBUFFER_DONTCARE; // bitmaps probably don't have dbl buffering
+           } else {
+               pfdFlags |= GDI.PFD_DOUBLEBUFFER;
+           }
+       }
+       
+       if (caps.getStereo()) {
+           pfdFlags |= GDI.PFD_STEREO;
+       }
+       pfd.setDwFlags(pfdFlags);
+       pfd.setIPixelType((byte) GDI.PFD_TYPE_RGBA);
+       pfd.setCColorBits((byte) colorDepth);
+       pfd.setCRedBits  ((byte) caps.getRedBits());
+       pfd.setCGreenBits((byte) caps.getGreenBits());
+       pfd.setCBlueBits ((byte) caps.getBlueBits());
+       pfd.setCAlphaBits((byte) caps.getAlphaBits());
+       int accumDepth = (caps.getAccumRedBits() +
+               caps.getAccumGreenBits() +
+               caps.getAccumBlueBits());
+       pfd.setCAccumBits     ((byte) accumDepth);
+       pfd.setCAccumRedBits  ((byte) caps.getAccumRedBits());
+       pfd.setCAccumGreenBits((byte) caps.getAccumGreenBits());
+       pfd.setCAccumBlueBits ((byte) caps.getAccumBlueBits());
+       pfd.setCAccumAlphaBits((byte) caps.getAccumAlphaBits());
+       pfd.setCDepthBits((byte) caps.getDepthBits());
+       pfd.setCStencilBits((byte) caps.getStencilBits());
+       pfd.setILayerType((byte) GDI.PFD_MAIN_PLANE);
+
+       // n/a with non ARB/GDI method:
+       //       multisample
+       //       opaque
+       //       pbuffer
+       return pfd;
+   }
+
+   static PIXELFORMATDESCRIPTOR createPixelFormatDescriptor(long hdc, int pfdID) {
+       PIXELFORMATDESCRIPTOR pfd = PIXELFORMATDESCRIPTOR.create();
+       pfd.setNSize((short) PIXELFORMATDESCRIPTOR.size());
+       pfd.setNVersion((short) 1);
+       if(0 != hdc && 1 <= pfdID) {
+           if (WGLUtil.DescribePixelFormat(hdc, pfdID, PIXELFORMATDESCRIPTOR.size(), pfd) == 0) {
+               // Accelerated pixel formats that are non displayable
+               if(DEBUG) {
+                   System.err.println("Info: Non displayable pixel format " + pfdID + " of device context: error code " + GDI.GetLastError());
+               }
+               return null;
+           }
+       }
+       return pfd;
+   }
+
+   static PIXELFORMATDESCRIPTOR createPixelFormatDescriptor() {
+       return createPixelFormatDescriptor(0, 0);
+   }
+
+   public String toString() {
+       return "WindowsWGLGraphicsConfiguration["+getScreen()+", pfdID " + getPixelFormatID() + ", ARB-Choosen " + isChoosenByARB() +
+               ",\n\trequested " + getRequestedCapabilities() +
+               ",\n\tchosen    " + getChosenCapabilities() +
+               "]";
+   }
 }
 
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
index 00ed91b..7b3bc3a 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
@@ -50,12 +50,16 @@ import javax.media.opengl.GLDrawableFactory;
 import javax.media.opengl.GLException;
 import javax.media.opengl.GLProfile;
 
+import com.jogamp.common.nio.Buffers;
+
 import jogamp.nativewindow.windows.GDI;
 import jogamp.nativewindow.windows.PIXELFORMATDESCRIPTOR;
 import jogamp.opengl.GLDrawableImpl;
 import jogamp.opengl.GLGraphicsConfigurationFactory;
 import jogamp.opengl.GLGraphicsConfigurationUtil;
 
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -85,7 +89,11 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
             throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilities objects - requested");
         }
 
-        return chooseGraphicsConfigurationStatic((GLCapabilitiesImmutable)capsChosen, (GLCapabilitiesImmutable)capsRequested, chooser, absScreen);
+        if (chooser != null && !(chooser instanceof GLCapabilitiesChooser)) {
+            throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilitiesChooser objects");
+        }
+        
+        return chooseGraphicsConfigurationStatic((GLCapabilitiesImmutable)capsChosen, (GLCapabilitiesImmutable)capsRequested, (GLCapabilitiesChooser)chooser, absScreen);
     }
 
     static WindowsWGLGraphicsConfiguration createDefaultGraphicsConfiguration(GLCapabilitiesImmutable caps,
@@ -95,27 +103,25 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
 
     static WindowsWGLGraphicsConfiguration chooseGraphicsConfigurationStatic(GLCapabilitiesImmutable capsChosen,
                                                                              GLCapabilitiesImmutable capsReq,
-                                                                             CapabilitiesChooser chooser,
+                                                                             GLCapabilitiesChooser chooser,
                                                                              AbstractGraphicsScreen absScreen) {
         if(null==absScreen) {
             absScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS);
         }
         final AbstractGraphicsDevice absDevice = absScreen.getDevice();
-        final GLDrawableFactory factory = GLDrawableFactory.getDesktopFactory();
-        capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities(
-                capsChosen, GLContext.isFBOAvailable(absDevice, capsChosen.getGLProfile()), factory.canCreateGLPbuffer(absDevice) );
-
+        capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, GLDrawableFactory.getDesktopFactory(), absDevice);
         return new WindowsWGLGraphicsConfiguration( absScreen, capsChosen, capsReq, (GLCapabilitiesChooser)chooser );
     }
 
     protected static List<GLCapabilitiesImmutable> getAvailableCapabilities(WindowsWGLDrawableFactory factory, AbstractGraphicsDevice device) {
-        WindowsWGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateSharedResource(device);
+        final WindowsWGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateSharedResource(device);
         if(null == sharedResource) {
             throw new GLException("Shared resource for device n/a: "+device);
         }
-        GLDrawableImpl sharedDrawable = sharedResource.getDrawable();
-        GLCapabilitiesImmutable capsChosen = sharedDrawable.getChosenGLCapabilities();
-        GLContext sharedContext = sharedResource.getContext();
+        final GLDrawableImpl sharedDrawable = sharedResource.getDrawable();
+        final GLContext sharedContext = sharedResource.getContext();
+        final GLProfile glp = GLProfile.getDefault(device);
+
         List<GLCapabilitiesImmutable> availableCaps = null;
         
         if ( sharedResource.needsCurrentContext4ARBPFDQueries() ) {
@@ -131,10 +137,10 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
                 throw new GLException("Error: HDC is null");
             }
             if (sharedResource.hasARBPixelFormat()) {
-                availableCaps = getAvailableGLCapabilitiesARB(hdc, sharedResource, capsChosen.getGLProfile());
+                availableCaps = WindowsWGLGraphicsConfigurationFactory.getAvailableGLCapabilitiesARB(sharedResource, sharedResource.getDevice(), glp, hdc);
             }
             if( null == availableCaps || availableCaps.isEmpty() ) {
-                availableCaps = getAvailableGLCapabilitiesGDI(hdc, capsChosen.getGLProfile());
+                availableCaps = getAvailableGLCapabilitiesGDI(device, glp, hdc);
             }
         } finally {
             if ( sharedResource.needsCurrentContext4ARBPFDQueries() ) {
@@ -150,17 +156,21 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
         return availableCaps;
     }
 
-    static List<GLCapabilitiesImmutable> getAvailableGLCapabilitiesARB(long hdc, WindowsWGLDrawableFactory.SharedResource sharedResource, GLProfile glProfile) {
-        int[] pformats = WindowsWGLGraphicsConfiguration.wglAllARBPFIDs((WindowsWGLContext)sharedResource.getContext(), hdc);
-        return WindowsWGLGraphicsConfiguration.wglARBPFIDs2AllGLCapabilities(sharedResource, hdc, pformats, glProfile);
+    static List<GLCapabilitiesImmutable> getAvailableGLCapabilitiesARB(WindowsWGLDrawableFactory.SharedResource sharedResource, AbstractGraphicsDevice device, GLProfile glProfile, long hdc) {
+        final int pfdIDCount = WindowsWGLGraphicsConfiguration.wglARBPFDIDCount((WindowsWGLContext)sharedResource.getContext(), hdc);
+        final int[] pformats = WindowsWGLGraphicsConfiguration.wglAllARBPFDIDs(pfdIDCount);
+        return WindowsWGLGraphicsConfiguration.wglARBPFIDs2GLCapabilities(sharedResource, device, glProfile, hdc, pformats, GLGraphicsConfigurationUtil.ALL_BITS);
     }
 
-    static List<GLCapabilitiesImmutable> getAvailableGLCapabilitiesGDI(long hdc, GLProfile glProfile) {
+    static List<GLCapabilitiesImmutable> getAvailableGLCapabilitiesGDI(AbstractGraphicsDevice device, GLProfile glProfile, long hdc) {
         int[] pformats = WindowsWGLGraphicsConfiguration.wglAllGDIPFIDs(hdc);
         int numFormats = pformats.length;
         List<GLCapabilitiesImmutable> bucket = new ArrayList<GLCapabilitiesImmutable>(numFormats);
         for (int i = 0; i < numFormats; i++) {
-            WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(bucket, glProfile, hdc, pformats[i], GLGraphicsConfigurationUtil.ALL_BITS);
+            final GLCapabilitiesImmutable caps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(device, glProfile, hdc, pformats[i], GLGraphicsConfigurationUtil.ALL_BITS);
+            if(null != caps) {
+                bucket.add(caps);
+            }
         }
         return bucket;
     }
@@ -274,8 +284,8 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
             }
         }
         try {
-            if( !updateGraphicsConfigurationARB(hdc, extHDC, config, chooser, (WindowsWGLDrawableFactory)factory, pfdIDs) ) {
-                updateGraphicsConfigurationGDI(hdc, extHDC, config, chooser, pfdIDs);
+            if( !updateGraphicsConfigurationARB((WindowsWGLDrawableFactory)factory, config, chooser, hdc, extHDC, pfdIDs) ) {
+                updateGraphicsConfigurationGDI(config, chooser, hdc, extHDC, pfdIDs);
             }
         } finally {
             if (null != sharedContext) {
@@ -284,10 +294,10 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
         }
     }
 
-    private static boolean updateGraphicsConfigurationARB(long hdc, boolean extHDC, WindowsWGLGraphicsConfiguration config,
-                                                          CapabilitiesChooser chooser, WindowsWGLDrawableFactory factory, int[] pformats) {
-        AbstractGraphicsDevice device = config.getScreen().getDevice();
-        WindowsWGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateSharedResource(device);
+    private static boolean updateGraphicsConfigurationARB(WindowsWGLDrawableFactory factory, WindowsWGLGraphicsConfiguration config, CapabilitiesChooser chooser,
+                                                          long hdc, boolean extHDC, int[] pformats) {
+        final AbstractGraphicsDevice device = config.getScreen().getDevice();
+        final WindowsWGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateSharedResource(device);
 
         if (null == sharedResource) {
             if (DEBUG) {
@@ -302,16 +312,25 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
             return false;
         }
 
-        GLCapabilitiesImmutable capsChosen = (GLCapabilitiesImmutable) config.getChosenCapabilities();
-        boolean isOpaque = capsChosen.isBackgroundOpaque() && GDI.DwmIsCompositionEnabled();
-        boolean onscreen = capsChosen.isOnscreen();
-        boolean usePBuffer = capsChosen.isPBuffer();
-        GLProfile glProfile = capsChosen.getGLProfile();
+        final GLCapabilitiesImmutable capsChosen = (GLCapabilitiesImmutable) config.getChosenCapabilities();
+        final boolean isOpaque = capsChosen.isBackgroundOpaque() && GDI.DwmIsCompositionEnabled();
+        final int winattrbits = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(capsChosen);
+        final GLProfile glProfile = capsChosen.getGLProfile();
+        
+        final int pfdIDCount = WindowsWGLGraphicsConfiguration.wglARBPFDIDCount((WindowsWGLContext)sharedResource.getContext(), hdc);
         
         if(DEBUG) {
-            System.err.println("translucency requested: "+(!capsChosen.isBackgroundOpaque())+", compositioning enabled: "+GDI.DwmIsCompositionEnabled()+" -> translucency "+(!isOpaque));
+            System.err.println("updateGraphicsConfigurationARB: hdc "+toHexString(hdc)+", pfdIDCount(hdc) "+pfdIDCount+", capsChosen "+capsChosen+", "+GLGraphicsConfigurationUtil.winAttributeBits2String(null, winattrbits).toString());
+            System.err.println("isOpaque "+isOpaque+" (translucency requested: "+(!capsChosen.isBackgroundOpaque())+", compositioning enabled: "+GDI.DwmIsCompositionEnabled()+")");
         }
 
+        if(0 >= pfdIDCount) {
+            if (DEBUG) {
+                System.err.println("updateGraphicsConfigurationARB: failed due to 0 pfdIDs for hdc "+toHexString(hdc)+" - hdc incompatible w/ ARB ext.");
+            }
+            return false;
+        }
+        
         WGLGLCapabilities pixelFormatCaps = null; // chosen or preset PFD ID's caps
         boolean pixelFormatSet = false; // indicates a preset PFD ID [caps]
         final int presetPFDID = extHDC ? -1 : WGLUtil.GetPixelFormat(hdc) ;
@@ -325,7 +344,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
                         + ", pixelformat " + presetPFDID);
             }
             pixelFormatSet = true;
-            pixelFormatCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedResource, hdc, presetPFDID, glProfile, onscreen, usePBuffer);
+            pixelFormatCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedResource, device, glProfile, hdc, presetPFDID, winattrbits);
             pixelFormatCaps = (WGLGLCapabilities) GLGraphicsConfigurationUtil.fixOpaqueGLCapabilities(pixelFormatCaps, isOpaque);
         } else {
             int recommendedIndex = -1; // recommended index
@@ -334,20 +353,20 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
                 // No given PFD IDs
                 //
                 // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice
-                int[] iattributes = new int[2 * WindowsWGLGraphicsConfiguration.MAX_ATTRIBS];
-                float[] fattributes = new float[1];
+                final IntBuffer iattributes = Buffers.newDirectIntBuffer(2*WindowsWGLGraphicsConfiguration.MAX_ATTRIBS);
+                final FloatBuffer fattributes = Buffers.newDirectFloatBuffer(1);
                 int accelerationMode = WGLExt.WGL_FULL_ACCELERATION_ARB;
-                pformats = WindowsWGLGraphicsConfiguration.wglChoosePixelFormatARB(hdc, sharedResource, capsChosen,
-                                                                                   iattributes, accelerationMode, fattributes);
+                pformats = WindowsWGLGraphicsConfiguration.wglChoosePixelFormatARB(sharedResource, device, capsChosen,
+                                                                                   hdc, iattributes, accelerationMode, fattributes);
                 if (null == pformats) {
                     accelerationMode = WGLExt.WGL_GENERIC_ACCELERATION_ARB;
-                    pformats = WindowsWGLGraphicsConfiguration.wglChoosePixelFormatARB(hdc, sharedResource, capsChosen,
-                                                                                       iattributes, accelerationMode, fattributes);
+                    pformats = WindowsWGLGraphicsConfiguration.wglChoosePixelFormatARB(sharedResource, device, capsChosen,
+                                                                                       hdc, iattributes, accelerationMode, fattributes);
                 }
                 if (null == pformats) {
                     accelerationMode = -1; // use what we are offered ..
-                    pformats = WindowsWGLGraphicsConfiguration.wglChoosePixelFormatARB(hdc, sharedResource, capsChosen,
-                                                                                       iattributes, accelerationMode, fattributes);
+                    pformats = WindowsWGLGraphicsConfiguration.wglChoosePixelFormatARB(sharedResource, device, capsChosen,
+                                                                                       hdc, iattributes, accelerationMode, fattributes);
                 }
                 if (null != pformats) {
                     recommendedIndex = 0;
@@ -356,7 +375,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
                         System.err.println("updateGraphicsConfigurationARB: wglChoosePixelFormatARB failed with: "+capsChosen);
                     }
                     // 2nd choice: get all GLCapabilities available, no preferred recommendedIndex available
-                    pformats = WindowsWGLGraphicsConfiguration.wglAllARBPFIDs((WindowsWGLContext)sharedResource.getContext(), hdc);
+                    pformats = WindowsWGLGraphicsConfiguration.wglAllARBPFDIDs(pfdIDCount);
                     if (DEBUG) {
                         final int len = ( null != pformats ) ? pformats.length : 0;
                         System.err.println("updateGraphicsConfigurationARB: NumFormats (wglAllARBPFIDs) " + len);
@@ -371,13 +390,12 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
                 }
             }
 
-            List<GLCapabilitiesImmutable> availableCaps =
-                WindowsWGLGraphicsConfiguration.wglARBPFIDs2GLCapabilities(sharedResource, hdc, pformats,
-                                                                           glProfile, onscreen, usePBuffer);
+            List<GLCapabilitiesImmutable> availableCaps = 
+                    WindowsWGLGraphicsConfiguration.wglARBPFIDs2GLCapabilities(sharedResource, device, glProfile, hdc, pformats, winattrbits);
+            
             if( null == availableCaps || 0 == availableCaps.size() ) {
                 if (DEBUG) {
-                    System.err.println("updateGraphicsConfigurationARB: wglARBPFIDs2GLCapabilities failed with " + pformats.length +
-                                       " pfd ids, onscreen " + onscreen + ", pbuffer " + usePBuffer);
+                    System.err.println("updateGraphicsConfigurationARB: wglARBPFIDs2GLCapabilities failed with " + pformats.length + " pfd ids");
                     Thread.dumpStack();
                 }
                 return false;
@@ -385,7 +403,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
 
             if (DEBUG) {
                 System.err.println("updateGraphicsConfigurationARB: " + pformats.length +
-                                   " pfd ids, onscreen " + onscreen + ", pbuffer " + usePBuffer + ", " + availableCaps.size() + " glcaps");
+                                   " pfd ids, " + GLGraphicsConfigurationUtil.winAttributeBits2String(null, winattrbits).toString() + ", " + availableCaps.size() + " glcaps");
                 if(0 <= recommendedIndex) {
                     System.err.println("updateGraphicsConfigurationARB: Used wglChoosePixelFormatARB to recommend pixel format " +
                                        pformats[recommendedIndex] + ", idx " + recommendedIndex +", "+availableCaps.get(recommendedIndex));
@@ -420,19 +438,25 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
         return true;
     }
 
-    private static boolean updateGraphicsConfigurationGDI(long hdc, boolean extHDC, WindowsWGLGraphicsConfiguration config,
-                                                          CapabilitiesChooser chooser, int[] pformats) {
+    private static boolean updateGraphicsConfigurationGDI(WindowsWGLGraphicsConfiguration config, CapabilitiesChooser chooser, long hdc,
+                                                          boolean extHDC, int[] pformats) {
         GLCapabilitiesImmutable capsChosen = (GLCapabilitiesImmutable) config.getChosenCapabilities();
-        if(capsChosen.isPBuffer()) {
+        if( !capsChosen.isOnscreen() && capsChosen.isPBuffer() ) {
             if (DEBUG) {
                 System.err.println("updateGraphicsConfigurationGDI: no pbuffer supported on GDI: " + capsChosen);
             }
             return false;
         }
-        boolean onscreen = capsChosen.isOnscreen();
-        GLProfile glProfile = capsChosen.getGLProfile();
-
-        List<GLCapabilitiesImmutable> availableCaps = new ArrayList<GLCapabilitiesImmutable>();
+        // final boolean onscreen = capsChosen.isOnscreen();
+        // final boolean useFBO = capsChosen.isFBO();
+        final GLProfile glProfile = capsChosen.getGLProfile();
+        final int winattrmask = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(capsChosen);
+        
+        if(DEBUG) {
+            System.err.println("updateGraphicsConfigurationGDI: capsChosen "+capsChosen+", "+GLGraphicsConfigurationUtil.winAttributeBits2String(null, winattrmask).toString());
+        }
+        
+        AbstractGraphicsDevice device = config.getScreen().getDevice();
         int pfdID; // chosen or preset PFD ID
         WGLGLCapabilities pixelFormatCaps = null; // chosen or preset PFD ID's caps
         boolean pixelFormatSet = false; // indicates a preset PFD ID [caps]
@@ -447,15 +471,29 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
                         + ", pixelformat " + pfdID);
             }
             pixelFormatSet = true;
-            pixelFormatCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, hdc, pfdID, onscreen);
+            pixelFormatCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(device, glProfile, hdc, pfdID, winattrmask);
+            if(null == pixelFormatCaps) {
+                throw new GLException("Could not map PFD2GLCaps w/ already chosen pfdID "+pfdID);
+            }
         } else {
-            if(null == pformats) {
+            final boolean givenPFormats = null != pformats;
+            if( !givenPFormats ) {
                 pformats = WindowsWGLGraphicsConfiguration.wglAllGDIPFIDs(hdc);
             }
-            final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, false, false);
 
+            List<GLCapabilitiesImmutable> availableCaps = new ArrayList<GLCapabilitiesImmutable>();
             for (int i = 0; i < pformats.length; i++) {
-                WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(availableCaps, glProfile, hdc, pformats[i], winattrmask);
+                final GLCapabilitiesImmutable caps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(device, glProfile, hdc, pformats[i], winattrmask);
+                if(null != caps) {
+                    availableCaps.add(caps);
+                    if(DEBUG) {
+                        final int j = availableCaps.size() - 1; 
+                        System.err.println("updateGraphicsConfigurationGDI: availableCaps["+i+" -> "+j+"]: "+caps);
+                    }
+                } else if(DEBUG) {
+                    GLCapabilitiesImmutable skipped = WindowsWGLGraphicsConfiguration.PFD2GLCapabilitiesNoCheck(device, glProfile, hdc, pformats[i]);
+                    System.err.println("updateGraphicsConfigurationGDI: availableCaps["+i+" -> skip]: pfdID "+pformats[i]+", "+skipped);
+                }
             }
 
             // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice
@@ -464,16 +502,21 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
             pfdID = WGLUtil.ChoosePixelFormat(hdc, pfd);
             int recommendedIndex = -1 ;
             if( 1 <= pfdID ) {
-                // seek index ..
+                // seek index .. in all formats _or_ in given formats!
                 for (recommendedIndex = availableCaps.size() - 1 ;
                      0 <= recommendedIndex && pfdID != ((WGLGLCapabilities) availableCaps.get(recommendedIndex)).getPFDID();
                      recommendedIndex--)
                 { /* nop */ }
+                if(DEBUG && 0 > recommendedIndex) {
+                    final GLCapabilitiesImmutable reqPFDCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilitiesNoCheck(device, glProfile, pfd, pfdID);
+                    final GLCapabilitiesImmutable chosenCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(device, glProfile, hdc, pfdID, winattrmask);
+                    System.err.println("Chosen PFDID "+pfdID+", but not found in available caps (use given pfdIDs "+givenPFormats+", reqPFDCaps "+reqPFDCaps+", chosenCaps: "+chosenCaps);
+                }
             }
-            // 2nd choice: if no preferred recommendedIndex available
             if (DEBUG) {
-                System.err.println("updateGraphicsConfigurationGDI: ChoosePixelFormat(HDC " + toHexString(hdc) + ") = " + pfdID + ", idx " + recommendedIndex + " (LastError: " + GDI.GetLastError() + ")");
+                System.err.println("updateGraphicsConfigurationGDI: ChoosePixelFormat(HDC " + toHexString(hdc) + ") = pfdID " + pfdID + ", idx " + recommendedIndex + " (LastError: " + GDI.GetLastError() + ")");
             }
+            // 2nd choice: if no preferred recommendedIndex available
             int chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex);
             if ( 0 > chosenIndex ) {
                 if (DEBUG) {
@@ -484,8 +527,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
             }
             pixelFormatCaps = (WGLGLCapabilities) availableCaps.get(chosenIndex);
             if (DEBUG) {
-                System.err.println("chosen pfdID (GDI): native recommended "+ (recommendedIndex+1) +
-                                   ", caps " + pixelFormatCaps);
+                System.err.println("chosen pfdID (GDI): chosenIndex "+ chosenIndex + ", caps " + pixelFormatCaps);
             }
         }
 
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/GLXUtil.java b/src/jogl/classes/jogamp/opengl/x11/glx/GLXUtil.java
index 7cc2d0f..2c591cf 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/GLXUtil.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/GLXUtil.java
@@ -33,10 +33,13 @@
 
 package jogamp.opengl.x11.glx;
 
+import java.nio.IntBuffer;
+
 import javax.media.opengl.GLException;
 
 import jogamp.opengl.Debug;
 
+import com.jogamp.common.nio.Buffers;
 import com.jogamp.common.util.VersionNumber;
 import com.jogamp.nativewindow.x11.X11GraphicsDevice;
 
@@ -51,34 +54,68 @@ public class GLXUtil {
             throw new IllegalArgumentException("null X11GraphicsDevice display handle");
         }        
         boolean glXAvailable = false;
+        x11Device.lock();
         try {
-            glXAvailable = GLX.glXQueryExtension(x11Device.getHandle(), null, 0, null, 0);
-        } catch (Throwable t) { /* n/a */ }
+            glXAvailable = GLX.glXQueryExtension(x11Device.getHandle(), null, null);
+        } catch (Throwable t) { /* n/a */
+        } finally {
+            x11Device.unlock();
+        }        
         return glXAvailable;        
     }
     
-    public static VersionNumber getGLXServerVersionNumber(long display) {
-        int[] major = new int[1];
-        int[] minor = new int[1];
+    public static String getGLXClientString(X11GraphicsDevice x11Device, int name) {
+        x11Device.lock();
+        try {
+            return GLX.glXGetClientString(x11Device.getHandle(), name);
+        } finally {
+            x11Device.unlock();
+        }        
+    }
+    public static String queryGLXServerString(X11GraphicsDevice x11Device, int screen_idx, int name) {
+        x11Device.lock();
+        try {
+            return GLX.glXQueryServerString(x11Device.getHandle(), screen_idx, name);
+        } finally {
+            x11Device.unlock();
+        }        
+    }    
+    public static String queryGLXExtensionsString(X11GraphicsDevice x11Device, int screen_idx) {
+        x11Device.lock();
+        try {
+            return GLX.glXQueryExtensionsString(x11Device.getHandle(), screen_idx);
+        } finally {
+            x11Device.unlock();
+        }        
+    }
+    
+    public static VersionNumber getGLXServerVersionNumber(X11GraphicsDevice x11Device) {
+        final IntBuffer major = Buffers.newDirectIntBuffer(1);
+        final IntBuffer minor = Buffers.newDirectIntBuffer(1);
         
-        if (!GLX.glXQueryVersion(display, major, 0, minor, 0)) {
-          throw new GLException("glXQueryVersion failed");
+        x11Device.lock();
+        try {
+            if (!GLX.glXQueryVersion(x11Device.getHandle(), major, minor)) {
+              throw new GLException("glXQueryVersion failed");
+            }
+    
+            // Work around bugs in ATI's Linux drivers where they report they
+            // only implement GLX version 1.2 on the server side
+            if (major.get(0) == 1 && minor.get(0) == 2) {
+              String str = GLX.glXGetClientString(x11Device.getHandle(), GLX.GLX_VERSION);
+              try {
+                  // e.g. "1.3"
+                  major.put(0, Integer.valueOf(str.substring(0, 1)).intValue());
+                  minor.put(0, Integer.valueOf(str.substring(2, 3)).intValue());
+              } catch (Exception e) {
+                  major.put(0, 1);
+                  minor.put(0, 2);
+              }
+            }
+        } finally {
+            x11Device.unlock();
         }
-
-        // Work around bugs in ATI's Linux drivers where they report they
-        // only implement GLX version 1.2 on the server side
-        if (major[0] == 1 && minor[0] == 2) {
-          String str = GLX.glXGetClientString(display, GLX.GLX_VERSION);
-          try {
-              // e.g. "1.3"
-              major[0] = Integer.valueOf(str.substring(0, 1)).intValue();
-              minor[0] = Integer.valueOf(str.substring(2, 3)).intValue();
-          } catch (Exception e) {
-              major[0] = 1;
-              minor[0] = 2;
-          }
-        }                
-        return new VersionNumber(major[0], minor[0], 0);
+        return new VersionNumber(major.get(0), minor.get(0), 0);
     }
     
     public static boolean isMultisampleAvailable(String extensions) {
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java
index 1f3edbd..bebb4e6 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java
@@ -40,6 +40,8 @@
 
 package jogamp.opengl.x11.glx;
 
+import java.nio.IntBuffer;
+
 import javax.media.nativewindow.NativeSurface;
 import javax.media.nativewindow.VisualIDHolder;
 import javax.media.opengl.GLCapabilities;
@@ -48,10 +50,11 @@ import javax.media.opengl.GLDrawableFactory;
 import javax.media.opengl.GLException;
 import javax.media.opengl.GLProfile;
 
+import jogamp.nativewindow.WrappedSurface;
 import jogamp.opengl.GLContextImpl;
 import jogamp.opengl.GLContextShareSet;
 
-import com.jogamp.nativewindow.WrappedSurface;
+import com.jogamp.common.nio.Buffers;
 import com.jogamp.nativewindow.x11.X11GraphicsScreen;
 
 public class X11ExternalGLXContext extends X11GLXContext {
@@ -78,34 +81,34 @@ public class X11ExternalGLXContext extends X11GLXContext {
     if (drawable == 0) {
       throw new GLException("Error: attempted to make an external GLDrawable without a drawable/context current");
     }    
-    int[] val = new int[1];
+    IntBuffer val = Buffers.newDirectIntBuffer(1);
     
     int w, h;
-    GLX.glXQueryDrawable(display, drawable, GLX.GLX_WIDTH, val, 0);
-    w=val[0];
-    GLX.glXQueryDrawable(display, drawable, GLX.GLX_HEIGHT, val, 0);
-    h=val[0];
+    GLX.glXQueryDrawable(display, drawable, GLX.GLX_WIDTH, val);
+    w=val.get(0);
+    GLX.glXQueryDrawable(display, drawable, GLX.GLX_HEIGHT, val);
+    h=val.get(0);
     
-    GLX.glXQueryContext(display, ctx, GLX.GLX_SCREEN, val, 0);
-    X11GraphicsScreen x11Screen = (X11GraphicsScreen) X11GraphicsScreen.createScreenDevice(display, val[0], false);
+    GLX.glXQueryContext(display, ctx, GLX.GLX_SCREEN, val);
+    X11GraphicsScreen x11Screen = (X11GraphicsScreen) X11GraphicsScreen.createScreenDevice(display, val.get(0), false);
 
-    GLX.glXQueryContext(display, ctx, GLX.GLX_FBCONFIG_ID, val, 0);
+    GLX.glXQueryContext(display, ctx, GLX.GLX_FBCONFIG_ID, val);
     X11GLXGraphicsConfiguration cfg = null;
     // sometimes glXQueryContext on an external context gives us a framebuffer config ID
     // of 0, which doesn't work in a subsequent call to glXChooseFBConfig; if this happens,
     // create and use a default config (this has been observed when running on CentOS 5.5 inside
     // of VMWare Server 2.0 with the Mesa 6.5.1 drivers)
-    if( VisualIDHolder.VID_UNDEFINED == val[0] || !X11GLXGraphicsConfiguration.GLXFBConfigIDValid(display, x11Screen.getIndex(), val[0]) ) {
+    if( VisualIDHolder.VID_UNDEFINED == val.get(0) || !X11GLXGraphicsConfiguration.GLXFBConfigIDValid(display, x11Screen.getIndex(), val.get(0)) ) {
         GLCapabilities glcapsDefault = new GLCapabilities(GLProfile.getDefault());
         cfg = X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(glcapsDefault, glcapsDefault, null, x11Screen, VisualIDHolder.VID_UNDEFINED);
         if(DEBUG) {
-            System.err.println("X11ExternalGLXContext invalid FBCONFIG_ID "+val[0]+", using default cfg: " + cfg);
+            System.err.println("X11ExternalGLXContext invalid FBCONFIG_ID "+val.get(0)+", using default cfg: " + cfg);
         }
     } else {
-        cfg = X11GLXGraphicsConfiguration.create(glp, x11Screen, val[0]);
+        cfg = X11GLXGraphicsConfiguration.create(glp, x11Screen, val.get(0));
     }
 
-    final WrappedSurface ns = new WrappedSurface(cfg, drawable, w, h, null);
+    final WrappedSurface ns = new WrappedSurface(cfg, drawable, w, h, true);
     return new X11ExternalGLXContext(new Drawable(factory, ns), ctx);
   }
 
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXDrawable.java
index 8652e2d..fca36c0 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXDrawable.java
@@ -39,13 +39,17 @@
 
 package jogamp.opengl.x11.glx;
 
+import java.nio.IntBuffer;
+
 import javax.media.nativewindow.NativeSurface;
 import javax.media.opengl.GLContext;
 import javax.media.opengl.GLDrawableFactory;
 import javax.media.opengl.GLException;
 import javax.media.opengl.GLProfile;
 
-import com.jogamp.nativewindow.WrappedSurface;
+import jogamp.nativewindow.WrappedSurface;
+
+import com.jogamp.common.nio.Buffers;
 import com.jogamp.nativewindow.x11.X11GraphicsScreen;
 
 
@@ -68,26 +72,27 @@ public class X11ExternalGLXDrawable extends X11GLXDrawable {
     if (drawable == 0) {
       throw new GLException("Error: attempted to make an external GLDrawable without a drawable current");
     }
-    int[] val = new int[1];
-    GLX.glXQueryContext(display, context, GLX.GLX_SCREEN, val, 0);
-    X11GraphicsScreen x11Screen = (X11GraphicsScreen) X11GraphicsScreen.createScreenDevice(display, val[0], false);
+    IntBuffer val = Buffers.newDirectIntBuffer(1);
+    
+    GLX.glXQueryContext(display, context, GLX.GLX_SCREEN, val);
+    X11GraphicsScreen x11Screen = (X11GraphicsScreen) X11GraphicsScreen.createScreenDevice(display, val.get(0), false);
 
-    GLX.glXQueryContext(display, context, GLX.GLX_FBCONFIG_ID, val, 0);
-    X11GLXGraphicsConfiguration cfg = X11GLXGraphicsConfiguration.create(glp, x11Screen, val[0]);
+    GLX.glXQueryContext(display, context, GLX.GLX_FBCONFIG_ID, val);
+    X11GLXGraphicsConfiguration cfg = X11GLXGraphicsConfiguration.create(glp, x11Screen, val.get(0));
 
     int w, h;
-    GLX.glXQueryDrawable(display, drawable, GLX.GLX_WIDTH, val, 0);
-    w=val[0];
-    GLX.glXQueryDrawable(display, drawable, GLX.GLX_HEIGHT, val, 0);
-    h=val[0];
+    GLX.glXQueryDrawable(display, drawable, GLX.GLX_WIDTH, val);
+    w=val.get(0);
+    GLX.glXQueryDrawable(display, drawable, GLX.GLX_HEIGHT, val);
+    h=val.get(0);
 
-    GLX.glXQueryContext(display, context, GLX.GLX_RENDER_TYPE, val, 0);
-    if ((val[0] & GLX.GLX_RGBA_TYPE) == 0) {
+    GLX.glXQueryContext(display, context, GLX.GLX_RENDER_TYPE, val);
+    if ((val.get(0) & GLX.GLX_RGBA_TYPE) == 0) {
       if (DEBUG) {
-        System.err.println("X11ExternalGLXDrawable: WARNING: forcing GLX_RGBA_TYPE for newly created contexts (current 0x"+Integer.toHexString(val[0])+")");
+        System.err.println("X11ExternalGLXDrawable: WARNING: forcing GLX_RGBA_TYPE for newly created contexts (current 0x"+Integer.toHexString(val.get(0))+")");
       }
     }
-    return new X11ExternalGLXDrawable(factory, new WrappedSurface(cfg, drawable, w, h, null));
+    return new X11ExternalGLXDrawable(factory, new WrappedSurface(cfg, drawable, w, h, true));
   }
 
   @Override
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
index e1e25be..76e0bc1 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
@@ -53,14 +53,16 @@ import javax.media.opengl.GLContext;
 import javax.media.opengl.GLException;
 import javax.media.opengl.GLProfile;
 
-import jogamp.nativewindow.x11.X11Lib;
 import jogamp.nativewindow.x11.X11Util;
 import jogamp.opengl.GLContextImpl;
 import jogamp.opengl.GLDrawableImpl;
+import jogamp.opengl.GLXExtensions;
 
 import com.jogamp.common.nio.Buffers;
+import com.jogamp.common.util.VersionNumber;
 import com.jogamp.gluegen.runtime.ProcAddressTable;
 import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
+import com.jogamp.nativewindow.x11.X11GraphicsDevice;
 import com.jogamp.opengl.GLExtensions;
 
 public abstract class X11GLXContext extends GLContextImpl {
@@ -70,13 +72,16 @@ public abstract class X11GLXContext extends GLContextImpl {
   // Table that holds the addresses of the native C-language entry points for
   // GLX extension functions.
   private GLXExtProcAddressTable glXExtProcAddressTable;
-  private int hasSwapIntervalSGI = 0;
+  /** 1 MESA, 2 SGI, 0 undefined, -1 none */
+  private int hasSwapInterval = 0;
   private int hasSwapGroupNV = 0;
 
   // This indicates whether the context we have created is indirect
   // and therefore requires the toolkit to be locked around all GL
   // calls rather than just all GLX calls
   protected boolean isDirect;
+  protected volatile VersionNumber glXServerVersion;
+  protected volatile boolean isGLXVersionGreaterEqualOneThree;
 
   static {
     functionNameMap = new HashMap<String, String>();
@@ -97,9 +102,11 @@ public abstract class X11GLXContext extends GLContextImpl {
   protected void resetStates() {
     // no inner state _glXExt=null;
     glXExtProcAddressTable = null;
-    hasSwapIntervalSGI = 0;
+    hasSwapInterval = 0;
     hasSwapGroupNV = 0;
     isDirect = false;
+    glXServerVersion = null;
+    isGLXVersionGreaterEqualOneThree = false;
     super.resetStates();
   }
 
@@ -130,8 +137,13 @@ public abstract class X11GLXContext extends GLContextImpl {
   @Override
   protected Map<String, String> getExtensionNameMap() { return extensionNameMap; }
 
-  protected final boolean isGLXVersionGreaterEqualOneThree() {
-    return ((X11GLXDrawableFactory)drawable.getFactoryImpl()).isGLXVersionGreaterEqualOneThree(drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice());
+  protected final boolean isGLXVersionGreaterEqualOneThree() { // fast-path: use cached boolean
+    if(null != glXServerVersion) {
+        return isGLXVersionGreaterEqualOneThree;
+    }
+    glXServerVersion = ((X11GLXDrawableFactory)drawable.getFactoryImpl()).getGLXVersionNumber(drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice()); 
+    isGLXVersionGreaterEqualOneThree = null != glXServerVersion ? glXServerVersion.compareTo(X11GLXDrawableFactory.versionOneThree) >= 0 : false;
+    return isGLXVersionGreaterEqualOneThree;
   }
 
   @Override
@@ -144,8 +156,10 @@ public abstract class X11GLXContext extends GLContextImpl {
 
     try {
         if ( isGLXVersionGreaterEqualOneThree() ) {
+            // System.err.println(getThreadName() +": X11GLXContext.makeCurrent: obj " + toHexString(hashCode()) + " / ctx "+toHexString(contextHandle)+": ctx "+toHexString(ctx)+", [write "+toHexString(writeDrawable)+", read "+toHexString(readDrawable)+"] - switch");
             res = GLX.glXMakeContextCurrent(dpy, writeDrawable, readDrawable, ctx);
         } else if ( writeDrawable == readDrawable ) {
+            // System.err.println(getThreadName() +": X11GLXContext.makeCurrent: obj " + toHexString(hashCode()) + " / ctx "+toHexString(contextHandle)+": ctx "+toHexString(ctx)+", [write "+toHexString(writeDrawable)+"] - switch");
             res = GLX.glXMakeCurrent(dpy, writeDrawable, ctx);
         } else {
             // should not happen due to 'isGLReadDrawableAvailable()' query in GLContextImpl
@@ -166,13 +180,11 @@ public abstract class X11GLXContext extends GLContextImpl {
 
   @Override
   protected void destroyContextARBImpl(long ctx) {
-    X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeSurface().getGraphicsConfiguration();
-    long display = config.getScreen().getDevice().getHandle();
+    final long display = drawable.getNativeSurface().getDisplayHandle();
 
     glXMakeContextCurrent(display, 0, 0, 0);
     GLX.glXDestroyContext(display, ctx);
   }
-
   private static final int ctx_arb_attribs_idx_major = 0;
   private static final int ctx_arb_attribs_idx_minor = 2;
   private static final int ctx_arb_attribs_idx_flags = 6;
@@ -228,20 +240,20 @@ public abstract class X11GLXContext extends GLContextImpl {
 
     X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeSurface().getGraphicsConfiguration();
     AbstractGraphicsDevice device = config.getScreen().getDevice();
-    long display = device.getHandle();
+    final long display = device.getHandle();
 
     try {
         // critical path, a remote display might not support this command,
         // hence we need to catch the X11 Error within this block.
-        X11Lib.XSync(display, false);
+        X11Util.setX11ErrorHandler(true, DEBUG ? false : true); // make sure X11 error handler is set
         ctx = _glXExt.glXCreateContextAttribsARB(display, config.getFBConfig(), share, direct, attribs);
-        X11Lib.XSync(display, false);
     } catch (RuntimeException re) {
         if(DEBUG) {
           Throwable t = new Throwable(getThreadName()+": Info: X11GLXContext.createContextARBImpl glXCreateContextAttribsARB failed with "+getGLVersion(major, minor, ctp, "@creation"), re);
           t.printStackTrace();
         }
     }
+    
     if(0!=ctx) {
         if (!glXMakeContextCurrent(display, drawable.getHandle(), drawableRead.getHandle(), ctx)) {
             if(DEBUG) {
@@ -263,16 +275,6 @@ public abstract class X11GLXContext extends GLContextImpl {
 
   @Override
   protected boolean createImpl(GLContextImpl shareWith) {
-      // covers the whole context creation loop incl createContextARBImpl and destroyContextARBImpl
-      X11Util.setX11ErrorHandler(true, DEBUG ? false : true);
-      try {
-          return createImplRaw(shareWith);
-      } finally {
-          X11Util.setX11ErrorHandler(false, false);
-      }
-  }
-
-  private boolean createImplRaw(GLContextImpl shareWith) {
     boolean direct = true; // try direct always
     isDirect = false; // fall back
 
@@ -401,14 +403,9 @@ public abstract class X11GLXContext extends GLContextImpl {
   protected void makeCurrentImpl() throws GLException {
     long dpy = drawable.getNativeSurface().getDisplayHandle();
 
-    if (GLX.glXGetCurrentContext() != contextHandle) {
-        X11Util.setX11ErrorHandler(true, DEBUG ? false : true);
-        try {
-            if (!glXMakeContextCurrent(dpy, drawable.getHandle(), drawableRead.getHandle(), contextHandle)) {
-                throw new GLException(getThreadName()+": Error making context current: "+this);
-            }
-        } finally {
-            X11Util.setX11ErrorHandler(false, false);
+    if (GLX.glXGetCurrentContext() != contextHandle) {        
+        if (!glXMakeContextCurrent(dpy, drawable.getHandle(), drawableRead.getHandle(), contextHandle)) {
+            throw new GLException(getThreadName()+": Error making context current: "+this);
         }
     }
   }
@@ -416,19 +413,14 @@ public abstract class X11GLXContext extends GLContextImpl {
   @Override
   protected void releaseImpl() throws GLException {
     long display = drawable.getNativeSurface().getDisplayHandle();
-    X11Util.setX11ErrorHandler(true, DEBUG ? false : true);
-    try {
-        if (!glXMakeContextCurrent(display, 0, 0, 0)) {
-            throw new GLException(getThreadName()+": Error freeing OpenGL context");
-        }
-    } finally {
-        X11Util.setX11ErrorHandler(false, false);
+    if (!glXMakeContextCurrent(display, 0, 0, 0)) {
+        throw new GLException(getThreadName()+": Error freeing OpenGL context");
     }
   }
 
   @Override
   protected void destroyImpl() throws GLException {
-    GLX.glXDestroyContext(drawable.getNativeSurface().getDisplayHandle(), contextHandle);
+    destroyContextARBImpl(contextHandle);
   }
 
   @Override
@@ -474,35 +466,40 @@ public abstract class X11GLXContext extends GLContextImpl {
 
   @Override
   protected final StringBuilder getPlatformExtensionsStringImpl() {
-    StringBuilder sb = new StringBuilder();
-    if (DEBUG) {
-      System.err.println("GLX Version client version "+ GLXUtil.getClientVersionNumber()+
-                         ", server: "+
-        ((X11GLXDrawableFactory)drawable.getFactoryImpl()).getGLXVersionNumber(drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice()));
-    }
     final NativeSurface ns = drawable.getNativeSurface();
-    if(((X11GLXDrawableFactory)drawable.getFactoryImpl()).isGLXVersionGreaterEqualOneOne(ns.getGraphicsConfiguration().getScreen().getDevice())) {
-        {
-            final String ret = GLX.glXGetClientString(ns.getDisplayHandle(), GLX.GLX_EXTENSIONS);
-            if (DEBUG) {
-              System.err.println("GLX extensions (glXGetClientString): " + ret);
-            }
-            sb.append(ret).append(" ");
+    final X11GraphicsDevice x11Device = (X11GraphicsDevice) ns.getGraphicsConfiguration().getScreen().getDevice();
+    StringBuilder sb = new StringBuilder();
+    x11Device.lock();
+    try{
+        if (DEBUG) {
+          System.err.println("GLX Version client version "+ GLXUtil.getClientVersionNumber()+
+                             ", server: "+ GLXUtil.getGLXServerVersionNumber(x11Device));
         }
-        {
-            final String ret = GLX.glXQueryExtensionsString(ns.getDisplayHandle(), ns.getScreenIndex());
-            if (DEBUG) {
-              System.err.println("GLX extensions (glXQueryExtensionsString): " + ret);
+        if(((X11GLXDrawableFactory)drawable.getFactoryImpl()).isGLXVersionGreaterEqualOneOne(x11Device)) {
+            {
+                final String ret = GLX.glXGetClientString(x11Device.getHandle(), GLX.GLX_EXTENSIONS);
+                if (DEBUG) {
+                  System.err.println("GLX extensions (glXGetClientString): " + ret);
+                }
+                sb.append(ret).append(" ");
             }
-            sb.append(ret).append(" ");
-        }
-        {
-            final String ret = GLX.glXQueryServerString(ns.getDisplayHandle(), ns.getScreenIndex(), GLX.GLX_EXTENSIONS);
-            if (DEBUG) {
-              System.err.println("GLX extensions (glXQueryServerString): " + ret);
+            {
+                final String ret = GLX.glXQueryExtensionsString(x11Device.getHandle(), ns.getScreenIndex());
+                if (DEBUG) {
+                  System.err.println("GLX extensions (glXQueryExtensionsString): " + ret);
+                }
+                sb.append(ret).append(" ");
+            }
+            {
+                final String ret = GLX.glXQueryServerString(x11Device.getHandle(), ns.getScreenIndex(), GLX.GLX_EXTENSIONS);
+                if (DEBUG) {
+                  System.err.println("GLX extensions (glXQueryServerString): " + ret);
+                }
+                sb.append(ret).append(" ");
             }
-            sb.append(ret).append(" ");
         }
+    } finally {
+        x11Device.unlock();
     }
     return sb;
   }
@@ -519,20 +516,36 @@ public abstract class X11GLXContext extends GLContextImpl {
 
   @Override
   protected boolean setSwapIntervalImpl(int interval) {
-    X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeSurface().getGraphicsConfiguration();
-    GLCapabilitiesImmutable glCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
-    if(!glCaps.isOnscreen()) { return false; }
+    if( !drawable.getChosenGLCapabilities().isOnscreen() ) { return false; } 
 
-    GLXExt glXExt = getGLXExt();
-    if(0==hasSwapIntervalSGI) {
+    final GLXExt glXExt = getGLXExt();
+    if(0==hasSwapInterval) {
         try {
-            hasSwapIntervalSGI = glXExt.isExtensionAvailable("GLX_SGI_swap_control")?1:-1;
-        } catch (Throwable t) { hasSwapIntervalSGI=1; }
-    }
-    if (hasSwapIntervalSGI>0) {
+            /** Same impl. ..
+            if( glXExt.isExtensionAvailable(GLXExtensions.GLX_MESA_swap_control) ) {
+                if(DEBUG) { System.err.println("X11GLXContext.setSwapInterval using: "+GLXExtensions.GLX_MESA_swap_control); }
+                hasSwapInterval =  1;
+            } else */ 
+            if ( glXExt.isExtensionAvailable(GLXExtensions.GLX_SGI_swap_control) ) {
+                if(DEBUG) { System.err.println("X11GLXContext.setSwapInterval using: "+GLXExtensions.GLX_SGI_swap_control); }
+                hasSwapInterval =  2;
+            } else {
+                hasSwapInterval = -1;
+            }
+        } catch (Throwable t) { hasSwapInterval=-1; }
+    } 
+    /* try {
+        switch( hasSwapInterval ) {
+            case 1:
+                return 0 == glXExt.glXSwapIntervalMESA(interval);
+            case 2:
+                return 0 == glXExt.glXSwapIntervalSGI(interval);
+        }
+    } catch (Throwable t) { hasSwapInterval = -1; } */
+    if (2 == hasSwapInterval) {
         try {
             return 0 == glXExt.glXSwapIntervalSGI(interval);
-        } catch (Throwable t) { hasSwapIntervalSGI=-1; }
+        } catch (Throwable t) { hasSwapInterval=-1; }
     }
     return false;
   }
@@ -540,10 +553,10 @@ public abstract class X11GLXContext extends GLContextImpl {
   private final int initSwapGroupImpl(GLXExt glXExt) {
       if(0==hasSwapGroupNV) {
         try {
-            hasSwapGroupNV = glXExt.isExtensionAvailable("GLX_NV_swap_group")?1:-1;
+            hasSwapGroupNV = glXExt.isExtensionAvailable(GLXExtensions.GLX_NV_swap_group)?1:-1;
         } catch (Throwable t) { hasSwapGroupNV=1; }
         if(DEBUG) {
-            System.err.println("initSwapGroupImpl: hasSwapGroupNV: "+hasSwapGroupNV);
+            System.err.println("initSwapGroupImpl: "+GLXExtensions.GLX_NV_swap_group+": "+hasSwapGroupNV);
         }
       }
       return hasSwapGroupNV;
@@ -557,9 +570,13 @@ public abstract class X11GLXContext extends GLContextImpl {
       if (initSwapGroupImpl(glXExt)>0) {
         final NativeSurface ns = drawable.getNativeSurface();
         try {
+            final IntBuffer maxGroupsNIO = Buffers.newDirectIntBuffer(maxGroups.length - maxGroups_offset);
+            final IntBuffer maxBarriersNIO = Buffers.newDirectIntBuffer(maxBarriers.length - maxBarriers_offset);
+            
             if( glXExt.glXQueryMaxSwapGroupsNV(ns.getDisplayHandle(), ns.getScreenIndex(),
-                                               maxGroups, maxGroups_offset,
-                                               maxBarriers, maxBarriers_offset) ) {
+                                               maxGroupsNIO, maxBarriersNIO) ) {
+                maxGroupsNIO.get(maxGroups, maxGroups_offset, maxGroupsNIO.remaining());
+                maxBarriersNIO.get(maxGroups, maxGroups_offset, maxBarriersNIO.remaining());
                 res = true;
             }
         } catch (Throwable t) { hasSwapGroupNV=-1; }
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawable.java
index e9912ce..8c64277 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawable.java
@@ -69,9 +69,10 @@ public abstract class X11GLXDrawable extends GLDrawableImpl {
   }
 
   @Override
-  protected final void swapBuffersImpl() {
-    // single-buffer is already filtered out @ GLDrawableImpl#swapBuffers()
-    GLX.glXSwapBuffers(getNativeSurface().getDisplayHandle(), getHandle());
+  protected final void swapBuffersImpl(boolean doubleBuffered) {
+    if(doubleBuffered) {
+        GLX.glXSwapBuffers(getNativeSurface().getDisplayHandle(), getHandle());
+    }
   }
 
   //---------------------------------------------------------------------------
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
index b2e74f9..e38aabe 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
@@ -47,9 +47,8 @@ import javax.media.nativewindow.AbstractGraphicsConfiguration;
 import javax.media.nativewindow.AbstractGraphicsDevice;
 import javax.media.nativewindow.AbstractGraphicsScreen;
 import javax.media.nativewindow.NativeSurface;
-import javax.media.nativewindow.NativeWindowFactory;
 import javax.media.nativewindow.ProxySurface;
-import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook;
+import javax.media.nativewindow.UpstreamSurfaceHook;
 import javax.media.nativewindow.VisualIDHolder;
 import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLCapabilitiesChooser;
@@ -58,8 +57,9 @@ import javax.media.opengl.GLContext;
 import javax.media.opengl.GLDrawable;
 import javax.media.opengl.GLException;
 import javax.media.opengl.GLProfile;
-import javax.media.opengl.GLProfile.ShutdownType;
 
+import jogamp.nativewindow.WrappedSurface;
+import jogamp.nativewindow.x11.X11DummyUpstreamSurfaceHook;
 import jogamp.nativewindow.x11.X11Lib;
 import jogamp.nativewindow.x11.X11Util;
 import jogamp.opengl.DesktopGLDynamicLookupHelper;
@@ -71,7 +71,6 @@ import jogamp.opengl.GLGraphicsConfigurationUtil;
 import jogamp.opengl.SharedResourceRunner;
 
 import com.jogamp.common.util.VersionNumber;
-import com.jogamp.nativewindow.WrappedSurface;
 import com.jogamp.nativewindow.x11.X11GraphicsDevice;
 import com.jogamp.nativewindow.x11.X11GraphicsScreen;
 
@@ -124,7 +123,12 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
   }
 
   @Override
-  protected final void destroy(ShutdownType shutdownType) {
+  protected final boolean isComplete() {
+      return null != x11GLXDynamicLookupHelper;
+  }
+  
+  @Override
+  protected final void destroy() {
     if(null != sharedResourceRunner) {
         sharedResourceRunner.stop();
         sharedResourceRunner = null;
@@ -137,14 +141,9 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
     /**
      * Pulling away the native library may cause havoc ..
      *
-    if(ShutdownType.COMPLETE == shutdownType && null != x11GLXDynamicLookupHelper) {
-        x11GLXDynamicLookupHelper.destroy();
-        x11GLXDynamicLookupHelper = null;
-    } */
-
-    // Don't really close pending Display connections,
-    // since this may trigger a JVM exception
-    X11Util.shutdown( false, DEBUG );
+       x11GLXDynamicLookupHelper.destroy();
+     */
+    x11GLXDynamicLookupHelper = null;
   }
 
   @Override
@@ -230,33 +229,26 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
 
         @Override
         public SharedResourceRunner.Resource createSharedResource(String connection) {
-            final X11GraphicsDevice sharedDevice =
-                    new X11GraphicsDevice(X11Util.openDisplay(connection), AbstractGraphicsDevice.DEFAULT_UNIT,
-                                          true); // own non-shared display connection, w/ locking
-                    // new X11GraphicsDevice(X11Util.openDisplay(connection), AbstractGraphicsDevice.DEFAULT_UNIT,
-                    //                       NativeWindowFactory.getNullToolkitLock(), true); // own non-shared display connection, w/o locking
+            final X11GraphicsDevice sharedDevice = new X11GraphicsDevice(X11Util.openDisplay(connection), AbstractGraphicsDevice.DEFAULT_UNIT, true /* owner */);
             sharedDevice.lock();
             try {
-                final X11GraphicsScreen sharedScreen = new X11GraphicsScreen(sharedDevice, 0);
+                final X11GraphicsScreen sharedScreen = new X11GraphicsScreen(sharedDevice, sharedDevice.getDefaultScreen());
                 
                 if(!GLXUtil.isGLXAvailableOnServer(sharedDevice)) {
                     throw new GLException("GLX not available on device/server: "+sharedDevice);
                 }
                 GLXUtil.initGLXClientDataSingleton(sharedDevice);
                 final String glXServerVendorName = GLX.glXQueryServerString(sharedDevice.getHandle(), 0, GLX.GLX_VENDOR);
-                final VersionNumber glXServerVersion = GLXUtil.getGLXServerVersionNumber(sharedDevice.getHandle());
+                final VersionNumber glXServerVersion = GLXUtil.getGLXServerVersionNumber(sharedDevice);
                 final boolean glXServerMultisampleAvailable = GLXUtil.isMultisampleAvailable(GLX.glXQueryServerString(sharedDevice.getHandle(), 0, GLX.GLX_EXTENSIONS));
-                if(X11Util.ATI_HAS_XCLOSEDISPLAY_BUG && GLXUtil.isVendorATI(glXServerVendorName)) {
-                    X11Util.setMarkAllDisplaysUnclosable(true);
-                    X11Util.markDisplayUncloseable(sharedDevice.getHandle());
-                }
                 
                 final GLProfile glp = GLProfile.get(sharedDevice, GLProfile.GL_PROFILE_LIST_MIN_DESKTOP, false);
                 if (null == glp) {
                     throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice);
                 }
-                
-                final GLDrawableImpl sharedDrawable = createOnscreenDrawableImpl(createDummySurfaceImpl(sharedDevice, false, new GLCapabilities(glp), null, 64, 64));
+
+                final GLCapabilitiesImmutable caps = new GLCapabilities(glp);
+                final GLDrawableImpl sharedDrawable = createOnscreenDrawableImpl(createDummySurfaceImpl(sharedDevice, false, caps, caps, null, 64, 64));
                 sharedDrawable.setRealized(true);
                 
                 final GLContextImpl sharedContext = (GLContextImpl) sharedDrawable.createContext(null);
@@ -457,7 +449,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
           return sr.getGLXVersion();
         }
         if( device instanceof X11GraphicsDevice ) {
-          return GLXUtil.getGLXServerVersionNumber(device.getHandle());
+          return GLXUtil.getGLXServerVersionNumber((X11GraphicsDevice)device);
         }
     }
     return null;
@@ -470,7 +462,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
           return sr.isGLXVersionGreaterEqualOneOne();
         }
         if( device instanceof X11GraphicsDevice ) {
-          final VersionNumber glXServerVersion = GLXUtil.getGLXServerVersionNumber(device.getHandle());
+          final VersionNumber glXServerVersion = GLXUtil.getGLXServerVersionNumber((X11GraphicsDevice)device);
           return glXServerVersion.compareTo(versionOneOne) >= 0;
         }
     }
@@ -484,7 +476,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
           return sr.isGLXVersionGreaterEqualOneThree();
         }
         if( device instanceof X11GraphicsDevice ) {
-          final VersionNumber glXServerVersion = GLXUtil.getGLXServerVersionNumber(device.getHandle());
+          final VersionNumber glXServerVersion = GLXUtil.getGLXServerVersionNumber((X11GraphicsDevice)device);
           return glXServerVersion.compareTo(versionOneThree) >= 0;
         }
     }
@@ -506,82 +498,31 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
   protected final ProxySurface createMutableSurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice, 
                                                         GLCapabilitiesImmutable capsChosen,
                                                         GLCapabilitiesImmutable capsRequested,
-                                                        GLCapabilitiesChooser chooser, int width, int height, UpstreamSurfaceHook lifecycleHook) {
+                                                        GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstreamHook) {
     final X11GraphicsDevice device;
-    if(createNewDevice) {
-        // Null X11 locking, due to private non-shared Display handle
-        device = new X11GraphicsDevice(X11Util.openDisplay(deviceReq.getConnection()), deviceReq.getUnitID(), NativeWindowFactory.getNullToolkitLock(), true);
+    if( createNewDevice || !(deviceReq instanceof X11GraphicsDevice) ) { 
+        device = new X11GraphicsDevice(X11Util.openDisplay(deviceReq.getConnection()), deviceReq.getUnitID(), true /* owner */);
     } else {
-        device = (X11GraphicsDevice)deviceReq;
+        device = (X11GraphicsDevice) deviceReq;
     }
-    final X11GraphicsScreen screen = new X11GraphicsScreen(device, 0);
+    final X11GraphicsScreen screen = new X11GraphicsScreen(device, device.getDefaultScreen());
     final X11GLXGraphicsConfiguration config = X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, screen, VisualIDHolder.VID_UNDEFINED);
     if(null == config) {
         throw new GLException("Choosing GraphicsConfiguration failed w/ "+capsChosen+" on "+screen); 
     }
-    return new WrappedSurface( config, 0, width, height, lifecycleHook);
+    return new WrappedSurface(config, 0, upstreamHook, createNewDevice);
   }
-
+  
   @Override
   public final ProxySurface createDummySurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice, 
-                                                   GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) {
-    final GLCapabilitiesImmutable chosenCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(requestedCaps);
-    return createMutableSurfaceImpl(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, width, height, dummySurfaceLifecycleHook); 
+                                                   GLCapabilitiesImmutable chosenCaps, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) {
+    chosenCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(chosenCaps);
+    return createMutableSurfaceImpl(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, new X11DummyUpstreamSurfaceHook(width, height)); 
   }  
-  private static final ProxySurface.UpstreamSurfaceHook dummySurfaceLifecycleHook = new ProxySurface.UpstreamSurfaceHook() {
-    @Override
-    public final void create(ProxySurface s) {
-        if( 0 == s.getSurfaceHandle() ) {
-            final X11GLXGraphicsConfiguration cfg = (X11GLXGraphicsConfiguration) s.getGraphicsConfiguration();
-            final X11GraphicsScreen screen = (X11GraphicsScreen) cfg.getScreen();
-            final X11GraphicsDevice device = (X11GraphicsDevice) screen.getDevice();
-            if(0 == device.getHandle()) {
-                device.open();
-                s.setImplBitfield(ProxySurface.OWN_DEVICE);
-            }
-            final long windowHandle = X11Lib.CreateDummyWindow(device.getHandle(), screen.getIndex(), cfg.getXVisualID(), s.getWidth(), s.getHeight());
-            if(0 == windowHandle) {
-                throw new GLException("Creating dummy window failed w/ "+cfg+", "+s.getWidth()+"x"+s.getHeight());
-            }
-            s.setSurfaceHandle(windowHandle);
-            if(DEBUG) {
-                System.err.println("X11GLXDrawableFactory.dummySurfaceLifecycleHook.create: "+s);
-            }
-        }
-    }
-    @Override
-    public final void destroy(ProxySurface s) {
-        if(0 != s.getSurfaceHandle()) {
-            final X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration) s.getGraphicsConfiguration();
-            final X11GraphicsDevice device = (X11GraphicsDevice) config.getScreen().getDevice();
-            X11Lib.DestroyDummyWindow(device.getHandle(), s.getSurfaceHandle());            
-            s.setSurfaceHandle(0);
-            if( 0 != ( ProxySurface.OWN_DEVICE & s.getImplBitfield() ) ) {
-                device.close();
-            }
-            if(DEBUG) {
-                System.err.println("X11GLXDrawableFactory.dummySurfaceLifecycleHook.destroy: "+s);
-            }
-        }
-    }
-    @Override
-    public final int getWidth(ProxySurface s) {
-        return s.initialWidth;
-    }
-    @Override
-    public final int getHeight(ProxySurface s) {
-        return s.initialHeight;
-    }
-    @Override
-    public String toString() {
-       return "X11SurfaceLifecycleHook[]";
-    }
-  };
-  
   
   @Override
   protected final ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice deviceReq, int screenIdx, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream) {
-    final X11GraphicsDevice device = new X11GraphicsDevice(X11Util.openDisplay(deviceReq.getConnection()), deviceReq.getUnitID(), NativeWindowFactory.getNullToolkitLock(), true);
+    final X11GraphicsDevice device = new X11GraphicsDevice(X11Util.openDisplay(deviceReq.getConnection()), deviceReq.getUnitID(), true /* owner */);
     final X11GraphicsScreen screen = new X11GraphicsScreen(device, screenIdx);
     final int xvisualID = X11Lib.GetVisualIDFromWindow(device.getHandle(), windowHandle);
     if(VisualIDHolder.VID_UNDEFINED == xvisualID) {
@@ -594,7 +535,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
     if(DEBUG) {
         System.err.println("X11GLXDrawableFactory.createProxySurfaceImpl 0x"+Long.toHexString(windowHandle)+": "+cfg);
     }
-    return new WrappedSurface(cfg, windowHandle, 0, 0, upstream);
+    return new WrappedSurface(cfg, windowHandle, upstream, true);
   }
 
   @Override
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java
index b458fff..12ce223 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java
@@ -33,10 +33,8 @@
 
 package jogamp.opengl.x11.glx;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.nio.IntBuffer;
 
-import javax.media.nativewindow.AbstractGraphicsDevice;
 import javax.media.nativewindow.CapabilitiesImmutable;
 import javax.media.nativewindow.GraphicsConfigurationFactory;
 import javax.media.nativewindow.VisualIDHolder;
@@ -45,7 +43,6 @@ import javax.media.opengl.GL;
 import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLCapabilitiesChooser;
 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;
@@ -56,8 +53,10 @@ import jogamp.nativewindow.x11.XRenderPictFormat;
 import jogamp.nativewindow.x11.XVisualInfo;
 import jogamp.opengl.GLGraphicsConfigurationUtil;
 
+import com.jogamp.common.nio.Buffers;
 import com.jogamp.common.nio.PointerBuffer;
 import com.jogamp.nativewindow.x11.X11GraphicsConfiguration;
+import com.jogamp.nativewindow.x11.X11GraphicsDevice;
 import com.jogamp.nativewindow.x11.X11GraphicsScreen;
 
 public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implements Cloneable {
@@ -70,28 +69,6 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
         this.chooser=chooser;
     }
 
-    static X11GLXGraphicsConfiguration create(GLProfile glp, X11GraphicsScreen x11Screen, int fbcfgID) {
-      final AbstractGraphicsDevice device = x11Screen.getDevice();
-      final long display = device.getHandle();
-      if(0==display) {
-          throw new GLException("Display null of "+x11Screen);
-      }
-      final int screen = x11Screen.getIndex();
-      final long fbcfg = glXFBConfigID2FBConfig(display, screen, fbcfgID);
-      if(0==fbcfg) {
-          throw new GLException("FBConfig null of "+toHexString(fbcfgID));
-      }
-      if(null==glp) {
-        glp = GLProfile.getDefault(x11Screen.getDevice());
-      }
-      final X11GLXDrawableFactory factory = (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory();
-      final X11GLCapabilities caps = GLXFBConfig2GLCapabilities(glp, device, fbcfg, true, true, true, factory.isGLXMultisampleAvailable(device));
-      if(null==caps) {
-          throw new GLException("GLCapabilities null of "+toHexString(fbcfg));
-      }
-      return new X11GLXGraphicsConfiguration(x11Screen, caps, caps, new DefaultGLCapabilitiesChooser());
-    }
-
     public Object clone() {
         return super.clone();
     }
@@ -126,11 +103,31 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
         }
     }
 
-    static int[] GLCapabilities2AttribList(GLCapabilitiesImmutable caps,
-                                           boolean forFBAttr,
-                                           boolean isMultisampleAvailable,
-                                           long display,
-                                           int screen) 
+    static X11GLXGraphicsConfiguration create(GLProfile glp, X11GraphicsScreen x11Screen, int fbcfgID) {
+      final X11GraphicsDevice device = (X11GraphicsDevice) x11Screen.getDevice();
+      final long display = device.getHandle();
+      if(0==display) {
+          throw new GLException("Display null of "+x11Screen);
+      }
+      final int screen = x11Screen.getIndex();
+      final long fbcfg = glXFBConfigID2FBConfig(display, screen, fbcfgID);
+      if(0==fbcfg) {
+          throw new GLException("FBConfig null of "+toHexString(fbcfgID));
+      }
+      if(null==glp) {
+        glp = GLProfile.getDefault(x11Screen.getDevice());
+      }
+      final X11GLXDrawableFactory factory = (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory();
+      final X11GLCapabilities caps = GLXFBConfig2GLCapabilities(device, glp, fbcfg, GLGraphicsConfigurationUtil.ALL_BITS, factory.isGLXMultisampleAvailable(device));      
+      if(null==caps) {
+          throw new GLException("GLCapabilities null of "+toHexString(fbcfg));
+      }
+      return new X11GLXGraphicsConfiguration(x11Screen, caps, caps, new DefaultGLCapabilitiesChooser());
+    }
+
+    static IntBuffer GLCapabilities2AttribList(GLCapabilitiesImmutable caps,
+                                               boolean forFBAttr, boolean isMultisampleAvailable,
+                                               long display, int screen) 
     {
         int colorDepth = (caps.getRedBits() +
                           caps.getGreenBits() +
@@ -138,84 +135,95 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
         if (colorDepth < 15) {
           throw new GLException("Bit depths < 15 (i.e., non-true-color) not supported");
         }
-        int[] res = new int[MAX_ATTRIBS];
+        final IntBuffer res = Buffers.newDirectIntBuffer(MAX_ATTRIBS);
         int idx = 0;
 
         if (forFBAttr) {
-          res[idx++] = GLX.GLX_DRAWABLE_TYPE;
-          res[idx++] = caps.isOnscreen() ? ( GLX.GLX_WINDOW_BIT ) : ( caps.isPBuffer() ? GLX.GLX_PBUFFER_BIT : GLX.GLX_PIXMAP_BIT ) ;
-        }
-
-        if (forFBAttr) {
-          res[idx++] = GLX.GLX_RENDER_TYPE;
-          res[idx++] = GLX.GLX_RGBA_BIT;
+          res.put(idx++, GLX.GLX_DRAWABLE_TYPE);
+          
+          final int surfaceType;
+          if( caps.isOnscreen() ) {
+              surfaceType = GLX.GLX_WINDOW_BIT;
+          } else if( caps.isFBO() ) {
+              surfaceType = GLX.GLX_WINDOW_BIT;  // native replacement!
+          } else if( caps.isPBuffer() ) {
+              surfaceType = GLX.GLX_PBUFFER_BIT;
+          } else if( caps.isBitmap() ) {
+              surfaceType = GLX.GLX_PIXMAP_BIT;
+          } else {
+              throw new GLException("no surface type set in caps: "+caps);
+          }
+          res.put(idx++, surfaceType);
+          
+          res.put(idx++, GLX.GLX_RENDER_TYPE);
+          res.put(idx++, GLX.GLX_RGBA_BIT);
         } else {
-          res[idx++] = GLX.GLX_RGBA;
+          res.put(idx++, GLX.GLX_RGBA);
         }
 
         // FIXME: Still a bug is Mesa: PBUFFER && GLX_STEREO==GL_FALSE ?
         if (forFBAttr) {
-            res[idx++] = GLX.GLX_DOUBLEBUFFER;
-            res[idx++] = caps.getDoubleBuffered()?GL.GL_TRUE:GL.GL_FALSE;
-            res[idx++] = GLX.GLX_STEREO;
-            res[idx++] = caps.getStereo()?GL.GL_TRUE:GL.GL_FALSE;
-            res[idx++] = GLX.GLX_TRANSPARENT_TYPE;
-            res[idx++] = GLX.GLX_NONE;
+            res.put(idx++, GLX.GLX_DOUBLEBUFFER);
+            res.put(idx++, caps.getDoubleBuffered()?GL.GL_TRUE:GL.GL_FALSE);
+            res.put(idx++, GLX.GLX_STEREO);
+            res.put(idx++, caps.getStereo()?GL.GL_TRUE:GL.GL_FALSE);
+            res.put(idx++, GLX.GLX_TRANSPARENT_TYPE);
+            res.put(idx++, GLX.GLX_NONE);
             /**
-            res[idx++] = caps.isBackgroundOpaque()?GLX.GLX_NONE:GLX.GLX_TRANSPARENT_RGB;
+            res.put(idx++, caps.isBackgroundOpaque()?GLX.GLX_NONE:GLX.GLX_TRANSPARENT_RGB;
             if(!caps.isBackgroundOpaque()) {
-                res[idx++] = GLX.GLX_TRANSPARENT_RED_VALUE;
-                res[idx++] = caps.getTransparentRedValue()>=0?caps.getTransparentRedValue():(int)GLX.GLX_DONT_CARE;
-                res[idx++] = GLX.GLX_TRANSPARENT_GREEN_VALUE;
-                res[idx++] = caps.getTransparentGreenValue()>=0?caps.getTransparentGreenValue():(int)GLX.GLX_DONT_CARE;
-                res[idx++] = GLX.GLX_TRANSPARENT_BLUE_VALUE;
-                res[idx++] = caps.getTransparentBlueValue()>=0?caps.getTransparentBlueValue():(int)GLX.GLX_DONT_CARE;
-                res[idx++] = GLX.GLX_TRANSPARENT_ALPHA_VALUE;
-                res[idx++] = caps.getTransparentAlphaValue()>=0?caps.getTransparentAlphaValue():(int)GLX.GLX_DONT_CARE;
+                res.put(idx++, GLX.GLX_TRANSPARENT_RED_VALUE);
+                res.put(idx++, caps.getTransparentRedValue()>=0?caps.getTransparentRedValue():(int)GLX.GLX_DONT_CARE);
+                res.put(idx++, GLX.GLX_TRANSPARENT_GREEN_VALUE);
+                res.put(idx++, caps.getTransparentGreenValue()>=0?caps.getTransparentGreenValue():(int)GLX.GLX_DONT_CARE);
+                res.put(idx++, GLX.GLX_TRANSPARENT_BLUE_VALUE);
+                res.put(idx++, caps.getTransparentBlueValue()>=0?caps.getTransparentBlueValue():(int)GLX.GLX_DONT_CARE);
+                res.put(idx++, GLX.GLX_TRANSPARENT_ALPHA_VALUE);
+                res.put(idx++, caps.getTransparentAlphaValue()>=0?caps.getTransparentAlphaValue():(int)GLX.GLX_DONT_CARE);
             } */
         } else {
             if (caps.getDoubleBuffered()) {
-              res[idx++] = GLX.GLX_DOUBLEBUFFER;
+              res.put(idx++, GLX.GLX_DOUBLEBUFFER);
             }
             if (caps.getStereo()) {
-              res[idx++] = GLX.GLX_STEREO;
+              res.put(idx++, GLX.GLX_STEREO);
             }
         }
 
-        res[idx++] = GLX.GLX_RED_SIZE;
-        res[idx++] = caps.getRedBits();
-        res[idx++] = GLX.GLX_GREEN_SIZE;
-        res[idx++] = caps.getGreenBits();
-        res[idx++] = GLX.GLX_BLUE_SIZE;
-        res[idx++] = caps.getBlueBits();
+        res.put(idx++, GLX.GLX_RED_SIZE);
+        res.put(idx++, caps.getRedBits());
+        res.put(idx++, GLX.GLX_GREEN_SIZE);
+        res.put(idx++, caps.getGreenBits());
+        res.put(idx++, GLX.GLX_BLUE_SIZE);
+        res.put(idx++, caps.getBlueBits());
         if(caps.getAlphaBits()>0) {
-            res[idx++] = GLX.GLX_ALPHA_SIZE;
-            res[idx++] = caps.getAlphaBits();
+            res.put(idx++, GLX.GLX_ALPHA_SIZE);
+            res.put(idx++, caps.getAlphaBits());
         }
         if (caps.getStencilBits() > 0) {
-          res[idx++] = GLX.GLX_STENCIL_SIZE;
-          res[idx++] = caps.getStencilBits();
+          res.put(idx++, GLX.GLX_STENCIL_SIZE);
+          res.put(idx++, caps.getStencilBits());
         }
-        res[idx++] = GLX.GLX_DEPTH_SIZE;
-        res[idx++] = caps.getDepthBits();
+        res.put(idx++, GLX.GLX_DEPTH_SIZE);
+        res.put(idx++, caps.getDepthBits());
         if (caps.getAccumRedBits()   > 0 ||
             caps.getAccumGreenBits() > 0 ||
             caps.getAccumBlueBits()  > 0 ||
             caps.getAccumAlphaBits() > 0) {
-          res[idx++] = GLX.GLX_ACCUM_RED_SIZE;
-          res[idx++] = caps.getAccumRedBits();
-          res[idx++] = GLX.GLX_ACCUM_GREEN_SIZE;
-          res[idx++] = caps.getAccumGreenBits();
-          res[idx++] = GLX.GLX_ACCUM_BLUE_SIZE;
-          res[idx++] = caps.getAccumBlueBits();
-          res[idx++] = GLX.GLX_ACCUM_ALPHA_SIZE;
-          res[idx++] = caps.getAccumAlphaBits();
+          res.put(idx++, GLX.GLX_ACCUM_RED_SIZE);
+          res.put(idx++, caps.getAccumRedBits());
+          res.put(idx++, GLX.GLX_ACCUM_GREEN_SIZE);
+          res.put(idx++, caps.getAccumGreenBits());
+          res.put(idx++, GLX.GLX_ACCUM_BLUE_SIZE);
+          res.put(idx++, caps.getAccumBlueBits());
+          res.put(idx++, GLX.GLX_ACCUM_ALPHA_SIZE);
+          res.put(idx++, caps.getAccumAlphaBits());
         }
         if (isMultisampleAvailable && caps.getSampleBuffers()) {
-          res[idx++] = GLX.GLX_SAMPLE_BUFFERS;
-          res[idx++] = GL.GL_TRUE;
-          res[idx++] = GLX.GLX_SAMPLES;
-          res[idx++] = caps.getNumSamples();
+          res.put(idx++, GLX.GLX_SAMPLE_BUFFERS);
+          res.put(idx++, GL.GL_TRUE);
+          res.put(idx++, GLX.GLX_SAMPLES);
+          res.put(idx++, caps.getNumSamples());
         }
         if (caps.isPBuffer()) {
           if (caps.getPbufferFloatingPointBuffers()) {
@@ -224,11 +232,11 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
                 glXExtensions.indexOf("GLX_NV_float_buffer") < 0) {
               throw new GLException("Floating-point pbuffers on X11 currently require NVidia hardware: "+glXExtensions);
             }
-            res[idx++] = GLXExt.GLX_FLOAT_COMPONENTS_NV;
-            res[idx++] = GL.GL_TRUE;
+            res.put(idx++, GLXExt.GLX_FLOAT_COMPONENTS_NV);
+            res.put(idx++, GL.GL_TRUE);
           }
         }
-        res[idx++] = 0;
+        res.put(idx++, 0);
         return res;
   }
 
@@ -240,21 +248,22 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
   }
 
   static boolean GLXFBConfigValid(long display, long fbcfg) {
-    int[] tmp = new int[1];
-    if(GLX.GLX_BAD_ATTRIBUTE == GLX.glXGetFBConfigAttrib(display, fbcfg, GLX.GLX_RENDER_TYPE, tmp, 0)) {
+    final IntBuffer tmp = Buffers.newDirectIntBuffer(1);
+    if(GLX.GLX_BAD_ATTRIBUTE == GLX.glXGetFBConfigAttrib(display, fbcfg, GLX.GLX_RENDER_TYPE, tmp)) {
       return false;
     }
     return true;
   }
 
-  static int FBCfgDrawableTypeBits(final AbstractGraphicsDevice device, GLProfile glp, final long fbcfg) {
+  static int FBCfgDrawableTypeBits(final X11GraphicsDevice device, final long fbcfg) {
     int val = 0;
 
-    int[] tmp = new int[1];
-    int fbtype = glXGetFBConfig(device.getHandle(), fbcfg, GLX.GLX_DRAWABLE_TYPE, tmp, 0);
+    final IntBuffer tmp = Buffers.newDirectIntBuffer(1);
+    int fbtype = glXGetFBConfig(device.getHandle(), fbcfg, GLX.GLX_DRAWABLE_TYPE, tmp);
 
     if ( 0 != ( fbtype & GLX.GLX_WINDOW_BIT ) ) {
-        val |= GLGraphicsConfigurationUtil.WINDOW_BIT;
+        val |= GLGraphicsConfigurationUtil.WINDOW_BIT |
+               GLGraphicsConfigurationUtil.FBO_BIT;
     }
     if ( 0 != ( fbtype & GLX.GLX_PIXMAP_BIT ) ) {
         val |= GLGraphicsConfigurationUtil.BITMAP_BIT;
@@ -262,25 +271,9 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
     if ( 0 != ( fbtype & GLX.GLX_PBUFFER_BIT ) ) {
         val |= GLGraphicsConfigurationUtil.PBUFFER_BIT;
     }
-    if ( GLContext.isFBOAvailable(device, glp) ) {
-        val |= GLGraphicsConfigurationUtil.FBO_BIT;
-    }
     return val;
   }
 
-  static X11GLCapabilities GLXFBConfig2GLCapabilities(GLProfile glp, AbstractGraphicsDevice device, long fbcfg,
-                                                            boolean relaxed, boolean onscreen, boolean usePBuffer,
-                                                            boolean isMultisampleAvailable) {
-    ArrayList<GLCapabilitiesImmutable> bucket = new ArrayList<GLCapabilitiesImmutable>();
-    final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer, false);
-    if( GLXFBConfig2GLCapabilities(bucket, glp, device, fbcfg, winattrmask, isMultisampleAvailable) ) {
-        return (X11GLCapabilities) bucket.get(0);
-    } else if ( relaxed && GLXFBConfig2GLCapabilities(bucket, glp, device, fbcfg, GLGraphicsConfigurationUtil.ALL_BITS, isMultisampleAvailable) ) {
-        return (X11GLCapabilities) bucket.get(0);
-    }
-    return null;
-  }
-
   static XRenderDirectFormat XVisual2XRenderMask(long dpy, long visual) {
     XRenderPictFormat renderPictFmt = X11Lib.XRenderFindVisualFormat(dpy, visual);
     if(null == renderPictFmt) {
@@ -289,10 +282,9 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
     return renderPictFmt.getDirect();
   }
 
-  static boolean GLXFBConfig2GLCapabilities(List<GLCapabilitiesImmutable> capsBucket,
-                                            GLProfile glp, AbstractGraphicsDevice device, long fbcfg,
-                                            int winattrmask, boolean isMultisampleAvailable) {
-    final int allDrawableTypeBits = FBCfgDrawableTypeBits(device, glp,  fbcfg);
+  static X11GLCapabilities GLXFBConfig2GLCapabilities(X11GraphicsDevice device, GLProfile glp, long fbcfg,
+                                                      int winattrmask, boolean isMultisampleAvailable) {
+    final int allDrawableTypeBits = FBCfgDrawableTypeBits(device, fbcfg);
     int drawableTypeBits = winattrmask & allDrawableTypeBits;
     
     final long display = device.getHandle(); 
@@ -303,25 +295,25 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
             System.err.println("X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities: Null XVisualInfo for FBConfigID 0x" + Integer.toHexString(fbcfgid));
         }
         // onscreen must have an XVisualInfo
-        drawableTypeBits = drawableTypeBits & ~GLGraphicsConfigurationUtil.WINDOW_BIT;
+        drawableTypeBits &= ~(GLGraphicsConfigurationUtil.WINDOW_BIT | GLGraphicsConfigurationUtil.FBO_BIT);
     }
 
     if( 0 == drawableTypeBits ) {
-        return false;
+        return null;
     }
 
-    int[] tmp = new int[1];
-    if(GLX.GLX_BAD_ATTRIBUTE == GLX.glXGetFBConfigAttrib(display, fbcfg, GLX.GLX_RENDER_TYPE, tmp, 0)) {
-      return false;
+    final IntBuffer tmp = Buffers.newDirectIntBuffer(1);
+    if(GLX.GLX_BAD_ATTRIBUTE == GLX.glXGetFBConfigAttrib(display, fbcfg, GLX.GLX_RENDER_TYPE, tmp)) {
+      return null;
     }
-    if( 0 == ( GLX.GLX_RGBA_BIT & tmp[0] ) ) {
-      return false; // no RGBA -> color index not supported
+    if( 0 == ( GLX.GLX_RGBA_BIT & tmp.get(0) ) ) {
+      return null; // no RGBA -> color index not supported
     }
 
-    GLCapabilities res = new X11GLCapabilities(visualInfo, fbcfg, fbcfgid, glp);
+    final X11GLCapabilities res = new X11GLCapabilities(visualInfo, fbcfg, fbcfgid, glp);
     if (isMultisampleAvailable) {
-      res.setSampleBuffers(glXGetFBConfig(display, fbcfg, GLX.GLX_SAMPLE_BUFFERS, tmp, 0) != 0);
-      res.setNumSamples   (glXGetFBConfig(display, fbcfg, GLX.GLX_SAMPLES,        tmp, 0));
+      res.setSampleBuffers(glXGetFBConfig(display, fbcfg, GLX.GLX_SAMPLE_BUFFERS, tmp) != 0);
+      res.setNumSamples   (glXGetFBConfig(display, fbcfg, GLX.GLX_SAMPLES,        tmp));
     }
     final XRenderDirectFormat xrmask = ( null != visualInfo ) ? 
                                          XVisual2XRenderMask( display, visualInfo.getVisual() ) : 
@@ -335,25 +327,25 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
         res.setTransparentAlphaValue(alphaMask);
     }
     // ALPHA shall be set at last - due to it's auto setting by the above (!opaque / samples)    
-    res.setDoubleBuffered(glXGetFBConfig(display, fbcfg, GLX.GLX_DOUBLEBUFFER,     tmp, 0) != 0);
-    res.setStereo        (glXGetFBConfig(display, fbcfg, GLX.GLX_STEREO,           tmp, 0) != 0);
-    res.setHardwareAccelerated(glXGetFBConfig(display, fbcfg, GLX.GLX_CONFIG_CAVEAT, tmp, 0) != GLX.GLX_SLOW_CONFIG);
-    res.setRedBits       (glXGetFBConfig(display, fbcfg, GLX.GLX_RED_SIZE,         tmp, 0));
-    res.setGreenBits     (glXGetFBConfig(display, fbcfg, GLX.GLX_GREEN_SIZE,       tmp, 0));
-    res.setBlueBits      (glXGetFBConfig(display, fbcfg, GLX.GLX_BLUE_SIZE,        tmp, 0));
-    res.setAlphaBits     (glXGetFBConfig(display, fbcfg, GLX.GLX_ALPHA_SIZE,       tmp, 0));
-    res.setAccumRedBits  (glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_RED_SIZE,   tmp, 0));
-    res.setAccumGreenBits(glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_GREEN_SIZE, tmp, 0));
-    res.setAccumBlueBits (glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_BLUE_SIZE,  tmp, 0));
-    res.setAccumAlphaBits(glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_ALPHA_SIZE, tmp, 0));
-    res.setDepthBits     (glXGetFBConfig(display, fbcfg, GLX.GLX_DEPTH_SIZE,       tmp, 0));
-    res.setStencilBits   (glXGetFBConfig(display, fbcfg, GLX.GLX_STENCIL_SIZE,     tmp, 0));
+    res.setDoubleBuffered(glXGetFBConfig(display, fbcfg, GLX.GLX_DOUBLEBUFFER,     tmp) != 0);
+    res.setStereo        (glXGetFBConfig(display, fbcfg, GLX.GLX_STEREO,           tmp) != 0);
+    res.setHardwareAccelerated(glXGetFBConfig(display, fbcfg, GLX.GLX_CONFIG_CAVEAT, tmp) != GLX.GLX_SLOW_CONFIG);
+    res.setRedBits       (glXGetFBConfig(display, fbcfg, GLX.GLX_RED_SIZE,         tmp));
+    res.setGreenBits     (glXGetFBConfig(display, fbcfg, GLX.GLX_GREEN_SIZE,       tmp));
+    res.setBlueBits      (glXGetFBConfig(display, fbcfg, GLX.GLX_BLUE_SIZE,        tmp));
+    res.setAlphaBits     (glXGetFBConfig(display, fbcfg, GLX.GLX_ALPHA_SIZE,       tmp));
+    res.setAccumRedBits  (glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_RED_SIZE,   tmp));
+    res.setAccumGreenBits(glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_GREEN_SIZE, tmp));
+    res.setAccumBlueBits (glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_BLUE_SIZE,  tmp));
+    res.setAccumAlphaBits(glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_ALPHA_SIZE, tmp));
+    res.setDepthBits     (glXGetFBConfig(display, fbcfg, GLX.GLX_DEPTH_SIZE,       tmp));
+    res.setStencilBits   (glXGetFBConfig(display, fbcfg, GLX.GLX_STENCIL_SIZE,     tmp));
     
     try { 
-        res.setPbufferFloatingPointBuffers(glXGetFBConfig(display, fbcfg, GLXExt.GLX_FLOAT_COMPONENTS_NV, tmp, 0) != GL.GL_FALSE);
+        res.setPbufferFloatingPointBuffers(glXGetFBConfig(display, fbcfg, GLXExt.GLX_FLOAT_COMPONENTS_NV, tmp) != GL.GL_FALSE);
     } catch (Exception e) {}
 
-    return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, res, drawableTypeBits );
+    return (X11GLCapabilities) GLGraphicsConfigurationUtil.fixWinAttribBitsAndHwAccel(device, drawableTypeBits, res); 
   }
 
   private static String glXGetFBConfigErrorCode(int err) {
@@ -364,26 +356,27 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
     }
   }
 
-  static int glXGetFBConfig(long display, long cfg, int attrib, int[] tmp, int tmp_offset) {
+  static int glXGetFBConfig(long display, long cfg, int attrib, IntBuffer tmp) {
     if (display == 0) {
       throw new GLException("No display connection");
     }
-    int res = GLX.glXGetFBConfigAttrib(display, cfg, attrib, tmp, tmp_offset);
+    int res = GLX.glXGetFBConfigAttrib(display, cfg, attrib, tmp);
     if (res != 0) {
       throw new GLException("glXGetFBConfig("+toHexString(attrib)+") failed: error code " + glXGetFBConfigErrorCode(res));
     }
-    return tmp[tmp_offset];
+    return tmp.get(tmp.position());
   }
 
   static int glXFBConfig2FBConfigID(long display, long cfg) {
-      int[] tmpID = new int[1];
-      return glXGetFBConfig(display, cfg, GLX.GLX_FBCONFIG_ID, tmpID, 0);
+      final IntBuffer tmpID = Buffers.newDirectIntBuffer(1);
+      return glXGetFBConfig(display, cfg, GLX.GLX_FBCONFIG_ID, tmpID);
   }
 
   static long glXFBConfigID2FBConfig(long display, int screen, int id) {
-      int[] attribs = new int[] { GLX.GLX_FBCONFIG_ID, id, 0 };
-      int[] count = { -1 };
-      PointerBuffer fbcfgsL = GLX.glXChooseFBConfig(display, screen, attribs, 0, count, 0);
+      final IntBuffer attribs = Buffers.newDirectIntBuffer(new int[] { GLX.GLX_FBCONFIG_ID, id, 0 });
+      final IntBuffer count = Buffers.newDirectIntBuffer(1);
+      count.put(0, -1);      
+      PointerBuffer fbcfgsL = GLX.glXChooseFBConfig(display, screen, attribs, count);
       if (fbcfgsL == null || fbcfgsL.limit()<1) {
           return 0;
       }
@@ -408,43 +401,46 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
       return res;
   }
 
-  static boolean XVisualInfo2GLCapabilities(List<GLCapabilitiesImmutable> capsBucket,
-                                            GLProfile glp, long display, XVisualInfo info,
-                                            final int winattrmask, boolean isMultisampleEnabled) {
-    final int allDrawableTypeBits = GLGraphicsConfigurationUtil.WINDOW_BIT | GLGraphicsConfigurationUtil.BITMAP_BIT ;
+  static X11GLCapabilities XVisualInfo2GLCapabilities(final X11GraphicsDevice device, GLProfile glp, XVisualInfo info,
+                                                      final int winattrmask, boolean isMultisampleEnabled) {
+    final int allDrawableTypeBits = GLGraphicsConfigurationUtil.WINDOW_BIT | 
+                                    GLGraphicsConfigurationUtil.BITMAP_BIT |
+                                    GLGraphicsConfigurationUtil.FBO_BIT ;
+    
     final int drawableTypeBits = winattrmask & allDrawableTypeBits;
 
     if( 0 == drawableTypeBits ) {
-        return false;
+        return null;
     }
 
-    int[] tmp = new int[1];
-    int val = glXGetConfig(display, info, GLX.GLX_USE_GL, tmp, 0);
+    final long display = device.getHandle();
+    final IntBuffer tmp = Buffers.newDirectIntBuffer(1);
+    int val = glXGetConfig(display, info, GLX.GLX_USE_GL, tmp);
     if (val == 0) {
       if(DEBUG) {
         System.err.println("Visual ("+toHexString(info.getVisualid())+") does not support OpenGL");
       }
-      return false;
+      return null;
     }
-    val = glXGetConfig(display, info, GLX.GLX_RGBA, tmp, 0);
+    val = glXGetConfig(display, info, GLX.GLX_RGBA, tmp);
     if (val == 0) {
       if(DEBUG) {
         System.err.println("Visual ("+toHexString(info.getVisualid())+") does not support RGBA");
       }
-      return false;
+      return null;
     }
 
     GLCapabilities res = new X11GLCapabilities(info, glp);
 
-    res.setDoubleBuffered(glXGetConfig(display, info, GLX.GLX_DOUBLEBUFFER,     tmp, 0) != 0);
-    res.setStereo        (glXGetConfig(display, info, GLX.GLX_STEREO,           tmp, 0) != 0);
+    res.setDoubleBuffered(glXGetConfig(display, info, GLX.GLX_DOUBLEBUFFER,     tmp) != 0);
+    res.setStereo        (glXGetConfig(display, info, GLX.GLX_STEREO,           tmp) != 0);
     // Note: use of hardware acceleration is determined by
     // glXCreateContext, not by the XVisualInfo. Optimistically claim
     // that all GLCapabilities have the capability to be hardware
     // accelerated.    
     if (isMultisampleEnabled) {
-      res.setSampleBuffers(glXGetConfig(display, info, GLX.GLX_SAMPLE_BUFFERS, tmp, 0) != 0);
-      res.setNumSamples   (glXGetConfig(display, info, GLX.GLX_SAMPLES,        tmp, 0));
+      res.setSampleBuffers(glXGetConfig(display, info, GLX.GLX_SAMPLE_BUFFERS, tmp) != 0);
+      res.setNumSamples   (glXGetConfig(display, info, GLX.GLX_SAMPLES,        tmp));
     }
     final XRenderDirectFormat xrmask = ( null != info ) ? 
                                          XVisual2XRenderMask( display, info.getVisual() ) : 
@@ -459,18 +455,18 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
     }
     // ALPHA shall be set at last - due to it's auto setting by the above (!opaque / samples)
     res.setHardwareAccelerated(true);
-    res.setDepthBits     (glXGetConfig(display, info, GLX.GLX_DEPTH_SIZE,       tmp, 0));
-    res.setStencilBits   (glXGetConfig(display, info, GLX.GLX_STENCIL_SIZE,     tmp, 0));
-    res.setRedBits       (glXGetConfig(display, info, GLX.GLX_RED_SIZE,         tmp, 0));
-    res.setGreenBits     (glXGetConfig(display, info, GLX.GLX_GREEN_SIZE,       tmp, 0));
-    res.setBlueBits      (glXGetConfig(display, info, GLX.GLX_BLUE_SIZE,        tmp, 0));
-    res.setAlphaBits     (glXGetConfig(display, info, GLX.GLX_ALPHA_SIZE,       tmp, 0));
-    res.setAccumRedBits  (glXGetConfig(display, info, GLX.GLX_ACCUM_RED_SIZE,   tmp, 0));
-    res.setAccumGreenBits(glXGetConfig(display, info, GLX.GLX_ACCUM_GREEN_SIZE, tmp, 0));
-    res.setAccumBlueBits (glXGetConfig(display, info, GLX.GLX_ACCUM_BLUE_SIZE,  tmp, 0));
-    res.setAccumAlphaBits(glXGetConfig(display, info, GLX.GLX_ACCUM_ALPHA_SIZE, tmp, 0));
-
-    return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, res, drawableTypeBits);
+    res.setDepthBits     (glXGetConfig(display, info, GLX.GLX_DEPTH_SIZE,       tmp));
+    res.setStencilBits   (glXGetConfig(display, info, GLX.GLX_STENCIL_SIZE,     tmp));
+    res.setRedBits       (glXGetConfig(display, info, GLX.GLX_RED_SIZE,         tmp));
+    res.setGreenBits     (glXGetConfig(display, info, GLX.GLX_GREEN_SIZE,       tmp));
+    res.setBlueBits      (glXGetConfig(display, info, GLX.GLX_BLUE_SIZE,        tmp));
+    res.setAlphaBits     (glXGetConfig(display, info, GLX.GLX_ALPHA_SIZE,       tmp));
+    res.setAccumRedBits  (glXGetConfig(display, info, GLX.GLX_ACCUM_RED_SIZE,   tmp));
+    res.setAccumGreenBits(glXGetConfig(display, info, GLX.GLX_ACCUM_GREEN_SIZE, tmp));
+    res.setAccumBlueBits (glXGetConfig(display, info, GLX.GLX_ACCUM_BLUE_SIZE,  tmp));
+    res.setAccumAlphaBits(glXGetConfig(display, info, GLX.GLX_ACCUM_ALPHA_SIZE, tmp));
+
+    return (X11GLCapabilities) GLGraphicsConfigurationUtil.fixWinAttribBitsAndHwAccel(device, drawableTypeBits, res); 
   }
 
   private static String glXGetConfigErrorCode(int err) {
@@ -483,15 +479,15 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
     }
   }
 
-  static int glXGetConfig(long display, XVisualInfo info, int attrib, int[] tmp, int tmp_offset) {
+  static int glXGetConfig(long display, XVisualInfo info, int attrib, IntBuffer tmp) {
     if (display == 0) {
       throw new GLException("No display connection");
     }
-    int res = GLX.glXGetConfig(display, info, attrib, tmp, tmp_offset);
+    int res = GLX.glXGetConfig(display, info, attrib, tmp);
     if (res != 0) {
       throw new GLException("glXGetConfig("+toHexString(attrib)+") failed: error code " + glXGetConfigErrorCode(res));
     }
-    return tmp[tmp_offset];
+    return tmp.get(tmp.position());
   }
 
   public String toString() {
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java
index 234b06b..e62dcad 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java
@@ -45,11 +45,11 @@ import javax.media.opengl.DefaultGLCapabilitiesChooser;
 import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLCapabilitiesChooser;
 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;
 
+import com.jogamp.common.nio.Buffers;
 import com.jogamp.common.nio.PointerBuffer;
 import com.jogamp.nativewindow.x11.X11GraphicsDevice;
 import com.jogamp.nativewindow.x11.X11GraphicsScreen;
@@ -59,6 +59,7 @@ import jogamp.nativewindow.x11.XVisualInfo;
 import jogamp.opengl.GLGraphicsConfigurationFactory;
 import jogamp.opengl.GLGraphicsConfigurationUtil;
 
+import java.nio.IntBuffer;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -128,18 +129,22 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
             throw new GLException("Shared resource for device n/a: "+device);
         }
         final X11GraphicsScreen sharedScreen = (X11GraphicsScreen) sharedResource.getScreen();
-        final boolean isMultisampleAvailable = factory.isGLXMultisampleAvailable(sharedScreen.getDevice());
-        final X11GLXDrawable sharedDrawable = (X11GLXDrawable) sharedResource.getDrawable();
-        final GLCapabilitiesImmutable capsChosen = sharedDrawable.getChosenGLCapabilities();
-        final GLProfile glp = capsChosen.getGLProfile();
+        final X11GraphicsDevice sharedDevice = (X11GraphicsDevice) sharedScreen.getDevice();
+        final boolean isMultisampleAvailable = sharedResource.isGLXMultisampleAvailable();
+        final GLProfile glp = GLProfile.getDefault(device);
 
         List<GLCapabilitiesImmutable> availableCaps = null;
-
-        if( sharedResource.isGLXVersionGreaterEqualOneThree() ) {
-            availableCaps = getAvailableGLCapabilitiesFBConfig(sharedScreen, glp, isMultisampleAvailable);
-        }
-        if( null == availableCaps || availableCaps.isEmpty() ) {
-            availableCaps = getAvailableGLCapabilitiesXVisual(sharedScreen, glp, isMultisampleAvailable);
+        
+        sharedDevice.lock();
+        try {
+            if( sharedResource.isGLXVersionGreaterEqualOneThree() ) {
+                availableCaps = getAvailableGLCapabilitiesFBConfig(sharedScreen, glp, isMultisampleAvailable);
+            }
+            if( null == availableCaps || availableCaps.isEmpty() ) {
+                availableCaps = getAvailableGLCapabilitiesXVisual(sharedScreen, glp, isMultisampleAvailable);
+            }
+        } finally {
+            sharedDevice.unlock();
         }
         if( null != availableCaps && availableCaps.size() > 1 ) {
             Collections.sort(availableCaps, XVisualIDComparator);
@@ -152,33 +157,35 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
 
         // Utilizing FBConfig
         //
-        AbstractGraphicsDevice absDevice = x11Screen.getDevice();
-        long display = absDevice.getHandle();
+        final X11GraphicsDevice absDevice = (X11GraphicsDevice) x11Screen.getDevice();
+        final long display = absDevice.getHandle();
 
-        int screen = x11Screen.getIndex();
-        int[] count = { -1 };
-        ArrayList<GLCapabilitiesImmutable> availableCaps = new ArrayList<GLCapabilitiesImmutable>();
+        final int screen = x11Screen.getIndex();
+        final IntBuffer count = Buffers.newDirectIntBuffer(1);
+        count.put(0, -1);
+        final ArrayList<GLCapabilitiesImmutable> availableCaps = new ArrayList<GLCapabilitiesImmutable>();
 
-        fbcfgsL = GLX.glXChooseFBConfig(display, screen, null, 0, count, 0);
+        fbcfgsL = GLX.glXChooseFBConfig(display, screen, null, count);
         if (fbcfgsL == null || fbcfgsL.limit()<=0) {
             if(DEBUG) {
-                System.err.println("X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesFBConfig: Failed glXChooseFBConfig ("+x11Screen+"): "+fbcfgsL+", "+count[0]);
+                System.err.println("X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesFBConfig: Failed glXChooseFBConfig ("+x11Screen+"): "+fbcfgsL+", "+count.get(0));
             }
             return null;
         }
         for (int i = 0; i < fbcfgsL.limit(); i++) {
-            if( !X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(availableCaps, glProfile, absDevice, fbcfgsL.get(i), GLGraphicsConfigurationUtil.ALL_BITS, isMultisampleAvailable) ) {
-                if(DEBUG) {
-                    System.err.println("X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesFBConfig: FBConfig invalid (2): ("+x11Screen+"): fbcfg: "+toHexString(fbcfgsL.get(i)));
-                }
+            final GLCapabilitiesImmutable caps = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(absDevice, glProfile, fbcfgsL.get(i), GLGraphicsConfigurationUtil.ALL_BITS, isMultisampleAvailable);
+            if(null != caps) {
+                availableCaps.add(caps);
+            } else if(DEBUG) {
+                System.err.println("X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesFBConfig: FBConfig invalid (2): ("+x11Screen+"): fbcfg: "+toHexString(fbcfgsL.get(i)));
             }
         }
         return availableCaps;
     }
 
     static List<GLCapabilitiesImmutable> getAvailableGLCapabilitiesXVisual(X11GraphicsScreen x11Screen, GLProfile glProfile, boolean isMultisampleAvailable) {
-        AbstractGraphicsDevice absDevice = x11Screen.getDevice();
-        long display = absDevice.getHandle();
+        final X11GraphicsDevice absDevice = (X11GraphicsDevice) x11Screen.getDevice();
+        final long display = absDevice.getHandle();
 
         int screen = x11Screen.getIndex();
 
@@ -191,10 +198,11 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
         }
         ArrayList<GLCapabilitiesImmutable> availableCaps = new ArrayList<GLCapabilitiesImmutable>();
         for (int i = 0; i < infos.length; i++) {
-            if( !X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(availableCaps, glProfile, display, infos[i], GLGraphicsConfigurationUtil.ALL_BITS, isMultisampleAvailable) ) {
-                if(DEBUG) {
-                    System.err.println("X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesXVisual: XVisual invalid: ("+x11Screen+"): fbcfg: "+toHexString(infos[i].getVisualid()));
-                }
+            final GLCapabilitiesImmutable caps = X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(absDevice, glProfile, infos[i], GLGraphicsConfigurationUtil.ALL_BITS, isMultisampleAvailable);
+            if(null != caps) {
+                availableCaps.add(caps);
+            } if(DEBUG) {
+                System.err.println("X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesXVisual: XVisual invalid: ("+x11Screen+"): fbcfg: "+toHexString(infos[i].getVisualid()));
             }
         }
         return availableCaps;
@@ -208,25 +216,29 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
         if (x11Screen == null) {
             throw new IllegalArgumentException("AbstractGraphicsScreen is null");
         }
-
         if (capsChosen == null) {
             capsChosen = new GLCapabilities(null);
         }
         X11GraphicsDevice x11Device = (X11GraphicsDevice) x11Screen.getDevice();        
         X11GLXDrawableFactory factory = (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory();
+        
+        capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, factory, x11Device);
+        final boolean usePBuffer = !capsChosen.isOnscreen() && capsChosen.isPBuffer();
 
-        capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, GLContext.isFBOAvailable(x11Device, capsChosen.getGLProfile()), factory.canCreateGLPbuffer(x11Device) );
-        boolean usePBuffer = capsChosen.isPBuffer();
-    
         X11GLXGraphicsConfiguration res = null;
-        if( factory.isGLXVersionGreaterEqualOneThree(x11Device) ) {
-            res = chooseGraphicsConfigurationFBConfig(capsChosen, capsReq, chooser, x11Screen, xvisualID);
-        }
-        if(null==res) {
-            if(usePBuffer) {
-                throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig for visualID "+toHexString(xvisualID)+", "+capsChosen);
+        x11Device.lock();
+        try {
+            if( factory.isGLXVersionGreaterEqualOneThree(x11Device) ) {
+                res = chooseGraphicsConfigurationFBConfig(capsChosen, capsReq, chooser, x11Screen, xvisualID);
             }
-            res = chooseGraphicsConfigurationXVisual(capsChosen, capsReq, chooser, x11Screen, xvisualID);
+            if(null==res) {
+                if(usePBuffer) {
+                    throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig for visualID "+toHexString(xvisualID)+", "+capsChosen);
+                }
+                res = chooseGraphicsConfigurationXVisual(capsChosen, capsReq, chooser, x11Screen, xvisualID);
+            }
+        } finally {
+            x11Device.unlock();
         }
         if(null==res) {
             throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig and XVisual for visualID "+toHexString(xvisualID)+", "+x11Screen+", "+capsChosen);
@@ -238,8 +250,8 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
     }
 
     static X11GLXGraphicsConfiguration fetchGraphicsConfigurationFBConfig(X11GraphicsScreen x11Screen, int fbID, GLProfile glp) {
-        final AbstractGraphicsDevice absDevice = x11Screen.getDevice();
-        final long display = absDevice.getHandle();
+        final X11GraphicsDevice x11Device = (X11GraphicsDevice) x11Screen.getDevice();
+        final long display = x11Device.getHandle();
         final int screen = x11Screen.getIndex();
 
         final long fbcfg = X11GLXGraphicsConfiguration.glXFBConfigID2FBConfig(display, screen, fbID);
@@ -251,7 +263,7 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
         }
         final X11GLXDrawableFactory factory = (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory();
                
-        final X11GLCapabilities caps = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glp, absDevice, fbcfg, true, true, true, factory.isGLXMultisampleAvailable(absDevice));
+        final X11GLCapabilities caps = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(x11Device, glp, fbcfg, GLGraphicsConfigurationUtil.ALL_BITS, factory.isGLXMultisampleAvailable(x11Device));
         return new X11GLXGraphicsConfiguration(x11Screen, caps, caps, new DefaultGLCapabilitiesChooser());
     }
 
@@ -262,33 +274,32 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
         int recommendedIndex = -1;
         PointerBuffer fbcfgsL = null;
         GLProfile glProfile = capsChosen.getGLProfile();
-        boolean onscreen = capsChosen.isOnscreen();
-        boolean usePBuffer = capsChosen.isPBuffer();
-        boolean useFBO = capsChosen.isFBO();
 
         // Utilizing FBConfig
         //
-        AbstractGraphicsDevice absDevice = x11Screen.getDevice();
-        long display = absDevice.getHandle();
+        X11GraphicsDevice x11Device = (X11GraphicsDevice) x11Screen.getDevice();
+        long display = x11Device.getHandle();
         int screen = x11Screen.getIndex();
         
         final X11GLXDrawableFactory factory = (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory();                              
-        final boolean isMultisampleAvailable = factory.isGLXMultisampleAvailable(absDevice);
-        int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capsChosen, true, isMultisampleAvailable, display, screen);
-        int[] count = { -1 };
+        final boolean isMultisampleAvailable = factory.isGLXMultisampleAvailable(x11Device);
+        final IntBuffer attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capsChosen, true, isMultisampleAvailable, display, screen);
+        final IntBuffer count = Buffers.newDirectIntBuffer(1);
+        count.put(0, -1);
         List<GLCapabilitiesImmutable> availableCaps = new ArrayList<GLCapabilitiesImmutable>();
-        final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer, useFBO);
+        final int winattrmask = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(capsChosen);
         // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice,
         // skipped if xvisualID is given
         if( VisualIDHolder.VID_UNDEFINED == xvisualID ) {
-            fbcfgsL = GLX.glXChooseFBConfig(display, screen, attribs, 0, count, 0);
+            fbcfgsL = GLX.glXChooseFBConfig(display, screen, attribs, count);
         }
         if (fbcfgsL != null && fbcfgsL.limit()>0) {
             for (int i = 0; i < fbcfgsL.limit(); i++) {
-                if( !X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(availableCaps, glProfile, absDevice, fbcfgsL.get(i), winattrmask, isMultisampleAvailable) ) {
-                    if(DEBUG) {
-                        System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid (1): ("+x11Screen+","+capsChosen+"): fbcfg: "+toHexString(fbcfgsL.get(i)));
-                    }
+                final GLCapabilitiesImmutable caps = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(x11Device, glProfile, fbcfgsL.get(i), winattrmask, isMultisampleAvailable);
+                if( null != caps ) {
+                    availableCaps.add(caps);
+                } else if(DEBUG) {
+                    System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid (1): ("+x11Screen+","+capsChosen+"): fbcfg: "+toHexString(fbcfgsL.get(i)));
                 }
             }
             if(availableCaps.size() > 0) {
@@ -309,19 +320,20 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
             // reset ..
             recommendedIndex = -1;
 
-            fbcfgsL = GLX.glXChooseFBConfig(display, screen, null, 0, count, 0);
+            fbcfgsL = GLX.glXChooseFBConfig(display, screen, null, count);
             if (fbcfgsL == null || fbcfgsL.limit()<=0) {
                 if(DEBUG) {
-                    System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXChooseFBConfig ("+x11Screen+","+capsChosen+"): "+fbcfgsL+", "+count[0]);
+                    System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXChooseFBConfig ("+x11Screen+","+capsChosen+"): "+fbcfgsL+", "+count.get(0));
                 }
                 return null;
             }
 
             for (int i = 0; i < fbcfgsL.limit(); i++) {
-                if( !X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(availableCaps, glProfile, absDevice, fbcfgsL.get(i), winattrmask, isMultisampleAvailable) ) {
-                    if(DEBUG) {
-                        System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid (2): ("+x11Screen+"): fbcfg: "+toHexString(fbcfgsL.get(i)));
-                    }
+                final GLCapabilitiesImmutable caps = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(x11Device, glProfile, fbcfgsL.get(i), winattrmask, isMultisampleAvailable);
+                if( null != caps ) {
+                    availableCaps.add(caps);
+                } else if(DEBUG) {
+                    System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid (2): ("+x11Screen+"): fbcfg: "+toHexString(fbcfgsL.get(i)));
                 }
             }
         }
@@ -374,23 +386,23 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
         }
 
         GLProfile glProfile = capsChosen.getGLProfile();
-        final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(capsChosen.isOnscreen(), false /* pbuffer */, false);
+        final int winattrmask = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(capsChosen.isOnscreen(), capsChosen.isFBO(), false /* pbuffer */, capsChosen.isBitmap());
         List<GLCapabilitiesImmutable> availableCaps = new ArrayList<GLCapabilitiesImmutable>();
         int recommendedIndex = -1;
 
-        AbstractGraphicsDevice absDevice = x11Screen.getDevice();
+        X11GraphicsDevice absDevice = (X11GraphicsDevice) x11Screen.getDevice();
         long display = absDevice.getHandle();
         int screen = x11Screen.getIndex();
         
         final X11GLXDrawableFactory factory = (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory();                              
         final boolean isMultisampleAvailable = factory.isGLXMultisampleAvailable(absDevice);        
-        int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capsChosen, false, isMultisampleAvailable, display, screen);
+        final IntBuffer attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capsChosen, false, isMultisampleAvailable, display, screen);
 
         XVisualInfo recommendedVis = null;
         // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice
         // skipped if xvisualID is given
         if( VisualIDHolder.VID_UNDEFINED == xvisualID ) {  
-            recommendedVis = GLX.glXChooseVisual(display, screen, attribs, 0);
+            recommendedVis = GLX.glXChooseVisual(display, screen, attribs);
             if (DEBUG) {
                 System.err.print("glXChooseVisual recommended ");
                 if (recommendedVis == null) {
@@ -411,15 +423,15 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
         }
 
         for (int i = 0; i < infos.length; i++) {
-            if( !X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(availableCaps, glProfile, display, infos[i], winattrmask, isMultisampleAvailable) ) {
-                if(DEBUG) {
-                    System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationXVisual: XVisual invalid: ("+x11Screen+"): fbcfg: "+toHexString(infos[i].getVisualid()));
-                }
-            } else {
+            final GLCapabilitiesImmutable caps = X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(absDevice, glProfile, infos[i], winattrmask, isMultisampleAvailable);
+            if( null != caps ) {
+                availableCaps.add(caps);
                 // Attempt to find the visual chosenIndex by glXChooseVisual, if not translucent
                 if (capsChosen.isBackgroundOpaque() && recommendedVis != null && recommendedVis.getVisualid() == infos[i].getVisualid()) {
                     recommendedIndex = availableCaps.size() - 1;
                 }
+            } else if(DEBUG) {
+                System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationXVisual: XVisual invalid: ("+x11Screen+"): fbcfg: "+toHexString(infos[i].getVisualid()));
             }
         }
 
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11OnscreenGLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11OnscreenGLXDrawable.java
index 3632993..c15065c 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11OnscreenGLXDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11OnscreenGLXDrawable.java
@@ -91,7 +91,7 @@ public class X11OnscreenGLXDrawable extends X11GLXDrawable {
             if(0!=glXWindow) {
                 GLX.glXDestroyWindow(dpy, glXWindow);
             }
-            glXWindow = GLX.glXCreateWindow(dpy, config.getFBConfig(), getNativeSurface().getSurfaceHandle(), null, 0);
+            glXWindow = GLX.glXCreateWindow(dpy, config.getFBConfig(), getNativeSurface().getSurfaceHandle(), null);
             if (DEBUG) {
               System.err.println("X11OnscreenGLXDrawable.setRealized(true): glXWindow: "+toHexString(getNativeSurface().getSurfaceHandle())+" -> "+toHexString(glXWindow));
             }
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java
index e1fe2f2..28db2ad 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java
@@ -40,6 +40,8 @@
 
 package jogamp.opengl.x11.glx;
 
+import java.nio.IntBuffer;
+
 import javax.media.nativewindow.AbstractGraphicsDevice;
 import javax.media.nativewindow.AbstractGraphicsScreen;
 import javax.media.nativewindow.NativeSurface;
@@ -50,6 +52,8 @@ import javax.media.opengl.GLDrawableFactory;
 import javax.media.opengl.GLException;
 import javax.media.opengl.GLPbuffer;
 
+import com.jogamp.common.nio.Buffers;
+
 public class X11PbufferGLXDrawable extends X11GLXDrawable {
   protected X11PbufferGLXDrawable(GLDrawableFactory factory, NativeSurface target) {
                                   /* GLCapabilities caps,
@@ -81,10 +85,11 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable {
   }
 
   private void createPbuffer() {
-      X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration) getNativeSurface().getGraphicsConfiguration();
-      AbstractGraphicsScreen aScreen = config.getScreen();
-      AbstractGraphicsDevice aDevice = aScreen.getDevice();
-      long display = aDevice.getHandle();
+      final MutableSurface ms = (MutableSurface) getNativeSurface();
+      final X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration) ms.getGraphicsConfiguration();
+      final AbstractGraphicsScreen aScreen = config.getScreen();
+      final AbstractGraphicsDevice aDevice = aScreen.getDevice();
+      final long display = aDevice.getHandle();
 
       if (DEBUG) {
         System.out.println("Pbuffer config: " + config);
@@ -94,8 +99,6 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable {
         throw new GLException("Null display");
       }
 
-      NativeSurface ns = getNativeSurface();
-
       GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable)config.getChosenCapabilities();
 
       if (chosenCaps.getPbufferRenderToTexture()) {
@@ -108,24 +111,24 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable {
 
       // Create the p-buffer.
       int niattribs = 0;
-      int[] iattributes = new int[7];
+      IntBuffer iattributes = Buffers.newDirectIntBuffer(7);
 
-      iattributes[niattribs++] = GLX.GLX_PBUFFER_WIDTH;
-      iattributes[niattribs++] = ns.getWidth();
-      iattributes[niattribs++] = GLX.GLX_PBUFFER_HEIGHT;
-      iattributes[niattribs++] = ns.getHeight();
-      iattributes[niattribs++] = GLX.GLX_LARGEST_PBUFFER; // exact
-      iattributes[niattribs++] = 0;
-      iattributes[niattribs++] = 0;
+      iattributes.put(niattribs++, GLX.GLX_PBUFFER_WIDTH);
+      iattributes.put(niattribs++, ms.getWidth());
+      iattributes.put(niattribs++, GLX.GLX_PBUFFER_HEIGHT);
+      iattributes.put(niattribs++, ms.getHeight());
+      iattributes.put(niattribs++, GLX.GLX_LARGEST_PBUFFER); // exact
+      iattributes.put(niattribs++, 0);
+      iattributes.put(niattribs++, 0);
 
-      long pbuffer = GLX.glXCreatePbuffer(display, config.getFBConfig(), iattributes, 0);
+      long pbuffer = GLX.glXCreatePbuffer(display, config.getFBConfig(), iattributes);
       if (pbuffer == 0) {
         // FIXME: query X error code for detail error message
         throw new GLException("pbuffer creation error: glXCreatePbuffer() failed");
       }
 
       // Set up instance variables
-      ((MutableSurface)ns).setSurfaceHandle(pbuffer);
+      ms.setSurfaceHandle(pbuffer);
 
       if (DEBUG) {
         System.err.println("Created pbuffer " + this);
diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m b/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m
new file mode 100644
index 0000000..6ebf400
--- /dev/null
+++ b/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m
@@ -0,0 +1,840 @@
+#import "MacOSXWindowSystemInterface.h"
+#import <QuartzCore/QuartzCore.h>
+#import <pthread.h>
+#include "timespec.h"
+
+#import <OpenGL/glext.h>
+
+/** 
+ * Partial include of gl3.h - which we can only expect and use 
+ * in case of a GL3 core context at runtime.
+ * Otherwise we would need to have 2 modules, one including GL2
+ * and one inclusing GL3 headers.
+ */
+#ifndef GL_ARB_vertex_array_object
+#define GL_VERTEX_ARRAY_BINDING           0x85B5
+extern void glBindVertexArray (GLuint array);
+extern void glDeleteVertexArrays (GLsizei n, const GLuint *arrays);
+extern void glGenVertexArrays (GLsizei n, GLuint *arrays);
+extern GLboolean glIsVertexArray (GLuint array);
+#endif
+
+// 
+// CADisplayLink only available on iOS >= 3.1, sad, since it's convenient.
+// Use CVDisplayLink otherwise.
+//
+// #define HAS_CADisplayLink 1
+//
+
+// lock/sync debug output
+//
+// #define DBG_SYNC 1
+//
+#ifdef DBG_SYNC
+    // #define SYNC_PRINT(...) NSLog(@ ## __VA_ARGS__)
+    #define SYNC_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
+#else
+    #define SYNC_PRINT(...)
+#endif
+
+// fps debug output
+//
+// #define DBG_PERF 1
+
+/**
+ * Capture setView(NULL), which produces a 'invalid drawable' message
+ *
+ * Also track lifecycle via DBG_PRINT messages, if VERBOSE is enabled!
+ */
+ at interface MyNSOpenGLContext: NSOpenGLContext
+{
+}
+- (id)initWithFormat:(NSOpenGLPixelFormat *)format shareContext:(NSOpenGLContext *)share;
+- (void)setView:(NSView *)view;
+- (void)update;
+- (void)dealloc;
+
+ at end
+
+ at implementation MyNSOpenGLContext
+
+- (id)initWithFormat:(NSOpenGLPixelFormat *)format shareContext:(NSOpenGLContext *)share
+{
+    DBG_PRINT("MyNSOpenGLContext.initWithFormat.0: format %p, share %p\n", format, share);
+    MyNSOpenGLContext * o = [super initWithFormat:format shareContext:share];
+    DBG_PRINT("MyNSOpenGLContext.initWithFormat.X: new %p\n", o);
+    return o;
+}
+
+- (void)setView:(NSView *)view
+{
+    DBG_PRINT("MyNSOpenGLContext.setView: this.0 %p, view %p\n", self, view);
+    if(NULL != view) {
+        [super setView:view];
+    }
+    DBG_PRINT("MyNSOpenGLContext.setView.X\n");
+}
+
+- (void)update
+{
+    DBG_PRINT("MyNSOpenGLContext.update: this.0 %p, view %p\n", self, [self view]);
+    [super update];
+    DBG_PRINT("MyNSOpenGLContext.update.X\n");
+}
+
+- (void)dealloc
+{
+    DBG_PRINT("MyNSOpenGLContext.dealloc: this.0 %p\n", self);
+    [super dealloc];
+    DBG_PRINT("MyNSOpenGLContext.dealloc.X: %p\n", self);
+}
+
+ at end
+
+ at interface MyNSOpenGLLayer: NSOpenGLLayer
+{
+ at private
+    GLfloat gl_texCoords[8];
+
+ at protected
+    NSOpenGLContext* parentCtx;
+    GLuint gl3ShaderProgramName;
+    GLuint vboBufVert;
+    GLuint vboBufTexCoord;
+    GLint vertAttrLoc;
+    GLint texCoordAttrLoc;
+    NSOpenGLPixelFormat* parentPixelFmt;
+    int texWidth;
+    int texHeight;
+    int newTexWidth;
+    int newTexHeight;
+    volatile NSOpenGLPixelBuffer* pbuffer;
+    volatile GLuint textureID;
+    volatile NSOpenGLPixelBuffer* newPBuffer;
+#ifdef HAS_CADisplayLink
+    CADisplayLink* displayLink;
+#else
+    CVDisplayLinkRef displayLink;
+#endif
+    int tc;
+    struct timespec tStart;
+ at public
+    struct timespec lastWaitTime;
+    GLint swapInterval;
+    GLint swapIntervalCounter;
+    pthread_mutex_t renderLock;
+    pthread_cond_t renderSignal;
+    volatile Bool shallDraw;
+}
+
+- (id) setupWithContext: (NSOpenGLContext*) parentCtx
+       gl3ShaderProgramName: (GLuint) gl3ShaderProgramName
+       pixelFormat: (NSOpenGLPixelFormat*) pfmt
+       pbuffer: (NSOpenGLPixelBuffer*) p
+       texIDArg: (GLuint) texID
+       opaque: (Bool) opaque
+       texWidth: (int) texWidth 
+       texHeight: (int) texHeight;
+
+- (Bool) validateTexSizeWithNewSize;
+- (Bool) validateTexSize: (int) _texWidth texHeight: (int) _texHeight;
+- (void) setTextureID: (int) _texID;
+
+- (Bool) isSamePBuffer: (NSOpenGLPixelBuffer*) p;
+- (void) setNewPBuffer: (NSOpenGLPixelBuffer*)p;
+- (void) applyNewPBuffer;
+
+- (NSOpenGLPixelFormat *)openGLPixelFormatForDisplayMask:(uint32_t)mask;
+- (NSOpenGLContext *)openGLContextForPixelFormat:(NSOpenGLPixelFormat *)pixelFormat;
+- (void)disableAnimation;
+- (void)pauseAnimation:(Bool)pause;
+- (void)deallocPBuffer;
+- (void)releaseLayer;
+- (void)dealloc;
+- (void)setSwapInterval:(int)interval;
+- (void)tick;
+- (void)waitUntilRenderSignal: (long) to_micros;
+- (Bool)isGLSourceValid;
+
+ at end
+
+#ifndef HAS_CADisplayLink
+
+static CVReturn renderMyNSOpenGLLayer(CVDisplayLinkRef displayLink, 
+                                      const CVTimeStamp *inNow, 
+                                      const CVTimeStamp *inOutputTime, 
+                                      CVOptionFlags flagsIn, 
+                                      CVOptionFlags *flagsOut, 
+                                      void *displayLinkContext)
+{
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+    MyNSOpenGLLayer* l = (MyNSOpenGLLayer*)displayLinkContext;
+    pthread_mutex_lock(&l->renderLock);
+    if( 0 < l->swapInterval ) {
+        l->swapIntervalCounter++;
+        if( l->swapIntervalCounter >= l->swapInterval ) {
+            SYNC_PRINT("<S %d/%d>", (int)l->swapIntervalCounter, l->swapInterval);
+            l->swapIntervalCounter = 0;
+            pthread_cond_signal(&l->renderSignal); // wake up vsync
+        }
+    }
+    pthread_mutex_unlock(&l->renderLock);
+    [pool release];
+    return kCVReturnSuccess;
+}
+
+#endif
+
+static const GLfloat gl_verts[] = {
+    -1.0, -1.0,
+    -1.0,  1.0,
+     1.0,  1.0,
+     1.0, -1.0
+};
+
+ at implementation MyNSOpenGLLayer
+
+- (id) setupWithContext: (NSOpenGLContext*) _parentCtx
+       gl3ShaderProgramName: (GLuint) _gl3ShaderProgramName
+       pixelFormat: (NSOpenGLPixelFormat*) _parentPixelFmt
+       pbuffer: (NSOpenGLPixelBuffer*) p
+       texIDArg: (GLuint) texID
+       opaque: (Bool) opaque
+       texWidth: (int) _texWidth 
+       texHeight: (int) _texHeight;
+{
+    pthread_mutexattr_t renderLockAttr;
+    pthread_mutexattr_init(&renderLockAttr);
+    pthread_mutexattr_settype(&renderLockAttr, PTHREAD_MUTEX_RECURSIVE);
+    pthread_mutex_init(&renderLock, &renderLockAttr); // recursive
+    pthread_cond_init(&renderSignal, NULL); // no attribute
+
+    {
+        int i;
+        for(i=0; i<8; i++) {
+            gl_texCoords[i] = 0.0f;
+        }
+    }
+    parentCtx = _parentCtx;
+    gl3ShaderProgramName = _gl3ShaderProgramName;
+    vboBufVert = 0;
+    vboBufTexCoord = 0;
+    vertAttrLoc = 0;
+    texCoordAttrLoc = 0;
+    parentPixelFmt = _parentPixelFmt;
+    swapInterval = 1; // defaults to on (as w/ new GL profiles)
+    swapIntervalCounter = 0;
+    timespec_now(&lastWaitTime);
+    shallDraw = NO;
+    newTexWidth = _texWidth;
+    newTexHeight = _texHeight;
+    [self validateTexSizeWithNewSize];
+    [self setTextureID: texID];
+
+    newPBuffer = NULL;
+    pbuffer = p;
+    if(NULL != pbuffer) {
+        [pbuffer retain];
+    }
+
+    {
+        // no animations for add/remove/swap sublayers etc 
+        // doesn't work: [self removeAnimationForKey: kCAOnOrderIn, kCAOnOrderOut, kCATransition]
+        [self removeAllAnimations];
+    }
+
+    // instantiate a deactivated displayLink
+#ifdef HAS_CADisplayLink
+    displayLink = [[CVDisplayLink displayLinkWithTarget:self selector:@selector(setNeedsDisplay)] retain];
+#else
+    CVReturn cvres;
+    {
+        int allDisplaysMask = 0;
+        int virtualScreen, accelerated, displayMask;
+        for (virtualScreen = 0; virtualScreen < [parentPixelFmt  numberOfVirtualScreens]; virtualScreen++) {
+            [parentPixelFmt getValues:&displayMask forAttribute:NSOpenGLPFAScreenMask forVirtualScreen:virtualScreen];
+            [parentPixelFmt getValues:&accelerated forAttribute:NSOpenGLPFAAccelerated forVirtualScreen:virtualScreen];
+            if (accelerated) {
+                allDisplaysMask |= displayMask;
+            }
+        }
+        cvres = CVDisplayLinkCreateWithOpenGLDisplayMask(allDisplaysMask, &displayLink);
+        if(kCVReturnSuccess != cvres) {
+            DBG_PRINT("MyNSOpenGLLayer::init %p, CVDisplayLinkCreateWithOpenGLDisplayMask %X failed: %d\n", self, allDisplaysMask, cvres);
+            displayLink = NULL;
+        }
+    }
+    if(NULL != displayLink) {
+        cvres = CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(displayLink, [parentCtx CGLContextObj], [parentPixelFmt CGLPixelFormatObj]);
+        if(kCVReturnSuccess != cvres) {
+            DBG_PRINT("MyNSOpenGLLayer::init %p, CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext failed: %d\n", self, cvres);
+            displayLink = NULL;
+        }
+    }
+    if(NULL != displayLink) {
+        cvres = CVDisplayLinkSetOutputCallback(displayLink, renderMyNSOpenGLLayer, self);
+        if(kCVReturnSuccess != cvres) {
+            DBG_PRINT("MyNSOpenGLLayer::init %p, CVDisplayLinkSetOutputCallback failed: %d\n", self, cvres);
+            displayLink = NULL;
+        }
+    }
+#endif
+    [self pauseAnimation: YES];
+
+    [self removeAllAnimations];
+    [self setAutoresizingMask: (kCALayerWidthSizable|kCALayerHeightSizable)];
+    [self setNeedsDisplayOnBoundsChange: YES];
+
+    [self setOpaque: opaque ? YES : NO];
+
+#ifdef VERBOSE_ON
+    CGRect lRect = [self bounds];
+    if(NULL != pbuffer) {
+        DBG_PRINT("MyNSOpenGLLayer::init (pbuffer) %p, ctx %p, pfmt %p, pbuffer %p, opaque %d, pbuffer %dx%d -> tex %dx%d, bounds: %lf/%lf %lfx%lf (refcnt %d)\n", 
+            self, parentCtx, parentPixelFmt, pbuffer, opaque, [pbuffer pixelsWide], [pbuffer pixelsHigh], texWidth, texHeight,
+            lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height, (int)[self retainCount]);
+    } else {
+        DBG_PRINT("MyNSOpenGLLayer::init (texture) %p, ctx %p, pfmt %p, opaque %d, tex[id %d, %dx%d], bounds: %lf/%lf %lfx%lf (refcnt %d)\n", 
+            self, parentCtx, parentPixelFmt, opaque, (int)textureID, texWidth, texHeight,
+            lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height, (int)[self retainCount]);
+    }
+#endif
+    return self;
+}
+
+- (Bool) validateTexSizeWithNewSize
+{
+    return [self validateTexSize: newTexWidth texHeight: newTexHeight];
+}
+
+- (Bool) validateTexSize: (int) _texWidth texHeight: (int) _texHeight
+{
+    if(_texHeight != texHeight || _texWidth != texWidth) {
+        texWidth = _texWidth;
+        texHeight = _texHeight;
+        CGRect lRect = [self bounds];
+        lRect.origin.x = 0;
+        lRect.origin.y = 0;
+        lRect.size.width = texWidth;
+        lRect.size.height = texHeight;
+        [self setFrame: lRect];
+
+        GLfloat texCoordWidth, texCoordHeight;
+        if(NULL != pbuffer) {
+            GLenum textureTarget = [pbuffer textureTarget] ;
+            GLsizei pwidth = [pbuffer pixelsWide];
+            GLsizei pheight = [pbuffer pixelsHigh];
+            if( GL_TEXTURE_2D == textureTarget ) {
+                texCoordWidth  = (GLfloat)pwidth /(GLfloat)texWidth  ;
+                texCoordHeight = (GLfloat)pheight/(GLfloat)texHeight ;
+            } else {
+                texCoordWidth  = pwidth;
+                texCoordHeight = pheight;
+            }
+        } else {
+            texCoordWidth  = (GLfloat)1.0f;
+            texCoordHeight = (GLfloat)1.0f;
+        }
+        gl_texCoords[3] = texCoordHeight;
+        gl_texCoords[5] = texCoordHeight;
+        gl_texCoords[4] = texCoordWidth;
+        gl_texCoords[6] = texCoordWidth;
+        return YES;
+    } else {
+        return NO;
+    }
+}
+
+- (void) setTextureID: (int) _texID
+{
+    textureID = _texID;
+}
+
+- (Bool) isSamePBuffer: (NSOpenGLPixelBuffer*) p
+{
+    return pbuffer == p || newPBuffer == p;
+}
+
+- (void)setNewPBuffer: (NSOpenGLPixelBuffer*)p
+{
+    SYNC_PRINT("<NP-S %p -> %p>", pbuffer, p);
+    newPBuffer = p;
+    [newPBuffer retain];
+}
+
+- (void) applyNewPBuffer
+{
+    if( NULL != newPBuffer ) { // volatile OK
+        SYNC_PRINT("<NP-A %p -> %p>", pbuffer, newPBuffer);
+
+        if( 0 != textureID ) {
+            glDeleteTextures(1, (GLuint *)&textureID);
+            [self setTextureID: 0];
+        }
+        [pbuffer release];
+
+        pbuffer = newPBuffer;
+        newPBuffer = NULL;
+    }
+}
+
+- (void)deallocPBuffer
+{
+    if(NULL != pbuffer) {
+        NSOpenGLContext* context = [self openGLContext];
+        if(NULL!=context) {
+            [context makeCurrentContext];
+
+            DBG_PRINT("MyNSOpenGLLayer::deallocPBuffer (with ctx) %p (refcnt %d) - context %p, pbuffer %p, texID %d\n", self, (int)[self retainCount], context, pbuffer, (int)textureID);
+
+            if( 0 != textureID ) {
+                glDeleteTextures(1, (GLuint *)&textureID);
+                [self setTextureID: 0];
+            }
+            if(NULL != pbuffer) {
+                [pbuffer release];
+                pbuffer = NULL;
+            }
+            if(NULL != newPBuffer) {
+                [newPBuffer release];
+                newPBuffer = NULL;
+            }
+
+            [context clearDrawable];
+        } else {
+            DBG_PRINT("MyNSOpenGLLayer::deallocPBuffer (w/o ctx) %p (refcnt %d) - context %p, pbuffer %p, texID %d\n", self, (int)[self retainCount], context, pbuffer, (int)textureID);
+        }
+    }
+}
+
+- (NSOpenGLPixelFormat *)openGLPixelFormatForDisplayMask:(uint32_t)mask
+{
+    DBG_PRINT("MyNSOpenGLLayer::openGLPixelFormatForDisplayMask: %p (refcnt %d) - parent-pfmt %p -> new-pfmt %p\n", 
+        self, (int)[self retainCount], parentPixelFmt, parentPixelFmt);
+    return parentPixelFmt;
+}
+
+- (NSOpenGLContext *)openGLContextForPixelFormat:(NSOpenGLPixelFormat *)pixelFormat
+{
+    DBG_PRINT("MyNSOpenGLLayer::openGLContextForPixelFormat.0: %p (refcnt %d) - pfmt %p, parent %p\n",
+        self, (int)[self retainCount], pixelFormat, parentCtx);
+    NSOpenGLContext * nctx = [[MyNSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:parentCtx];
+    DBG_PRINT("MyNSOpenGLLayer::openGLContextForPixelFormat.X: new-ctx %p\n", nctx);
+    return nctx;
+}
+
+- (void)disableAnimation
+{
+    DBG_PRINT("MyNSOpenGLLayer::disableAnimation: %p (refcnt %d) - displayLink %p\n", self, (int)[self retainCount], displayLink);
+    pthread_mutex_lock(&renderLock);
+    [self setAsynchronous: NO];
+    if(NULL != displayLink) {
+#ifdef HAS_CADisplayLink
+        [displayLink setPaused: YES];
+        [displayLink release];
+#else
+        CVDisplayLinkStop(displayLink);
+        CVDisplayLinkRelease(displayLink);
+#endif
+        displayLink = NULL;
+    }
+    pthread_mutex_unlock(&renderLock);
+}
+
+- (void)releaseLayer
+{
+    DBG_PRINT("MyNSOpenGLLayer::releaseLayer.0: %p (refcnt %d)\n", self, (int)[self retainCount]);
+    pthread_mutex_lock(&renderLock);
+    [self disableAnimation];
+    [self deallocPBuffer];
+    [[self openGLContext] release];
+    [self release];
+    DBG_PRINT("MyNSOpenGLLayer::releaseLayer.X: %p (refcnt %d)\n", self, (int)[self retainCount]);
+    pthread_mutex_unlock(&renderLock);
+}
+
+- (void)dealloc
+{
+    DBG_PRINT("MyNSOpenGLLayer::dealloc.0 %p (refcnt %d)\n", self, (int)[self retainCount]);
+    // NSLog(@"MyNSOpenGLLayer::dealloc: %@",[NSThread callStackSymbols]);
+
+    pthread_mutex_lock(&renderLock);
+    [self disableAnimation];
+    [self deallocPBuffer];
+    pthread_mutex_unlock(&renderLock);
+    pthread_cond_destroy(&renderSignal);
+    pthread_mutex_destroy(&renderLock);
+    [super dealloc];
+    DBG_PRINT("MyNSOpenGLLayer::dealloc.X %p\n", self);
+}
+
+- (Bool)isGLSourceValid
+{
+    return NULL != pbuffer || NULL != newPBuffer || 0 != textureID ;
+}
+
+- (void)resizeWithOldSuperlayerSize:(CGSize)size
+ {
+    CGRect lRectS = [[self superlayer] bounds];
+
+    DBG_PRINT("MyNSOpenGLLayer::resizeWithOldSuperlayerSize: %p, texSize %dx%d, bounds: %lfx%lf -> %lfx%lf (refcnt %d)\n", 
+        self, texWidth, texHeight, size.width, size.height, lRectS.size.width, lRectS.size.height, (int)[self retainCount]);
+
+    newTexWidth = lRectS.size.width;
+    newTexHeight = lRectS.size.height;
+    shallDraw = [self isGLSourceValid];
+    SYNC_PRINT("<SZ %dx%d>", newTexWidth, newTexHeight);
+
+    [super resizeWithOldSuperlayerSize: size];
+}
+
+- (BOOL)canDrawInOpenGLContext:(NSOpenGLContext *)context pixelFormat:(NSOpenGLPixelFormat *)pixelFormat 
+        forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp
+{
+    SYNC_PRINT("<? %d>", (int)shallDraw);
+    return shallDraw;
+}
+
+- (void)drawInOpenGLContext:(NSOpenGLContext *)context pixelFormat:(NSOpenGLPixelFormat *)pixelFormat 
+        forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp
+{
+    pthread_mutex_unlock(&renderLock);
+    SYNC_PRINT("<* ");
+    // NSLog(@"MyNSOpenGLLayer::DRAW: %@",[NSThread callStackSymbols]);
+
+    if( shallDraw && ( NULL != pbuffer || NULL != newPBuffer || 0 != textureID ) ) {
+        [context makeCurrentContext];
+
+        if( NULL != newPBuffer ) { // volatile OK
+            [self applyNewPBuffer];
+        }
+
+        GLenum textureTarget;
+
+        Bool texSizeChanged = [self validateTexSizeWithNewSize];
+
+        if( NULL != pbuffer ) {
+            if( texSizeChanged && 0 != textureID ) {
+                glDeleteTextures(1, (GLuint *)&textureID);
+                [self setTextureID: 0];
+            }
+            textureTarget = [pbuffer textureTarget];
+            if( 0 != gl3ShaderProgramName ) {
+                glUseProgram(gl3ShaderProgramName);
+                glActiveTexture(GL_TEXTURE0);
+            }
+            if( 0 == textureID ) {
+                glGenTextures(1, (GLuint *)&textureID);
+                glBindTexture(textureTarget, textureID);
+                glTexParameteri(textureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+                glTexParameteri(textureTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+                glTexParameteri(textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+                glTexParameteri(textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+            } else {
+                glBindTexture(textureTarget, textureID);
+            }
+            [context setTextureImageToPixelBuffer: (NSOpenGLPixelBuffer*) pbuffer colorBuffer: GL_FRONT];
+        } else {
+            if( 0 != gl3ShaderProgramName ) {
+                glUseProgram(gl3ShaderProgramName);
+                glActiveTexture(GL_TEXTURE0);
+            }
+            textureTarget = GL_TEXTURE_2D;
+            glBindTexture(textureTarget, textureID);
+        }
+        SYNC_PRINT(" %d gl3Prog %d/%d*>", (int)textureID, (int)gl3ShaderProgramName, (int)glIsProgram (gl3ShaderProgramName));
+
+        if( 0 == vboBufVert ) { // Once: Init Data and Bind to Pointer
+            if( 0 != gl3ShaderProgramName ) {
+                // Install default VAO as required by GL 3.2 core!
+                GLuint vaoBuf = 0;
+                glGenVertexArrays(1, &vaoBuf);
+                glBindVertexArray(vaoBuf);
+
+                // Set texture-unit 0
+                GLint texUnitLoc = glGetUniformLocation (gl3ShaderProgramName, "mgl_Texture0");
+                glUniform1i (texUnitLoc, 0);
+            }
+            glGenBuffers( 1, &vboBufVert );
+            glBindBuffer( GL_ARRAY_BUFFER, vboBufVert );
+            glBufferData( GL_ARRAY_BUFFER, 4 * 2 * sizeof(GLfloat), gl_verts, GL_STATIC_DRAW);
+            if( 0 != gl3ShaderProgramName ) {
+                vertAttrLoc = glGetAttribLocation( gl3ShaderProgramName, "mgl_Vertex" );
+                glVertexAttribPointer( vertAttrLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL );
+            } else {
+                glVertexPointer(2, GL_FLOAT, 0, NULL);
+            }
+
+            glGenBuffers( 1, &vboBufTexCoord );
+            glBindBuffer( GL_ARRAY_BUFFER, vboBufTexCoord );
+            glBufferData( GL_ARRAY_BUFFER, 4 * 2 * sizeof(GLfloat), gl_texCoords, GL_STATIC_DRAW);
+            if( 0 != gl3ShaderProgramName ) {
+                texCoordAttrLoc = glGetAttribLocation( gl3ShaderProgramName, "mgl_MultiTexCoord" );
+                glVertexAttribPointer( texCoordAttrLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL );
+            } else {
+                glTexCoordPointer(2, GL_FLOAT, 0, NULL);
+            }
+        }
+        if( texSizeChanged ) {
+            glBindBuffer( GL_ARRAY_BUFFER, vboBufTexCoord );
+            glBufferSubData( GL_ARRAY_BUFFER, 0, 4 * 2 * sizeof(GLfloat), gl_texCoords);
+            if( 0 != gl3ShaderProgramName ) {
+                glVertexAttribPointer( texCoordAttrLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL );
+            } else {
+                glTexCoordPointer(2, GL_FLOAT, 0, NULL);
+            }
+        }
+        if( 0 != gl3ShaderProgramName ) {
+            glEnableVertexAttribArray( vertAttrLoc );
+            glEnableVertexAttribArray( texCoordAttrLoc );
+        } else {
+            glEnable(textureTarget);
+           
+            glEnableClientState(GL_VERTEX_ARRAY);
+            glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+        }
+
+        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+           
+        if( 0 != gl3ShaderProgramName ) {
+            glDisableVertexAttribArray( vertAttrLoc );
+            glDisableVertexAttribArray( texCoordAttrLoc );
+            glUseProgram(0);
+        } else {
+            glDisableClientState(GL_VERTEX_ARRAY);
+            glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+           
+            glDisable(textureTarget);
+        }
+
+        glBindTexture(textureTarget, 0);
+
+        [context clearDrawable];
+
+        [super drawInOpenGLContext: context pixelFormat: pixelFormat forLayerTime: timeInterval displayTime: timeStamp];
+
+    } else {
+        // glClear(GL_COLOR_BUFFER_BIT);
+        // glBlitFramebuffer(0, 0, texWidth, texHeight, 
+        //                   0, 0, texWidth, texHeight,
+        //                   GL_COLOR_BUFFER_BIT, GL_NEAREST);
+        SYNC_PRINT(" 0*>");
+    }
+
+    #ifdef DBG_PERF
+        [self tick];
+    #endif
+    shallDraw = NO;
+
+    if( 0 >= swapInterval ) {
+        pthread_cond_signal(&renderSignal); // wake up !vsync
+        SYNC_PRINT("<s>");
+    }
+    SYNC_PRINT("<$>\n");
+    pthread_mutex_unlock(&renderLock);
+}
+
+- (void)pauseAnimation:(Bool)pause
+{
+    DBG_PRINT("MyNSOpenGLLayer::pauseAnimation: %d\n", (int)pause);
+    [self setAsynchronous: NO];
+    if(pause) {
+        if(NULL != displayLink) {
+            #ifdef HAS_CADisplayLink
+                [displayLink setPaused: YES];
+            #else
+                CVDisplayLinkStop(displayLink);
+            #endif
+        }
+    } else {
+        if(NULL != displayLink) {
+            #ifdef HAS_CADisplayLink
+                [displayLink setPaused: NO];
+                [displayLink setFrameInterval: swapInterval];
+            #else
+                CVDisplayLinkStart(displayLink);
+            #endif
+        }
+    }
+    tc = 0;
+    timespec_now(&tStart);
+}
+
+- (void)setSwapInterval:(int)interval
+{
+    /**
+     * v-sync doesn't works w/ NSOpenGLLayer's context .. well :(
+     * Using CVDisplayLink .. see setSwapInterval() below.
+     *
+        GLint si;
+        [context getValues: &si forParameter: NSOpenGLCPSwapInterval];
+        if(si != swapInterval) {
+            DBG_PRINT("MyNSOpenGLLayer::drawInOpenGLContext %p setSwapInterval: %d -> %d\n", self, si, swapInterval);
+            [context setValues: &swapInterval forParameter: NSOpenGLCPSwapInterval];
+        }
+    */
+
+    pthread_mutex_lock(&renderLock);
+    DBG_PRINT("MyNSOpenGLLayer::setSwapInterval.0: %d - displayLink %p\n", interval, displayLink);
+    swapInterval = interval;
+    swapIntervalCounter = 0;
+    pthread_mutex_unlock(&renderLock);
+
+    if(0 < swapInterval) {
+        [self pauseAnimation: NO];
+    } else {
+        [self pauseAnimation: YES];
+    }
+    DBG_PRINT("MyNSOpenGLLayer::setSwapInterval.X: %d\n", interval);
+}
+ 
+-(void)tick
+{
+    tc++;
+    if(tc%60==0) {
+        struct timespec t1, td;
+        timespec_now(&t1);
+        timespec_subtract(&td, &t1, &tStart);
+        long td_ms = timespec_milliseconds(&td);
+        fprintf(stderr, "NSOpenGLLayer: %ld ms / %d frames, %ld ms / frame, %f fps\n",
+            td_ms, tc, td_ms/tc, (tc * 1000.0) / (float)td_ms );
+        fflush(NULL);
+    }
+}
+
+- (void)waitUntilRenderSignal: (long) to_micros
+{
+    BOOL ready = NO;
+    int wr = 0;
+    pthread_mutex_lock(&renderLock);
+    SYNC_PRINT("{W %ld us", to_micros);
+    do {
+        if(0 >= swapInterval) {
+            ready = YES;
+        }
+        if(NO == ready) {
+            #ifdef DBG_SYNC
+                struct timespec t0, t1, td, td2;
+                timespec_now(&t0);
+            #endif
+            if(0 < to_micros) {
+                struct timespec to_abs = lastWaitTime;
+                timespec_addmicros(&to_abs, to_micros);
+                #ifdef DBG_SYNC
+                    timespec_subtract(&td, &to_abs, &t0);
+                    fprintf(stderr, ", (%ld) / ", timespec_milliseconds(&td));
+                #endif
+                wr = pthread_cond_timedwait(&renderSignal, &renderLock, &to_abs);
+                #ifdef DBG_SYNC
+                    timespec_now(&t1);
+                    timespec_subtract(&td, &t1, &t0);
+                    timespec_subtract(&td2, &t1, &lastWaitTime);
+                    fprintf(stderr, "(%ld) / (%ld) ms", timespec_milliseconds(&td), timespec_milliseconds(&td2));
+                #endif
+            } else {
+                pthread_cond_wait (&renderSignal, &renderLock);
+                #ifdef DBG_SYNC
+                    timespec_now(&t1);
+                    timespec_subtract(&td, &t1, &t0);
+                    timespec_subtract(&td2, &t1, &lastWaitTime);
+                    fprintf(stderr, "(%ld) / (%ld) ms", timespec_milliseconds(&td), timespec_milliseconds(&td2));
+                #endif
+            }
+            ready = YES;
+        }
+    } while (NO == ready && 0 == wr) ;
+    SYNC_PRINT("-%d-%d-%d}", shallDraw, wr, ready);
+    timespec_now(&lastWaitTime);
+    pthread_mutex_unlock(&renderLock);
+}
+
+ at end
+
+NSOpenGLLayer* createNSOpenGLLayer(NSOpenGLContext* ctx, int gl3ShaderProgramName, NSOpenGLPixelFormat* fmt, NSOpenGLPixelBuffer* p, uint32_t texID, Bool opaque, int texWidth, int texHeight) {
+  // This simply crashes after dealloc() has been called .. ie. ref-count -> 0 too early ?
+  // However using alloc/init, actual dealloc happens at JAWT destruction, hence too later IMHO.
+  // return [[MyNSOpenGLLayer layer] setupWithContext:ctx pixelFormat: fmt pbuffer: p texIDArg: (GLuint)texID
+  //                                                      opaque: opaque texWidth: texWidth texHeight: texHeight];
+
+  return [[[MyNSOpenGLLayer alloc] init] setupWithContext:ctx gl3ShaderProgramName: (GLuint)gl3ShaderProgramName pixelFormat: fmt pbuffer: p texIDArg: (GLuint)texID
+                                                              opaque: opaque texWidth: texWidth texHeight: texHeight];
+}
+
+void setNSOpenGLLayerSwapInterval(NSOpenGLLayer* layer, int interval) {
+    MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+    [l setSwapInterval: interval];
+    [pool release];
+}
+
+void waitUntilNSOpenGLLayerIsReady(NSOpenGLLayer* layer, long to_micros) {
+    MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+    [l waitUntilRenderSignal: to_micros];
+    [pool release];
+}
+
+void setNSOpenGLLayerNeedsDisplayFBO(NSOpenGLLayer* layer, uint32_t texID) {
+    MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+    Bool shallDraw;
+
+    // volatile OK
+    [l setTextureID: texID];
+    shallDraw = [l isGLSourceValid];
+    l->shallDraw = shallDraw;
+
+    SYNC_PRINT("<! T %d>", (int)shallDraw);
+    if(shallDraw) {
+        if ( [NSThread isMainThread] == YES ) {
+          [l setNeedsDisplay];
+        } else {
+          // don't wait - using doublebuffering
+          [l performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO];
+        }
+    }
+    // DBG_PRINT("MyNSOpenGLLayer::setNSOpenGLLayerNeedsDisplay %p\n", l);
+    [pool release];
+}
+
+void setNSOpenGLLayerNeedsDisplayPBuffer(NSOpenGLLayer* layer, NSOpenGLPixelBuffer* p) {
+    MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+    Bool shallDraw;
+
+    if( NO == [l isSamePBuffer: p] ) {
+        [l setNewPBuffer: p];
+    }
+
+    // volatile OK
+    shallDraw = [l isGLSourceValid];
+    l->shallDraw = shallDraw;
+
+    SYNC_PRINT("<! T %d>", (int)shallDraw);
+    if(shallDraw) {
+        if ( [NSThread isMainThread] == YES ) {
+          [l setNeedsDisplay];
+        } else {
+          // don't wait - using doublebuffering
+          [l performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO];
+        }
+    }
+    // DBG_PRINT("MyNSOpenGLLayer::setNSOpenGLLayerNeedsDisplay %p\n", l);
+    [pool release];
+}
+
+void releaseNSOpenGLLayer(NSOpenGLLayer* layer) {
+    MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+    DBG_PRINT("MyNSOpenGLLayer::releaseNSOpenGLLayer.0: %p\n", l);
+
+    if ( [NSThread isMainThread] == YES ) {
+        [l releaseLayer];
+    } else { 
+        [l performSelectorOnMainThread:@selector(releaseLayer) withObject:nil waitUntilDone:NO];
+    }
+
+    DBG_PRINT("MyNSOpenGLLayer::releaseNSOpenGLLayer.X: %p\n", l);
+    [pool release];
+}
+
diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface-pbuffer.m b/src/jogl/native/macosx/MacOSXWindowSystemInterface-pbuffer.m
deleted file mode 100644
index b81b43e..0000000
--- a/src/jogl/native/macosx/MacOSXWindowSystemInterface-pbuffer.m
+++ /dev/null
@@ -1,494 +0,0 @@
-#import "MacOSXWindowSystemInterface.h"
-#import <QuartzCore/QuartzCore.h>
-#import <pthread.h>
-#include "timespec.h"
-
-// 
-// CADisplayLink only available on iOS >= 3.1, sad, since it's convenient.
-// Use CVDisplayLink otherwise.
-//
-// #define HAS_CADisplayLink 1
-//
-
-// lock/sync debug output
-//
-// #define DBG_SYNC 1
-//
-#ifdef DBG_SYNC
-    // #define SYNC_PRINT(...) NSLog(@ ## __VA_ARGS__)
-    #define SYNC_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
-#else
-    #define SYNC_PRINT(...)
-#endif
-
-// fps debug output
-//
-// #define DBG_PERF 1
-
- at interface MyNSOpenGLLayer: NSOpenGLLayer
-{
- at protected
-    NSOpenGLPixelBuffer* pbuffer;
-    int texWidth;
-    int texHeight;
-    GLuint textureID;
-#ifdef HAS_CADisplayLink
-    CADisplayLink* displayLink;
-#else
-    CVDisplayLinkRef displayLink;
-#endif
-    int tc;
-    struct timespec t0;
- at public
-    struct timespec lastWaitTime;
-    GLint swapInterval;
-    GLint swapIntervalCounter;
-    pthread_mutex_t renderLock;
-    pthread_cond_t renderSignal;
-    BOOL shallDraw;
-}
-
-- (id) setupWithContext: (NSOpenGLContext*) ctx
-       pixelFormat: (NSOpenGLPixelFormat*) pfmt
-       pbuffer: (NSOpenGLPixelBuffer*) p
-       opaque: (Bool) opaque
-       texWidth: (int) texWidth 
-       texHeight: (int) texHeight;
-
-- (void)deallocTex;
-- (void)disableAnimation;
-- (void)releaseLayer;
-- (void)dealloc;
-- (int)getSwapInterval;
-- (void)setSwapInterval:(int)interval;
-- (void)tick;
-
- at end
-
-#ifndef HAS_CADisplayLink
-
-static CVReturn renderMyNSOpenGLLayer(CVDisplayLinkRef displayLink, 
-                                      const CVTimeStamp *inNow, 
-                                      const CVTimeStamp *inOutputTime, 
-                                      CVOptionFlags flagsIn, 
-                                      CVOptionFlags *flagsOut, 
-                                      void *displayLinkContext)
-{
-    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
-    MyNSOpenGLLayer* l = (MyNSOpenGLLayer*)displayLinkContext;
-    pthread_mutex_lock(&l->renderLock);
-    #ifdef DBG_PERF
-        [l tick];
-    #endif
-    if(0 < l->swapInterval) {
-        l->swapIntervalCounter++;
-        if(l->swapIntervalCounter>=l->swapInterval) {
-            l->swapIntervalCounter = 0;
-            pthread_cond_signal(&l->renderSignal);
-            SYNC_PRINT("S");
-        }
-    }
-    pthread_mutex_unlock(&l->renderLock);
-    [pool release];
-    return kCVReturnSuccess;
-}
-
-#endif
-
- at implementation MyNSOpenGLLayer
-
-- (id) setupWithContext: (NSOpenGLContext*) _ctx
-       pixelFormat: (NSOpenGLPixelFormat*) _fmt
-       pbuffer: (NSOpenGLPixelBuffer*) p
-       opaque: (Bool) opaque
-       texWidth: (int) _texWidth 
-       texHeight: (int) _texHeight;
-{
-    pthread_mutexattr_t renderLockAttr;
-    pthread_mutexattr_init(&renderLockAttr);
-    pthread_mutexattr_settype(&renderLockAttr, PTHREAD_MUTEX_RECURSIVE);
-    pthread_mutex_init(&renderLock, &renderLockAttr); // recursive
-    pthread_cond_init(&renderSignal, NULL); // no attribute
-
-    textureID = 0;
-    swapInterval = 1; // defaults to on (as w/ new GL profiles)
-    swapIntervalCounter = 0;
-    timespec_now(&lastWaitTime);
-    shallDraw = NO;
-    texWidth = _texWidth;
-    texHeight = _texHeight;
-    pbuffer = p;
-    [pbuffer retain];
-
-    {
-        CGRect lRect = CGRectMake(0, 0, texWidth, texHeight);
-        [self setFrame:lRect];
-
-        // no animations for add/remove/swap sublayers etc 
-        // doesn't work: [self removeAnimationForKey: kCAOnOrderIn, kCAOnOrderOut, kCATransition]
-        [self removeAllAnimations];
-    }
-
-    // instantiate a deactivated displayLink
-#ifdef HAS_CADisplayLink
-    displayLink = [[CVDisplayLink displayLinkWithTarget:self selector:@selector(setNeedsDisplay)] retain];
-    [displayLink setPaused: YES];
-#else
-    CVReturn cvres;
-    {
-        int allDisplaysMask = 0;
-        int virtualScreen, accelerated, displayMask;
-        for (virtualScreen = 0; virtualScreen < [_fmt  numberOfVirtualScreens]; virtualScreen++) {
-            [_fmt getValues:&displayMask forAttribute:NSOpenGLPFAScreenMask forVirtualScreen:virtualScreen];
-            [_fmt getValues:&accelerated forAttribute:NSOpenGLPFAAccelerated forVirtualScreen:virtualScreen];
-            if (accelerated) {
-                allDisplaysMask |= displayMask;
-            }
-        }
-        cvres = CVDisplayLinkCreateWithOpenGLDisplayMask(allDisplaysMask, &displayLink);
-        if(kCVReturnSuccess != cvres) {
-            DBG_PRINT("MyNSOpenGLLayer::init %p, CVDisplayLinkCreateWithOpenGLDisplayMask %X failed: %d\n", self, allDisplaysMask, cvres);
-            displayLink = NULL;
-        }
-    }
-    if(NULL != displayLink) {
-        cvres = CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(displayLink, [_ctx CGLContextObj], [_fmt CGLPixelFormatObj]);
-        if(kCVReturnSuccess != cvres) {
-            DBG_PRINT("MyNSOpenGLLayer::init %p, CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext failed: %d\n", self, cvres);
-            displayLink = NULL;
-        }
-    }
-    if(NULL != displayLink) {
-        cvres = CVDisplayLinkSetOutputCallback(displayLink, renderMyNSOpenGLLayer, self);
-        if(kCVReturnSuccess != cvres) {
-            DBG_PRINT("MyNSOpenGLLayer::init %p, CVDisplayLinkSetOutputCallback failed: %d\n", self, cvres);
-            displayLink = NULL;
-        }
-    }
-    if(NULL != displayLink) {
-        CVDisplayLinkStop(displayLink);
-    }
-#endif
-    [self setAsynchronous: YES];
-
-    [self setNeedsDisplayOnBoundsChange: YES];
-
-    [self setOpaque: opaque ? YES : NO];
-
-    CGRect lRect = [self frame];
-    DBG_PRINT("MyNSOpenGLLayer::init %p, ctx %p, pfmt %p, pbuffer %p, opaque %d, pbuffer %dx%d -> tex %dx%d, frame: %lf/%lf %lfx%lf (refcnt %d)\n", 
-        self, _ctx, _fmt, pbuffer, opaque, [pbuffer pixelsWide], [pbuffer pixelsHigh], texWidth, texHeight,
-        lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height, (int)[self retainCount]);
-    return self;
-}
-
-- (void)disableAnimation
-{
-    DBG_PRINT("MyNSOpenGLLayer::disableAnimation: %p (refcnt %d) - displayLink %p\n", self, (int)[self retainCount], displayLink);
-    pthread_mutex_lock(&renderLock);
-    [self setAsynchronous: NO];
-    if(NULL != displayLink) {
-#ifdef HAS_CADisplayLink
-        [displayLink setPaused: YES];
-        [displayLink release];
-#else
-        CVDisplayLinkStop(displayLink);
-        CVDisplayLinkRelease(displayLink);
-#endif
-        displayLink = NULL;
-    }
-    pthread_mutex_unlock(&renderLock);
-}
-
-- (void)deallocTex
-{
-    pthread_mutex_lock(&renderLock);
-    NSOpenGLContext* context = [self openGLContext];
-    DBG_PRINT("MyNSOpenGLLayer::deallocTex %p (refcnt %d) - context %p, pbuffer %p\n", self, (int)[self retainCount], context, pbuffer);
-    if(NULL != pbuffer) {
-        if(NULL!=context) {
-            [context makeCurrentContext];
-            if(0 != textureID) {
-                glDeleteTextures(1, &textureID);
-                textureID = 0;
-            }
-            [context clearDrawable];
-        }
-        [pbuffer release];
-        pbuffer = NULL;
-    }
-    pthread_mutex_unlock(&renderLock);
-}
-
-- (void)releaseLayer
-{
-    DBG_PRINT("MyNSOpenGLLayer::releaseLayer.0: %p (refcnt %d)\n", self, (int)[self retainCount]);
-    pthread_mutex_lock(&renderLock);
-    [self disableAnimation];
-    [self deallocTex];
-    [self release];
-    DBG_PRINT("MyNSOpenGLLayer::releaseLayer.X: %p (refcnt %d)\n", self, (int)[self retainCount]);
-    pthread_mutex_unlock(&renderLock);
-}
-
-- (void)dealloc
-{
-    DBG_PRINT("MyNSOpenGLLayer::dealloc.0 %p (refcnt %d)\n", self, (int)[self retainCount]);
-    // NSLog(@"MyNSOpenGLLayer::dealloc: %@",[NSThread callStackSymbols]);
-
-    [self disableAnimation];
-    [self deallocTex];
-    pthread_cond_destroy(&renderSignal);
-    pthread_mutex_destroy(&renderLock);
-    [super dealloc];
-    DBG_PRINT("MyNSOpenGLLayer::dealloc.X %p\n", self);
-}
-
-- (BOOL)canDrawInOpenGLContext:(NSOpenGLContext *)context pixelFormat:(NSOpenGLPixelFormat *)pixelFormat 
-        forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp
-{
-    // assume both methods 'canDrawInOpenGLContext' and 'drawInOpenGLContext' 
-    // are called from the same thread subsequently
-    pthread_mutex_lock(&renderLock);
-    Bool res = NULL != pbuffer && YES == shallDraw;
-    if(!res) {
-        SYNC_PRINT("0");
-        pthread_mutex_unlock(&renderLock);
-    } else {
-        SYNC_PRINT("1");
-    }
-    return res;
-}
-
-- (void)drawInOpenGLContext:(NSOpenGLContext *)context pixelFormat:(NSOpenGLPixelFormat *)pixelFormat 
-        forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp
-{
-    [context makeCurrentContext];
-   
-    GLenum textureTarget = [pbuffer textureTarget];
-    GLfloat texCoordWidth, texCoordHeight;
-    {
-        GLsizei pwidth = [pbuffer pixelsWide];
-        GLsizei pheight = [pbuffer pixelsHigh];
-        texCoordWidth  = textureTarget == GL_TEXTURE_2D ? (GLfloat)pwidth /(GLfloat)texWidth  : pwidth;
-        texCoordHeight = textureTarget == GL_TEXTURE_2D ? (GLfloat)pheight/(GLfloat)texHeight : pheight;
-    }
-    Bool texCreated = 0 == textureID;
-   
-    if(texCreated) {
-        glGenTextures(1, &textureID);
-
-        CGRect lRect = [self frame];
-        DBG_PRINT("MyNSOpenGLLayer::drawInOpenGLContext %p, pbuffer %p %dx%d -> tex %dx%d [%fx%f] id 0x%X target 0x%X, frame: %lf/%lf %lfx%lf (refcnt %d)\n", 
-            self, pbuffer, [pbuffer pixelsWide], [pbuffer pixelsHigh], texWidth, texHeight, texCoordWidth, texCoordHeight, textureID, textureTarget,
-            lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height, (int)[self retainCount]);
-    }
-
-    glBindTexture(textureTarget, textureID);
-
-    /**
-    if(texCreated) {
-      // proper tex size setup
-      glTexImage2D(textureTarget, 0, GL_RGB, texWidth, texHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
-    } */
-
-    [context setTextureImageToPixelBuffer: pbuffer colorBuffer: GL_FRONT];
-
-    glTexParameteri(textureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    glTexParameteri(textureTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-    glTexParameteri(textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-    glTexParameteri(textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-   
-    glEnable(textureTarget);
-   
-    static GLfloat verts[] = {
-    -1.0, -1.0,
-    -1.0,  1.0,
-     1.0,  1.0,
-     1.0, -1.0
-    };
-   
-    GLfloat tex[] = {
-     0.0,           0.0,
-     0.0,           texCoordHeight,
-     texCoordWidth, texCoordHeight,
-     texCoordWidth, 0.0
-    };
-   
-    glEnableClientState(GL_VERTEX_ARRAY);
-    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-    glVertexPointer(2, GL_FLOAT, 0, verts);
-    glTexCoordPointer(2, GL_FLOAT, 0, tex);
-   
-    glDrawArrays(GL_QUADS, 0, 4);
-   
-    glDisableClientState(GL_VERTEX_ARRAY);
-    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-   
-    glDisable(textureTarget);
-    glBindTexture(textureTarget, 0);
-   
-    [super drawInOpenGLContext: context pixelFormat: pixelFormat forLayerTime: timeInterval displayTime: timeStamp];
-    shallDraw = NO;
-    if(0 >= swapInterval) {
-        pthread_cond_signal(&renderSignal); // just to wake up
-        SYNC_PRINT("s");
-    }
-    SYNC_PRINT("$");
-    pthread_mutex_unlock(&renderLock);
-}
-
-- (int)getSwapInterval
-{
-    return swapInterval;
-}
-
-- (void)setSwapInterval:(int)interval
-{
-    /**
-     * v-sync doesn't works w/ NSOpenGLLayer's context .. well :(
-     * Using CVDisplayLink .. see setSwapInterval() below.
-     *
-        GLint si;
-        [context getValues: &si forParameter: NSOpenGLCPSwapInterval];
-        if(si != swapInterval) {
-            DBG_PRINT("MyNSOpenGLLayer::drawInOpenGLContext %p setSwapInterval: %d -> %d\n", self, si, swapInterval);
-            [context setValues: &swapInterval forParameter: NSOpenGLCPSwapInterval];
-        }
-    } */
-
-    pthread_mutex_lock(&renderLock);
-    DBG_PRINT("MyNSOpenGLLayer::setSwapInterval.0: %d - displayLink %p\n", interval, displayLink);
-    swapInterval = interval;
-    swapIntervalCounter = 0;
-    pthread_mutex_unlock(&renderLock);
-
-    if(NULL!=displayLink) {
-        if(0 < swapInterval) {
-            tc = 0;
-            timespec_now(&t0);
-
-            [self setAsynchronous: NO];
-            #ifdef HAS_CADisplayLink
-                [displayLink setPaused: NO];
-                [displayLink setFrameInterval: interval];
-            #else
-                DBG_PRINT("MyNSOpenGLLayer::setSwapInterval.1.b.1\n");
-                CVDisplayLinkStart(displayLink);
-                DBG_PRINT("MyNSOpenGLLayer::setSwapInterval.1.b.X\n");
-            #endif
-        } else {
-            #ifdef HAS_CADisplayLink
-                [displayLink setPaused: YES];
-            #else
-                DBG_PRINT("MyNSOpenGLLayer::setSwapInterval.0.b.1\n");
-                CVDisplayLinkStop(displayLink);
-                DBG_PRINT("MyNSOpenGLLayer::setSwapInterval.0.b.X\n");
-            #endif
-            [self setAsynchronous: YES];
-        }
-    }
-    DBG_PRINT("MyNSOpenGLLayer::setSwapInterval.X: %d\n", interval);
-}
-
--(void)tick
-{
-    tc++;
-    if(tc%60==0) {
-        struct timespec t1, td;
-        timespec_now(&t1);
-        timespec_subtract(&td, &t1, &t0);
-        long td_ms = timespec_milliseconds(&td);
-        fprintf(stderr, "NSOpenGLLayer: %ld ms / %d frames, %ld ms / frame, %f fps\n",
-            td_ms, tc, td_ms/tc, (tc * 1000.0) / (float)td_ms );
-        fflush(NULL);
-    }
-}
-
- at end
-
-NSOpenGLLayer* createNSOpenGLLayer(NSOpenGLContext* ctx, NSOpenGLPixelFormat* fmt, NSOpenGLPixelBuffer* p, Bool opaque, int texWidth, int texHeight) {
-  // This simply crashes after dealloc() has been called .. ie. ref-count -> 0 too early ?
-  // However using alloc/init, actual dealloc happens at JAWT destruction, hence too later IMHO.
-  // return [[MyNSOpenGLLayer layer] setupWithContext:ctx pixelFormat: fmt pbuffer: p opaque: opaque texWidth: texWidth texHeight: texHeight];
-
-  return [[[MyNSOpenGLLayer alloc] init] setupWithContext:ctx pixelFormat: fmt pbuffer: p opaque: opaque texWidth: texWidth texHeight: texHeight];
-}
-
-void setNSOpenGLLayerSwapInterval(NSOpenGLLayer* layer, int interval) {
-  MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
-  [l setSwapInterval: interval];
-}
-
-void waitUntilNSOpenGLLayerIsReady(NSOpenGLLayer* layer, long to_micros) {
-    MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
-    BOOL ready = NO;
-    int wr = 0;
-    pthread_mutex_lock(&l->renderLock);
-    SYNC_PRINT("{");
-    do {
-        if([l getSwapInterval] <= 0) {
-            ready = !l->shallDraw;
-        }
-        if(NO == ready) {
-            if(0 < to_micros) {
-                #ifdef DBG_SYNC
-                    struct timespec t0, t1, td, td2;
-                    timespec_now(&t0);
-                #endif
-                struct timespec to_abs = l->lastWaitTime;
-                timespec_addmicros(&to_abs, to_micros);
-                #ifdef DBG_SYNC
-                    timespec_subtract(&td, &to_abs, &t0);
-                    fprintf(stderr, "(%ld) / ", timespec_milliseconds(&td));
-                #endif
-                wr = pthread_cond_timedwait(&l->renderSignal, &l->renderLock, &to_abs);
-                #ifdef DBG_SYNC
-                    timespec_now(&t1);
-                    timespec_subtract(&td, &t1, &t0);
-                    timespec_subtract(&td2, &t1, &l->lastWaitTime);
-                    fprintf(stderr, "(%ld) / (%ld) ms", timespec_milliseconds(&td), timespec_milliseconds(&td2));
-                #endif
-            } else {
-                pthread_cond_wait (&l->renderSignal, &l->renderLock);
-            }
-            ready = !l->shallDraw;
-        }
-    } while (NO == ready && 0 == wr) ;
-    SYNC_PRINT("-%d}", ready);
-    timespec_now(&l->lastWaitTime);
-    pthread_mutex_unlock(&l->renderLock);
-}
-
-void setNSOpenGLLayerNeedsDisplay(NSOpenGLLayer* layer) {
-    MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
-    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
-    pthread_mutex_lock(&l->renderLock);
-    l->shallDraw = YES;
-    if ( [NSThread isMainThread] == YES ) {
-      [l setNeedsDisplay];
-    } else {
-      // can't wait, otherwise we may deadlock AWT
-      [l performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO];
-    }
-    SYNC_PRINT(".");
-    pthread_mutex_unlock(&l->renderLock);
-    // DBG_PRINT("MyNSOpenGLLayer::setNSOpenGLLayerNeedsDisplay %p\n", l);
-    [pool release];
-}
-
-void releaseNSOpenGLLayer(NSOpenGLLayer* layer) {
-    MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
-    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
-    DBG_PRINT("MyNSOpenGLLayer::releaseNSOpenGLLayer.0: %p\n", l);
-
-    if ( [NSThread isMainThread] == YES ) {
-        [l releaseLayer];
-    } else { 
-        [l performSelectorOnMainThread:@selector(releaseLayer) withObject:nil waitUntilDone:NO];
-    }
-
-    DBG_PRINT("MyNSOpenGLLayer::releaseNSOpenGLLayer.X: %p\n", l);
-    [pool release];
-}
-
diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface.m b/src/jogl/native/macosx/MacOSXWindowSystemInterface.m
index f774f8f..48807ee 100644
--- a/src/jogl/native/macosx/MacOSXWindowSystemInterface.m
+++ b/src/jogl/native/macosx/MacOSXWindowSystemInterface.m
@@ -446,7 +446,7 @@ NSOpenGLPixelFormat* createPixelFormat(int* iattrs, int niattrs, int* ivalues) {
 
   NSOpenGLPixelFormat* fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
   // if(fmt == nil) { fallback to a [NSOpenGLView defaultPixelFormat] crashed (SIGSEGV) on 10.6.7/NV }
-  DBG_PRINT("createPixelFormat.X: pfmt %p\n", fmt);
+  DBG_PRINT("\ncreatePixelFormat.X: pfmt %p\n", fmt);
 
   [pool release];
   return fmt;
@@ -503,7 +503,7 @@ NSView* getNSView(NSOpenGLContext* ctx) {
 
 NSOpenGLContext* createContext(NSOpenGLContext* share,
                     NSView* view,
-                    Bool allowIncompleteView,
+                    Bool incompleteView,
                     NSOpenGLPixelFormat* fmt,
                     Bool opaque,
                     int* viewNotReady)
@@ -512,13 +512,13 @@ NSOpenGLContext* createContext(NSOpenGLContext* share,
 
     getRendererInfo();
     
-    DBG_PRINT("createContext.0: share %p, view %p, allowIncompleteView %d, pixfmt %p, opaque %d\n",
-        share, view, (int)allowIncompleteView, fmt, opaque);
+    DBG_PRINT("createContext.0: share %p, view %p, incompleteView %d, pixfmt %p, opaque %d\n",
+        share, view, (int)incompleteView, fmt, opaque);
 
     if (view != nil) {
         Bool viewReady = true;
 
-        if(!allowIncompleteView) {
+        if(!incompleteView) {
             if ([view lockFocusIfCanDraw] == NO) {
                 DBG_PRINT("createContext.1 [view lockFocusIfCanDraw] failed\n");
                 viewReady = false;
@@ -527,7 +527,7 @@ NSOpenGLContext* createContext(NSOpenGLContext* share,
         if(viewReady) {
             NSRect frame = [view frame];
             if ((frame.size.width == 0) || (frame.size.height == 0)) {
-                if(!allowIncompleteView) {
+                if(!incompleteView) {
                     [view unlockFocus];
                 }
                 DBG_PRINT("createContext.2 view.frame size %dx%d\n", (int)frame.size.width, (int)frame.size.height);
@@ -557,8 +557,10 @@ NSOpenGLContext* createContext(NSOpenGLContext* share,
             GLint zeroOpacity = 0;
             [ctx setValues:&zeroOpacity forParameter:NSOpenGLCPSurfaceOpacity];
         }
-        [ctx setView:view];
-        if(!allowIncompleteView) {
+        if(!incompleteView) {
+            DBG_PRINT("createContext.3.0: setView\n");
+            [ctx setView:view];
+            DBG_PRINT("createContext.3.X: setView\n");
             [view unlockFocus];        
         }
       }
@@ -628,7 +630,12 @@ void setContextOpacity(NSOpenGLContext* ctx, int opacity) {
 
 void updateContext(NSOpenGLContext* ctx) {
   NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
-  [ctx update];
+  NSView *nsView = [ctx view];
+  if(NULL != nsView) {
+      DBG_PRINT("updateContext.0: ctx %p, ctx.view %p\n", ctx, nsView);
+      [ctx update];
+      DBG_PRINT("updateContext.X\n");
+  }
   [pool release];
 }
 
@@ -638,7 +645,10 @@ void copyContext(NSOpenGLContext* dest, NSOpenGLContext* src, int mask) {
 
 void* updateContextRegister(NSOpenGLContext* ctx, NSView* view) {
   NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+
+  DBG_PRINT("updateContextRegister.0: ctx %p, view %p\n", ctx, view);
   ContextUpdater *contextUpdater = [[ContextUpdater alloc] initWithContext: ctx view: view];
+  DBG_PRINT("updateContextRegister.X: ctxupd %p\n", contextUpdater);
   [pool release];
   return contextUpdater;
 }
@@ -658,44 +668,62 @@ void updateContextUnregister(void* updater) {
   ContextUpdater *contextUpdater = (ContextUpdater *)updater;
     
   NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+  DBG_PRINT("updateContextUnregister.0: ctxupd %p\n", contextUpdater);
   [contextUpdater release];
+  DBG_PRINT("updateContextUnregister.X\n");
   [pool release];
 }
 
 NSOpenGLPixelBuffer* createPBuffer(int renderTarget, int internalFormat, int width, int height) {
   NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+  DBG_PRINT("createPBuffer.0: renderTarget 0x%x, ifmt 0x%x, %dx%d: \n", renderTarget, internalFormat, width, height);
   NSOpenGLPixelBuffer* pBuffer = [[NSOpenGLPixelBuffer alloc]
                                    initWithTextureTarget:renderTarget
                                    textureInternalFormat:internalFormat
                                    textureMaxMipMapLevel:0
                                    pixelsWide:width
                                    pixelsHigh:height];
+  DBG_PRINT("createPBuffer.X: res %p\n", pBuffer);
   [pool release];
   return pBuffer;
 }
 
 Bool destroyPBuffer(NSOpenGLPixelBuffer* pBuffer) {
   NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+  DBG_PRINT("destroyPBuffer.0: pbuffer %p\n", pBuffer);
   [pBuffer release];
+  DBG_PRINT("destroyPBuffer.X\n");
   [pool release];
   return true;
 }
 
 void setContextPBuffer(NSOpenGLContext* ctx, NSOpenGLPixelBuffer* pBuffer) {
   NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+  DBG_PRINT("setContextPBuffer.0: ctx %p, pbuffer %p\n", ctx, pBuffer);
   [ctx setPixelBuffer: pBuffer
              cubeMapFace: 0
              mipMapLevel: 0
              currentVirtualScreen: [ctx currentVirtualScreen]];
+  DBG_PRINT("setContextPBuffer.X\n");
   [pool release];
 }
 
 void setContextTextureImageToPBuffer(NSOpenGLContext* ctx, NSOpenGLPixelBuffer* pBuffer, GLenum colorBuffer) {
   NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+  DBG_PRINT("setContextTextureImageToPBuffer.0: ctx %p, pbuffer %p, colorBuffer 0x%x\n", ctx, pBuffer, (int)colorBuffer);
   [ctx setTextureImageToPixelBuffer: pBuffer colorBuffer: colorBuffer];
+  DBG_PRINT("setContextTextureImageToPBuffer.X\n");
   [pool release];
 }
 
+Bool isNSOpenGLPixelBuffer(uint64_t object) {
+  NSObject *nsObj = (NSObject*) (intptr_t) object;
+  DBG_PRINT("isNSOpenGLPixelBuffer.0: obj %p\n", object);
+  Bool res = [nsObj isMemberOfClass:[NSOpenGLPixelBuffer class]];
+  DBG_PRINT("isNSOpenGLPixelBuffer.X: res %d\n", (int)res);
+  return res;
+}
+
 #include <mach-o/dyld.h>
 Bool imagesInitialized = false;
 static char libGLStr[] = "/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib";
@@ -746,38 +774,3 @@ void resetGammaRamp() {
   CGDisplayRestoreColorSyncSettings();
 }
 
-/***
- * The following static functions are copied out of NEWT's OSX impl. <src/newt/native/MacWindow.m>
- * May need to push code to NativeWindow, to remove duplication.
- */
-static NSScreen * NewtScreen_getNSScreenByIndex(int screen_idx) {
-    NSArray *screens = [NSScreen screens];
-    if(screen_idx<0) screen_idx=0;
-    if(screen_idx>=[screens count]) screen_idx=0;
-    return (NSScreen *) [screens objectAtIndex: screen_idx];
-}
-static CGDirectDisplayID NewtScreen_getCGDirectDisplayIDByNSScreen(NSScreen *screen) {
-    // Mind: typedef uint32_t CGDirectDisplayID; - however, we assume it's 64bit on 64bit ?!
-    NSDictionary * dict = [screen deviceDescription];
-    NSNumber * val = (NSNumber *) [dict objectForKey: @"NSScreenNumber"];
-    // [NSNumber integerValue] returns NSInteger which is 32 or 64 bit native size
-    return (CGDirectDisplayID) [val integerValue];
-}
-static long GetDictionaryLong(CFDictionaryRef theDict, const void* key) 
-{
-    long value = 0;
-    CFNumberRef numRef;
-    numRef = (CFNumberRef)CFDictionaryGetValue(theDict, key); 
-    if (numRef != NULL)
-        CFNumberGetValue(numRef, kCFNumberLongType, &value);    
-    return value;
-}
-#define CGDDGetModeRefreshRate(mode) GetDictionaryLong((mode), kCGDisplayRefreshRate)
-
-int getScreenRefreshRate(int scrn_idx) {
-    NSScreen *screen = NewtScreen_getNSScreenByIndex(scrn_idx);
-    CGDirectDisplayID display = NewtScreen_getCGDirectDisplayIDByNSScreen(screen);
-    CFDictionaryRef mode = CGDisplayCurrentMode(display);
-    return CGDDGetModeRefreshRate(mode);
-}
-
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/DelegatedUpstreamSurfaceHookMutableSize.java b/src/nativewindow/classes/com/jogamp/nativewindow/DelegatedUpstreamSurfaceHookMutableSize.java
new file mode 100644
index 0000000..22c95f3
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/DelegatedUpstreamSurfaceHookMutableSize.java
@@ -0,0 +1,39 @@
+package com.jogamp.nativewindow;
+
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
+
+public class DelegatedUpstreamSurfaceHookMutableSize extends UpstreamSurfaceHookMutableSize {
+    final UpstreamSurfaceHook upstream;
+
+    /**
+     * @param upstream optional upstream UpstreamSurfaceHook used for {@link #create(ProxySurface)} and {@link #destroy(ProxySurface)}.
+     * @param width initial width
+     * @param height initial height
+     */
+    public DelegatedUpstreamSurfaceHookMutableSize(UpstreamSurfaceHook upstream, int width, int height) {
+        super(width, height);
+        this.upstream = upstream;
+    }
+
+    @Override
+    public final void create(ProxySurface s) {
+        if(null != upstream) {
+            upstream.create(s);
+        }
+    }
+
+    @Override
+    public final void destroy(ProxySurface s) {
+        if(null != upstream) {
+            upstream.destroy(s);
+        }
+    }
+    
+    @Override
+    public String toString() {
+        return getClass().getSimpleName()+"[ "+ width + "x" + height + ", " + upstream + "]";        
+    }
+    
+}
+
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/DelegatedUpstreamSurfaceHookWithSurfaceSize.java b/src/nativewindow/classes/com/jogamp/nativewindow/DelegatedUpstreamSurfaceHookWithSurfaceSize.java
new file mode 100644
index 0000000..85e2458
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/DelegatedUpstreamSurfaceHookWithSurfaceSize.java
@@ -0,0 +1,54 @@
+package com.jogamp.nativewindow;
+
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
+
+public class DelegatedUpstreamSurfaceHookWithSurfaceSize implements UpstreamSurfaceHook {
+    final UpstreamSurfaceHook upstream;
+    final NativeSurface surface;
+
+    /**
+     * @param upstream optional upstream UpstreamSurfaceHook used for {@link #create(ProxySurface)} and {@link #destroy(ProxySurface)}.
+     * @param surface mandatory {@link NativeSurface} used for {@link #getWidth(ProxySurface)} and {@link #getHeight(ProxySurface)}
+     */
+    public DelegatedUpstreamSurfaceHookWithSurfaceSize(UpstreamSurfaceHook upstream, NativeSurface surface) {
+        this.upstream = upstream;
+        this.surface = surface;
+        if(null == surface) {
+            throw new IllegalArgumentException("given surface is null");
+        }
+    }
+
+    @Override
+    public final void create(ProxySurface s) {
+        if(null != upstream) {
+            upstream.create(s);
+        }
+    }
+
+    @Override
+    public final void destroy(ProxySurface s) {
+        if(null != upstream) {
+            upstream.destroy(s);
+        }
+    }
+
+    @Override
+    public final int getWidth(ProxySurface s) {
+        return surface.getWidth();
+    }
+
+    @Override
+    public final int getHeight(ProxySurface s) {
+        return surface.getHeight();
+    }      
+    
+    @Override
+    public String toString() {
+        final String us_s = null != surface ? ( surface.getClass().getName() + ": 0x" + Long.toHexString(surface.getSurfaceHandle()) + " " +surface.getWidth() + "x" + surface.getHeight() ) : "nil";        
+        return getClass().getSimpleName()+"["+upstream+", "+us_s+"]";
+    }
+    
+}
+
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/UpstreamSurfaceHookMutableSize.java b/src/nativewindow/classes/com/jogamp/nativewindow/UpstreamSurfaceHookMutableSize.java
new file mode 100644
index 0000000..29c540a
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/UpstreamSurfaceHookMutableSize.java
@@ -0,0 +1,45 @@
+package com.jogamp.nativewindow;
+
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
+
+public class UpstreamSurfaceHookMutableSize implements UpstreamSurfaceHook.MutableSize {
+    int width, height;
+
+    /**
+     * @param width initial width
+     * @param height initial height
+     */
+    public UpstreamSurfaceHookMutableSize(int width, int height) {
+        this.width = width;
+        this.height = height;
+    }
+
+    @Override
+    public final void setSize(int width, int height) {
+        this.width = width;
+        this.height = height;        
+    }
+    
+    @Override
+    public final int getWidth(ProxySurface s) {
+        return width;
+    }
+
+    @Override
+    public final int getHeight(ProxySurface s) {
+        return height;
+    }
+    @Override
+    public void create(ProxySurface s) { /* nop */ }
+
+    @Override
+    public void destroy(ProxySurface s) { /* nop */ }
+    
+    @Override
+    public String toString() {
+        return getClass().getSimpleName()+"[ "+ 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 d4b927c..a62d08c 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java
@@ -39,12 +39,14 @@ package com.jogamp.nativewindow.awt;
 
 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.applet.Applet;
 import javax.media.nativewindow.AbstractGraphicsConfiguration;
 import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.CapabilitiesImmutable;
 import javax.media.nativewindow.NativeSurface;
 import javax.media.nativewindow.NativeWindow;
 import javax.media.nativewindow.NativeWindowException;
@@ -110,21 +112,6 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
     this.offscreenSurfaceLayer = 0;
   }
 
-  @Override
-  public void setShallUseOffscreenLayer(boolean v) {
-      shallUseOffscreenLayer = v;
-  }
-
-  @Override
-  public final boolean getShallUseOffscreenLayer() {
-      return shallUseOffscreenLayer;
-  }
-
-  @Override
-  public final boolean isOffscreenLayerSurfaceEnabled() {
-      return isOffscreenLayerSurface;
-  }
-
   protected synchronized void invalidate() {
     invalidateNative();
     jawt = null;
@@ -136,26 +123,29 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
   }
   protected abstract void invalidateNative();
 
-  protected final void updateBounds(JAWT_Rectangle jawtBounds) {
-    if(DEBUG) {
-        final Rectangle jb = new Rectangle(jawtBounds.getX(), jawtBounds.getY(), jawtBounds.getWidth(), jawtBounds.getHeight());
-        if(!bounds.equals(jb)) {
+  protected final boolean updateBounds(JAWT_Rectangle jawtBounds) {
+    final Rectangle jb = new Rectangle(jawtBounds.getX(), jawtBounds.getY(), jawtBounds.getWidth(), jawtBounds.getHeight());
+    final boolean changed = !bounds.equals(jb);
+    
+    if(changed) {
+        if(DEBUG) {
             System.err.println("JAWTWindow.updateBounds: "+bounds+" -> "+jb);
             Thread.dumpStack();
         }
+        bounds.setX(jawtBounds.getX());
+        bounds.setY(jawtBounds.getY());
+        bounds.setWidth(jawtBounds.getWidth());
+        bounds.setHeight(jawtBounds.getHeight());
+    
+        if(component instanceof Container) {
+            java.awt.Insets contInsets = ((Container)component).getInsets();
+            insets.setLeftWidth(contInsets.left);
+            insets.setRightWidth(contInsets.right);
+            insets.setTopHeight(contInsets.top);
+            insets.setBottomHeight(contInsets.bottom);
+        }
     }
-    bounds.setX(jawtBounds.getX());
-    bounds.setY(jawtBounds.getY());
-    bounds.setWidth(jawtBounds.getWidth());
-    bounds.setHeight(jawtBounds.getHeight());
-
-    if(component instanceof Container) {
-        java.awt.Insets contInsets = ((Container)component).getInsets();
-        insets.setLeftWidth(contInsets.left);
-        insets.setRightWidth(contInsets.right);
-        insets.setTopHeight(contInsets.top);
-        insets.setBottomHeight(contInsets.bottom);
-    }
+    return changed;
   }
 
   /** @return the JAWT_DrawingSurfaceInfo's (JAWT_Rectangle) bounds, updated with lock */
@@ -181,9 +171,29 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
       return jawt;
   }
 
-  /**
-   * {@inheritDoc}
-   */
+  //
+  // OffscreenLayerOption
+  //
+  
+  @Override
+  public void setShallUseOffscreenLayer(boolean v) {
+      shallUseOffscreenLayer = v;
+  }
+
+  @Override
+  public final boolean getShallUseOffscreenLayer() {
+      return shallUseOffscreenLayer;
+  }
+
+  @Override
+  public final boolean isOffscreenLayerSurfaceEnabled() {
+      return isOffscreenLayerSurface;
+  }
+
+  //
+  // OffscreenLayerSurface
+  //
+
   @Override
   public final void attachSurfaceLayer(final long layerHandle) throws NativeWindowException {
       if( !isOffscreenLayerSurfaceEnabled() ) {
@@ -205,9 +215,6 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
   }
   protected abstract void attachSurfaceLayerImpl(final long layerHandle);
 
-  /**
-   * {@inheritDoc}
-   */
   @Override
   public final void detachSurfaceLayer() throws NativeWindowException {
       if( !isOffscreenLayerSurfaceEnabled() ) {
@@ -232,11 +239,21 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
   }
   protected abstract void detachSurfaceLayerImpl(final long layerHandle);
 
+  protected final long getAttachedSurfaceLayer() {
+      return offscreenSurfaceLayer;
+  }
+  
   @Override
   public final boolean isSurfaceLayerAttached() {
       return 0 != offscreenSurfaceLayer;
   }
   
+  @Override
+  public final void setChosenCapabilities(CapabilitiesImmutable caps) {
+      ((MutableGraphicsConfiguration)getGraphicsConfiguration()).setChosenCapabilities(caps);
+      getPrivateGraphicsConfiguration().setChosenCapabilities(caps);      
+  }
+  
   //
   // SurfaceUpdateListener
   //
@@ -381,7 +398,7 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
   public final AbstractGraphicsConfiguration getGraphicsConfiguration() {
     return config.getNativeGraphicsConfiguration();
   }
-
+  
   @Override
   public final long getDisplayHandle() {
     return getGraphicsConfiguration().getScreen().getDevice().getHandle();
@@ -393,13 +410,13 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
   }
 
   @Override
-  public int getWidth() {
+  public final int getWidth() {
     return component.getWidth();
   }
 
   @Override
-  public int getHeight() {
-    return component.getHeight();
+  public final int getHeight() {
+    return component.getHeight();    
   }
 
   //
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java b/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java
index 389949e..b824350 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java
@@ -37,7 +37,7 @@ import javax.media.nativewindow.*;
 /** Encapsulates a graphics device on EGL platforms.
  */
 public class EGLGraphicsDevice extends DefaultGraphicsDevice implements Cloneable {
-    final long nativeDisplayID;
+    final long[] nativeDisplayID = new long[1];
     final EGLDisplayLifecycleCallback eglLifecycleCallback;
 
     /**
@@ -51,9 +51,10 @@ public class EGLGraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
         /**
          * Implementation should issue an <code>EGL.eglGetDisplay(nativeDisplayID)</code>
          * inclusive <code>EGL.eglInitialize(eglDisplayHandle, ..)</code> call.
-         * @param eglDisplayHandle
+         * @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, or <code>0</code> if not successful
          */
-        public long eglGetAndInitDisplay(long nativeDisplayID);
+        public long eglGetAndInitDisplay(long[] nativeDisplayID);
         
         /**
          * Implementation should issue an <code>EGL.eglTerminate(eglDisplayHandle)</code> call.
@@ -66,19 +67,19 @@ public class EGLGraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
      * Note that this is not an open connection, ie no native display handle exist.
      * This constructor exist to setup a default device connection/unit.<br>
      */
-    public EGLGraphicsDevice(String connection, int unitID) {
-        super(NativeWindowFactory.TYPE_EGL, connection, unitID);
-        this.nativeDisplayID = 0 ; // EGL.EGL_DEFAULT_DISPLAY
+    public EGLGraphicsDevice() {
+        super(NativeWindowFactory.TYPE_EGL, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
+        this.nativeDisplayID[0] = 0 ; // EGL.EGL_DEFAULT_DISPLAY
         this.eglLifecycleCallback = null;
     }
 
     public EGLGraphicsDevice(long nativeDisplayID, long eglDisplay, String connection, int unitID, EGLDisplayLifecycleCallback eglLifecycleCallback) {
         super(NativeWindowFactory.TYPE_EGL, connection, unitID, eglDisplay);
-        this.nativeDisplayID = nativeDisplayID;
+        this.nativeDisplayID[0] = nativeDisplayID;
         this.eglLifecycleCallback = eglLifecycleCallback;
     }
     
-    public long getNativeDisplayID() { return nativeDisplayID; }
+    public long getNativeDisplayID() { return nativeDisplayID[0]; }
     
     @Override
     public Object clone() {
@@ -113,7 +114,7 @@ public class EGLGraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
     
     @Override
     public String toString() {
-        return "EGLGraphicsDevice[type EGL, connection "+getConnection()+", unitID "+getUnitID()+", handle 0x"+Long.toHexString(getHandle())+", nativeDisplayID 0x"+Long.toHexString(nativeDisplayID)+"]";
+        return "EGLGraphicsDevice[type EGL, connection "+getConnection()+", unitID "+getUnitID()+", handle 0x"+Long.toHexString(getHandle())+", nativeDisplayID 0x"+Long.toHexString(nativeDisplayID[0])+", eglLifecycleCallback "+(null != eglLifecycleCallback)+"]";
     }
 }
 
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java b/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
index ba07d97..7be747f 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
@@ -83,7 +83,9 @@ public class SWTAccessor {
     static {
         Field f = null;
         
-        if(NativeWindowFactory.TYPE_MACOSX != NativeWindowFactory.getNativeWindowType(false) ) {
+        final String nwt = NativeWindowFactory.getNativeWindowType(false);
+
+        if(NativeWindowFactory.TYPE_MACOSX != nwt ) {
             try {
                 f = Control.class.getField(str_handle);
             } catch (Exception ex) {
@@ -124,7 +126,7 @@ public class SWTAccessor {
         Class<?> c=null;                
         Method m1=null, m2=null, m3=null, m4=null, m5=null;
         Class<?> handleType = swt_uses_long_handles  ? long.class : int.class ;
-        if( NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(false) ) {
+        if( NativeWindowFactory.TYPE_X11 == nwt ) {
             try {
                 c = ReflectionUtil.getClass(str_OS_gtk_class, false, SWTAccessor.class.getClassLoader());
                 m1 = c.getDeclaredMethod(str_gtk_widget_realize, handleType);        
@@ -208,35 +210,38 @@ public class SWTAccessor {
         if( null != OS_gtk_class ) {
             long widgedHandle = callStaticMethodL2L(OS_GTK_WIDGET_WINDOW, handle);
             long displayHandle = callStaticMethodL2L(OS_gdk_x11_drawable_get_xdisplay, widgedHandle);
-            return new X11GraphicsDevice(displayHandle, AbstractGraphicsDevice.DEFAULT_UNIT, false);
+            return new X11GraphicsDevice(displayHandle, AbstractGraphicsDevice.DEFAULT_UNIT, false /* owner */);
         }
-        if( NativeWindowFactory.TYPE_WINDOWS == NativeWindowFactory.getNativeWindowType(false) ) {
+        final String nwt = NativeWindowFactory.getNativeWindowType(false);
+        if( NativeWindowFactory.TYPE_WINDOWS == nwt ) {
             return new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
         }
-        if( NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false) ) {
+        if( NativeWindowFactory.TYPE_MACOSX == nwt ) {
             return new MacOSXGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT);
         }
-        throw new UnsupportedOperationException("n/a for this windowing system: "+NativeWindowFactory.getNativeWindowType(false));
+        throw new UnsupportedOperationException("n/a for this windowing system: "+nwt);
     }
     public static AbstractGraphicsScreen getScreen(AbstractGraphicsDevice device, int screen) {
         if( null != OS_gtk_class ) {
             return new X11GraphicsScreen((X11GraphicsDevice)device, screen);
-        } 
-        if( NativeWindowFactory.TYPE_WINDOWS == NativeWindowFactory.getNativeWindowType(false) ||
-            NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false) ) {
+        }
+        final String nwt = NativeWindowFactory.getNativeWindowType(false);
+        if( NativeWindowFactory.TYPE_WINDOWS == nwt ||
+            NativeWindowFactory.TYPE_MACOSX == nwt ) {
             return new DefaultGraphicsScreen(device, screen);
         }
-        throw new UnsupportedOperationException("n/a for this windowing system: "+NativeWindowFactory.getNativeWindowType(false));        
+        throw new UnsupportedOperationException("n/a for this windowing system: "+nwt);        
     }
     public static int getNativeVisualID(AbstractGraphicsDevice device, long windowHandle) {
         if( null != OS_gtk_class ) {
             return X11Lib.GetVisualIDFromWindow(device.getHandle(), windowHandle);
         }
-        if( NativeWindowFactory.TYPE_WINDOWS == NativeWindowFactory.getNativeWindowType(false) ||
-            NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false) ) {
+        final String nwt = NativeWindowFactory.getNativeWindowType(false);
+        if( NativeWindowFactory.TYPE_WINDOWS == nwt ||
+            NativeWindowFactory.TYPE_MACOSX == nwt ) {
             return VisualIDHolder.VID_UNDEFINED;
         }
-        throw new UnsupportedOperationException("n/a for this windowing system: "+NativeWindowFactory.getNativeWindowType(false));        
+        throw new UnsupportedOperationException("n/a for this windowing system: "+nwt);        
     }
     
     public static long getWindowHandle(Control swtControl) {
@@ -245,11 +250,12 @@ public class SWTAccessor {
             long widgedHandle = callStaticMethodL2L(OS_GTK_WIDGET_WINDOW, handle);
             return callStaticMethodL2L(OS_gdk_x11_drawable_get_xid, widgedHandle);
         }
-        if( NativeWindowFactory.TYPE_WINDOWS == NativeWindowFactory.getNativeWindowType(false) ||
-            NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false) ) {
+        final String nwt = NativeWindowFactory.getNativeWindowType(false);
+        if( NativeWindowFactory.TYPE_WINDOWS == nwt ||
+            NativeWindowFactory.TYPE_MACOSX == nwt ) {
             return handle;
         }
-        throw new UnsupportedOperationException("n/a for this windowing system: "+NativeWindowFactory.getNativeWindowType(false));
+        throw new UnsupportedOperationException("n/a for this windowing system: "+nwt);
     }
     
     public static long newGC(final Control swtControl, final GCData gcData) {
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java
index 5e4d6f4..0f28ca6 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java
@@ -46,6 +46,7 @@ import javax.media.nativewindow.ToolkitLock;
 
 public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneable {
     final boolean handleOwner;
+    final boolean isXineramaEnabled;
 
     /** Constructs a new X11GraphicsDevice corresponding to the given connection and default
      *  {@link javax.media.nativewindow.ToolkitLock} via {@link NativeWindowFactory#getDefaultToolkitLock(String)}.<br>
@@ -56,10 +57,11 @@ public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
     public X11GraphicsDevice(String connection, int unitID) {
         super(NativeWindowFactory.TYPE_X11, connection, unitID);
         handleOwner = false;
+        isXineramaEnabled = false;
     }
 
     /** Constructs a new X11GraphicsDevice corresponding to the given native display handle and default
-     *  {@link javax.media.nativewindow.ToolkitLock} via {@link NativeWindowFactory#createDefaultToolkitLock(String, long)}.
+     *  {@link javax.media.nativewindow.ToolkitLock} via {@link NativeWindowFactory#getDefaultToolkitLock(String, long)}.
      *  @see DefaultGraphicsDevice#DefaultGraphicsDevice(String, String, int, long)
      */
     public X11GraphicsDevice(long display, int unitID, boolean owner) {
@@ -69,11 +71,12 @@ public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
             throw new NativeWindowException("null display");
         }
         handleOwner = owner;
+        isXineramaEnabled = X11Util.XineramaIsEnabled(this);
     }
 
     /**
      * @param display the Display connection
-     * @param locker custom {@link javax.media.nativewindow.ToolkitLock}, eg to force null locking in NEWT
+     * @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(long display, int unitID, ToolkitLock locker, boolean owner) {
@@ -82,13 +85,42 @@ public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
             throw new NativeWindowException("null display");
         }
         handleOwner = owner;
+        isXineramaEnabled = X11Util.XineramaIsEnabled(this);
     }
+    
 
+    private static int getDefaultScreenImpl(long dpy) {
+        return X11Lib.DefaultScreen(dpy);
+    }
+    
+    /**
+     * Returns the default screen number as referenced by the display connection, i.e. 'somewhere:0.1' -> 1
+     * <p>
+     * Implementation uses the XLib macro <code>DefaultScreen(display)</code>.
+     * </p>
+     */
+    public int getDefaultScreen() {
+        final long display = getHandle();
+        if(0==display) {
+            throw new NativeWindowException("null display");
+        }
+        final int ds = getDefaultScreenImpl(display);
+        if(DEBUG) {
+            System.err.println(Thread.currentThread().getName() + " - X11GraphicsDevice.getDefaultDisplay() of "+this+": "+ds+", count "+X11Lib.ScreenCount(display));
+        }
+        return ds;
+    }
+    
     public int getDefaultVisualID() {
-        // It still could be an AWT hold handle ..
         final long display = getHandle();
-        final int scrnIdx = X11Lib.DefaultScreen(display);
-        return X11Lib.DefaultVisualID(display, scrnIdx);
+        if(0==display) {
+            throw new NativeWindowException("null display");
+        }
+        return X11Lib.DefaultVisualID(display, getDefaultScreenImpl(display));
+    }
+    
+    public final boolean isXineramaEnabled() {
+        return isXineramaEnabled;
     }
     
     @Override
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsScreen.java b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsScreen.java
index 5f3c220..2ec6629 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsScreen.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsScreen.java
@@ -33,10 +33,12 @@
 
 package com.jogamp.nativewindow.x11;
 
-import javax.media.nativewindow.*;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.DefaultGraphicsScreen;
+import javax.media.nativewindow.NativeWindowException;
 
 import jogamp.nativewindow.x11.X11Lib;
-import jogamp.nativewindow.x11.X11Util;
 
 /** Encapsulates a screen index on X11
     platforms. Objects of this type are passed to {@link
@@ -48,7 +50,7 @@ public class X11GraphicsScreen extends DefaultGraphicsScreen implements Cloneabl
 
     /** Constructs a new X11GraphicsScreen corresponding to the given native screen index. */
     public X11GraphicsScreen(X11GraphicsDevice device, int screen) {
-        super(device, fetchScreen(device, screen));
+        super(device, device.isXineramaEnabled() ? 0 : screen);
     }
 
     public static AbstractGraphicsScreen createScreenDevice(long display, int screenIdx, boolean owner) {
@@ -61,14 +63,6 @@ public class X11GraphicsScreen extends DefaultGraphicsScreen implements Cloneabl
         return X11Lib.DefaultVisualID(getDevice().getHandle(), getIndex());
     }
     
-    private static int fetchScreen(X11GraphicsDevice device, int screen) {
-        // It still could be an AWT hold handle ..
-        if(X11Util.XineramaIsEnabled(device.getHandle())) {
-            screen = 0; // Xinerama -> 1 screen
-        }
-        return screen;
-    }
-
     public Object clone() {
       return super.clone();
     }
diff --git a/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java
index 756e445..8ecd524 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java
@@ -102,17 +102,24 @@ public interface AbstractGraphicsDevice extends Cloneable {
     public long getHandle();
 
     /**
-     * Optionally locking the device, utilizing eg {@link javax.media.nativewindow.ToolkitLock}.
+     * Optionally locking the device, utilizing eg {@link javax.media.nativewindow.ToolkitLock#lock()}.
      * The lock implementation must be recursive.
      */
     public void lock();
 
     /** 
-     * Optionally unlocking the device, utilizing eg {@link javax.media.nativewindow.ToolkitLock}.
+     * Optionally unlocking the device, utilizing eg {@link javax.media.nativewindow.ToolkitLock#unlock()}.
      * The lock implementation must be recursive.
+     * 
+     * @throws RuntimeException in case the lock is not acquired by this thread.
      */
     public void unlock();
 
+    /**
+     * @throws RuntimeException if current thread does not hold the lock 
+     */
+    public void validateLocked() throws RuntimeException;
+    
     /** 
      * Optionally [re]opening the device if handle is <code>null</code>.
      * <p>
@@ -131,7 +138,7 @@ public interface AbstractGraphicsDevice extends Cloneable {
     /**
      * Optionally closing the device if handle is not <code>null</code>.
      * <p>
-     * The default implementation is a <code>NOP</code>, just setting the handle to <code>null</code>.
+     * The default implementation {@link ToolkitLock#dispose() dispose} it's {@link ToolkitLock} and sets the handle to <code>null</code>.
      * </p>
      * <p>
      * Example implementations like {@link com.jogamp.nativewindow.x11.X11GraphicsDevice} 
diff --git a/src/nativewindow/classes/javax/media/nativewindow/Capabilities.java b/src/nativewindow/classes/javax/media/nativewindow/Capabilities.java
index cb33aec..5795e8c 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/Capabilities.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/Capabilities.java
@@ -61,6 +61,9 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
 
   // Switch for on- or offscreen
   private boolean onscreen  = true;
+  
+  // offscreen bitmap mode
+  private boolean isBitmap  = false;
 
   /** Creates a Capabilities object. All attributes are in a default
       state.
@@ -71,7 +74,7 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
   public Object cloneMutable() {
     return clone();
   }
-
+  
   @Override
   public Object clone() {
     try {
@@ -81,10 +84,32 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
     }
   }
 
+  /**
+   * Copies all {@link Capabilities} values 
+   * from <code>source</code> into this instance.
+   * @return this instance
+   */
+  public Capabilities copyFrom(CapabilitiesImmutable other) {
+    redBits = other.getRedBits();
+    greenBits = other.getGreenBits();
+    blueBits = other.getBlueBits();
+    alphaBits = other.getAlphaBits();
+    backgroundOpaque = other.isBackgroundOpaque();
+    onscreen = other.isOnscreen();
+    isBitmap = other.isBitmap();
+    transparentValueRed = other.getTransparentRedValue();
+    transparentValueGreen = other.getTransparentGreenValue();
+    transparentValueBlue = other.getTransparentBlueValue();
+    transparentValueAlpha = other.getTransparentAlphaValue();
+    return this;
+  }
+  
   @Override
   public int hashCode() {
     // 31 * x == (x << 5) - x
     int hash = 31 + this.redBits;
+    hash = ((hash << 5) - hash) + ( this.onscreen ? 1 : 0 );
+    hash = ((hash << 5) - hash) + ( this.isBitmap ? 1 : 0 );
     hash = ((hash << 5) - hash) + this.greenBits;
     hash = ((hash << 5) - hash) + this.blueBits;
     hash = ((hash << 5) - hash) + this.alphaBits;
@@ -93,7 +118,6 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
     hash = ((hash << 5) - hash) + this.transparentValueGreen;
     hash = ((hash << 5) - hash) + this.transparentValueBlue;
     hash = ((hash << 5) - hash) + this.transparentValueAlpha;
-    hash = ((hash << 5) - hash) + ( this.onscreen ? 1 : 0 );
     return hash;
   }
 
@@ -109,12 +133,13 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
                   other.getBlueBits()==blueBits &&
                   other.getAlphaBits()==alphaBits &&
                   other.isBackgroundOpaque()==backgroundOpaque &&
-                  other.isOnscreen()==onscreen;
-    if(!backgroundOpaque) {
-     res = res && other.getTransparentRedValue()==transparentValueRed &&
-                  other.getTransparentGreenValue()==transparentValueGreen &&
-                  other.getTransparentBlueValue()==transparentValueBlue &&
-                  other.getTransparentAlphaValue()==transparentValueAlpha;
+                  other.isOnscreen()==onscreen &&
+                  other.isBitmap()==isBitmap;
+    if(res && !backgroundOpaque) {
+     res = other.getTransparentRedValue()==transparentValueRed &&
+           other.getTransparentGreenValue()==transparentValueGreen &&
+           other.getTransparentBlueValue()==transparentValueBlue &&
+           other.getTransparentAlphaValue()==transparentValueAlpha;
     }
 
     return res;
@@ -158,9 +183,6 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
       }
   }
 
-  /** Returns the number of bits requested for the color buffer's red
-      component. On some systems only the color depth, which is the
-      sum of the red, green, and blue bits, is considered. */
   @Override
   public final int getRedBits() {
     return redBits;
@@ -173,9 +195,6 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
     this.redBits = redBits;
   }
 
-  /** Returns the number of bits requested for the color buffer's
-      green component. On some systems only the color depth, which is
-      the sum of the red, green, and blue bits, is considered. */
   @Override
   public final int getGreenBits() {
     return greenBits;
@@ -188,9 +207,6 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
     this.greenBits = greenBits;
   }
 
-  /** Returns the number of bits requested for the color buffer's blue
-      component. On some systems only the color depth, which is the
-      sum of the red, green, and blue bits, is considered. */
   @Override
   public final int getBlueBits() {
     return blueBits;
@@ -203,9 +219,6 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
     this.blueBits = blueBits;
   }
 
-  /** Returns the number of bits requested for the color buffer's
-      alpha component. On some systems only the color depth, which is
-      the sum of the red, green, and blue bits, is considered. */
   @Override
   public final int getAlphaBits() {
     return alphaBits;
@@ -228,10 +241,7 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
   }
 
   /**
-   * Defaults to true, ie. opaque surface.
-   * <p>
-   * On supported platforms, setting opaque to false may result in a translucent surface. </p>
-   *
+   * Sets whether the surface shall be opaque or translucent.
    * <p>
    * Platform implementations may need an alpha component in the surface (eg. Windows),
    * or expect pre-multiplied alpha values (eg. X11/XRender).<br>
@@ -240,16 +250,9 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
    * Please note that in case alpha is required on the platform the
    * clear color shall have an alpha lower than 1.0 to allow anything shining through.
    * </p>
-   *
    * <p>
    * Mind that translucency may cause a performance penalty
-   * due to the composite work required by the window manager.</p>
-   *
-   * <p>
-   * The platform implementation may utilize the transparency RGBA values.<br>
-   * This is true for the original GLX transparency specification, which is no more used today.<br>
-   * Actually these values are currently not used by any implementation,
-   * so we may mark them deprecated soon, if this doesn't change.<br>
+   * due to the composite work required by the window manager.
    * </p>
    */
   public void setBackgroundOpaque(boolean opaque) {
@@ -259,56 +262,65 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
       }
   }
 
-  /** Indicates whether the background of this OpenGL context should
-      be considered opaque. Defaults to true.
-
-      @see #setBackgroundOpaque
-  */
   @Override
   public final boolean isBackgroundOpaque() {
     return backgroundOpaque;
   }
 
-  /** Sets whether the drawable surface supports onscreen.
-      Defaults to true.
-  */
+  /**
+   * Sets whether the surface shall be on- or offscreen.
+   * <p>
+   * Defaults to true.
+   * </p>
+   * <p>
+   * If requesting an offscreen surface without further selection of it's mode, 
+   * e.g. FBO, Pbuffer or {@link #setBitmap(boolean) bitmap},
+   * the implementation will choose the best available offscreen mode.
+   * </p>
+   * @param onscreen
+   */
   public void setOnscreen(boolean onscreen) {
     this.onscreen=onscreen;
   }
 
-  /** Indicates whether the drawable surface is onscreen.
-      Defaults to true.
-  */
   @Override
   public final boolean isOnscreen() {
     return onscreen;
   }
 
-  /** Gets the transparent red value for the frame buffer configuration.
-    * This value is undefined if {@link #isBackgroundOpaque()} equals true.
-    * @see #setTransparentRedValue
-    */
+  /**
+   * Requesting offscreen bitmap mode.
+   * <p>
+   * If enabled this method also invokes {@link #setOnscreen(int) setOnscreen(false)}.
+   * </p>
+   * <p>
+   * Defaults to false.
+   * </p>
+   * <p>
+   * Requesting offscreen bitmap mode disables the offscreen auto selection.
+   * </p>
+   */
+  public void setBitmap(boolean enable) {
+    if(enable) {
+      setOnscreen(false);
+    }
+    isBitmap = enable;
+  }
+  
+  @Override
+  public boolean isBitmap() {
+    return isBitmap;      
+  }
+  
   @Override
   public final int getTransparentRedValue() { return transparentValueRed; }
 
-  /** Gets the transparent green value for the frame buffer configuration.
-    * This value is undefined if {@link #isBackgroundOpaque()} equals true.
-    * @see #setTransparentGreenValue
-    */
   @Override
   public final int getTransparentGreenValue() { return transparentValueGreen; }
 
-  /** Gets the transparent blue value for the frame buffer configuration.
-    * This value is undefined if {@link #isBackgroundOpaque()} equals true.
-    * @see #setTransparentBlueValue
-    */
   @Override
   public final int getTransparentBlueValue() { return transparentValueBlue; }
 
-  /** Gets the transparent alpha value for the frame buffer configuration.
-    * This value is undefined if {@link #isBackgroundOpaque()} equals true.
-    * @see #setTransparentAlphaValue
-    */
   @Override
   public final int getTransparentAlphaValue() { return transparentValueAlpha; }
 
@@ -342,32 +354,58 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
 
   @Override
   public StringBuilder toString(StringBuilder sink) {
+      return toString(sink, true);
+  }
+  
+  /** Returns a textual representation of this Capabilities
+      object. */
+  @Override
+  public String toString() {
+    StringBuilder msg = new StringBuilder();
+    msg.append("Caps[");
+    toString(msg);
+    msg.append("]");
+    return msg.toString();
+  }
+  
+  /** Return a textual representation of this object's on/off screen state. Use the given StringBuffer [optional]. */
+  protected StringBuilder onoffScreenToString(StringBuilder sink) {
     if(null == sink) {
         sink = new StringBuilder();
     }
     if(onscreen) {
         sink.append("on-scr");
     } else {
-        sink.append("offscr");
+        sink.append("offscr[");
+    }
+    if(isBitmap) {
+        sink.append("bitmap");
+    } else if(onscreen) {
+        sink.append(".");        // no additional off-screen modes besides on-screen
+    } else {
+        sink.append("auto-cfg"); // auto-config off-screen mode            
+    }
+    sink.append("]");    
+    
+    return sink;
+  }
+  
+  protected StringBuilder toString(StringBuilder sink, boolean withOnOffScreen) {  
+    if(null == sink) {
+        sink = new StringBuilder();
     }
-    sink.append(", rgba 0x").append(toHexString(redBits)).append("/").append(toHexString(greenBits)).append("/").append(toHexString(blueBits)).append("/").append(toHexString(alphaBits));
+    sink.append("rgba 0x").append(toHexString(redBits)).append("/").append(toHexString(greenBits)).append("/").append(toHexString(blueBits)).append("/").append(toHexString(alphaBits));
     if(backgroundOpaque) {
         sink.append(", opaque");
     } else {
         sink.append(", trans-rgba 0x").append(toHexString(transparentValueRed)).append("/").append(toHexString(transparentValueGreen)).append("/").append(toHexString(transparentValueBlue)).append("/").append(toHexString(transparentValueAlpha));
     }
+    if(withOnOffScreen) {
+        sink.append(", ");
+        onoffScreenToString(sink);
+    }
     return sink;
   }
+  
   protected final String toHexString(int val) { return Integer.toHexString(val); }
-
-  /** Returns a textual representation of this Capabilities
-      object. */
-  @Override
-  public String toString() {
-    StringBuilder msg = new StringBuilder();
-    msg.append("Caps[");
-    toString(msg);
-    msg.append("]");
-    return msg.toString();
-  }
 }
diff --git a/src/nativewindow/classes/javax/media/nativewindow/CapabilitiesImmutable.java b/src/nativewindow/classes/javax/media/nativewindow/CapabilitiesImmutable.java
index b984a46..b801ab4 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/CapabilitiesImmutable.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/CapabilitiesImmutable.java
@@ -39,45 +39,66 @@ import com.jogamp.common.type.WriteCloneable;
 public interface CapabilitiesImmutable extends VisualIDHolder, WriteCloneable, Comparable<CapabilitiesImmutable> {
 
     /**
-     * Returns the number of bits requested for the color buffer's red
+     * Returns the number of bits for the color buffer's red
      * component. On some systems only the color depth, which is the sum of the
      * red, green, and blue bits, is considered.
      */
     int getRedBits();
 
     /**
-     * Returns the number of bits requested for the color buffer's green
+     * Returns the number of bits for the color buffer's green
      * component. On some systems only the color depth, which is the sum of the
      * red, green, and blue bits, is considered.
      */
     int getGreenBits();
 
     /**
-     * Returns the number of bits requested for the color buffer's blue
+     * Returns the number of bits for the color buffer's blue
      * component. On some systems only the color depth, which is the sum of the
      * red, green, and blue bits, is considered.
      */
     int getBlueBits();
 
     /**
-     * Returns the number of bits requested for the color buffer's alpha
+     * Returns the number of bits for the color buffer's alpha
      * component. On some systems only the color depth, which is the sum of the
      * red, green, and blue bits, is considered.
      */
     int getAlphaBits();
 
     /**
-     * Indicates whether the background of this OpenGL context should be
-     * considered opaque. Defaults to true.
+     * Returns whether an opaque or translucent surface is requested, supported or chosen.
+     * <p>
+     * Default is true, i.e. opaque.
+     * </p> 
      */
     boolean isBackgroundOpaque();
 
     /**
-     * Indicates whether the drawable surface is onscreen. Defaults to true.
+     * Returns whether an on- or offscreen surface is requested, available or chosen. 
+     * <p>
+     * Default is true, i.e. onscreen.
+     * </p>
+     * <p>
+     * Mind that an capabilities intance w/ <i>available</i> semantics
+     * may show onscreen, but also the offscreen modes FBO, Pbuffer or {@link #setBitmap(boolean) bitmap}.
+     * This is valid, since one native configuration maybe used for either functionality.
+     * </p> 
      */
     boolean isOnscreen();
 
     /**
+     * Returns whether bitmap offscreen mode is requested, available or chosen.
+     * <p>
+     * Default is false.
+     * </p>
+     * <p>
+     * For chosen capabilities, only the selected offscreen surface is set to <code>true</code>.
+     * </p>
+     */
+    boolean isBitmap();
+    
+    /**
      * Gets the transparent red value for the frame buffer configuration. This
      * value is undefined if; equals true.
      */
diff --git a/src/nativewindow/classes/javax/media/nativewindow/DefaultCapabilitiesChooser.java b/src/nativewindow/classes/javax/media/nativewindow/DefaultCapabilitiesChooser.java
index 9d4b112..744c7e6 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/DefaultCapabilitiesChooser.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/DefaultCapabilitiesChooser.java
@@ -68,6 +68,9 @@ import jogamp.nativewindow.Debug;
 public class DefaultCapabilitiesChooser implements CapabilitiesChooser {
   private static final boolean DEBUG = Debug.isPropertyDefined("nativewindow.debug.CapabilitiesChooser", true); 
 
+  private final static int NO_SCORE = -9999999;
+  private final static int COLOR_MISMATCH_PENALTY_SCALE     = 36;
+  
   public int chooseCapabilities(final CapabilitiesImmutable desired,
                                 final List<? extends CapabilitiesImmutable> available,
                                 final int windowSystemRecommendedChoice) {
@@ -92,8 +95,6 @@ public class DefaultCapabilitiesChooser implements CapabilitiesChooser {
 
     // Create score array
     int[] scores = new int[availnum];
-    int NO_SCORE = -9999999;
-    int COLOR_MISMATCH_PENALTY_SCALE     = 36;
     for (int i = 0; i < availnum; i++) {
       scores[i] = NO_SCORE;
     }
@@ -103,6 +104,10 @@ public class DefaultCapabilitiesChooser implements CapabilitiesChooser {
       if (cur == null) {
         continue;
       }
+      if (desired.isOnscreen() && !cur.isOnscreen()) {
+        continue; // requested onscreen, but n/a
+      }
+      
       int score = 0;
       // Compute difference in color depth
       score += (COLOR_MISMATCH_PENALTY_SCALE *
diff --git a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
index 583fde0..9288652 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
@@ -60,7 +60,7 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
 
     /**
      * Create an instance with the system default {@link ToolkitLock}.
-     * gathered via {@link NativeWindowFactory#createDefaultToolkitLock(String, long)}.
+     * gathered via {@link NativeWindowFactory#getDefaultToolkitLock(String, long)}.
      * @param type
      * @param handle
      */
@@ -70,7 +70,7 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
         this.unitID = unitID;
         this.uniqueID = getUniqueID(type, connection, unitID);
         this.handle = handle;
-        this.toolkitLock = NativeWindowFactory.createDefaultToolkitLock(type, handle);
+        this.toolkitLock = NativeWindowFactory.getDefaultToolkitLock(type, handle);
     }
 
     /**
@@ -123,8 +123,10 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
     }
 
     /**
-     * No lock is performed on the graphics device per default,
-     * instead the aggregated recursive {@link ToolkitLock#lock()} is invoked.
+     * {@inheritDoc}
+     * <p>
+     * Locking is perfomed via delegation to {@link ToolkitLock#lock()}, {@link ToolkitLock#unlock()}.
+     * </p>
      *
      * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long)
      * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long, javax.media.nativewindow.ToolkitLock)
@@ -134,9 +136,16 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
         toolkitLock.lock();
     }
 
+    @Override
+    public final void validateLocked() throws RuntimeException {
+        toolkitLock.validateLocked();
+    }
+    
     /** 
-     * No lock is performed on the graphics device per default,
-     * instead the aggregated recursive {@link ToolkitLock#unlock()} is invoked.
+     * {@inheritDoc}
+     * <p>
+     * Locking is perfomed via delegation to {@link ToolkitLock#lock()}, {@link ToolkitLock#unlock()}.
+     * </p>
      *
      * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long)
      * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long, javax.media.nativewindow.ToolkitLock)
@@ -153,6 +162,7 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
 
     @Override
     public boolean close() {
+        toolkitLock.dispose();
         if(0 != handle) {
             handle = 0;
             return true;
@@ -162,7 +172,7 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
 
     @Override
     public String toString() {
-        return getClass().getSimpleName()+"[type "+getType()+", connection "+getConnection()+", unitID "+getUnitID()+", handle 0x"+Long.toHexString(getHandle())+"]";
+        return getClass().getSimpleName()+"[type "+getType()+", connection "+getConnection()+", unitID "+getUnitID()+", handle 0x"+Long.toHexString(getHandle())+", "+toolkitLock+"]";
     }
 
     /**
diff --git a/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java b/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java
index c3fdc67..9694f24 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java
@@ -129,7 +129,7 @@ public abstract class GraphicsConfigurationFactory {
             // well as X11GraphicsDevices in non-AWT situations)
             registerFactory(defaultDeviceCapsType.deviceType, defaultDeviceCapsType.capsType, new DefaultGraphicsConfigurationFactoryImpl());
             
-            if (NativeWindowFactory.TYPE_X11.equals(NativeWindowFactory.getNativeWindowType(true))) {
+            if (NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(true)) {
                 try {
                     ReflectionUtil.callStaticMethod("jogamp.nativewindow.x11.X11GraphicsConfigurationFactory", 
                                                     "registerFactory", null, null, GraphicsConfigurationFactory.class.getClassLoader());                
diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java b/src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java
index cec7d4e..27462ae 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java
@@ -124,8 +124,11 @@ public interface NativeSurface extends SurfaceUpdatedListener {
   /**
    * Provide a mechanism to utilize custom (pre-) swap surface
    * code. This method is called before the render toolkit (e.g. JOGL) 
-   * swaps the buffer/surface. The implementation may itself apply the swapping,
+   * swaps the buffer/surface if double buffering is enabled.
+   * <p> 
+   * The implementation may itself apply the swapping,
    * in which case true shall be returned.
+   * </p>
    *
    * @return true if this method completed swapping the surface,
    *         otherwise false, in which case eg the GLDrawable 
diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
index 6faa989..179610b 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
@@ -33,7 +33,7 @@
 
 package javax.media.nativewindow;
 
-import java.lang.reflect.Constructor;
+import java.io.File;
 import java.lang.reflect.Method;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
@@ -43,6 +43,8 @@ import java.util.Map;
 
 import jogamp.nativewindow.Debug;
 import jogamp.nativewindow.NativeWindowFactoryImpl;
+import jogamp.nativewindow.ToolkitProperties;
+import jogamp.nativewindow.ResourceToolkitLock;
 
 import com.jogamp.common.os.Platform;
 import com.jogamp.common.util.ReflectionUtil;
@@ -56,57 +58,72 @@ import com.jogamp.common.util.ReflectionUtil;
 public abstract class NativeWindowFactory {
     protected static final boolean DEBUG;
 
-    /** OpenKODE/EGL type, as retrieved with {@link #getNativeWindowType(boolean)}*/
-    public static final String TYPE_EGL = "EGL";
+    /** OpenKODE/EGL type, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}.*/
+    public static final String TYPE_EGL = ".egl".intern();
 
-    /** Microsoft Windows type, as retrieved with {@link #getNativeWindowType(boolean)} */
-    public static final String TYPE_WINDOWS = "Windows";
+    /** Microsoft Windows type, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}. */
+    public static final String TYPE_WINDOWS = ".windows".intern();
 
-    /** X11 type, as retrieved with {@link #getNativeWindowType(boolean)} */
-    public static final String TYPE_X11 = "X11";
+    /** X11 type, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}. */
+    public static final String TYPE_X11 = ".x11".intern();
 
-    /** Android/EGL type, as retrieved with {@link #getNativeWindowType(boolean)}*/
-    public static final String TYPE_ANDROID = "ANDROID";
+    /** Broadcom VC IV/EGL type, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}. */
+    public static final String TYPE_BCM_VC_IV = ".bcm.vc.iv".intern();
 
-    /** Mac OS X type, as retrieved with {@link #getNativeWindowType(boolean)} */
-    public static final String TYPE_MACOSX = "MacOSX";
+    /** Android/EGL type, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}.*/
+    public static final String TYPE_ANDROID = ".android".intern();
 
-    /** Generic AWT type, as retrieved with {@link #getNativeWindowType(boolean)} */
-    public static final String TYPE_AWT = "AWT";
+    /** Mac OS X type, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}. */
+    public static final String TYPE_MACOSX = ".macosx".intern();
 
-    /** Generic DEFAULT type, where platform implementation don't care, as retrieved with {@link #getNativeWindowType(boolean)} */
-    public static final String TYPE_DEFAULT = "default";
+    /** Generic AWT type, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}. */
+    public static final String TYPE_AWT = ".awt".intern();
 
+    /** Generic DEFAULT type, where platform implementation don't care, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}. */
+    public static final String TYPE_DEFAULT = ".default".intern();
+
+    private static final String nativeWindowingTypePure;   // canonical String via String.intern()
+    private static final String nativeWindowingTypeCustom; // canonical String via String.intern()
+    
     private static NativeWindowFactory defaultFactory;
     private static Map<Class<?>, NativeWindowFactory> registeredFactories;
     
     private static Class<?> nativeWindowClass;
-    private static String nativeWindowingTypePure;
-    private static String nativeWindowingTypeCustom;
     private static boolean isAWTAvailable;
     
     private static final String JAWTUtilClassName = "jogamp.nativewindow.jawt.JAWTUtil" ;
+    /** {@link jogamp.nativewindow.x11.X11Util} implements {@link ToolkitProperties}. */
     private static final String X11UtilClassName = "jogamp.nativewindow.x11.X11Util";
+    /** {@link jogamp.nativewindow.macosx.OSXUtil} implements {@link ToolkitProperties}. */
     private static final String OSXUtilClassName = "jogamp.nativewindow.macosx.OSXUtil";
+    /** {@link jogamp.nativewindow.windows.GDIUtil} implements {@link ToolkitProperties}. */
     private static final String GDIClassName = "jogamp.nativewindow.windows.GDIUtil";
     
     private static ToolkitLock jawtUtilJAWTToolkitLock;
     
-    public static final String X11JAWTToolkitLockClassName = "jogamp.nativewindow.jawt.x11.X11JAWTToolkitLock" ;
-    public static final String X11ToolkitLockClassName = "jogamp.nativewindow.x11.X11ToolkitLock" ;
-    
-    private static Class<?>  x11JAWTToolkitLockClass;
-    private static Constructor<?> x11JAWTToolkitLockConstructor;
-    private static Class<?>  x11ToolkitLockClass;
-    private static Constructor<?> x11ToolkitLockConstructor;
-    private static boolean isFirstUIActionOnProcess;
     private static boolean requiresToolkitLock;
+    private static boolean desktopHasThreadingIssues;
 
+    private static volatile boolean isJVMShuttingDown = false;
+    
     /** Creates a new NativeWindowFactory instance. End users do not
         need to call this method. */
     protected NativeWindowFactory() {
     }
 
+    private static final boolean guessBroadcomVCIV() {
+        return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
+            private final File vcliblocation = new File(
+                    "/opt/vc/lib/libbcm_host.so");
+                public Boolean run() {
+                    if ( vcliblocation.isFile() ) {
+                        return Boolean.TRUE;
+                    }
+                    return Boolean.FALSE;
+                }
+        } ).booleanValue();
+    }
+
     private static String _getNativeWindowingType() {
         switch(Platform.OS_TYPE) {
             case ANDROID:
@@ -123,6 +140,9 @@ public abstract class NativeWindowFactory {
             case SUNOS:
             case HPUX:
             default:
+              if( guessBroadcomVCIV() ) {
+                return TYPE_BCM_VC_IV;
+              }
               return TYPE_X11;
         }
     }
@@ -134,73 +154,73 @@ public abstract class NativeWindowFactory {
             System.err.println(Thread.currentThread().getName()+" - Info: NativeWindowFactory.<init>");
             // Thread.dumpStack();
         }
+        
+        // Gather the windowing TK first
+        nativeWindowingTypePure = _getNativeWindowingType();
+        final String tmp = Debug.getProperty("nativewindow.ws.name", true);
+        if(null==tmp || tmp.length()==0) {
+            nativeWindowingTypeCustom = nativeWindowingTypePure;
+        } else {
+            nativeWindowingTypeCustom = tmp.intern(); // canonical representation
+        }
     }
 
     static boolean initialized = false;
 
-    private static void initSingletonNativeImpl(final boolean firstUIActionOnProcess, final ClassLoader cl) {
-        isFirstUIActionOnProcess = firstUIActionOnProcess;
-        
+    private static void initSingletonNativeImpl(final ClassLoader cl) {
         final String clazzName;
-        if( TYPE_X11.equals(nativeWindowingTypePure) ) {
+        if( TYPE_X11 == nativeWindowingTypePure ) {
             clazzName = X11UtilClassName;
-        } else if( TYPE_WINDOWS.equals(nativeWindowingTypePure) ) {
+        } else if( TYPE_WINDOWS == nativeWindowingTypePure ) {
             clazzName = GDIClassName;
-        } else if( TYPE_MACOSX.equals(nativeWindowingTypePure) ) {
+        } else if( TYPE_MACOSX == nativeWindowingTypePure ) {
             clazzName = OSXUtilClassName;
         } else {
             clazzName = null;
         }
         if( null != clazzName ) {
-            ReflectionUtil.callStaticMethod(clazzName, "initSingleton",
-                                            new Class[] { boolean.class },
-                                            new Object[] { new Boolean(firstUIActionOnProcess) }, cl );
+            ReflectionUtil.callStaticMethod(clazzName, "initSingleton", null, null, cl );
             
-            final Boolean res = (Boolean) ReflectionUtil.callStaticMethod(clazzName, "requiresToolkitLock", null, null, cl);
-            requiresToolkitLock = res.booleanValue();             
+            final Boolean res1 = (Boolean) ReflectionUtil.callStaticMethod(clazzName, "requiresToolkitLock", null, null, cl);
+            requiresToolkitLock = res1.booleanValue();
+            final Boolean res2 = (Boolean) ReflectionUtil.callStaticMethod(clazzName, "hasThreadingIssues", null, null, cl);
+            desktopHasThreadingIssues = res2.booleanValue();
         } else {            
             requiresToolkitLock = false;
-        }        
+            desktopHasThreadingIssues = false;
+        }
     }
 
+    private static void shutdownNativeImpl(final ClassLoader cl) {
+        final String clazzName;
+        if( TYPE_X11 == nativeWindowingTypePure ) {
+            clazzName = X11UtilClassName;
+        } else if( TYPE_WINDOWS == nativeWindowingTypePure ) {
+            clazzName = GDIClassName;
+        } else if( TYPE_MACOSX == nativeWindowingTypePure ) {
+            clazzName = OSXUtilClassName;
+        } else {
+            clazzName = null;
+        }
+        if( null != clazzName ) {
+            ReflectionUtil.callStaticMethod(clazzName, "shutdown", null, null, cl );
+        }        
+    }
+    
     /**
      * Static one time initialization of this factory.<br>
      * This initialization method <b>must be called</b> once by the program or utilizing modules!
-     * <p>
-     * The parameter <code>firstUIActionOnProcess</code> has an impact on concurrent locking:
-     * <ul>
-     *   <li> {@link #getDefaultToolkitLock() getDefaultToolkitLock() }</li>
-     *   <li> {@link #getDefaultToolkitLock(java.lang.String) getDefaultToolkitLock(type) }</li>
-     *   <li> {@link #createDefaultToolkitLock(java.lang.String, long) createDefaultToolkitLock(type, dpyHandle) }</li>
-     *   <li> {@link #createDefaultToolkitLockNoAWT(java.lang.String, long) createDefaultToolkitLockNoAWT(type, dpyHandle) }</li>
-     * </ul>
-     * </p>
-     * @param firstUIActionOnProcess Should be <code>true</code> if called before the first UI action of the running program,
-     * otherwise <code>false</code>.
      */
-    public static synchronized void initSingleton(final boolean firstUIActionOnProcess) {
+    public static synchronized void initSingleton() {
         if(!initialized) {
             initialized = true;
 
             if(DEBUG) {
-                System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.initSingleton("+firstUIActionOnProcess+")");
+                System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.initSingleton()");
             }
 
             final ClassLoader cl = NativeWindowFactory.class.getClassLoader();
 
-            // Gather the windowing OS first
-            nativeWindowingTypePure = _getNativeWindowingType();
-            String tmp = Debug.getProperty("nativewindow.ws.name", true);
-            if(null==tmp || tmp.length()==0) {
-                nativeWindowingTypeCustom = nativeWindowingTypePure;
-            } else {
-                nativeWindowingTypeCustom = tmp;
-            }
-
-            if(firstUIActionOnProcess) {
-                // X11 initialization before possible AWT initialization
-                initSingletonNativeImpl(true, cl);
-            }            
             isAWTAvailable = false; // may be set to true below
 
             if( Platform.AWT_AVAILABLE &&
@@ -248,10 +268,13 @@ public abstract class NativeWindowFactory {
                     }                    
                 }
             }
-            if(!firstUIActionOnProcess) {
-                // X11 initialization after possible AWT initialization
-                initSingletonNativeImpl(false, cl);
-            }
+            
+            // X11 initialization after possible AWT initialization
+            // This is performed post AWT initialization, allowing AWT to complete the same,
+            // which may have been triggered before NativeWindow initialization. 
+            // This way behavior is more uniforms across configurations (Applet/RCP, applications, ..). 
+            initSingletonNativeImpl(cl);
+            
             registeredFactories = Collections.synchronizedMap(new HashMap<Class<?>, NativeWindowFactory>());
 
             // register our default factory -> NativeWindow
@@ -264,20 +287,9 @@ public abstract class NativeWindowFactory {
                 // register either our default factory or (if exist) the X11/AWT one -> AWT Component
                 registerFactory(ReflectionUtil.getClass(ReflectionUtil.AWTNames.ComponentClass, false, cl), factory);
             }
-
-            if( TYPE_X11 == nativeWindowingTypePure ) {
-                // passing through RuntimeException if not exists intended
-                x11ToolkitLockClass = ReflectionUtil.getClass(X11ToolkitLockClassName, false, cl);
-                x11ToolkitLockConstructor = ReflectionUtil.getConstructor(x11ToolkitLockClass, new Class[] { long.class } );
-                if( isAWTAvailable() ) {
-                    x11JAWTToolkitLockClass = ReflectionUtil.getClass(X11JAWTToolkitLockClassName, false, cl);
-                    x11JAWTToolkitLockConstructor = ReflectionUtil.getConstructor(x11JAWTToolkitLockClass, new Class[] { long.class } );
-                }
-            }
             
             if(DEBUG) {
-                System.err.println("NativeWindowFactory firstUIActionOnProcess "+firstUIActionOnProcess);
-                System.err.println("NativeWindowFactory requiresToolkitLock "+requiresToolkitLock);
+                System.err.println("NativeWindowFactory requiresToolkitLock "+requiresToolkitLock+", desktopHasThreadingIssues "+desktopHasThreadingIssues);
                 System.err.println("NativeWindowFactory isAWTAvailable "+isAWTAvailable+", defaultFactory "+factory);
             }
             
@@ -285,39 +297,41 @@ public abstract class NativeWindowFactory {
         }
     }
 
-    public static synchronized void shutdown() {
+    public static synchronized void shutdown(boolean _isJVMShuttingDown) {
+        isJVMShuttingDown = _isJVMShuttingDown;
+        if(DEBUG) {
+            System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.shutdown() START: JVM Shutdown "+isJVMShuttingDown);                
+        }
         if(initialized) {
             initialized = false;
-            if(DEBUG) {
-                System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.shutdown() START");                
+            if(null != registeredFactories) {
+                registeredFactories.clear();
+                registeredFactories = null;
             }
-            registeredFactories.clear();
-            registeredFactories = null;
             GraphicsConfigurationFactory.shutdown();
-            // X11Util.shutdown(..) already called via GLDrawableFactory.shutdown() ..
-            if(DEBUG) {
-                System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.shutdown() END");                
-            }
+        }
+        shutdownNativeImpl(NativeWindowFactory.class.getClassLoader()); // always re-shutdown
+        // SharedResourceToolkitLock.shutdown(DEBUG); // not used yet
+        if(DEBUG) {
+            System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.shutdown() END JVM Shutdown "+isJVMShuttingDown);
         }
     }
     
-    /** @return true if initialized with <b>{@link #initSingleton(boolean) initSingleton(firstUIActionOnProcess==true)}</b>,
-        otherwise false. */
-    public static boolean isFirstUIActionOnProcess() {
-        return isFirstUIActionOnProcess;
-    }
-
+    /** Returns true if the JVM is shutting down, otherwise false. */ 
+    public static final boolean isJVMShuttingDown() { return isJVMShuttingDown; }
+    
     /** @return true if the underlying toolkit requires locking, otherwise false. */
     public static boolean requiresToolkitLock() {
         return requiresToolkitLock;
-    }    
+    }
     
     /** @return true if not headless, AWT Component and NativeWindow's AWT part available */
     public static boolean isAWTAvailable() { return isAWTAvailable; }
 
     /**
      * @param useCustom if false return the native value, if true return a custom value if set, otherwise fallback to the native value.
-     * @return a define native window type, like {@link #TYPE_X11}, ..
+     * @return the native window type, e.g. {@link #TYPE_X11}, which is canonical via {@link String#intern()}. 
+     *        Hence {@link String#equals(Object)} and <code>==</code> produce the same result.
      */
     public static String getNativeWindowType(boolean useCustom) {
         return useCustom?nativeWindowingTypeCustom:nativeWindowingTypePure;
@@ -325,13 +339,13 @@ public abstract class NativeWindowFactory {
 
     /** Don't know if we shall add this factory here .. 
     public static AbstractGraphicsDevice createGraphicsDevice(String type, String connection, int unitID, long handle, ToolkitLock locker) {
-        if(type.equals(TYPE_EGL)) {
+        if(TYPE_EGL == type) {
             return new
-        } else if(type.equals(TYPE_X11)) {
-        } else if(type.equals(TYPE_WINDOWS)) {
-        } else if(type.equals(TYPE_MACOSX)) {
-        } else if(type.equals(TYPE_AWT)) {
-        } else if(type.equals(TYPE_DEFAULT)) {
+        } else if(TYPE_X11 == type) {
+        } else if(TYPE_WINDOWS == type) {
+        } else if(TYPE_MACOSX == type)) {
+        } else if(TYPE_AWT == type) {
+        } else if(TYPE_DEFAULT == type) {
         }
     } */
 
@@ -345,9 +359,24 @@ public abstract class NativeWindowFactory {
         return defaultFactory;
     }
 
+    /** 
+     * Returns the AWT {@link ToolkitLock} (JAWT based) if {@link #isAWTAvailable}, otherwise null.
+     * <p>
+     * The JAWT based {@link ToolkitLock} also locks the global lock,
+     * which matters if the latter is required.
+     * </p> 
+     */ 
+    public static ToolkitLock getAWTToolkitLock() {
+        return jawtUtilJAWTToolkitLock;
+    }
+
+    public static ToolkitLock getNullToolkitLock() {
+        return NativeWindowFactoryImpl.getNullToolkitLock();
+    }
+    
     /**
-     * Provides the system default {@link ToolkitLock}, a singleton instance.
-     * <br>
+     * Provides the system default {@link ToolkitLock} for the default system windowing type.
+     * @see #getNativeWindowType(boolean)
      * @see #getDefaultToolkitLock(java.lang.String)
      */
     public static ToolkitLock getDefaultToolkitLock() {
@@ -355,117 +384,41 @@ public abstract class NativeWindowFactory {
     }
 
     /**
-     * Provides the default {@link ToolkitLock} for <code>type</code>, a singleton instance.
-     * <br>
+     * Provides the default {@link ToolkitLock} for <code>type</code>.
      * <ul>
-     *   <li> If {@link #initSingleton(boolean) initSingleton( <b>firstUIActionOnProcess := false</b> )} </li>
-     *   <ul>
-     *     <li>If <b>AWT-type</b> and <b>native-X11-type</b> and <b>AWT-available</b></li>
-     *       <ul>
-     *         <li> return {@link #getAWTToolkitLock()} </li>
-     *       </ul>
-     *   </ul>
-     *   <li> Otherwise return {@link #getNullToolkitLock()} </li>
+     *   <li> JAWT {@link ToolkitLock} if required and <code>type</code> is of {@link #TYPE_AWT} and AWT available,</li>
+     *   <li> {@link jogamp.nativewindow.ResourceToolkitLock} if required, otherwise</li>
+     *   <li> {@link jogamp.nativewindow.NullToolkitLock} </li>
      * </ul>
      */
     public static ToolkitLock getDefaultToolkitLock(String type) {
-        if( requiresToolkitLock() ) {
-            if( TYPE_AWT == type && TYPE_X11 == getNativeWindowType(false) && isAWTAvailable() ) {
+        if( requiresToolkitLock ) {
+            if( TYPE_AWT == type && isAWTAvailable() ) {
                 return getAWTToolkitLock();
             }
+            return ResourceToolkitLock.create();
         }
         return NativeWindowFactoryImpl.getNullToolkitLock();
     }
 
-    /** Returns the AWT Toolkit (JAWT based) if {@link #isAWTAvailable}, otherwise null. */ 
-    public static ToolkitLock getAWTToolkitLock() {
-        return jawtUtilJAWTToolkitLock;
-    }
-
-    public static ToolkitLock getNullToolkitLock() {
-        return NativeWindowFactoryImpl.getNullToolkitLock();
-    }
-
     /**
-     * Creates the default {@link ToolkitLock} for <code>type</code> and <code>deviceHandle</code>.
-     * <br>
+     * Provides the default {@link ToolkitLock} for <code>type</code> and <code>deviceHandle</code>.
      * <ul>
-     *   <li> If {@link #initSingleton(boolean) initSingleton( <b>firstUIActionOnProcess := false</b> )} </li>
-     *   <ul>
-     *     <li>If <b>X11 type</b> </li>
-     *     <ul>
-     *       <li> return {@link jogamp.nativewindow.x11.X11ToolkitLock} </li>
-     *     </ul>
-     *   </ul>
-     *   <li> Otherwise return {@link jogamp.nativewindow.NullToolkitLock} </li>
+     *   <li> JAWT {@link ToolkitLock} if required and <code>type</code> is of {@link #TYPE_AWT} and AWT available,</li>
+     *   <li> {@link jogamp.nativewindow.ResourceToolkitLock} if required, otherwise</li>
+     *   <li> {@link jogamp.nativewindow.NullToolkitLock} </li>
      * </ul>
      */
-    public static ToolkitLock createDefaultToolkitLock(String type, long deviceHandle) {
-        if( requiresToolkitLock() ) {
-            if( TYPE_X11 == type ) {
-                if( 0== deviceHandle ) {
-                    throw new RuntimeException("JAWTUtil.createDefaultToolkitLock() called with NULL device but on X11");
-                }
-                return createX11ToolkitLock(deviceHandle);
+    public static ToolkitLock getDefaultToolkitLock(String type, long deviceHandle) {
+        if( requiresToolkitLock ) {
+            if( TYPE_AWT == type && isAWTAvailable() ) {
+                return getAWTToolkitLock();
             }
+            return ResourceToolkitLock.create();
         }
         return NativeWindowFactoryImpl.getNullToolkitLock();
     }
     
-    /**
-     * Creates the default {@link ToolkitLock} for <code>type</code> and <code>deviceHandle</code>.
-     * <br>
-     * <ul>
-     *   <li> If {@link #initSingleton(boolean) initSingleton( <b>firstUIActionOnProcess := false</b> )} </li>
-     *   <ul>
-     *     <li>If <b>X11 type</b> </li>
-     *     <ul>
-     *       <li> If <b>shared-AWT-type</b> and <b>AWT available</b> </li>
-     *       <ul>
-     *         <li> return {@link jogamp.nativewindow.jawt.x11.X11JAWTToolkitLock} </li>
-     *       </ul>
-     *       <li> else return {@link jogamp.nativewindow.x11.X11ToolkitLock} </li>
-     *     </ul>
-     *   </ul>
-     *   <li> Otherwise return {@link jogamp.nativewindow.NullToolkitLock} </li>
-     * </ul>
-     */
-    public static ToolkitLock createDefaultToolkitLock(String type, String sharedType, long deviceHandle) {
-        if( requiresToolkitLock() ) {
-            if( TYPE_X11 == type ) {
-                if( 0== deviceHandle ) {
-                    throw new RuntimeException("JAWTUtil.createDefaultToolkitLock() called with NULL device but on X11");
-                }
-                if( TYPE_AWT == sharedType && isAWTAvailable() ) {
-                    return createX11AWTToolkitLock(deviceHandle);
-                }
-                return createX11ToolkitLock(deviceHandle);
-            }
-        }
-        return NativeWindowFactoryImpl.getNullToolkitLock();
-    }
-
-    protected static ToolkitLock createX11AWTToolkitLock(long deviceHandle) {
-        try {
-            if(DEBUG) {
-                System.err.println("NativeWindowFactory.createX11AWTToolkitLock(0x"+Long.toHexString(deviceHandle)+")");
-                // Thread.dumpStack();
-            }            
-            return (ToolkitLock) x11JAWTToolkitLockConstructor.newInstance(new Object[]{new Long(deviceHandle)});
-        } catch (Exception ex) {
-            throw new RuntimeException(ex);
-        }
-    }
-
-    protected static ToolkitLock createX11ToolkitLock(long deviceHandle) {
-        try {
-            return (ToolkitLock) x11ToolkitLockConstructor.newInstance(new Object[]{new Long(deviceHandle)});
-        } catch (Exception ex) {
-            throw new RuntimeException(ex);
-        }
-    }
-
-
     /** Returns the appropriate NativeWindowFactory to handle window
         objects of the given type. The windowClass might be {@link
         NativeWindow NativeWindow}, in which case the client has
diff --git a/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java b/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java
index f7dbc6c..f980010 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java
@@ -50,4 +50,7 @@ public interface OffscreenLayerSurface {
   /** Returns true if a surface layer is attached, otherwise false. */
   public boolean isSurfaceLayerAttached();
   
+  /** Sets the capabilities of this instance, allowing upstream API's to refine it, i.e. OpenGL related settings. */
+  public void setChosenCapabilities(CapabilitiesImmutable caps);
+  
 }
diff --git a/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java b/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java
index 7fc9789..395fdc8 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java
@@ -1,5 +1,5 @@
 /**
- * Copyright 2010 JogAmp Community. All rights reserved.
+ * 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:
@@ -29,242 +29,82 @@
 package javax.media.nativewindow;
 
 import jogamp.nativewindow.Debug;
-import jogamp.nativewindow.SurfaceUpdatedHelper;
 
-import com.jogamp.common.util.locks.LockFactory;
-import com.jogamp.common.util.locks.RecursiveLock;
-
-public abstract class ProxySurface implements NativeSurface, MutableSurface {
+/**
+ * Provides a mutable {@link NativeSurface}, i.e. {@link MutableSurface}, while allowing an
+ * {@link UpstreamSurfaceHook} to influence the lifecycle and information.
+ * 
+ * @see UpstreamSurfaceHook
+ * @see MutableSurface
+ * @see NativeSurface
+ */
+public interface ProxySurface extends MutableSurface {    
     public static final boolean DEBUG = Debug.debug("ProxySurface");
     
     /** 
-     * Implementation specific bitvalue stating the upstream's {@link AbstractGraphicsDevice} is owned by this {@link ProxySurface}.
-     * @see #setImplBitfield(int)
-     * @see #getImplBitfield()
+     * Implementation specific bit-value stating this {@link ProxySurface} owns the upstream's surface handle
+     * @see #addUpstreamOptionBits(int)
+     * @see #getUpstreamOptionBits()
      */ 
-    public static final int OWN_DEVICE = 1 << 7;
+    public static final int OPT_PROXY_OWNS_UPSTREAM_SURFACE = 1 << 6;
+    
+    /** 
+     * Implementation specific bit-value stating this {@link ProxySurface} owns the upstream's {@link AbstractGraphicsDevice}.
+     * @see #addUpstreamOptionBits(int)
+     * @see #getUpstreamOptionBits()
+     */ 
+    public static final int OPT_PROXY_OWNS_UPSTREAM_DEVICE = 1 << 7;
     
     /** 
      * Implementation specific bitvalue stating the upstream's {@link NativeSurface} is an invisible window, i.e. maybe incomplete.
-     * @see #setImplBitfield(int)
-     * @see #getImplBitfield()
+     * @see #addUpstreamOptionBits(int)
+     * @see #getUpstreamOptionBits()
      */ 
-    public static final int INVISIBLE_WINDOW = 1 << 8;
+    public static final int OPT_UPSTREAM_WINDOW_INVISIBLE = 1 << 8;
 
-    /** Interface allowing upstream caller to pass lifecycle actions and size info to a {@link ProxySurface} instance. */ 
-    public interface UpstreamSurfaceHook {
-        /** called within {@link ProxySurface#createNotify()} within lock, before using surface. */
-        public void create(ProxySurface s);
-        /** called within {@link ProxySurface#destroyNotify()} within lock, before clearing fields. */
-        public void destroy(ProxySurface s);
+    /** Allow redefining the AbstractGraphicsConfiguration */
+    public void setGraphicsConfiguration(AbstractGraphicsConfiguration cfg);    
 
-        /** Returns the width of the upstream surface */ 
-        public int getWidth(ProxySurface s);
-        /** Returns the height of the upstream surface */ 
-        public int getHeight(ProxySurface s);
-    }
+    /** Returns the set {@link UpstreamSurfaceHook}, or null if not set. */
+    public UpstreamSurfaceHook getUpstreamSurfaceHook();
     
-    private final SurfaceUpdatedHelper surfaceUpdatedHelper = new SurfaceUpdatedHelper();
-    private final AbstractGraphicsConfiguration config; // control access due to delegation
-    private final UpstreamSurfaceHook upstream;
-    public final int initialWidth;
-    public final int initialHeight;
-    private long surfaceHandle_old;
-    protected RecursiveLock surfaceLock = LockFactory.createRecursiveLock();
-    protected long displayHandle;
-    protected int scrnIndex;
-    protected int implBitfield;
-
     /**
-     * @param cfg the {@link AbstractGraphicsConfiguration} to be used
-     * @param initialWidth the initial width
-     * @param initialHeight the initial height
+     * Sets the {@link UpstreamSurfaceHook} and returns the previous value.
      */
-    protected ProxySurface(AbstractGraphicsConfiguration cfg, int initialWidth, int initialHeight, UpstreamSurfaceHook upstream) {
-        if(null == cfg) {
-            throw new IllegalArgumentException("null config");
-        }
-        this.config = cfg;
-        this.upstream = upstream;
-        this.initialWidth = initialWidth;
-        this.initialHeight = initialHeight;
-        this.displayHandle=config.getNativeGraphicsConfiguration().getScreen().getDevice().getHandle();
-        this.surfaceHandle_old = 0;
-        this.implBitfield = 0;
-    }
-
-    public final UpstreamSurfaceHook getUpstreamSurfaceHook() { return upstream; }
+    public void setUpstreamSurfaceHook(UpstreamSurfaceHook hook);
+    
+    /** 
+     * Enables or disables the {@link UpstreamSurfaceHook} lifecycle functions 
+     * {@link UpstreamSurfaceHook#create(ProxySurface)} and {@link UpstreamSurfaceHook#destroy(ProxySurface)}.
+     * <p>
+     * Use this for small code blocks where the native resources shall not change,
+     * i.e. resizing a derived (OpenGL) drawable.
+     * </p> 
+     */
+    public void enableUpstreamSurfaceHookLifecycle(boolean enable);
     
     /** 
-     * If a valid {@link UpstreamSurfaceHook} instance is passed in the 
-     * {@link ProxySurface#ProxySurface(AbstractGraphicsConfiguration, int, int, UpstreamSurfaceHook) constructor}, 
      * {@link UpstreamSurfaceHook#create(ProxySurface)} is being issued and the proxy surface/window handles shall be set.
      */ 
-    public void createNotify() {
-        if(null != upstream) {
-            upstream.create(this);
-        }
-        this.displayHandle=config.getNativeGraphicsConfiguration().getScreen().getDevice().getHandle();
-        this.surfaceHandle_old = 0;
-    }
+    public void createNotify();
     
     /** 
-     * If a valid {@link UpstreamSurfaceHook} instance is passed in the 
-     * {@link ProxySurface#ProxySurface(AbstractGraphicsConfiguration, int, int, UpstreamSurfaceHook) constructor}, 
-     * {@link UpstreamSurfaceHook#destroy(ProxySurface)} is being issued and all fields are cleared.
+     * {@link UpstreamSurfaceHook#destroy(ProxySurface)} is being issued and all proxy surface/window handles shall be cleared.
      */ 
-    public void destroyNotify() {
-        if(null != upstream) {
-            upstream.destroy(this);
-            invalidateImpl();
-        }
-        this.displayHandle = 0;
-        this.surfaceHandle_old = 0;
-    }
+    public void destroyNotify();
     
-    /** 
-     * Must be overridden by implementations allowing having a {@link UpstreamSurfaceHook} being passed.
-     * @see #destroyNotify() 
-     */
-    protected void invalidateImpl() {
-        throw new InternalError("UpstreamSurfaceHook given, but required method not implemented.");        
-    }
+    public StringBuilder getUpstreamOptionBits(StringBuilder sink);
+    public int getUpstreamOptionBits();
     
-    @Override
-    public final long getDisplayHandle() {
-        return displayHandle;
-    }
-
-    protected final AbstractGraphicsConfiguration getPrivateGraphicsConfiguration() {
-        return config;
-    }
-
-    @Override
-    public final AbstractGraphicsConfiguration getGraphicsConfiguration() {
-        return config.getNativeGraphicsConfiguration();
-    }
-
-    @Override
-    public final int getScreenIndex() {
-        return getGraphicsConfiguration().getScreen().getIndex();
-    }
-
-    @Override
-    public abstract long getSurfaceHandle();
-
-    @Override
-    public abstract void setSurfaceHandle(long surfaceHandle);
+    /** Returns <code>true</code> if the give bit-mask <code>v</code> is set in this instance upstream-option-bits, otherwise <code>false</code>.*/
+    public boolean containsUpstreamOptionBits(int v);
     
-    @Override
-    public final int getWidth() {
-        if(null != upstream) {
-            return upstream.getWidth(this);
-        }
-        return initialWidth;
-    }
-
-    @Override
-    public final int getHeight() {
-        if(null != upstream) {
-            return upstream.getHeight(this);
-        }
-        return initialHeight;
-    }
-
-    @Override
-    public boolean surfaceSwap() {
-        return false;
-    }
-
-    @Override
-    public void addSurfaceUpdatedListener(SurfaceUpdatedListener l) {
-        surfaceUpdatedHelper.addSurfaceUpdatedListener(l);
-    }
-
-    @Override
-    public void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l) throws IndexOutOfBoundsException {
-        surfaceUpdatedHelper.addSurfaceUpdatedListener(index, l);
-    }
-
-    @Override
-    public void removeSurfaceUpdatedListener(SurfaceUpdatedListener l) {
-        surfaceUpdatedHelper.removeSurfaceUpdatedListener(l);
-    }
-
-    @Override
-    public void surfaceUpdated(Object updater, NativeSurface ns, long when) {
-        surfaceUpdatedHelper.surfaceUpdated(updater, ns, when);
-    }
-
-    @Override
-    public int lockSurface() throws NativeWindowException, RuntimeException  {
-        surfaceLock.lock();
-        int res = surfaceLock.getHoldCount() == 1 ? LOCK_SURFACE_NOT_READY : LOCK_SUCCESS; // new lock ?
-
-        if ( LOCK_SURFACE_NOT_READY == res ) {
-            try {
-                final AbstractGraphicsDevice adevice = getGraphicsConfiguration().getScreen().getDevice();
-                adevice.lock();
-                try {
-                    res = lockSurfaceImpl();
-                    if(LOCK_SUCCESS == res && surfaceHandle_old != getSurfaceHandle()) {
-                        res = LOCK_SURFACE_CHANGED;
-                        if(DEBUG) {
-                            System.err.println("ProxySurface: surface change 0x"+Long.toHexString(surfaceHandle_old)+" -> 0x"+Long.toHexString(getSurfaceHandle()));
-                            // Thread.dumpStack();
-                        }
-                    }
-                } finally {
-                    if (LOCK_SURFACE_NOT_READY >= res) {
-                        adevice.unlock();
-                    }
-                }
-            } finally {
-                if (LOCK_SURFACE_NOT_READY >= res) {
-                    surfaceLock.unlock();
-                }
-            }
-        }
-        return res;
-    }
-
-    @Override
-    public final void unlockSurface() {
-        surfaceLock.validateLocked();
-        surfaceHandle_old = getSurfaceHandle();
-
-        if (surfaceLock.getHoldCount() == 1) {
-            final AbstractGraphicsDevice adevice = getGraphicsConfiguration().getScreen().getDevice();
-            try {
-                unlockSurfaceImpl();
-            } finally {
-                adevice.unlock();
-            }
-        }
-        surfaceLock.unlock();
-    }
-
-    protected abstract int lockSurfaceImpl();
-
-    protected abstract void unlockSurfaceImpl() ;
-
-    public final void validateSurfaceLocked() {
-        surfaceLock.validateLocked();
-    }
-
-    @Override
-    public final boolean isSurfaceLockedByOtherThread() {
-        return surfaceLock.isLockedByOtherThread();
-    }
-
-    @Override
-    public final Thread getSurfaceLockOwner() {
-        return surfaceLock.getOwner();
-    }
+    /** Add the given bit-mask to this instance upstream-option-bits using bit-or w/ <code>v</code>.*/
+    public void addUpstreamOptionBits(int v);
     
-    @Override
-    public abstract String toString();
+    /** Clear the given bit-mask from this instance upstream-option-bits using bit-and w/ <code>~v</code>*/
+    public void clearUpstreamOptionBits(int v);
     
-    public int getImplBitfield() { return implBitfield; }    
-    public void setImplBitfield(int v) { implBitfield=v; }
+    public StringBuilder toString(StringBuilder sink);
+    public String toString();
 }
diff --git a/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java b/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java
index 30f9660..eccfcfa 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java
@@ -33,12 +33,46 @@ import jogamp.nativewindow.Debug;
 /**
  * Marker for a singleton global recursive blocking lock implementation,
  * optionally locking a native windowing toolkit as well.
- * <br>
- * One use case is the AWT locking on X11, see {@link jogamp.nativewindow.jawt.JAWTToolkitLock}.
+ * <p>
+ * Toolkit locks are created solely via {@link NativeWindowFactory}.
+ * </p>
+ * <p>
+ * One use case is the AWT locking on X11, see {@link NativeWindowFactory#getDefaultToolkitLock(String, long)}.
+ * </p>
  */
 public interface ToolkitLock {
+    public static final boolean DEBUG = Debug.debug("ToolkitLock");
     public static final boolean TRACE_LOCK = Debug.isPropertyDefined("nativewindow.debug.ToolkitLock.TraceLock", true);
 
+    /**
+     * Blocking until the lock is acquired by this Thread or a timeout is reached.
+     * <p>
+     * Timeout is implementation specific, if used at all.
+     * </p>
+     *
+     * @throws RuntimeException in case of a timeout
+     */
     public void lock();
+    
+    /**
+     * Release the lock.
+     *
+     * @throws RuntimeException in case the lock is not acquired by this thread.
+     */
     public void unlock();
+    
+    /**
+     * @throws RuntimeException if current thread does not hold the lock 
+     */
+    public void validateLocked() throws RuntimeException;
+    
+    /** 
+     * Dispose this instance.
+     * <p> 
+     * Shall be called when instance is no more required.
+     * </p>
+     * This allows implementations sharing a lock via resources
+     * to decrease the reference counter.  
+     */
+    public void dispose();
 }
diff --git a/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java b/src/nativewindow/classes/javax/media/nativewindow/UpstreamSurfaceHook.java
similarity index 59%
copy from src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java
copy to src/nativewindow/classes/javax/media/nativewindow/UpstreamSurfaceHook.java
index 30f9660..6fe2e53 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/UpstreamSurfaceHook.java
@@ -1,5 +1,5 @@
 /**
- * Copyright 2010 JogAmp Community. All rights reserved.
+ * 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:
@@ -28,17 +28,25 @@
 
 package javax.media.nativewindow;
 
-import jogamp.nativewindow.Debug;
+/** 
+ * Interface allowing upstream caller to pass lifecycle actions and size info 
+ * to a {@link ProxySurface} instance. 
+ */ 
+public interface UpstreamSurfaceHook {
+    /** called within {@link ProxySurface#createNotify()} within lock, before using surface. */
+    public void create(ProxySurface s);
+    /** called within {@link ProxySurface#destroyNotify()} within lock, before clearing fields. */
+    public void destroy(ProxySurface s);
 
-/**
- * Marker for a singleton global recursive blocking lock implementation,
- * optionally locking a native windowing toolkit as well.
- * <br>
- * One use case is the AWT locking on X11, see {@link jogamp.nativewindow.jawt.JAWTToolkitLock}.
- */
-public interface ToolkitLock {
-    public static final boolean TRACE_LOCK = Debug.isPropertyDefined("nativewindow.debug.ToolkitLock.TraceLock", true);
-
-    public void lock();
-    public void unlock();
+    /** Returns the width of the upstream surface, used if {@link ProxySurface#UPSTREAM_PROVIDES_SIZE} is set. */ 
+    public int getWidth(ProxySurface s);
+    /** Returns the height of the upstream surface, used if {@link ProxySurface#UPSTREAM_PROVIDES_SIZE} is set. */ 
+    public int getHeight(ProxySurface s);
+    
+    /**
+     * {@link UpstreamSurfaceHook} w/ mutable size, allowing it's {@link ProxySurface} user to resize.  
+     */ 
+    public interface MutableSize extends UpstreamSurfaceHook {
+        public void setSize(int width, int height);
+    }
 }
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTToolkitLock.java b/src/nativewindow/classes/jogamp/nativewindow/GlobalToolkitLock.java
similarity index 53%
rename from src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTToolkitLock.java
rename to src/nativewindow/classes/jogamp/nativewindow/GlobalToolkitLock.java
index 743d371..c9f8308 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTToolkitLock.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/GlobalToolkitLock.java
@@ -1,5 +1,5 @@
 /**
- * Copyright 2010 JogAmp Community. All rights reserved.
+ * 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:
@@ -25,52 +25,54 @@
  * authors and should not be interpreted as representing official policies, either expressed
  * or implied, of JogAmp Community.
  */
-package jogamp.nativewindow.jawt.x11;
 
-import jogamp.nativewindow.jawt.*;
-import jogamp.nativewindow.x11.X11Lib;
-import jogamp.nativewindow.x11.X11Util;
+package jogamp.nativewindow;
+
 import javax.media.nativewindow.ToolkitLock;
 
 import com.jogamp.common.util.locks.LockFactory;
 import com.jogamp.common.util.locks.RecursiveLock;
 
 /**
- * Implementing a recursive {@link javax.media.nativewindow.ToolkitLock}
- * utilizing JAWT's AWT lock via {@link JAWTUtil#lockToolkit()} and {@link X11Util#XLockDisplay(long)}.
- * <br>
- * This strategy should only be used if AWT is using the underlying native windowing toolkit
- * in a not intrinsic thread safe manner, e.g. under X11 where no XInitThreads() call
- * is issued before any other X11 usage. This is the current situation for e.g. Webstart or Applets.
+ * Implementing a global recursive {@link javax.media.nativewindow.ToolkitLock}.
+ * <p>
+ * This is the last resort for unstable driver where multiple X11 display connections 
+ * to the same connection name are not treated thread safe within the GL/X11 driver.
+ * </p>
  */
-public class X11JAWTToolkitLock implements ToolkitLock {
-    long displayHandle;
-    RecursiveLock lock;
-
-    public X11JAWTToolkitLock(long displayHandle) {
-        this.displayHandle = displayHandle;
-        if(!X11Util.isNativeLockAvailable()) {
-            lock = LockFactory.createRecursiveLock();
-        }
+public class GlobalToolkitLock implements ToolkitLock {
+    private static final RecursiveLock globalLock = LockFactory.createRecursiveLock();
+    private static GlobalToolkitLock singleton = new GlobalToolkitLock();
+    
+    public static final GlobalToolkitLock getSingleton() {
+        return singleton;
     }
-
+    
+    private GlobalToolkitLock() { }
+    
+    @Override
     public final void lock() {
-        if(TRACE_LOCK) { System.err.println("X11JAWTToolkitLock.lock() - native: "+(null==lock)); }
-        JAWTUtil.lockToolkit();
-        if(null == lock) {
-            X11Lib.XLockDisplay(displayHandle);
-        } else {
-            lock.lock();
-        }
+        globalLock.lock();
+        if(TRACE_LOCK) { System.err.println("GlobalToolkitLock.lock()"); }
     }
 
+    @Override
     public final void unlock() {
-        if(TRACE_LOCK) { System.err.println("X11JAWTToolkitLock.unlock() - native: "+(null==lock)); }
-        if(null == lock) {
-            X11Lib.XUnlockDisplay(displayHandle);
-        } else {
-            lock.unlock();
-        }
-        JAWTUtil.unlockToolkit();
+        if(TRACE_LOCK) { System.err.println("GlobalToolkitLock.unlock()"); }
+        globalLock.unlock(); // implicit lock validation
+    }
+    
+    @Override
+    public final void validateLocked() throws RuntimeException {
+        globalLock.validateLocked();
+    }
+    
+    @Override
+    public final void dispose() {
+        // nop
+    }
+    
+    public String toString() {
+        return "GlobalToolkitLock[obj 0x"+Integer.toHexString(hashCode())+", isOwner "+globalLock.isOwner(Thread.currentThread())+", "+globalLock.toString()+"]";
     }
 }
diff --git a/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java b/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java
index 9e18439..a3a66b7 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java
@@ -39,7 +39,6 @@ import javax.media.nativewindow.NativeWindow;
 import javax.media.nativewindow.NativeWindowFactory;
 import javax.media.nativewindow.ToolkitLock;
 
-import com.jogamp.common.os.Platform;
 import com.jogamp.common.util.ReflectionUtil;
 import com.jogamp.common.util.ReflectionUtil.AWTNames;
 
@@ -47,7 +46,7 @@ public class NativeWindowFactoryImpl extends NativeWindowFactory {
     private static final ToolkitLock nullToolkitLock = new NullToolkitLock();
 
     public static ToolkitLock getNullToolkitLock() {
-            return nullToolkitLock;
+        return nullToolkitLock;
     }
     
     // This subclass of NativeWindowFactory handles the case of
@@ -76,21 +75,21 @@ public class NativeWindowFactoryImpl extends NativeWindowFactory {
     private NativeWindow getAWTNativeWindow(Object winObj, AbstractGraphicsConfiguration config) {
         if (nativeWindowConstructor == null) {
             try {
-                String windowingType = getNativeWindowType(true);
-                String windowClassName = null;
+                final String windowingType = getNativeWindowType(true);
+                final String windowClassName;
 
                 // We break compile-time dependencies on the AWT here to
                 // make it easier to run this code on mobile devices
 
-                if (windowingType.equals(TYPE_WINDOWS)) {
+                if (TYPE_WINDOWS == windowingType) {
                     windowClassName = "jogamp.nativewindow.jawt.windows.WindowsJAWTWindow";
-                } else if (windowingType.equals(TYPE_MACOSX)) {
+                } else if (TYPE_MACOSX == windowingType) {
                     windowClassName = "jogamp.nativewindow.jawt.macosx.MacOSXJAWTWindow";
-                } else if (windowingType.equals(TYPE_X11)) {
+                } else if (TYPE_X11 == windowingType) {
                     // Assume Linux, Solaris, etc. Should probably test for these explicitly.
                     windowClassName = "jogamp.nativewindow.jawt.x11.X11JAWTWindow";
                 } else {
-                    throw new IllegalArgumentException("OS " + Platform.getOSName() + " not yet supported");
+                    throw new IllegalArgumentException("Native windowing type " + windowingType + " (custom) not yet supported, platform reported native windowing type: "+getNativeWindowType(false));
                 }
 
                 nativeWindowConstructor = ReflectionUtil.getConstructor(
diff --git a/src/nativewindow/classes/jogamp/nativewindow/NullToolkitLock.java b/src/nativewindow/classes/jogamp/nativewindow/NullToolkitLock.java
index 1af6bf2..5fc5fe3 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/NullToolkitLock.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/NullToolkitLock.java
@@ -28,18 +28,18 @@
 
 package jogamp.nativewindow;
 
+import javax.media.nativewindow.NativeWindowFactory;
 import javax.media.nativewindow.ToolkitLock;
 
 /**
- * Implementing a singleton global recursive {@link javax.media.nativewindow.ToolkitLock}
- * without any locking. Since there is no locking it all,
- * it is intrinsically recursive.
+ * Implementing a singleton global NOP {@link javax.media.nativewindow.ToolkitLock}
+ * without any locking. Since there is no locking it all, it is intrinsically recursive.
  */
 public class NullToolkitLock implements ToolkitLock {
-
     /** Singleton via {@link NativeWindowFactoryImpl#getNullToolkitLock()} */
     protected NullToolkitLock() { }
     
+    @Override
     public final void lock() {
         if(TRACE_LOCK) {
             System.err.println("NullToolkitLock.lock()");
@@ -47,7 +47,25 @@ public class NullToolkitLock implements ToolkitLock {
         }
     }
 
+    @Override
     public final void unlock() {
         if(TRACE_LOCK) { System.err.println("NullToolkitLock.unlock()"); }
     }
+    
+    @Override
+    public final void validateLocked() throws RuntimeException {
+        if( NativeWindowFactory.requiresToolkitLock() ) {
+            throw new RuntimeException("NullToolkitLock does not lock, but locking is required.");
+        }
+    }
+    
+    @Override
+    public final void dispose() {
+        // nop
+    }
+    
+    public String toString() {
+        return "NullToolkitLock[]";
+    }
+    
 }
diff --git a/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java b/src/nativewindow/classes/jogamp/nativewindow/ProxySurfaceImpl.java
similarity index 56%
copy from src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java
copy to src/nativewindow/classes/jogamp/nativewindow/ProxySurfaceImpl.java
index 7fc9789..63f56cb 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/ProxySurfaceImpl.java
@@ -26,96 +26,89 @@
  * or implied, of JogAmp Community.
  */
 
-package javax.media.nativewindow;
+package jogamp.nativewindow;
+
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.SurfaceUpdatedListener;
+import javax.media.nativewindow.UpstreamSurfaceHook;
 
-import jogamp.nativewindow.Debug;
-import jogamp.nativewindow.SurfaceUpdatedHelper;
 
 import com.jogamp.common.util.locks.LockFactory;
 import com.jogamp.common.util.locks.RecursiveLock;
 
-public abstract class ProxySurface implements NativeSurface, MutableSurface {
-    public static final boolean DEBUG = Debug.debug("ProxySurface");
-    
-    /** 
-     * Implementation specific bitvalue stating the upstream's {@link AbstractGraphicsDevice} is owned by this {@link ProxySurface}.
-     * @see #setImplBitfield(int)
-     * @see #getImplBitfield()
-     */ 
-    public static final int OWN_DEVICE = 1 << 7;
-    
-    /** 
-     * Implementation specific bitvalue stating the upstream's {@link NativeSurface} is an invisible window, i.e. maybe incomplete.
-     * @see #setImplBitfield(int)
-     * @see #getImplBitfield()
-     */ 
-    public static final int INVISIBLE_WINDOW = 1 << 8;
-
-    /** Interface allowing upstream caller to pass lifecycle actions and size info to a {@link ProxySurface} instance. */ 
-    public interface UpstreamSurfaceHook {
-        /** called within {@link ProxySurface#createNotify()} within lock, before using surface. */
-        public void create(ProxySurface s);
-        /** called within {@link ProxySurface#destroyNotify()} within lock, before clearing fields. */
-        public void destroy(ProxySurface s);
-
-        /** Returns the width of the upstream surface */ 
-        public int getWidth(ProxySurface s);
-        /** Returns the height of the upstream surface */ 
-        public int getHeight(ProxySurface s);
-    }
-    
+public abstract class ProxySurfaceImpl implements ProxySurface {    
     private final SurfaceUpdatedHelper surfaceUpdatedHelper = new SurfaceUpdatedHelper();
-    private final AbstractGraphicsConfiguration config; // control access due to delegation
-    private final UpstreamSurfaceHook upstream;
-    public final int initialWidth;
-    public final int initialHeight;
+    protected long displayHandle; // convenient ref of config.screen.device.handle
+    private AbstractGraphicsConfiguration config; // control access due to delegation
+    private UpstreamSurfaceHook upstream;
     private long surfaceHandle_old;
-    protected RecursiveLock surfaceLock = LockFactory.createRecursiveLock();
-    protected long displayHandle;
-    protected int scrnIndex;
-    protected int implBitfield;
+    private RecursiveLock surfaceLock = LockFactory.createRecursiveLock();
+    private int implBitfield;
+    private boolean upstreamSurfaceHookLifecycleEnabled;
 
     /**
      * @param cfg the {@link AbstractGraphicsConfiguration} to be used
-     * @param initialWidth the initial width
-     * @param initialHeight the initial height
+     * @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>. Owning the device implies closing it at {@link #destroyNotify()}.
      */
-    protected ProxySurface(AbstractGraphicsConfiguration cfg, int initialWidth, int initialHeight, UpstreamSurfaceHook upstream) {
+    protected ProxySurfaceImpl(AbstractGraphicsConfiguration cfg, UpstreamSurfaceHook upstream, boolean ownsDevice) {
         if(null == cfg) {
-            throw new IllegalArgumentException("null config");
+            throw new IllegalArgumentException("null AbstractGraphicsConfiguration");
+        }
+        if(null == upstream) {
+            throw new IllegalArgumentException("null UpstreamSurfaceHook");
         }
         this.config = cfg;
-        this.upstream = upstream;
-        this.initialWidth = initialWidth;
-        this.initialHeight = initialHeight;
         this.displayHandle=config.getNativeGraphicsConfiguration().getScreen().getDevice().getHandle();
+        this.upstream = upstream;
         this.surfaceHandle_old = 0;
         this.implBitfield = 0;
+        this.upstreamSurfaceHookLifecycleEnabled = true;
+        if(ownsDevice) {
+            addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE );
+        }        
     }
 
+    @Override
     public final UpstreamSurfaceHook getUpstreamSurfaceHook() { return upstream; }
     
-    /** 
-     * If a valid {@link UpstreamSurfaceHook} instance is passed in the 
-     * {@link ProxySurface#ProxySurface(AbstractGraphicsConfiguration, int, int, UpstreamSurfaceHook) constructor}, 
-     * {@link UpstreamSurfaceHook#create(ProxySurface)} is being issued and the proxy surface/window handles shall be set.
-     */ 
-    public void createNotify() {
-        if(null != upstream) {
+    @Override
+    public void setUpstreamSurfaceHook(UpstreamSurfaceHook hook) {
+        if(null == hook) {
+            throw new IllegalArgumentException("null UpstreamSurfaceHook");
+        }
+        upstream = hook;
+    }
+        
+    @Override
+    public final void enableUpstreamSurfaceHookLifecycle(boolean enable) {
+        upstreamSurfaceHookLifecycleEnabled = enable;
+    }
+    
+    @Override
+    public void createNotify() {        
+        if(upstreamSurfaceHookLifecycleEnabled) {
             upstream.create(this);
         }
         this.displayHandle=config.getNativeGraphicsConfiguration().getScreen().getDevice().getHandle();
         this.surfaceHandle_old = 0;
     }
-    
-    /** 
-     * If a valid {@link UpstreamSurfaceHook} instance is passed in the 
-     * {@link ProxySurface#ProxySurface(AbstractGraphicsConfiguration, int, int, UpstreamSurfaceHook) constructor}, 
-     * {@link UpstreamSurfaceHook#destroy(ProxySurface)} is being issued and all fields are cleared.
-     */ 
+
+    @Override
     public void destroyNotify() {
-        if(null != upstream) {
+        if(upstreamSurfaceHookLifecycleEnabled) {
             upstream.destroy(this);
+            if( containsUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE ) ) {
+                final AbstractGraphicsDevice aDevice = getGraphicsConfiguration().getScreen().getDevice();
+                aDevice.close();
+                clearUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE );
+            }
             invalidateImpl();
         }
         this.displayHandle = 0;
@@ -145,6 +138,11 @@ public abstract class ProxySurface implements NativeSurface, MutableSurface {
     }
 
     @Override
+    public final void setGraphicsConfiguration(AbstractGraphicsConfiguration cfg) {
+        config = cfg;
+    }
+    
+    @Override
     public final int getScreenIndex() {
         return getGraphicsConfiguration().getScreen().getIndex();
     }
@@ -157,18 +155,12 @@ public abstract class ProxySurface implements NativeSurface, MutableSurface {
     
     @Override
     public final int getWidth() {
-        if(null != upstream) {
-            return upstream.getWidth(this);
-        }
-        return initialWidth;
+        return upstream.getWidth(this);
     }
 
     @Override
     public final int getHeight() {
-        if(null != upstream) {
-            return upstream.getHeight(this);
-        }
-        return initialHeight;
+        return upstream.getHeight(this);
     }
 
     @Override
@@ -210,7 +202,7 @@ public abstract class ProxySurface implements NativeSurface, MutableSurface {
                     if(LOCK_SUCCESS == res && surfaceHandle_old != getSurfaceHandle()) {
                         res = LOCK_SURFACE_CHANGED;
                         if(DEBUG) {
-                            System.err.println("ProxySurface: surface change 0x"+Long.toHexString(surfaceHandle_old)+" -> 0x"+Long.toHexString(getSurfaceHandle()));
+                            System.err.println("ProxySurfaceImpl: surface change 0x"+Long.toHexString(surfaceHandle_old)+" -> 0x"+Long.toHexString(getSurfaceHandle()));
                             // Thread.dumpStack();
                         }
                     }
@@ -262,9 +254,73 @@ public abstract class ProxySurface implements NativeSurface, MutableSurface {
         return surfaceLock.getOwner();
     }
     
+    public final StringBuilder getUpstreamOptionBits(StringBuilder sink) {
+        if(null == sink) {
+            sink = new StringBuilder();
+        }
+        sink.append("UOB[ ");
+        if(0 == implBitfield) {
+            sink.append("]");
+            return sink;
+        }
+        boolean needsOr = false;
+        if( 0 != ( implBitfield & OPT_PROXY_OWNS_UPSTREAM_SURFACE ) ) {
+            sink.append("OWNS_SURFACE");
+            needsOr = true;
+        }
+        if( 0 != ( implBitfield & OPT_PROXY_OWNS_UPSTREAM_DEVICE ) ) {
+            if(needsOr) {
+                sink.append(" | ");
+            }
+            sink.append("OWNS_DEVICE");
+            needsOr = true;
+        }
+        if( 0 != ( implBitfield & OPT_UPSTREAM_WINDOW_INVISIBLE ) ) {
+            if(needsOr) {
+                sink.append(" | ");
+            }
+            sink.append("WINDOW_INVISIBLE");
+            needsOr = true;
+        }
+        sink.append(" ]");
+        return sink;
+    }
+    
     @Override
-    public abstract String toString();
+    public final int getUpstreamOptionBits() { return implBitfield; }
     
-    public int getImplBitfield() { return implBitfield; }    
-    public void setImplBitfield(int v) { implBitfield=v; }
+    @Override
+    public final boolean containsUpstreamOptionBits(int v) {
+        return v == ( implBitfield & v ) ;
+    }
+    
+    @Override
+    public final void addUpstreamOptionBits(int v) { implBitfield |= v; }
+    
+    @Override
+    public final void clearUpstreamOptionBits(int v) { implBitfield &= ~v; }
+    
+    @Override
+    public StringBuilder toString(StringBuilder sink) {
+        if(null == sink) {
+            sink = new StringBuilder();
+        }
+        sink.append(getUpstreamSurfaceHook()).
+        append(", displayHandle 0x" + Long.toHexString(getDisplayHandle())).
+        append(", surfaceHandle 0x" + Long.toHexString(getSurfaceHandle())).
+        append(", size " + getWidth() + "x" + getHeight()).append(", ");
+        getUpstreamOptionBits(sink);
+        sink.append(", surfaceLock "+surfaceLock);
+        return sink;
+    }
+    
+    @Override
+    public String toString() {
+        StringBuilder msg = new StringBuilder();
+        msg.append(getClass().getSimpleName()).append("[ ");
+        toString(msg);
+        msg.append(" ]");
+        return msg.toString();
+    }
+
 }
diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11ToolkitLock.java b/src/nativewindow/classes/jogamp/nativewindow/ResourceToolkitLock.java
similarity index 58%
rename from src/nativewindow/classes/jogamp/nativewindow/x11/X11ToolkitLock.java
rename to src/nativewindow/classes/jogamp/nativewindow/ResourceToolkitLock.java
index 5166ef5..5b79de0 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11ToolkitLock.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/ResourceToolkitLock.java
@@ -1,5 +1,5 @@
 /**
- * Copyright 2010 JogAmp Community. All rights reserved.
+ * 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:
@@ -25,7 +25,8 @@
  * authors and should not be interpreted as representing official policies, either expressed
  * or implied, of JogAmp Community.
  */
-package jogamp.nativewindow.x11;
+
+package jogamp.nativewindow;
 
 import javax.media.nativewindow.ToolkitLock;
 
@@ -33,38 +34,46 @@ import com.jogamp.common.util.locks.LockFactory;
 import com.jogamp.common.util.locks.RecursiveLock;
 
 /**
- * Implementing a recursive {@link javax.media.nativewindow.ToolkitLock}
- * utilizing {@link X11Util#XLockDisplay(long)}.
- * <br>
- * This strategy should not be used in case XInitThreads() is being used,
- * or a higher level toolkit lock is required, ie AWT lock.
+ * Implementing a resource based recursive {@link javax.media.nativewindow.ToolkitLock}.
+ * <p>
+ * A resource handle maybe used within a unique object
+ * and can be synchronized across threads via an instance of ResourceToolkitLock.
+ * </p>
  */
-public class X11ToolkitLock implements ToolkitLock {
-    long displayHandle;
-    RecursiveLock lock;
-
-    public X11ToolkitLock(long displayHandle) {
-        this.displayHandle = displayHandle;
-        if(!X11Util.isNativeLockAvailable()) {
-            lock = LockFactory.createRecursiveLock();
-        }
+public class ResourceToolkitLock implements ToolkitLock {
+    public static final ResourceToolkitLock create() {
+        return new ResourceToolkitLock();
     }
 
+    private final RecursiveLock lock;
+
+    private ResourceToolkitLock() {
+        this.lock = LockFactory.createRecursiveLock();
+    }
+    
+    @Override
     public final void lock() {
-        if(TRACE_LOCK) { System.err.println("X11ToolkitLock.lock() - native: "+(null==lock)); }
-        if(null == lock) {
-            X11Lib.XLockDisplay(displayHandle);
-        } else {
-            lock.lock();
-        }
+        lock.lock();
+        if(TRACE_LOCK) { System.err.println("ResourceToolkitLock.lock()"); }
     }
 
+    @Override
     public final void unlock() {
-        if(TRACE_LOCK) { System.err.println("X11ToolkitLock.unlock() - native: "+(null==lock)); }
-        if(null == lock) {
-            X11Lib.XUnlockDisplay(displayHandle);
-        } else {
-            lock.unlock();
-        }
+        if(TRACE_LOCK) { System.err.println("ResourceToolkitLock.unlock()"); }
+        lock.unlock(); // implicit lock validation
+    }
+    
+    @Override
+    public final void validateLocked() throws RuntimeException {
+        lock.validateLocked();
+    }
+    
+    @Override
+    public final void dispose() {
+        // nop
+    }
+    
+    public String toString() {
+        return "ResourceToolkitLock[obj 0x"+Integer.toHexString(hashCode())+", isOwner "+lock.isOwner(Thread.currentThread())+", "+lock.toString()+"]";
     }
 }
diff --git a/src/nativewindow/classes/jogamp/nativewindow/SharedResourceToolkitLock.java b/src/nativewindow/classes/jogamp/nativewindow/SharedResourceToolkitLock.java
new file mode 100644
index 0000000..94d12e6
--- /dev/null
+++ b/src/nativewindow/classes/jogamp/nativewindow/SharedResourceToolkitLock.java
@@ -0,0 +1,148 @@
+/**
+ * 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 jogamp.nativewindow;
+
+import java.util.Iterator;
+
+import javax.media.nativewindow.ToolkitLock;
+
+import com.jogamp.common.util.LongObjectHashMap;
+import com.jogamp.common.util.locks.LockFactory;
+import com.jogamp.common.util.locks.RecursiveLock;
+
+/**
+ * Implementing a shared resource based recursive {@link javax.media.nativewindow.ToolkitLock}.
+ * <p>
+ * A resource handle maybe used within many objects
+ * and can be synchronized across threads via an unique instance of SharedResourceToolkitLock.
+ * </p>
+ * <p>
+ * Implementation holds a synchronized map from handle to reference counted {@link SharedResourceToolkitLock}.
+ * New elements are added via {@link #get(long)} if new
+ * and removed via {@link #dispose()} if no more referenced.
+ * </p>
+ */
+public class SharedResourceToolkitLock implements ToolkitLock {
+    private static final LongObjectHashMap handle2Lock;
+    static {
+        handle2Lock = new LongObjectHashMap();
+        handle2Lock.setKeyNotFoundValue(null);
+    }
+    
+    /** 
+     * @return number of unclosed EGL Displays.<br>
+     */
+    public static int shutdown(boolean verbose) {
+        if(DEBUG || verbose || handle2Lock.size() > 0 ) {
+            System.err.println("SharedResourceToolkitLock: Shutdown (open: "+handle2Lock.size()+")");
+            if(DEBUG) {
+                Thread.dumpStack();
+            }
+            if( handle2Lock.size() > 0) {
+                dumpOpenDisplayConnections();
+            }
+        }
+        return handle2Lock.size();
+    }
+    
+    public static void dumpOpenDisplayConnections() {
+        System.err.println("SharedResourceToolkitLock: Open ResourceToolkitLock's: "+handle2Lock.size());
+        int i=0;
+        for(Iterator<LongObjectHashMap.Entry> iter = handle2Lock.iterator(); iter.hasNext(); i++) {
+            final LongObjectHashMap.Entry e = iter.next();
+            System.err.println("SharedResourceToolkitLock: Open["+i+"]: "+e.value);
+        }
+    }
+    
+    public static final SharedResourceToolkitLock get(long handle) {
+        SharedResourceToolkitLock res;
+        synchronized(handle2Lock) {
+            res = (SharedResourceToolkitLock) handle2Lock.get(handle);
+            if( null == res ) {
+                res = new SharedResourceToolkitLock(handle);
+                res.refCount++;
+                handle2Lock.put(handle, res);
+                if(DEBUG || TRACE_LOCK) { System.err.println("SharedResourceToolkitLock.get() * NEW   *: "+res); }
+            } else {
+                res.refCount++;
+                if(DEBUG || TRACE_LOCK) { System.err.println("SharedResourceToolkitLock.get() * EXIST *: "+res); }
+            }
+        }
+        return res;
+    }
+
+    private final RecursiveLock lock;
+    private final long handle;
+    private volatile int refCount;
+
+    private SharedResourceToolkitLock(long handle) {
+        this.lock = LockFactory.createRecursiveLock();
+        this.handle = handle;
+        this.refCount = 0;
+    }
+    
+    
+    @Override
+    public final void lock() {
+        lock.lock();
+        if(TRACE_LOCK) { System.err.println("SharedResourceToolkitLock.lock()"); }
+    }
+
+    @Override
+    public final void unlock() {
+        if(TRACE_LOCK) { System.err.println("SharedResourceToolkitLock.unlock()"); }
+        lock.unlock();
+    }
+    
+    @Override
+    public final void validateLocked() throws RuntimeException {
+        lock.validateLocked();
+    }
+    
+    @Override
+    public final void dispose() {
+        if(0 < refCount) { // volatile OK
+            synchronized(handle2Lock) {
+                refCount--;
+                if(0 == refCount) {
+                    if(DEBUG || TRACE_LOCK) { System.err.println("SharedResourceToolkitLock.dispose() * REMOV *: "+this); }
+                    handle2Lock.remove(handle);
+                } else {
+                    if(DEBUG || TRACE_LOCK) { System.err.println("SharedResourceToolkitLock.dispose() * DOWN  *: "+this); }
+                }
+            }
+        } else {
+            if(DEBUG || TRACE_LOCK) { System.err.println("SharedResourceToolkitLock.dispose() * NULL  *: "+this); }
+        }
+    }
+    
+    public String toString() {
+        return "SharedResourceToolkitLock[refCount "+refCount+", handle 0x"+Long.toHexString(handle)+", obj 0x"+Integer.toHexString(hashCode())+", isOwner "+lock.isOwner(Thread.currentThread())+", "+lock.toString()+"]";
+    }
+}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/ToolkitProperties.java b/src/nativewindow/classes/jogamp/nativewindow/ToolkitProperties.java
new file mode 100644
index 0000000..ed23def
--- /dev/null
+++ b/src/nativewindow/classes/jogamp/nativewindow/ToolkitProperties.java
@@ -0,0 +1,47 @@
+package jogamp.nativewindow;
+
+import javax.media.nativewindow.NativeWindowFactory;
+
+/**
+ * Marker interface.
+ * <p>
+ * Implementation requires to provide static methods:
+ * <pre>
+    public static void initSingleton() {}
+    
+    public static void shutdown() {}
+    
+    public static boolean requiresToolkitLock() {}
+    
+    public static boolean hasThreadingIssues() {}
+ * </pre>
+ * Above static methods are invoked by {@link NativeWindowFactory#initSingleton()}, 
+ * or {@link NativeWindowFactory#shutdown()} via reflection.
+ * </p>
+ */
+public interface ToolkitProperties {
+
+    /**
+     * Called by {@link NativeWindowFactory#initSingleton()}
+     */
+    // void initSingleton();
+    
+    /** 
+     * Cleanup resources.
+     * <p>
+     * Called by {@link NativeWindowFactory#shutdown()}
+     * </p>
+     */
+    // void shutdown();
+    
+    /**
+     * Called by {@link NativeWindowFactory#initSingleton()}
+     */
+    // boolean requiresToolkitLock();
+    
+    /**
+     * Called by {@link NativeWindowFactory#initSingleton()}
+     */
+    // boolean hasThreadingIssues();    
+    
+}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/WrappedSurface.java b/src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java
similarity index 54%
rename from src/nativewindow/classes/com/jogamp/nativewindow/WrappedSurface.java
rename to src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java
index b7f6ba4..e544bc6 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/WrappedSurface.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java
@@ -26,17 +26,46 @@
  * or implied, of JogAmp Community.
  */
 
-package com.jogamp.nativewindow;
+package jogamp.nativewindow;
 
 import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsDevice;
 import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
 
-public class WrappedSurface extends ProxySurface {
-  protected long surfaceHandle;  
+import com.jogamp.nativewindow.UpstreamSurfaceHookMutableSize;
 
-  public WrappedSurface(AbstractGraphicsConfiguration cfg, long handle, int initialWidth, int initialHeight, UpstreamSurfaceHook upstream) {
-    super(cfg, initialWidth, initialHeight, upstream);
-    surfaceHandle=handle;
+public class WrappedSurface extends ProxySurfaceImpl {
+  protected long surfaceHandle;
+
+  /**
+   * Utilizes a {@link UpstreamSurfaceHook.MutableSize} to hold the size information,
+   * which is being passed to the {@link ProxySurface} instance.
+   * 
+   * @param cfg the {@link AbstractGraphicsConfiguration} to be used
+   * @param handle the wrapped pre-existing native surface handle, maybe 0 if not yet determined
+   * @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 WrappedSurface(AbstractGraphicsConfiguration cfg, long handle, int initialWidth, int initialHeight, boolean ownsDevice) {
+      super(cfg, new UpstreamSurfaceHookMutableSize(initialWidth, initialHeight), ownsDevice);
+      surfaceHandle=handle;
+  }
+  
+  /**
+   * @param cfg the {@link AbstractGraphicsConfiguration} to be used
+   * @param handle 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 WrappedSurface(AbstractGraphicsConfiguration cfg, long handle, UpstreamSurfaceHook upstream, boolean ownsDevice) {
+      super(cfg, upstream, ownsDevice);
+      surfaceHandle=handle;
   }
 
   @Override
@@ -63,16 +92,4 @@ public class WrappedSurface extends ProxySurface {
   protected final void unlockSurfaceImpl() {
   }
 
-  @Override
-  public String toString() {
-    final UpstreamSurfaceHook ush = getUpstreamSurfaceHook();
-    final String ush_s = null != ush ? ( ush.getClass().getName() + ": " + ush ) : "nil"; 
-    
-    return "WrappedSurface[config " + getPrivateGraphicsConfiguration()+
-           ", displayHandle 0x" + Long.toHexString(getDisplayHandle()) +
-           ", surfaceHandle 0x" + Long.toHexString(getSurfaceHandle()) +
-           ", size " + getWidth() + "x" + getHeight() +
-           ", surfaceLock "+surfaceLock+
-           ", upstreamSurfaceHook "+ush_s+"]";
-  }
 }
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTJNILibLoader.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTJNILibLoader.java
index 2377c2b..f579da2 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTJNILibLoader.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTJNILibLoader.java
@@ -60,7 +60,7 @@ public class JAWTJNILibLoader extends NWJNILibLoader {
         // ensure references from jogl_awt shared object
         // will succeed since JAWT shared object isn't in
         // default library path
-        if ( ! NativeWindowFactory.TYPE_MACOSX.equals( NativeWindowFactory.getNativeWindowType(false) ) ) {
+        if ( NativeWindowFactory.TYPE_MACOSX != NativeWindowFactory.getNativeWindowType(false) ) {
             try {
                 loadLibrary("jawt", null, true, JAWTJNILibLoader.class.getClassLoader());
             } catch (Throwable t) {
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java
index 36d7c37..349da8e 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java
@@ -48,6 +48,7 @@ import java.util.ArrayList;
 import java.util.Map;
 
 import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.NativeWindowFactory;
 import javax.media.nativewindow.ToolkitLock;
 
 import jogamp.nativewindow.Debug;
@@ -78,6 +79,9 @@ public class JAWTUtil {
   private static final Method  sunToolkitAWTLockMethod;
   private static final Method  sunToolkitAWTUnlockMethod;
   private static final boolean hasSunToolkitAWTLock;
+  
+  private static volatile Thread exclusiveOwnerThread;
+  private static int lockCounter;
 
   private static final ToolkitLock jawtToolkitLock;
 
@@ -228,14 +232,25 @@ public class JAWTUtil {
     }
     hasSunToolkitAWTLock = _hasSunToolkitAWTLock;
     // hasSunToolkitAWTLock = false;
+    exclusiveOwnerThread = null;
+    lockCounter = 0;
 
     jawtToolkitLock = new ToolkitLock() {
           public final void lock() {
               JAWTUtil.lockToolkit();
+              if(TRACE_LOCK) { System.err.println("JAWTToolkitLock.lock()"); }
           }    
           public final void unlock() {
+              if(TRACE_LOCK) { System.err.println("JAWTToolkitLock.unlock()"); }
               JAWTUtil.unlockToolkit();
           }
+          @Override
+          public final void validateLocked() throws RuntimeException {
+              JAWTUtil.validateLocked();
+          }
+          public final void dispose() {
+              // nop
+          }          
       };  
 
     // trigger native AWT toolkit / properties initialization
@@ -271,10 +286,18 @@ public class JAWTUtil {
     }
   }
 
+  /**
+   * Called by {@link NativeWindowFactory#initSingleton()}
+   */
   public static void initSingleton() {
       // just exist to ensure static init has been run
   }
-
+  
+  /**
+   * Called by {@link NativeWindowFactory#shutdown()}
+   */
+  public static void shutdown() {      
+  }
 
   public static boolean hasJava2D() {
     return j2dExist;
@@ -300,7 +323,7 @@ public class JAWTUtil {
    * JAWT's native Lock() function calls SunToolkit.awtLock(),
    * which just uses AWT's global ReentrantLock.<br>
    */
-  private static void awtLock() {
+  private static final void awtLock() {
     if(hasSunToolkitAWTLock) {
         try {
             sunToolkitAWTLockMethod.invoke(null, (Object[])null);
@@ -310,6 +333,10 @@ public class JAWTUtil {
     } else {
         jawtLockObject.Lock();
     }
+    if(0 == lockCounter) {
+        exclusiveOwnerThread = Thread.currentThread();
+    }
+    lockCounter++;
   }
 
   /**
@@ -318,7 +345,12 @@ public class JAWTUtil {
    * JAWT's native Unlock() function calls SunToolkit.awtUnlock(),
    * which just uses AWT's global ReentrantLock.<br>
    */
-  private static void awtUnlock() {
+  private static final void awtUnlock() {
+    awtValidateLocked();
+    lockCounter--;
+    if(0 == lockCounter) {
+        exclusiveOwnerThread = null;
+    }
     if(hasSunToolkitAWTLock) {
         try {
             sunToolkitAWTUnlockMethod.invoke(null, (Object[])null);
@@ -330,6 +362,16 @@ public class JAWTUtil {
     }
   }
 
+  private static final void awtValidateLocked() throws RuntimeException {
+    final Thread ct = Thread.currentThread();
+    if( ct != exclusiveOwnerThread ) {
+        if ( null == exclusiveOwnerThread ) {
+            throw new RuntimeException(ct.getName()+": JAWT-ToolkitLock not locked");
+        }
+        throw new RuntimeException(ct.getName()+": Not JAWT-ToolkitLock owner. Owner is "+exclusiveOwnerThread.getName());
+    }
+  }
+  
   public static void lockToolkit() throws NativeWindowException {
     if(ToolkitLock.TRACE_LOCK) { System.err.println("JAWTUtil-ToolkitLock.lock()"); }
     if(!headlessMode && !isJava2DQueueFlusherThread()) {
@@ -343,6 +385,13 @@ public class JAWTUtil {
         awtUnlock();
     }
   }
+  
+  public static final void validateLocked() throws RuntimeException {
+    if(!headlessMode && !isJava2DQueueFlusherThread()) {
+        awtValidateLocked();
+    }
+  }
+  
 
   public static ToolkitLock getJAWTToolkitLock() {
     return jawtToolkitLock;
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
index e81d61e..5fd2422 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
@@ -51,7 +51,6 @@ import javax.media.nativewindow.NativeWindowException;
 import javax.media.nativewindow.MutableSurface;
 import javax.media.nativewindow.util.Point;
 
-import com.jogamp.nativewindow.MutableGraphicsConfiguration;
 import com.jogamp.nativewindow.awt.JAWTWindow;
 
 import jogamp.nativewindow.jawt.JAWT;
@@ -71,17 +70,18 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface {
   }
 
   protected void invalidateNative() {
-      surfaceHandle=0;
+      offscreenSurfaceHandle=0;
+      offscreenSurfaceHandleSet=false;
       if(isOffscreenLayerSurfaceEnabled()) {
           if(0 != rootSurfaceLayerHandle) {
               OSXUtil.DestroyCALayer(rootSurfaceLayerHandle);
               rootSurfaceLayerHandle = 0;
           }
-          if(0 != drawable) {
-              OSXUtil.DestroyNSWindow(drawable);
-              drawable = 0;
+          if(0 != windowHandle) {
+              OSXUtil.DestroyNSWindow(windowHandle);
           }
       }
+      windowHandle=0;
   }
 
   protected void attachSurfaceLayerImpl(final long layerHandle) {
@@ -92,8 +92,14 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface {
       OSXUtil.RemoveCASublayer(rootSurfaceLayerHandle, layerHandle);
   }
     
-  public long getSurfaceHandle() {
-    return isOffscreenLayerSurfaceEnabled() ? surfaceHandle : super.getSurfaceHandle() ;
+  @Override
+  public final long getWindowHandle() {
+    return windowHandle;
+  }
+  
+  @Override
+  public final long getSurfaceHandle() {
+    return offscreenSurfaceHandleSet ? offscreenSurfaceHandle : drawable /* super.getSurfaceHandle() */ ;
   }
   
   public void setSurfaceHandle(long surfaceHandle) {
@@ -103,7 +109,8 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface {
       if(DEBUG) {
         System.err.println("MacOSXJAWTWindow.setSurfaceHandle(): 0x"+Long.toHexString(surfaceHandle));
       }
-      this.surfaceHandle = surfaceHandle;
+      this.offscreenSurfaceHandle = surfaceHandle;
+      this.offscreenSurfaceHandleSet = true;
   }
 
   protected JAWT fetchJAWTImpl() throws NativeWindowException {
@@ -167,6 +174,7 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface {
           unlockSurfaceImpl();
           return NativeWindow.LOCK_SURFACE_NOT_READY;
         } else {
+          windowHandle = OSXUtil.GetNSWindow(drawable);
           ret = NativeWindow.LOCK_SUCCESS;
         }
     } else {
@@ -177,36 +185,46 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface {
          * The actual surface/ca-layer shall be created/attached 
          * by the upper framework (JOGL) since they require more information. 
          */
+        String errMsg = null;
         if(0 == drawable) {
-            drawable = OSXUtil.CreateNSWindow(0, 0, getBounds().getWidth(), getBounds().getHeight());
-            if(0 == drawable) {
-              unlockSurfaceImpl();
-              throw new NativeWindowException("Unable to created dummy NSWindow (layered case)");
+            windowHandle = OSXUtil.CreateNSWindow(0, 0, 64, 64);
+            if(0 == windowHandle) {
+              errMsg = "Unable to create dummy NSWindow (layered case)";
+            } else {
+                drawable = OSXUtil.GetNSView(windowHandle);
+                if(0 == drawable) {
+                  errMsg = "Null NSView of NSWindow 0x"+Long.toHexString(windowHandle);
+                }
+            }
+            if(null == errMsg) {
+                // fix caps reflecting offscreen! (no GL available here ..)
+                Capabilities caps = (Capabilities) getGraphicsConfiguration().getChosenCapabilities().cloneMutable();
+                caps.setOnscreen(false);
+                setChosenCapabilities(caps);
             }
-            // fix caps reflecting offscreen!
-            Capabilities caps = (Capabilities) getPrivateGraphicsConfiguration().getChosenCapabilities().cloneMutable();
-            caps.setOnscreen(false);
-            getPrivateGraphicsConfiguration().setChosenCapabilities(caps);
-            caps = (Capabilities) getGraphicsConfiguration().getChosenCapabilities().cloneMutable();
-            caps.setOnscreen(false);
-            ((MutableGraphicsConfiguration)getGraphicsConfiguration()).setChosenCapabilities(caps);
         }
-        if(0 == rootSurfaceLayerHandle) {
-            rootSurfaceLayerHandle = OSXUtil.CreateCALayer(bounds.getX(), bounds.getY(), bounds.getWidth(), bounds.getHeight());
-            if(0 == rootSurfaceLayerHandle) {
-              OSXUtil.DestroyNSWindow(drawable);
-              drawable = 0;
-              unlockSurfaceImpl();
-              throw new NativeWindowException("Could not create root CALayer: "+this);                
+        if(null == errMsg) {
+            if(0 == rootSurfaceLayerHandle) {        
+                rootSurfaceLayerHandle = OSXUtil.CreateCALayer(bounds.getX(), bounds.getY(), bounds.getWidth(), bounds.getHeight());
+                if(0 == rootSurfaceLayerHandle) {
+                  errMsg = "Could not create root CALayer";                
+                } else if(!SetJAWTRootSurfaceLayer0(dsi.getBuffer(), rootSurfaceLayerHandle)) {
+                  errMsg = "Could not set JAWT rootSurfaceLayerHandle 0x"+Long.toHexString(rootSurfaceLayerHandle);
+                }
             }
-            if(!SetJAWTRootSurfaceLayer0(dsi.getBuffer(), rootSurfaceLayerHandle)) {
+        }
+        if(null != errMsg) {
+            if(0 != rootSurfaceLayerHandle) {
               OSXUtil.DestroyCALayer(rootSurfaceLayerHandle);
               rootSurfaceLayerHandle = 0;
-              OSXUtil.DestroyNSWindow(drawable);
-              drawable = 0;
-              unlockSurfaceImpl();
-              throw new NativeWindowException("Could not set JAWT rootSurfaceLayerHandle: "+this);
             }
+            if(0 != windowHandle) {
+              OSXUtil.DestroyNSWindow(windowHandle);
+              windowHandle = 0;
+            }
+            drawable = 0;
+            unlockSurfaceImpl();
+            throw new NativeWindowException(errMsg+": "+this);
         }
         ret = NativeWindow.LOCK_SUCCESS;
     }
@@ -264,7 +282,9 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface {
   
   private long rootSurfaceLayerHandle = 0; // attached to the JAWT_SurfaceLayer
   
-  private long surfaceHandle = 0;
+  private long windowHandle = 0;
+  private long offscreenSurfaceHandle = 0;
+  private boolean offscreenSurfaceHandleSet = false;
    
   // Workaround for instance of 4796548
   private boolean firstLock = true;
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java
index 736718d..4678092 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java
@@ -127,7 +127,8 @@ public class X11JAWTWindow extends JAWTWindow {
   }
 
   protected Point getLocationOnScreenNativeImpl(int x, int y) {
-    return X11Lib.GetRelativeLocation( getDisplayHandle(), getScreenIndex(), getWindowHandle(), 0 /*root win*/, x, y);
+    // surface is locked and hence the device
+    return X11Lib.GetRelativeLocation(getDisplayHandle(), getScreenIndex(), getWindowHandle(), 0 /*root win*/, x, y);
   }
   
   // Variables for lockSurface/unlockSurface
diff --git a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXDummyUpstreamSurfaceHook.java b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXDummyUpstreamSurfaceHook.java
new file mode 100644
index 0000000..de3206c
--- /dev/null
+++ b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXDummyUpstreamSurfaceHook.java
@@ -0,0 +1,56 @@
+package jogamp.nativewindow.macosx;
+
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
+
+import com.jogamp.nativewindow.UpstreamSurfaceHookMutableSize;
+
+public class OSXDummyUpstreamSurfaceHook extends UpstreamSurfaceHookMutableSize {
+    long nsWindow;
+    
+    /**
+     * @param width the initial width as returned by {@link NativeSurface#getWidth()} via {@link UpstreamSurfaceHook#getWidth(ProxySurface)}, 
+     *        not the actual dummy surface width. 
+     *        The latter is platform specific and small
+     * @param height the initial height as returned by {@link NativeSurface#getHeight()} via {@link UpstreamSurfaceHook#getHeight(ProxySurface)}, 
+     *        not the actual dummy surface height,
+     *        The latter is platform specific and small
+     */
+    public OSXDummyUpstreamSurfaceHook(int width, int height) {
+        super(width, height);
+        nsWindow = 0;
+    }
+    
+    @Override
+    public final void create(ProxySurface s) {
+        if(0 == nsWindow && 0 == s.getSurfaceHandle()) {
+            nsWindow = OSXUtil.CreateNSWindow(0, 0, 64, 64);
+            if(0 == nsWindow) {
+                throw new NativeWindowException("Error NS window 0");
+            }
+            long nsView = OSXUtil.GetNSView(nsWindow);
+            if(0 == nsView) {
+                throw new NativeWindowException("Error NS view 0");
+            }
+            s.setSurfaceHandle(nsView);
+            s.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );            
+        }
+        s.addUpstreamOptionBits(ProxySurface.OPT_UPSTREAM_WINDOW_INVISIBLE);
+    }
+    
+    @Override
+    public final void destroy(ProxySurface s) {
+        if( s.containsUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE ) ) {
+            if( 0 == nsWindow || 0 == s.getSurfaceHandle() ) {
+                throw new InternalError("Owns upstream surface, but no OSX view/window: "+s+", nsWindow 0x"+Long.toHexString(nsWindow));
+            }
+            OSXUtil.DestroyNSWindow(nsWindow);
+            nsWindow = 0;
+            s.setSurfaceHandle(0);
+            s.clearUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
+        }
+    }
+
+}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
index 894084f..a195f13 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
@@ -28,42 +28,64 @@
 package jogamp.nativewindow.macosx;
 
 import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.NativeWindowFactory;
 import javax.media.nativewindow.util.Insets;
 import javax.media.nativewindow.util.Point;
 
 import jogamp.nativewindow.Debug;
 import jogamp.nativewindow.NWJNILibLoader;
+import jogamp.nativewindow.ToolkitProperties;
 
-public class OSXUtil {
+public class OSXUtil implements ToolkitProperties {
     private static boolean isInit = false;  
     private static final boolean DEBUG = Debug.debug("OSXUtil");
     
-    public static synchronized void initSingleton(boolean firstX11ActionOnProcess) {
+    /**
+     * Called by {@link NativeWindowFactory#initSingleton()}
+     * @see ToolkitProperties
+     */
+    public static synchronized void initSingleton() {
       if(!isInit) {
+          if(DEBUG) {
+              System.out.println("OSXUtil.initSingleton()");
+          }
           if(!NWJNILibLoader.loadNativeWindow("macosx")) {
               throw new NativeWindowException("NativeWindow MacOSX native library load error.");
           }
           
           if( !initIDs0() ) {
               throw new NativeWindowException("MacOSX: Could not initialized native stub");
-          }
-  
-          if(DEBUG) {
-              System.out.println("OSX.isFirstX11ActionOnProcess: "+firstX11ActionOnProcess);
-          }
-  
+          }  
           isInit = true;
       }
     }
 
-    public static boolean requiresToolkitLock() {
-        return false;
-    }
+    /**
+     * Called by {@link NativeWindowFactory#shutdown()}
+     * @see ToolkitProperties
+     */
+    public static void shutdown() { }
+    
+    /**
+     * Called by {@link NativeWindowFactory#initSingleton()}
+     * @see ToolkitProperties
+     */
+    public static boolean requiresToolkitLock() { return false; }
+    
+    /**
+     * Called by {@link NativeWindowFactory#initSingleton()}
+     * @see ToolkitProperties
+     */
+    public static final boolean hasThreadingIssues() { return false; }
     
     public static boolean isNSView(long object) {
         return isNSView0(object);
     }
     
+    public static boolean isNSWindow(long object) {
+        return isNSWindow0(object);
+    }
+    
     /**
      * In case the <code>windowOrView</code> is top-level,
      * you shall set <code>topLevel</code> to true where
@@ -106,6 +128,9 @@ public class OSXUtil {
     public static long GetNSView(long nsWindow) {
       return GetNSView0(nsWindow);
     }
+    public static long GetNSWindow(long nsView) {
+      return GetNSWindow0(nsView);
+    }
     
     public static long CreateCALayer(int x, int y, int width, int height) {
         return CreateCALayer0(x, y, width, height);
@@ -141,6 +166,11 @@ public class OSXUtil {
         return IsMainThread0();
     }
     
+    /** Returns the screen refresh rate in Hz. If unavailable, returns 60Hz. */
+    public static int GetScreenRefreshRate(int scrn_idx) {
+        return GetScreenRefreshRate0(scrn_idx);
+    }
+    
     /***
     private static boolean  isAWTEDTMainThreadInit = false;
     private static boolean  isAWTEDTMainThread;
@@ -164,15 +194,18 @@ public class OSXUtil {
     
     private static native boolean initIDs0();
     private static native boolean isNSView0(long object);
+    private static native boolean isNSWindow0(long object);
     private static native Object GetLocationOnScreen0(long windowOrView, int src_x, int src_y);
     private static native Object GetInsets0(long windowOrView);
     private static native long CreateNSWindow0(int x, int y, int width, int height);
     private static native void DestroyNSWindow0(long nsWindow);
     private static native long GetNSView0(long nsWindow);
+    private static native long GetNSWindow0(long nsView);
     private static native long CreateCALayer0(int x, int y, int width, int height);
     private static native void AddCASublayer0(long rootCALayer, long subCALayer);
     private static native void RemoveCASublayer0(long rootCALayer, long subCALayer);
     private static native void DestroyCALayer0(long caLayer);
     private static native void RunOnMainThread0(boolean waitUntilDone, Runnable runnable);
     private static native boolean IsMainThread0();
+    private static native int GetScreenRefreshRate0(int scrn_idx);
 }
diff --git a/src/nativewindow/classes/jogamp/nativewindow/windows/GDIDummyUpstreamSurfaceHook.java b/src/nativewindow/classes/jogamp/nativewindow/windows/GDIDummyUpstreamSurfaceHook.java
new file mode 100644
index 0000000..aa5f3da
--- /dev/null
+++ b/src/nativewindow/classes/jogamp/nativewindow/windows/GDIDummyUpstreamSurfaceHook.java
@@ -0,0 +1,50 @@
+package jogamp.nativewindow.windows;
+
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
+
+import com.jogamp.nativewindow.UpstreamSurfaceHookMutableSize;
+
+public class GDIDummyUpstreamSurfaceHook extends UpstreamSurfaceHookMutableSize {
+    /**
+     * @param width the initial width as returned by {@link NativeSurface#getWidth()} via {@link UpstreamSurfaceHook#getWidth(ProxySurface)}, 
+     *        not the actual dummy surface width. 
+     *        The latter is platform specific and small
+     * @param height the initial height as returned by {@link NativeSurface#getHeight()} via {@link UpstreamSurfaceHook#getHeight(ProxySurface)}, 
+     *        not the actual dummy surface height,
+     *        The latter is platform specific and small
+     */
+    public GDIDummyUpstreamSurfaceHook(int width, int height) {
+        super(width, height);
+    }
+    
+    @Override
+    public final void create(ProxySurface s) {
+        final GDISurface ms = (GDISurface)s;
+        if(0 == ms.getWindowHandle()) {            
+            final long windowHandle = GDIUtil.CreateDummyWindow(0, 0, 64, 64);
+            if(0 == windowHandle) {
+                throw new NativeWindowException("Error windowHandle 0, werr: "+GDI.GetLastError());
+            }    
+            ms.setWindowHandle(windowHandle);
+            ms.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );            
+        }
+        s.addUpstreamOptionBits(ProxySurface.OPT_UPSTREAM_WINDOW_INVISIBLE);
+    }
+    
+    @Override
+    public final void destroy(ProxySurface s) {
+        final GDISurface ms = (GDISurface)s;
+        if( ms.containsUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE ) ) {
+            if( 0 == ms.getWindowHandle() ) {
+                throw new InternalError("Owns upstream surface, but no GDI window: "+ms);
+            }
+            GDI.ShowWindow(ms.getWindowHandle(), GDI.SW_HIDE);
+            GDIUtil.DestroyDummyWindow(ms.getWindowHandle());
+            ms.setWindowHandle(0);
+            ms.clearUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
+        }
+    }    
+}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/windows/GDISurface.java b/src/nativewindow/classes/jogamp/nativewindow/windows/GDISurface.java
index e368aa6..3db2b5f 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/windows/GDISurface.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/windows/GDISurface.java
@@ -29,9 +29,13 @@
 package jogamp.nativewindow.windows;
 
 import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsDevice;
 import javax.media.nativewindow.NativeWindowException;
 import javax.media.nativewindow.ProxySurface;
-import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook;
+import javax.media.nativewindow.UpstreamSurfaceHook;
+
+import jogamp.nativewindow.ProxySurfaceImpl;
+import jogamp.nativewindow.windows.GDI;
 
 
 /**
@@ -40,12 +44,20 @@ import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook;
  * The latter will get and release the HDC.
  * The size via getWidth()/getHeight() is invalid.
  */
-public class GDISurface extends ProxySurface {
+public class GDISurface extends ProxySurfaceImpl {
   protected long windowHandle;
   protected long surfaceHandle;
 
-  public GDISurface(AbstractGraphicsConfiguration cfg, long windowHandle, int initialWidth, int initialHeight, UpstreamSurfaceHook upstream) {
-    super(cfg, initialWidth, initialHeight, upstream);
+  /**
+   * @param cfg the {@link AbstractGraphicsConfiguration} to be used
+   * @param windowHandle the wrapped pre-existing native window 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>. Owning the device implies closing it at {@link #destroyNotify()}.
+   */
+  public GDISurface(AbstractGraphicsConfiguration cfg, long windowHandle, UpstreamSurfaceHook upstream, boolean ownsDevice) {
+    super(cfg, upstream, ownsDevice);
     this.windowHandle=windowHandle;
     this.surfaceHandle=0;
   }
@@ -114,18 +126,4 @@ public class GDISurface extends ProxySurface {
   final public long getSurfaceHandle() {
     return surfaceHandle;
   }
-
-  @Override
-  final public String toString() {
-    final UpstreamSurfaceHook ush = getUpstreamSurfaceHook();
-    final String ush_s = null != ush ? ( ush.getClass().getName() + ": " + ush ) : "nil";       
-    return getClass().getSimpleName()+"[config "+getPrivateGraphicsConfiguration()+
-                ", displayHandle 0x"+Long.toHexString(getDisplayHandle())+
-                ", windowHandle 0x"+Long.toHexString(windowHandle)+
-                ", surfaceHandle 0x"+Long.toHexString(getSurfaceHandle())+
-                ", size "+getWidth()+"x"+getHeight()+
-                ", surfaceLock "+surfaceLock+
-                ", upstreamSurfaceHook "+ush_s+"]";
-  }
-
 }
diff --git a/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java b/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java
index d17a189..2f4e183 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java
@@ -29,43 +29,63 @@ package jogamp.nativewindow.windows;
 
 import javax.media.nativewindow.util.Point;
 import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.NativeWindowFactory;
 
 import jogamp.nativewindow.NWJNILibLoader;
 import jogamp.nativewindow.Debug;
+import jogamp.nativewindow.ToolkitProperties;
 import jogamp.nativewindow.x11.X11Util;
 
-public class GDIUtil {
+public class GDIUtil implements ToolkitProperties {
     private static final boolean DEBUG = Debug.debug("GDIUtil");
   
     private static final String dummyWindowClassNameBase = "_dummyWindow_clazz" ;
     private static RegisteredClassFactory dummyWindowClassFactory;
     private static boolean isInit = false;
   
-    public static synchronized void initSingleton(boolean firstX11ActionOnProcess) {
+    /**
+     * Called by {@link NativeWindowFactory#initSingleton()}
+     * @see ToolkitProperties
+     */
+    public static synchronized void initSingleton() {
         if(!isInit) {
             synchronized(X11Util.class) {
                 if(!isInit) {
-                    isInit = true;
+                    if(DEBUG) {
+                        System.out.println("GDI.initSingleton()");
+                    }
                     if(!NWJNILibLoader.loadNativeWindow("win32")) {
                         throw new NativeWindowException("NativeWindow Windows native library load error.");
                     }
-
                     if( !initIDs0() ) {
                         throw new NativeWindowException("GDI: Could not initialized native stub");
                     }
-
-                    if(DEBUG) {
-                        System.out.println("GDI.isFirstX11ActionOnProcess: "+firstX11ActionOnProcess);
-                    }
-
-                    dummyWindowClassFactory = new RegisteredClassFactory(dummyWindowClassNameBase, getDummyWndProc0());
+                    dummyWindowClassFactory = new RegisteredClassFactory(dummyWindowClassNameBase, getDummyWndProc0());                    
+                    isInit = true;
                 }
             }
         }
     }
   
+    /**
+     * Called by {@link NativeWindowFactory#shutdown()}
+     * @see ToolkitProperties
+     */
+    public static void shutdown() {      
+    }
+    
+    /**
+     * Called by {@link NativeWindowFactory#initSingleton()}
+     * @see ToolkitProperties
+     */
     public static boolean requiresToolkitLock() { return false; }
   
+    /**
+     * Called by {@link NativeWindowFactory#initSingleton()}
+     * @see ToolkitProperties
+     */
+    public static final boolean hasThreadingIssues() { return false; }
+    
     private static RegisteredClass dummyWindowClass = null;
     private static Object dummyWindowSync = new Object();
   
diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11DummyUpstreamSurfaceHook.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11DummyUpstreamSurfaceHook.java
new file mode 100644
index 0000000..67a33e5
--- /dev/null
+++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11DummyUpstreamSurfaceHook.java
@@ -0,0 +1,70 @@
+package jogamp.nativewindow.x11;
+
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
+
+import jogamp.nativewindow.x11.X11Lib;
+
+import com.jogamp.nativewindow.UpstreamSurfaceHookMutableSize;
+import com.jogamp.nativewindow.x11.X11GraphicsConfiguration;
+import com.jogamp.nativewindow.x11.X11GraphicsDevice;
+import com.jogamp.nativewindow.x11.X11GraphicsScreen;
+
+public class X11DummyUpstreamSurfaceHook extends UpstreamSurfaceHookMutableSize {
+    /**
+     * @param width the initial width as returned by {@link NativeSurface#getWidth()} via {@link UpstreamSurfaceHook#getWidth(ProxySurface)}, 
+     *        not the actual dummy surface width. 
+     *        The latter is platform specific and small
+     * @param height the initial height as returned by {@link NativeSurface#getHeight()} via {@link UpstreamSurfaceHook#getHeight(ProxySurface)}, 
+     *        not the actual dummy surface height,
+     *        The latter is platform specific and small
+     */
+    public X11DummyUpstreamSurfaceHook(int width, int height) {
+        super(width, height);
+    }
+    
+    @Override
+    public final void create(ProxySurface s) {
+        final X11GraphicsConfiguration cfg = (X11GraphicsConfiguration) s.getGraphicsConfiguration();
+        final X11GraphicsScreen screen = (X11GraphicsScreen) cfg.getScreen();
+        final X11GraphicsDevice device = (X11GraphicsDevice) screen.getDevice();
+        device.lock();
+        try {
+            if(0 == device.getHandle()) {
+                device.open();
+                s.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE );
+            }
+            if( 0 == s.getSurfaceHandle() ) {
+                final long windowHandle = X11Lib.CreateDummyWindow(device.getHandle(), screen.getIndex(), cfg.getXVisualID(), 64, 64);
+                if(0 == windowHandle) {
+                    throw new NativeWindowException("Creating dummy window failed w/ "+cfg);
+                }
+                s.setSurfaceHandle(windowHandle);
+                s.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );            
+            }
+            s.addUpstreamOptionBits(ProxySurface.OPT_UPSTREAM_WINDOW_INVISIBLE);
+        } finally {
+            device.unlock();
+        }
+    }
+    
+    @Override
+    public final void destroy(ProxySurface s) {
+        if( s.containsUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE ) ) {
+            final X11GraphicsDevice device = (X11GraphicsDevice) s.getGraphicsConfiguration().getScreen().getDevice();
+            if( 0 == s.getSurfaceHandle() ) {
+                throw new InternalError("Owns upstream surface, but no X11 window: "+s);
+            }
+            device.lock();
+            try {
+                X11Lib.DestroyDummyWindow(device.getHandle(), s.getSurfaceHandle());            
+                s.setSurfaceHandle(0);
+                s.clearUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
+            } finally {
+                device.unlock();
+            }
+        }
+    }
+}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
index 7b46a1d..c771cd6 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
@@ -34,6 +34,7 @@
 package jogamp.nativewindow.x11;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 
 import javax.media.nativewindow.AbstractGraphicsDevice;
@@ -42,13 +43,15 @@ import javax.media.nativewindow.NativeWindowFactory;
 
 import jogamp.nativewindow.Debug;
 import jogamp.nativewindow.NWJNILibLoader;
+import jogamp.nativewindow.ToolkitProperties;
 
 import com.jogamp.common.util.LongObjectHashMap;
+import com.jogamp.nativewindow.x11.X11GraphicsDevice;
 
 /**
  * Contains a thread safe X11 utility to retrieve display connections.
  */
-public class X11Util {
+public class X11Util implements ToolkitProperties {
     /** 
      * See Bug 515 - https://jogamp.org/bugzilla/show_bug.cgi?id=515
      * <p> 
@@ -67,48 +70,56 @@ public class X11Util {
      * </p>
      * <p>
      * You may test this, ie just reverse the destroy order below.
-     * See also native test: jogl/test/native/displayMultiple02.c
+     * See also native test: jogl/test-native/displayMultiple02.c
      * </p>
      * <p>
-     * Workaround is to not close them at all if driver vendor is ATI.
+     * Workaround is to not close them at all if driver vendor is ATI
+     * during operation.
+     * </p>
+     * <p>
+     * With ATI X11 drivers all connections must be closed at JVM shutdown,
+     * otherwise a SIGSEGV (after JVM safepoint) will be caused. 
      * </p>
      */
-    public static final boolean ATI_HAS_XCLOSEDISPLAY_BUG = true;
+    public static final boolean ATI_HAS_XCLOSEDISPLAY_BUG = !Debug.isPropertyDefined("nativewindow.debug.X11Util.ATI_HAS_NO_XCLOSEDISPLAY_BUG", true);
+
+    /**
+     * See Bug 623 - https://jogamp.org/bugzilla/show_bug.cgi?id=623
+     */
+    public static final boolean ATI_HAS_MULTITHREADING_BUG = !Debug.isPropertyDefined("nativewindow.debug.X11Util.ATI_HAS_NO_MULTITHREADING_BUG", true);
 
-    /** Value is <code>true</code>, best 'stable' results if always using XInitThreads(). */
-    public static final boolean XINITTHREADS_ALWAYS_ENABLED = true;
-    
-    /** Value is <code>true</code>, best 'stable' results if not using XLockDisplay/XUnlockDisplay at all. */
-    public static final boolean HAS_XLOCKDISPLAY_BUG = true;
-    
     public static final boolean DEBUG = Debug.debug("X11Util");
     public static final boolean XSYNC_ENABLED = Debug.isPropertyDefined("nativewindow.debug.X11Util.XSync", true);
     public static final boolean XERROR_STACKDUMP = DEBUG || Debug.isPropertyDefined("nativewindow.debug.X11Util.XErrorStackDump", true);
     private static final boolean TRACE_DISPLAY_LIFECYCLE = Debug.isPropertyDefined("nativewindow.debug.X11Util.TraceDisplayLifecycle", true);
     private static String nullDisplayName = null;
-    private static boolean isX11LockAvailable = false;
-    private static boolean requiresX11Lock = true;
     private static volatile boolean isInit = false;
     private static boolean markAllDisplaysUnclosable = false; // ATI/AMD X11 driver issues
+    private static boolean hasThreadingIssues = false; // ATI/AMD X11 driver issues
 
-    private static int setX11ErrorHandlerRecCount = 0;
     private static Object setX11ErrorHandlerLock = new Object();
-
+    private static final String X11_EXTENSION_ATIFGLRXDRI     = "ATIFGLRXDRI";
+    private static final String X11_EXTENSION_ATIFGLEXTENSION = "ATIFGLEXTENSION";
     
-    @SuppressWarnings("unused")
-    public static void initSingleton(final boolean firstX11ActionOnProcess) {
+    /**
+     * Called by {@link NativeWindowFactory#initSingleton()}
+     * @see ToolkitProperties
+     */
+    public static void initSingleton() {
         if(!isInit) {
             synchronized(X11Util.class) {
                 if(!isInit) {
                     isInit = true;
+                    if(DEBUG) {
+                        System.out.println("X11Util.initSingleton()");
+                    }
                     if(!NWJNILibLoader.loadNativeWindow("x11")) {
                         throw new NativeWindowException("NativeWindow X11 native library load error.");
                     }
         
-                    final boolean callXInitThreads = XINITTHREADS_ALWAYS_ENABLED || firstX11ActionOnProcess;
-                    final boolean isXInitThreadsOK = initialize0( XINITTHREADS_ALWAYS_ENABLED || firstX11ActionOnProcess, XERROR_STACKDUMP);
-                    isX11LockAvailable = isXInitThreadsOK && !HAS_XLOCKDISPLAY_BUG ;
+                    final boolean isInitOK = initialize0( XERROR_STACKDUMP );
         
+                    final boolean hasX11_EXTENSION_ATIFGLRXDRI, hasX11_EXTENSION_ATIFGLEXTENSION;
                     final long dpy = X11Lib.XOpenDisplay(null);
                     if(0 != dpy) {
                         if(XSYNC_ENABLED) {
@@ -116,20 +127,29 @@ public class X11Util {
                         }                    
                         try {
                             nullDisplayName = X11Lib.XDisplayString(dpy);
+                            hasX11_EXTENSION_ATIFGLRXDRI = X11Lib.QueryExtension(dpy, X11_EXTENSION_ATIFGLRXDRI);
+                            hasX11_EXTENSION_ATIFGLEXTENSION = X11Lib.QueryExtension(dpy, X11_EXTENSION_ATIFGLEXTENSION);
                         } finally {
                             X11Lib.XCloseDisplay(dpy);
                         }
                     } else {
                         nullDisplayName = "nil";
+                        hasX11_EXTENSION_ATIFGLRXDRI = false;
+                        hasX11_EXTENSION_ATIFGLEXTENSION = false;
                     }
+                    hasThreadingIssues = ATI_HAS_MULTITHREADING_BUG && ( hasX11_EXTENSION_ATIFGLRXDRI || hasX11_EXTENSION_ATIFGLEXTENSION );
+                    markAllDisplaysUnclosable = ATI_HAS_XCLOSEDISPLAY_BUG && ( hasX11_EXTENSION_ATIFGLRXDRI || hasX11_EXTENSION_ATIFGLEXTENSION );
                     
                     if(DEBUG) {
-                        System.err.println("X11Util firstX11ActionOnProcess: "+firstX11ActionOnProcess+
-                                           ", requiresX11Lock "+requiresX11Lock+
-                                           ", XInitThreads [called "+callXInitThreads+", OK "+isXInitThreadsOK+"]"+
-                                           ", isX11LockAvailable "+isX11LockAvailable+
-                                           ", X11 Display(NULL) <"+nullDisplayName+">"+
-                                           ", XSynchronize Enabled: "+XSYNC_ENABLED);
+                        System.err.println("X11Util.initSingleton(): OK "+isInitOK+"]"+
+                                           ",\n\t X11 Display(NULL) <"+nullDisplayName+">"+
+                                           ",\n\t XSynchronize Enabled: " + XSYNC_ENABLED+
+                                           ",\n\t X11_EXTENSION_ATIFGLRXDRI " + hasX11_EXTENSION_ATIFGLRXDRI+
+                                           ",\n\t X11_EXTENSION_ATIFGLEXTENSION " + hasX11_EXTENSION_ATIFGLEXTENSION+
+                                           ",\n\t requiresToolkitLock "+requiresToolkitLock()+
+                                           ",\n\t hasThreadingIssues "+hasThreadingIssues()+
+                                           ",\n\t markAllDisplaysUnclosable "+getMarkAllDisplaysUnclosable()
+                                           );
                         // Thread.dumpStack();
                     }
                 }
@@ -137,30 +157,84 @@ public class X11Util {
         }
     }
     
-    public static synchronized boolean isNativeLockAvailable() {
-        return isX11LockAvailable;
+    // not exactly thread safe, but good enough for our purpose,
+    // which is to tag a NamedDisplay uncloseable after creation.
+    private static Object globalLock = new Object(); 
+    private static LongObjectHashMap openDisplayMap = new LongObjectHashMap(); // handle -> name
+    private static List<NamedDisplay> openDisplayList = new ArrayList<NamedDisplay>();     // open, no close attempt
+    private static List<NamedDisplay> reusableDisplayList = new ArrayList<NamedDisplay>(); // close attempt, marked uncloseable, for reuse
+    private static List<NamedDisplay> pendingDisplayList = new ArrayList<NamedDisplay>();  // all open (close attempt or reusable) in creation order
+    private static final HashMap<String /* displayName */, Boolean> displayXineramaEnabledMap = new HashMap<String, Boolean>();
+    
+    /** 
+     * Cleanup resources.
+     * <p>
+     * Called by {@link NativeWindowFactory#shutdown()}
+     * </p>
+     * @see ToolkitProperties
+     */
+    public static void shutdown() {
+        if(isInit) {
+            synchronized(X11Util.class) {
+                if(isInit) {                    
+                    final boolean isJVMShuttingDown = NativeWindowFactory.isJVMShuttingDown() ;
+                    if(DEBUG || openDisplayMap.size() > 0 || reusableDisplayList.size() > 0 || pendingDisplayList.size() > 0) {
+                        System.err.println("X11Util.Display: Shutdown (JVM shutdown: "+isJVMShuttingDown+
+                                           ", open (no close attempt): "+openDisplayMap.size()+"/"+openDisplayList.size()+
+                                           ", reusable (open, marked uncloseable): "+reusableDisplayList.size()+
+                                           ", pending (open in creation order): "+pendingDisplayList.size()+
+                                           ")");
+                        if(DEBUG) {
+                            Thread.dumpStack();
+                        }
+                        if( openDisplayList.size() > 0) {
+                            X11Util.dumpOpenDisplayConnections();
+                        }
+                        if(DEBUG) {
+                            if( reusableDisplayList.size() > 0 || pendingDisplayList.size() > 0 ) {
+                                X11Util.dumpPendingDisplayConnections();
+                            }
+                        }
+                    }
+            
+                    synchronized(globalLock) {
+                        // Only at JVM shutdown time, since AWT impl. seems to 
+                        // dislike closing of X11 Display's (w/ ATI driver). 
+                        if( isJVMShuttingDown ) {
+                            isInit = false;                            
+                            closePendingDisplayConnections();    
+                            openDisplayList.clear();
+                            reusableDisplayList.clear();
+                            pendingDisplayList.clear();
+                            openDisplayMap.clear();
+                            displayXineramaEnabledMap.clear();
+                            shutdown0();
+                        }
+                    }
+                }
+            }
+        }
     }
-
-    public static synchronized boolean requiresToolkitLock() {
-        return requiresX11Lock;
+    
+    /**
+     * Called by {@link NativeWindowFactory#initSingleton()}
+     * @see ToolkitProperties
+     */
+    public static final boolean requiresToolkitLock() {
+        return true; // JAWT locking: yes, instead of native X11 locking w use a recursive lock per display connection.
     }
-
+    
+    /**
+     * Called by {@link NativeWindowFactory#initSingleton()}
+     * @see ToolkitProperties
+     */
+    public static final boolean hasThreadingIssues() {
+        return hasThreadingIssues; // JOGL impl. may utilize special locking "somewhere" 
+    }
+    
     public static void setX11ErrorHandler(boolean onoff, boolean quiet) {
         synchronized(setX11ErrorHandlerLock) {
-            if(onoff) {
-                if(0==setX11ErrorHandlerRecCount) {
-                    setX11ErrorHandler0(true, quiet);
-                }
-                setX11ErrorHandlerRecCount++;
-            } else {
-                if(0 >= setX11ErrorHandlerRecCount) {
-                    throw new InternalError();
-                }
-                setX11ErrorHandlerRecCount--;
-                if(0==setX11ErrorHandlerRecCount) {
-                    setX11ErrorHandler0(false, false);
-                }
-            }
+            setX11ErrorHandler0(onoff, quiet);
         }
     }
 
@@ -171,19 +245,9 @@ public class X11Util {
     public static boolean getMarkAllDisplaysUnclosable() {
         return markAllDisplaysUnclosable;
     }
-    public static void setMarkAllDisplaysUnclosable(boolean v) {
-        markAllDisplaysUnclosable = v;
-    }
     
     private X11Util() {}
 
-    // not exactly thread safe, but good enough for our purpose,
-    // which is to tag a NamedDisplay uncloseable after creation.
-    private static Object globalLock = new Object(); 
-    private static LongObjectHashMap openDisplayMap = new LongObjectHashMap(); // handle -> name
-    private static List<NamedDisplay> openDisplayList = new ArrayList<NamedDisplay>();
-    private static List<NamedDisplay> pendingDisplayList = new ArrayList<NamedDisplay>();
-
     public static class NamedDisplay {
         final String name;
         final long   handle;
@@ -217,8 +281,7 @@ public class X11Util {
         public final boolean equals(Object obj) {
             if(this == obj) { return true; }
             if(obj instanceof NamedDisplay) {
-                NamedDisplay n = (NamedDisplay) obj;
-                return handle == n.handle;
+                return handle == ((NamedDisplay) obj).handle;
             }
             return false;
         }
@@ -245,61 +308,25 @@ public class X11Util {
         }
     }
 
-    /** 
-     * Cleanup resources. 
-     * If <code>realXCloseOpenAndPendingDisplays</code> is <code>false</code>, 
-     * keep alive all references (open display connection) for restart on same ClassLoader.
-     * 
-     * @return number of unclosed X11 Displays.<br>
-     * @param realXCloseOpenAndPendingDisplays if true, {@link #closePendingDisplayConnections()} is called.
-     */
-    public static int shutdown(boolean realXCloseOpenAndPendingDisplays, boolean verbose) {
-        int num=0;
-        if(DEBUG || verbose || openDisplayMap.size() > 0 || pendingDisplayList.size() > 0) {
-            System.err.println("X11Util.Display: Shutdown (close open / pending Displays: "+realXCloseOpenAndPendingDisplays+
-                               ", open (no close attempt): "+openDisplayMap.size()+"/"+openDisplayList.size()+
-                               ", pending (not closed, marked uncloseable): "+pendingDisplayList.size()+")");
-            if(DEBUG) {
-                Thread.dumpStack();
-            }
-            if( openDisplayList.size() > 0) {
-                X11Util.dumpOpenDisplayConnections();
-            }
-            if( pendingDisplayList.size() > 0 ) {
-                X11Util.dumpPendingDisplayConnections();
-            }
-        }
-
-        synchronized(globalLock) {
-            if(realXCloseOpenAndPendingDisplays) {
-                closePendingDisplayConnections();    
-                openDisplayList.clear();
-                pendingDisplayList.clear();
-                openDisplayMap.clear();
-                shutdown0();
-            }
-        }
-        return num;
-    }
-
     /**
-     * Closing pending Display connections in reverse order.
+     * Closing pending Display connections in original creation order, if {@link #getMarkAllDisplaysUnclosable()} is true.
      *
      * @return number of closed Display connections
      */
-    public static int closePendingDisplayConnections() {
+    private static int closePendingDisplayConnections() {
         int num=0;
         synchronized(globalLock) {
-            if(DEBUG) {
-                System.err.println("X11Util: Closing Pending X11 Display Connections: "+pendingDisplayList.size());
-            }
-            for(int i=pendingDisplayList.size()-1; i>=0; i--) {
-                NamedDisplay ndpy = (NamedDisplay) pendingDisplayList.get(i);
-                if(DEBUG) {
-                    System.err.println("X11Util.closePendingDisplayConnections(): Closing ["+i+"]: "+ndpy);
+            if( getMarkAllDisplaysUnclosable() ) {
+                for(int i=0; i<pendingDisplayList.size(); i++) {
+                    final NamedDisplay ndpy = (NamedDisplay) pendingDisplayList.get(i);
+                    if(DEBUG) {
+                        final boolean closeAttempted = !openDisplayMap.containsKey(ndpy.getHandle());
+                        System.err.println("X11Util.closePendingDisplayConnections(): Closing ["+i+"]: "+ndpy+" - closeAttempted "+closeAttempted);
+                    }
+                    XCloseDisplay(ndpy.getHandle());
+                    num++;
                 }
-                XCloseDisplay(ndpy.getHandle());
-                num++;
+                System.err.println("X11Util.closePendingDisplayConnections(): Closed "+num+" pending display connections");
             }
         }
         return num;
@@ -327,6 +354,12 @@ public class X11Util {
         }
     }
     
+    public static int getReusableDisplayConnectionNumber() {
+        synchronized(globalLock) {
+            return reusableDisplayList.size();
+        }
+    }
+
     public static int getPendingDisplayConnectionNumber() {
         synchronized(globalLock) {
             return pendingDisplayList.size();
@@ -335,7 +368,18 @@ public class X11Util {
 
     public static void dumpPendingDisplayConnections() {
         synchronized(globalLock) {
-            System.err.println("X11Util: Pending X11 Display Connections: "+pendingDisplayList.size());
+            System.err.println("X11Util: Reusable X11 Display Connections: "+reusableDisplayList.size());
+            for(int i=0; i<reusableDisplayList.size(); i++) {
+                NamedDisplay ndpy = (NamedDisplay) reusableDisplayList.get(i);
+                System.err.println("X11Util: Reusable["+i+"]: "+ndpy);
+                if(null!=ndpy) {
+                    Throwable t = ndpy.getCreationStack();
+                    if(null!=t) {
+                        t.printStackTrace();
+                    }
+                }
+            }
+            System.err.println("X11Util: Pending X11 Display Connections (creation order): "+pendingDisplayList.size());
             for(int i=0; i<pendingDisplayList.size(); i++) {
                 NamedDisplay ndpy = (NamedDisplay) pendingDisplayList.get(i);
                 System.err.println("X11Util: Pending["+i+"]: "+ndpy);
@@ -368,10 +412,10 @@ public class X11Util {
         name = validateDisplayName(name);
         boolean reused = false;
         
-        synchronized(globalLock) {            
-            for(int i=0; i<pendingDisplayList.size(); i++) {
-                if(pendingDisplayList.get(i).getName().equals(name)) {
-                    namedDpy = pendingDisplayList.remove(i);
+        synchronized(globalLock) {
+            for(int i=0; i<reusableDisplayList.size(); i++) {
+                if(reusableDisplayList.get(i).getName().equals(name)) {
+                    namedDpy = reusableDisplayList.remove(i);
                     dpy = namedDpy.getHandle();
                     reused = true;
                     break;
@@ -385,6 +429,7 @@ public class X11Util {
                 // if you like to debug and synchronize X11 commands ..
                 // setSynchronizeDisplay(dpy, true);
                 namedDpy = new NamedDisplay(name, dpy);
+                pendingDisplayList.add(namedDpy);
             }
             namedDpy.addRef();
             openDisplayMap.put(dpy, namedDpy);
@@ -419,9 +464,11 @@ public class X11Util {
             
             if(!namedDpy.isUncloseable()) {
                 XCloseDisplay(namedDpy.getHandle());
+                pendingDisplayList.remove(namedDpy);
             } else {
                 // for reuse
-                pendingDisplayList.add(namedDpy);
+                X11Lib.XSync(namedDpy.getHandle(), true); // flush output buffer and discard all events                
+                reusableDisplayList.add(namedDpy);
             }
             
             if(DEBUG) {
@@ -457,53 +504,60 @@ public class X11Util {
      *******************************/
 
     public static long XOpenDisplay(String arg0) {
-        NativeWindowFactory.getDefaultToolkitLock().lock();
-        try {
-            long handle = X11Lib.XOpenDisplay(arg0);
-            if(XSYNC_ENABLED && 0 != handle) {
-                X11Lib.XSynchronize(handle, true);
-            }                    
-            if(TRACE_DISPLAY_LIFECYCLE) {
-                System.err.println(Thread.currentThread()+" - X11Util.XOpenDisplay("+arg0+") 0x"+Long.toHexString(handle));
-                // Thread.dumpStack();
-            }
-            return handle;
-        } finally {
-            NativeWindowFactory.getDefaultToolkitLock().unlock();
+        long handle = X11Lib.XOpenDisplay(arg0);
+        if(XSYNC_ENABLED && 0 != handle) {
+            X11Lib.XSynchronize(handle, true);
+        }                    
+        if(TRACE_DISPLAY_LIFECYCLE) {
+            System.err.println(Thread.currentThread()+" - X11Util.XOpenDisplay("+arg0+") 0x"+Long.toHexString(handle));
+            // Thread.dumpStack();
         }
+        return handle;
     }
 
     public static int XCloseDisplay(long display) {
-        NativeWindowFactory.getDefaultToolkitLock().lock();
+        if(TRACE_DISPLAY_LIFECYCLE) {
+            System.err.println(Thread.currentThread()+" - X11Util.XCloseDisplay() 0x"+Long.toHexString(display));
+            // Thread.dumpStack();
+        }
+        int res = -1;
         try {
-            if(TRACE_DISPLAY_LIFECYCLE) {
-                System.err.println(Thread.currentThread()+" - X11Util.XCloseDisplay() 0x"+Long.toHexString(display));
-                // Thread.dumpStack();
-            }
-            int res = -1;            
-            X11Util.setX11ErrorHandler(true, DEBUG ? false : true);
-            try {
-                res = X11Lib.XCloseDisplay(display);
-            } catch (Exception ex) {
-                System.err.println("X11Util: Catched Exception:");
-                ex.printStackTrace();
-            } finally {
-                X11Util.setX11ErrorHandler(false, false);                    
-            }
-            return res;            
-        } finally {
-            NativeWindowFactory.getDefaultToolkitLock().unlock();
+            res = X11Lib.XCloseDisplay(display);
+        } catch (Exception ex) {
+            System.err.println("X11Util: Catched Exception:");
+            ex.printStackTrace();
         }
+        return res;            
     }
 
     static volatile boolean XineramaFetched = false;
     static long XineramaLibHandle = 0;
     static long XineramaQueryFunc = 0;
     
-    public static boolean XineramaIsEnabled(long display) {
-        if(0==display) {
-            throw new IllegalArgumentException("Display NULL");
+    public static boolean XineramaIsEnabled(X11GraphicsDevice device) {
+        if(null == device) {
+            throw new IllegalArgumentException("X11 Display device is NULL");
+        }
+        device.lock();
+        try {
+            return XineramaIsEnabled(device.getHandle());
+        } finally {
+            device.unlock();
+        }        
+    }
+    
+    public static boolean XineramaIsEnabled(long displayHandle) {
+        if( 0 == displayHandle ) {
+            throw new IllegalArgumentException("X11 Display handle is NULL");
         }
+        final String displayName = X11Lib.XDisplayString(displayHandle);
+        synchronized(displayXineramaEnabledMap) {
+            final Boolean b = displayXineramaEnabledMap.get(displayName);
+            if(null != b) {
+                return b.booleanValue();
+            }
+        }
+        final boolean res;
         if(!XineramaFetched) { // volatile: ok
             synchronized(X11Util.class) {
                 if( !XineramaFetched ) {
@@ -516,22 +570,27 @@ public class X11Util {
             }
         }
         if(0!=XineramaQueryFunc) {
-            final boolean res = X11Lib.XineramaIsEnabled(XineramaQueryFunc, display);
+            res = X11Lib.XineramaIsEnabled(XineramaQueryFunc, displayHandle);
+        } else {
             if(DEBUG) {
-                System.err.println("XineramaIsEnabled: "+res);
+                System.err.println("XineramaIsEnabled: Couldn't bind to Xinerama - lib 0x"+Long.toHexString(XineramaLibHandle)+
+                                   "query 0x"+Long.toHexString(XineramaQueryFunc));
             }
-            return res;
-        } else if(DEBUG) {
-            System.err.println("XineramaIsEnabled: Couldn't bind to Xinerama - lib 0x"+Long.toHexString(XineramaLibHandle)+
-                               "query 0x"+Long.toHexString(XineramaQueryFunc));
+            res = false;
         }
-        return false;
+        synchronized(displayXineramaEnabledMap) {
+            if(DEBUG) {
+                System.err.println("XineramaIsEnabled Cache: Display "+displayName+" (0x"+Long.toHexString(displayHandle)+") -> "+res);
+            }
+            displayXineramaEnabledMap.put(displayName, Boolean.valueOf(res));
+        }
+        return res;
     }
     
     private static final String getCurrentThreadName() { return Thread.currentThread().getName(); } // Callback for JNI
     private static final void dumpStack() { Thread.dumpStack(); } // Callback for JNI
     
-    private static native boolean initialize0(boolean firstUIActionOnProcess, boolean debug);
+    private static native boolean initialize0(boolean debug);
     private static native void shutdown0();
     private static native void setX11ErrorHandler0(boolean onoff, boolean quiet);
 }
diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/awt/X11AWTGraphicsConfigurationFactory.java b/src/nativewindow/classes/jogamp/nativewindow/x11/awt/X11AWTGraphicsConfigurationFactory.java
index 1de03e8..b152f0f 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/x11/awt/X11AWTGraphicsConfigurationFactory.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/x11/awt/X11AWTGraphicsConfigurationFactory.java
@@ -91,7 +91,7 @@ public class X11AWTGraphicsConfigurationFactory extends GraphicsConfigurationFac
         
         final long displayHandleAWT = X11SunJDKReflection.graphicsDeviceGetDisplay(device);
         final long displayHandle;
-        boolean owner = false;
+        final boolean owner;
         if(0==displayHandleAWT) {
             displayHandle = X11Util.openDisplay(null);
             owner = true;
@@ -112,9 +112,8 @@ public class X11AWTGraphicsConfigurationFactory extends GraphicsConfigurationFac
                 System.err.println(getThreadName()+" - X11AWTGraphicsConfigurationFactory: AWT dpy "+displayName+" / "+toHexString(displayHandleAWT)+", create X11 display "+toHexString(displayHandle));
             }
         }
-        final ToolkitLock lock = owner ? 
-                NativeWindowFactory.getDefaultToolkitLock(NativeWindowFactory.TYPE_AWT) : // own non-shared X11 display connection, no X11 lock
-                NativeWindowFactory.createDefaultToolkitLock(NativeWindowFactory.TYPE_X11, NativeWindowFactory.TYPE_AWT, displayHandle);
+        // Global JAWT lock required - No X11 resource locking due to private display connection
+        final ToolkitLock lock = NativeWindowFactory.getDefaultToolkitLock(NativeWindowFactory.TYPE_AWT); 
         final X11GraphicsDevice x11Device = new X11GraphicsDevice(displayHandle, AbstractGraphicsDevice.DEFAULT_UNIT, lock, owner); 
         final X11GraphicsScreen x11Screen = new X11GraphicsScreen(x11Device, awtScreen.getIndex());
         if(DEBUG) {
diff --git a/src/nativewindow/native/macosx/OSXmisc.m b/src/nativewindow/native/macosx/OSXmisc.m
index 2c853a4..1cf41fc 100644
--- a/src/nativewindow/native/macosx/OSXmisc.m
+++ b/src/nativewindow/native/macosx/OSXmisc.m
@@ -119,6 +119,12 @@ Java_jogamp_nativewindow_macosx_OSXUtil_isNSView0(JNIEnv *env, jclass _unused, j
     return [nsObj isMemberOfClass:[NSView class]];
 }
 
+JNIEXPORT jboolean JNICALL 
+Java_jogamp_nativewindow_macosx_OSXUtil_isNSWindow0(JNIEnv *env, jclass _unused, jlong object) {
+    NSObject *nsObj = (NSObject*) (intptr_t) object;
+    return [nsObj isMemberOfClass:[NSWindow class]];
+}
+
 /*
  * Class:     Java_jogamp_nativewindow_macosx_OSXUtil
  * Method:    getLocationOnScreen0
@@ -238,8 +244,10 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_CreateNSWindow0
     [myWindow setPreservesContentDuringLiveResize: YES];
     // Remove animations
 NS_DURING
+    if ( [myWindow respondsToSelector:@selector(setAnimationBehavior:)] ) {
         // Available >= 10.7 - Removes default animations
         [myWindow setAnimationBehavior: NSWindowAnimationBehaviorNone];
+    }
 NS_HANDLER
 NS_ENDHANDLER
 
@@ -278,11 +286,28 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetNSView0
     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
     NSWindow* win = (NSWindow*) ((intptr_t) window);
 
-    DBG_PRINT( "contentView0 - window: %p (START)\n", win);
-
     jlong res = (jlong) ((intptr_t) [win contentView]);
 
-    DBG_PRINT( "contentView0 - window: %p (END)\n", win);
+    DBG_PRINT( "GetNSView(window: %p): %p\n", win, (void*) (intptr_t) res);
+
+    [pool release];
+    return res;
+}
+
+/*
+ * Class:     Java_jogamp_nativewindow_macosx_OSXUtil
+ * Method:    GetNSWindow0
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetNSWindow0
+  (JNIEnv *env, jclass unused, jlong view)
+{
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+    NSView* v = (NSView*) ((intptr_t) view);
+
+    jlong res = (jlong) ((intptr_t) [v window]);
+
+    DBG_PRINT( "GetNSWindow(view: %p): %p\n", v, (void*) (intptr_t) res);
 
     [pool release];
     return res;
@@ -314,6 +339,8 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_CreateCALayer0
     // no animations for add/remove/swap sublayers etc 
     // doesn't work: [layer removeAnimationForKey: kCAOnOrderIn, kCAOnOrderOut, kCATransition]
     [layer removeAllAnimations];
+    [layer setAutoresizingMask: (kCALayerWidthSizable|kCALayerHeightSizable)];
+    [layer setNeedsDisplayOnBoundsChange: YES];
     DBG_PRINT("CALayer::CreateCALayer.1: %p %lf/%lf %lfx%lf\n", layer, lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height);
     DBG_PRINT("CALayer::CreateCALayer.X: %p (refcnt %d)\n", layer, (int)[layer retainCount]);
 
@@ -357,7 +384,11 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_AddCASublayer0
         // no animations for add/remove/swap sublayers etc 
         // doesn't work: [layer removeAnimationForKey: kCAOnOrderIn, kCAOnOrderOut, kCATransition]
         [rootLayer removeAllAnimations];
+        [rootLayer setAutoresizingMask: (kCALayerWidthSizable|kCALayerHeightSizable)];
+        [rootLayer setNeedsDisplayOnBoundsChange: YES];
         [subLayer removeAllAnimations];
+        [subLayer setAutoresizingMask: (kCALayerWidthSizable|kCALayerHeightSizable)];
+        [subLayer setNeedsDisplayOnBoundsChange: YES];
     }];
     DBG_PRINT("CALayer::AddCASublayer0.X: %p . %p (refcnt %d)\n", rootLayer, subLayer, (int)[subLayer retainCount]);
     JNF_COCOA_EXIT(env);
@@ -404,6 +435,63 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_DestroyCALayer0
     JNF_COCOA_EXIT(env);
 }
 
+/*
+ * Class:     Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow
+ * Method:    SetJAWTRootSurfaceLayer0
+ * Signature: (JJ)Z
+ */
+JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow_SetJAWTRootSurfaceLayer0
+  (JNIEnv *env, jclass unused, jobject jawtDrawingSurfaceInfoBuffer, jlong caLayer)
+{
+    JNF_COCOA_ENTER(env);
+    JAWT_DrawingSurfaceInfo* dsi = (JAWT_DrawingSurfaceInfo*) (*env)->GetDirectBufferAddress(env, jawtDrawingSurfaceInfoBuffer);
+    if (NULL == dsi) {
+        NativewindowCommon_throwNewRuntimeException(env, "Argument \"jawtDrawingSurfaceInfoBuffer\" was not a direct buffer");
+        return JNI_FALSE;
+    }
+    CALayer* layer = (CALayer*) (intptr_t) caLayer;
+    [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
+        id <JAWT_SurfaceLayers> surfaceLayers = (id <JAWT_SurfaceLayers>)dsi->platformInfo;
+        DBG_PRINT("CALayer::SetJAWTRootSurfaceLayer.0: %p -> %p (refcnt %d)\n", surfaceLayers.layer, layer, (int)[layer retainCount]);
+        surfaceLayers.layer = layer; // already incr. retain count
+        DBG_PRINT("CALayer::SetJAWTRootSurfaceLayer.X: %p (refcnt %d)\n", layer, (int)[layer retainCount]);
+    }];
+    JNF_COCOA_EXIT(env);
+    return JNI_TRUE;
+}
+
+/*
+ * Class:     Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow
+ * Method:    UnsetJAWTRootSurfaceLayer0
+ * Signature: (JJ)Z
+JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow_UnsetJAWTRootSurfaceLayer0
+  (JNIEnv *env, jclass unused, jobject jawtDrawingSurfaceInfoBuffer, jlong caLayer)
+{
+    JNF_COCOA_ENTER(env);
+    JAWT_DrawingSurfaceInfo* dsi = (JAWT_DrawingSurfaceInfo*) (*env)->GetDirectBufferAddress(env, jawtDrawingSurfaceInfoBuffer);
+    if (NULL == dsi) {
+        NativewindowCommon_throwNewRuntimeException(env, "Argument \"jawtDrawingSurfaceInfoBuffer\" was not a direct buffer");
+        return JNI_FALSE;
+    }
+    CALayer* layer = (CALayer*) (intptr_t) caLayer;
+    {
+        id <JAWT_SurfaceLayers> surfaceLayers = (id <JAWT_SurfaceLayers>)dsi->platformInfo;
+        if(layer != surfaceLayers.layer) {
+            NativewindowCommon_throwNewRuntimeException(env, "Attached layer %p doesn't match given layer %p\n", surfaceLayers.layer, layer);
+            return JNI_FALSE;
+        }
+    }
+    // [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
+        id <JAWT_SurfaceLayers> surfaceLayers = (id <JAWT_SurfaceLayers>)dsi->platformInfo;
+        DBG_PRINT("CALayer::detachJAWTSurfaceLayer: (%p) %p -> NULL\n", layer, surfaceLayers.layer);
+        surfaceLayers.layer = NULL;
+        [layer release];
+    // }];
+    JNF_COCOA_EXIT(env);
+    return JNI_TRUE;
+}
+ */
+
 @interface MainRunnable : NSObject
 
 {
@@ -489,60 +577,65 @@ JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_IsMainThread0
     return ( [NSThread isMainThread] == YES ) ? JNI_TRUE : JNI_FALSE ;
 }
 
-/*
- * Class:     Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow
- * Method:    SetJAWTRootSurfaceLayer0
- * Signature: (JJ)Z
+/***
+ * The following static functions are copied out of NEWT's OSX impl. <src/newt/native/MacWindow.m>
+ * May need to push code to NativeWindow, to remove duplication.
  */
-JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow_SetJAWTRootSurfaceLayer0
-  (JNIEnv *env, jclass unused, jobject jawtDrawingSurfaceInfoBuffer, jlong caLayer)
+static NSScreen * NewtScreen_getNSScreenByIndex(int screen_idx) {
+    NSArray *screens = [NSScreen screens];
+    if(screen_idx<0) screen_idx=0;
+    if(screen_idx>=[screens count]) screen_idx=0;
+    return (NSScreen *) [screens objectAtIndex: screen_idx];
+}
+static CGDirectDisplayID NewtScreen_getCGDirectDisplayIDByNSScreen(NSScreen *screen) {
+    // Mind: typedef uint32_t CGDirectDisplayID; - however, we assume it's 64bit on 64bit ?!
+    NSDictionary * dict = [screen deviceDescription];
+    NSNumber * val = (NSNumber *) [dict objectForKey: @"NSScreenNumber"];
+    // [NSNumber integerValue] returns NSInteger which is 32 or 64 bit native size
+    return (CGDirectDisplayID) [val integerValue];
+}
+static long GetDictionaryLong(CFDictionaryRef theDict, const void* key) 
 {
-    JNF_COCOA_ENTER(env);
-    JAWT_DrawingSurfaceInfo* dsi = (JAWT_DrawingSurfaceInfo*) (*env)->GetDirectBufferAddress(env, jawtDrawingSurfaceInfoBuffer);
-    if (NULL == dsi) {
-        NativewindowCommon_throwNewRuntimeException(env, "Argument \"jawtDrawingSurfaceInfoBuffer\" was not a direct buffer");
-        return JNI_FALSE;
-    }
-    CALayer* layer = (CALayer*) (intptr_t) caLayer;
-    [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
-        id <JAWT_SurfaceLayers> surfaceLayers = (id <JAWT_SurfaceLayers>)dsi->platformInfo;
-        DBG_PRINT("CALayer::SetJAWTRootSurfaceLayer.0: %p -> %p (refcnt %d)\n", surfaceLayers.layer, layer, (int)[layer retainCount]);
-        surfaceLayers.layer = layer; // already incr. retain count
-        DBG_PRINT("CALayer::SetJAWTRootSurfaceLayer.X: %p (refcnt %d)\n", layer, (int)[layer retainCount]);
-    }];
-    JNF_COCOA_EXIT(env);
-    return JNI_TRUE;
+    long value = 0;
+    CFNumberRef numRef;
+    numRef = (CFNumberRef)CFDictionaryGetValue(theDict, key); 
+    if (numRef != NULL)
+        CFNumberGetValue(numRef, kCFNumberLongType, &value);    
+    return value;
 }
+#define CGDDGetModeRefreshRate(mode) GetDictionaryLong((mode), kCGDisplayRefreshRate)
 
 /*
- * Class:     Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow
- * Method:    UnsetJAWTRootSurfaceLayer0
- * Signature: (JJ)Z
-JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow_UnsetJAWTRootSurfaceLayer0
-  (JNIEnv *env, jclass unused, jobject jawtDrawingSurfaceInfoBuffer, jlong caLayer)
+ * Class:     Java_jogamp_nativewindow_macosx_OSXUtil
+ * Method:    GetScreenRefreshRate
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetScreenRefreshRate0
+  (JNIEnv *env, jclass unused, jint scrn_idx)
 {
+    int res = 0;
     JNF_COCOA_ENTER(env);
-    JAWT_DrawingSurfaceInfo* dsi = (JAWT_DrawingSurfaceInfo*) (*env)->GetDirectBufferAddress(env, jawtDrawingSurfaceInfoBuffer);
-    if (NULL == dsi) {
-        NativewindowCommon_throwNewRuntimeException(env, "Argument \"jawtDrawingSurfaceInfoBuffer\" was not a direct buffer");
-        return JNI_FALSE;
-    }
-    CALayer* layer = (CALayer*) (intptr_t) caLayer;
-    {
-        id <JAWT_SurfaceLayers> surfaceLayers = (id <JAWT_SurfaceLayers>)dsi->platformInfo;
-        if(layer != surfaceLayers.layer) {
-            NativewindowCommon_throwNewRuntimeException(env, "Attached layer %p doesn't match given layer %p\n", surfaceLayers.layer, layer);
-            return JNI_FALSE;
+    // NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+    NSScreen *screen = NewtScreen_getNSScreenByIndex((int)scrn_idx);
+    DBG_PRINT("GetScreenRefreshRate.0: screen %p\n", (void *)screen);
+    if(NULL != screen) {
+        CGDirectDisplayID display = NewtScreen_getCGDirectDisplayIDByNSScreen(screen);
+        DBG_PRINT("GetScreenRefreshRate.1: display %p\n", (void *)display);
+        if(0 != display) {
+            CFDictionaryRef mode = CGDisplayCurrentMode(display);
+            DBG_PRINT("GetScreenRefreshRate.2: mode %p\n", (void *)mode);
+            if(NULL != mode) {
+                res = CGDDGetModeRefreshRate(mode);
+                DBG_PRINT("GetScreenRefreshRate.3: res %d\n", res);
+            }
         }
     }
-    // [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
-        id <JAWT_SurfaceLayers> surfaceLayers = (id <JAWT_SurfaceLayers>)dsi->platformInfo;
-        DBG_PRINT("CALayer::detachJAWTSurfaceLayer: (%p) %p -> NULL\n", layer, surfaceLayers.layer);
-        surfaceLayers.layer = NULL;
-        [layer release];
-    // }];
+    if(0 == res) {
+        res = 60; // default .. (experienced on OSX 10.6.8)
+    }
+    DBG_PRINT(stderr, "GetScreenRefreshRate.X: %d\n", res);
+    // [pool release];
     JNF_COCOA_EXIT(env);
-    return JNI_TRUE;
+    return res;
 }
- */
 
diff --git a/src/nativewindow/native/x11/Xmisc.c b/src/nativewindow/native/x11/Xmisc.c
index fcba858..129baac 100644
--- a/src/nativewindow/native/x11/Xmisc.c
+++ b/src/nativewindow/native/x11/Xmisc.c
@@ -29,6 +29,7 @@
 #include "NativewindowCommon.h"
 #include "Xmisc.h"
 #include "jogamp_nativewindow_x11_X11Lib.h"
+#include "jogamp_nativewindow_x11_X11Util.h"
 
 // #define VERBOSE_ON 1
 
@@ -160,10 +161,12 @@ static JavaVM *jvmHandle = NULL;
 static int jvmVersion = 0;
 
 static void setupJVMVars(JNIEnv * env) {
-    if(0 != (*env)->GetJavaVM(env, &jvmHandle)) {
-        jvmHandle = NULL;
+    if( NULL != env && NULL == jvmHandle ) {
+        if(0 != (*env)->GetJavaVM(env, &jvmHandle)) {
+            jvmHandle = NULL;
+        }
+        jvmVersion = (*env)->GetVersion(env);
     }
-    jvmVersion = (*env)->GetVersion(env);
 }
 
 static XErrorHandler origErrorHandler = NULL ;
@@ -175,44 +178,42 @@ static int x11ErrorHandler(Display *dpy, XErrorEvent *e)
 {
     if(!errorHandlerQuiet) {
         const char * errnoStr = strerror(errno);
-        char threadName[80];
         char errCodeStr[80];
         char reqCodeStr[80];
-
         int shallBeDetached = 0;
-        JNIEnv *jniEnv = NativewindowCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
+        JNIEnv *jniEnv = NULL;
 
-        (void) NativewindowCommon_GetStaticStringMethod(jniEnv, X11UtilClazz, getCurrentThreadNameID, threadName, sizeof(threadName), "n/a");
         snprintf(errCodeStr, sizeof(errCodeStr), "%d", e->request_code);
         XGetErrorDatabaseText(dpy, "XRequest", errCodeStr, "Unknown", reqCodeStr, sizeof(reqCodeStr));
         XGetErrorText(dpy, e->error_code, errCodeStr, sizeof(errCodeStr));
 
-        fprintf(stderr, "Info: Nativewindow X11 Error (Thread: %s): %d - %s, dpy %p, id %x, # %d: %d:%d %s\n",
-            threadName, e->error_code, errCodeStr, e->display, (int)e->resourceid, (int)e->serial,
+        fprintf(stderr, "Info: Nativewindow X11 Error: %d - %s, dpy %p, id %x, # %d: %d:%d %s\n",
+            e->error_code, errCodeStr, e->display, (int)e->resourceid, (int)e->serial,
             (int)e->request_code, (int)e->minor_code, reqCodeStr);
+        fflush(stderr);
 
-        if( errorHandlerDebug ) {
-            (*jniEnv)->CallStaticVoidMethod(jniEnv, X11UtilClazz, dumpStackID);
+        if( NULL != jvmHandle && ( errorHandlerDebug || errorHandlerThrowException ) ) {
+            jniEnv = NativewindowCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
+            if(NULL == jniEnv) {
+                fprintf(stderr, "Nativewindow X11 Error: null JNIEnv");
+                fflush(stderr);
+            }
         }
 
-        if(errorHandlerThrowException) {
-            if(NULL != jniEnv) {
-                NativewindowCommon_throwNewRuntimeException(jniEnv, "Nativewindow X11 Error (Thread: %s): %d - %s, dpy %p, id %x, # %d: %d:%d %s\n",
-                                                            threadName, e->error_code, errCodeStr, e->display, (int)e->resourceid, (int)e->serial,
+        if( NULL != jniEnv ) {
+            if( errorHandlerDebug ) {
+                (*jniEnv)->CallStaticVoidMethod(jniEnv, X11UtilClazz, dumpStackID);
+            }
+
+            if(errorHandlerThrowException) {
+                NativewindowCommon_throwNewRuntimeException(jniEnv, "Nativewindow X11 Error: %d - %s, dpy %p, id %x, # %d: %d:%d %s\n",
+                                                            e->error_code, errCodeStr, e->display, (int)e->resourceid, (int)e->serial,
                                                             (int)e->request_code, (int)e->minor_code, reqCodeStr);
-            } else {
-                fprintf(stderr, "Nativewindow X11 Error: null JNIEnv");
-                #if 0
-                    if(NULL!=origErrorHandler) {
-                        origErrorHandler(dpy, e);
-                    }
-                #endif
             }
-        }
-        fflush(stderr);
 
-        if (NULL != jniEnv && shallBeDetached) {
-            (*jvmHandle)->DetachCurrentThread(jvmHandle);
+            if (shallBeDetached) {
+                (*jvmHandle)->DetachCurrentThread(jvmHandle);
+            }
         }
     }
 
@@ -246,20 +247,19 @@ static int x11IOErrorHandler(Display *dpy)
 {
     const char * dpyName = XDisplayName(NULL);
     const char * errnoStr = strerror(errno);
-    char threadName[80];
     int shallBeDetached = 0;
-    JNIEnv *jniEnv = NativewindowCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
+    JNIEnv *jniEnv = NULL;
 
-    (void) NativewindowCommon_GetStaticStringMethod(jniEnv, X11UtilClazz, getCurrentThreadNameID, threadName, sizeof(threadName), "n/a");
+    fprintf(stderr, "Nativewindow X11 IOError: Display %p (%s): %s\n", dpy, dpyName, errnoStr);
+    fflush(stderr);
 
-    fprintf(stderr, "Nativewindow X11 IOError (Thread %s): Display %p (%s): %s\n", threadName, dpy, dpyName, errnoStr);
-    (*jniEnv)->CallStaticVoidMethod(jniEnv, X11UtilClazz, dumpStackID);
-
-    if (NULL != jniEnv) {
-        NativewindowCommon_FatalError(jniEnv, "Nativewindow X11 IOError (Thread %s): Display %p (%s): %s", threadName, dpy, dpyName, errnoStr);
-
-        if (shallBeDetached) {
-            (*jvmHandle)->DetachCurrentThread(jvmHandle);
+    if( NULL != jvmHandle ) {
+        jniEnv = NativewindowCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
+        if (NULL != jniEnv) {
+            NativewindowCommon_FatalError(jniEnv, "Nativewindow X11 IOError: Display %p (%s): %s", dpy, dpyName, errnoStr);
+            if (shallBeDetached) {
+                (*jvmHandle)->DetachCurrentThread(jvmHandle);
+            }
         }
     }
     if(NULL!=origIOErrorHandler) {
@@ -280,41 +280,30 @@ static void x11IOErrorHandlerEnable(int onoff, JNIEnv * env) {
     }
 }
 
-static int _initialized=0;
-static jboolean _xinitThreadsOK=JNI_FALSE;
+static int _initialized = 0;
 
 JNIEXPORT jboolean JNICALL 
-Java_jogamp_nativewindow_x11_X11Util_initialize0(JNIEnv *env, jclass clazz, jboolean firstUIActionOnProcess, jboolean debug) {
-    if(0==_initialized) {
+Java_jogamp_nativewindow_x11_X11Util_initialize0(JNIEnv *env, jclass clazz, jboolean debug) {
+    if( 0 == _initialized ) {
         if(debug) {
             errorHandlerDebug = 1;
         }
         X11UtilClazz = (jclass)(*env)->NewGlobalRef(env, clazz);
-        if( JNI_TRUE == firstUIActionOnProcess ) {
-            if( 0 == XInitThreads() ) {
-                fprintf(stderr, "Warning: XInitThreads() failed\n");
-            } else {
-                _xinitThreadsOK=JNI_TRUE;
-                if(debug) {
-                    fprintf(stderr, "X11: XInitThreads() called for concurrent Thread support\n");
-                }
-            }
-        } else if(debug) {
-            fprintf(stderr, "X11: XInitThreads() _not_ called for concurrent Thread support\n");
-        }
 
         _initClazzAccess(env);
         x11IOErrorHandlerEnable(1, env);
+        NativewindowCommon_x11ErrorHandlerEnable(env, NULL, 1, 0, 0 /* no dpy, no sync */);
         _initialized=1;
         if(JNI_TRUE == debug) {
             fprintf(stderr, "Info: NativeWindow native init passed\n");
         }
     }
-    return _xinitThreadsOK;
+    return JNI_TRUE;
 }
 
 JNIEXPORT void JNICALL 
 Java_jogamp_nativewindow_x11_X11Util_shutdown0(JNIEnv *env, jclass _unused) {
+    NativewindowCommon_x11ErrorHandlerEnable(env, NULL, 0, 0, 0 /* no dpy, no sync */);
     x11IOErrorHandlerEnable(0, env);
 }
 
@@ -347,7 +336,7 @@ Java_jogamp_nativewindow_x11_X11Lib_XGetVisualInfo1__JJLjava_nio_ByteBuffer_2Lja
   }
   NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) arg0, 1, 0, 0);
   _res = XGetVisualInfo((Display *) (intptr_t) arg0, (long) arg1, (XVisualInfo *) _ptr2, (int *) _ptr3);
-  NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) arg0, 0, 0, 0);
+  // NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) arg0, 0, 0, 0);
   count = _ptr3[0];
   if (arg3 != NULL) {
     (*env)->ReleasePrimitiveArrayCritical(env, arg3, _ptr3, 0);
@@ -382,7 +371,7 @@ Java_jogamp_nativewindow_x11_X11Lib_GetVisualIDFromWindow(JNIEnv *env, jclass _u
     } else {
         r = 0;
     }
-    NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
+    // NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
 
     return r;
 }
@@ -396,7 +385,7 @@ Java_jogamp_nativewindow_x11_X11Lib_DefaultVisualID(JNIEnv *env, jclass _unused,
     }
   NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) display, 1, 0, 0);
   r = (jint) XVisualIDFromVisual( DefaultVisual( (Display*) (intptr_t) display, screen ) );
-  NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) display, 0, 0, 0);
+  // NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) display, 0, 0, 0);
   return r;
 }
 
@@ -439,7 +428,7 @@ Java_jogamp_nativewindow_x11_X11Lib_XCloseDisplay__J(JNIEnv *env, jclass _unused
   }
   NativewindowCommon_x11ErrorHandlerEnable(env, NULL, 1, 0, 0);
   _res = XCloseDisplay((Display *) (intptr_t) display);
-  NativewindowCommon_x11ErrorHandlerEnable(env, NULL, 0, 0, 0);
+  // NativewindowCommon_x11ErrorHandlerEnable(env, NULL, 0, 0, 0);
   return _res;
 }
 
@@ -497,7 +486,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow
 
     if (visual==NULL)
     { 
-        NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
+        // NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
         NativewindowCommon_throwNewRuntimeException(env, "could not query Visual by given VisualID, bail out!");
         return 0;
     } 
@@ -541,7 +530,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow
 
     XSelectInput(dpy, window, 0); // no events
 
-    NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
+    // NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
 
     DBG_PRINT( "X11: [CreateWindow] created window %p on display %p\n", window, dpy);
 
@@ -569,7 +558,7 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_x11_X11Lib_DestroyDummyWindow
     XUnmapWindow(dpy, w);
     XSync(dpy, False);
     XDestroyWindow(dpy, w);
-    NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
+    // NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
 }
 
 /*
@@ -597,7 +586,7 @@ JNIEXPORT jobject JNICALL Java_jogamp_nativewindow_x11_X11Lib_GetRelativeLocatio
 
     res = XTranslateCoordinates(dpy, src_win, dest_win, src_x, src_y, &dest_x, &dest_y, &child);
 
-    NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 0);
+    // NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 0);
 
     DBG_PRINT( "X11: GetRelativeLocation0: %p %d/%d -> %p %d/%d - ok: %d\n",
         (void*)src_win, src_x, src_y, (void*)dest_win, dest_x, dest_y, (int)res);
@@ -605,3 +594,38 @@ JNIEXPORT jobject JNICALL Java_jogamp_nativewindow_x11_X11Lib_GetRelativeLocatio
     return (*env)->NewObject(env, pointClz, pointCstr, (jint)dest_x, (jint)dest_y);
 }
 
+/*
+ * Class:     jogamp_nativewindow_x11_X11Lib
+ * Method:    QueryExtension0
+ * Signature: (JLjava/lang/String;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_x11_X11Lib_QueryExtension0
+  (JNIEnv *env, jclass unused, jlong jdisplay, jstring jextensionName)
+{
+    int32_t major_opcode, first_event, first_error;
+    jboolean res = JNI_FALSE;
+    Display * display = (Display *) (intptr_t) jdisplay;
+    const char* extensionName = NULL;
+
+    if(NULL==display) {
+        NativewindowCommon_throwNewRuntimeException(env, "NULL argument \"display\"");
+        return res;
+    }
+    if ( NULL == jextensionName ) {
+        NativewindowCommon_throwNewRuntimeException(env, "NULL argument \"extensionName\"");
+        return res;
+    }
+    extensionName = (*env)->GetStringUTFChars(env, jextensionName, (jboolean*)NULL);
+    if ( NULL == extensionName ) {
+        NativewindowCommon_throwNewRuntimeException(env, "Failed to get UTF-8 chars for argument \"extensionName\"");
+        return res;
+    }
+
+    res = True == XQueryExtension(display, extensionName, &major_opcode, &first_event, &first_error) ? JNI_TRUE : JNI_FALSE;
+
+    if ( NULL != jextensionName ) {
+        (*env)->ReleaseStringUTFChars(env, jextensionName, extensionName);
+    }
+    return res;
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/Display.java b/src/newt/classes/com/jogamp/newt/Display.java
index 1e9a0e9..e97dec8 100644
--- a/src/newt/classes/com/jogamp/newt/Display.java
+++ b/src/newt/classes/com/jogamp/newt/Display.java
@@ -88,7 +88,7 @@ public abstract class Display {
     public abstract boolean isNativeValid();
 
     /**
-     * @return number of references by Screen
+     * @return number of references
      */
     public abstract int getReferenceCount();
 
@@ -96,7 +96,7 @@ public abstract class Display {
      * The 1st call will initiate native creation,
      * since we follow the lazy creation pattern.
      *
-     * @return number of references after adding one
+     * @return number of references post operation
      * @throws NativeWindowException if the native creation failed.
      * @see #removeReference()
      */
@@ -106,24 +106,30 @@ public abstract class Display {
      * The last call may destroy this instance,
      * if {@link #getDestroyWhenUnused()} returns <code>true</code>.
      *
-     * @return number of references after removing one
+     * @return number of references post operation
      * @see #addReference()
      * @see #getDestroyWhenUnused()
      * @see #setDestroyWhenUnused(boolean)
      */
     public abstract int removeReference();
 
+    /** 
+     * Return the {@link AbstractGraphicsDevice} used for depending resources lifecycle, 
+     * i.e. {@link Screen} and {@link Window}, as well as the event dispatching (EDT). */ 
     public abstract AbstractGraphicsDevice getGraphicsDevice();
 
     /**
-     * @return the fully qualified Display name,
-     * which is a key of {@link #getType()} + {@link #getName()} + {@link #getId()}
+     * Return the handle of the {@link AbstractGraphicsDevice} as returned by {@link #getGraphicsDevice()}.
      */
-    public abstract String getFQName();
-
     public abstract long getHandle();
 
     /**
+     * @return The fully qualified Display name,
+     * which is a key of {@link #getType()} + {@link #getName()} + {@link #getId()}.
+     */
+    public abstract String getFQName();
+
+    /**
      * @return this display internal serial id
      */
     public abstract int getId();
@@ -141,6 +147,9 @@ public abstract class Display {
      */
     public abstract String getType();
 
+    /** Return true if this instance is exclusive, i.e. will not be shared. */
+    public abstract boolean isExclusive();
+
     /**
      * Sets a new {@link EDTUtil} and returns the previous one.
      * <p>
@@ -155,6 +164,14 @@ public abstract class Display {
      * If <code>newEDTUtil</code> is not null and equals the previous one,
      * <code>null</code> is returned and no change is being made.
      * </p>
+     * <p>
+     * Note that <code>newEDTUtil</code> will not be started if not done so already,
+     * to do so you may issue {@link EDTUtil#invoke(boolean, Runnable) invoke} 
+     * on the new EDTUtil:
+     * <pre>
+     *          newEDTUtil.invoke(true, new Runnable() { public void run() { } } );
+     * </pre>
+     * </p>
      */
     public abstract EDTUtil setEDTUtil(EDTUtil newEDTUtil);
     
@@ -183,11 +200,12 @@ public abstract class Display {
      * 
      * @param type
      * @param name
-     * @param fromIndex start index, then increasing until found or end of list     * 
+     * @param fromIndex start index, then increasing until found or end of list
+     * @paran shared if true, only shared instances are found, otherwise also exclusive 
      * @return 
      */
-    public static Display getFirstDisplayOf(String type, String name, int fromIndex) {
-        return getDisplayOfImpl(type, name, fromIndex, 1);
+    public static Display getFirstDisplayOf(String type, String name, int fromIndex, boolean shared) {
+        return getDisplayOfImpl(type, name, fromIndex, 1, shared);
     }
 
     /**
@@ -195,19 +213,22 @@ public abstract class Display {
      * @param type
      * @param name
      * @param fromIndex start index, then decreasing until found or end of list. -1 is interpreted as size - 1.
+     * @paran shared if true, only shared instances are found, otherwise also exclusive 
      * @return
      */
-    public static Display getLastDisplayOf(String type, String name, int fromIndex) {
-        return getDisplayOfImpl(type, name, fromIndex, -1);
+    public static Display getLastDisplayOf(String type, String name, int fromIndex, boolean shared) {
+        return getDisplayOfImpl(type, name, fromIndex, -1, shared);
     }
 
-    private static Display getDisplayOfImpl(String type, String name, int fromIndex, int incr) {
+    private static Display getDisplayOfImpl(String type, String name, int fromIndex, int incr, boolean shared) {
         synchronized(displayList) {
             int i = fromIndex >= 0 ? fromIndex : displayList.size() - 1 ;
             while( ( incr > 0 ) ? i < displayList.size() : i >= 0 ) {
                 Display display = (Display) displayList.get(i);
                 if( display.getType().equals(type) &&
-                    display.getName().equals(name) ) {
+                    display.getName().equals(name) &&
+                    ( !shared || shared && !display.isExclusive() ) 
+                  ) {
                     return display;
                 }
                 i+=incr;
diff --git a/src/newt/classes/com/jogamp/newt/NewtFactory.java b/src/newt/classes/com/jogamp/newt/NewtFactory.java
index 61dbfb3..1bf47f4 100644
--- a/src/newt/classes/com/jogamp/newt/NewtFactory.java
+++ b/src/newt/classes/com/jogamp/newt/NewtFactory.java
@@ -49,17 +49,24 @@ import jogamp.newt.WindowImpl;
 public class NewtFactory {
     public static final boolean DEBUG_IMPLEMENTATION = Debug.debug("Window");
 
+    public static final String DRIVER_DEFAULT_ROOT_PACKAGE = "jogamp.newt.driver";
+    
     // Work-around for initialization order problems on Mac OS X
     // between native Newt and (apparently) Fmod
     static {
-        NativeWindowFactory.initSingleton(false); // last resort ..
+        NativeWindowFactory.initSingleton(); // last resort ..
         WindowImpl.init(NativeWindowFactory.getNativeWindowType(true));
     }
 
     public static Class<?> getCustomClass(String packageName, String classBaseName) {
         Class<?> clazz = null;
         if(packageName!=null && classBaseName!=null) {
-            final String clazzName = packageName + "." + classBaseName ;
+            final String clazzName;
+            if( packageName.startsWith(".") ) {
+                clazzName = DRIVER_DEFAULT_ROOT_PACKAGE + packageName + "." + classBaseName ;
+            } else {
+                clazzName = packageName + "." + classBaseName ;
+            }            
             try {
                 clazz = Class.forName(clazzName);
             } catch (Throwable t) {
@@ -298,7 +305,7 @@ public class NewtFactory {
      * Instantiate a Display entity using the native handle.
      */
     public static Display createDisplay(String type, long handle, boolean reuse) {
-      return DisplayImpl.create(type, null, handle, false);
+      return DisplayImpl.create(type, null, handle, reuse);
     }
 
     public static boolean isScreenCompatible(NativeWindow parent, Screen childScreen) {
diff --git a/src/newt/classes/com/jogamp/newt/Screen.java b/src/newt/classes/com/jogamp/newt/Screen.java
index 26f19ad..a09748d 100644
--- a/src/newt/classes/com/jogamp/newt/Screen.java
+++ b/src/newt/classes/com/jogamp/newt/Screen.java
@@ -89,13 +89,14 @@ public abstract class Screen {
     public abstract boolean isNativeValid();
 
     /**
-     * @return number of references by Window
+     * @return number of references
      */
     public abstract int getReferenceCount();
 
     /**
      * See {@link Display#addReference()}
-     *
+     * 
+     * @return number of references post operation
      * @throws NativeWindowException if the native creation failed.
      * @see #removeReference()
      * @see #setDestroyWhenUnused(boolean)
@@ -105,7 +106,8 @@ public abstract class Screen {
 
     /**
      * See {@link Display#removeReference()}
-     *
+     * 
+     * @return number of references post operation
      * @see #addReference()
      * @see #setDestroyWhenUnused(boolean)
      * @see #getDestroyWhenUnused()
@@ -145,7 +147,7 @@ public abstract class Screen {
     public abstract Display getDisplay();
 
     /** 
-     * @return the screen fully qualified Screen name,
+     * @return The screen fully qualified Screen name,
      * which is a key of {@link com.jogamp.newt.Display#getFQName()} + {@link #getIndex()}.
      */
     public abstract String getFQName();
diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java
index e8537fe..cc42465 100644
--- a/src/newt/classes/com/jogamp/newt/Window.java
+++ b/src/newt/classes/com/jogamp/newt/Window.java
@@ -129,7 +129,7 @@ public interface Window extends NativeWindow, WindowClosingProtocol {
      * <pre>
      * if ( 0 == windowHandle && visible ) {
      *   this.visible = visible;
-     *   if( 0 < width*height ) {
+     *   if( 0 < width && 0 < height ) {
      *     createNative();
      *   }
      * } else if ( this.visible != visible ) {
@@ -171,9 +171,9 @@ public interface Window extends NativeWindow, WindowClosingProtocol {
      * <p>
      * Zero size semantics are respected, see {@link #setVisible(boolean)}:<br>
      * <pre>
-     * if ( 0 != windowHandle && 0 ≥ width*height && visible ) {
+     * if ( visible && 0 != windowHandle && ( 0 ≥ width || 0 ≥ height ) ) {
      *   setVisible(false);
-     * } else if ( 0 == windowHandle && 0 < width*height && visible ) {
+     * } else if ( visible && 0 == windowHandle && 0 < width && 0 < height ) {
      *   setVisible(true);
      * } else {
      *   // as expected ..
@@ -245,6 +245,7 @@ public interface Window extends NativeWindow, WindowClosingProtocol {
 
     String getTitle();
 
+    /** @see #setPointerVisible(boolean) */
     boolean isPointerVisible();
 
     /**
@@ -256,6 +257,7 @@ public interface Window extends NativeWindow, WindowClosingProtocol {
      */
     void setPointerVisible(boolean pointerVisible);
 
+    /** @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 6f0028a..89a749c 100644
--- a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
+++ b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
@@ -68,6 +68,15 @@ import com.jogamp.newt.event.awt.AWTAdapter;
 import com.jogamp.newt.event.awt.AWTKeyAdapter;
 import com.jogamp.newt.event.awt.AWTMouseAdapter;
 
+/**
+ * AWT {@link java.awt.Canvas Canvas} containing a NEWT {@link Window} using native parenting.
+ *  
+ * <h5><A NAME="java2dgl">Offscreen Layer Remarks</A></h5>
+ * 
+ * {@link OffscreenLayerOption#setShallUseOffscreenLayer(boolean) setShallUseOffscreenLayer(true)}
+ * maybe called to use an offscreen drawable (FBO or PBuffer) allowing 
+ * the underlying JAWT mechanism to composite the image, if supported.
+ */
 @SuppressWarnings("serial")
 public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProtocol, OffscreenLayerOption {
     public static final boolean DEBUG = Debug.debug("Window");
diff --git a/src/newt/classes/com/jogamp/newt/event/InputEvent.java b/src/newt/classes/com/jogamp/newt/event/InputEvent.java
index 819338c..0122bda 100644
--- a/src/newt/classes/com/jogamp/newt/event/InputEvent.java
+++ b/src/newt/classes/com/jogamp/newt/event/InputEvent.java
@@ -34,22 +34,37 @@
 
 package com.jogamp.newt.event;
 
+import com.jogamp.newt.Window;
+
 @SuppressWarnings("serial")
 public abstract class InputEvent extends NEWTEvent
 {
- public static final int  SHIFT_MASK     = 1 <<  0;
- public static final int  CTRL_MASK      = 1 <<  1;
- public static final int  META_MASK      = 1 <<  2;
- public static final int  ALT_MASK       = 1 <<  3;
- public static final int  ALT_GRAPH_MASK = 1 <<  5;
- public static final int  BUTTON1_MASK   = 1 <<  6;
- public static final int  BUTTON2_MASK   = 1 <<  7;
- public static final int  BUTTON3_MASK   = 1 <<  8;
- public static final int  BUTTON4_MASK   = 1 <<  9;
- public static final int  BUTTON5_MASK   = 1 << 10;
- public static final int  BUTTON6_MASK   = 1 << 11;
- public static final int  CONFINED_MASK  = 1 << 16;
- public static final int  INVISIBLE_MASK = 1 << 17;
+ public static final int  SHIFT_MASK       = 1 <<  0;
+ public static final int  CTRL_MASK        = 1 <<  1;
+ public static final int  META_MASK        = 1 <<  2;
+ public static final int  ALT_MASK         = 1 <<  3;
+ public static final int  ALT_GRAPH_MASK   = 1 <<  4;
+ 
+ public static final int  BUTTON1_MASK     = 1 <<  5;
+ public static final int  BUTTON2_MASK     = 1 <<  6;
+ public static final int  BUTTON3_MASK     = 1 <<  7;
+ public static final int  BUTTON4_MASK     = 1 <<  8;
+ public static final int  BUTTON5_MASK     = 1 <<  9;
+ public static final int  BUTTON6_MASK     = 1 << 10;
+ public static final int  BUTTON7_MASK     = 1 << 11;
+ public static final int  BUTTON8_MASK     = 1 << 12;
+ public static final int  BUTTON9_MASK     = 1 << 13;
+ 
+ public static final int  BUTTONLAST_MASK  = 1 << 20;  // 16
+ 
+ /** Event is caused by auto-repeat. */
+ public static final int  AUTOREPEAT_MASK  = 1 << 29;
+ 
+ /** Pointer is confined, see {@link Window#confinePointer(boolean)}. */
+ public static final int  CONFINED_MASK    = 1 << 30;
+ 
+ /** Pointer is invisible, see {@link Window#setPointerVisible(boolean)}. */
+ public static final int  INVISIBLE_MASK   = 1 << 31;
 
  /** 
   * Returns the corresponding button mask for the given button.
@@ -61,7 +76,7 @@ public abstract class InputEvent extends NEWTEvent
   */
  public static final int getButtonMask(int button)  {
      if( 0 < button && button <= MouseEvent.BUTTON_NUMBER ) {
-         return 1 << ( 5 + button ) ;
+         return 1 << ( 4 + button ) ;
      }
      return 0;
  }
@@ -76,30 +91,64 @@ public abstract class InputEvent extends NEWTEvent
     this.modifiers=modifiers;
  }
 
+ /** Return the modifier bits of this event, e.g. see {@link #SHIFT_MASK} .. etc. */
  public int getModifiers() {
     return modifiers;
  }
+ /** {@link #getModifiers()} contains {@link #ALT_MASK}. */
  public boolean isAltDown() {
     return (modifiers&ALT_MASK)!=0;
  }
+ /** {@link #getModifiers()} contains {@link #ALT_GRAPH_MASK}. */
  public boolean isAltGraphDown() {
     return (modifiers&ALT_GRAPH_MASK)!=0;
  }
+ /** {@link #getModifiers()} contains {@link #CTRL_MASK}. */
  public boolean isControlDown() {
     return (modifiers&CTRL_MASK)!=0;
  }
+ /** {@link #getModifiers()} contains {@link #META_MASK}. */
  public boolean isMetaDown() {
     return (modifiers&META_MASK)!=0;
  }
+ /** {@link #getModifiers()} contains {@link #SHIFT_MASK}. */
  public boolean isShiftDown()  {
     return (modifiers&SHIFT_MASK)!=0;
  }
+ /** {@link #getModifiers()} contains {@link #AUTOREPEAT_MASK}. */
+ public boolean isAutoRepeat()  {
+    return (modifiers&AUTOREPEAT_MASK)!=0;
+ }
+ /** {@link #getModifiers()} contains {@link #CONFINED_MASK}. Pointer is confined, see {@link Window#confinePointer(boolean)}. */
  public boolean isConfined()  {
     return (modifiers&CONFINED_MASK)!=0;
  }
+ /** {@link #getModifiers()} contains {@link #INVISIBLE_MASK}. Pointer is invisible, see {@link Window#setPointerVisible(boolean)}. */ 
  public boolean isInvisible()  {
     return (modifiers&INVISIBLE_MASK)!=0;
  }
+ 
+ public StringBuilder getModifiersString(StringBuilder sb) {
+    if(null == sb) {
+        sb = new StringBuilder();
+    }
+    sb.append("[");
+    boolean isFirst = true;
+    if(isShiftDown()) { if(!isFirst) { sb.append(", "); } isFirst = false; sb.append("shift"); }
+    if(isControlDown()) { if(!isFirst) { sb.append(", "); } isFirst = false; sb.append("ctrl"); }
+    if(isMetaDown()) { if(!isFirst) { sb.append(", "); } isFirst = false; sb.append("meta"); }    
+    if(isAltDown()) { if(!isFirst) { sb.append(", "); } isFirst = false; sb.append("alt"); }
+    if(isAltGraphDown()) { if(!isFirst) { sb.append(", "); } isFirst = false; sb.append("altg"); }
+    if(isAutoRepeat()) { if(!isFirst) { sb.append(", "); } isFirst = false; sb.append("repeat"); }
+    for(int i=1; i<=MouseEvent.BUTTON_NUMBER; i++) {
+        if(isButtonDown(i)) { if(!isFirst) { sb.append(", "); } isFirst = false; sb.append("button").append(i); }
+    }
+    if(isConfined()) { if(!isFirst) { sb.append(", "); } isFirst = false; sb.append("confined"); }
+    if(isInvisible()) { if(!isFirst) { sb.append(", "); } isFirst = false; sb.append("invisible"); }
+    sb.append("]");
+    
+    return sb;
+ }
 
  /**
   * @return Array of pressed mouse buttons  [{@link MouseEvent#BUTTON1} .. {@link MouseEvent#BUTTON6}]. 
@@ -124,7 +173,18 @@ public abstract class InputEvent extends NEWTEvent
  }
  
  public String toString() {
-     return "InputEvent[modifiers: 0x"+Integer.toHexString(modifiers)+", "+super.toString()+"]";
+     return toString(null).toString();
+ }
+ 
+ public StringBuilder toString(StringBuilder sb) {
+     if(null == sb) {
+         sb = new StringBuilder();
+     }
+     sb.append("InputEvent[modifiers: ");
+     getModifiersString(sb);
+     sb.append(", ");
+     super.toString(sb).append("]");
+     return sb;
  }
 
  private final int modifiers;
diff --git a/src/newt/classes/com/jogamp/newt/event/KeyEvent.java b/src/newt/classes/com/jogamp/newt/event/KeyEvent.java
index 4db661e..289aa31 100644
--- a/src/newt/classes/com/jogamp/newt/event/KeyEvent.java
+++ b/src/newt/classes/com/jogamp/newt/event/KeyEvent.java
@@ -34,85 +34,148 @@
 
 package com.jogamp.newt.event;
 
+/**
+ * Key events are delivered in the following order:
+ * <ol>
+ *   <li>{@link #EVENT_KEY_PRESSED}</li>
+ *   <li>{@link #EVENT_KEY_RELEASED}</li>
+ *   <li>{@link #EVENT_KEY_TYPED}</li>
+ * </ol>
+ * In case the native platform does not
+ * deliver keyboard events in the above order or skip events, 
+ * the NEWT driver will reorder and inject synthetic events if required. 
+ * <p>
+ * Besides regular modifiers like {@link InputEvent#SHIFT_MASK} etc., 
+ * the {@link InputEvent#AUTOREPEAT_MASK} bit is added if repetition is detected.
+ * </p>
+ * <p>
+ * Auto-Repeat shall behave as follow:
+ * <pre>
+    D = pressed, U = released, T = typed
+    0 = normal, 1 = auto-repeat
+
+    D(0), [ U(1), T(1), D(1), U(1) T(1) ..], U(0) T(0)
+ * </pre>
+ * The idea is if you mask out auto-repeat in your event listener
+ * you just get one long pressed key D/U/T triple.
+ * </p>
+ * <p>
+ * {@link #isModifierKey() Modifiers keys} will produce regular events (pressed, released and typed),
+ * however they will not produce Auto-Repeat events itself.
+ * </p>
+ */
 @SuppressWarnings("serial")
 public class KeyEvent extends InputEvent
 {
- public KeyEvent(int eventType, Object source, long when, int modifiers, int keyCode, char keyChar) {
-     super(eventType, source, when, modifiers); 
-     this.keyCode=keyCode;
-     this.keyChar=keyChar;
- }
-
- /** Only valid on all platforms at {@link KeyListener#keyTyped(KeyEvent)} */
- public char getKeyChar() {
-    return keyChar;
- }
- 
- /** Always valid. */
- public int getKeyCode() {
-    return keyCode;
- }
-
- public String toString() {
-    return "KeyEvent["+getEventTypeString(getEventType())+
-                     ", code "+keyCode+"("+toHexString(keyCode)+"), char '"+keyChar+"' ("+toHexString((int)keyChar)+"), isActionKey "+isActionKey()+", "+super.toString()+"]";
- }
-
- public static String getEventTypeString(int type) {
-    switch(type) {
+    public KeyEvent(int eventType, Object source, long when, int modifiers, int keyCode, char keyChar) {
+        super(eventType, source, when, modifiers); 
+        this.keyCode=keyCode;
+        this.keyChar=keyChar;
+    }
+
+    /** 
+     * Returns the character matching the {@link #getKeyCode() virtual key code}, if exist.
+     * <p>
+     * <b>Disclaimer</b>: Only valid on all platforms at {@link KeyListener#keyTyped(KeyEvent)}.
+     * Precisely, on the Windows platform we currently cannot deliver the proper character
+     * in case of shifted keys where no uppercase exists, e.g. 'shift + 1' doesn't produce '!'.
+     * </p> 
+     */
+    public char getKeyChar() {
+        return keyChar;
+    }
+
+    /** Returns the virtual key code. */
+    public int getKeyCode() {
+        return keyCode;
+    }
+
+    public String toString() {
+        return toString(null).toString();
+    }
+
+    public StringBuilder toString(StringBuilder sb) {
+        if(null == sb) {
+            sb = new StringBuilder();
+        }
+        sb.append("KeyEvent[").append(getEventTypeString(getEventType())).append(", code ").append(keyCode).append("(").append(toHexString(keyCode)).append("), char '").append(keyChar).append("' (").append(toHexString((int)keyChar)).append("), isActionKey ").append(isActionKey()).append(", ");
+        return super.toString(sb).append("]");
+    }
+
+    public static String getEventTypeString(int type) {
+        switch(type) {
         case EVENT_KEY_PRESSED: return "EVENT_KEY_PRESSED";
         case EVENT_KEY_RELEASED: return "EVENT_KEY_RELEASED";
         case EVENT_KEY_TYPED: return "EVENT_KEY_TYPED";
         default: return "unknown (" + type + ")";
+        }
+    }
+
+    /** Returns true if <code>keyCode</code> represents a modifier key, i.e. one of {@link #VK_SHIFT}, {@link #VK_CONTROL}, {@link #VK_ALT}, {@link #VK_ALT_GRAPH}, {@link #VK_META}. */
+    public static boolean isModifierKey(int keyCode) {
+        switch (keyCode) {
+            case VK_SHIFT:
+            case VK_CONTROL:
+            case VK_ALT:
+            case VK_ALT_GRAPH:
+            case VK_META:
+                return true;
+            default:
+                return false;
+        }
     }
- }
-
- public boolean   isActionKey() {
-    switch (keyCode) {
-      case VK_HOME:
-      case VK_END:
-      case VK_PAGE_UP:
-      case VK_PAGE_DOWN:
-      case VK_UP:
-      case VK_DOWN:
-      case VK_LEFT:
-      case VK_RIGHT:
-
-      case VK_F1:
-      case VK_F2:
-      case VK_F3:
-      case VK_F4:
-      case VK_F5:
-      case VK_F6:
-      case VK_F7:
-      case VK_F8:
-      case VK_F9:
-      case VK_F10:
-      case VK_F11:
-      case VK_F12:
-      case VK_F13:
-      case VK_F14:
-      case VK_F15:
-      case VK_F16:
-      case VK_F17:
-      case VK_F18:
-      case VK_F19:
-      case VK_F20:
-      case VK_F21:
-      case VK_F22:
-      case VK_F23:
-      case VK_F24:
-      case VK_PRINTSCREEN:
-      case VK_CAPS_LOCK:
-      case VK_PAUSE:
-      case VK_INSERT:
-
-      case VK_HELP:
-      case VK_WINDOWS:
-          return true;
+    
+    /** Returns true if {@link #getKeyCode()} represents a modifier key, i.e. one of {@link #VK_SHIFT}, {@link #VK_CONTROL}, {@link #VK_ALT}, {@link #VK_ALT_GRAPH}, {@link #VK_META}. */
+    public boolean isModifierKey() {
+        return isModifierKey(keyCode);
+    }
+    
+    public boolean isActionKey() {
+        switch (keyCode) {
+            case VK_HOME:
+            case VK_END:
+            case VK_PAGE_UP:
+            case VK_PAGE_DOWN:
+            case VK_UP:
+            case VK_DOWN:
+            case VK_LEFT:
+            case VK_RIGHT:
+    
+            case VK_F1:
+            case VK_F2:
+            case VK_F3:
+            case VK_F4:
+            case VK_F5:
+            case VK_F6:
+            case VK_F7:
+            case VK_F8:
+            case VK_F9:
+            case VK_F10:
+            case VK_F11:
+            case VK_F12:
+            case VK_F13:
+            case VK_F14:
+            case VK_F15:
+            case VK_F16:
+            case VK_F17:
+            case VK_F18:
+            case VK_F19:
+            case VK_F20:
+            case VK_F21:
+            case VK_F22:
+            case VK_F23:
+            case VK_F24:
+            case VK_PRINTSCREEN:
+            case VK_CAPS_LOCK:
+            case VK_PAUSE:
+            case VK_INSERT:
+    
+            case VK_HELP:
+            case VK_WINDOWS:
+                return true;
+        }
+        return false;
     }
-    return false;
- }
 
     private final int keyCode;
     private final char keyChar;
@@ -123,10 +186,10 @@ public class KeyEvent extends InputEvent
 
     /* Virtual key codes. */
 
-    public static final int VK_ENTER          = '\n';
-    public static final int VK_BACK_SPACE     = '\b';
-    public static final int VK_TAB            = '\t';
     public static final int VK_CANCEL         = 0x03;
+    public static final int VK_BACK_SPACE     = 0x08; // '\b'
+    public static final int VK_TAB            = 0x09; // '\t'
+    public static final int VK_ENTER          = 0x0A; // '\n'
     public static final int VK_CLEAR          = 0x0C;
     public static final int VK_SHIFT          = 0x10;
     public static final int VK_CONTROL        = 0x11;
@@ -264,17 +327,9 @@ public class KeyEvent extends InputEvent
     public static final int VK_ADD            = 0x6B;
 
     /** 
-     * This constant is obsolete, and is included only for backwards
-     * compatibility.
-     * @see #VK_SEPARATOR
-     */
-    public static final int VK_SEPARATER      = 0x6C;
-
-    /** 
      * Constant for the Numpad Separator key. 
-     * @since 1.4
      */
-    public static final int VK_SEPARATOR      = VK_SEPARATER;
+    public static final int VK_SEPARATOR      = 0x6C;
 
     public static final int VK_SUBTRACT       = 0x6D;
     public static final int VK_DECIMAL        = 0x6E;
@@ -321,77 +376,76 @@ public class KeyEvent extends InputEvent
 
     /**
      * Constant for the F13 function key.
-     * @since 1.2
+     * <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p>
      */
-    /* F13 - F24 are used on IBM 3270 keyboard; use random range for constants. */
     public static final int VK_F13            = 0xF000;
- 
+
     /**
      * Constant for the F14 function key.
-     * @since 1.2
+     * <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p>
      */
     public static final int VK_F14            = 0xF001;
- 
+
     /**
      * Constant for the F15 function key.
-     * @since 1.2
+     * <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p>
      */
     public static final int VK_F15            = 0xF002;
- 
+
     /**
      * Constant for the F16 function key.
-     * @since 1.2
+     * <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p>
      */
     public static final int VK_F16            = 0xF003;
- 
+
     /**
      * Constant for the F17 function key.
-     * @since 1.2
+     * <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p>
      */
     public static final int VK_F17            = 0xF004;
- 
+
     /**
      * Constant for the F18 function key.
-     * @since 1.2
+     * <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p>
      */
     public static final int VK_F18            = 0xF005;
- 
+
     /**
      * Constant for the F19 function key.
-     * @since 1.2
+     * <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p>
      */
     public static final int VK_F19            = 0xF006;
- 
+
     /**
      * Constant for the F20 function key.
-     * @since 1.2
+     * <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p>
      */
     public static final int VK_F20            = 0xF007;
- 
+
     /**
      * Constant for the F21 function key.
-     * @since 1.2
+     * <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p>
      */
     public static final int VK_F21            = 0xF008;
- 
+
     /**
      * Constant for the F22 function key.
-     * @since 1.2
+     * <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p>
      */
     public static final int VK_F22            = 0xF009;
- 
+
     /**
      * Constant for the F23 function key.
-     * @since 1.2
+     * <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p>
      */
     public static final int VK_F23            = 0xF00A;
- 
+
     /**
      * Constant for the F24 function key.
-     * @since 1.2
+     * <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p>
      */
     public static final int VK_F24            = 0xF00B;
- 
+
     public static final int VK_PRINTSCREEN    = 0x9A;
     public static final int VK_INSERT         = 0x9B;
     public static final int VK_HELP           = 0x9C;
@@ -403,172 +457,152 @@ public class KeyEvent extends InputEvent
     /**
      * Constant for the numeric keypad <b>up</b> arrow key.
      * @see #VK_UP
-     * @since 1.2
      */
     public static final int VK_KP_UP          = 0xE0;
 
     /**
      * Constant for the numeric keypad <b>down</b> arrow key.
      * @see #VK_DOWN
-     * @since 1.2
      */
     public static final int VK_KP_DOWN        = 0xE1;
 
     /**
      * Constant for the numeric keypad <b>left</b> arrow key.
      * @see #VK_LEFT
-     * @since 1.2
      */
     public static final int VK_KP_LEFT        = 0xE2;
 
     /**
      * Constant for the numeric keypad <b>right</b> arrow key.
      * @see #VK_RIGHT
-     * @since 1.2
      */
     public static final int VK_KP_RIGHT       = 0xE3;
-    
-    /* For European keyboards */
-    /** @since 1.2 */
+
+    /** For European keyboards */
     public static final int VK_DEAD_GRAVE               = 0x80;
-    /** @since 1.2 */
+    /** For European keyboards */
     public static final int VK_DEAD_ACUTE               = 0x81;
-    /** @since 1.2 */
+    /** For European keyboards */
     public static final int VK_DEAD_CIRCUMFLEX          = 0x82;
-    /** @since 1.2 */
+    /** For European keyboards */
     public static final int VK_DEAD_TILDE               = 0x83;
-    /** @since 1.2 */
+    /** For European keyboards */
     public static final int VK_DEAD_MACRON              = 0x84;
-    /** @since 1.2 */
+    /** For European keyboards */
     public static final int VK_DEAD_BREVE               = 0x85;
-    /** @since 1.2 */
+    /** For European keyboards */
     public static final int VK_DEAD_ABOVEDOT            = 0x86;
-    /** @since 1.2 */
+    /** For European keyboards */
     public static final int VK_DEAD_DIAERESIS           = 0x87;
-    /** @since 1.2 */
+    /** For European keyboards */
     public static final int VK_DEAD_ABOVERING           = 0x88;
-    /** @since 1.2 */
+    /** For European keyboards */
     public static final int VK_DEAD_DOUBLEACUTE         = 0x89;
-    /** @since 1.2 */
+    /** For European keyboards */
     public static final int VK_DEAD_CARON               = 0x8a;
-    /** @since 1.2 */
+    /** For European keyboards */
     public static final int VK_DEAD_CEDILLA             = 0x8b;
-    /** @since 1.2 */
+    /** For European keyboards */
     public static final int VK_DEAD_OGONEK              = 0x8c;
-    /** @since 1.2 */
+    /** For European keyboards */
     public static final int VK_DEAD_IOTA                = 0x8d;
-    /** @since 1.2 */
+    /** For European keyboards */
     public static final int VK_DEAD_VOICED_SOUND        = 0x8e;
-    /** @since 1.2 */
+    /** For European keyboards */
     public static final int VK_DEAD_SEMIVOICED_SOUND    = 0x8f;
 
-    /** @since 1.2 */
+    /** For European keyboards */
     public static final int VK_AMPERSAND                = 0x96;
-    /** @since 1.2 */
+    /** For European keyboards */
     public static final int VK_ASTERISK                 = 0x97;
-    /** @since 1.2 */
+    /** For European keyboards */
     public static final int VK_QUOTEDBL                 = 0x98;
-    /** @since 1.2 */
+    /** For European keyboards */
     public static final int VK_LESS                     = 0x99;
 
-    /** @since 1.2 */
+    /** For European keyboards */
     public static final int VK_GREATER                  = 0xa0;
-    /** @since 1.2 */
+    /** For European keyboards */
     public static final int VK_BRACELEFT                = 0xa1;
-    /** @since 1.2 */
+    /** For European keyboards */
     public static final int VK_BRACERIGHT               = 0xa2;
 
     /**
      * Constant for the "@" key.
-     * @since 1.2
      */
     public static final int VK_AT                       = 0x0200;
- 
+
     /**
      * Constant for the ":" key.
-     * @since 1.2
      */
     public static final int VK_COLON                    = 0x0201;
- 
+
     /**
      * Constant for the "^" key.
-     * @since 1.2
      */
     public static final int VK_CIRCUMFLEX               = 0x0202;
- 
+
     /**
      * Constant for the "$" key.
-     * @since 1.2
      */
     public static final int VK_DOLLAR                   = 0x0203;
- 
+
     /**
      * Constant for the Euro currency sign key.
-     * @since 1.2
      */
     public static final int VK_EURO_SIGN                = 0x0204;
- 
+
     /**
      * Constant for the "!" key.
-     * @since 1.2
      */
     public static final int VK_EXCLAMATION_MARK         = 0x0205;
- 
+
     /**
      * Constant for the inverted exclamation mark key.
-     * @since 1.2
      */
     public static final int VK_INVERTED_EXCLAMATION_MARK = 0x0206;
- 
+
     /**
      * Constant for the "(" key.
-     * @since 1.2
      */
     public static final int VK_LEFT_PARENTHESIS         = 0x0207;
- 
+
     /**
      * Constant for the "#" key.
-     * @since 1.2
      */
     public static final int VK_NUMBER_SIGN              = 0x0208;
- 
+
     /**
      * Constant for the "+" key.
-     * @since 1.2
      */
     public static final int VK_PLUS                     = 0x0209;
- 
+
     /**
      * Constant for the ")" key.
-     * @since 1.2
      */
     public static final int VK_RIGHT_PARENTHESIS        = 0x020A;
- 
+
     /**
      * Constant for the "_" key.
-     * @since 1.2
      */
     public static final int VK_UNDERSCORE               = 0x020B;
- 
+
     /**
      * Constant for the Microsoft Windows "Windows" key.
      * It is used for both the left and right version of the key.  
-     * @see #getKeyLocation()
-     * @since 1.5
      */
     public static final int VK_WINDOWS                  = 0x020C;
- 
+
     /**
      * Constant for the Microsoft Windows Context Menu key.
-     * @since 1.5
      */
     public static final int VK_CONTEXT_MENU             = 0x020D;
- 
+
     /* for input method support on Asian Keyboards */
 
     /* not clear what this means - listed in Microsoft Windows API */
     public static final int VK_FINAL                    = 0x0018;
-    
+
     /** Constant for the Convert function key. */
     /* Japanese PC 106 keyboard, Japanese Solaris keyboard: henkan */
     public static final int VK_CONVERT                  = 0x001C;
@@ -576,7 +610,7 @@ public class KeyEvent extends InputEvent
     /** Constant for the Don't Convert function key. */
     /* Japanese PC 106 keyboard: muhenkan */
     public static final int VK_NONCONVERT               = 0x001D;
-    
+
     /** Constant for the Accept or Commit function key. */
     /* Japanese Solaris keyboard: kakutei */
     public static final int VK_ACCEPT                   = 0x001E;
@@ -594,87 +628,75 @@ public class KeyEvent extends InputEvent
 
     /**
      * Constant for the Alphanumeric function key.
-     * @since 1.2
      */
     /* Japanese PC 106 keyboard: eisuu */
     public static final int VK_ALPHANUMERIC             = 0x00F0;
- 
+
     /**
      * Constant for the Katakana function key.
-     * @since 1.2
      */
     /* Japanese PC 106 keyboard: katakana */
     public static final int VK_KATAKANA                 = 0x00F1;
- 
+
     /**
      * Constant for the Hiragana function key.
-     * @since 1.2
      */
     /* Japanese PC 106 keyboard: hiragana */
     public static final int VK_HIRAGANA                 = 0x00F2;
- 
+
     /**
      * Constant for the Full-Width Characters function key.
-     * @since 1.2
      */
     /* Japanese PC 106 keyboard: zenkaku */
     public static final int VK_FULL_WIDTH               = 0x00F3;
- 
+
     /**
      * Constant for the Half-Width Characters function key.
-     * @since 1.2
      */
     /* Japanese PC 106 keyboard: hankaku */
     public static final int VK_HALF_WIDTH               = 0x00F4;
- 
+
     /**
      * Constant for the Roman Characters function key.
-     * @since 1.2
      */
     /* Japanese PC 106 keyboard: roumaji */
     public static final int VK_ROMAN_CHARACTERS         = 0x00F5;
- 
+
     /**
      * Constant for the All Candidates function key.
-     * @since 1.2
      */
     /* Japanese PC 106 keyboard - VK_CONVERT + ALT: zenkouho */
     public static final int VK_ALL_CANDIDATES           = 0x0100;
- 
+
     /**
      * Constant for the Previous Candidate function key.
-     * @since 1.2
      */
     /* Japanese PC 106 keyboard - VK_CONVERT + SHIFT: maekouho */
     public static final int VK_PREVIOUS_CANDIDATE       = 0x0101;
- 
+
     /**
      * Constant for the Code Input function key.
-     * @since 1.2
      */
     /* Japanese PC 106 keyboard - VK_ALPHANUMERIC + ALT: kanji bangou */
     public static final int VK_CODE_INPUT               = 0x0102;
- 
+
     /**
      * Constant for the Japanese-Katakana function key.
      * This key switches to a Japanese input method and selects its Katakana input mode.
-     * @since 1.2
      */
     /* Japanese Macintosh keyboard - VK_JAPANESE_HIRAGANA + SHIFT */
     public static final int VK_JAPANESE_KATAKANA        = 0x0103;
- 
+
     /**
      * Constant for the Japanese-Hiragana function key.
      * This key switches to a Japanese input method and selects its Hiragana input mode.
-     * @since 1.2
      */
     /* Japanese Macintosh keyboard */
     public static final int VK_JAPANESE_HIRAGANA        = 0x0104;
- 
+
     /**
      * Constant for the Japanese-Roman function key.
      * This key switches to a Japanese input method and selects its Roman-Direct input mode.
-     * @since 1.2
      */
     /* Japanese Macintosh keyboard */
     public static final int VK_JAPANESE_ROMAN           = 0x0105;
@@ -682,51 +704,38 @@ public class KeyEvent extends InputEvent
     /**
      * Constant for the locking Kana function key.
      * This key locks the keyboard into a Kana layout.
-     * @since 1.3
      */
     /* Japanese PC 106 keyboard with special Windows driver - eisuu + Control; Japanese Solaris keyboard: kana */
     public static final int VK_KANA_LOCK                = 0x0106;
 
     /**
      * Constant for the input method on/off key.
-     * @since 1.3
      */
     /* Japanese PC 106 keyboard: kanji. Japanese Solaris keyboard: nihongo */
     public static final int VK_INPUT_METHOD_ON_OFF      = 0x0107;
 
     /* for Sun keyboards */
-    /** @since 1.2 */
     public static final int VK_CUT                      = 0xFFD1;
-    /** @since 1.2 */
     public static final int VK_COPY                     = 0xFFCD;
-    /** @since 1.2 */
     public static final int VK_PASTE                    = 0xFFCF;
-    /** @since 1.2 */
     public static final int VK_UNDO                     = 0xFFCB;
-    /** @since 1.2 */
     public static final int VK_AGAIN                    = 0xFFC9;
-    /** @since 1.2 */
     public static final int VK_FIND                     = 0xFFD0;
-    /** @since 1.2 */
     public static final int VK_PROPS                    = 0xFFCA;
-    /** @since 1.2 */
     public static final int VK_STOP                     = 0xFFC8;
-    
+
     /**
      * Constant for the Compose function key.
-     * @since 1.2
      */
     public static final int VK_COMPOSE                  = 0xFF20;
- 
+
     /**
      * Constant for the AltGraph function key.
-     * @since 1.2
      */
     public static final int VK_ALT_GRAPH                = 0xFF7E;
 
     /**
      * Constant for the Begin key.
-     * @since 1.5
      */
     public static final int VK_BEGIN                    = 0xFF58;
 
diff --git a/src/newt/classes/com/jogamp/newt/event/MouseEvent.java b/src/newt/classes/com/jogamp/newt/event/MouseEvent.java
index ceaf7d4..914aaa6 100644
--- a/src/newt/classes/com/jogamp/newt/event/MouseEvent.java
+++ b/src/newt/classes/com/jogamp/newt/event/MouseEvent.java
@@ -49,8 +49,15 @@ public class MouseEvent extends InputEvent
     public static final int BUTTON5 = 5;
     /** ID for button 6, value <code>6</code> */
     public static final int BUTTON6 = 6;
-    /** Number of buttons, value <code>6</code> */
-    public static final int BUTTON_NUMBER = 6;
+    /** ID for button 6, value <code>7</code> */
+    public static final int BUTTON7 = 7;
+    /** ID for button 6, value <code>8</code> */
+    public static final int BUTTON8 = 8;
+    /** ID for button 6, value <code>9</code> */
+    public static final int BUTTON9 = 9;
+    
+    /** Maximum number of buttons, value <code>16</code> */
+    public static final int BUTTON_NUMBER =  16;
 
     public static final int getClickTimeout() { 
         return 300; 
@@ -165,7 +172,13 @@ public class MouseEvent extends InputEvent
     }
 
     public String toString() {
-        StringBuilder sb = new StringBuilder();
+        return toString(null).toString();
+    }
+
+    public StringBuilder toString(StringBuilder sb) {
+        if(null == sb) {
+            sb = new StringBuilder();
+        }
         sb.append("MouseEvent[").append(getEventTypeString(getEventType()))
         .append(", ").append(x).append("/").append(y)
         .append(", button ").append(button).append(", count ")
@@ -182,8 +195,8 @@ public class MouseEvent extends InputEvent
             }
             sb.append("]");
         }        
-        sb.append(", ").append(super.toString()).append("]");
-        return sb.toString();
+        sb.append(", ");
+        return super.toString(sb).append("]");
     }
 
     public static String getEventTypeString(int type) {
diff --git a/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java b/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java
index 3f3817b..9d8d92f 100644
--- a/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java
+++ b/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java
@@ -151,15 +151,17 @@ public class NEWTEvent extends java.util.EventObject {
     }
 
     public String toString() {
-        return "NEWTEvent[sys:"+isSystemEvent()+", source:"+getSource().getClass().getName()+", when:"+getWhen()+" d "+(System.currentTimeMillis()-getWhen())+"ms]";
+        return toString(null).toString();
     }
 
-    public static String toHexString(int hex) {
-        return "0x" + Integer.toHexString(hex);
+    public StringBuilder toString(StringBuilder sb) {
+        if(null == sb) {
+            sb = new StringBuilder();
+        }
+        return sb.append("NEWTEvent[sys:").append(isSystemEvent()).append(", source:").append(getSource().getClass().getName()).append(", when:").append(getWhen()).append(" d ").append((System.currentTimeMillis()-getWhen())).append("ms]");
     }
 
-    public static String toHexString(long hex) {
-        return "0x" + Long.toHexString(hex);
+    static String toHexString(int hex) {
+        return "0x" + Integer.toHexString(hex);
     }
-
 }
diff --git a/src/newt/classes/com/jogamp/newt/event/WindowEvent.java b/src/newt/classes/com/jogamp/newt/event/WindowEvent.java
index f3d62d8..163b514 100644
--- a/src/newt/classes/com/jogamp/newt/event/WindowEvent.java
+++ b/src/newt/classes/com/jogamp/newt/event/WindowEvent.java
@@ -39,6 +39,7 @@ package com.jogamp.newt.event;
  * NEWT will automatically handle component moves and resizes internally, regardless of whether a program is receiving these events or not. <br>
  * The actual event semantic, here move and resize, is processed before the event is send.<br>
  */
+ at SuppressWarnings("serial")
 public class WindowEvent extends NEWTEvent {
     public static final int EVENT_WINDOW_RESIZED = 100;
     public static final int EVENT_WINDOW_MOVED   = 101; 
@@ -64,8 +65,16 @@ public class WindowEvent extends NEWTEvent {
             default: return "unknown (" + type + ")";
         }
     }
+    
     public String toString() {
-        return "WindowEvent["+getEventTypeString(getEventType()) +
-            ", " + super.toString() + "]";
+        return toString(null).toString();
+    }
+
+    public StringBuilder toString(StringBuilder sb) {
+        if(null == sb) {
+            sb = new StringBuilder();
+        }
+        sb.append("WindowEvent[").append(getEventTypeString(getEventType())).append(", ");
+        return super.toString(sb).append("]");
     }
 }
diff --git a/src/newt/classes/com/jogamp/newt/event/WindowUpdateEvent.java b/src/newt/classes/com/jogamp/newt/event/WindowUpdateEvent.java
index 505939d..e3f0373 100644
--- a/src/newt/classes/com/jogamp/newt/event/WindowUpdateEvent.java
+++ b/src/newt/classes/com/jogamp/newt/event/WindowUpdateEvent.java
@@ -30,6 +30,7 @@ package com.jogamp.newt.event;
 
 import javax.media.nativewindow.util.Rectangle;
 
+ at SuppressWarnings("serial")
 public class WindowUpdateEvent extends WindowEvent {
     final Rectangle bounds;
 
@@ -44,6 +45,14 @@ public class WindowUpdateEvent extends WindowEvent {
     }
 
     public String toString() {
-        return "WindowUpdateEvent["+super.toString()+", "+bounds+"]";
+        return toString(null).toString();
+    }
+
+    public StringBuilder toString(StringBuilder sb) {
+        if(null == sb) {
+            sb = new StringBuilder();
+        }
+        sb.append("WindowUpdateEvent[").append(bounds).append(", ");
+        return super.toString(sb).append("]");
     }
 }
diff --git a/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java b/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java
index 69b0d04..2d63ca4 100644
--- a/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java
+++ b/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java
@@ -28,6 +28,8 @@
  
 package com.jogamp.newt.event.awt;
 
+import java.awt.Dimension;
+
 import jogamp.newt.awt.event.AWTNewtEventFactory;
 
 public class AWTWindowAdapter 
@@ -61,9 +63,9 @@ public class AWTWindowAdapter
         if(awtComponent instanceof java.awt.Window) {
             ((java.awt.Window)awtComponent).addWindowListener(this);
         }
-        return this;
+        return this;        
     }
-
+    
     public AWTAdapter removeFrom(java.awt.Component awtComponent) {
         awtComponent.removeFocusListener(this);
         awtComponent.removeComponentListener(this);
@@ -89,6 +91,9 @@ public class AWTWindowAdapter
 
     public void focusGained(java.awt.event.FocusEvent e) {
         com.jogamp.newt.event.WindowEvent event = AWTNewtEventFactory.createWindowEvent(e, newtWindow);
+        if(DEBUG_IMPLEMENTATION) {
+            System.err.println("AWT: focusGained: "+e+" -> "+event);
+        }
         if(null!=newtListener) {
             ((com.jogamp.newt.event.WindowListener)newtListener).windowGainedFocus(event);
         } else {
@@ -98,6 +103,9 @@ public class AWTWindowAdapter
 
     public void focusLost(java.awt.event.FocusEvent e) {
         com.jogamp.newt.event.WindowEvent event = AWTNewtEventFactory.createWindowEvent(e, newtWindow);
+        if(DEBUG_IMPLEMENTATION) {
+            System.err.println("AWT: focusLost: "+e+" -> "+event);
+        }
         if(null!=newtListener) {
             ((com.jogamp.newt.event.WindowListener)newtListener).windowLostFocus(event);
         } else {
@@ -108,7 +116,19 @@ public class AWTWindowAdapter
     public void componentResized(java.awt.event.ComponentEvent e) {
         com.jogamp.newt.event.WindowEvent event = AWTNewtEventFactory.createWindowEvent(e, newtWindow);
         if(DEBUG_IMPLEMENTATION) {
-            System.err.println("AWT: componentResized: "+event);
+            final java.awt.Component c = e.getComponent();
+            final java.awt.Dimension sz = c.getSize();
+            final java.awt.Insets insets;
+            final java.awt.Dimension sz2;
+            if(c instanceof java.awt.Container) {
+                insets = ((java.awt.Container)c).getInsets();
+                sz2 = new Dimension(sz.width - insets.left - insets.right,
+                                    sz.height - insets.top - insets.bottom);
+            } else {
+                insets = null;
+                sz2 = sz;
+            }
+            System.err.println("AWT: componentResized: "+sz+" ( "+insets+", "+sz2+" ), "+e+" -> "+event);
         }
         if(null!=newtListener) {
             ((com.jogamp.newt.event.WindowListener)newtListener).windowResized(event);
@@ -120,7 +140,7 @@ public class AWTWindowAdapter
     public void componentMoved(java.awt.event.ComponentEvent e) {
         com.jogamp.newt.event.WindowEvent event = AWTNewtEventFactory.createWindowEvent(e, newtWindow);
         if(DEBUG_IMPLEMENTATION) {
-            System.err.println("AWT: componentMoved: "+event);
+            System.err.println("AWT: componentMoved: "+e+" -> "+event);
         }
         if(null!=newtListener) {
             ((com.jogamp.newt.event.WindowListener)newtListener).windowMoved(event);
diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
index 0fc1b4e..a89ccae 100644
--- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
+++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
@@ -51,6 +51,7 @@ import javax.media.opengl.GLAutoDrawable;
 import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLCapabilitiesImmutable;
 import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
 import javax.media.opengl.GLDrawableFactory;
 import javax.media.opengl.GLEventListener;
 import javax.media.opengl.GLException;
@@ -97,7 +98,7 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
      * Constructor. Do not call this directly -- use {@link #create()} instead.
      */
     protected GLWindow(Window window) {
-        super(null, null, false);
+        super(null, null, false /* always handle device lifecycle ourselves */);
         this.window = (WindowImpl) window;
         this.window.setHandleDestroyNotify(false);
         window.addWindowListener(new WindowAdapter() {
@@ -107,8 +108,8 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
                 }
 
                 @Override
-                public void windowResized(WindowEvent e) {
-                    defaultWindowResizedOp();
+                public void windowResized(WindowEvent e) {                    
+                    defaultWindowResizedOp(getWidth(), getHeight());
                 }
 
                 @Override
@@ -201,11 +202,8 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
 
     @Override
     public final CapabilitiesImmutable getChosenCapabilities() {
-        if (drawable == null) {
-            return window.getChosenCapabilities();
-        }
-
-        return drawable.getChosenGLCapabilities();
+        final GLDrawable _drawable = drawable;
+        return null != _drawable ? _drawable.getChosenGLCapabilities() : window.getChosenCapabilities();        
     }
 
     @Override
@@ -536,19 +534,24 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
             return;
         }
 
+        final boolean done;
         final RecursiveLock lock = window.getLock();
         lock.lock(); // sync: context/drawable could have been recreated/destroyed while animating
         try {
             if( null != context ) {
                 // surface is locked/unlocked implicit by context's makeCurrent/release
                 helper.invokeGL(drawable, context, defaultDisplayAction, defaultInitAction);
-            } else if( 0<getWidth()*getHeight() ) {
-                // retry drawable and context creation, will itself issue resize -> display
-                setVisible(true);
+                done = true;
+            } else {
+                done = false;
             }
         } finally {
             lock.unlock();
         }
+        if( !done && 0<getWidth()*getHeight() ) {
+            // retry drawable and context creation, will itself issue resize -> display
+            setVisible(true);
+        }
     }
 
     //----------------------------------------------------------------------
diff --git a/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java b/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java
index f45b864..5252258 100644
--- a/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java
+++ b/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java
@@ -63,13 +63,13 @@ import com.jogamp.newt.Window;
 import com.jogamp.newt.event.WindowEvent;
 import com.jogamp.newt.util.EDTUtil;
 
+/**
+ * SWT {@link Canvas} containing a NEWT {@link Window} using native parenting.
+ */
 public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol {
     private static final boolean DEBUG = Debug.debug("Window");
     private static final boolean isOSX = NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false);
     
-    /** SWT EDTUtil associated w/ parent's SWT Display */
-    private final EDTUtil swtEDTUtil;
-    
     private final AbstractGraphicsScreen screen;     
     
     private WindowClosingMode newtChildCloseOp = WindowClosingMode.DISPOSE_ON_CLOSE;
@@ -117,8 +117,6 @@ public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol {
     public NewtCanvasSWT(final Composite parent, final int style, Window child) {
         super(parent, style | SWT.NO_BACKGROUND);
         
-        swtEDTUtil = new SWTEDTUtil(parent.getDisplay());
-
         SWTAccessor.setRealized(this, true);
 
         clientArea = getClientArea();
@@ -159,7 +157,7 @@ public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol {
         }
         updateSizeCheck();
         final Rectangle nClientArea = clientArea;
-        if(0 == nClientArea.width * nClientArea.height) {
+        if(0 >= nClientArea.width || 0 >= nClientArea.height) {        
             return false;
         }
         
@@ -326,8 +324,14 @@ public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol {
             updateSizeCheck();
             final int w = clientArea.width;
             final int h = clientArea.height;
-            
-            newtChild.getScreen().getDisplay().setEDTUtil(swtEDTUtil);
+
+            // set SWT EDT and start it
+            {
+                final Display newtDisplay = newtChild.getScreen().getDisplay();
+                final EDTUtil edt = new SWTEDTUtil(newtDisplay, getDisplay());
+                newtDisplay.setEDTUtil(edt);
+                edt.invoke(true, new Runnable() { public void run() { } } ); // start EDT
+            }
             
             newtChild.setSize(w, h);
             newtChild.reparentWindow(nativeWindow);
diff --git a/src/newt/classes/com/jogamp/newt/swt/SWTEDTUtil.java b/src/newt/classes/com/jogamp/newt/swt/SWTEDTUtil.java
index 3538caa..d4b83d8 100644
--- a/src/newt/classes/com/jogamp/newt/swt/SWTEDTUtil.java
+++ b/src/newt/classes/com/jogamp/newt/swt/SWTEDTUtil.java
@@ -27,7 +27,9 @@
  */
 package com.jogamp.newt.swt;
 
-import org.eclipse.swt.widgets.Display;
+import java.awt.EventQueue;
+
+import jogamp.newt.Debug;
 
 import com.jogamp.newt.util.EDTUtil;
 
@@ -36,64 +38,243 @@ import com.jogamp.newt.util.EDTUtil;
  * of the given {@link Display}.
  */
 public class SWTEDTUtil implements EDTUtil {
-    private final Display swtDisplay;
+    public static final boolean DEBUG = Debug.debug("EDT");
+        
+    private final Object edtLock = new Object(); // locking the EDT start/stop state
+    private final ThreadGroup threadGroup; 
+    private final String name;
+    private final Runnable dispatchMessages;
+    private final org.eclipse.swt.widgets.Display swtDisplay;
+    private NewtEventDispatchThread nedt = null;
+    private int start_iter=0;
+    private static long pollPeriod = EDTUtil.defaultEDTPollPeriod;
     
-    public SWTEDTUtil(Display swtDisplay) {
+    public SWTEDTUtil(final com.jogamp.newt.Display newtDisplay, org.eclipse.swt.widgets.Display swtDisplay) {
+        this.threadGroup = Thread.currentThread().getThreadGroup();
+        this.name=Thread.currentThread().getName()+"-SWTDisplay-"+newtDisplay.getFQName()+"-EDT-";
+        this.dispatchMessages = new Runnable() {
+            public void run() {
+                ((jogamp.newt.DisplayImpl) newtDisplay).dispatchMessages();
+            } };
         this.swtDisplay = swtDisplay;
+        this.nedt = new NewtEventDispatchThread(threadGroup, name);
+        this.nedt.setDaemon(true); // don't stop JVM from shutdown ..
     }
     
-    public final Display getDisplay() {
+    public final org.eclipse.swt.widgets.Display getDisplay() {
         return swtDisplay;
     }
     
     @Override
     public long getPollPeriod() {
-        return 0;
+        return pollPeriod;
     }
 
     @Override
     public void setPollPeriod(long ms) {
+        pollPeriod = ms;
     }
 
     @Override
     public void reset() {
+        synchronized(edtLock) { 
+            waitUntilStopped();
+            if(DEBUG) {
+                System.err.println(Thread.currentThread()+": EDT reset - edt: "+nedt);
+            }
+            this.nedt = new NewtEventDispatchThread(threadGroup, name);
+            this.nedt.setDaemon(true); // don't stop JVM from shutdown ..
+        }
     }
 
-    @Override
-    public void start() {
+    private final void startImpl() {
+        if(nedt.isAlive()) {
+            throw new RuntimeException("EDT Thread.isAlive(): true, isRunning: "+nedt.isRunning()+", edt: "+nedt);
+        }
+        start_iter++;
+        nedt.setName(name+start_iter);
+        nedt.shouldStop = false;
+        if(DEBUG) {
+            System.err.println(Thread.currentThread()+": EDT START - edt: "+nedt);
+            // Thread.dumpStack();
+        }
+        nedt.start();
     }
-
+    
     @Override
     public boolean isCurrentThreadEDT() {
         return swtDisplay.getThread() == Thread.currentThread();
     }
 
     @Override
+    public final boolean isCurrentThreadNEDT() {
+        return nedt == Thread.currentThread();
+    }
+    
+    @Override
+    public final boolean isCurrentThreadEDTorNEDT() {
+        final Thread ct = Thread.currentThread();
+        return ct == swtDisplay.getThread() || ct == nedt ;
+    }
+    
+    @Override
     public boolean isRunning() {
-        return true;
+        return nedt.isRunning() ; // SWT is always running
     }
-
+    
     @Override
-    public void invokeStop(Runnable finalTask) {
-        swtDisplay.syncExec(finalTask);
+    public final void invokeStop(Runnable task) {
+        invokeImpl(true, task, true);
     }
 
     @Override
-    public void invoke(boolean wait, Runnable task) {
+    public final void invoke(boolean wait, Runnable task) {
+        invokeImpl(wait, task, false);
+    }
+    
+    private void invokeImpl(boolean wait, Runnable task, boolean stop) {
+        if(task == null) {
+            throw new RuntimeException("Null Runnable");
+        }
+        synchronized(edtLock) { // lock the EDT status
+            if( nedt.shouldStop ) {
+                // drop task ..
+                if(DEBUG) {
+                    System.err.println("Warning: EDT about (1) to stop, won't enqueue new task: "+nedt);
+                    Thread.dumpStack();
+                }
+                return; 
+            }
+            // System.err.println(Thread.currentThread()+" XXX stop: "+stop+", tasks: "+edt.tasks.size()+", task: "+task);
+            // Thread.dumpStack();
+            if(stop) {
+                nedt.shouldStop = true;
+                if(DEBUG) {
+                    System.err.println(Thread.currentThread()+": EDT signal STOP (on edt: "+isCurrentThreadEDT()+") - "+nedt);
+                    // Thread.dumpStack();
+                }
+            }
+            
+            // start if should not stop && not started yet                    
+            if( !stop && !nedt.isRunning() ) {
+                startImpl();
+            }
+        }
         if(wait) {
             swtDisplay.syncExec(task);
         } else {
             swtDisplay.asyncExec(task);
         }
-    }
+    }    
 
     @Override
-    public void waitUntilIdle() {
-        // all sync ..
+    final public void waitUntilIdle() {
+        final NewtEventDispatchThread _edt;
+        synchronized(edtLock) {
+            _edt = nedt;
+        }
+        if(!_edt.isRunning() || EventQueue.isDispatchThread()  || _edt == Thread.currentThread()) {
+            return;
+        }
+        try {
+            swtDisplay.syncExec(new Runnable() {
+                public void run() { }
+            });
+        } catch (Exception e) { }
     }
 
     @Override
-    public void waitUntilStopped() {
-        // all sync ..
+    final public void waitUntilStopped() {
+        synchronized(edtLock) {
+            if(nedt.isRunning() && nedt != Thread.currentThread() ) {
+                while(nedt.isRunning()) {
+                    try {
+                        edtLock.wait();
+                    } catch (InterruptedException e) {
+                        e.printStackTrace();
+                    }
+                }
+            }
+        }
     }
+    
+    class NewtEventDispatchThread extends Thread {
+        volatile boolean shouldStop = false;
+        volatile boolean isRunning = false;
+        Object sync = new Object();
+
+        public NewtEventDispatchThread(ThreadGroup tg, String name) {
+            super(tg, name);
+        }
+
+        final public boolean isRunning() {
+            return isRunning;
+        }
+
+        @Override
+        final public void start() throws IllegalThreadStateException {
+            isRunning = true;
+            super.start();
+        }
+
+        /** 
+         * Utilizing locking only on tasks and its execution,
+         * not for event dispatching.
+         */
+        @Override
+        final public void run() {
+            if(DEBUG) {
+                System.err.println(getName()+": EDT run() START "+ getName());
+            }
+            RuntimeException error = null;
+            try {
+                do {
+                    // event dispatch
+                    if(!shouldStop) {
+                        // FIXME: Determine whether we require to run the 
+                        // delivery of events (dispatch) on AWT-EDT.
+                        // Since the WindowDriver itself delivers all Window related events,
+                        // this shall not be required.
+                        //   AWTEDTExecutor.singleton.invoke(true, dispatchMessages);
+                        dispatchMessages.run();
+                    }
+                    // wait
+                    synchronized(sync) {
+                        if(!shouldStop) {
+                            try {
+                                sync.wait(pollPeriod);
+                            } catch (InterruptedException e) {
+                                e.printStackTrace();
+                            }
+                        }
+                    }
+                } while(!shouldStop) ;
+            } catch (Throwable t) {
+                // handle errors ..
+                shouldStop = true;
+                if(t instanceof RuntimeException) {
+                    error = (RuntimeException) t;
+                } else {
+                    error = new RuntimeException("Within EDT", t);
+                }
+            } finally {
+                if(DEBUG) {
+                    System.err.println(getName()+": EDT run() END "+ getName()+", "+error); 
+                }
+                synchronized(edtLock) {
+                    isRunning = !shouldStop;
+                    if(!isRunning) {
+                        edtLock.notifyAll();
+                    }
+                }
+                if(DEBUG) {
+                    System.err.println(getName()+": EDT run() EXIT "+ getName()+", exception: "+error);
+                }
+                if(null!=error) {
+                    throw error;
+                }
+            } // finally
+        } // run()
+    } // EventDispatchThread
+    
 }
diff --git a/src/newt/classes/com/jogamp/newt/util/EDTUtil.java b/src/newt/classes/com/jogamp/newt/util/EDTUtil.java
index 4493e27..7e19d9d 100644
--- a/src/newt/classes/com/jogamp/newt/util/EDTUtil.java
+++ b/src/newt/classes/com/jogamp/newt/util/EDTUtil.java
@@ -28,6 +28,9 @@
 
 package com.jogamp.newt.util;
 
+import jogamp.newt.DisplayImpl;
+import com.jogamp.newt.event.NEWTEvent;
+
 /**
  * EDT stands for Event Dispatch Thread.
  * <p>
@@ -63,25 +66,46 @@ public interface EDTUtil {
     
     /**
      * Create a new EDT. One should invoke <code>reset()</code><br>
-     * after <code>invokeStop(..)</code> in case another <code>start()</code> or <code>invoke(..)</code>
+     * after <code>invokeStop(..)</code> in case another start via <code>invoke(..)</code>
      * is expected.
      *
-     * @see #start()
      * @see #invoke(boolean, java.lang.Runnable)
      * @see #invokeStop(java.lang.Runnable)
      */
     public void reset();
 
     /**
-     * Start the EDT
+     * Returns true if the current thread is the event dispatch thread (EDT).
+     * <p>
+     * The EDT is the platform specific thread dispatching toolkit-events 
+     * and executing toolkit-tasks enqueued via {@link #invoke(boolean, Runnable)}.
+     * </p>
+     * <p>
+     * Usually it is the same thread as used to dequeue informal {@link NEWTEvent}s (NEDT), see {@link #isCurrentThreadNEDT()}, 
+     * however, this may differ, e.g. SWT and AWT implementation.
+     * </p>
      */
-    public void start();
+    public boolean isCurrentThreadEDT();
 
     /**
-     * @return True if the current thread is the EDT thread
+     * Returns true if the current thread is the internal NEWT event dequeue thread (NEDT).
+     * <p>
+     * The NEDT is the NEWT thread used to dequeue informal {@link NEWTEvent}s enqueued internally 
+     * via {@link DisplayImpl#enqueueEvent(boolean, NEWTEvent)}.
+     * </p>
+     * <p>
+     * Usually it is the same thread as the EDT, see {@link #isCurrentThreadEDT()}, 
+     * however, this may differ, e.g. SWT and AWT implementation.
+     * </p>
      */
-    public boolean isCurrentThreadEDT();
-
+    public boolean isCurrentThreadNEDT();
+    
+    /**
+     * Returns <code>true</code> if either {@link #isCurrentThreadEDT()} or {@link #isCurrentThreadNEDT()} is <code>true</code>,
+     * otherwise <code>false</code>.
+     */
+    public boolean isCurrentThreadEDTorNEDT();
+    
     /**
      * @return True if EDT is running
      */
@@ -101,9 +125,9 @@ public interface EDTUtil {
     public void invokeStop(Runnable finalTask);
 
     /** 
+     * Shall start the thread if not running.<br>
      * Append task to the EDT task queue.<br>
      * Wait until execution is finished if <code>wait == true</code>.<br>
-     * Shall start the thread if not running.<br>
      * Can be issued from within EDT, ie from within an enqueued task.<br>
      *
      * @throws RuntimeException in case EDT is stopped and not {@link #reset()}
diff --git a/src/newt/classes/com/jogamp/newt/util/MainThread.java b/src/newt/classes/com/jogamp/newt/util/MainThread.java
index bbe415b..5e79e9b 100644
--- a/src/newt/classes/com/jogamp/newt/util/MainThread.java
+++ b/src/newt/classes/com/jogamp/newt/util/MainThread.java
@@ -74,7 +74,7 @@ import jogamp.newt.NEWTJNILibLoader;
  *
  * To support your NEWT Window platform, 
  * you have to pass your <i>main thread</i> actions to {@link #invoke invoke(..)},
- * have a look at the {@link com.jogamp.newt.macosx.MacWindow MacWindow} implementation.<br>
+ * have a look at the {@link jogamp.newt.driver.macosx.WindowDriver NEWT Mac OSX Window} driver implementation.<br>
  * <i>TODO</i>: Some hardcoded dependencies exist in this implementation, 
  * where you have to patch this code or factor it out. <P>
  * 
@@ -92,7 +92,7 @@ import jogamp.newt.NEWTJNILibLoader;
  * Which starts 4 threads, each with a window and OpenGL rendering.<br>
  */
 public class MainThread {
-    private static final String MACOSXDisplayClassName = "jogamp.newt.driver.macosx.MacDisplay";
+    private static final String MACOSXDisplayClassName = "jogamp.newt.driver.macosx.DisplayDriver";
     private static final Platform.OSType osType;
     private static final boolean isMacOSX;
     private static final ThreadGroup rootThreadGroup;
@@ -101,7 +101,7 @@ public class MainThread {
     public static final boolean  HINT_USE_MAIN_THREAD;
     
     static {
-        NativeWindowFactory.initSingleton(true);
+        NativeWindowFactory.initSingleton();
         NEWTJNILibLoader.loadNEWT();
         HINT_USE_MAIN_THREAD = !NativeWindowFactory.isAWTAvailable() || 
                                 Debug.getBooleanProperty("newt.MainThread.force", true);
diff --git a/src/newt/classes/jogamp/newt/DefaultEDTUtil.java b/src/newt/classes/jogamp/newt/DefaultEDTUtil.java
index bdbe960..18418a8 100644
--- a/src/newt/classes/jogamp/newt/DefaultEDTUtil.java
+++ b/src/newt/classes/jogamp/newt/DefaultEDTUtil.java
@@ -49,12 +49,12 @@ import com.jogamp.newt.util.EDTUtil;
 public class DefaultEDTUtil implements EDTUtil {
     public static final boolean DEBUG = Debug.debug("EDT");
 
-    private ThreadGroup threadGroup; 
+    private final Object edtLock = new Object(); // locking the EDT start/stop state
+    private final ThreadGroup threadGroup; 
+    private final String name;
+    private final Runnable dispatchMessages;
     private EventDispatchThread edt = null;
-    private Object edtLock = new Object(); // locking the EDT start/stop state
-    private String name;
-    int start_iter=0;
-    private Runnable dispatchMessages;
+    private int start_iter=0;
     private static long pollPeriod = EDTUtil.defaultEDTPollPeriod;
 
     public DefaultEDTUtil(ThreadGroup tg, String name, Runnable dispatchMessages) {
@@ -65,14 +65,17 @@ public class DefaultEDTUtil implements EDTUtil {
         this.edt.setDaemon(true); // don't stop JVM from shutdown ..
     }
 
+    @Override
     final public long getPollPeriod() {
         return pollPeriod;
     }
 
+    @Override
     final public void setPollPeriod(long ms) {
         pollPeriod = ms;
     }
     
+    @Override
     public final void reset() {
         synchronized(edtLock) { 
             waitUntilStopped();
@@ -88,36 +91,46 @@ public class DefaultEDTUtil implements EDTUtil {
         }
     }
 
-    public final void start() {
-        synchronized(edtLock) { 
-            if(!edt.isRunning() && !edt.shouldStop) {
-                if(edt.isAlive()) {
-                    throw new RuntimeException("EDT Thread.isAlive(): true, isRunning: "+edt.isRunning()+", edt: "+edt+", tasks: "+edt.tasks.size());
-                }
-                start_iter++;
-                edt.setName(name+start_iter);
-                edt.shouldStop = false;
-                if(DEBUG) {
-                    System.err.println(Thread.currentThread()+": EDT START - edt: "+edt);
-                    // Thread.dumpStack();
-                }
-                edt.start();
-            }
+    private final void startImpl() {
+        if(edt.isAlive()) {
+            throw new RuntimeException("EDT Thread.isAlive(): true, isRunning: "+edt.isRunning()+", edt: "+edt+", tasks: "+edt.tasks.size());
         }
+        start_iter++;
+        edt.setName(name+start_iter);
+        edt.shouldStop = false;
+        if(DEBUG) {
+            System.err.println(Thread.currentThread()+": EDT START - edt: "+edt);
+            // Thread.dumpStack();
+        }
+        edt.start();
     }
 
+    @Override
     public final boolean isCurrentThreadEDT() {
-        return edt == Thread.currentThread();
+        return edt == Thread.currentThread(); // EDT == NEDT
+    }
+    
+    @Override
+    public final boolean isCurrentThreadNEDT() {
+        return edt == Thread.currentThread(); // EDT == NEDT
     }
 
+    @Override
+    public final boolean isCurrentThreadEDTorNEDT() {
+        return edt == Thread.currentThread(); // EDT == NEDT
+    }    
+    
+    @Override
     public final boolean isRunning() {
         return edt.isRunning() ;
     }
 
+    @Override
     public final void invokeStop(Runnable task) {
         invokeImpl(true, task, true);
     }
 
+    @Override
     public final void invoke(boolean wait, Runnable task) {
         invokeImpl(wait, task, false);
     }
@@ -158,8 +171,11 @@ public class DefaultEDTUtil implements EDTUtil {
                         }
                     }
                 } else {
+                    // start if should not stop && not started yet                    
+                    if( !stop && !edt.isRunning() ) {
+                        startImpl();
+                    }
                     synchronized(edt.tasks) {
-                        start(); // start if not started yet and !shouldStop
                         wait = wait && edt.isRunning();
                         rTask = new RunnableTask(task,
                                                  wait ? rTaskLock : null,
@@ -195,6 +211,7 @@ public class DefaultEDTUtil implements EDTUtil {
         }
     }
 
+    @Override
     final public void waitUntilIdle() {
         final EventDispatchThread _edt;
         synchronized(edtLock) {
@@ -215,6 +232,7 @@ public class DefaultEDTUtil implements EDTUtil {
         }
     }
 
+    @Override
     final public void waitUntilStopped() {
         synchronized(edtLock) {
             if(edt.isRunning() && edt != Thread.currentThread() ) {
diff --git a/src/newt/classes/jogamp/newt/DisplayImpl.java b/src/newt/classes/jogamp/newt/DisplayImpl.java
index b178bb5..fbccc57 100644
--- a/src/newt/classes/jogamp/newt/DisplayImpl.java
+++ b/src/newt/classes/jogamp/newt/DisplayImpl.java
@@ -42,9 +42,9 @@ import com.jogamp.newt.event.NEWTEventConsumer;
 import jogamp.newt.event.NEWTEventTask;
 import com.jogamp.newt.util.EDTUtil;
 import java.util.ArrayList;
+
 import javax.media.nativewindow.AbstractGraphicsDevice;
 import javax.media.nativewindow.NativeWindowException;
-import javax.media.nativewindow.NativeWindowFactory;
 
 public abstract class DisplayImpl extends Display {
     private static int serialno = 1;
@@ -52,26 +52,9 @@ public abstract class DisplayImpl extends Display {
     private static Class<?> getDisplayClass(String type) 
         throws ClassNotFoundException 
     {
-        Class<?> displayClass = NewtFactory.getCustomClass(type, "Display");
-        if(null==displayClass) {
-            if (NativeWindowFactory.TYPE_ANDROID == type) {
-                displayClass = Class.forName("jogamp.newt.driver.android.AndroidDisplay");
-            } else if (NativeWindowFactory.TYPE_EGL == type) {
-                displayClass = Class.forName("jogamp.newt.driver.kd.KDDisplay");
-            } else if (NativeWindowFactory.TYPE_WINDOWS == type) {
-                displayClass = Class.forName("jogamp.newt.driver.windows.WindowsDisplay");
-            } else if (NativeWindowFactory.TYPE_MACOSX == type) {
-                displayClass = Class.forName("jogamp.newt.driver.macosx.MacDisplay");
-            } else if (NativeWindowFactory.TYPE_X11 == type) {
-                displayClass = Class.forName("jogamp.newt.driver.x11.X11Display");
-            } else if (NativeWindowFactory.TYPE_AWT == type) {
-                displayClass = Class.forName("jogamp.newt.driver.awt.AWTDisplay");
-            } else {
-                throw new RuntimeException("Unknown display type \"" + type + "\"");
-            }
-        }
+        final Class<?> displayClass = NewtFactory.getCustomClass(type, "DisplayDriver");
         if(null==displayClass) {
-            throw new ClassNotFoundException("Failed to find NEWT Display Class <"+type+".Display>");            
+            throw new ClassNotFoundException("Failed to find NEWT Display Class <"+type+".DisplayDriver>");            
         }
         return displayClass;
     }
@@ -84,7 +67,7 @@ public abstract class DisplayImpl extends Display {
             name = display.validateDisplayName(name, handle);
             synchronized(displayList) {
                 if(reuse) {
-                    Display display0 = Display.getLastDisplayOf(type, name, -1);
+                    Display display0 = Display.getLastDisplayOf(type, name, -1, true /* shared only */);
                     if(null != display0) {
                         if(DEBUG) {
                             System.err.println("Display.create() REUSE: "+display0+" "+getThreadName());
@@ -92,9 +75,9 @@ public abstract class DisplayImpl extends Display {
                         return display0;
                     }
                 }
+                display.exclusive = !reuse;
                 display.name = name;
                 display.type=type;
-                display.destroyWhenUnused=false;
                 display.refCount=0;
                 display.id = serialno++;
                 display.fqname = getFQName(display.type, display.name, display.id);
@@ -112,7 +95,7 @@ public abstract class DisplayImpl extends Display {
             throw new RuntimeException(e);
         }
     }
-
+    
     @Override
     public boolean equals(Object obj) {
         if (obj == null) {
@@ -134,10 +117,12 @@ public abstract class DisplayImpl extends Display {
         return true;
     }
 
+    @Override
     public int hashCode() {
         return hashCode;
     }
 
+    @Override
     public  synchronized final void createNative()
         throws NativeWindowException
     {
@@ -166,10 +151,6 @@ public abstract class DisplayImpl extends Display {
         }
     }
 
-    protected boolean shallRunOnEDT() { 
-        return true; 
-    }
-
     protected EDTUtil createEDTUtil() {
         final EDTUtil def;
         if(NewtFactory.useEDT()) {
@@ -187,8 +168,7 @@ public abstract class DisplayImpl extends Display {
     public EDTUtil setEDTUtil(EDTUtil newEDTUtil) {        
         if(null == newEDTUtil) {
             newEDTUtil = createEDTUtil();
-        }
-        if( newEDTUtil == edtUtil ) {
+        } else if( newEDTUtil == edtUtil ) {
             if(DEBUG) {
                 System.err.println("Display.setEDTUtil: "+newEDTUtil+" - keep!");
             }
@@ -198,12 +178,7 @@ public abstract class DisplayImpl extends Display {
         if(DEBUG) {
             System.err.println("Display.setEDTUtil: "+oldEDTUtil+" -> "+newEDTUtil);
         }
-        if(null != oldEDTUtil) {
-            stopEDT( new Runnable() { public void run() {} } );
-            // ready for restart ..
-            oldEDTUtil.waitUntilStopped();
-            oldEDTUtil.reset();
-        }
+        removeEDT( new Runnable() { public void run() {} } );
         edtUtil = newEDTUtil;
         return oldEDTUtil;
     }
@@ -213,16 +188,19 @@ public abstract class DisplayImpl extends Display {
         return edtUtil;
     }
 
-    private void stopEDT(final Runnable task) {
-        if( shallRunOnEDT() && null!=edtUtil ) {
+    private void removeEDT(final Runnable task) {
+        if(null!=edtUtil) {            
             edtUtil.invokeStop(task);
+            // ready for restart ..
+            edtUtil.waitUntilStopped();
+            edtUtil.reset();
         } else {
             task.run();
         }
     }
 
     public void runOnEDTIfAvail(boolean wait, final Runnable task) {
-        if( shallRunOnEDT() && null!=edtUtil && !edtUtil.isCurrentThreadEDT()) {
+        if( null!=edtUtil && !edtUtil.isCurrentThreadEDT()) {
             edtUtil.invoke(wait, task);
         } else {
             task.run();
@@ -231,18 +209,17 @@ public abstract class DisplayImpl extends Display {
 
     public boolean validateEDT() {
         if(0==refCount && null==aDevice && null != edtUtil && edtUtil.isRunning()) {
-            stopEDT( new Runnable() {
+            removeEDT( new Runnable() {
                 public void run() {
                     // nop
                 }
             } );
-            edtUtil.waitUntilStopped();
-            edtUtil.reset();
             return true;
         }
         return false;
     }
 
+    @Override
     public synchronized final void destroy() {
         if(DEBUG) {
             dumpDisplayList("Display.destroy("+getFQName()+") BEGIN");
@@ -258,17 +235,13 @@ public abstract class DisplayImpl extends Display {
         }
         final AbstractGraphicsDevice f_aDevice = aDevice;
         final DisplayImpl f_dpy = this;
-        stopEDT( new Runnable() {
+        removeEDT( new Runnable() {
             public void run() {
                 if ( null != f_aDevice ) {
                     f_dpy.closeNativeImpl();
                 }
             }
         } );
-        if(null!=edtUtil) {
-            edtUtil.waitUntilStopped();
-            edtUtil.reset();
-        }
         aDevice = null;
         refCount=0;
         if(DEBUG) {
@@ -309,21 +282,30 @@ public abstract class DisplayImpl extends Display {
     protected abstract void createNativeImpl();
     protected abstract void closeNativeImpl();
 
+    @Override
     public final int getId() {
         return id;
     }
 
+    @Override
     public final String getType() {
         return type;
     }
 
+    @Override
     public final String getName() {
         return name;
     }
 
+    @Override
     public final String getFQName() {
         return fqname;
     }
+    
+    @Override
+    public final boolean isExclusive() {
+        return exclusive;
+    }
 
     public static final String nilString = "nil" ;
 
@@ -343,9 +325,10 @@ public abstract class DisplayImpl extends Display {
         sb.append(name);
         sb.append("-");
         sb.append(id);
-        return sb.toString().intern();
+        return sb.toString();
     }
 
+    @Override
     public final long getHandle() {
         if(null!=aDevice) {
             return aDevice.getHandle();
@@ -353,14 +336,17 @@ public abstract class DisplayImpl extends Display {
         return 0;
     }
 
+    @Override
     public final AbstractGraphicsDevice getGraphicsDevice() {
         return aDevice;
     }
 
+    @Override
     public synchronized final boolean isNativeValid() {
         return null != aDevice;
     }
 
+    @Override
     public boolean isEDTRunning() {
         if(null!=edtUtil) {
             return edtUtil.isRunning();
@@ -370,9 +356,10 @@ public abstract class DisplayImpl extends Display {
 
     @Override
     public String toString() {
-        return "NEWT-Display["+getFQName()+", refCount "+refCount+", hasEDT "+(null!=edtUtil)+", edtRunning "+isEDTRunning()+", "+aDevice+"]";
+        return "NEWT-Display["+getFQName()+", excl "+exclusive+", refCount "+refCount+", hasEDT "+(null!=edtUtil)+", edtRunning "+isEDTRunning()+", "+aDevice+"]";
     }
 
+    /** Dispatch native Toolkit messageges */
     protected abstract void dispatchMessagesNative();
 
     private Object eventsLock = new Object();
@@ -384,7 +371,7 @@ public abstract class DisplayImpl extends Display {
             DisplayImpl.this.dispatchMessages();
         }
     }
-    DispatchMessagesRunnable dispatchMessagesRunnable = new DispatchMessagesRunnable();
+    protected DispatchMessagesRunnable dispatchMessagesRunnable = new DispatchMessagesRunnable();
 
     final void dispatchMessage(final NEWTEventTask eventTask) {
         final NEWTEvent event = eventTask.get();
@@ -422,6 +409,7 @@ public abstract class DisplayImpl extends Display {
         eventTask.notifyCaller();        
     }
     
+    @Override
     public void dispatchMessages() {
         // System.err.println("Display.dispatchMessages() 0 "+this+" "+getThreadName());
         if(0==refCount || // no screens 
@@ -464,8 +452,8 @@ public abstract class DisplayImpl extends Display {
             return;
         }
         
-        // can't wait if we are on EDT -> consume right away
-        if(wait && edtUtil.isCurrentThreadEDT()) {
+        // can't wait if we are on EDT or NEDT -> consume right away
+        if(wait && edtUtil.isCurrentThreadEDTorNEDT() ) {
             dispatchMessage(new NEWTEventTask(e, null));
             return;
         }
@@ -494,20 +482,23 @@ public abstract class DisplayImpl extends Display {
     public interface DisplayRunnable<T> {
         T run(long dpy);
     }    
-    public final <T> T runWithLockedDisplayHandle(DisplayRunnable<T> action) {
-        final AbstractGraphicsDevice aDevice = getGraphicsDevice();
-        if(null == aDevice) {
-            throw new RuntimeException("null device - not initialized: "+this);
-        }
+    public static final <T> T runWithLockedDevice(AbstractGraphicsDevice device, DisplayRunnable<T> action) {
         T res;
-        aDevice.lock();
+        device.lock();
         try {
-            res = action.run(aDevice.getHandle());
+            res = action.run(device.getHandle());
         } finally {
-            aDevice.unlock();
+            device.unlock();
         }
         return res;
     }
+    public final <T> T runWithLockedDisplayDevice(DisplayRunnable<T> action) {
+        final AbstractGraphicsDevice device = getGraphicsDevice();
+        if(null == device) {
+            throw new RuntimeException("null device - not initialized: "+this);
+        }
+        return runWithLockedDevice(device, action);
+    }
     
     protected EDTUtil edtUtil = null;
     protected int id;
@@ -516,7 +507,7 @@ public abstract class DisplayImpl extends Display {
     protected String fqname;
     protected int hashCode;
     protected int refCount; // number of Display references by Screen
-    protected boolean destroyWhenUnused;
+    protected boolean exclusive; // do not share this display, uses NullLock!
     protected AbstractGraphicsDevice aDevice;
 }
 
diff --git a/src/newt/classes/jogamp/newt/OffscreenWindow.java b/src/newt/classes/jogamp/newt/OffscreenWindow.java
index ba98ca3..c6c1814 100644
--- a/src/newt/classes/jogamp/newt/OffscreenWindow.java
+++ b/src/newt/classes/jogamp/newt/OffscreenWindow.java
@@ -39,20 +39,16 @@ import javax.media.nativewindow.AbstractGraphicsScreen;
 import javax.media.nativewindow.GraphicsConfigurationFactory;
 import javax.media.nativewindow.MutableSurface;
 import javax.media.nativewindow.NativeWindowException;
-import javax.media.nativewindow.ProxySurface;
 import javax.media.nativewindow.VisualIDHolder;
 import javax.media.nativewindow.util.Insets;
 import javax.media.nativewindow.util.Point;
 
 public class OffscreenWindow extends WindowImpl implements MutableSurface {
 
-    long surfaceHandle = 0;
-    ProxySurface.UpstreamSurfaceHook upstreamHook;
-    ProxySurface dummySurface;
+    long surfaceHandle;
     
     public OffscreenWindow() {
-        upstreamHook = null;
-        dummySurface = null;
+        surfaceHandle = 0;
     }
 
     static long nextWindowHandle = 0x100; // start here - a marker
@@ -62,17 +58,6 @@ public class OffscreenWindow extends WindowImpl implements MutableSurface {
             throw new NativeWindowException("Capabilities is onscreen");
         }
         final AbstractGraphicsScreen aScreen = getScreen().getGraphicsScreen();
-        /** Cannot use OpenGL here ..
-        if(capsRequested instanceof GLCapabilitiesImmutable) {
-            final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) capsRequested;
-            if(caps.isFBO() && GLContext.isFBOAvailable(aScreen.getDevice(), caps.getGLProfile()) ) {
-                final GLDrawableFactoryImpl factory = (GLDrawableFactoryImpl) GLDrawableFactory.getFactory(caps.getGLProfile());
-                final GLCapabilitiesImmutable dummyCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(caps);
-                final ProxySurface dummySurface = factory.createDummySurfaceImpl(aScreen.getDevice(), false, dummyCaps, null, 64, 64);
-                upstreamHook = dummySurface.getUpstreamSurfaceHook();
-                dummySurface.createNotify();
-            }
-        } */
         final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(aScreen.getDevice(), capsRequested).chooseGraphicsConfiguration(
                                                          capsRequested, capsRequested, capabilitiesChooser, aScreen, VisualIDHolder.VID_UNDEFINED);
         if (null == cfg) {
@@ -83,6 +68,7 @@ public class OffscreenWindow extends WindowImpl implements MutableSurface {
         synchronized(OffscreenWindow.class) {
             setWindowHandle(nextWindowHandle++);
         }
+        visibleChanged(false, true);        
     }
 
     protected void closeNativeImpl() {
@@ -92,11 +78,6 @@ public class OffscreenWindow extends WindowImpl implements MutableSurface {
     @Override
     public synchronized void destroy() {
         super.destroy();
-        if(null != dummySurface) {
-            dummySurface.destroyNotify();
-            dummySurface = null;
-            upstreamHook = null;
-        }
         surfaceHandle = 0;
     }
 
@@ -106,10 +87,6 @@ public class OffscreenWindow extends WindowImpl implements MutableSurface {
 
     @Override
     public long getSurfaceHandle() {
-        if(null != dummySurface) {
-            return dummySurface.getSurfaceHandle();
-            // return upstreamHook.getWidth();
-        }
         return surfaceHandle;
     }        
 
@@ -128,8 +105,8 @@ public class OffscreenWindow extends WindowImpl implements MutableSurface {
     }
 
     protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) {
+        sizeChanged(false, width, height, false);
         if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) {
-            sizeChanged(false, width, height, false);
             visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags));
         } else {
             /**
diff --git a/src/newt/classes/jogamp/newt/ScreenImpl.java b/src/newt/classes/jogamp/newt/ScreenImpl.java
index cf614b6..56d6f67 100644
--- a/src/newt/classes/jogamp/newt/ScreenImpl.java
+++ b/src/newt/classes/jogamp/newt/ScreenImpl.java
@@ -42,7 +42,6 @@ import java.util.List;
 
 import javax.media.nativewindow.AbstractGraphicsScreen;
 import javax.media.nativewindow.NativeWindowException;
-import javax.media.nativewindow.NativeWindowFactory;
 import javax.media.nativewindow.util.Dimension;
 import javax.media.nativewindow.util.DimensionImmutable;
 import javax.media.nativewindow.util.Point;
@@ -90,31 +89,13 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
         });
     }
     
-    @SuppressWarnings("unchecked")
-    private static Class<? extends Screen> getScreenClass(String type) throws ClassNotFoundException 
+    private static Class<?> getScreenClass(String type) throws ClassNotFoundException 
     {
-        Class<?> screenClass = NewtFactory.getCustomClass(type, "Screen");
+        final Class<?> screenClass = NewtFactory.getCustomClass(type, "ScreenDriver");
         if(null==screenClass) {
-            if (NativeWindowFactory.TYPE_ANDROID == type) {
-                screenClass = Class.forName("jogamp.newt.driver.android.AndroidScreen");
-            } else if (NativeWindowFactory.TYPE_EGL == type) {
-                screenClass = Class.forName("jogamp.newt.driver.kd.KDScreen");
-            } else if (NativeWindowFactory.TYPE_WINDOWS == type) {
-                screenClass = Class.forName("jogamp.newt.driver.windows.WindowsScreen");
-            } else if (NativeWindowFactory.TYPE_MACOSX == type) {
-                screenClass = Class.forName("jogamp.newt.driver.macosx.MacScreen");
-            } else if (NativeWindowFactory.TYPE_X11 == type) {
-                screenClass = Class.forName("jogamp.newt.driver.x11.X11Screen");
-            } else if (NativeWindowFactory.TYPE_AWT == type) {
-                screenClass = Class.forName("jogamp.newt.driver.awt.AWTScreen");
-            } else {
-                throw new RuntimeException("Unknown window type \"" + type + "\"");
-            }
+            throw new ClassNotFoundException("Failed to find NEWT Screen Class <"+type+".ScreenDriver>");            
         }
-        if(null==screenClass) {
-            throw new ClassNotFoundException("Failed to find NEWT Screen Class <"+type+".Screen>");            
-        }
-        return (Class<? extends Screen>)screenClass;
+        return screenClass;
     }
 
     public static Screen create(Display display, int idx) {
@@ -133,7 +114,7 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
                 }
             }
             synchronized(screenList) {
-                Class<? extends Screen> screenClass = getScreenClass(display.getType());
+                Class<?> screenClass = getScreenClass(display.getType());
                 ScreenImpl screen  = (ScreenImpl) screenClass.newInstance();
                 screen.display = (DisplayImpl) display;
                 idx = screen.validateScreenIndex(idx);
@@ -148,7 +129,7 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
                     }
                 }
                 screen.screen_idx = idx;
-                screen.fqname = (display.getFQName()+idx).intern();
+                screen.fqname = display.getFQName()+"-s"+idx;
                 screen.hashCode = screen.fqname.hashCode();
                 screenList.add(screen);
                 if(DEBUG) {
@@ -296,7 +277,7 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
     protected void updateVirtualScreenOriginAndSize() {
         getVirtualScreenOriginAndSize(vOrigin, vSize);
         if(DEBUG) {
-            System.err.println("Detected screen origin "+vOrigin+", size "+vSize);
+            System.err.println("Detected virtual screen origin "+vOrigin+", size "+vSize);
         }
     }
 
@@ -340,18 +321,24 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
         return null;
     }
 
+    private final ScreenModeStatus getScreenModeStatus(boolean throwException) {
+        final String key = this.getFQName();
+        final ScreenModeStatus res = ScreenModeStatus.getScreenModeStatus(key);
+        if(null == res & throwException) {
+            throw new InternalError("ScreenModeStatus.getScreenModeStatus("+key+") == null");
+        }
+        return res;
+    }
+    
     public ScreenMode getOriginalScreenMode() {
-        ScreenModeStatus sms = ScreenModeStatus.getScreenModeStatus(this.getFQName());
+        final ScreenModeStatus sms = getScreenModeStatus(false);
         return ( null != sms ) ? sms.getOriginalScreenMode() : null ;
     }
 
     public ScreenMode getCurrentScreenMode() {
         ScreenMode smU = null;
-        ScreenModeStatus sms = ScreenModeStatus.getScreenModeStatus(this.getFQName());
-        if(null == sms) {
-            throw new InternalError("ScreenModeStatus.getScreenModeStatus("+this.getFQName()+") == null");            
-        }
-        ScreenMode sm0 = getCurrentScreenModeIntern();
+        final ScreenModeStatus sms = getScreenModeStatus(true);
+        final ScreenMode sm0 = getCurrentScreenModeIntern();
         if(null == sm0) {
             throw new InternalError("getCurrentScreenModeImpl() == null");
         }
@@ -397,12 +384,23 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
                 System.err.println("Screen.setCurrentScreenMode ("+(System.nanoTime()-tStart)/1e6+"ms): fireScreenModeChangeNotify() "+smU);
             }
 
-            success = setCurrentScreenModeImpl(smU);                                
-            if(DEBUG) {
-                System.err.println("Screen.setCurrentScreenMode ("+(System.nanoTime()-tStart)/1e6+"ms): setCurrentScreenModeImpl() "+smU+", success: "+success);
+            success = setCurrentScreenModeImpl(smU);
+            if(success) {
+                if(DEBUG) {
+                    System.err.println("Screen.setCurrentScreenMode ("+(System.nanoTime()-tStart)/1e6+"ms): setCurrentScreenModeImpl() "+smU+", success(1): "+success);
+                }
+            } else {
+                // 2nd attempt validate!
+                final ScreenMode queriedCurrent = getCurrentScreenMode(); // may fireScreenModeChanged(..) if successful and differs!
+                final ScreenMode smsCurrent = sms.getCurrentScreenMode();
+                success = smsCurrent.hashCode() == smU.hashCode() && queriedCurrent.hashCode() == smU.hashCode() ;
+                if(DEBUG) {
+                    System.err.println("Screen.setCurrentScreenMode.2: queried "+queriedCurrent);
+                    System.err.println("Screen.setCurrentScreenMode.2:     SMS "+smsCurrent);
+                    System.err.println("Screen.setCurrentScreenMode ("+(System.nanoTime()-tStart)/1e6+"ms): setCurrentScreenModeImpl() "+smU+", success(2): "+success);
+                }
             }
-
-            sms.fireScreenModeChanged(smU, success);                            
+            sms.fireScreenModeChanged(smU, success);
             if(DEBUG) {
                 System.err.println("Screen.setCurrentScreenMode ("+(System.nanoTime()-tStart)/1e6+"ms): X.X "+smU+", success: "+success);
             }
@@ -501,7 +499,7 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
             res = getCurrentScreenModeImpl();
         }
         if(null == res) {
-            if( 0==getWidth()*getHeight() ) {
+            if( 0>=getWidth() || 0>=getHeight() ) {
                 updateVirtualScreenOriginAndSize();
             }
             int[] props = new int[ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL];
diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java
index 606101a..4f8eb3d 100644
--- a/src/newt/classes/jogamp/newt/WindowImpl.java
+++ b/src/newt/classes/jogamp/newt/WindowImpl.java
@@ -37,6 +37,7 @@ package jogamp.newt;
 import java.util.ArrayList;
 import java.lang.reflect.Method;
 
+import com.jogamp.common.util.IntBitfield;
 import com.jogamp.common.util.ReflectionUtil;
 import com.jogamp.newt.NewtFactory;
 import com.jogamp.newt.Display;
@@ -85,7 +86,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
     private volatile long windowHandle = 0; // lifecycle critical
     private volatile boolean visible = false; // lifecycle critical
     private RecursiveLock windowLock = LockFactory.createRecursiveLock();  // Window instance wide lock
-    private RecursiveLock surfaceLock = LockFactory.createRecursiveLock(); // Surface only lock
+    private int surfaceLockCount = 0; // surface lock recursion count
     
     private ScreenImpl screen; // never null after create - may change reference though (reparent)
     private boolean screenReferenceAdded = false;
@@ -152,26 +153,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
     private static Class<?> getWindowClass(String type)
         throws ClassNotFoundException
     {
-        Class<?> windowClass = NewtFactory.getCustomClass(type, "Window");
+        final Class<?> windowClass = NewtFactory.getCustomClass(type, "WindowDriver");
         if(null==windowClass) {
-            if (NativeWindowFactory.TYPE_ANDROID == type) {
-                windowClass = Class.forName("jogamp.newt.driver.android.AndroidWindow");
-            } else if (NativeWindowFactory.TYPE_EGL == type) {
-                windowClass = Class.forName("jogamp.newt.driver.kd.KDWindow");
-            } else if (NativeWindowFactory.TYPE_WINDOWS == type) {
-                windowClass = Class.forName("jogamp.newt.driver.windows.WindowsWindow");
-            } else if (NativeWindowFactory.TYPE_MACOSX == type) {
-                windowClass = Class.forName("jogamp.newt.driver.macosx.MacWindow");
-            } else if (NativeWindowFactory.TYPE_X11 == type) {
-                windowClass = Class.forName("jogamp.newt.driver.x11.X11Window");
-            } else if (NativeWindowFactory.TYPE_AWT == type) {
-                windowClass = Class.forName("jogamp.newt.driver.awt.AWTWindow");
-            } else {
-                throw new NativeWindowException("Unknown window type \"" + type + "\"");
-            }
-        }
-        if(null==windowClass) {
-            throw new ClassNotFoundException("Failed to find NEWT Window Class <"+type+".Window>");            
+            throw new ClassNotFoundException("Failed to find NEWT Window Class <"+type+".WindowDriver>");            
         }
         return windowClass;
     }
@@ -570,10 +554,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
     @Override
     public final int lockSurface() throws NativeWindowException, RuntimeException {
         final RecursiveLock _wlock = windowLock;
-        final RecursiveLock _slock = surfaceLock;
         _wlock.lock();
-        _slock.lock();
-        int res = _slock.getHoldCount() == 1 ? LOCK_SURFACE_NOT_READY : LOCK_SUCCESS; // new lock ?
+        surfaceLockCount++;
+        int res = ( 1 == surfaceLockCount ) ? LOCK_SURFACE_NOT_READY : LOCK_SUCCESS; // new lock ?
 
         if ( LOCK_SURFACE_NOT_READY == res ) {
             try {
@@ -590,7 +573,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
                 }
             } finally {
                 if (LOCK_SURFACE_NOT_READY >= res) {
-                    _slock.unlock();
                     _wlock.unlock();
                 }
             }
@@ -600,12 +582,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
 
     @Override
     public final void unlockSurface() {
-        final RecursiveLock _slock = surfaceLock;
         final RecursiveLock _wlock = windowLock;
-        _slock.validateLocked();
         _wlock.validateLocked();
 
-        if (_slock.getHoldCount() == 1) {
+        if ( 1 == surfaceLockCount ) {
             final AbstractGraphicsDevice adevice = getGraphicsConfiguration().getScreen().getDevice();
             try {
                 unlockSurfaceImpl();
@@ -613,42 +593,48 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
                 adevice.unlock();
             }
         }
-        _slock.unlock();
+        surfaceLockCount--;
         _wlock.unlock();
     }
 
     @Override
     public final boolean isSurfaceLockedByOtherThread() {
-        return surfaceLock.isLockedByOtherThread();
+        return windowLock.isLockedByOtherThread();
     }
 
     @Override
     public final Thread getSurfaceLockOwner() {
-        return surfaceLock.getOwner();
+        return windowLock.getOwner();
     }
 
     public final RecursiveLock getLock() {
         return windowLock;
     }
     
+    @Override
     public long getSurfaceHandle() {
         return windowHandle; // default: return window handle
     }
 
+    @Override
     public boolean surfaceSwap() {
         return false;
     }
 
+    @Override
     public final AbstractGraphicsConfiguration getGraphicsConfiguration() {
         return config.getNativeGraphicsConfiguration();
     }
 
-    public final long getDisplayHandle() {
-        return getScreen().getDisplay().getHandle();
+    @Override
+    public long getDisplayHandle() {
+        // Actually: return getGraphicsConfiguration().getScreen().getDevice().getHandle();
+        return screen.getDisplay().getHandle(); // shortcut
     }
 
+    @Override
     public final int  getScreenIndex() {
-        return getScreen().getIndex();
+        return screen.getIndex();
     }
 
     //----------------------------------------------------------------------
@@ -784,11 +770,15 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
         }
     }
 
-    public void setVisible(boolean visible) {
+    protected 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));
         }
-        runOnEDTIfAvail(true, new VisibleAction(visible));
+        runOnEDTIfAvail(wait, new VisibleAction(visible));        
+    }
+    
+    public void setVisible(boolean visible) {
+        setVisible(true, visible);
     }
     
     private class SetSizeAction implements Runnable {
@@ -800,27 +790,18 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
         }
 
         public final void run() {
-            boolean recreate = false;
             final RecursiveLock _lock = windowLock;
             _lock.lock();
             try {
                 if ( !isFullscreen() && ( getWidth() != width || getHeight() != height ) ) {
-                    recreate = isNativeValid() && !getGraphicsConfiguration().getChosenCapabilities().isOnscreen();
                     if(DEBUG_IMPLEMENTATION) {
-                        System.err.println("Window setSize: START "+getWidth()+"x"+getHeight()+" -> "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible "+visible+", recreate "+recreate);
-                    }
-                    if(recreate) {
-                        // will trigger visibleAction:=2 -> create if wasVisible
-                        final boolean wasVisible = WindowImpl.this.visible;
-                        screen.addReference(); // retain screen
-                        destroyAction.run();
-                        WindowImpl.this.visible = wasVisible;
+                        System.err.println("Window setSize: START "+getWidth()+"x"+getHeight()+" -> "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible "+visible);
                     }
                     int visibleAction; // 0 nop, 1 invisible, 2 visible (create)
-                    if ( isNativeValid() && 0>=width*height && visible ) {
+                    if ( visible && isNativeValid() && ( 0 >= width || 0 >= height ) ) {
                         visibleAction=1; // invisible
                         defineSize(0, 0);
-                    } else if ( !isNativeValid() && 0<width*height && visible ) {
+                    } else if ( visible && !isNativeValid() && 0 < width && 0 < height ) {
                         visibleAction = 2; // visible (create)
                         defineSize(width, height);
                     } else if ( isNativeValid() ) {
@@ -840,9 +821,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
                     }
                 }
             } finally {
-                if(recreate) {
-                    screen.removeReference(); // bring back ref-count
-                }
                 _lock.unlock();
             }
         }
@@ -957,11 +935,15 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
      */
     protected static boolean isOffscreenInstance(NativeWindow cWin, NativeWindow pWin) {
         boolean ofs = false;
-        if( null != cWin.getGraphicsConfiguration() ) {
-            ofs = !cWin.getGraphicsConfiguration().getChosenCapabilities().isOnscreen();
+        final AbstractGraphicsConfiguration cWinCfg = cWin.getGraphicsConfiguration(); 
+        if( null != cWinCfg ) {
+            ofs = !cWinCfg.getChosenCapabilities().isOnscreen();
         }
-        if( !ofs && null != pWin && null != pWin.getGraphicsConfiguration() ) {
-            ofs |= !pWin.getGraphicsConfiguration().getChosenCapabilities().isOnscreen();
+        if( !ofs && null != pWin ) {
+            final AbstractGraphicsConfiguration pWinCfg = pWin.getGraphicsConfiguration();
+            if( null != pWinCfg ) {
+                ofs = !pWinCfg.getChosenCapabilities().isOnscreen();
+            }
         }
         return ofs;
     }
@@ -1069,7 +1051,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
                                     setScreen( (ScreenImpl) newScreen );
                                 }
                             }
-                            if( 0<width*height ) {
+                            if( 0 < width && 0 < height ) {
                                 operation = ReparentOperation.ACTION_NATIVE_CREATION;
                             } else {
                                 operation = ReparentOperation.ACTION_NATIVE_CREATION_PENDING;
@@ -1108,7 +1090,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
                     } else if( !isNativeValid() || forceDestroyCreate ) {
                         // Destroy this window and mark it for [pending] creation.
                         destroy();
-                        if( 0<width*height ) {
+                        if( 0 < width && 0 < height ) {
                             operation = ReparentOperation.ACTION_NATIVE_CREATION;
                         } else {
                             operation = ReparentOperation.ACTION_NATIVE_CREATION_PENDING;
@@ -1575,8 +1557,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
         for (int i = 0; i < keyListeners.size(); i++ ) {
           sb.append(keyListeners.get(i)+", ");
         }
-        sb.append("], surfaceLock "+surfaceLock);
-        sb.append(", windowLock "+windowLock+"]");
+        sb.append("], windowLock "+windowLock+"]");
         return sb.toString();
     }
 
@@ -1731,6 +1712,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
                 // set current state
                 WindowImpl.this.fullscreen = fullscreen;
 
+                final ScreenMode sm = screen.getCurrentScreenMode();
                 int x,y,w,h;
                 
                 if(fullscreen) {
@@ -1740,8 +1722,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
                     nfs_height = getHeight();
                     x = screen.getX(); 
                     y = screen.getY();
-                    w = screen.getWidth();
-                    h = screen.getHeight();
+                    w = sm.getRotatedWidth();
+                    h = sm.getRotatedHeight();
                 } else {
                     x = nfs_x;
                     y = nfs_y;
@@ -1763,7 +1745,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
                     }
                 }
                 if(DEBUG_IMPLEMENTATION) {
-                    System.err.println("Window fs: "+fullscreen+" "+x+"/"+y+" "+w+"x"+h+", "+isUndecorated()+", "+screen);
+                    System.err.println("Window fs: "+fullscreen+" "+x+"/"+y+" "+w+"x"+h+", "+isUndecorated()+
+                                       ", virtl-size: "+screen.getWidth()+"x"+screen.getHeight()+", SM "+sm.getRotatedWidth()+"x"+sm.getRotatedHeight());
                 }
 
                 DisplayImpl display = (DisplayImpl) screen.getDisplay();
@@ -2187,6 +2170,33 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
     //
     // KeyListener/Event Support
     //
+    protected IntBitfield keyPressedState = new IntBitfield(KeyEvent.VK_CONTEXT_MENU+1);
+    protected IntBitfield keyRepeatState = new IntBitfield(KeyEvent.VK_CONTEXT_MENU+1);
+    
+    /**
+     * @param keyCode
+     * @return 1 if pressed, 0 if not pressed, -1 if not handled. 
+     */
+    protected final int isKeyPressed(int keyCode) { 
+        if( 0 <= keyCode && keyCode < keyPressedState.capacity() ) {
+            return keyPressedState.get(keyCode) ? 1 : 0;
+        }
+        return -1;
+    }
+    /**
+     * @param keyCode
+     * @return 1 if pressed, 0 if not pressed, -1 if not handled. 
+     */
+    protected final int isKeyInAutoRepeat(int keyCode) { 
+        if( 0 <= keyCode && keyCode < keyRepeatState.capacity() ) {
+            return keyRepeatState.get(keyCode) ? 1 : 0;
+        }
+        return -1;
+    }
+    protected final boolean isKeyCodeTracked(int keyCode) { 
+        return 0 <= keyCode && keyCode < keyRepeatState.capacity();
+    }
+        
     public void sendKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) {
         consumeKeyEvent(new KeyEvent(eventType, this, System.currentTimeMillis(), modifiers, keyCode, keyChar) );
     }
diff --git a/src/newt/classes/jogamp/newt/driver/android/AndroidDisplay.java b/src/newt/classes/jogamp/newt/driver/android/DisplayDriver.java
similarity index 94%
copy from src/newt/classes/jogamp/newt/driver/android/AndroidDisplay.java
copy to src/newt/classes/jogamp/newt/driver/android/DisplayDriver.java
index 0a43c9b..a367462 100644
--- a/src/newt/classes/jogamp/newt/driver/android/AndroidDisplay.java
+++ b/src/newt/classes/jogamp/newt/driver/android/DisplayDriver.java
@@ -33,11 +33,11 @@ import jogamp.opengl.egl.*;
 
 import javax.media.nativewindow.*;
 
-public class AndroidDisplay extends jogamp.newt.DisplayImpl {
+public class DisplayDriver extends jogamp.newt.DisplayImpl {
     static {
         NEWTJNILibLoader.loadNEWT();
 
-        if (!AndroidWindow.initIDs0()) {
+        if (!WindowDriver.initIDs0()) {
             throw new NativeWindowException("Failed to initialize Android NEWT Windowing library");
         }
     }
@@ -47,7 +47,7 @@ public class AndroidDisplay extends jogamp.newt.DisplayImpl {
     }
 
 
-    public AndroidDisplay() {
+    public DisplayDriver() {
     }
 
     protected void createNativeImpl() {
diff --git a/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java b/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java
index 4537fa9..28c4da7 100644
--- a/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java
+++ b/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java
@@ -36,7 +36,7 @@ import javax.media.opengl.FPSCounter;
 import com.jogamp.newt.Window;
 import com.jogamp.opengl.util.Animator;
 
-import jogamp.newt.driver.android.AndroidWindow;
+import jogamp.newt.driver.android.WindowDriver;
 
 import android.app.Activity;
 import android.content.Context;
@@ -83,10 +83,10 @@ public class NewtBaseActivity extends Activity {
     */
    public void setContentView(android.view.Window androidWindow, Window newtWindow) {
        newtWindow = newtWindow.getDelegatedWindow();
-       if(newtWindow instanceof AndroidWindow) {
+       if(newtWindow instanceof WindowDriver) {
            adaptTheme4Transparency(newtWindow.getRequestedCapabilities());
            layoutForNEWTWindow(androidWindow, newtWindow);
-           AndroidWindow newtAWindow = (AndroidWindow)newtWindow;
+           WindowDriver newtAWindow = (WindowDriver)newtWindow;
            androidWindow.setContentView(newtAWindow.getAndroidView());
            registerNEWTWindow(newtAWindow);
        } else {
@@ -107,8 +107,8 @@ public class NewtBaseActivity extends Activity {
     */
    public void addContentView(android.view.Window androidWindow, Window newtWindow, android.view.ViewGroup.LayoutParams params) {
        newtWindow = newtWindow.getDelegatedWindow();
-       if(newtWindow instanceof AndroidWindow) {
-           AndroidWindow newtAWindow = (AndroidWindow)newtWindow;
+       if(newtWindow instanceof WindowDriver) {
+           WindowDriver newtAWindow = (WindowDriver)newtWindow;
            androidWindow.addContentView(newtAWindow.getAndroidView(), params);
            registerNEWTWindow(newtAWindow);
        } else {
@@ -265,16 +265,17 @@ public class NewtBaseActivity extends Activity {
      if(!isDelegatedActivity()) {
          super.onResume();
      }
-     if(null != animator) {
-         animator.resume();
-         animator.resetFPSCounter();
-     }
-     for(int i=newtWindows.size()-1; i>=0; i--) {
+     for(int i=0; i<newtWindows.size(); i++) {
          final Window win = newtWindows.get(i);
+         win.setVisible(true);
          if(win instanceof FPSCounter) {
              ((FPSCounter)win).resetFPSCounter();
          }
      }
+     if(null != animator) {
+         animator.resume();
+         animator.resetFPSCounter();
+     }
    }
 
    @Override
@@ -283,6 +284,10 @@ public class NewtBaseActivity extends Activity {
      if(null != animator) {
          animator.pause();
      }
+     for(int i=0; i<newtWindows.size(); i++) {
+         final Window win = newtWindows.get(i);
+         win.setVisible(false);
+     }
      if(!isDelegatedActivity()) {
          super.onPause();
      }
diff --git a/src/newt/classes/jogamp/newt/driver/android/NewtVersionActivity.java b/src/newt/classes/jogamp/newt/driver/android/NewtVersionActivity.java
index 36b8333..a49f164 100644
--- a/src/newt/classes/jogamp/newt/driver/android/NewtVersionActivity.java
+++ b/src/newt/classes/jogamp/newt/driver/android/NewtVersionActivity.java
@@ -69,7 +69,7 @@ public class NewtVersionActivity extends NewtBaseActivity {
        glWindow.setUndecorated(true);
        glWindow.setSize(32, 32);
        glWindow.setPosition(0, 0);
-       final android.view.View androidGLView = ((AndroidWindow)glWindow.getDelegatedWindow()).getAndroidView();       
+       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);
        
diff --git a/src/newt/classes/jogamp/newt/driver/android/AndroidScreen.java b/src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java
similarity index 97%
rename from src/newt/classes/jogamp/newt/driver/android/AndroidScreen.java
rename to src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java
index e108ed0..795aac5 100644
--- a/src/newt/classes/jogamp/newt/driver/android/AndroidScreen.java
+++ b/src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java
@@ -41,13 +41,13 @@ import android.util.DisplayMetrics;
 import android.view.Surface;
 import android.view.WindowManager;
 
-public class AndroidScreen extends jogamp.newt.ScreenImpl {
+public class ScreenDriver extends jogamp.newt.ScreenImpl {
 
     static {
-        AndroidDisplay.initSingleton();
+        DisplayDriver.initSingleton();
     }
 
-    public AndroidScreen() {
+    public ScreenDriver() {
     }
 
     protected void createNativeImpl() {
diff --git a/src/newt/classes/jogamp/newt/driver/android/AndroidWindow.java b/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java
similarity index 89%
rename from src/newt/classes/jogamp/newt/driver/android/AndroidWindow.java
rename to src/newt/classes/jogamp/newt/driver/android/WindowDriver.java
index 73192a0..f185206 100644
--- a/src/newt/classes/jogamp/newt/driver/android/AndroidWindow.java
+++ b/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java
@@ -39,6 +39,7 @@ import javax.media.nativewindow.util.Insets;
 import javax.media.nativewindow.util.Point;
 import javax.media.opengl.GLCapabilitiesChooser;
 import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLException;
 
 import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
 
@@ -59,9 +60,9 @@ import android.view.inputmethod.InputMethodManager;
 import android.view.SurfaceView;
 import android.view.View;
 
-public class AndroidWindow extends jogamp.newt.WindowImpl implements Callback2 {    
+public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {    
     static {
-        AndroidDisplay.initSingleton();
+        DisplayDriver.initSingleton();
     }
 
     public static CapabilitiesImmutable fixCaps(boolean matchFormatPrecise, int format, CapabilitiesImmutable rCaps) {
@@ -142,11 +143,11 @@ public class AndroidWindow extends jogamp.newt.WindowImpl implements Callback2 {
 
         @Override
         public boolean onTouch(View v, android.view.MotionEvent event) {
-            final com.jogamp.newt.event.MouseEvent[] newtEvents = AndroidNewtEventFactory.createMouseEvents(event, AndroidWindow.this);
+            final com.jogamp.newt.event.MouseEvent[] newtEvents = AndroidNewtEventFactory.createMouseEvents(event, WindowDriver.this);
             if(null != newtEvents) {
                 focusChanged(false, true);
                 for(int i=0; i<newtEvents.length; i++) {
-                    AndroidWindow.this.enqueueEvent(false, newtEvents[i]);
+                    WindowDriver.this.enqueueEvent(false, newtEvents[i]);
                 }
                 try { Thread.sleep((long) (1000.0F/30.0F)); }
                 catch(InterruptedException e) { }
@@ -157,10 +158,10 @@ public class AndroidWindow extends jogamp.newt.WindowImpl implements Callback2 {
 
         @Override
         public boolean onKey(View v, int keyCode, android.view.KeyEvent event) {
-            final com.jogamp.newt.event.KeyEvent[] newtEvents = AndroidNewtEventFactory.createKeyEvents(keyCode, event, AndroidWindow.this);
+            final com.jogamp.newt.event.KeyEvent[] newtEvents = AndroidNewtEventFactory.createKeyEvents(keyCode, event, WindowDriver.this);
             if(null != newtEvents) {
                 for(int i=0; i<newtEvents.length; i++) {
-                    AndroidWindow.this.enqueueEvent(false, newtEvents[i]);
+                    WindowDriver.this.enqueueEvent(false, newtEvents[i]);
                 }
                 return true;
             }
@@ -169,7 +170,7 @@ public class AndroidWindow extends jogamp.newt.WindowImpl implements Callback2 {
         
         @Override
         public void onFocusChange(View v, boolean hasFocus) {
-            AndroidWindow.this.focusChanged(false, hasFocus);
+            WindowDriver.this.focusChanged(false, hasFocus);
         }
         
     }
@@ -178,7 +179,7 @@ public class AndroidWindow extends jogamp.newt.WindowImpl implements Callback2 {
         return new Class<?>[] { Context.class } ;
     }
     
-    public AndroidWindow() {
+    public WindowDriver() {
         reset();
     }
 
@@ -212,7 +213,7 @@ public class AndroidWindow extends jogamp.newt.WindowImpl implements Callback2 {
         androidView.setFocusableInTouchMode(true);
         
         final SurfaceHolder sh = androidView.getHolder();
-        sh.addCallback(AndroidWindow.this); 
+        sh.addCallback(WindowDriver.this); 
         sh.setFormat(getFormat(getRequestedCapabilities()));
         
         // default size -> TBD ! 
@@ -263,15 +264,24 @@ public class AndroidWindow extends jogamp.newt.WindowImpl implements Callback2 {
         setGraphicsConfiguration(eglConfig);
         setWindowHandle(surfaceHandle);
         focusChanged(false, true);
-        Log.d(MD.TAG, "createNativeImpl X");
+        Log.d(MD.TAG, "createNativeImpl X: eglSurfaceHandle 0x"+Long.toHexString(eglSurface));
     }
 
     @Override
     protected void closeNativeImpl() {
+        Log.d(MD.TAG, "closeNativeImpl 0 - surfaceHandle 0x"+Long.toHexString(surfaceHandle)+
+                    ", eglSurfaceHandle 0x"+Long.toHexString(eglSurface)+
+                    ", format [a "+androidFormat+", n "+nativeFormat+"], "+getX()+"/"+getY()+" "+getWidth()+"x"+getHeight()+" - "+Thread.currentThread().getName());
+        if(0 != eglSurface) {
+            final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) getScreen().getDisplay().getGraphicsDevice();
+            if (!EGL.eglDestroySurface(eglDevice.getHandle(), eglSurface)) {
+                throw new GLException("Error destroying window surface (eglDestroySurface)");
+            }
+            eglSurface = 0;        
+        }        
         release0(surfaceHandle);
         surface = null;
         surfaceHandle = 0;
-        eglSurface = 0;        
     }
 
     @Override
@@ -291,25 +301,33 @@ public class AndroidWindow extends jogamp.newt.WindowImpl implements Callback2 {
         }
     }
 
-    protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) {
+    protected 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;
         }
-        if(width>0 || height>0) {
+        if(getWidth() != width || getHeight() != height) {
             if(0!=getWindowHandle()) {
                 Log.d(MD.TAG, "reconfigureWindowImpl.setSize n/a");
-                return false;
+                res = false;
+            } else {
+                defineSize(width, height);
             }
         }
-        if(x>=0 || y>=0) {
-            Log.d(MD.TAG, "reconfigureWindowImpl.setPos n/a");
-            return false;
+        if(getX() != x || getY() != y) {
+            if(0!=getWindowHandle()) {
+                Log.d(MD.TAG, "reconfigureWindowImpl.setPos n/a");
+                res = false;
+            } else {
+                definePosition(x, y);
+            }
         }
         if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) {
             visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags));            
         }
-        return true;
+        return res;
     }
 
     protected Point getLocationOnScreenImpl(int x, int y) {
@@ -410,7 +428,7 @@ public class AndroidWindow extends jogamp.newt.WindowImpl implements Callback2 {
                           getX()+"/"+getY()+" "+nWidth+"x"+nHeight+", visible: "+isVisible());
     
             if(isVisible()) {
-               setVisible(true);
+               setVisible(false, true);
             }
         }
         sizeChanged(false, aWidth, aHeight, false);
diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java b/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java
index a795004..17eb6a2 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2008 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
@@ -34,6 +35,7 @@
 package jogamp.newt.driver.awt;
 
 import java.awt.Canvas;
+import java.awt.Graphics;
 import java.awt.GraphicsDevice;
 import java.awt.GraphicsConfiguration;
 import java.lang.reflect.Method;
@@ -60,14 +62,16 @@ public class AWTCanvas extends Canvas {
   private GraphicsConfiguration chosen;
   private AWTGraphicsConfiguration awtConfig;
 
+  private WindowDriver newtWindowImpl;
   private CapabilitiesChooser chooser=null;
   private CapabilitiesImmutable capabilities;
 
   private boolean displayConfigChanged=false;
 
-  public AWTCanvas(CapabilitiesImmutable capabilities, CapabilitiesChooser chooser) {
+  public AWTCanvas(WindowDriver newtWindowImpl, CapabilitiesImmutable capabilities, CapabilitiesChooser chooser) {
     super();
 
+    this.newtWindowImpl = newtWindowImpl;
     if(null==capabilities) {
         throw new NativeWindowException("Capabilities null");
     }
@@ -79,6 +83,25 @@ public class AWTCanvas extends Canvas {
     return awtConfig;
   }
 
+  /**
+   * Overridden from Canvas to prevent the AWT's clearing of the
+   * canvas from interfering with the OpenGL rendering.
+   */
+  @Override
+  public void update(Graphics g) {
+    paint(g);
+  }
+
+  /** Overridden to cause OpenGL rendering to be performed during
+      repaint cycles. Subclasses which override this method must call
+      super.paint() in their paint() method in order to function
+      properly.
+   */
+  @Override
+  public void paint(Graphics g) {
+    newtWindowImpl.windowRepaint(0, 0, getWidth(), getHeight());
+  }
+  
   public boolean hasDeviceChanged() {
     boolean res = displayConfigChanged;
     displayConfigChanged=false;
@@ -274,10 +297,10 @@ public class AWTCanvas extends Canvas {
   private void disableBackgroundErase() {
     if (!disableBackgroundEraseInitialized) {
       try {
-        AccessController.doPrivileged(new PrivilegedAction() {
+        AccessController.doPrivileged(new PrivilegedAction<Object>() {
             public Object run() {
               try {
-                Class clazz = getToolkit().getClass();
+                Class<?> clazz = getToolkit().getClass();
                 while (clazz != null && disableBackgroundEraseMethod == null) {
                   try {
                     disableBackgroundEraseMethod =
diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java b/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java
index 9426511..8771f5c 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java
@@ -28,72 +28,239 @@
 
 package jogamp.newt.driver.awt;
 
-import javax.media.opengl.Threading;
+import java.awt.EventQueue;
 
 import com.jogamp.newt.util.EDTUtil;
+
+import jogamp.common.awt.AWTEDTExecutor;
 import jogamp.newt.Debug;
 
 public class AWTEDTUtil implements EDTUtil {
     public static final boolean DEBUG = Debug.debug("EDT");
-
-    private static AWTEDTUtil singletonMainThread = new AWTEDTUtil(); // one singleton MainThread
     
-    public static AWTEDTUtil getSingleton() {
-        return singletonMainThread;
-    }
+    private final Object edtLock = new Object(); // locking the EDT start/stop state
+    private final ThreadGroup threadGroup; 
+    private final String name;
+    private final Runnable dispatchMessages;
+    private NewtEventDispatchThread nedt = null;
+    private int start_iter=0;
+    private static long pollPeriod = EDTUtil.defaultEDTPollPeriod;
 
-    AWTEDTUtil() {
-        // package private access ..
+    public AWTEDTUtil(ThreadGroup tg, String name, Runnable dispatchMessages) {
+        this.threadGroup = tg;
+        this.name=Thread.currentThread().getName()+"-"+name+"-EDT-";
+        this.dispatchMessages=dispatchMessages;
+        this.nedt = new NewtEventDispatchThread(threadGroup, name);
+        this.nedt.setDaemon(true); // don't stop JVM from shutdown ..
     }
 
+    @Override
     final public long getPollPeriod() {
-        return 0;
+        return pollPeriod;
     }
 
+    @Override
     final public void setPollPeriod(long ms) {
-        // nop
+        pollPeriod = ms;
     }
     
+    @Override
     final public void reset() {
-        // nop AWT is always running
+        synchronized(edtLock) { 
+            waitUntilStopped();
+            if(DEBUG) {
+                System.err.println(Thread.currentThread()+": EDT reset - edt: "+nedt);
+            }
+            this.nedt = new NewtEventDispatchThread(threadGroup, name);
+            this.nedt.setDaemon(true); // don't stop JVM from shutdown ..
+        }
     }
 
-    final public void start() {
-        // nop AWT is always running
+    private final void startImpl() {
+        if(nedt.isAlive()) {
+            throw new RuntimeException("EDT Thread.isAlive(): true, isRunning: "+nedt.isRunning()+", edt: "+nedt);
+        }
+        start_iter++;
+        nedt.setName(name+start_iter);
+        nedt.shouldStop = false;
+        if(DEBUG) {
+            System.err.println(Thread.currentThread()+": EDT START - edt: "+nedt);
+            // Thread.dumpStack();
+        }
+        nedt.start();
     }
 
+    @Override
     final public boolean isCurrentThreadEDT() {
-        return Threading.isToolkitThread();
+        return EventQueue.isDispatchThread();
     }
 
+    @Override
+    public final boolean isCurrentThreadNEDT() {
+        return nedt == Thread.currentThread();
+    }
+    
+    @Override
+    public final boolean isCurrentThreadEDTorNEDT() {
+        return EventQueue.isDispatchThread() || nedt == Thread.currentThread();        
+    }
+    
+    @Override
     final public boolean isRunning() {
-        return true; // AWT is always running
+        return nedt.isRunning() ; // AWT is always running
     }
 
-    final public void invokeStop(Runnable r) {
-        invoke(true, r); // AWT is always running
+    @Override
+    public final void invokeStop(Runnable task) {
+        invokeImpl(true, task, true);
     }
 
-    final public void invoke(boolean wait, Runnable r) {
-        if(r == null) {
-            return;
-        }
-        
-        Threading.invoke(wait, r, null);
+    @Override
+    public final void invoke(boolean wait, Runnable task) {
+        invokeImpl(wait, task, false);
     }
+    
+    private void invokeImpl(boolean wait, Runnable task, boolean stop) {
+        if(task == null) {
+            throw new RuntimeException("Null Runnable");
+        }
+        synchronized(edtLock) { // lock the EDT status
+            if( nedt.shouldStop ) {
+                // drop task ..
+                if(DEBUG) {
+                    System.err.println("Warning: EDT about (1) to stop, won't enqueue new task: "+nedt);
+                    Thread.dumpStack();
+                }
+                return; 
+            }
+            // System.err.println(Thread.currentThread()+" XXX stop: "+stop+", tasks: "+edt.tasks.size()+", task: "+task);
+            // Thread.dumpStack();
+            if(stop) {
+                nedt.shouldStop = true;
+                if(DEBUG) {
+                    System.err.println(Thread.currentThread()+": EDT signal STOP (on edt: "+isCurrentThreadEDT()+") - "+nedt);
+                    // Thread.dumpStack();
+                }
+            }
+            
+            // start if should not stop && not started yet                    
+            if( !stop && !nedt.isRunning() ) {
+                startImpl();
+            }
+        }
+        AWTEDTExecutor.singleton.invoke(wait, task);
+    }    
 
+    @Override
     final public void waitUntilIdle() {
-        // wait until previous events are processed, at least ..
+        final NewtEventDispatchThread _edt;
+        synchronized(edtLock) {
+            _edt = nedt;
+        }
+        if(!_edt.isRunning() || EventQueue.isDispatchThread()  || _edt == Thread.currentThread()) {
+            return;
+        }
         try {
-            Threading.invoke(true, new Runnable() {
+            AWTEDTExecutor.singleton.invoke(true, new Runnable() {
                 public void run() { }
-            }, null);
+            });
         } catch (Exception e) { }
     }
 
+    @Override
     final public void waitUntilStopped() {
-        // nop: AWT is always running
+        synchronized(edtLock) {
+            if(nedt.isRunning() && nedt != Thread.currentThread() ) {
+                while(nedt.isRunning()) {
+                    try {
+                        edtLock.wait();
+                    } catch (InterruptedException e) {
+                        e.printStackTrace();
+                    }
+                }
+            }
+        }
     }
+    
+    class NewtEventDispatchThread extends Thread {
+        volatile boolean shouldStop = false;
+        volatile boolean isRunning = false;
+        Object sync = new Object();
+
+        public NewtEventDispatchThread(ThreadGroup tg, String name) {
+            super(tg, name);
+        }
+
+        final public boolean isRunning() {
+            return isRunning;
+        }
+
+        @Override
+        final public void start() throws IllegalThreadStateException {
+            isRunning = true;
+            super.start();
+        }
+
+        /** 
+         * Utilizing locking only on tasks and its execution,
+         * not for event dispatching.
+         */
+        @Override
+        final public void run() {
+            if(DEBUG) {
+                System.err.println(getName()+": EDT run() START "+ getName());
+            }
+            RuntimeException error = null;
+            try {
+                do {
+                    // event dispatch
+                    if(!shouldStop) {
+                        // FIXME: Determine whether we require to run the 
+                        // delivery of events (dispatch) on AWT-EDT.
+                        // Since the WindowDriver itself delivers all Window related events,
+                        // this shall not be required.
+                        //   AWTEDTExecutor.singleton.invoke(true, dispatchMessages);
+                        dispatchMessages.run();
+                    }
+                    // wait
+                    synchronized(sync) {
+                        if(!shouldStop) {
+                            try {
+                                sync.wait(pollPeriod);
+                            } catch (InterruptedException e) {
+                                e.printStackTrace();
+                            }
+                        }
+                    }
+                } while(!shouldStop) ;
+            } catch (Throwable t) {
+                // handle errors ..
+                shouldStop = true;
+                if(t instanceof RuntimeException) {
+                    error = (RuntimeException) t;
+                } else {
+                    error = new RuntimeException("Within EDT", t);
+                }
+            } finally {
+                if(DEBUG) {
+                    System.err.println(getName()+": EDT run() END "+ getName()+", "+error); 
+                }
+                synchronized(edtLock) {
+                    isRunning = !shouldStop;
+                    if(!isRunning) {
+                        edtLock.notifyAll();
+                    }
+                }
+                if(DEBUG) {
+                    System.err.println(getName()+": EDT run() EXIT "+ getName()+", exception: "+error);
+                }
+                if(null!=error) {
+                    throw error;
+                }
+            } // finally
+        } // run()
+    } // EventDispatchThread
+    
 }
 
 
diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTDisplay.java b/src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java
similarity index 84%
rename from src/newt/classes/jogamp/newt/driver/awt/AWTDisplay.java
rename to src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java
index 65f8b47..ead567d 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/AWTDisplay.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java
@@ -38,10 +38,11 @@ import com.jogamp.nativewindow.awt.AWTGraphicsDevice;
 import com.jogamp.newt.NewtFactory;
 import com.jogamp.newt.util.EDTUtil;
 
+import jogamp.newt.DefaultEDTUtil;
 import jogamp.newt.DisplayImpl;
 
-public class AWTDisplay extends DisplayImpl {
-    public AWTDisplay() {
+public class DisplayDriver extends DisplayImpl {
+    public DisplayDriver() {
     }
 
     protected void createNativeImpl() {
@@ -52,15 +53,12 @@ public class AWTDisplay extends DisplayImpl {
         aDevice = d;
     }
 
-    protected void closeNativeImpl() { }
-
-    @Override
     protected EDTUtil createEDTUtil() {
         final EDTUtil def;
         if(NewtFactory.useEDT()) {
-            def = AWTEDTUtil.getSingleton();
+            def = new AWTEDTUtil(Thread.currentThread().getThreadGroup(), "AWTDisplay-"+getFQName(), dispatchMessagesRunnable);            
             if(DEBUG) {
-                System.err.println("AWTDisplay.createNative("+getFQName()+") Create EDTUtil: "+def.getClass().getName());
+                System.err.println("Display.createNative("+getFQName()+") Create EDTUtil: "+def.getClass().getName());
             }
         } else {
             def = null;
@@ -68,6 +66,10 @@ public class AWTDisplay extends DisplayImpl {
         return def;
     }
 
+    protected void closeNativeImpl() { 
+        aDevice.close();
+    }
+
     protected void dispatchMessagesNative() { /* nop */ }
 }
 
diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTScreen.java b/src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java
similarity index 97%
rename from src/newt/classes/jogamp/newt/driver/awt/AWTScreen.java
rename to src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java
index a3c0281..6b1283a 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/AWTScreen.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java
@@ -42,8 +42,8 @@ import javax.media.nativewindow.util.Point;
 import com.jogamp.nativewindow.awt.AWTGraphicsDevice;
 import com.jogamp.nativewindow.awt.AWTGraphicsScreen;
 
-public class AWTScreen extends ScreenImpl {
-    public AWTScreen() {
+public class ScreenDriver extends ScreenImpl {
+    public ScreenDriver() {
     }
 
     protected void createNativeImpl() {
diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTWindow.java b/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java
similarity index 71%
rename from src/newt/classes/jogamp/newt/driver/awt/AWTWindow.java
rename to src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java
index 2b2fed5..bee43a9 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/AWTWindow.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java
@@ -36,6 +36,7 @@ package jogamp.newt.driver.awt;
 
 import java.awt.BorderLayout;
 import java.awt.Container;
+import java.awt.Dimension;
 import java.awt.Frame;
 import java.awt.Insets;
 
@@ -47,6 +48,8 @@ import jogamp.newt.WindowImpl;
 import com.jogamp.nativewindow.awt.AWTGraphicsConfiguration;
 import com.jogamp.nativewindow.awt.AWTGraphicsDevice;
 import com.jogamp.nativewindow.awt.AWTGraphicsScreen;
+import com.jogamp.newt.event.WindowEvent;
+import com.jogamp.newt.event.WindowUpdateEvent;
 import com.jogamp.newt.event.awt.AWTKeyAdapter;
 import com.jogamp.newt.event.awt.AWTMouseAdapter;
 import com.jogamp.newt.event.awt.AWTWindowAdapter;
@@ -55,9 +58,9 @@ import com.jogamp.newt.event.awt.AWTWindowAdapter;
     AWT. This is provided for convenience of porting to platforms
     supporting Java SE. */
 
-public class AWTWindow extends WindowImpl {
+public class WindowDriver extends WindowImpl {
 
-    public AWTWindow() {
+    public WindowDriver() {
         this(null);
     }
 
@@ -65,7 +68,7 @@ public class AWTWindow extends WindowImpl {
         return new Class<?>[] { Container.class } ;
     }
 
-    public AWTWindow(Container container) {
+    public WindowDriver(Container container) {
         super();
         this.container = container;
         if(container instanceof Frame) {
@@ -107,18 +110,18 @@ public class AWTWindow extends WindowImpl {
             frame.setTitle(getTitle());
         }
         container.setLayout(new BorderLayout());
-        canvas = new AWTCanvas(capsRequested, AWTWindow.this.capabilitiesChooser);
-
-        addWindowListener(new LocalWindowListener());
-
-        new AWTMouseAdapter(this).addTo(canvas); // fwd all AWT Mouse events to here
-        new AWTKeyAdapter(this).addTo(canvas); // fwd all AWT Key events to here
+        
+        canvas = new AWTCanvas(this, capsRequested, WindowDriver.this.capabilitiesChooser);
 
         // canvas.addComponentListener(listener);
         container.add(canvas, BorderLayout.CENTER);
-        container.setSize(getWidth(), getHeight());
-        container.setLocation(getX(), getY());
-        new AWTWindowAdapter(this).addTo(container); // fwd all AWT Window events to here
+        
+        // via EDT ..
+        new AWTMouseAdapter(this).addTo(canvas); // fwd all AWT Mouse events to here
+        new AWTKeyAdapter(this).addTo(canvas); // fwd all AWT Key events to here
+        
+        // direct w/o EDT
+        new AWTWindowAdapter(new LocalWindowListener(), this).addTo(canvas); // fwd all AWT Window events to here
 
         reconfigureWindowImpl(getX(), getY(), getWidth(), getHeight(), getReconfigureFlags(FLAG_CHANGE_VISIBILITY | FLAG_CHANGE_DECORATION, true));
         // throws exception if failed ..
@@ -152,10 +155,10 @@ public class AWTWindow extends WindowImpl {
             setGraphicsConfiguration(cfg);
             
             // propagate new info ..
-            ((AWTScreen)getScreen()).setAWTGraphicsScreen((AWTGraphicsScreen)cfg.getScreen());
-            ((AWTDisplay)getScreen().getDisplay()).setAWTGraphicsDevice((AWTGraphicsDevice)cfg.getScreen().getDevice());
+            ((ScreenDriver)getScreen()).setAWTGraphicsScreen((AWTGraphicsScreen)cfg.getScreen());
+            ((DisplayDriver)getScreen().getDisplay()).setAWTGraphicsDevice((AWTGraphicsDevice)cfg.getScreen().getDevice());
     
-            ((AWTScreen)getScreen()).updateVirtualScreenOriginAndSize();
+            ((ScreenDriver)getScreen()).updateVirtualScreenOriginAndSize();
         }
         return res;
     }
@@ -174,20 +177,32 @@ public class AWTWindow extends WindowImpl {
                 frame.setUndecorated(isUndecorated());
             } else {
                 if(DEBUG_IMPLEMENTATION) {
-                    System.err.println("AWTWindow can't undecorate already created frame");
+                    System.err.println(getThreadName()+": AWTWindow can't undecorate already created frame");
                 }
             }
         }
         
+        final Dimension szClient = new Dimension(width, height);
+        canvas.setMinimumSize(szClient);
+        canvas.setPreferredSize(szClient);
+        canvas.setSize(szClient);
+        if(DEBUG_IMPLEMENTATION) {
+            final Insets insets = container.getInsets();
+            final Dimension szContainer = new Dimension(width + insets.left + insets.right,
+                                                        height + insets.top + insets.bottom);
+            System.err.println(getThreadName()+": AWTWindow new size: szClient "+szClient+", szCont "+szContainer+", insets "+insets);
+        }
+        
         if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) {
+            if(null != frame) {
+                frame.pack();
+            }
+            container.validate();            
             container.setVisible(0 != ( FLAG_IS_VISIBLE & flags));
         }
         
         container.setLocation(x, y);
-        Insets insets = container.getInsets();
-        container.setSize(width + insets.left + insets.right,
-                          height + insets.top + insets.bottom);
-
+        
         if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) {
             if( 0 != ( FLAG_IS_VISIBLE & flags ) ) {
                 if( !hasDeviceChanged() ) {
@@ -200,6 +215,12 @@ public class AWTWindow extends WindowImpl {
                 }
             }
             visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags));
+        } else {
+            container.invalidate();
+            if(null != frame) {
+                frame.pack();
+            }
+            container.validate();            
         }
         
         return true;
@@ -216,18 +237,41 @@ public class AWTWindow extends WindowImpl {
         return canvas;
     }
 
-    class LocalWindowListener extends com.jogamp.newt.event.WindowAdapter { 
+    class LocalWindowListener implements com.jogamp.newt.event.WindowListener { 
         @Override
         public void windowMoved(com.jogamp.newt.event.WindowEvent e) {
             if(null!=container) {
-                definePosition(container.getX(), container.getY());
+                WindowDriver.this.positionChanged(false, container.getX(), container.getY());
             }
         }
         @Override
         public void windowResized(com.jogamp.newt.event.WindowEvent e) {
             if(null!=canvas) {
-                defineSize(canvas.getWidth(), canvas.getHeight());
+                WindowDriver.this.sizeChanged(false, canvas.getWidth(), canvas.getHeight(), false);
+            }
+        }
+        @Override
+        public void windowDestroyNotify(WindowEvent e) {
+            WindowDriver.this.windowDestroyNotify(false);
+        }
+        @Override
+        public void windowDestroyed(WindowEvent e) {
+            if(isNativeValid()) {
+                WindowDriver.this.windowDestroyNotify(true);
             }
+            
+        }
+        @Override
+        public void windowGainedFocus(WindowEvent e) {
+            WindowDriver.this.focusChanged(false, true);            
+        }
+        @Override
+        public void windowLostFocus(WindowEvent e) {
+            WindowDriver.this.focusChanged(false, false);            
+        }
+        @Override
+        public void windowRepaint(WindowUpdateEvent e) {
+            WindowDriver.this.windowRepaint(false, 0, 0, getWidth(), getHeight());            
         }
     }
 }
diff --git a/src/newt/classes/jogamp/newt/driver/broadcom/egl/Display.java b/src/newt/classes/jogamp/newt/driver/bcm/egl/DisplayDriver.java
similarity index 90%
rename from src/newt/classes/jogamp/newt/driver/broadcom/egl/Display.java
rename to src/newt/classes/jogamp/newt/driver/bcm/egl/DisplayDriver.java
index e3f50b7..cc55c33 100644
--- a/src/newt/classes/jogamp/newt/driver/broadcom/egl/Display.java
+++ b/src/newt/classes/jogamp/newt/driver/bcm/egl/DisplayDriver.java
@@ -32,22 +32,23 @@
  * 
  */
 
-package jogamp.newt.driver.broadcom.egl;
+package jogamp.newt.driver.bcm.egl;
 
 import javax.media.nativewindow.AbstractGraphicsDevice;
 import javax.media.nativewindow.NativeWindowException;
 
 import jogamp.newt.NEWTJNILibLoader;
 import jogamp.opengl.egl.EGL;
+import jogamp.opengl.egl.EGLDisplayUtil;
 
 import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
 
-public class Display extends jogamp.newt.DisplayImpl {
+public class DisplayDriver extends jogamp.newt.DisplayImpl {
 
     static {
         NEWTJNILibLoader.loadNEWT();
 
-        if (!Window.initIDs()) {
+        if (!WindowDriver.initIDs()) {
             throw new NativeWindowException("Failed to initialize BCEGL Window jmethodIDs");
         }
     }
@@ -57,11 +58,11 @@ public class Display extends jogamp.newt.DisplayImpl {
     }
 
 
-    public Display() {
+    public DisplayDriver() {
     }
 
     protected void createNativeImpl() {
-        final long handle = CreateDisplay(Screen.fixedWidth, Screen.fixedHeight);
+        final long handle = CreateDisplay(ScreenDriver.fixedWidth, ScreenDriver.fixedHeight);
         if (handle == EGL.EGL_NO_DISPLAY) {
             throw new NativeWindowException("BC EGL CreateDisplay failed");
         }
@@ -72,6 +73,7 @@ public class Display extends jogamp.newt.DisplayImpl {
         if (aDevice.getHandle() != EGL.EGL_NO_DISPLAY) {
             DestroyDisplay(aDevice.getHandle());
         }
+        aDevice.close();
     }
 
     protected void dispatchMessagesNative() {
diff --git a/src/newt/classes/jogamp/newt/driver/broadcom/egl/Screen.java b/src/newt/classes/jogamp/newt/driver/bcm/egl/ScreenDriver.java
similarity index 94%
rename from src/newt/classes/jogamp/newt/driver/broadcom/egl/Screen.java
rename to src/newt/classes/jogamp/newt/driver/bcm/egl/ScreenDriver.java
index 0544bc0..deb2a53 100644
--- a/src/newt/classes/jogamp/newt/driver/broadcom/egl/Screen.java
+++ b/src/newt/classes/jogamp/newt/driver/bcm/egl/ScreenDriver.java
@@ -32,20 +32,20 @@
  * 
  */
 
-package jogamp.newt.driver.broadcom.egl;
+package jogamp.newt.driver.bcm.egl;
 
 import javax.media.nativewindow.DefaultGraphicsScreen;
 import javax.media.nativewindow.util.Dimension;
 import javax.media.nativewindow.util.Point;
 
-public class Screen extends jogamp.newt.ScreenImpl {
+public class ScreenDriver extends jogamp.newt.ScreenImpl {
 
     static {
-        Display.initSingleton();
+        DisplayDriver.initSingleton();
     }
 
 
-    public Screen() {
+    public ScreenDriver() {
     }
 
     protected void createNativeImpl() {
diff --git a/src/newt/classes/jogamp/newt/driver/broadcom/egl/Window.java b/src/newt/classes/jogamp/newt/driver/bcm/egl/WindowDriver.java
similarity index 97%
rename from src/newt/classes/jogamp/newt/driver/broadcom/egl/Window.java
rename to src/newt/classes/jogamp/newt/driver/bcm/egl/WindowDriver.java
index 223ad64..49d3d98 100644
--- a/src/newt/classes/jogamp/newt/driver/broadcom/egl/Window.java
+++ b/src/newt/classes/jogamp/newt/driver/bcm/egl/WindowDriver.java
@@ -32,7 +32,7 @@
  * 
  */
 
-package jogamp.newt.driver.broadcom.egl;
+package jogamp.newt.driver.bcm.egl;
 
 import javax.media.nativewindow.AbstractGraphicsConfiguration;
 import javax.media.nativewindow.GraphicsConfigurationFactory;
@@ -44,12 +44,12 @@ import javax.media.opengl.GLCapabilitiesImmutable;
 
 import jogamp.opengl.egl.EGLGraphicsConfiguration;
 
-public class Window extends jogamp.newt.WindowImpl {
+public class WindowDriver extends jogamp.newt.WindowImpl {
     static {
-        Display.initSingleton();
+        DisplayDriver.initSingleton();
     }
 
-    public Window() {
+    public WindowDriver() {
     }
 
     protected void createNativeImpl() {
diff --git a/src/newt/classes/jogamp/newt/driver/android/AndroidDisplay.java b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/DisplayDriver.java
similarity index 68%
copy from src/newt/classes/jogamp/newt/driver/android/AndroidDisplay.java
copy to src/newt/classes/jogamp/newt/driver/bcm/vc/iv/DisplayDriver.java
index 0a43c9b..08c5c57 100644
--- a/src/newt/classes/jogamp/newt/driver/android/AndroidDisplay.java
+++ b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/DisplayDriver.java
@@ -1,5 +1,5 @@
 /**
- * Copyright 2011 JogAmp Community. All rights reserved.
+ * 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:
@@ -26,19 +26,28 @@
  * or implied, of JogAmp Community.
  */
 
-package jogamp.newt.driver.android;
+package jogamp.newt.driver.bcm.vc.iv;
 
-import jogamp.newt.*;
-import jogamp.opengl.egl.*;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.NativeWindowException;
 
-import javax.media.nativewindow.*;
+import jogamp.newt.DisplayImpl;
+import jogamp.newt.NEWTJNILibLoader;
+import jogamp.opengl.egl.EGL;
+import jogamp.opengl.egl.EGLDisplayUtil;
 
-public class AndroidDisplay extends jogamp.newt.DisplayImpl {
+public class DisplayDriver extends DisplayImpl {
     static {
         NEWTJNILibLoader.loadNEWT();
 
-        if (!AndroidWindow.initIDs0()) {
-            throw new NativeWindowException("Failed to initialize Android NEWT Windowing library");
+        if (!DisplayDriver.initIDs()) {
+            throw new NativeWindowException("Failed to initialize bcm.vc.iv Display jmethodIDs");
+        }
+        if (!ScreenDriver.initIDs()) {
+            throw new NativeWindowException("Failed to initialize bcm.vc.iv Screen jmethodIDs");
+        }
+        if (!WindowDriver.initIDs()) {
+            throw new NativeWindowException("Failed to initialize bcm.vc.iv Window jmethodIDs");
         }
     }
 
@@ -47,11 +56,11 @@ public class AndroidDisplay extends jogamp.newt.DisplayImpl {
     }
 
 
-    public AndroidDisplay() {
+    public DisplayDriver() {
     }
 
     protected void createNativeImpl() {
-        // EGL Device
+        // FIXME: map name to EGL_*_DISPLAY
         aDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
     }
 
@@ -60,7 +69,10 @@ public class AndroidDisplay extends jogamp.newt.DisplayImpl {
     }
 
     protected void dispatchMessagesNative() {
-        // n/a .. DispatchMessages();
-    }    
+        DispatchMessages();
+    }
+
+    protected static native boolean initIDs();    
+    private native void DispatchMessages();
 }
 
diff --git a/src/newt/classes/jogamp/newt/driver/android/AndroidDisplay.java b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/ScreenDriver.java
similarity index 57%
rename from src/newt/classes/jogamp/newt/driver/android/AndroidDisplay.java
rename to src/newt/classes/jogamp/newt/driver/bcm/vc/iv/ScreenDriver.java
index 0a43c9b..787d1a1 100644
--- a/src/newt/classes/jogamp/newt/driver/android/AndroidDisplay.java
+++ b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/ScreenDriver.java
@@ -1,5 +1,5 @@
 /**
- * Copyright 2011 JogAmp Community. All rights reserved.
+ * 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:
@@ -26,41 +26,48 @@
  * or implied, of JogAmp Community.
  */
 
-package jogamp.newt.driver.android;
+package jogamp.newt.driver.bcm.vc.iv;
 
-import jogamp.newt.*;
-import jogamp.opengl.egl.*;
+import javax.media.nativewindow.DefaultGraphicsScreen;
+import javax.media.nativewindow.util.Dimension;
+import javax.media.nativewindow.util.Point;
 
-import javax.media.nativewindow.*;
+import jogamp.newt.ScreenImpl;
 
-public class AndroidDisplay extends jogamp.newt.DisplayImpl {
+public class ScreenDriver extends ScreenImpl {
     static {
-        NEWTJNILibLoader.loadNEWT();
-
-        if (!AndroidWindow.initIDs0()) {
-            throw new NativeWindowException("Failed to initialize Android NEWT Windowing library");
-        }
-    }
-
-    public static void initSingleton() {
-        // just exist to ensure static init has been run
+        DisplayDriver.initSingleton();
     }
 
-
-    public AndroidDisplay() {
+    public ScreenDriver() {
     }
 
     protected void createNativeImpl() {
-        // EGL Device
-        aDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
+        aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), screen_idx);
+        initNative();
     }
 
-    protected void closeNativeImpl() {
-        aDevice.close();
+    protected void closeNativeImpl() { }
+
+    protected int validateScreenIndex(int idx) {
+        return 0; // only one screen available 
+    }       
+    
+    protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) {
+        virtualOrigin.setX(0);
+        virtualOrigin.setY(0);
+        virtualSize.setWidth(cachedWidth);
+        virtualSize.setHeight(cachedHeight);
+    }
+    
+    protected void setScreenSize(int width, int height) {
+        cachedWidth = width;
+        cachedHeight = height;
     }
+    
+    private static int cachedWidth = 0;
+    private static int cachedHeight = 0;    
 
-    protected void dispatchMessagesNative() {
-        // n/a .. DispatchMessages();
-    }    
+    protected static native boolean initIDs();
+    protected native void initNative();
 }
-
diff --git a/src/newt/classes/jogamp/newt/driver/kd/KDWindow.java b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/WindowDriver.java
similarity index 52%
copy from src/newt/classes/jogamp/newt/driver/kd/KDWindow.java
copy to src/newt/classes/jogamp/newt/driver/bcm/vc/iv/WindowDriver.java
index 9f9d694..21fbea9 100644
--- a/src/newt/classes/jogamp/newt/driver/kd/KDWindow.java
+++ b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/WindowDriver.java
@@ -1,107 +1,107 @@
-/*
- * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
- * Copyright (c) 2012 JogAmp Community. All rights reserved.
+/**
+ * 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:
  * 
- * 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.
  * 
- * - Redistribution 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.
  * 
- * - 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.
+ * 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.kd;
+package jogamp.newt.driver.bcm.vc.iv;
 
 import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.Capabilities;
 import javax.media.nativewindow.GraphicsConfigurationFactory;
 import javax.media.nativewindow.NativeWindowException;
 import javax.media.nativewindow.VisualIDHolder;
-import javax.media.nativewindow.VisualIDHolder.VIDType;
 import javax.media.nativewindow.util.Insets;
 import javax.media.nativewindow.util.Point;
-import javax.media.opengl.GLCapabilitiesImmutable;
 
 import jogamp.newt.WindowImpl;
-import jogamp.opengl.egl.EGLGraphicsConfiguration;
+import jogamp.newt.driver.linux.LinuxMouseTracker;
 
-public class KDWindow extends WindowImpl {
+public class WindowDriver extends WindowImpl {
     private static final String WINDOW_CLASS_NAME = "NewtWindow";
 
     static {
-        KDDisplay.initSingleton();
+        DisplayDriver.initSingleton();
     }
 
-    public KDWindow() {
+    public WindowDriver() {
     }
 
     protected void createNativeImpl() {
         if(0!=getParentWindowHandle()) {
             throw new RuntimeException("Window parenting not supported (yet)");
         }
+        
         final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice(), capsRequested).chooseGraphicsConfiguration(
                 capsRequested, capsRequested, capabilitiesChooser, getScreen().getGraphicsScreen(), VisualIDHolder.VID_UNDEFINED);
         if (null == cfg) {
             throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
         }
+        final Capabilities chosenCaps = (Capabilities) cfg.getChosenCapabilities();
+        // FIXME: Pass along opaque flag, since EGL doesn't determine it
+        if(capsRequested.isBackgroundOpaque() != chosenCaps.isBackgroundOpaque()) {
+            chosenCaps.setBackgroundOpaque(capsRequested.isBackgroundOpaque());
+        }
         setGraphicsConfiguration(cfg);
-
-        GLCapabilitiesImmutable eglCaps = (GLCapabilitiesImmutable) cfg.getChosenCapabilities();
-        int eglConfigID = eglCaps.getVisualID(VIDType.EGL_CONFIG);
-        long eglConfig = EGLGraphicsConfiguration.EGLConfigId2EGLConfig(getDisplayHandle(), eglConfigID);
-
-        eglWindowHandle = CreateWindow(getDisplayHandle(), eglConfig);
-        if (eglWindowHandle == 0) {
-            throw new NativeWindowException("Error creating egl window: "+cfg+", eglConfigID "+eglConfigID+", eglConfig 0x"+Long.toHexString(eglConfig));
+        nativeWindowHandle = CreateWindow(getWidth(), getHeight(), chosenCaps.isBackgroundOpaque(), chosenCaps.getAlphaBits());
+        if (nativeWindowHandle == 0) {
+            throw new NativeWindowException("Error creating egl window: "+cfg);
         }
-        setVisible0(eglWindowHandle, false);
-        setWindowHandle(RealizeWindow(eglWindowHandle));
+        setVisible0(nativeWindowHandle, false);
+        setWindowHandle(nativeWindowHandle);
         if (0 == getWindowHandle()) {
             throw new NativeWindowException("Error native Window Handle is null");
         }
-        windowHandleClose = eglWindowHandle;
+        windowHandleClose = nativeWindowHandle;
+        addWindowListener(LinuxMouseTracker.getSingleton());
+        focusChanged(false, true);        
     }
 
     protected void closeNativeImpl() {
+        removeWindowListener(LinuxMouseTracker.getSingleton());
+        
         if(0!=windowHandleClose) {
             CloseWindow(windowHandleClose, windowUserData);
             windowUserData=0;
         }
     }
 
-    protected void requestFocusImpl(boolean reparented) { }
+    protected void requestFocusImpl(boolean reparented) { 
+        focusChanged(false, true);
+    }
 
     protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) {
         if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) {
-            setVisible0(eglWindowHandle, 0 != ( FLAG_IS_VISIBLE & flags));
+            setVisible0(nativeWindowHandle, 0 != ( FLAG_IS_VISIBLE & flags));
             visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags));
         }
         
-        if(0!=eglWindowHandle) {
+        if(0!=nativeWindowHandle) {
             if(0 != ( FLAG_CHANGE_FULLSCREEN & flags)) {
                 final boolean fs = 0 != ( FLAG_IS_FULLSCREEN & flags) ;
-                setFullScreen0(eglWindowHandle, fs);
+                setFullScreen0(nativeWindowHandle, fs);
                 if(fs) {
                     return true;
                 }
@@ -111,7 +111,7 @@ public class KDWindow extends WindowImpl {
             width=(width>0)?width:getWidth();
             height=(height>0)?height:getHeight();
             if(width>0 || height>0) {
-                setSize0(eglWindowHandle, width, height);
+                setSize0(nativeWindowHandle, width, height);
             }
             if(x>=0 || y>=0) {
                 System.err.println("setPosition n/a in KD");
@@ -138,7 +138,7 @@ public class KDWindow extends WindowImpl {
     //
 
     protected static native boolean initIDs();
-    private        native long CreateWindow(long displayHandle, long eglConfig);
+    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);
@@ -149,15 +149,7 @@ public class KDWindow extends WindowImpl {
         windowUserData=userData;
     }
 
-    @Override
-    protected void sizeChanged(boolean defer, int newWidth, int newHeight, boolean force) {
-        if(isFullscreen()) {
-            ((KDScreen)getScreen()).sizeChanged(getWidth(), getHeight());
-        }
-        super.sizeChanged(defer, newWidth, newHeight, force);
-    }
-
-    private long   eglWindowHandle;
+    private long   nativeWindowHandle;
     private long   windowHandleClose;
     private long   windowUserData;
 }
diff --git a/src/newt/classes/jogamp/newt/driver/intel/gdl/Display.java b/src/newt/classes/jogamp/newt/driver/intel/gdl/DisplayDriver.java
similarity index 87%
rename from src/newt/classes/jogamp/newt/driver/intel/gdl/Display.java
rename to src/newt/classes/jogamp/newt/driver/intel/gdl/DisplayDriver.java
index 20e151e..e370038 100644
--- a/src/newt/classes/jogamp/newt/driver/intel/gdl/Display.java
+++ b/src/newt/classes/jogamp/newt/driver/intel/gdl/DisplayDriver.java
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 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
@@ -36,16 +37,16 @@ package jogamp.newt.driver.intel.gdl;
 import jogamp.newt.*;
 import javax.media.nativewindow.*;
 
-public class Display extends jogamp.newt.DisplayImpl {
+public class DisplayDriver extends jogamp.newt.DisplayImpl {
     static int initCounter = 0;
 
     static {
         NEWTJNILibLoader.loadNEWT();
 
-        if (!Screen.initIDs()) {
+        if (!ScreenDriver.initIDs()) {
             throw new NativeWindowException("Failed to initialize GDL Screen jmethodIDs");
         }
-        if (!Window.initIDs()) {
+        if (!WindowDriver.initIDs()) {
             throw new NativeWindowException("Failed to initialize GDL Window jmethodIDs");
         }
     }
@@ -55,11 +56,11 @@ public class Display extends jogamp.newt.DisplayImpl {
     }
 
 
-    public Display() {
+    public DisplayDriver() {
     }
 
     protected void createNativeImpl() {
-        synchronized(Display.class) {
+        synchronized(DisplayDriver.class) {
             if(0==initCounter) {
                 displayHandle = CreateDisplay();
                 if(0==displayHandle) {
@@ -75,7 +76,7 @@ public class Display extends jogamp.newt.DisplayImpl {
         if(0==displayHandle) {
             throw new NativeWindowException("displayHandle null; initCnt "+initCounter);
         }
-        synchronized(Display.class) {
+        synchronized(DisplayDriver.class) {
             if(initCounter>0) {
                 initCounter--;
                 if(0==initCounter) {
@@ -83,6 +84,7 @@ public class Display extends jogamp.newt.DisplayImpl {
                 }
             }
         }
+        aDevice.close();
     }
 
     protected void dispatchMessagesNative() {
@@ -91,14 +93,14 @@ public class Display extends jogamp.newt.DisplayImpl {
         }
     }
 
-    protected void setFocus(Window focus) {
+    protected void setFocus(WindowDriver focus) {
         focusedWindow = focus;
     }
 
     private long displayHandle = 0;
-    private Window focusedWindow = null;
+    private WindowDriver focusedWindow = null;
     private native long CreateDisplay();
     private native void DestroyDisplay(long displayHandle);
-    private native void DispatchMessages(long displayHandle, Window focusedWindow);
+    private native void DispatchMessages(long displayHandle, WindowDriver focusedWindow);
 }
 
diff --git a/src/newt/classes/jogamp/newt/driver/intel/gdl/Screen.java b/src/newt/classes/jogamp/newt/driver/intel/gdl/ScreenDriver.java
similarity index 94%
rename from src/newt/classes/jogamp/newt/driver/intel/gdl/Screen.java
rename to src/newt/classes/jogamp/newt/driver/intel/gdl/ScreenDriver.java
index 66ad1c6..8eed14d 100644
--- a/src/newt/classes/jogamp/newt/driver/intel/gdl/Screen.java
+++ b/src/newt/classes/jogamp/newt/driver/intel/gdl/ScreenDriver.java
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 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
@@ -38,13 +39,13 @@ import javax.media.nativewindow.DefaultGraphicsScreen;
 import javax.media.nativewindow.util.Dimension;
 import javax.media.nativewindow.util.Point;
 
-public class Screen extends jogamp.newt.ScreenImpl {
+public class ScreenDriver extends jogamp.newt.ScreenImpl {
 
     static {
-        Display.initSingleton();
+        DisplayDriver.initSingleton();
     }
 
-    public Screen() {
+    public ScreenDriver() {
     }
 
     protected void createNativeImpl() {
diff --git a/src/newt/classes/jogamp/newt/driver/intel/gdl/Window.java b/src/newt/classes/jogamp/newt/driver/intel/gdl/WindowDriver.java
similarity index 90%
rename from src/newt/classes/jogamp/newt/driver/intel/gdl/Window.java
rename to src/newt/classes/jogamp/newt/driver/intel/gdl/WindowDriver.java
index d5c75ab..98335f1 100644
--- a/src/newt/classes/jogamp/newt/driver/intel/gdl/Window.java
+++ b/src/newt/classes/jogamp/newt/driver/intel/gdl/WindowDriver.java
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 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
@@ -37,12 +38,12 @@ import javax.media.nativewindow.*;
 import javax.media.nativewindow.util.Insets;
 import javax.media.nativewindow.util.Point;
 
-public class Window extends jogamp.newt.WindowImpl {
+public class WindowDriver extends jogamp.newt.WindowImpl {
     static {
-        Display.initSingleton();
+        DisplayDriver.initSingleton();
     }
 
-    public Window() {
+    public WindowDriver() {
     }
 
     static long nextWindowHandle = 1;
@@ -61,7 +62,7 @@ public class Window extends jogamp.newt.WindowImpl {
         }
         setGraphicsConfiguration(cfg);
 
-        synchronized(Window.class) {
+        synchronized(WindowDriver.class) {
             setWindowHandle(nextWindowHandle++); // just a marker
 
             surfaceHandle = CreateSurface(aDevice.getHandle(), getScreen().getWidth(), getScreen().getHeight(), getX(), getY(), getWidth(), getHeight());
@@ -73,16 +74,16 @@ public class Window extends jogamp.newt.WindowImpl {
 
     protected void closeNativeImpl() {
         if(0!=surfaceHandle) {
-            synchronized(Window.class) {
+            synchronized(WindowDriver.class) {
                 CloseSurface(getDisplayHandle(), surfaceHandle);
             }
             surfaceHandle = 0;
-            ((Display)getScreen().getDisplay()).setFocus(null);
+            ((DisplayDriver)getScreen().getDisplay()).setFocus(null);
         }
     }
 
     protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) {
-        Screen  screen = (Screen) getScreen();
+        ScreenDriver  screen = (ScreenDriver) getScreen();
 
         if(width>screen.getWidth()) {
             width=screen.getWidth();
@@ -103,7 +104,7 @@ public class Window extends jogamp.newt.WindowImpl {
 
         if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) {
             if(0 != ( FLAG_IS_VISIBLE & flags)) {
-                ((Display)getScreen().getDisplay()).setFocus(this);
+                ((DisplayDriver)getScreen().getDisplay()).setFocus(this);
             }
             visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags));
         }
@@ -112,7 +113,7 @@ public class Window extends jogamp.newt.WindowImpl {
     }
 
     protected void requestFocusImpl(boolean reparented) {
-        ((Display)getScreen().getDisplay()).setFocus(this);
+        ((DisplayDriver)getScreen().getDisplay()).setFocus(this);
     }
 
     @Override
diff --git a/src/newt/classes/jogamp/newt/driver/kd/KDDisplay.java b/src/newt/classes/jogamp/newt/driver/kd/DisplayDriver.java
similarity index 94%
rename from src/newt/classes/jogamp/newt/driver/kd/KDDisplay.java
rename to src/newt/classes/jogamp/newt/driver/kd/DisplayDriver.java
index 07b0318..745be5d 100644
--- a/src/newt/classes/jogamp/newt/driver/kd/KDDisplay.java
+++ b/src/newt/classes/jogamp/newt/driver/kd/DisplayDriver.java
@@ -42,13 +42,12 @@ import jogamp.newt.NEWTJNILibLoader;
 import jogamp.opengl.egl.EGL;
 import jogamp.opengl.egl.EGLDisplayUtil;
 
-public class KDDisplay extends DisplayImpl {
-
+public class DisplayDriver extends DisplayImpl {
     static {
         NEWTJNILibLoader.loadNEWT();
 
-        if (!KDWindow.initIDs()) {
-            throw new NativeWindowException("Failed to initialize KDWindow jmethodIDs");
+        if (!WindowDriver.initIDs()) {
+            throw new NativeWindowException("Failed to initialize kd.Window jmethodIDs");
         }
     }
 
@@ -57,7 +56,7 @@ public class KDDisplay extends DisplayImpl {
     }
 
 
-    public KDDisplay() {
+    public DisplayDriver() {
     }
 
     protected void createNativeImpl() {
diff --git a/src/newt/classes/jogamp/newt/driver/kd/KDScreen.java b/src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java
similarity index 95%
rename from src/newt/classes/jogamp/newt/driver/kd/KDScreen.java
rename to src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java
index ee34758..656bcf5 100644
--- a/src/newt/classes/jogamp/newt/driver/kd/KDScreen.java
+++ b/src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java
@@ -40,12 +40,12 @@ import javax.media.nativewindow.util.Point;
 
 import jogamp.newt.ScreenImpl;
 
-public class KDScreen extends ScreenImpl {
+public class ScreenDriver extends ScreenImpl {
     static {
-        KDDisplay.initSingleton();
+        DisplayDriver.initSingleton();
     }
 
-    public KDScreen() {
+    public ScreenDriver() {
     }
 
     protected void createNativeImpl() {
diff --git a/src/newt/classes/jogamp/newt/driver/kd/KDWindow.java b/src/newt/classes/jogamp/newt/driver/kd/WindowDriver.java
similarity index 97%
rename from src/newt/classes/jogamp/newt/driver/kd/KDWindow.java
rename to src/newt/classes/jogamp/newt/driver/kd/WindowDriver.java
index 9f9d694..c733a3e 100644
--- a/src/newt/classes/jogamp/newt/driver/kd/KDWindow.java
+++ b/src/newt/classes/jogamp/newt/driver/kd/WindowDriver.java
@@ -46,14 +46,14 @@ import javax.media.opengl.GLCapabilitiesImmutable;
 import jogamp.newt.WindowImpl;
 import jogamp.opengl.egl.EGLGraphicsConfiguration;
 
-public class KDWindow extends WindowImpl {
+public class WindowDriver extends WindowImpl {
     private static final String WINDOW_CLASS_NAME = "NewtWindow";
 
     static {
-        KDDisplay.initSingleton();
+        DisplayDriver.initSingleton();
     }
 
-    public KDWindow() {
+    public WindowDriver() {
     }
 
     protected void createNativeImpl() {
@@ -152,7 +152,7 @@ public class KDWindow extends WindowImpl {
     @Override
     protected void sizeChanged(boolean defer, int newWidth, int newHeight, boolean force) {
         if(isFullscreen()) {
-            ((KDScreen)getScreen()).sizeChanged(getWidth(), getHeight());
+            ((ScreenDriver)getScreen()).sizeChanged(getWidth(), getHeight());
         }
         super.sizeChanged(defer, newWidth, newHeight, force);
     }
diff --git a/src/newt/classes/jogamp/newt/driver/linux/LinuxMouseTracker.java b/src/newt/classes/jogamp/newt/driver/linux/LinuxMouseTracker.java
new file mode 100644
index 0000000..885649d
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/driver/linux/LinuxMouseTracker.java
@@ -0,0 +1,221 @@
+/**
+ * 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 jogamp.newt.driver.linux;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+
+import jogamp.newt.WindowImpl;
+
+import com.jogamp.newt.Window;
+import com.jogamp.newt.event.MouseEvent;
+import com.jogamp.newt.event.WindowEvent;
+import com.jogamp.newt.event.WindowListener;
+import com.jogamp.newt.event.WindowUpdateEvent;
+
+/**
+ * Experimental native mouse tracker thread for GNU/Linux
+ * just reading <code>/dev/input/mice</code>
+ * within it's own polling thread.
+ */
+public class LinuxMouseTracker implements WindowListener {
+    
+    private static final LinuxMouseTracker lmt;
+    
+    static {
+        lmt = new LinuxMouseTracker();
+        final Thread t = new Thread(lmt.mouseDevicePoller, "NEWT-LinuxMouseTracker");
+        t.setDaemon(true);
+        t.start();
+    }
+    
+    public static LinuxMouseTracker getSingleton() {
+        return lmt;
+    }
+
+    private volatile boolean stop = false;
+    private int x = 0;
+    private int y = 0;
+    private int buttonDown = 0;
+    private int old_x = 0;
+    private int old_y = 0;
+    private int old_buttonDown = 0;
+    private WindowImpl focusedWindow = null;
+    private MouseDevicePoller mouseDevicePoller = new MouseDevicePoller();
+    
+    @Override
+    public void windowResized(WindowEvent e) { }
+
+    @Override
+    public void windowMoved(WindowEvent e) { }
+
+    @Override
+    public void windowDestroyNotify(WindowEvent e) {
+        Object s = e.getSource();
+        if(focusedWindow == s) {
+            focusedWindow = null;
+        }
+    }
+
+    @Override
+    public void windowDestroyed(WindowEvent e) { }
+
+    @Override
+    public void windowGainedFocus(WindowEvent e) {
+        Object s = e.getSource();
+        if(s instanceof WindowImpl) {
+            focusedWindow = (WindowImpl) s;
+        }
+    }
+
+    @Override
+    public void windowLostFocus(WindowEvent e) {
+        Object s = e.getSource();
+        if(focusedWindow == s) {
+            focusedWindow = null;
+        }
+    }
+
+    @Override
+    public void windowRepaint(WindowUpdateEvent e) { }
+    
+    class MouseDevicePoller implements Runnable {
+        @Override
+        public void run() {
+            final byte[] b = new byte[3];
+            final File f = new File("/dev/input/mice");
+            f.setReadOnly();
+            InputStream fis;
+            try {
+                fis = new FileInputStream(f);
+            } catch (FileNotFoundException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+                return;
+            }
+            int xd=0,yd=0; //x/y movement delta
+            boolean xo=false,yo=false; // x/y overflow (out of range -255 to +255)
+            boolean lb=false,mb=false,rb=false,hs=false,vs=false; //left/middle/right mousebutton
+            while(!stop) {
+                int remaining=3;
+                while(remaining>0) {
+                    int read = 0;
+                    try {
+                        read = fis.read(b, 0, remaining);
+                    } catch (IOException e) {
+                        // TODO Auto-generated catch block
+                        e.printStackTrace();
+                    }
+                    if(read<0) {
+                        stop = true; // EOF of mouse !?
+                    } else {
+                        remaining -= read;
+                    }
+                }
+                lb=(b[0]&1)>0;
+                rb=(b[0]&2)>0;
+                mb=(b[0]&4)>0;
+                hs=(b[0]&16)>0;
+                vs=(b[0]&32)>0;
+                xo=(b[0]&64)>0;
+                yo=(b[0]&128)>0;
+                xd=b[1];
+                yd=b[2];
+            
+                x+=xd;
+                y+=yd;
+                
+                if(x<0) {
+                    x=0;
+                }
+                if(y<0) {
+                    y=0;
+                }
+                
+                if(lb) {
+                    buttonDown = MouseEvent.BUTTON1;
+                }
+                if(mb) {
+                    buttonDown = MouseEvent.BUTTON2;
+                }
+                if(rb) {
+                    buttonDown = MouseEvent.BUTTON3;
+                }
+                
+                if(null != focusedWindow) {
+                    if( x >= focusedWindow.getScreen().getWidth() ) {
+                        x = focusedWindow.getScreen().getWidth() - 1;
+                    }
+                    if( y >= focusedWindow.getScreen().getHeight() ) {
+                        y = focusedWindow.getScreen().getHeight() - 1;
+                    }
+                    int wx = x - focusedWindow.getX(), wy = y - focusedWindow.getY(); 
+                    
+                    if(old_x != x || old_y != y) {
+                        // mouse moved
+                        focusedWindow.sendMouseEvent(MouseEvent.EVENT_MOUSE_MOVED, 0, wx, wy, 0, 0 ); 
+                    }
+                    
+                    if(old_buttonDown != buttonDown) {
+                        // press/release
+                        if( 0 != buttonDown ) {
+                            focusedWindow.sendMouseEvent(                            
+                                    MouseEvent.EVENT_MOUSE_PRESSED, 
+                                    0, wx, wy, buttonDown, 0 ); 
+                        } else {
+                            focusedWindow.sendMouseEvent(                            
+                                    MouseEvent.EVENT_MOUSE_RELEASED, 
+                                    0, wx, wy, old_buttonDown, 0 ); 
+                        }
+                    }                
+                } else {
+                    if(Window.DEBUG_MOUSE_EVENT) {
+                        System.out.println(x+"/"+y+", hs="+hs+",vs="+vs+",lb="+lb+",rb="+rb+",mb="+mb+",xo="+xo+",yo="+yo+"xd="+xd+",yd="+yd);
+                    }
+                }
+                
+                old_x = x;
+                old_y = y;
+                old_buttonDown = buttonDown;
+                
+            }
+            if(null != fis) {
+                try {
+                    fis.close();
+                } catch (IOException e) {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace();
+                }
+            }
+        }
+    }    
+}
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/MacDisplay.java b/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java
similarity index 92%
rename from src/newt/classes/jogamp/newt/driver/macosx/MacDisplay.java
rename to src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java
index 18f8d95..b49c6b6 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/MacDisplay.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 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
@@ -41,14 +42,14 @@ import com.jogamp.nativewindow.macosx.MacOSXGraphicsDevice;
 import jogamp.newt.DisplayImpl;
 import jogamp.newt.NEWTJNILibLoader;
 
-public class MacDisplay extends DisplayImpl {
+public class DisplayDriver extends DisplayImpl {
     static {
         NEWTJNILibLoader.loadNEWT();
 
         if(!initNSApplication0()) {
             throw new NativeWindowException("Failed to initialize native Application hook");
         }
-        if(!MacWindow.initIDs0()) {
+        if(!WindowDriver.initIDs0()) {
             throw new NativeWindowException("Failed to initialize jmethodIDs");
         }
         if(DEBUG) {
@@ -60,7 +61,7 @@ public class MacDisplay extends DisplayImpl {
         // just exist to ensure static init has been run
     }
     
-    public MacDisplay() {
+    public DisplayDriver() {
     }
 
     protected void dispatchMessagesNative() {
@@ -71,7 +72,9 @@ public class MacDisplay extends DisplayImpl {
         aDevice = new MacOSXGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT);
     }
 
-    protected void closeNativeImpl() { }
+    protected void closeNativeImpl() { 
+        aDevice.close();
+    }
 
     public static void runNSApplication() {
         runNSApplication0();
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/MacKeyUtil.java b/src/newt/classes/jogamp/newt/driver/macosx/MacKeyUtil.java
index 46625f7..5966bd3 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/MacKeyUtil.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/MacKeyUtil.java
@@ -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.
+ */
 package jogamp.newt.driver.macosx;
 
 import com.jogamp.newt.event.KeyEvent;
@@ -135,13 +162,13 @@ public class MacKeyUtil {
             case kVK_Space:                return KeyEvent.VK_SPACE;
             case kVK_Delete:               return KeyEvent.VK_BACK_SPACE;
             case kVK_Escape:               return KeyEvent.VK_ESCAPE;
-            case kVK_Command:              return KeyEvent.VK_ALT;
+            case kVK_Command:              return KeyEvent.VK_WINDOWS;
             case kVK_Shift:                return KeyEvent.VK_SHIFT;
             case kVK_CapsLock:             return KeyEvent.VK_CAPS_LOCK;
-            case kVK_Option:               return KeyEvent.VK_WINDOWS;
+            case kVK_Option:               return KeyEvent.VK_ALT;
             case kVK_Control:              return KeyEvent.VK_CONTROL;
             case kVK_RightShift:           return KeyEvent.VK_SHIFT;
-            case kVK_RightOption:          return KeyEvent.VK_WINDOWS;
+            case kVK_RightOption:          return KeyEvent.VK_ALT;
             case kVK_RightControl:         return KeyEvent.VK_CONTROL;
             // case kVK_Function:             return KeyEvent.VK_F;
             case kVK_F17:                  return KeyEvent.VK_F17;
@@ -179,78 +206,73 @@ public class MacKeyUtil {
             case kVK_UpArrow:              return KeyEvent.VK_UP;
         }
         
-        if (keyChar == '\r') {
-            // Turn these into \n
-            return KeyEvent.VK_ENTER;
-        }
-
-        if (keyChar >= NSUpArrowFunctionKey && keyChar <= NSModeSwitchFunctionKey) {
-            switch (keyChar) {
-                case NSUpArrowFunctionKey:     return KeyEvent.VK_UP;
-                case NSDownArrowFunctionKey:   return KeyEvent.VK_DOWN;
-                case NSLeftArrowFunctionKey:   return KeyEvent.VK_LEFT;
-                case NSRightArrowFunctionKey:  return KeyEvent.VK_RIGHT;
-                case NSF1FunctionKey:          return KeyEvent.VK_F1;
-                case NSF2FunctionKey:          return KeyEvent.VK_F2;
-                case NSF3FunctionKey:          return KeyEvent.VK_F3;
-                case NSF4FunctionKey:          return KeyEvent.VK_F4;
-                case NSF5FunctionKey:          return KeyEvent.VK_F5;
-                case NSF6FunctionKey:          return KeyEvent.VK_F6;
-                case NSF7FunctionKey:          return KeyEvent.VK_F7;
-                case NSF8FunctionKey:          return KeyEvent.VK_F8;
-                case NSF9FunctionKey:          return KeyEvent.VK_F9;
-                case NSF10FunctionKey:         return KeyEvent.VK_F10;
-                case NSF11FunctionKey:         return KeyEvent.VK_F11;
-                case NSF12FunctionKey:         return KeyEvent.VK_F12;
-                case NSF13FunctionKey:         return KeyEvent.VK_F13;
-                case NSF14FunctionKey:         return KeyEvent.VK_F14;
-                case NSF15FunctionKey:         return KeyEvent.VK_F15;
-                case NSF16FunctionKey:         return KeyEvent.VK_F16;
-                case NSF17FunctionKey:         return KeyEvent.VK_F17;
-                case NSF18FunctionKey:         return KeyEvent.VK_F18;
-                case NSF19FunctionKey:         return KeyEvent.VK_F19;
-                case NSF20FunctionKey:         return KeyEvent.VK_F20;
-                case NSF21FunctionKey:         return KeyEvent.VK_F21;
-                case NSF22FunctionKey:         return KeyEvent.VK_F22;
-                case NSF23FunctionKey:         return KeyEvent.VK_F23;
-                case NSF24FunctionKey:         return KeyEvent.VK_F24;
-                case NSInsertFunctionKey:      return KeyEvent.VK_INSERT;
-                case NSDeleteFunctionKey:      return KeyEvent.VK_DELETE;
-                case NSHomeFunctionKey:        return KeyEvent.VK_HOME;
-                case NSBeginFunctionKey:       return KeyEvent.VK_BEGIN;
-                case NSEndFunctionKey:         return KeyEvent.VK_END;
-                case NSPageUpFunctionKey:      return KeyEvent.VK_PAGE_UP;
-                case NSPageDownFunctionKey:    return KeyEvent.VK_PAGE_DOWN;
-                case NSPrintScreenFunctionKey: return KeyEvent.VK_PRINTSCREEN;
-                case NSScrollLockFunctionKey:  return KeyEvent.VK_SCROLL_LOCK;
-                case NSPauseFunctionKey:       return KeyEvent.VK_PAUSE;
-                // Not handled:
-                // NSSysReqFunctionKey
-                // NSBreakFunctionKey
-                // NSResetFunctionKey
-                case NSStopFunctionKey:        return KeyEvent.VK_STOP;
-                // Not handled:
-                // NSMenuFunctionKey
-                // NSUserFunctionKey
-                // NSSystemFunctionKey
-                // NSPrintFunctionKey
-                // NSClearLineFunctionKey
-                // NSClearDisplayFunctionKey
-                // NSInsertLineFunctionKey
-                // NSDeleteLineFunctionKey
-                // NSInsertCharFunctionKey
-                // NSDeleteCharFunctionKey
-                // NSPrevFunctionKey
-                // NSNextFunctionKey
-                // NSSelectFunctionKey
-                // NSExecuteFunctionKey
-                // NSUndoFunctionKey
-                // NSRedoFunctionKey
-                // NSFindFunctionKey
-                // NSHelpFunctionKey
-                // NSModeSwitchFunctionKey
-                default: break;
-            }
+        switch (keyChar) {
+            case NSUpArrowFunctionKey:     return KeyEvent.VK_UP;
+            case NSDownArrowFunctionKey:   return KeyEvent.VK_DOWN;
+            case NSLeftArrowFunctionKey:   return KeyEvent.VK_LEFT;
+            case NSRightArrowFunctionKey:  return KeyEvent.VK_RIGHT;
+            case NSF1FunctionKey:          return KeyEvent.VK_F1;
+            case NSF2FunctionKey:          return KeyEvent.VK_F2;
+            case NSF3FunctionKey:          return KeyEvent.VK_F3;
+            case NSF4FunctionKey:          return KeyEvent.VK_F4;
+            case NSF5FunctionKey:          return KeyEvent.VK_F5;
+            case NSF6FunctionKey:          return KeyEvent.VK_F6;
+            case NSF7FunctionKey:          return KeyEvent.VK_F7;
+            case NSF8FunctionKey:          return KeyEvent.VK_F8;
+            case NSF9FunctionKey:          return KeyEvent.VK_F9;
+            case NSF10FunctionKey:         return KeyEvent.VK_F10;
+            case NSF11FunctionKey:         return KeyEvent.VK_F11;
+            case NSF12FunctionKey:         return KeyEvent.VK_F12;
+            case NSF13FunctionKey:         return KeyEvent.VK_F13;
+            case NSF14FunctionKey:         return KeyEvent.VK_F14;
+            case NSF15FunctionKey:         return KeyEvent.VK_F15;
+            case NSF16FunctionKey:         return KeyEvent.VK_F16;
+            case NSF17FunctionKey:         return KeyEvent.VK_F17;
+            case NSF18FunctionKey:         return KeyEvent.VK_F18;
+            case NSF19FunctionKey:         return KeyEvent.VK_F19;
+            case NSF20FunctionKey:         return KeyEvent.VK_F20;
+            case NSF21FunctionKey:         return KeyEvent.VK_F21;
+            case NSF22FunctionKey:         return KeyEvent.VK_F22;
+            case NSF23FunctionKey:         return KeyEvent.VK_F23;
+            case NSF24FunctionKey:         return KeyEvent.VK_F24;
+            case NSInsertFunctionKey:      return KeyEvent.VK_INSERT;
+            case NSDeleteFunctionKey:      return KeyEvent.VK_DELETE;
+            case NSHomeFunctionKey:        return KeyEvent.VK_HOME;
+            case NSBeginFunctionKey:       return KeyEvent.VK_BEGIN;
+            case NSEndFunctionKey:         return KeyEvent.VK_END;
+            case NSPageUpFunctionKey:      return KeyEvent.VK_PAGE_UP;
+            case NSPageDownFunctionKey:    return KeyEvent.VK_PAGE_DOWN;
+            case NSPrintScreenFunctionKey: return KeyEvent.VK_PRINTSCREEN;
+            case NSScrollLockFunctionKey:  return KeyEvent.VK_SCROLL_LOCK;
+            case NSPauseFunctionKey:       return KeyEvent.VK_PAUSE;
+            // Not handled:
+            // NSSysReqFunctionKey
+            // NSBreakFunctionKey
+            // NSResetFunctionKey
+            case NSStopFunctionKey:        return KeyEvent.VK_STOP;
+            // Not handled:
+            // NSMenuFunctionKey
+            // NSUserFunctionKey
+            // NSSystemFunctionKey
+            // NSPrintFunctionKey
+            // NSClearLineFunctionKey
+            // NSClearDisplayFunctionKey
+            // NSInsertLineFunctionKey
+            // NSDeleteLineFunctionKey
+            // NSInsertCharFunctionKey
+            // NSDeleteCharFunctionKey
+            // NSPrevFunctionKey
+            // NSNextFunctionKey
+            // NSSelectFunctionKey
+            // NSExecuteFunctionKey
+            // NSUndoFunctionKey
+            // NSRedoFunctionKey
+            // NSFindFunctionKey
+            // NSHelpFunctionKey
+            // NSModeSwitchFunctionKey
+            case 0x60: return KeyEvent.VK_BACK_QUOTE; // `
+            case 0x27: return KeyEvent.VK_QUOTE;      // '          
+            case '\r': return KeyEvent.VK_ENTER;
         }
 
         if ('a' <= keyChar && keyChar <= 'z') {
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/MacScreen.java b/src/newt/classes/jogamp/newt/driver/macosx/ScreenDriver.java
similarity index 97%
rename from src/newt/classes/jogamp/newt/driver/macosx/MacScreen.java
rename to src/newt/classes/jogamp/newt/driver/macosx/ScreenDriver.java
index b9c725f..24e60ba 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/MacScreen.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/ScreenDriver.java
@@ -47,18 +47,18 @@ import com.jogamp.common.util.IntObjectHashMap;
 import com.jogamp.newt.ScreenMode;
 import com.jogamp.newt.util.ScreenModeUtil;
 
-public class MacScreen extends ScreenImpl {
+public class ScreenDriver extends ScreenImpl {
     
     // caching native CGDisplayScreenSize() results, since it's ridiculous slow (~6 ms each call)
     private static IntObjectHashMap/*<int, DimensionImmutable>*/ scrnIdx2Dimension;
     
     static {
-        MacDisplay.initSingleton();
+        DisplayDriver.initSingleton();
         scrnIdx2Dimension = new IntObjectHashMap();
         scrnIdx2Dimension.setKeyNotFoundValue(null);
     }
 
-    public MacScreen() {
+    public ScreenDriver() {
     }
 
     protected void createNativeImpl() {
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java
similarity index 79%
rename from src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java
rename to src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java
index 27d7a16..5755bdf 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java
@@ -45,19 +45,21 @@ import javax.media.nativewindow.util.InsetsImmutable;
 import javax.media.nativewindow.util.Point;
 import javax.media.nativewindow.util.PointImmutable;
 
+import jogamp.nativewindow.macosx.OSXUtil;
 import jogamp.newt.WindowImpl;
 import jogamp.newt.driver.DriverClearFocus;
 import jogamp.newt.driver.DriverUpdatePosition;
 
+import com.jogamp.newt.event.InputEvent;
 import com.jogamp.newt.event.KeyEvent;
 
-public class MacWindow extends WindowImpl implements MutableSurface, DriverClearFocus, DriverUpdatePosition {
+public class WindowDriver extends WindowImpl implements MutableSurface, DriverClearFocus, DriverUpdatePosition {
     
     static {
-        MacDisplay.initSingleton();
+        DisplayDriver.initSingleton();
     }
 
-    public MacWindow() {
+    public WindowDriver() {
     }
     
     @Override
@@ -117,6 +119,7 @@ public class MacWindow extends WindowImpl implements MutableSurface, DriverClear
         return 0 != sscSurfaceHandle ? sscSurfaceHandle : surfaceHandle;
     }
 
+    @Override
     public void setSurfaceHandle(long surfaceHandle) {
         if(DEBUG_IMPLEMENTATION) {
             System.err.println("MacWindow.setSurfaceHandle(): 0x"+Long.toHexString(surfaceHandle));
@@ -147,7 +150,7 @@ public class MacWindow extends WindowImpl implements MutableSurface, DriverClear
         
     public final void clearFocus() {
         if(DEBUG_IMPLEMENTATION) {
-            System.err.println("MacWindow: clearFocus() - requestFocusParent, isOffscreenInstance "+isOffscreenInstance);
+            System.err.println("MacWindow: clearFocus(), isOffscreenInstance "+isOffscreenInstance);
         }
         if(!isOffscreenInstance) {
             resignFocus0(getWindowHandle());
@@ -170,13 +173,22 @@ public class MacWindow extends WindowImpl implements MutableSurface, DriverClear
     
     
     protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) {
-        final Point pS = getTopLevelLocationOnScreen(x, y);
-        isOffscreenInstance = 0 != sscSurfaceHandle || isOffscreenInstance(this, this.getParent());
+        final boolean _isOffscreenInstance = isOffscreenInstance(this, this.getParent());
+        isOffscreenInstance = 0 != sscSurfaceHandle || _isOffscreenInstance;
+        final PointImmutable pS = isOffscreenInstance ? new Point(0, 0) : getTopLevelLocationOnScreen(x, y);
         
         if(DEBUG_IMPLEMENTATION) {
+            final AbstractGraphicsConfiguration cWinCfg = this.getGraphicsConfiguration();
+            final NativeWindow pWin = getParent();
+            final AbstractGraphicsConfiguration pWinCfg = null != pWin ? pWin.getGraphicsConfiguration() : null;
             System.err.println("MacWindow reconfig: "+x+"/"+y+" -> "+pS+" - "+width+"x"+height+
-                               ", offscreenInstance "+isOffscreenInstance+
-                               ", "+getReconfigureFlagsAsString(null, flags));
+                               ",\n\t parent type "+(null != pWin ? pWin.getClass().getName() : null)+
+                               ",\n\t   this-chosenCaps "+(null != cWinCfg ? cWinCfg.getChosenCapabilities() : null)+
+                               ",\n\t parent-chosenCaps "+(null != pWinCfg ? pWinCfg.getChosenCapabilities() : null)+
+                               ", isOffscreenInstance(sscSurfaceHandle "+toHexString(sscSurfaceHandle)+
+                               ", ioi: "+_isOffscreenInstance+
+                               ") -> "+isOffscreenInstance+
+                               "\n\t, "+getReconfigureFlagsAsString(null, flags));
         }
         
         if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) && 0 == ( FLAG_IS_VISIBLE & flags) ) {
@@ -190,7 +202,11 @@ public class MacWindow extends WindowImpl implements MutableSurface, DriverClear
             0 != ( FLAG_CHANGE_DECORATION & flags) ||
             0 != ( FLAG_CHANGE_PARENTING & flags) ||
             0 != ( FLAG_CHANGE_FULLSCREEN & flags) ) {
-            createWindow(isOffscreenInstance, 0 != getWindowHandle(), pS, width, height, 0 != ( FLAG_IS_FULLSCREEN & flags));
+            if(isOffscreenInstance) {
+                createWindow(true, 0 != getWindowHandle(), pS, 64, 64, false);
+            } else {
+                createWindow(false, 0 != getWindowHandle(), pS, width, height, 0 != ( FLAG_IS_FULLSCREEN & flags));
+            }
             if(isVisible()) { flags |= FLAG_CHANGE_VISIBILITY; } 
         }
         if(x>=0 && y>=0) {
@@ -221,16 +237,21 @@ public class MacWindow extends WindowImpl implements MutableSurface, DriverClear
     }
 
     protected Point getLocationOnScreenImpl(int x, int y) {
-        Point p = new Point(x, y);
+        final NativeWindow parent = getParent();
+        final boolean useParent = null != parent && 0 != parent.getWindowHandle() ;
+        
+        if( !useParent && !isOffscreenInstance && 0 != surfaceHandle) {
+            return OSXUtil.GetLocationOnScreen(surfaceHandle, true, x, y);
+        }
+        
+        final Point p = new Point(x, y);
         // min val is 0
         p.setX(Math.max(p.getX(), 0));
         p.setY(Math.max(p.getY(), 0));
-        
-        final NativeWindow parent = getParent();
-        if( null != parent && 0 != parent.getWindowHandle() ) {
+        if( useParent ) {
             p.translate(parent.getLocationOnScreen(null));
         }
-        return p;        
+        return p;
     }
     
     private Point getTopLevelLocationOnScreen(int x, int y) {
@@ -291,55 +312,56 @@ public class MacWindow extends WindowImpl implements MutableSurface, DriverClear
         } // else may need offscreen solution ? FIXME
     }
     
-    @Override
-    public void sendKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) {
-        // Note that we send the key char for the key code on this
-        // platform -- we do not get any useful key codes out of the system
-        final int keyCode2 = MacKeyUtil.validateKeyCode(keyCode, keyChar);
-        final boolean valid = validateKeyEvent(eventType, modifiers, keyCode);
-        if(DEBUG_IMPLEMENTATION) System.err.println("MacWindow.sendKeyEvent "+Thread.currentThread().getName()+" char: 0x"+Integer.toHexString(keyChar)+", code 0x"+Integer.toHexString(keyCode)+" -> 0x"+Integer.toHexString(keyCode2)+", valid "+valid);
-        if(valid) {
-            // only deliver keyChar on key Typed events, harmonizing platform behavior
-            keyChar = KeyEvent.EVENT_KEY_TYPED == eventType ? keyChar : (char)-1;
-            super.sendKeyEvent(eventType, modifiers, keyCode2, keyChar);
+    private final void emitKeyEvent(boolean send, boolean wait, int eventType, int modifiers, int keyCode, char keyChar) {
+        if( send ) {
+            super.sendKeyEvent(eventType, modifiers, keyCode, keyChar);
+        } else {
+            super.enqueueKeyEvent(wait, eventType, modifiers, keyCode, keyChar);
         }
     }
-    
-    @Override
-    public void enqueueKeyEvent(boolean wait, int eventType, int modifiers, int keyCode, char keyChar) {
+
+    private final void handleKeyEvent(boolean send, boolean wait, int eventType, int modifiers, int _keyCode, char keyChar) {
         // Note that we send the key char for the key code on this
         // platform -- we do not get any useful key codes out of the system
-        final int keyCode2 = MacKeyUtil.validateKeyCode(keyCode, keyChar);
-        final boolean valid = validateKeyEvent(eventType, modifiers, keyCode);
-        if(DEBUG_IMPLEMENTATION) System.err.println("MacWindow.enqueueKeyEvent "+Thread.currentThread().getName()+" char: 0x"+Integer.toHexString(keyChar)+", code 0x"+Integer.toHexString(keyCode)+" -> 0x"+Integer.toHexString(keyCode2)+", valid "+valid);
-        if(valid) {
-            // only deliver keyChar on key Typed events, harmonizing platform behavior
-            keyChar = KeyEvent.EVENT_KEY_TYPED == eventType ? keyChar : (char)-1;
-            super.enqueueKeyEvent(wait, eventType, modifiers, keyCode2, keyChar);
-        }
-    }
-
-    private int keyDownModifiers = 0;
-    private int keyDownCode = 0;
-    
-    private boolean validateKeyEvent(int eventType, int modifiers, int keyCode) {
+        final int keyCode = MacKeyUtil.validateKeyCode(_keyCode, keyChar);
+        // final boolean isModifierKeyCode = KeyEvent.isModifierKey(keyCode);
+        // System.err.println("*** handleKeyEvent: event "+KeyEvent.getEventTypeString(eventType)+", key 0x"+Integer.toHexString(_keyCode)+" -> 0x"+Integer.toHexString(keyCode)+", mods "+toHexString(modifiers)+", was: pressed "+isKeyPressed(keyCode)+", repeat "+isKeyInAutoRepeat(keyCode)+", isModifierKeyCode "+isModifierKeyCode);
+            
+        // 1:1 Order: OSX and NEWT delivery order is PRESSED, RELEASED and TYPED            
+        // Auto-Repeat: OSX delivers only PRESSED, inject auto-repeat RELEASE and TYPED keys _before_ PRESSED
         switch(eventType) {
-            case KeyEvent.EVENT_KEY_PRESSED:
-                keyDownModifiers = modifiers;
-                keyDownCode = keyCode;
-                return true;
             case KeyEvent.EVENT_KEY_RELEASED:
-                return keyDownModifiers == modifiers && keyDownCode == keyCode;
+                if( isKeyCodeTracked(keyCode) ) {
+                    keyRepeatState.put(keyCode, false); // prev == true -> AR out
+                    keyPressedState.put(keyCode, false);
+                }
+                break;
+            case KeyEvent.EVENT_KEY_PRESSED:
+                if( isKeyCodeTracked(keyCode) ) {
+                    if( keyPressedState.put(keyCode, true) ) {
+                        // key was already pressed
+                        keyRepeatState.put(keyCode, true); // prev == false ->  AR in
+                        modifiers |= InputEvent.AUTOREPEAT_MASK;
+                        emitKeyEvent(send, wait, KeyEvent.EVENT_KEY_RELEASED, modifiers, keyCode, keyChar); // RELEASED
+                        emitKeyEvent(send, wait, KeyEvent.EVENT_KEY_TYPED, modifiers, keyCode, keyChar); // TYPED
+                    }
+                }
+                break;
             case KeyEvent.EVENT_KEY_TYPED:
-                final boolean matchKeyDown = keyDownModifiers == modifiers && keyDownCode == keyCode;
-                keyDownModifiers = 0;
-                keyDownCode = 0;
-                return matchKeyDown;
-            default:
-                throw new NativeWindowException("Unexpected key event type " + eventType);
+                break;
         }
+        emitKeyEvent(send, wait, eventType, modifiers, keyCode, keyChar);
+    }
+    
+    @Override
+    public void sendKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) {
+        handleKeyEvent(true, false, eventType, modifiers, keyCode, keyChar);
     }
     
+    @Override
+    public void enqueueKeyEvent(boolean wait, int eventType, int modifiers, int keyCode, char keyChar) {
+        handleKeyEvent(false, wait, eventType, modifiers, keyCode, keyChar);
+    }
 
     //----------------------------------------------------------------------
     // Internals only
diff --git a/src/newt/classes/jogamp/newt/driver/windows/WindowsDisplay.java b/src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java
similarity index 94%
rename from src/newt/classes/jogamp/newt/driver/windows/WindowsDisplay.java
rename to src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java
index 225b115..615f9e6 100644
--- a/src/newt/classes/jogamp/newt/driver/windows/WindowsDisplay.java
+++ b/src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java
@@ -43,7 +43,7 @@ import javax.media.nativewindow.NativeWindowException;
 
 import com.jogamp.nativewindow.windows.WindowsGraphicsDevice;
 
-public class WindowsDisplay extends DisplayImpl {
+public class DisplayDriver extends DisplayImpl {
 
     private static final String newtClassBaseName = "_newt_clazz" ;
     private static RegisteredClassFactory sharedClassFactory;
@@ -51,10 +51,10 @@ public class WindowsDisplay extends DisplayImpl {
     static {
         NEWTJNILibLoader.loadNEWT();
 
-        if (!WindowsWindow.initIDs0()) {
+        if (!WindowDriver.initIDs0()) {
             throw new NativeWindowException("Failed to initialize WindowsWindow jmethodIDs");
         }        
-        sharedClassFactory = new RegisteredClassFactory(newtClassBaseName, WindowsWindow.getNewtWndProc0());
+        sharedClassFactory = new RegisteredClassFactory(newtClassBaseName, WindowDriver.getNewtWndProc0());
     }
 
     public static void initSingleton() {
@@ -63,7 +63,7 @@ public class WindowsDisplay extends DisplayImpl {
 
     private RegisteredClass sharedClass;
 
-    public WindowsDisplay() {
+    public DisplayDriver() {
     }
 
     protected void createNativeImpl() {
@@ -73,6 +73,7 @@ public class WindowsDisplay extends DisplayImpl {
 
     protected void closeNativeImpl() { 
         sharedClassFactory.releaseSharedClass();
+        aDevice.close();
     }
 
     protected void dispatchMessagesNative() {
diff --git a/src/newt/classes/jogamp/newt/driver/windows/WindowsScreen.java b/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java
similarity index 97%
rename from src/newt/classes/jogamp/newt/driver/windows/WindowsScreen.java
rename to src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java
index f8bce9d..948b294 100644
--- a/src/newt/classes/jogamp/newt/driver/windows/WindowsScreen.java
+++ b/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java
@@ -42,13 +42,13 @@ import jogamp.newt.ScreenImpl;
 import com.jogamp.newt.ScreenMode;
 import com.jogamp.newt.util.ScreenModeUtil;
 
-public class WindowsScreen extends ScreenImpl {
+public class ScreenDriver extends ScreenImpl {
 
     static {
-        WindowsDisplay.initSingleton();
+        DisplayDriver.initSingleton();
     }
 
-    public WindowsScreen() {
+    public ScreenDriver() {
     }
 
     protected void createNativeImpl() {
diff --git a/src/newt/classes/jogamp/newt/driver/windows/WindowsWindow.java b/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java
similarity index 74%
rename from src/newt/classes/jogamp/newt/driver/windows/WindowsWindow.java
rename to src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java
index 6a8c81f..6aac861 100644
--- a/src/newt/classes/jogamp/newt/driver/windows/WindowsWindow.java
+++ b/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java
@@ -46,11 +46,13 @@ import javax.media.nativewindow.util.Insets;
 import javax.media.nativewindow.util.InsetsImmutable;
 import javax.media.nativewindow.util.Point;
 
+import com.jogamp.common.util.IntIntHashMap;
+import com.jogamp.newt.event.InputEvent;
 import com.jogamp.newt.event.KeyEvent;
 import com.jogamp.newt.event.MouseAdapter;
 import com.jogamp.newt.event.MouseEvent;
 
-public class WindowsWindow extends WindowImpl {
+public class WindowDriver extends WindowImpl {
 
     private long hmon;
     private long hdc;
@@ -58,10 +60,10 @@ public class WindowsWindow extends WindowImpl {
     private long windowHandleClose;
 
     static {
-        WindowsDisplay.initSingleton();
+        DisplayDriver.initSingleton();
     }
 
-    public WindowsWindow() {
+    public WindowDriver() {
     }
 
     @Override
@@ -118,8 +120,8 @@ public class WindowsWindow extends WindowImpl {
     }
 
     protected void createNativeImpl() {
-        final WindowsScreen  screen = (WindowsScreen) getScreen();
-        final WindowsDisplay display = (WindowsDisplay) screen.getDisplay();
+        final ScreenDriver  screen = (ScreenDriver) getScreen();
+        final DisplayDriver display = (DisplayDriver) screen.getDisplay();
         final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(display.getGraphicsDevice(), capsRequested).chooseGraphicsConfiguration(
                 capsRequested, capsRequested, capabilitiesChooser, screen.getGraphicsScreen(), VisualIDHolder.VID_UNDEFINED);
         if (null == cfg) {
@@ -146,7 +148,7 @@ public class WindowsWindow extends WindowImpl {
     
     class MouseTracker extends MouseAdapter {
         public void mouseEntered(MouseEvent e) {
-            WindowsWindow.trackPointerLeave0(WindowsWindow.this.getWindowHandle());
+            WindowDriver.trackPointerLeave0(WindowDriver.this.getWindowHandle());
         }
     }
 
@@ -163,7 +165,6 @@ public class WindowsWindow extends WindowImpl {
                 }
             }
             try {
-                GDI.SetParent(windowHandleClose, 0); // detach first, experience hang w/ SWT parent
                 GDI.DestroyWindow(windowHandleClose);
             } catch (Throwable t) {
                 if(DEBUG_IMPLEMENTATION) {
@@ -259,34 +260,73 @@ public class WindowsWindow extends WindowImpl {
         // nop - using event driven insetsChange(..)         
     }
     
-    private final int validateKeyCode(int eventType, int keyCode) {
+    private final void emitKeyEvent(boolean send, boolean wait, int eventType, int modifiers, int keyCode, char keyChar) {
+        if( send ) {
+            super.sendKeyEvent(eventType, modifiers, keyCode, keyChar);
+        } else {
+            super.enqueueKeyEvent(wait, eventType, modifiers, keyCode, keyChar);
+        }
+    }
+    
+    /** FIXME: We have to store the keyChar for typed events, since keyChar from pressed/released may be wrong (Uppercase: SHIFT-1, etc ..). */
+    private IntIntHashMap typedKeyCode2KeyChar = new IntIntHashMap(KeyEvent.VK_CONTEXT_MENU+1); 
+
+    private final void handleKeyEvent(boolean send, boolean wait, int eventType, int modifiers, int keyCode, char keyChar) {
+        final boolean isModifierKeyCode = KeyEvent.isModifierKey(keyCode);
+        // System.err.println("*** handleKeyEvent: event "+KeyEvent.getEventTypeString(eventType)+", keyCode "+toHexString(keyCode)+", keyChar <"+keyChar+">, mods "+toHexString(modifiers)+", was: pressed "+isKeyPressed(keyCode)+", repeat "+isKeyInAutoRepeat(keyCode)+", isModifierKeyCode "+isModifierKeyCode);
+        
+        // Reorder: WINDOWS delivery order is PRESSED, TYPED and RELEASED -> NEWT order: PRESSED, RELEASED and TYPED
+        // Auto-Repeat: WINDOWS delivers only PRESSED and TYPED.        
         switch(eventType) {
+            case KeyEvent.EVENT_KEY_RELEASED:
+                if( isKeyCodeTracked(keyCode) ) {
+                    if( keyRepeatState.put(keyCode, false) && !isModifierKeyCode ) {
+                        // AR out - send out missing PRESSED
+                        emitKeyEvent(send, wait, KeyEvent.EVENT_KEY_PRESSED, modifiers | InputEvent.AUTOREPEAT_MASK, keyCode, keyChar);
+                    }
+                    keyPressedState.put(keyCode, false);
+                }
+                final int keyCharTyped = typedKeyCode2KeyChar.put(keyCode, 0);
+                if( 0 != keyCharTyped ) {
+                    keyChar = (char)keyCharTyped;
+                }
+                emitKeyEvent(send, wait, eventType, modifiers, keyCode, keyChar);
+                emitKeyEvent(send, wait, KeyEvent.EVENT_KEY_TYPED, modifiers, keyCode, keyChar);
+                break;
             case KeyEvent.EVENT_KEY_PRESSED:
-                lastPressedKeyCode = keyCode;
+                if( isKeyCodeTracked(keyCode) ) {
+                    if( keyPressedState.put(keyCode, true) ) {
+                        // key was already pressed
+                        if( keyRepeatState.put(keyCode, true) && !isModifierKeyCode ) {
+                            emitKeyEvent(send, wait, eventType, modifiers | InputEvent.AUTOREPEAT_MASK, keyCode, keyChar);
+                        } // else AR in - skip already send PRESSED ; or ALT
+                    } else {
+                        emitKeyEvent(send, wait, eventType, modifiers, keyCode, keyChar);
+                    }
+                } else {
+                    emitKeyEvent(send, wait, eventType, modifiers, keyCode, keyChar);
+                }
                 break;
             case KeyEvent.EVENT_KEY_TYPED:
-                if(-1==keyCode) {
-                    keyCode = lastPressedKeyCode;
+                if( 1 == isKeyInAutoRepeat(keyCode) ) {
+                    modifiers |= InputEvent.AUTOREPEAT_MASK;
+                    emitKeyEvent(send, wait, KeyEvent.EVENT_KEY_RELEASED, modifiers, keyCode, keyChar);
+                    emitKeyEvent(send, wait, eventType, modifiers, keyCode, keyChar);
+                } else if( 0 != keyCode ) {
+                    typedKeyCode2KeyChar.put(keyCode, keyChar);
                 }
-                lastPressedKeyCode = -1;
                 break;
         }
-        return keyCode;
     }
-    private int lastPressedKeyCode = 0;
     
     @Override
     public void sendKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) {
-        // Note that we have to regenerate the keyCode for EVENT_KEY_TYPED on this platform
-        keyCode = validateKeyCode(eventType, keyCode);
-        super.sendKeyEvent(eventType, modifiers, keyCode, keyChar);        
+        handleKeyEvent(true, false, eventType, modifiers, keyCode, keyChar);
     }
     
     @Override
     public void enqueueKeyEvent(boolean wait, int eventType, int modifiers, int keyCode, char keyChar) {
-        // Note that we have to regenerate the keyCode for EVENT_KEY_TYPED on this platform
-        keyCode = validateKeyCode(eventType, keyCode);
-        super.enqueueKeyEvent(wait, eventType, modifiers, keyCode, keyChar);
+        handleKeyEvent(false, wait, eventType, modifiers, keyCode, keyChar);
     }
     
     //----------------------------------------------------------------------
diff --git a/src/newt/classes/jogamp/newt/driver/x11/X11Display.java b/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java
similarity index 61%
rename from src/newt/classes/jogamp/newt/driver/x11/X11Display.java
rename to src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java
index 8243fcf..f3a548a 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/X11Display.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java
@@ -36,7 +36,6 @@ package jogamp.newt.driver.x11;
 
 import javax.media.nativewindow.AbstractGraphicsDevice;
 import javax.media.nativewindow.NativeWindowException;
-import javax.media.nativewindow.NativeWindowFactory;
 
 import com.jogamp.nativewindow.x11.X11GraphicsDevice;
 
@@ -44,7 +43,7 @@ import jogamp.nativewindow.x11.X11Util;
 import jogamp.newt.DisplayImpl;
 import jogamp.newt.NEWTJNILibLoader;
 
-public class X11Display extends DisplayImpl {
+public class DisplayDriver extends DisplayImpl {
 
     static {
         NEWTJNILibLoader.loadNEWT();
@@ -53,7 +52,7 @@ public class X11Display extends DisplayImpl {
             throw new NativeWindowException("Failed to initialize X11Display jmethodIDs");
         }
 
-        if (!X11Window.initIDs0()) {
+        if (!WindowDriver.initIDs0()) {
             throw new NativeWindowException("Failed to initialize X11Window jmethodIDs");
         }
     }
@@ -63,7 +62,7 @@ public class X11Display extends DisplayImpl {
     }
 
 
-    public X11Display() {
+    public DisplayDriver() {
     }
 
     public String validateDisplayName(String name, long handle) {
@@ -74,71 +73,55 @@ public class X11Display extends DisplayImpl {
      * {@inheritDoc}
      *
      * We use a private non-shared X11 Display instance for EDT window operations and one for exposed animation, eg. OpenGL.
-     * <p>
-     * In case {@link X11Util#HAS_XLOCKDISPLAY_BUG} and {@link X11Util#XINITTHREADS_ALWAYS_ENABLED}, 
-     * we use null locking. Even though this seems not to be rational, it gives most stable results on all platforms.
-     * </p>
-     * <p>
-     * Otherwise we use basic locking via the constructor {@link X11GraphicsDevice#X11GraphicsDevice(long, int, boolean)},
-     * since it is possible to share this device via {@link com.jogamp.newt.NewtFactory#createDisplay(String, boolean)}.
-     * </p> 
      */
-    @SuppressWarnings("unused")
     protected void createNativeImpl() {
+        X11Util.setX11ErrorHandler(true, DEBUG ? false : true); // make sure X11 error handler is set
         long handle = X11Util.openDisplay(name);
         if( 0 == handle ) {
             throw new RuntimeException("Error creating display(Win): "+name);
         }
-        if(USE_SEPARATE_DISPLAY_FOR_EDT) {
-            edtDisplayHandle = X11Util.openDisplay(name);
-            if( 0 == edtDisplayHandle ) {
-                X11Util.closeDisplay(handle);
-                throw new RuntimeException("Error creating display(EDT): "+name);
-            }
-        } else {
-            edtDisplayHandle = handle;
-        }
+        aDevice = new X11GraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_UNIT, true /* owner */);
         try {
-            CompleteDisplay0(edtDisplayHandle);
+            CompleteDisplay0(aDevice.getHandle());
         } catch(RuntimeException e) {
             closeNativeImpl();
-            throw e;
-        }
-        
-        // see API doc above!
-        if(X11Util.XINITTHREADS_ALWAYS_ENABLED && X11Util.HAS_XLOCKDISPLAY_BUG) {
-            aDevice = new X11GraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_UNIT, NativeWindowFactory.getNullToolkitLock(), false);            
-        } else {
-            aDevice = new X11GraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_UNIT, false);
+            throw e;                
         }
     }
 
+    @Override
     protected void closeNativeImpl() {
-        DisplayRelease0(edtDisplayHandle, javaObjectAtom, windowDeleteAtom);
+        DisplayRelease0(aDevice.getHandle(), javaObjectAtom, windowDeleteAtom);
         javaObjectAtom = 0;
         windowDeleteAtom = 0;
-        // closing using ATI driver bug 'same order'
-        final long handle = getHandle();
-        X11Util.closeDisplay(handle);
-        if(handle != edtDisplayHandle) {
-            X11Util.closeDisplay(edtDisplayHandle);
-        }
-        edtDisplayHandle = 0;
+        aDevice.close(); // closes X11 display
     }
 
+    @Override
     protected void dispatchMessagesNative() {
-        if(0 != edtDisplayHandle) {
-            DispatchMessages0(edtDisplayHandle, javaObjectAtom, windowDeleteAtom);
+        aDevice.lock();
+        try {
+            final long handle = aDevice.getHandle();
+            if(0 != handle) {
+                DispatchMessages0(handle, javaObjectAtom, windowDeleteAtom);
+            }
+        } finally {
+            if(null != aDevice) { // could be pulled by destroy event
+                aDevice.unlock();
+            }
         }
     }
 
-    protected long getEDTHandle() { return edtDisplayHandle; }
     protected long getJavaObjectAtom() { return javaObjectAtom; }
     protected long getWindowDeleteAtom() { return windowDeleteAtom; }
     
+    /** 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; }
+    
     //----------------------------------------------------------------------
     // Internals only
     //
+    
     private static native boolean initIDs0(boolean debug);
 
     private native void CompleteDisplay0(long handle);
@@ -151,21 +134,10 @@ public class X11Display extends DisplayImpl {
 
     private native void DispatchMessages0(long display, long javaObjectAtom, long windowDeleteAtom);
 
-    /**
-     * 2011/06/14 libX11 1.4.2 and libxcb 1.7 bug 20708 - Multithreading Issues w/ OpenGL, ..
-     *            https://bugs.freedesktop.org/show_bug.cgi?id=20708
-     *            https://jogamp.org/bugzilla/show_bug.cgi?id=502
-     *            Affects: Ubuntu 11.04, OpenSuSE 11, ..
-     *            Workaround: Using a separate X11 Display connection for event dispatching (EDT)
-     */    
-    private final boolean USE_SEPARATE_DISPLAY_FOR_EDT = true;
-    
-    private long edtDisplayHandle;
-    
     /** X11 Window delete atom marker used on EDT */
     private long windowDeleteAtom;
     
     /** X11 Window java object property used on EDT */
-    private long javaObjectAtom;
+    private long javaObjectAtom;    
 }
 
diff --git a/src/newt/classes/jogamp/newt/driver/x11/X11Screen.java b/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java
similarity index 91%
rename from src/newt/classes/jogamp/newt/driver/x11/X11Screen.java
rename to src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java
index 93db854..7a3c718 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/X11Screen.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java
@@ -48,18 +48,18 @@ import com.jogamp.nativewindow.x11.X11GraphicsScreen;
 import com.jogamp.newt.ScreenMode;
 import com.jogamp.newt.util.ScreenModeUtil;
 
-public class X11Screen extends ScreenImpl {
+public class ScreenDriver extends ScreenImpl {
 
     static {
-        X11Display.initSingleton();
+        DisplayDriver.initSingleton();
     }
 
-    public X11Screen() {
+    public ScreenDriver() {
     }
 
     protected void createNativeImpl() {
         // validate screen index
-        Long handle = display.runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<Long>() {
+        Long handle = runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Long>() {
             public Long run(long dpy) {        
                 return new Long(GetScreen0(dpy, screen_idx));
             } } );        
@@ -81,7 +81,7 @@ public class X11Screen extends ScreenImpl {
     private int nmode_number;
 
     protected int[] getScreenModeFirstImpl() {
-        return runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<int[]>() {
+        return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<int[]>() {
             public int[] run(long dpy) {
                 // initialize iterators and static data
                 nrotations = getAvailableScreenModeRotations0(dpy, screen_idx);
@@ -110,7 +110,7 @@ public class X11Screen extends ScreenImpl {
 
     protected int[] getScreenModeNextImpl() {
         // assemble: w x h x bpp x f x r        
-        return runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<int[]>() {
+        return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<int[]>() {
             public int[] run(long dpy) {
                 /**
                 System.err.println("******** mode: "+nmode_number);
@@ -176,7 +176,7 @@ public class X11Screen extends ScreenImpl {
     }
 
     protected ScreenMode getCurrentScreenModeImpl() {
-        return runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<ScreenMode>() {
+        return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<ScreenMode>() {
             public ScreenMode run(long dpy) {
                 long screenConfigHandle = getScreenConfiguration0(dpy, screen_idx);
                 if(0 == screenConfigHandle) {
@@ -237,7 +237,7 @@ public class X11Screen extends ScreenImpl {
             throw new RuntimeException("ScreenMode not element of ScreenMode list: "+screenMode);
         }
         final long t0 = System.currentTimeMillis();
-        boolean done = runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<Boolean>() {
+        boolean done = runWithTempDisplayHandle( new DisplayImpl.DisplayRunnable<Boolean>() {
             public Boolean run(long dpy) {
                 boolean done = false;
                 long screenConfigHandle = getScreenConfiguration0(dpy, screen_idx);
@@ -276,23 +276,23 @@ public class X11Screen extends ScreenImpl {
         return done;
     }
 
-    private class XineramaEnabledQuery implements DisplayImpl.DisplayRunnable<Boolean> {
+    private DisplayImpl.DisplayRunnable<Boolean> xineramaEnabledQueryWithTemp = new DisplayImpl.DisplayRunnable<Boolean>() {
         public Boolean run(long dpy) {        
             return new Boolean(X11Util.XineramaIsEnabled(dpy)); 
-        }        
-    }
-    private XineramaEnabledQuery xineramaEnabledQuery = new XineramaEnabledQuery();
+        } };
     
     protected int validateScreenIndex(final int idx) {
-        if(getDisplay().isNativeValid()) {
-            return runWithLockedDisplayHandle( xineramaEnabledQuery ).booleanValue() ? 0 : idx;
+        final DisplayDriver x11Display = (DisplayDriver) getDisplay();
+        final Boolean r = x11Display.isXineramaEnabled();
+        if( null != r ) {
+            return r.booleanValue() ? 0 : idx;
         } else {
-            return runWithTempDisplayHandle( xineramaEnabledQuery ).booleanValue() ? 0 : idx;
+            return runWithTempDisplayHandle( xineramaEnabledQueryWithTemp ).booleanValue() ? 0 : idx;
         }
     }
         
     protected void getVirtualScreenOriginAndSize(final Point virtualOrigin, final Dimension virtualSize) {
-        display.runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<Object>() {
+        runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Object>() {
             public Object run(long dpy) {
                 virtualOrigin.setX(0);
                 virtualOrigin.setY(0);
@@ -305,10 +305,8 @@ public class X11Screen extends ScreenImpl {
     //----------------------------------------------------------------------
     // Internals only
     //    
-    private final <T> T runWithLockedDisplayHandle(DisplayRunnable<T> action) {
-        return display.runWithLockedDisplayHandle(action);
-        // return runWithTempDisplayHandle(action);
-        // return runWithoutLock(action);
+    private final <T> T runWithLockedDisplayDevice(DisplayRunnable<T> action) {
+        return display.runWithLockedDisplayDevice(action);
     }
     
     private final <T> T runWithTempDisplayHandle(DisplayRunnable<T> action) {
@@ -324,9 +322,6 @@ public class X11Screen extends ScreenImpl {
         }
         return res;
     }
-    private final <T> T runWithoutLock(DisplayRunnable<T> action) {
-        return action.run(display.getHandle());
-    }
     
     private static native long GetScreen0(long dpy, int scrn_idx);
 
diff --git a/src/newt/classes/jogamp/newt/driver/x11/X11Window.java b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java
similarity index 68%
rename from src/newt/classes/jogamp/newt/driver/x11/X11Window.java
rename to src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java
index 5501f5a..c21cb4b 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/X11Window.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java
@@ -35,6 +35,7 @@
 package jogamp.newt.driver.x11;
 
 import jogamp.nativewindow.x11.X11Lib;
+import jogamp.nativewindow.x11.X11Util;
 import jogamp.newt.DisplayImpl;
 import jogamp.newt.DisplayImpl.DisplayRunnable;
 import jogamp.newt.WindowImpl;
@@ -44,28 +45,40 @@ import javax.media.nativewindow.util.Insets;
 import javax.media.nativewindow.util.InsetsImmutable;
 import javax.media.nativewindow.util.Point;
 
+import com.jogamp.nativewindow.x11.X11GraphicsDevice;
+import com.jogamp.nativewindow.x11.X11GraphicsScreen;
 import com.jogamp.newt.event.MouseEvent;
 
-public class X11Window extends WindowImpl {
+public class WindowDriver extends WindowImpl {
     private static final String WINDOW_CLASS_NAME = "NewtWindow";
-    private static final int X11_WHEEL_ONE_UP_BUTTON = 4;
+    private static final int X11_WHEEL_ONE_UP_BUTTON   = 4;
     private static final int X11_WHEEL_ONE_DOWN_BUTTON = 5;
-    private static final int X11_WHEEL_TWO_UP_BUTTON = 6;
+    private static final int X11_WHEEL_TWO_UP_BUTTON   = 6;
     private static final int X11_WHEEL_TWO_DOWN_BUTTON = 7;
     
     static {
-        X11Display.initSingleton();
+        DisplayDriver.initSingleton();
     }
 
-    public X11Window() {
+    public WindowDriver() {
     }
 
     protected void createNativeImpl() {
-        final X11Screen screen = (X11Screen) getScreen();
-        final X11Display display = (X11Display) screen.getDisplay();
+        final ScreenDriver screen = (ScreenDriver) getScreen();
+        final DisplayDriver display = (DisplayDriver) screen.getDisplay();
+        final AbstractGraphicsDevice edtDevice = display.getGraphicsDevice();
+        
+        // Decoupled X11 Device/Screen allowing X11 display lock-free off-thread rendering 
+        final long renderDeviceHandle = X11Util.openDisplay(edtDevice.getConnection());
+        if( 0 == renderDeviceHandle ) {
+            throw new RuntimeException("Error creating display(EDT): "+edtDevice.getConnection());
+        }
+        renderDevice = new X11GraphicsDevice(renderDeviceHandle, AbstractGraphicsDevice.DEFAULT_UNIT, true /* owner */);
+        final AbstractGraphicsScreen renderScreen = new X11GraphicsScreen(renderDevice, screen.getIndex());
+        
         final GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(display.getGraphicsDevice(), capsRequested);
         final AbstractGraphicsConfiguration cfg = factory.chooseGraphicsConfiguration(
-                capsRequested, capsRequested, capabilitiesChooser, screen.getGraphicsScreen(), VisualIDHolder.VID_UNDEFINED);
+                capsRequested, capsRequested, capabilitiesChooser, renderScreen, VisualIDHolder.VID_UNDEFINED);
         if(DEBUG_IMPLEMENTATION) {
             System.err.println("X11Window.createNativeImpl() factory: "+factory+", chosen config: "+cfg);
         }        
@@ -78,11 +91,16 @@ public class X11Window extends WindowImpl {
         }
         setGraphicsConfiguration(cfg);
         final int flags = getReconfigureFlags(0, true) & 
-                          ( FLAG_IS_ALWAYSONTOP | FLAG_IS_UNDECORATED ) ;        
-        setWindowHandle(CreateWindow0(getParentWindowHandle(),
-                               display.getEDTHandle(), screen.getIndex(), visualID, 
-                               display.getJavaObjectAtom(), display.getWindowDeleteAtom(), 
-                               getX(), getY(), getWidth(), getHeight(), autoPosition(), flags));
+                          ( FLAG_IS_ALWAYSONTOP | FLAG_IS_UNDECORATED ) ;
+        edtDevice.lock();
+        try {        
+            setWindowHandle(CreateWindow0(getParentWindowHandle(),
+                                   edtDevice.getHandle(), screen.getIndex(), visualID, 
+                                   display.getJavaObjectAtom(), display.getWindowDeleteAtom(), 
+                                   getX(), getY(), getWidth(), getHeight(), autoPosition(), flags));
+        } finally {
+            edtDevice.unlock();
+        }
         windowHandleClose = getWindowHandle();
         if (0 == windowHandleClose) {
             throw new NativeWindowException("Error creating window");
@@ -91,9 +109,11 @@ public class X11Window extends WindowImpl {
 
     protected void closeNativeImpl() {
         if(0!=windowHandleClose && null!=getScreen() ) {
-            X11Display display = (X11Display) getScreen().getDisplay();
+            DisplayDriver display = (DisplayDriver) getScreen().getDisplay();
+            final AbstractGraphicsDevice edtDevice = display.getGraphicsDevice();
+            edtDevice.lock();
             try {
-                CloseWindow0(display.getEDTHandle(), windowHandleClose, 
+                CloseWindow0(edtDevice.getHandle(), windowHandleClose, 
                              display.getJavaObjectAtom(), display.getWindowDeleteAtom());
             } catch (Throwable t) {
                 if(DEBUG_IMPLEMENTATION) { 
@@ -101,28 +121,47 @@ public class X11Window extends WindowImpl {
                     e.printStackTrace();
                 }
             } finally {
+                edtDevice.unlock();
                 windowHandleClose = 0;
             }
         }
+        if(null != renderDevice) {
+            renderDevice.close(); // closes X11 display
+            renderDevice = null;
+        }
     }
 
-    protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) { 
+    @Override
+    public long getDisplayHandle() {
+        // Actually: return getGraphicsConfiguration().getScreen().getDevice().getHandle();
+        return renderDevice.getHandle(); // shortcut
+    }
+    
+    protected boolean reconfigureWindowImpl(final int x, final int y, final int width, final int height, final 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();         
             
             // client position -> top-level window position
-            x -= i.getLeftWidth() ;
-            y -= i.getTopHeight() ;
+            _x = x - i.getLeftWidth() ;
+            _y = y - i.getTopHeight() ;
+        } else {
+            _x = x;
+            _y = y;
         }
-        final X11Display display = (X11Display) getScreen().getDisplay();
-        reconfigureWindow0( getDisplayEDTHandle(), getScreenIndex(), 
-                            getParentWindowHandle(), getWindowHandle(), display.getWindowDeleteAtom(),
-                            x, y, width, height, flags);
-
+        final DisplayDriver display = (DisplayDriver) getScreen().getDisplay();
+        runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Object>() {
+            public Object run(long dpy) {
+                reconfigureWindow0( dpy, getScreenIndex(), 
+                                    getParentWindowHandle(), getWindowHandle(), display.getWindowDeleteAtom(),
+                                    _x, _y, width, height, flags);
+                return null;
+            }
+        });
         return true;
     }
 
@@ -133,13 +172,18 @@ public class X11Window extends WindowImpl {
         }
     }
     
-    protected void requestFocusImpl(boolean force) {
-        requestFocus0(getDisplayEDTHandle(), getWindowHandle(), force);
+    protected void requestFocusImpl(final boolean force) {        
+        runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Object>() {
+            public Object run(long dpy) {
+                requestFocus0(dpy, getWindowHandle(), force);
+                return null;
+            }
+        });
     }
 
     @Override
     protected void setTitleImpl(final String title) {
-        runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<Object>() {
+        runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Object>() {
             public Object run(long dpy) {
                 setTitle0(dpy, getWindowHandle(), title);
                 return null;
@@ -149,35 +193,38 @@ public class X11Window extends WindowImpl {
     
     @Override
     protected boolean setPointerVisibleImpl(final boolean pointerVisible) {
-        return runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<Boolean>() {
+        return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Boolean>() {
             public Boolean run(long dpy) {
-                return Boolean.valueOf(setPointerVisible0(getDisplayEDTHandle(), getWindowHandle(), pointerVisible));
+                return Boolean.valueOf(setPointerVisible0(dpy, getWindowHandle(), pointerVisible));
             }
         }).booleanValue();
     }
 
     @Override
     protected boolean confinePointerImpl(final boolean confine) {
-        return runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<Boolean>() {
+        return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Boolean>() {
             public Boolean run(long dpy) {
-                return Boolean.valueOf(confinePointer0(getDisplayEDTHandle(), getWindowHandle(), confine));
+                return Boolean.valueOf(confinePointer0(dpy, getWindowHandle(), confine));
             }
         }).booleanValue();
     }
     
     @Override
     protected void warpPointerImpl(final int x, final int y) {
-        runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<Object>() {
+        runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Object>() {
             public Object run(long dpy) {
-                warpPointer0(getDisplayEDTHandle(), getWindowHandle(), x, y);
+                warpPointer0(dpy, getWindowHandle(), x, y);
                 return null;
             }
         });
     }
     
     protected Point getLocationOnScreenImpl(final int x, final int y) {
-        // X11Util.GetRelativeLocation: locks display already !
-        return X11Lib.GetRelativeLocation( getScreen().getDisplay().getHandle(), getScreenIndex(), getWindowHandle(), 0 /*root win*/, x, y);
+        return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Point>() {
+            public Point run(long dpy) {
+                return X11Lib.GetRelativeLocation(dpy, getScreenIndex(), getWindowHandle(), 0 /*root win*/, x, y);
+            }
+        } );
     }
 
     protected void updateInsetsImpl(Insets insets) {
@@ -229,16 +276,11 @@ public class X11Window extends WindowImpl {
     //----------------------------------------------------------------------
     // Internals only
     //
-    
     private static final String getCurrentThreadName() { return Thread.currentThread().getName(); } // Callback for JNI
     private static final void dumpStack() { Thread.dumpStack(); } // Callback for JNI
     
-    private final long getDisplayEDTHandle() {
-        return ((X11Display) getScreen().getDisplay()).getEDTHandle();
-    }
-    private final <T> T runWithLockedDisplayHandle(DisplayRunnable<T> action) {
-        return ((DisplayImpl) getScreen().getDisplay()).runWithLockedDisplayHandle(action);
-        // return runWithTempDisplayHandle(action);
+    private final <T> T runWithLockedDisplayDevice(DisplayRunnable<T> action) {
+        return ((DisplayDriver) getScreen().getDisplay()).runWithLockedDisplayDevice(action);
     }
 
     protected static native boolean initIDs0();
@@ -258,4 +300,5 @@ public class X11Window extends WindowImpl {
     private static native void warpPointer0(long display, long windowHandle, int x, int y);
     
     private long   windowHandleClose;
+    private X11GraphicsDevice renderDevice;    
 }
diff --git a/src/newt/native/AndroidWindow.c b/src/newt/native/AndroidWindow.c
index fa57656..94695e1 100644
--- a/src/newt/native/AndroidWindow.c
+++ b/src/newt/native/AndroidWindow.c
@@ -9,7 +9,7 @@
 #include <unistd.h>
 #include <errno.h>
 
-#include "jogamp_newt_driver_android_AndroidWindow.h"
+#include "jogamp_newt_driver_android_WindowDriver.h"
 
 #include <android/native_window.h>
 #include <android/native_window_jni.h>
@@ -23,56 +23,56 @@
 #endif
 
 
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_android_AndroidWindow_getSurfaceHandle0
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_android_WindowDriver_getSurfaceHandle0
     (JNIEnv *env, jclass clazz, jobject surface)
 {
     ANativeWindow * anw = ANativeWindow_fromSurface(env, surface);
     return (jlong) (intptr_t) anw;
 }
 
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_android_AndroidWindow_getSurfaceVisualID0
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_android_WindowDriver_getSurfaceVisualID0
     (JNIEnv *env, jclass clazz, jlong surfaceHandle)
 {
     ANativeWindow * anw = (ANativeWindow *) (intptr_t) surfaceHandle;
     return (jint) ANativeWindow_getFormat(anw);
 }
 
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_android_AndroidWindow_setSurfaceVisualID0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_android_WindowDriver_setSurfaceVisualID0
     (JNIEnv *env, jclass clazz, jlong surfaceHandle, jint nativeVisualID)
 {
     ANativeWindow * anw = (ANativeWindow *) (intptr_t) surfaceHandle;
     ANativeWindow_setBuffersGeometry(anw, 0, 0, nativeVisualID);
 }
 
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_android_AndroidWindow_getWidth0
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_android_WindowDriver_getWidth0
     (JNIEnv *env, jclass clazz, jlong surfaceHandle)
 {
     ANativeWindow * anw = (ANativeWindow *) (intptr_t) surfaceHandle;
     return (jint) ANativeWindow_getWidth(anw);
 }
 
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_android_AndroidWindow_getHeight0
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_android_WindowDriver_getHeight0
     (JNIEnv *env, jclass clazz, jlong surfaceHandle)
 {
     ANativeWindow * anw = (ANativeWindow *) (intptr_t) surfaceHandle;
     return (jint) ANativeWindow_getHeight(anw);
 }
 
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_android_AndroidWindow_acquire0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_android_WindowDriver_acquire0
     (JNIEnv *env, jclass clazz, jlong surfaceHandle)
 {
     ANativeWindow * anw = (ANativeWindow *) (intptr_t) surfaceHandle;
     ANativeWindow_acquire(anw);
 }
 
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_android_AndroidWindow_release0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_android_WindowDriver_release0
     (JNIEnv *env, jclass clazz, jlong surfaceHandle)
 {
     ANativeWindow * anw = (ANativeWindow *) (intptr_t) surfaceHandle;
     ANativeWindow_release(anw);
 }
 
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_android_AndroidWindow_initIDs0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_android_WindowDriver_initIDs0
   (JNIEnv *env, jclass clazz)
 {
     DBG_PRINT( "initIDs ok\n" );
diff --git a/src/newt/native/InputEvent.h b/src/newt/native/InputEvent.h
index b42c06d..3fa7dbe 100644
--- a/src/newt/native/InputEvent.h
+++ b/src/newt/native/InputEvent.h
@@ -34,13 +34,24 @@
 #ifndef _INPUT_EVENT_H_
 #define _INPUT_EVENT_H_
 
-#define EVENT_SHIFT_MASK      1
-#define EVENT_CTRL_MASK       2
-#define EVENT_META_MASK       4
-#define EVENT_ALT_MASK        8
-#define EVENT_ALT_GRAPH_MASK 32
-#define EVENT_BUTTON1_MASK   (1<<6)
-#define EVENT_BUTTON2_MASK   (1<<7)
-#define EVENT_BUTTON3_MASK   (1<<8)
+#define EVENT_SHIFT_MASK      (1 <<  0)
+#define EVENT_CTRL_MASK       (1 <<  1)
+#define EVENT_META_MASK       (1 <<  2)
+#define EVENT_ALT_MASK        (1 <<  3)
+#define EVENT_ALT_GRAPH_MASK  (1 <<  4)
+
+#define EVENT_BUTTON1_MASK    (1 <<  5)
+#define EVENT_BUTTON2_MASK    (1 <<  6)
+#define EVENT_BUTTON3_MASK    (1 <<  7)
+#define EVENT_BUTTON4_MASK    (1 <<  8)
+#define EVENT_BUTTON5_MASK    (1 <<  9)
+#define EVENT_BUTTON6_MASK    (1 << 10)
+#define EVENT_BUTTON7_MASK    (1 << 11)
+#define EVENT_BUTTON8_MASK    (1 << 12)
+#define EVENT_BUTTON9_MASK    (1 << 13)
+
+#define EVENT_AUTOREPEAT_MASK (1 << 29)
+#define EVENT_CONFINED_MASK   (1 << 30)
+#define EVENT_INVISIBLE_MASK  (1 << 31)
 
 #endif
diff --git a/src/newt/native/IntelGDL.c b/src/newt/native/IntelGDL.c
index 690e112..a3bf101 100644
--- a/src/newt/native/IntelGDL.c
+++ b/src/newt/native/IntelGDL.c
@@ -37,9 +37,9 @@
 #include <stdio.h>
 #include <string.h>
 
-#include "jogamp_newt_driver_intel_gdl_Display.h"
-#include "jogamp_newt_driver_intel_gdl_Screen.h"
-#include "jogamp_newt_driver_intel_gdl_Window.h"
+#include "jogamp_newt_driver_intel_gdl_DisplayDriver.h"
+#include "jogamp_newt_driver_intel_gdl_ScreenDriver.h"
+#include "jogamp_newt_driver_intel_gdl_WindowDriver.h"
 
 #include "MouseEvent.h"
 #include "KeyEvent.h"
@@ -122,7 +122,7 @@ static void JNI_ThrowNew(JNIEnv *env, const char *throwable, const char* message
  * Display
  */
 
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_Display_DispatchMessages
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_DisplayDriver_DispatchMessages
   (JNIEnv *env, jobject obj, jlong displayHandle, jobject focusedWindow)
 {
     // FIXME: n/a
@@ -137,7 +137,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_Display_DispatchMessage
     } */
 }
 
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_intel_gdl_Display_CreateDisplay
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_intel_gdl_DisplayDriver_CreateDisplay
   (JNIEnv *env, jobject obj)
 {
     gdl_ret_t retval;
@@ -170,7 +170,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_intel_gdl_Display_CreateDisplay
     return (jlong) (intptr_t) p_driver_info;
 }
 
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_Display_DestroyDisplay
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_DisplayDriver_DestroyDisplay
   (JNIEnv *env, jobject obj, jlong displayHandle)
 {
     gdl_driver_info_t * p_driver_info = (gdl_driver_info_t *) (intptr_t) displayHandle;
@@ -189,7 +189,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_Display_DestroyDisplay
  * Screen
  */
 
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_intel_gdl_Screen_initIDs
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_intel_gdl_ScreenDriver_initIDs
   (JNIEnv *env, jclass clazz)
 {
     screenCreatedID = (*env)->GetMethodID(env, clazz, "screenCreated", "(II)V");
@@ -201,7 +201,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_intel_gdl_Screen_initIDs
     return JNI_TRUE;
 }
 
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_Screen_GetScreenInfo
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_ScreenDriver_GetScreenInfo
   (JNIEnv *env, jobject obj, jlong displayHandle, jint idx)
 {
     gdl_driver_info_t * p_driver_info = (gdl_driver_info_t *) (intptr_t) displayHandle;
@@ -233,7 +233,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_Screen_GetScreenInfo
  * Window
  */
 
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_intel_gdl_Window_initIDs
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_intel_gdl_WindowDriver_initIDs
   (JNIEnv *env, jclass clazz)
 {
     updateBoundsID = (*env)->GetMethodID(env, clazz, "updateBounds", "(IIII)V");
@@ -245,7 +245,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_intel_gdl_Window_initIDs
     return JNI_TRUE;
 }
 
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_intel_gdl_Window_CreateSurface
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_intel_gdl_WindowDriver_CreateSurface
   (JNIEnv *env, jobject obj, jlong displayHandle, jint scr_width, jint scr_height, jint x, jint y, jint width, jint height) {
 
     gdl_driver_info_t * p_driver_info = (gdl_driver_info_t *) (intptr_t) displayHandle;
@@ -338,7 +338,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_intel_gdl_Window_CreateSurface
     return (jlong) (intptr_t) plane;
 }
 
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_Window_CloseSurface
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_WindowDriver_CloseSurface
   (JNIEnv *env, jobject obj, jlong display, jlong surface)
 {
     gdl_plane_id_t plane = (gdl_plane_id_t) (intptr_t) surface ;
@@ -347,7 +347,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_Window_CloseSurface
     DBG_PRINT("[CloseSurface] plane %d\n", plane);
 }
 
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_Window_SetBounds0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_WindowDriver_SetBounds0
   (JNIEnv *env, jobject obj, jlong surface, jint scr_width, jint scr_height, jint x, jint y, jint width, jint height) {
 
     gdl_plane_id_t plane = (gdl_plane_id_t) (intptr_t) surface ;
diff --git a/src/newt/native/KDWindow.c b/src/newt/native/KDWindow.c
index 5afe6fc..f1d6aec 100644
--- a/src/newt/native/KDWindow.c
+++ b/src/newt/native/KDWindow.c
@@ -44,7 +44,7 @@
 #include <KD/kd.h>
 #include <EGL/egl.h>
 
-#include "jogamp_newt_driver_kd_KDWindow.h"
+#include "jogamp_newt_driver_kd_WindowDriver.h"
 
 #include "MouseEvent.h"
 #include "KeyEvent.h"
@@ -82,7 +82,7 @@ static jmethodID sendKeyEventID = NULL;
  * Display
  */
 
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_KDDisplay_DispatchMessages
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_DisplayDriver_DispatchMessages
   (JNIEnv *env, jobject obj)
 {
     const KDEvent * evt;
@@ -180,7 +180,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_KDDisplay_DispatchMessages
  * Window
  */
 
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_kd_KDWindow_initIDs
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_kd_WindowDriver_initIDs
   (JNIEnv *env, jclass clazz)
 {
 #ifdef VERBOSE_ON
@@ -208,7 +208,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_kd_KDWindow_initIDs
     return JNI_TRUE;
 }
 
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_kd_KDWindow_CreateWindow
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_kd_WindowDriver_CreateWindow
   (JNIEnv *env, jobject obj, jlong display, jlong jeglConfig)
 {
     EGLDisplay dpy  = (EGLDisplay)(intptr_t)display;
@@ -236,7 +236,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_kd_KDWindow_CreateWindow
     return (jlong) (intptr_t) window;
 }
 
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_kd_KDWindow_RealizeWindow
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_kd_WindowDriver_RealizeWindow
   (JNIEnv *env, jobject obj, jlong window)
 {
     KDWindow *w = (KDWindow*) (intptr_t) window;
@@ -251,7 +251,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_kd_KDWindow_RealizeWindow
     return (jlong) (intptr_t) nativeWindow;
 }
 
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_kd_KDWindow_CloseWindow
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_kd_WindowDriver_CloseWindow
   (JNIEnv *env, jobject obj, jlong window, jlong juserData)
 {
     KDWindow *w = (KDWindow*) (intptr_t) window;
@@ -265,11 +265,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_kd_KDWindow_CloseWindow
 }
 
 /*
- * Class:     jogamp_newt_driver_kd_KDWindow
+ * Class:     jogamp_newt_driver_kd_WindowDriver
  * Method:    setVisible0
  * Signature: (JJZ)V
  */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_KDWindow_setVisible0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_WindowDriver_setVisible0
   (JNIEnv *env, jobject obj, jlong window, jboolean visible)
 {
     KDWindow *w = (KDWindow*) (intptr_t) window;
@@ -279,7 +279,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_KDWindow_setVisible0
     (*env)->CallVoidMethod(env, obj, visibleChangedID, JNI_FALSE, visible); // FIXME: or defer=true ?
 }
 
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_KDWindow_setFullScreen0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_WindowDriver_setFullScreen0
   (JNIEnv *env, jobject obj, jlong window, jboolean fullscreen)
 {
 /** not supported, due to missing NV property ..
@@ -296,7 +296,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_KDWindow_setFullScreen0
     (void)fullscreen;
 }
 
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_KDWindow_setSize0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_WindowDriver_setSize0
   (JNIEnv *env, jobject obj, jlong window, jint width, jint height)
 {
     KDWindow *w = (KDWindow*) (intptr_t) window;
diff --git a/src/newt/native/MacWindow.m b/src/newt/native/MacWindow.m
index bbadc9d..b9c3392 100644
--- a/src/newt/native/MacWindow.m
+++ b/src/newt/native/MacWindow.m
@@ -33,7 +33,7 @@
 
 #import <inttypes.h>
 
-#import "jogamp_newt_driver_macosx_MacWindow.h"
+#import "jogamp_newt_driver_macosx_WindowDriver.h"
 #import "NewtMacWindow.h"
 
 #import "MouseEvent.h"
@@ -94,7 +94,13 @@ static void changeContentView(JNIEnv *env, jobject javaWindowObject, NSView *pvi
     if(NULL!=oldNSView) {
 NS_DURING
         // Available >= 10.5 - Makes the menubar disapear
-        if([oldNSView isInFullScreenMode]) {
+        BOOL iifs;
+        if ( [oldNSView respondsToSelector:@selector(isInFullScreenMode)] ) {
+            iifs = [oldNSView isInFullScreenMode];
+        } else {
+            iifs = NO;
+        }
+        if(iifs && [oldNSView respondsToSelector:@selector(exitFullScreenModeWithOptions:)] ) {
             [oldNSView exitFullScreenModeWithOptions: NULL];
         }
 NS_HANDLER
@@ -155,11 +161,11 @@ NS_ENDHANDLER
 }
 
 /*
- * Class:     jogamp_newt_driver_macosx_MacDisplay
+ * Class:     jogamp_newt_driver_macosx_DisplayDriver
  * Method:    initIDs
  * Signature: ()Z
  */
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacDisplay_initNSApplication0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_DisplayDriver_initNSApplication0
   (JNIEnv *env, jclass clazz)
 {
     static int initialized = 0;
@@ -189,11 +195,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacDisplay_initNSAppli
 }
 
 /*
- * Class:     jogamp_newt_driver_macosx_MacDisplay
+ * Class:     jogamp_newt_driver_macosx_DisplayDriver
  * Method:    runNSApplication0
  * Signature: ()V
  */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacDisplay_runNSApplication0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_DisplayDriver_runNSApplication0
   (JNIEnv *env, jclass clazz)
 {
     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
@@ -206,11 +212,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacDisplay_runNSApplicatio
 }
 
 /*
- * Class:     jogamp_newt_driver_macosx_MacDisplay
+ * Class:     jogamp_newt_driver_macosx_DisplayDriver
  * Method:    stopNSApplication0
  * Signature: ()V
  */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacDisplay_stopNSApplication0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_DisplayDriver_stopNSApplication0
   (JNIEnv *env, jclass clazz)
 {
     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
@@ -250,11 +256,11 @@ static NSScreen * NewtScreen_getNSScreenByIndex(int screen_idx) {
 }
 
 /*
- * Class:     jogamp_newt_driver_macosx_MacScreen
+ * Class:     jogamp_newt_driver_macosx_ScreenDriver
  * Method:    getWidthImpl
  * Signature: (I)I
  */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_macosx_MacScreen_getWidthImpl0
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getWidthImpl0
   (JNIEnv *env, jclass clazz, jint screen_idx)
 {
     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
@@ -268,11 +274,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_macosx_MacScreen_getWidthImpl0
 }
 
 /*
- * Class:     jogamp_newt_driver_macosx_MacScreen
+ * Class:     jogamp_newt_driver_macosx_ScreenDriver
  * Method:    getHeightImpl
  * Signature: (I)I
  */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_macosx_MacScreen_getHeightImpl0
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getHeightImpl0
   (JNIEnv *env, jclass clazz, jint screen_idx)
 {
     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
@@ -318,11 +324,11 @@ static long GetDictionaryLong(CFDictionaryRef theDict, const void* key)
 #define ROTMODES_PER_REALMODE 4
 
 /*
- * Class:     jogamp_newt_driver_macosx_MacScreen
+ * Class:     jogamp_newt_driver_macosx_ScreenDriver
  * Method:    getScreenSizeMM0
  * Signature: (I)[I
  */
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_MacScreen_getScreenSizeMM0
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getScreenSizeMM0
   (JNIEnv *env, jobject obj, jint scrn_idx)
 {
     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
@@ -367,11 +373,11 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_MacScreen_getScreenSi
 }
 
 /*
- * Class:     jogamp_newt_driver_macosx_MacScreen
+ * Class:     jogamp_newt_driver_macosx_ScreenDriver
  * Method:    getScreenMode0
  * Signature: (IIII)[I
  */
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_MacScreen_getScreenMode0
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getScreenMode0
   (JNIEnv *env, jobject obj, jint scrn_idx, jint mode_idx, jint widthMM, jint heightMM)
 {
     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
@@ -430,6 +436,8 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_MacScreen_getScreenMo
     if( -1 < mode_idx ) {
         prop[propIndex++] = mode_idx;
     }
+    int refreshRate = CGDDGetModeRefreshRate(mode);
+    int fRefreshRate = ( 0 < refreshRate ) ? refreshRate : 60; // default .. (experienced on OSX 10.6.8)
     prop[propIndex++] = 0; // set later for verification of iterator
     propIndexRes = propIndex;
     prop[propIndex++] = mWidth;
@@ -437,14 +445,14 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_MacScreen_getScreenMo
     prop[propIndex++] = CGDDGetModeBitsPerPixel(mode);
     prop[propIndex++] = widthMM;
     prop[propIndex++] = heightMM;
-    prop[propIndex++] = CGDDGetModeRefreshRate(mode);
+    prop[propIndex++] = fRefreshRate;
     prop[propIndex++] = ccwRot;
     prop[propIndex - NUM_SCREEN_MODE_PROPERTIES_ALL] = ( -1 < mode_idx ) ? propIndex-1 : propIndex ; // count == NUM_SCREEN_MODE_PROPERTIES_ALL
 
-    DBG_PRINT( "getScreenMode0: Mode %d/%d (%d): %dx%d, %d bpp, %dx%d mm, %d Hz, rot %d ccw\n",
+    DBG_PRINT( "getScreenMode0: Mode %d/%d (%d): %dx%d, %d bpp, %dx%d mm, %d / %d Hz, rot %d ccw\n",
         (int)mode_idx, (int)numberOfAvailableModesRots, (int)numberOfAvailableModes, 
         (int)prop[propIndexRes+0], (int)prop[propIndexRes+1], (int)prop[propIndexRes+2], 
-        (int)prop[propIndexRes+3], (int)prop[propIndexRes+4], (int)prop[propIndexRes+5], (int)prop[propIndexRes+6]);
+        (int)prop[propIndexRes+3], (int)prop[propIndexRes+4], (int)prop[propIndexRes+5], refreshRate, (int)prop[propIndexRes+6]);
 
     jintArray properties = (*env)->NewIntArray(env, prop_num);
     if (properties == NULL) {
@@ -459,11 +467,11 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_MacScreen_getScreenMo
 }
 
 /*
- * Class:     jogamp_newt_driver_macosx_MacScreen
+ * Class:     jogamp_newt_driver_macosx_ScreenDriver
  * Method:    setScreenMode0
  * Signature: (II)Z
  */
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacScreen_setScreenMode0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_setScreenMode0
   (JNIEnv *env, jobject object, jint scrn_idx, jint mode_idx)
 {
     jboolean res = JNI_TRUE;
@@ -504,11 +512,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacScreen_setScreenMod
 }
 
 /*
- * Class:     jogamp_newt_driver_macosx_MacWindow
+ * Class:     jogamp_newt_driver_macosx_WindowDriver
  * Method:    initIDs
  * Signature: ()Z
  */
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacWindow_initIDs0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_initIDs0
   (JNIEnv *env, jclass clazz)
 {
     static int initialized = 0;
@@ -516,19 +524,21 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacWindow_initIDs0
     if(initialized) return JNI_TRUE;
     initialized = 1;
 
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+
     jclass c;
     c = (*env)->FindClass(env, ClazzNamePoint);
     if(NULL==c) {
-        NewtCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_macosx_MacWindow_initIDs0: can't find %s", ClazzNamePoint);
+        NewtCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_macosx_WindowDriver_initIDs0: can't find %s", ClazzNamePoint);
     }
     pointClz = (jclass)(*env)->NewGlobalRef(env, c);
     (*env)->DeleteLocalRef(env, c);
     if(NULL==pointClz) {
-        NewtCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_macosx_MacWindow_initIDs0: can't use %s", ClazzNamePoint);
+        NewtCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_macosx_WindowDriver_initIDs0: can't use %s", ClazzNamePoint);
     }
     pointCstr = (*env)->GetMethodID(env, pointClz, ClazzAnyCstrName, ClazzNamePointCstrSignature);
     if(NULL==pointCstr) {
-        NewtCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_macosx_MacWindow_initIDs0: can't fetch %s.%s %s",
+        NewtCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_macosx_WindowDriver_initIDs0: can't fetch %s.%s %s",
             ClazzNamePoint, ClazzAnyCstrName, ClazzNamePointCstrSignature);
     }
 
@@ -537,15 +547,18 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacWindow_initIDs0
     //    printf("Going to sleep for 10 seconds\n");
     //    sleep(10);
 
-    return (jboolean) [NewtMacWindow initNatives: env forClass: clazz];
+    BOOL res =  [NewtMacWindow initNatives: env forClass: clazz];
+    [pool release];
+
+    return (jboolean) res;
 }
 
 /*
- * Class:     jogamp_newt_driver_macosx_MacWindow
+ * Class:     jogamp_newt_driver_macosx_WindowDriver
  * Method:    createWindow0
  * Signature: (JIIIIZIIIJ)J
  */
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_MacWindow_createWindow0
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createWindow0
   (JNIEnv *env, jobject jthis, jlong parent, jint x, jint y, jint w, jint h, jboolean opaque, jboolean fullscreen, jint styleMask, 
    jint bufferingType, jint screen_idx, jlong jview)
 {
@@ -602,8 +615,10 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_MacWindow_createWindow0
     // Remove animations for child windows
     if(NULL != parentWindow) {
 NS_DURING
-        // Available >= 10.7 - Removes default animations
-        [myWindow setAnimationBehavior: NSWindowAnimationBehaviorNone];
+        if ( [myWindow respondsToSelector:@selector(setAnimationBehavior:)] ) {
+            // Available >= 10.7 - Removes default animations
+            [myWindow setAnimationBehavior: NSWindowAnimationBehaviorNone];
+        }
 NS_HANDLER
 NS_ENDHANDLER
     }
@@ -658,8 +673,12 @@ NS_ENDHANDLER
 NS_DURING
     // concurrent view rendering
     // Available >= 10.6 - Makes the menubar disapear
-    [myWindow setAllowsConcurrentViewDrawing: YES];
-    [myView setCanDrawConcurrently: YES];
+    if ( [myWindow respondsToSelector:@selector(setAllowsConcurrentViewDrawing:)] ) {
+        [myWindow setAllowsConcurrentViewDrawing: YES];
+    }
+    if ( [myView respondsToSelector:@selector(setCanDrawConcurrently:)] ) {
+        [myView setCanDrawConcurrently: YES];
+    }
 NS_HANDLER
 NS_ENDHANDLER
 
@@ -669,7 +688,9 @@ NS_ENDHANDLER
 NS_DURING
     // Available >= 10.5 - Makes the menubar disapear
     if(fullscreen) {
-         [myView enterFullScreenMode: myScreen withOptions:NULL];
+        if ( [myView respondsToSelector:@selector(enterFullScreenMode:withOptions:)] ) {
+            [myView enterFullScreenMode: myScreen withOptions:NULL];
+        }
     }
 NS_HANDLER
 NS_ENDHANDLER
@@ -698,11 +719,11 @@ NS_ENDHANDLER
 
 
 /*
- * Class:     jogamp_newt_driver_macosx_MacWindow
+ * Class:     jogamp_newt_driver_macosx_WindowDriver
  * Method:    close0
  * Signature: (J)V
  */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_close0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_close0
   (JNIEnv *env, jobject unused, jlong window)
 {
     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
@@ -730,7 +751,13 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_close0
 NS_DURING
     if(NULL!=mView) {
         // Available >= 10.5 - Makes the menubar disapear
-        if([mView isInFullScreenMode]) {
+        BOOL iifs;
+        if ( [mView respondsToSelector:@selector(isInFullScreenMode)] ) {
+            iifs = [mView isInFullScreenMode];
+        } else {
+            iifs = NO;
+        }
+        if(iifs && [mView respondsToSelector:@selector(exitFullScreenModeWithOptions:)] ) {
             [mView exitFullScreenModeWithOptions: NULL];
         }
         // Note: mWin's release will also release it's mView!
@@ -761,11 +788,11 @@ NS_ENDHANDLER
 }
 
 /*
- * Class:     Java_jogamp_newt_driver_macosx_MacWindow
+ * Class:     Java_jogamp_newt_driver_macosx_WindowDriver
  * Method:    lockSurface0
  * Signature: (J)Z
  */
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacWindow_lockSurface0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_lockSurface0
   (JNIEnv *env, jclass clazz, jlong window)
 {
     NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window);
@@ -779,11 +806,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacWindow_lockSurface0
 }
 
 /*
- * Class:     Java_jogamp_newt_driver_macosx_MacWindow
+ * Class:     Java_jogamp_newt_driver_macosx_WindowDriver
  * Method:    unlockSurface0
  * Signature: (J)V
  */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_unlockSurface0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_unlockSurface0
   (JNIEnv *env, jclass clazz, jlong window)
 {
     NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window);
@@ -794,11 +821,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_unlockSurface0
 }
 
 /*
- * Class:     jogamp_newt_driver_macosx_MacWindow
+ * Class:     jogamp_newt_driver_macosx_WindowDriver
  * Method:    requestFocus0
  * Signature: (JZ)V
  */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_requestFocus0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_requestFocus0
   (JNIEnv *env, jobject window, jlong w, jboolean force)
 {
     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
@@ -819,11 +846,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_requestFocus0
 }
 
 /*
- * Class:     jogamp_newt_driver_macosx_MacWindow
+ * Class:     jogamp_newt_driver_macosx_WindowDriver
  * Method:    resignFocus0
  * Signature: (J)V
  */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_resignFocus0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_resignFocus0
   (JNIEnv *env, jobject window, jlong w)
 {
     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
@@ -846,11 +873,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_resignFocus0
 }
 
 /*
- * Class:     jogamp_newt_driver_macosx_MacWindow
+ * Class:     jogamp_newt_driver_macosx_WindowDriver
  * Method:    orderFront0
  * Signature: (J)V
  */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_orderFront0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_orderFront0
   (JNIEnv *env, jobject unused, jlong window)
 {
     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
@@ -866,11 +893,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_orderFront0
 }
 
 /*
- * Class:     jogamp_newt_driver_macosx_MacWindow
+ * Class:     jogamp_newt_driver_macosx_WindowDriver
  * Method:    orderOut
  * Signature: (J)V
  */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_orderOut0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_orderOut0
   (JNIEnv *env, jobject unused, jlong window)
 {
     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
@@ -891,11 +918,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_orderOut0
 }
 
 /*
- * Class:     jogamp_newt_driver_macosx_MacWindow
+ * Class:     jogamp_newt_driver_macosx_WindowDriver
  * Method:    setTitle0
  * Signature: (JLjava/lang/String;)V
  */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_setTitle0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setTitle0
   (JNIEnv *env, jobject unused, jlong window, jstring title)
 {
     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
@@ -913,11 +940,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_setTitle0
 }
 
 /*
- * Class:     jogamp_newt_driver_macosx_MacWindow
+ * Class:     jogamp_newt_driver_macosx_WindowDriver
  * Method:    contentView
  * Signature: (J)J
  */
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_MacWindow_contentView0
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_contentView0
   (JNIEnv *env, jobject unused, jlong window)
 {
     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
@@ -934,11 +961,11 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_MacWindow_contentView0
 }
 
 /*
- * Class:     jogamp_newt_driver_macosx_MacWindow
+ * Class:     jogamp_newt_driver_macosx_WindowDriver
  * Method:    changeContentView
  * Signature: (J)J
  */
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_MacWindow_changeContentView0
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_changeContentView0
   (JNIEnv *env, jobject jthis, jlong parentWindowOrView, jlong window, jlong jview)
 {
     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
@@ -977,11 +1004,11 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_MacWindow_changeContentVi
 }
 
 /*
- * Class:     jogamp_newt_driver_macosx_MacWindow
+ * Class:     jogamp_newt_driver_macosx_WindowDriver
  * Method:    setContentSize
  * Signature: (JII)V
  */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_setContentSize0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setContentSize0
   (JNIEnv *env, jobject unused, jlong window, jint w, jint h)
 {
     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
@@ -998,11 +1025,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_setContentSize0
 }
 
 /*
- * Class:     jogamp_newt_driver_macosx_MacWindow
+ * Class:     jogamp_newt_driver_macosx_WindowDriver
  * Method:    setFrameTopLeftPoint
  * Signature: (JJII)V
  */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_setFrameTopLeftPoint0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setFrameTopLeftPoint0
   (JNIEnv *env, jobject unused, jlong parent, jlong window, jint x, jint y)
 {
     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
@@ -1027,11 +1054,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_setFrameTopLeftP
 }
 
 /*
- * Class:     jogamp_newt_driver_macosx_MacWindow
+ * Class:     jogamp_newt_driver_macosx_WindowDriver
  * Method:    setAlwaysOnTop0
  * Signature: (JZ)V
  */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_setAlwaysOnTop0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setAlwaysOnTop0
   (JNIEnv *env, jobject unused, jlong window, jboolean atop)
 {
     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
@@ -1051,11 +1078,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_setAlwaysOnTop0
 }
 
 /*
- * Class:     jogamp_newt_driver_macosx_MacWindow
+ * Class:     jogamp_newt_driver_macosx_WindowDriver
  * Method:    getLocationOnScreen0
  * Signature: (JII)Ljavax/media/nativewindow/util/Point;
  */
-JNIEXPORT jobject JNICALL Java_jogamp_newt_driver_macosx_MacWindow_getLocationOnScreen0
+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);
@@ -1072,11 +1099,11 @@ JNIEXPORT jobject JNICALL Java_jogamp_newt_driver_macosx_MacWindow_getLocationOn
 }
 
 /*
- * Class:     Java_jogamp_newt_driver_macosx_MacWindow
+ * Class:     Java_jogamp_newt_driver_macosx_WindowDriver
  * Method:    setPointerVisible0
  * Signature: (JZ)Z
  */
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacWindow_setPointerVisible0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setPointerVisible0
   (JNIEnv *env, jclass clazz, jlong window, jboolean hasFocus, jboolean mouseVisible)
 {
     NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window);
@@ -1086,11 +1113,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacWindow_setPointerVi
 }
 
 /*
- * Class:     Java_jogamp_newt_driver_macosx_MacWindow
+ * Class:     Java_jogamp_newt_driver_macosx_WindowDriver
  * Method:    confinePointer0
  * Signature: (JZ)Z
  */
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacWindow_confinePointer0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_confinePointer0
   (JNIEnv *env, jclass clazz, jlong window, jboolean confine)
 {
     NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window);
@@ -1099,11 +1126,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacWindow_confinePoint
 }
 
 /*
- * Class:     Java_jogamp_newt_driver_macosx_MacWindow
+ * Class:     Java_jogamp_newt_driver_macosx_WindowDriver
  * Method:    warpPointer0
  * Signature: (JJII)V
  */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_warpPointer0
+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);
diff --git a/src/newt/native/NewtMacWindow.h b/src/newt/native/NewtMacWindow.h
index c0912ad..29b646f 100644
--- a/src/newt/native/NewtMacWindow.h
+++ b/src/newt/native/NewtMacWindow.h
@@ -111,6 +111,7 @@
     BOOL mouseInside;
     BOOL cursorIsHidden;
     BOOL realized;
+    BOOL modsDown[4]; // shift, ctrl, alt/option, win/command
     NSPoint lastInsideMousePosition;
 @public
     int cachedInsets[4]; // l, r, t, b
@@ -145,6 +146,7 @@
 - (void) setMousePosition:(NSPoint)p;
 
 - (void) sendKeyEvent: (NSEvent*) event eventType: (jint) evType;
+- (void) sendKeyEvent: (jint) keyCode characters: (NSString*) chars modifiers: (NSUInteger)mods eventType: (jint) evType;
 - (void) sendMouseEvent: (NSEvent*) event eventType: (jint) evType;
 - (void) focusChanged: (BOOL) gained;
 
@@ -157,6 +159,8 @@
 - (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;
diff --git a/src/newt/native/NewtMacWindow.m b/src/newt/native/NewtMacWindow.m
index b58b99e..b89b5c2 100644
--- a/src/newt/native/NewtMacWindow.m
+++ b/src/newt/native/NewtMacWindow.m
@@ -368,6 +368,10 @@ static jmethodID windowRepaintID = NULL;
     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;
@@ -597,6 +601,14 @@ static jint mods2JavaMods(NSUInteger mods)
 
 - (void) sendKeyEvent: (NSEvent*) event eventType: (jint) evType
 {
+    jint keyCode = (jint) [event keyCode];
+    NSString* chars = [event charactersIgnoringModifiers];
+    NSUInteger mods = [event modifierFlags];
+    [self sendKeyEvent: keyCode characters: chars modifiers: mods eventType: evType];
+}
+
+- (void) sendKeyEvent: (jint) keyCode characters: (NSString*) chars modifiers: (NSUInteger)mods eventType: (jint) evType
+{
     NSView* nsview = [self contentView];
     if( ! [nsview isMemberOfClass:[NewtView class]] ) {
         return;
@@ -616,16 +628,30 @@ static jint mods2JavaMods(NSUInteger mods)
     }
 
     int i;
-    jint keyCode = (jint) [event keyCode];
-    NSString* chars = [event charactersIgnoringModifiers];
-    int len = [chars length];
-    jint javaMods = mods2JavaMods([event modifierFlags]);
-
-    for (i = 0; i < len; i++) {
-        // Note: the key code in the NSEvent does not map to anything we can use
-        jchar keyChar = (jchar) [chars characterAtIndex: i];
+    int len = NULL != chars ? [chars length] : 0;
+    jint javaMods = mods2JavaMods(mods);
+
+    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
+            jchar keyChar = (jchar) [chars characterAtIndex: i];
+
+            DBG_PRINT("sendKeyEvent: %d/%d char 0x%X, code 0x%X\n", i, len, (int)keyChar, (int)keyCode);
+
+            #ifdef USE_SENDIO_DIRECT
+            (*env)->CallVoidMethod(env, javaWindowObject, sendKeyEventID,
+                                   evType, javaMods, keyCode, keyChar);
+            #else
+            (*env)->CallVoidMethod(env, javaWindowObject, enqueueKeyEventID, JNI_FALSE,
+                                   evType, javaMods, keyCode, keyChar);
+            #endif
+        }
+    } else {
+        // non-printable chars
+        jchar keyChar = (jchar) -1;
 
-        DBG_PRINT("sendKeyEvent: %d/%d char 0x%X, code 0x%X\n", i, len, (int)keyChar, (int)keyCode);
+        DBG_PRINT("sendKeyEvent: code 0x%X\n", (int)keyCode);
 
         #ifdef USE_SENDIO_DIRECT
         (*env)->CallVoidMethod(env, javaWindowObject, sendKeyEventID,
@@ -805,6 +831,35 @@ static jint mods2JavaMods(NSUInteger mods)
     [self sendKeyEvent: theEvent eventType: EVENT_KEY_TYPED];
 }
 
+#define kVK_Shift     0x38
+#define kVK_Option    0x3A
+#define kVK_Control   0x3B
+#define kVK_Command   0x37
+
+- (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: keyCode characters: NULL modifiers: mods|keyMask eventType: EVENT_KEY_PRESSED];
+    } else if ( YES == modsDown[keyIdx] && 0 == ( mods & keyMask ) )  {
+        modsDown[keyIdx] = NO;
+        [self sendKeyEvent: keyCode characters: NULL modifiers: mods|keyMask eventType: EVENT_KEY_RELEASED];
+        [self sendKeyEvent: keyCode characters: NULL modifiers: mods|keyMask eventType: EVENT_KEY_TYPED];
+    }
+}
+
+- (void) flagsChanged:(NSEvent *) theEvent
+{
+    NSUInteger mods = [theEvent modifierFlags];
+
+    // BOOL modsDown[4]; // shift, ctrl, alt/option, win/command
+
+    [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) mouseEntered: (NSEvent*) theEvent
 {
     DBG_PRINT( "mouseEntered: confined %d, visible %d\n", mouseConfined, mouseVisible);
diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c
index 6d9c04d..e3d5cff 100644
--- a/src/newt/native/WindowsWindow.c
+++ b/src/newt/native/WindowsWindow.c
@@ -81,9 +81,9 @@
 #define DISPLAY_DEVICE_ACTIVE 0x00000001
 #endif
 
-#include "jogamp_newt_driver_windows_WindowsDisplay.h"
-#include "jogamp_newt_driver_windows_WindowsScreen.h"
-#include "jogamp_newt_driver_windows_WindowsWindow.h"
+#include "jogamp_newt_driver_windows_DisplayDriver.h"
+#include "jogamp_newt_driver_windows_ScreenDriver.h"
+#include "jogamp_newt_driver_windows_WindowDriver.h"
 
 #include "Window.h"
 #include "MouseEvent.h"
@@ -463,87 +463,108 @@ static void BuildDynamicKeyMapTable()
     } // for each VK_OEM_*
 }
 
-static jint GetModifiers() {
+static jint GetModifiers(BOOL altKeyFlagged, UINT jkey) {
     jint modifiers = 0;
     // have to do &0xFFFF to avoid runtime assert caused by compiling with
     // /RTCcsu
-    if (HIBYTE((GetKeyState(VK_CONTROL) & 0xFFFF)) != 0) {
+    if ( HIBYTE((GetKeyState(VK_CONTROL) & 0xFFFF)) != 0 || J_VK_CONTROL == jkey ) {
         modifiers |= EVENT_CTRL_MASK;
     }
-    if (HIBYTE((GetKeyState(VK_SHIFT) & 0xFFFF)) != 0) {
+    if ( HIBYTE((GetKeyState(VK_SHIFT) & 0xFFFF)) != 0 || J_VK_SHIFT == jkey ) {
         modifiers |= EVENT_SHIFT_MASK;
     }
-    if (HIBYTE((GetKeyState(VK_MENU) & 0xFFFF)) != 0) {
+    if ( altKeyFlagged || HIBYTE((GetKeyState(VK_MENU) & 0xFFFF)) != 0 || J_VK_ALT == jkey ) {
         modifiers |= EVENT_ALT_MASK;
     }
-    if (HIBYTE((GetKeyState(VK_LBUTTON) & 0xFFFF)) != 0) {
+    if ( HIBYTE((GetKeyState(VK_LBUTTON) & 0xFFFF)) != 0 ) {
         modifiers |= EVENT_BUTTON1_MASK;
     }
-    if (HIBYTE((GetKeyState(VK_MBUTTON) & 0xFFFF)) != 0) {
+    if ( HIBYTE((GetKeyState(VK_MBUTTON) & 0xFFFF)) != 0 ) {
         modifiers |= EVENT_BUTTON2_MASK;
     }
-    if (HIBYTE((GetKeyState(VK_RBUTTON) & 0xFFFF)) != 0) {
+    if ( HIBYTE((GetKeyState(VK_RBUTTON) & 0xFFFF)) != 0 ) {
         modifiers |= EVENT_BUTTON3_MASK;
     }
 
     return modifiers;
 }
 
-static int WmChar(JNIEnv *env, jobject window, UINT character, UINT repCnt,
-                  UINT flags, BOOL system)
-{
+static BOOL IsAltKeyDown(BYTE flags, BOOL system) {
     // The Alt modifier is reported in the 29th bit of the lParam,
-    // i.e., it is the 13th bit of `flags' (which is HIWORD(lParam)).
-    BOOL alt_is_down = (flags & (1<<13)) != 0;
-    if (system && alt_is_down) {
-        if (character == VK_SPACE) {
-            return 1;
-        }
-    }
-
-    if (character == VK_RETURN) {
-        character = J_VK_ENTER;
-    }
-    (*env)->CallVoidMethod(env, window, sendKeyEventID,
-                           (jint) EVENT_KEY_TYPED,
-                           GetModifiers(),
-                           (jint) -1,
-                           (jchar) character);
-    return 1;
+    // i.e., it is the 5th bit of `flags' (which is HIBYTE(HIWORD(lParam))).
+    return system && ( flags & (1<<5) ) != 0;
 }
 
-UINT WindowsKeyToJavaKey(UINT windowsKey, UINT modifiers)
+UINT WindowsKeyToJavaKey(UINT windowsKey)
 {
-    int i, j;
+    int i, j, javaKey = J_VK_UNDEFINED;
     // for the general case, use a bi-directional table
     for (i = 0; keyMapTable[i].windowsKey != 0; i++) {
         if (keyMapTable[i].windowsKey == windowsKey) {
-            return keyMapTable[i].javaKey;
+            javaKey = keyMapTable[i].javaKey;
         }
     }
-    for (j = 0; dynamicKeyMapTable[j].windowsKey != 0; j++) {
-        if (dynamicKeyMapTable[j].windowsKey == windowsKey) {
-            if (dynamicKeyMapTable[j].javaKey != J_VK_UNDEFINED) {
-                return dynamicKeyMapTable[j].javaKey;
-            } else {
-                break;
+    if( J_VK_UNDEFINED == javaKey ) {
+        for (j = 0; dynamicKeyMapTable[j].windowsKey != 0; j++) {
+            if (dynamicKeyMapTable[j].windowsKey == windowsKey) {
+                if (dynamicKeyMapTable[j].javaKey != J_VK_UNDEFINED) {
+                    javaKey = dynamicKeyMapTable[j].javaKey;
+                } else {
+                    break;
+                }
             }
         }
     }
 
-    return J_VK_UNDEFINED;
+#ifdef DEBUG_KEYS
+    STD_PRINT("*** WindowsWindow: WindowsKeyToJavaKey 0x%X -> 0x%X\n", windowsKey, javaKey);
+#endif
+    return javaKey;
 }
 
-static int WmKeyDown(JNIEnv *env, jobject window, UINT wkey, UINT repCnt,
-                     UINT flags, BOOL system)
-{
-    UINT modifiers = 0, jkey = 0, character = -1;
+#ifndef MAPVK_VSC_TO_VK
+    #define MAPVK_VSC_TO_VK 1
+#endif
+#ifndef MAPVK_VK_TO_CHAR
+    #define MAPVK_VK_TO_CHAR 2
+#endif
+
+static UINT WmVKey2ShiftedChar(UINT wkey, UINT modifiers) {
+    UINT c = MapVirtualKey(wkey, MAPVK_VK_TO_CHAR);
+    if( 0 != ( modifiers & EVENT_SHIFT_MASK ) ) {
+        return islower(c) ? toupper(c) : c;
+    }
+    return isupper(c) ? tolower(c) : c;
+}
+
+static int WmChar(JNIEnv *env, jobject window, UINT character, WORD repCnt, BYTE scanCode, BYTE flags, BOOL system) {
+    UINT modifiers = 0, jkey = 0, wkey = 0;
+
+    wkey = MapVirtualKey(scanCode, MAPVK_VSC_TO_VK);
+    jkey = WindowsKeyToJavaKey(wkey);
+    modifiers = GetModifiers( IsAltKeyDown(flags, system), 0 );
+
+    if (character == VK_RETURN) {
+        character = J_VK_ENTER;
+    }
+
+    (*env)->CallVoidMethod(env, window, sendKeyEventID,
+                           (jint) EVENT_KEY_TYPED,
+                           modifiers,
+                           (jint) jkey,
+                           (jchar) character);
+    return 1;
+}
+
+static int WmKeyDown(JNIEnv *env, jobject window, UINT wkey, WORD repCnt, BYTE scanCode, BYTE flags, BOOL system) {
+    UINT modifiers = 0, jkey = 0, character = 0;
     if (wkey == VK_PROCESSKEY) {
         return 1;
     }
 
-    modifiers = GetModifiers();
-    jkey = WindowsKeyToJavaKey(wkey, modifiers);
+    jkey = WindowsKeyToJavaKey(wkey);
+    modifiers = GetModifiers( IsAltKeyDown(flags, system), jkey );
+    character = WmVKey2ShiftedChar(wkey, modifiers);
 
 /*
     character = WindowsKeyToJavaChar(wkey, modifiers, SAVE);
@@ -562,24 +583,24 @@ static int WmKeyDown(JNIEnv *env, jobject window, UINT wkey, UINT repCnt,
     if (jkey == J_VK_DELETE) {
         (*env)->CallVoidMethod(env, window, sendKeyEventID,
                                (jint) EVENT_KEY_TYPED,
-                               GetModifiers(),
-                               (jint) -1,
+                               modifiers,
+                               (jint) 0,
                                (jchar) '\177');
     }
 
     return 0;
 }
 
-static int WmKeyUp(JNIEnv *env, jobject window, UINT wkey, UINT repCnt,
-                   UINT flags, BOOL system)
-{
-    UINT modifiers = 0, jkey = 0, character = -1;
+static int WmKeyUp(JNIEnv *env, jobject window, UINT wkey, WORD repCnt, BYTE scanCode, BYTE flags, BOOL system) {
+    UINT modifiers = 0, jkey = 0, character = 0;
     if (wkey == VK_PROCESSKEY) {
         return 1;
     }
 
-    modifiers = GetModifiers();
-    jkey = WindowsKeyToJavaKey(wkey, modifiers);
+    jkey = WindowsKeyToJavaKey(wkey);
+    modifiers = GetModifiers( IsAltKeyDown(flags, system), jkey );
+    character = WmVKey2ShiftedChar(wkey, modifiers);
+
 /*
     character = WindowsKeyToJavaChar(wkey, modifiers, SAVE);
 */
@@ -595,20 +616,25 @@ static int WmKeyUp(JNIEnv *env, jobject window, UINT wkey, UINT repCnt,
 
 static void NewtWindows_requestFocus (JNIEnv *env, jobject window, HWND hwnd, jboolean force) {
     HWND pHwnd, current;
+    BOOL isEnabled = IsWindowEnabled(hwnd);
     pHwnd = GetParent(hwnd);
     current = GetFocus();
-    DBG_PRINT("*** WindowsWindow: requestFocus.S parent %p, window %p, isCurrent %d\n", 
-        (void*) pHwnd, (void*)hwnd, current==hwnd);
+    DBG_PRINT("*** WindowsWindow: requestFocus.S force %d, parent %p, window %p, isEnabled %d, isCurrent %d\n", 
+        (int)force, (void*)pHwnd, (void*)hwnd, isEnabled, current==hwnd);
 
-    if( JNI_TRUE==force || current!=hwnd) {
+    if( JNI_TRUE==force || current!=hwnd || !isEnabled ) {
         UINT flags = SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
+        if(!isEnabled) {
+            EnableWindow(hwnd, TRUE);
+        }
         SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, flags);
         SetForegroundWindow(hwnd);  // Slightly Higher Priority
-        SetFocus(hwnd);// Sets Keyboard Focus To Window
+        SetFocus(hwnd);// Sets Keyboard Focus To Window (activates parent window if exist, or this window)
         if(NULL!=pHwnd) {
             SetActiveWindow(hwnd);
         }
-        DBG_PRINT("*** WindowsWindow: requestFocus.X1\n");
+        current = GetFocus();
+        DBG_PRINT("*** WindowsWindow: requestFocus.X1 isCurrent %d\n", current==hwnd);
     }
     DBG_PRINT("*** WindowsWindow: requestFocus.XX\n");
 }
@@ -770,21 +796,15 @@ static void WmSize(JNIEnv *env, jobject window, HWND wnd, UINT type)
     (*env)->CallVoidMethod(env, window, sizeChangedID, JNI_FALSE, w, h, JNI_FALSE);
 }
 
-static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
-                                WPARAM wParam, LPARAM lParam)
-{
+static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lParam) {
     LRESULT res = 0;
     int useDefWindowProc = 0;
     JNIEnv *env = NULL;
     jobject window = NULL;
     BOOL isKeyDown = FALSE;
     WindowUserData * wud;
-
-#ifdef DEBUG_KEYS
-    if (  WM_KEYDOWN == message ) {
-        STD_PRINT("*** WindowsWindow: wndProc window %p, 0x%X %d/%d\n", wnd, message, (int)LOWORD(lParam), (int)HIWORD(lParam));
-    }
-#endif
+    WORD repCnt; 
+    BYTE scanCode, flags;
 
 #if !defined(__MINGW64__) && ( defined(UNDER_CE) || _MSC_VER <= 1200 )
     wud = (WindowUserData *) GetWindowLong(wnd, GWL_USERDATA);
@@ -826,26 +846,57 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
         break;
 
     case WM_SYSCHAR:
-        useDefWindowProc = WmChar(env, window, wParam,
-                                  LOWORD(lParam), HIWORD(lParam), FALSE);
+        repCnt = HIWORD(lParam); scanCode = LOBYTE(repCnt); flags = HIBYTE(repCnt);
+        repCnt = LOWORD(lParam);
+#ifdef DEBUG_KEYS
+        STD_PRINT("*** WindowsWindow: windProc WM_SYSCHAR sending window %p -> %p, char 0x%X, repCnt %d, scanCode 0x%X, flags 0x%X\n", wnd, window, (int)wParam, (int)repCnt, (int)scanCode, (int)flags);
+#endif
+        useDefWindowProc = WmChar(env, window, wParam, repCnt, scanCode, flags, TRUE);
+        break;
+
+    case WM_SYSKEYDOWN:
+        repCnt = HIWORD(lParam); scanCode = LOBYTE(repCnt); flags = HIBYTE(repCnt);
+        repCnt = LOWORD(lParam);
+#ifdef DEBUG_KEYS
+        STD_PRINT("*** WindowsWindow: windProc WM_SYSKEYDOWN sending window %p -> %p, code 0x%X, repCnt %d, scanCode 0x%X, flags 0x%X\n", wnd, window, (int)wParam, (int)repCnt, (int)scanCode, (int)flags);
+#endif
+        useDefWindowProc = WmKeyDown(env, window, wParam, repCnt, scanCode, flags, TRUE);
+        break;
+
+    case WM_SYSKEYUP:
+        repCnt = HIWORD(lParam); scanCode = LOBYTE(repCnt); flags = HIBYTE(repCnt);
+        repCnt = LOWORD(lParam);
+#ifdef DEBUG_KEYS
+        STD_PRINT("*** WindowsWindow: windProc WM_SYSKEYUP sending window %p -> %p, code 0x%X, repCnt %d, scanCode 0x%X, flags 0x%X\n", wnd, window, (int)wParam, (int)repCnt, (int)scanCode, (int)flags);
+#endif
+        useDefWindowProc = WmKeyUp(env, window, wParam, repCnt, scanCode, flags, TRUE);
         break;
 
     case WM_CHAR:
-        useDefWindowProc = WmChar(env, window, wParam,
-                                  LOWORD(lParam), HIWORD(lParam), TRUE);
+        repCnt = HIWORD(lParam); scanCode = LOBYTE(repCnt); flags = HIBYTE(repCnt);
+        repCnt = LOWORD(lParam);
+#ifdef DEBUG_KEYS
+        STD_PRINT("*** WindowsWindow: windProc WM_CHAR sending window %p -> %p, char 0x%X, repCnt %d, scanCode 0x%X, flags 0x%X\n", wnd, window, (int)wParam, (int)repCnt, (int)scanCode, (int)flags);
+#endif
+        useDefWindowProc = WmChar(env, window, wParam, repCnt, scanCode, flags, FALSE);
         break;
         
     case WM_KEYDOWN:
+        repCnt = HIWORD(lParam); scanCode = LOBYTE(repCnt); flags = HIBYTE(repCnt);
+        repCnt = LOWORD(lParam);
 #ifdef DEBUG_KEYS
-        STD_PRINT("*** WindowsWindow: windProc sending window %p -> %p, 0x%X %d/%d\n", wnd, window, message, (int)LOWORD(lParam), (int)HIWORD(lParam));
+        STD_PRINT("*** WindowsWindow: windProc WM_KEYDOWN sending window %p -> %p, code 0x%X, repCnt %d, scanCode 0x%X, flags 0x%X\n", wnd, window, (int)wParam, (int)repCnt, (int)scanCode, (int)flags);
 #endif
-        useDefWindowProc = WmKeyDown(env, window, wParam,
-                                     LOWORD(lParam), HIWORD(lParam), FALSE);
+        useDefWindowProc = WmKeyDown(env, window, wParam, repCnt, scanCode, flags, FALSE);
         break;
 
     case WM_KEYUP:
-        useDefWindowProc = WmKeyUp(env, window, wParam,
-                                   LOWORD(lParam), HIWORD(lParam), FALSE);
+        repCnt = HIWORD(lParam); scanCode = LOBYTE(repCnt); flags = HIBYTE(repCnt);
+        repCnt = LOWORD(lParam);
+#ifdef DEBUG_KEYS
+        STD_PRINT("*** WindowsWindow: windProc WM_KEYUP sending window %p -> %p, code 0x%X, repCnt %d, scanCode 0x%X, flags 0x%X\n", wnd, window, (int)wParam, (int)repCnt, (int)scanCode, (int)flags);
+#endif
+        useDefWindowProc = WmKeyUp(env, window, wParam, repCnt, scanCode, flags, FALSE);
         break;
 
     case WM_SIZE:
@@ -868,7 +919,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
         (*env)->CallVoidMethod(env, window, requestFocusID, JNI_FALSE);
         (*env)->CallVoidMethod(env, window, sendMouseEventID,
                                (jint) EVENT_MOUSE_PRESSED,
-                               GetModifiers(),
+                               GetModifiers( FALSE, 0 ),
                                (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
                                (jint) 1, (jint) 0);
         useDefWindowProc = 1;
@@ -877,7 +928,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
     case WM_LBUTTONUP:
         (*env)->CallVoidMethod(env, window, sendMouseEventID,
                                (jint) EVENT_MOUSE_RELEASED,
-                               GetModifiers(),
+                               GetModifiers( FALSE, 0 ),
                                (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
                                (jint) 1, (jint) 0);
         useDefWindowProc = 1;
@@ -888,7 +939,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
         (*env)->CallVoidMethod(env, window, requestFocusID, JNI_FALSE);
         (*env)->CallVoidMethod(env, window, sendMouseEventID,
                                (jint) EVENT_MOUSE_PRESSED,
-                               GetModifiers(),
+                               GetModifiers( FALSE, 0 ),
                                (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
                                (jint) 2, (jint) 0);
         useDefWindowProc = 1;
@@ -897,7 +948,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
     case WM_MBUTTONUP:
         (*env)->CallVoidMethod(env, window, sendMouseEventID,
                                (jint) EVENT_MOUSE_RELEASED,
-                               GetModifiers(),
+                               GetModifiers( FALSE, 0 ),
                                (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
                                (jint) 2, (jint) 0);
         useDefWindowProc = 1;
@@ -908,7 +959,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
         (*env)->CallVoidMethod(env, window, requestFocusID, JNI_FALSE);
         (*env)->CallVoidMethod(env, window, sendMouseEventID,
                                (jint) EVENT_MOUSE_PRESSED,
-                               GetModifiers(),
+                               GetModifiers( FALSE, 0 ),
                                (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
                                (jint) 3, (jint) 0);
         useDefWindowProc = 1;
@@ -917,7 +968,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
     case WM_RBUTTONUP:
         (*env)->CallVoidMethod(env, window, sendMouseEventID,
                                (jint) EVENT_MOUSE_RELEASED,
-                               GetModifiers(),
+                               GetModifiers( FALSE, 0 ),
                                (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
                                (jint) 3,  (jint) 0);
         useDefWindowProc = 1;
@@ -926,7 +977,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
     case WM_MOUSEMOVE:
         (*env)->CallVoidMethod(env, window, sendMouseEventID,
                                (jint) EVENT_MOUSE_MOVED,
-                               GetModifiers(),
+                               GetModifiers( FALSE, 0 ),
                                (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
                                (jint) 0,  (jint) 0);
         useDefWindowProc = 1;
@@ -951,7 +1002,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
         ScreenToClient(wnd, &eventPt);
         (*env)->CallVoidMethod(env, window, sendMouseEventID,
                                (jint) EVENT_MOUSE_WHEEL_MOVED,
-                               GetModifiers(),
+                               GetModifiers( FALSE, 0 ),
                                (jint) eventPt.x, (jint) eventPt.y,
                                (jint) 1,  (jint) (GET_WHEEL_DELTA_WPARAM(wParam)/120.0f));
         useDefWindowProc = 1;
@@ -959,11 +1010,13 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
     }
 
     case WM_SETFOCUS:
+        DBG_PRINT("*** WindowsWindow: WM_SETFOCUS window %p, lost %p\n", wnd, (HWND)wParam);
         (*env)->CallVoidMethod(env, window, focusChangedID, JNI_FALSE, JNI_TRUE);
         useDefWindowProc = 1;
         break;
 
     case WM_KILLFOCUS:
+        DBG_PRINT("*** WindowsWindow: WM_KILLFOCUS window %p, received %p\n", wnd, (HWND)wParam);
         (*env)->CallVoidMethod(env, window, focusChangedID, JNI_FALSE, JNI_FALSE);
         useDefWindowProc = 1;
         break;
@@ -1011,11 +1064,11 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
 }
 
 /*
- * Class:     jogamp_newt_driver_windows_WindowsDisplay
+ * Class:     jogamp_newt_driver_windows_DisplayDriver
  * Method:    DispatchMessages
  * Signature: ()V
  */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsDisplay_DispatchMessages0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_DisplayDriver_DispatchMessages0
   (JNIEnv *env, jclass clazz)
 {
     int i = 0;
@@ -1028,11 +1081,6 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsDisplay_DispatchMe
         // DBG_PRINT("*** WindowsWindow.DispatchMessages0: thread 0x%X - gotOne %d\n", (int)GetCurrentThreadId(), (int)gotOne);
         if (gotOne) {
             ++i;
-#ifdef DEBUG_KEYS
-            if(WM_KEYDOWN == msg.message) {
-                STD_PRINT("*** WindowsWindow: DispatchMessages window %p, 0x%X %d/%d\n", msg.hwnd, msg.message, (int)LOWORD(msg.lParam), (int)HIWORD(msg.lParam));
-            }
-#endif
             TranslateMessage(&msg);
             DispatchMessage(&msg);
         }
@@ -1040,11 +1088,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsDisplay_DispatchMe
 }
 
 /*
- * Class:     jogamp_newt_driver_windows_WindowsScreen
+ * Class:     jogamp_newt_driver_windows_ScreenDriver
  * Method:    getOriginX0
  * Signature: (I)I
  */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getOriginX0
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getOriginX0
   (JNIEnv *env, jobject obj, jint scrn_idx)
 {
     if( GetSystemMetrics( SM_CMONITORS) > 1) {
@@ -1055,11 +1103,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getOriginX0
 }
 
 /*
- * Class:     jogamp_newt_driver_windows_WindowsScreen
+ * Class:     jogamp_newt_driver_windows_ScreenDriver
  * Method:    getOriginY0
  * Signature: (I)I
  */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getOriginY0
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getOriginY0
   (JNIEnv *env, jobject obj, jint scrn_idx)
 {
     if( GetSystemMetrics( SM_CMONITORS ) > 1) {
@@ -1070,11 +1118,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getOriginY0
 }
 
 /*
- * Class:     jogamp_newt_driver_windows_WindowsScreen
+ * Class:     jogamp_newt_driver_windows_ScreenDriver
  * Method:    getWidthImpl
  * Signature: (I)I
  */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getWidthImpl0
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getWidthImpl0
   (JNIEnv *env, jobject obj, jint scrn_idx)
 {
     if( GetSystemMetrics( SM_CMONITORS) > 1) {
@@ -1085,11 +1133,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getWidthImp
 }
 
 /*
- * Class:     jogamp_newt_driver_windows_WindowsScreen
+ * Class:     jogamp_newt_driver_windows_ScreenDriver
  * Method:    getHeightImpl
  * Signature: (I)I
  */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getHeightImpl0
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getHeightImpl0
   (JNIEnv *env, jobject obj, jint scrn_idx)
 {
     if( GetSystemMetrics( SM_CMONITORS ) > 1) {
@@ -1173,11 +1221,11 @@ static HDC NewtScreen_createDisplayDC(LPCTSTR displayDeviceName) {
 }
 
 /*
- * Class:     jogamp_newt_driver_windows_WindowsScreen
+ * Class:     jogamp_newt_driver_windows_ScreenDriver
  * Method:    getScreenMode0
  * Signature: (II)[I
  */
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getScreenMode0
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getScreenMode0
   (JNIEnv *env, jobject obj, jint scrn_idx, jint mode_idx)
 {
     DISPLAY_DEVICE device;
@@ -1246,11 +1294,11 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getScr
 }
 
 /*
- * Class:     jogamp_newt_driver_windows_WindowsScreen
+ * Class:     jogamp_newt_driver_windows_ScreenDriver
  * Method:    setScreenMode0
  * Signature: (IIIIII)Z
  */
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_setScreenMode0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_setScreenMode0
   (JNIEnv *env, jobject object, jint scrn_idx, jint width, jint height, jint bits, jint rate, jint rot)
 {
     DISPLAY_DEVICE device;
@@ -1283,11 +1331,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_setScre
 }
 
 /*
- * Class:     jogamp_newt_driver_windows_WindowsWindow
+ * Class:     jogamp_newt_driver_windows_WindowDriver
  * Method:    initIDs0
  * Signature: ()Z
  */
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_initIDs0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowDriver_initIDs0
   (JNIEnv *env, jclass clazz)
 {
     NewtCommon_init(env);
@@ -1324,11 +1372,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_initIDs
 }
 
 /*
- * Class:     jogamp_newt_driver_windows_WindowsWindow
+ * Class:     jogamp_newt_driver_windows_WindowDriver
  * Method:    getNewtWndProc0
  * Signature: ()J
  */
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_getNewtWndProc0
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowDriver_getNewtWndProc0
   (JNIEnv *env, jclass clazz)
 {
     return (jlong) (intptr_t) wndProc;
@@ -1366,10 +1414,10 @@ static void NewtWindow_setVisiblePosSize(HWND hwnd, BOOL atop, BOOL visible,
 }
 
 /*
- * Class:     jogamp_newt_driver_windows_WindowsWindow
+ * Class:     jogamp_newt_driver_windows_WindowDriver
  * Method:    CreateWindow
  */
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_CreateWindow0
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowDriver_CreateWindow0
   (JNIEnv *env, jobject obj, 
    jlong hInstance, jstring jWndClassName, jstring jWndName, 
    jlong parent,
@@ -1473,11 +1521,11 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_CreateWind
 }
 
 /*
- * Class:     jogamp_newt_driver_windows_WindowsWindow
+ * Class:     jogamp_newt_driver_windows_WindowDriver
  * Method:    MonitorFromWindow
  * Signature: (J)J
  */
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_MonitorFromWindow0
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowDriver_MonitorFromWindow0
   (JNIEnv *env, jobject obj, jlong window)
 {
     #if (_WIN32_WINNT >= 0x0500 || _WIN32_WINDOWS >= 0x0410 || WINVER >= 0x0500) && !defined(_WIN32_WCE)
@@ -1506,11 +1554,11 @@ static jboolean NewtWindows_setFullScreen(jboolean fullscreen)
 }
 
 /*
- * Class:     jogamp_newt_driver_windows_WindowsWindow
+ * Class:     jogamp_newt_driver_windows_WindowDriver
  * Method:    reconfigureWindow0
  * Signature: (JJIIIII)V
  */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_reconfigureWindow0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_reconfigureWindow0
   (JNIEnv *env, jobject obj, jlong parent, jlong window,
    jint x, jint y, jint width, jint height, jint flags)
 {
@@ -1591,11 +1639,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_reconfigure
 }
 
 /*
- * Class:     jogamp_newt_driver_windows_WindowsWindow
+ * Class:     jogamp_newt_driver_windows_WindowDriver
  * Method:    setTitle
  * Signature: (JLjava/lang/String;)V
  */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_setTitle0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_setTitle0
   (JNIEnv *env, jclass clazz, jlong window, jstring title)
 {
     HWND hwnd = (HWND) (intptr_t) window;
@@ -1609,11 +1657,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_setTitle0
 }
 
 /*
- * Class:     jogamp_newt_driver_windows_WindowsWindow
+ * Class:     jogamp_newt_driver_windows_WindowDriver
  * Method:    requestFocus
  * Signature: (JZ)V
  */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_requestFocus0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_requestFocus0
   (JNIEnv *env, jobject obj, jlong window, jboolean force)
 {
     DBG_PRINT("*** WindowsWindow: RequestFocus0\n");
@@ -1621,11 +1669,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_requestFocu
 }
 
 /*
- * Class:     Java_jogamp_newt_driver_windows_WindowsWindow
+ * Class:     Java_jogamp_newt_driver_windows_WindowDriver
  * Method:    setPointerVisible0
  * Signature: (JJZ)Z
  */
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_setPointerVisible0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowDriver_setPointerVisible0
   (JNIEnv *env, jclass clazz, jlong window, jboolean mouseVisible)
 {
     HWND hwnd = (HWND) (intptr_t) window;
@@ -1660,11 +1708,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_setPoin
 }
 
 /*
- * Class:     Java_jogamp_newt_driver_windows_WindowsWindow
+ * Class:     Java_jogamp_newt_driver_windows_WindowDriver
  * Method:    confinePointer0
  * Signature: (JJZIIII)Z
  */
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_confinePointer0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowDriver_confinePointer0
   (JNIEnv *env, jclass clazz, jlong window, jboolean confine, jint l, jint t, jint r, jint b)
 {
     HWND hwnd = (HWND) (intptr_t) window;
@@ -1686,11 +1734,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_confine
 }
 
 /*
- * Class:     Java_jogamp_newt_driver_windows_WindowsWindow
+ * Class:     Java_jogamp_newt_driver_windows_WindowDriver
  * Method:    warpPointer0
  * Signature: (JJII)V
  */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_warpPointer0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_warpPointer0
   (JNIEnv *env, jclass clazz, jlong window, jint x, jint y)
 {
     DBG_PRINT( "*** WindowsWindow: warpPointer0: %d/%d\n", x, y);
@@ -1698,11 +1746,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_warpPointer
 }
 
 /*
- * Class:     Java_jogamp_newt_driver_windows_WindowsWindow
+ * Class:     Java_jogamp_newt_driver_windows_WindowDriver
  * Method:    trackPointerLeave0
  * Signature: (J)V
  */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_trackPointerLeave0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_trackPointerLeave0
   (JNIEnv *env, jclass clazz, jlong window)
 {
     HWND hwnd = (HWND) (intptr_t) window;
diff --git a/src/newt/native/X11Common.h b/src/newt/native/X11Common.h
index 982255b..4d1a7b5 100644
--- a/src/newt/native/X11Common.h
+++ b/src/newt/native/X11Common.h
@@ -45,9 +45,9 @@
 
 #include <X11/extensions/Xrandr.h>
 
-#include "jogamp_newt_driver_x11_X11Screen.h"
-#include "jogamp_newt_driver_x11_X11Display.h"
-#include "jogamp_newt_driver_x11_X11Window.h"
+#include "jogamp_newt_driver_x11_ScreenDriver.h"
+#include "jogamp_newt_driver_x11_DisplayDriver.h"
+#include "jogamp_newt_driver_x11_WindowDriver.h"
 
 #include "Window.h"
 #include "MouseEvent.h"
@@ -70,7 +70,6 @@ extern jclass X11NewtWindowClazz;
 extern jmethodID insetsChangedID;
 extern jmethodID visibleChangedID;
 
-void NewtDisplay_x11ErrorHandlerEnable(JNIEnv * env, Display *dpy, int onoff, int quiet, int sync);
 jobject getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlong javaObjectAtom, Bool showWarning);
 
 Status NewtWindows_getRootAndParent (Display *dpy, Window w, Window * root_return, Window * parent_return);
diff --git a/src/newt/native/X11Display.c b/src/newt/native/X11Display.c
index ce7d9a0..3f34a16 100644
--- a/src/newt/native/X11Display.c
+++ b/src/newt/native/X11Display.c
@@ -34,7 +34,7 @@ jclass X11NewtWindowClazz = NULL;
 jmethodID insetsChangedID = NULL;
 jmethodID visibleChangedID = NULL;
 
-static const char * const ClazzNameX11NewtWindow = "jogamp/newt/driver/x11/X11Window";
+static const char * const ClazzNameX11NewtWindow = "jogamp/newt/driver/x11/WindowDriver";
 
 static jmethodID displayCompletedID = NULL;
 
@@ -52,90 +52,6 @@ static jmethodID enqueueKeyEventID = NULL;
 static jmethodID sendKeyEventID = NULL;
 static jmethodID requestFocusID = NULL;
 
-static JavaVM *jvmHandle = NULL;
-static int jvmVersion = 0;
-
-static void setupJVMVars(JNIEnv * env) {
-    if(0 != (*env)->GetJavaVM(env, &jvmHandle)) {
-        jvmHandle = NULL;
-    }
-    jvmVersion = (*env)->GetVersion(env);
-}
-
-static XErrorHandler origErrorHandler = NULL ;
-static int errorHandlerQuiet = 0 ;
-static int errorHandlerDebug = 0 ;
-static int errorHandlerThrowException = 0;
-
-static int x11ErrorHandler(Display *dpy, XErrorEvent *e)
-{
-    if(!errorHandlerQuiet) {
-        const char * errnoStr = strerror(errno);
-        char threadName[80];
-        char errCodeStr[80];
-        char reqCodeStr[80];
-
-        int shallBeDetached = 0;
-        JNIEnv *jniEnv = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
-
-        (void) NewtCommon_GetStaticStringMethod(jniEnv, X11NewtWindowClazz, getCurrentThreadNameID, threadName, sizeof(threadName), "n/a");
-        snprintf(errCodeStr, sizeof(errCodeStr), "%d", e->request_code);
-        XGetErrorDatabaseText(dpy, "XRequest", errCodeStr, "Unknown", reqCodeStr, sizeof(reqCodeStr));
-        XGetErrorText(dpy, e->error_code, errCodeStr, sizeof(errCodeStr));
-
-        fprintf(stderr, "Info: Newt X11 Error (Thread: %s): %d - %s, dpy %p, id %x, # %d: %d:%d %s\n",
-            threadName, e->error_code, errCodeStr, e->display, (int)e->resourceid, (int)e->serial,
-            (int)e->request_code, (int)e->minor_code, reqCodeStr);
-
-        if( errorHandlerDebug ) {
-            (*jniEnv)->CallStaticVoidMethod(jniEnv, X11NewtWindowClazz, dumpStackID);
-        }
-
-        if(errorHandlerThrowException) {
-            if(NULL != jniEnv) {
-                NewtCommon_throwNewRuntimeException(jniEnv, "Newt X11 Error (Thread: %s): %d - %s, dpy %p, id %x, # %d: %d:%d %s\n",
-                                                    threadName, e->error_code, errCodeStr, e->display, (int)e->resourceid, (int)e->serial,
-                                                    (int)e->request_code, (int)e->minor_code, reqCodeStr);
-            } else {
-                fprintf(stderr, "Nativewindow X11 Error: null JNIEnv");
-                #if 0
-                    if(NULL!=origErrorHandler) {
-                        origErrorHandler(dpy, e);
-                    }
-                #endif
-            }
-        }
-        fflush(stderr);
-
-        if (NULL != jniEnv && shallBeDetached) {
-            (*jvmHandle)->DetachCurrentThread(jvmHandle);
-        }
-    }
-
-    return 0;
-}
-
-void NewtDisplay_x11ErrorHandlerEnable(JNIEnv * env, Display *dpy, int onoff, int quiet, int sync) {
-    errorHandlerQuiet = quiet;
-    if(onoff) {
-        if(NULL==origErrorHandler) {
-            setupJVMVars(env);
-            origErrorHandler = XSetErrorHandler(x11ErrorHandler);
-            if(sync && NULL!=dpy) {
-                XSync(dpy, False);
-            }
-        }
-    } else {
-        if(NULL!=origErrorHandler) {
-            if(sync && NULL!=dpy) {
-                XSync(dpy, False);
-            }
-            XSetErrorHandler(origErrorHandler);
-            origErrorHandler = NULL;
-        }
-    }
-}
-
 /**
  * Keycode
  */
@@ -230,28 +146,32 @@ static jint X11KeySym2NewtVKey(KeySym keySym) {
             return J_VK_INSERT;
         case XK_Help:
             return J_VK_HELP;
+        case XK_grave:
+            return J_VK_BACK_QUOTE;
+        case XK_apostrophe:
+            return J_VK_QUOTE;
     }
     return keySym;
 }
 
-static jint X11InputState2NewtModifiers(unsigned int xstate) {
+static jint X11InputState2NewtModifiers(unsigned int xstate, KeySym keySym) {
     jint modifiers = 0;
-    if ((ControlMask & xstate) != 0) {
+    if ( (ControlMask & xstate) != 0 || J_VK_CONTROL == keySym ) {
         modifiers |= EVENT_CTRL_MASK;
     }
-    if ((ShiftMask & xstate) != 0) {
+    if ( (ShiftMask & xstate) != 0 || J_VK_SHIFT == keySym ) {
         modifiers |= EVENT_SHIFT_MASK;
     }
-    if ((Mod1Mask & xstate) != 0) {
+    if ( (Mod1Mask & xstate) != 0 || J_VK_ALT == keySym ) {
         modifiers |= EVENT_ALT_MASK;
     }
-    if ((Button1Mask & xstate) != 0) {
+    if ( (Button1Mask & xstate) != 0 ) {
         modifiers |= EVENT_BUTTON1_MASK;
     }
-    if ((Button2Mask & xstate) != 0) {
+    if ( (Button2Mask & xstate) != 0 ) {
         modifiers |= EVENT_BUTTON2_MASK;
     }
-    if ((Button3Mask & xstate) != 0) {
+    if ( (Button3Mask & xstate) != 0 ) {
         modifiers |= EVENT_BUTTON3_MASK;
     }
 
@@ -264,29 +184,26 @@ static jint X11InputState2NewtModifiers(unsigned int xstate) {
  */
 
 /*
- * Class:     jogamp_newt_driver_x11_X11Display
+ * Class:     jogamp_newt_driver_x11_DisplayDriver
  * Method:    initIDs
  * Signature: (Z)Z
  */
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Display_initIDs0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_initIDs0
   (JNIEnv *env, jclass clazz, jboolean debug)
 {
     jclass c;
 
-    if(debug) {
-        errorHandlerDebug = 1 ;
-    }
     NewtCommon_init(env);
 
     if(NULL==X11NewtWindowClazz) {
         c = (*env)->FindClass(env, ClazzNameX11NewtWindow);
         if(NULL==c) {
-            NewtCommon_FatalError(env, "NEWT X11Window: can't find %s", ClazzNameX11NewtWindow);
+            NewtCommon_FatalError(env, "NEWT X11Display: can't find %s", ClazzNameX11NewtWindow);
         }
         X11NewtWindowClazz = (jclass)(*env)->NewGlobalRef(env, c);
         (*env)->DeleteLocalRef(env, c);
         if(NULL==X11NewtWindowClazz) {
-            NewtCommon_FatalError(env, "NEWT X11Window: can't use %s", ClazzNameX11NewtWindow);
+            NewtCommon_FatalError(env, "NEWT X11Display: can't use %s", ClazzNameX11NewtWindow);
         }
     }
 
@@ -331,11 +248,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Display_initIDs0
 }
 
 /*
- * Class:     jogamp_newt_driver_x11_X11Display
+ * Class:     jogamp_newt_driver_x11_DisplayDriver
  * Method:    CompleteDisplay
  * Signature: (J)V
  */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_CompleteDisplay0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_CompleteDisplay0
   (JNIEnv *env, jobject obj, jlong display)
 {
     Display * dpy = (Display *)(intptr_t)display;
@@ -366,11 +283,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_CompleteDisplay0
 }
 
 /*
- * Class:     jogamp_newt_driver_x11_X11Display
+ * Class:     jogamp_newt_driver_x11_DisplayDriver
  * Method:    DisplayRelease0
  * Signature: (JJJ)V
  */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DisplayRelease0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DisplayRelease0
   (JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong windowDeleteAtom)
 {
     Display * dpy = (Display *)(intptr_t)display;
@@ -390,16 +307,17 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DisplayRelease0
 }
 
 /*
- * Class:     jogamp_newt_driver_x11_X11Display
+ * Class:     jogamp_newt_driver_x11_DisplayDriver
  * Method:    DispatchMessages
  * Signature: (JIJJ)V
  */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessages0
   (JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong windowDeleteAtom)
 {
     Display * dpy = (Display *) (intptr_t) display;
     Atom wm_delete_atom = (Atom)windowDeleteAtom;
     int num_events = 100;
+    int autoRepeatModifiers = 0;
 
     if ( NULL == dpy ) {
         return;
@@ -415,10 +333,10 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0
         char text[255];
 
         // XEventsQueued(dpy, X):
-        //   QueuedAlready                 : No I/O Flush or system call  doesn't work on some cards (eg ATI) ?) 
+        //   QueuedAlready    == XQLength(): No I/O Flush or system call  doesn't work on some cards (eg ATI) ?) 
         //   QueuedAfterFlush == XPending(): I/O Flush only if no already queued events are available
         //   QueuedAfterReading            : QueuedAlready + if queue==0, attempt to read more ..
-        if ( 0 >= XPending(dpy) ) {
+        if ( 0 >= XEventsQueued(dpy, QueuedAfterFlush) ) {
             // DBG_PRINT( "X11: DispatchMessages 0x%X - Leave 1\n", dpy); 
             return;
         }
@@ -426,19 +344,17 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0
         XNextEvent(dpy, &evt);
         num_events--;
 
-        if( 0==evt.xany.window ) {
-            NewtCommon_throwNewRuntimeException(env, "event window NULL, bail out!");
-            return ;
-        }
-
         if(dpy!=evt.xany.display) {
             NewtCommon_throwNewRuntimeException(env, "wrong display, bail out!");
             return ;
         }
 
-        // DBG_PRINT( "X11: DispatchMessages dpy %p, win %p, Event %d\n", (void*)dpy, (void*)evt.xany.window, (int)evt.type);
+        if( 0==evt.xany.window ) {
+            DBG_PRINT( "X11: DispatchMessages dpy %p, Event %d - Window NULL, ignoring\n", (void*)dpy, (int)evt.type);
+            continue;
+        }
 
-        NewtDisplay_x11ErrorHandlerEnable(env, dpy, 1, 0, 0);
+        // DBG_PRINT( "X11: DispatchMessages dpy %p, win %p, Event %d\n", (void*)dpy, (void*)evt.xany.window, (int)evt.type);
 
         jwindow = getJavaWindowProperty(env, dpy, evt.xany.window, javaObjectAtom,
         #ifdef VERBOSE_ON
@@ -448,16 +364,28 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0
         #endif
             );
 
-        NewtDisplay_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
-
         if(NULL==jwindow) {
-            fprintf(stderr, "Warning: NEWT X11 DisplayDispatch %p, Couldn't handle event %d for X11 window %p\n", 
-                (void*)dpy, evt.type, (void*)evt.xany.window);
+            fprintf(stderr, "Warning: NEWT X11 DisplayDispatch %p, Couldn't handle event %d for X11 window %p\n", (void*)dpy, evt.type, (void*)evt.xany.window);
             continue;
         }
  
         switch(evt.type) {
             case KeyRelease:
+                if (XEventsQueued(dpy, QueuedAfterReading)) {
+                  XEvent nevt;
+                  XPeekEvent(dpy, &nevt);
+
+                  if (nevt.type == KeyPress && nevt.xkey.time == evt.xkey.time &&
+                      nevt.xkey.keycode == evt.xkey.keycode)
+                  {
+                    autoRepeatModifiers |= EVENT_AUTOREPEAT_MASK;
+                  } else {
+                    autoRepeatModifiers &= ~EVENT_AUTOREPEAT_MASK;
+                  }
+                } else {
+                    autoRepeatModifiers &= ~EVENT_AUTOREPEAT_MASK;
+                }
+                // fall through intended
             case KeyPress:
                 if(XLookupString(&evt.xkey,text,255,&keySym,0)==1) {
                     KeySym lower_return = 0, upper_return = 0;
@@ -469,13 +397,13 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0
                     keyChar=0;
                     keySym = X11KeySym2NewtVKey(keySym);
                 }
-                modifiers = X11InputState2NewtModifiers(evt.xkey.state);
+                modifiers |= X11InputState2NewtModifiers(evt.xkey.state, keySym) | autoRepeatModifiers;
                 break;
 
             case ButtonPress:
             case ButtonRelease:
             case MotionNotify:
-                modifiers = X11InputState2NewtModifiers(evt.xbutton.state);
+                modifiers |= X11InputState2NewtModifiers(evt.xbutton.state, 0);
                 break;
 
             default:
@@ -544,23 +472,23 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0
             case KeyPress:
                 #ifdef USE_SENDIO_DIRECT
                 (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_PRESSED, 
-                                      modifiers, keySym, (jchar) -1);
+                                      modifiers, keySym, (jchar) keyChar);
                 #else
                 (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_PRESSED, 
-                                      modifiers, keySym, (jchar) -1);
+                                      modifiers, keySym, (jchar) keyChar);
                 #endif
 
                 break;
             case KeyRelease:
                 #ifdef USE_SENDIO_DIRECT
                 (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_RELEASED, 
-                                      modifiers, keySym, (jchar) -1);
+                                      modifiers, keySym, (jchar) keyChar);
 
                 (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_TYPED, 
                                       modifiers, keySym, (jchar) keyChar);
                 #else
                 (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_RELEASED, 
-                                      modifiers, keySym, (jchar) -1);
+                                      modifiers, keySym, (jchar) keyChar);
 
                 (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_TYPED, 
                                       modifiers, keySym, (jchar) keyChar);
diff --git a/src/newt/native/X11Display.c b/src/newt/native/X11Event.c
similarity index 50%
copy from src/newt/native/X11Display.c
copy to src/newt/native/X11Event.c
index ce7d9a0..0792034 100644
--- a/src/newt/native/X11Display.c
+++ b/src/newt/native/X11Event.c
@@ -1,405 +1,10 @@
-/**
- * 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.
- */
 
-#include "X11Common.h"
+#include "X11Event.h"
 
-#define USE_SENDIO_DIRECT 1
-
-jclass X11NewtWindowClazz = NULL;
-jmethodID insetsChangedID = NULL;
-jmethodID visibleChangedID = NULL;
-
-static const char * const ClazzNameX11NewtWindow = "jogamp/newt/driver/x11/X11Window";
-
-static jmethodID displayCompletedID = NULL;
-
-static jmethodID getCurrentThreadNameID = NULL;
-static jmethodID dumpStackID = NULL;
-static jmethodID sizeChangedID = NULL;
-static jmethodID positionChangedID = NULL;
-static jmethodID focusChangedID = NULL;
-static jmethodID reparentNotifyID = NULL;
-static jmethodID windowDestroyNotifyID = NULL;
-static jmethodID windowRepaintID = NULL;
-static jmethodID enqueueMouseEventID = NULL;
-static jmethodID sendMouseEventID = NULL;
-static jmethodID enqueueKeyEventID = NULL;
-static jmethodID sendKeyEventID = NULL;
-static jmethodID requestFocusID = NULL;
-
-static JavaVM *jvmHandle = NULL;
-static int jvmVersion = 0;
-
-static void setupJVMVars(JNIEnv * env) {
-    if(0 != (*env)->GetJavaVM(env, &jvmHandle)) {
-        jvmHandle = NULL;
-    }
-    jvmVersion = (*env)->GetVersion(env);
-}
-
-static XErrorHandler origErrorHandler = NULL ;
-static int errorHandlerQuiet = 0 ;
-static int errorHandlerDebug = 0 ;
-static int errorHandlerThrowException = 0;
-
-static int x11ErrorHandler(Display *dpy, XErrorEvent *e)
-{
-    if(!errorHandlerQuiet) {
-        const char * errnoStr = strerror(errno);
-        char threadName[80];
-        char errCodeStr[80];
-        char reqCodeStr[80];
-
-        int shallBeDetached = 0;
-        JNIEnv *jniEnv = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
-
-        (void) NewtCommon_GetStaticStringMethod(jniEnv, X11NewtWindowClazz, getCurrentThreadNameID, threadName, sizeof(threadName), "n/a");
-        snprintf(errCodeStr, sizeof(errCodeStr), "%d", e->request_code);
-        XGetErrorDatabaseText(dpy, "XRequest", errCodeStr, "Unknown", reqCodeStr, sizeof(reqCodeStr));
-        XGetErrorText(dpy, e->error_code, errCodeStr, sizeof(errCodeStr));
-
-        fprintf(stderr, "Info: Newt X11 Error (Thread: %s): %d - %s, dpy %p, id %x, # %d: %d:%d %s\n",
-            threadName, e->error_code, errCodeStr, e->display, (int)e->resourceid, (int)e->serial,
-            (int)e->request_code, (int)e->minor_code, reqCodeStr);
-
-        if( errorHandlerDebug ) {
-            (*jniEnv)->CallStaticVoidMethod(jniEnv, X11NewtWindowClazz, dumpStackID);
-        }
-
-        if(errorHandlerThrowException) {
-            if(NULL != jniEnv) {
-                NewtCommon_throwNewRuntimeException(jniEnv, "Newt X11 Error (Thread: %s): %d - %s, dpy %p, id %x, # %d: %d:%d %s\n",
-                                                    threadName, e->error_code, errCodeStr, e->display, (int)e->resourceid, (int)e->serial,
-                                                    (int)e->request_code, (int)e->minor_code, reqCodeStr);
-            } else {
-                fprintf(stderr, "Nativewindow X11 Error: null JNIEnv");
-                #if 0
-                    if(NULL!=origErrorHandler) {
-                        origErrorHandler(dpy, e);
-                    }
-                #endif
-            }
-        }
-        fflush(stderr);
-
-        if (NULL != jniEnv && shallBeDetached) {
-            (*jvmHandle)->DetachCurrentThread(jvmHandle);
-        }
-    }
-
-    return 0;
-}
-
-void NewtDisplay_x11ErrorHandlerEnable(JNIEnv * env, Display *dpy, int onoff, int quiet, int sync) {
-    errorHandlerQuiet = quiet;
-    if(onoff) {
-        if(NULL==origErrorHandler) {
-            setupJVMVars(env);
-            origErrorHandler = XSetErrorHandler(x11ErrorHandler);
-            if(sync && NULL!=dpy) {
-                XSync(dpy, False);
-            }
-        }
-    } else {
-        if(NULL!=origErrorHandler) {
-            if(sync && NULL!=dpy) {
-                XSync(dpy, False);
-            }
-            XSetErrorHandler(origErrorHandler);
-            origErrorHandler = NULL;
-        }
-    }
-}
-
-/**
- * Keycode
- */
-
-#define IS_WITHIN(k,a,b) ((a)<=(k)&&(k)<=(b))
-
-static jint X11KeySym2NewtVKey(KeySym keySym) {
-    if(IS_WITHIN(keySym,XK_F1,XK_F12)) 
-        return (keySym-XK_F1)+J_VK_F1;
-    if(IS_WITHIN(keySym,XK_KP_0,XK_KP_9)) 
-        return (keySym-XK_KP_0)+J_VK_NUMPAD0;
-
-    switch(keySym) {
-        case XK_Return:
-        case XK_KP_Enter:
-            return J_VK_ENTER;
-        case XK_BackSpace:
-            return J_VK_BACK_SPACE;
-        case XK_Tab:
-        case XK_KP_Tab:
-        case XK_ISO_Left_Tab:
-            return J_VK_TAB;
-        case XK_Cancel:
-            return J_VK_CANCEL;
-        case XK_Clear:
-            return J_VK_CLEAR;
-        case XK_Shift_L:
-        case XK_Shift_R:
-            return J_VK_SHIFT;
-        case XK_Control_L:
-        case XK_Control_R:
-            return J_VK_CONTROL;
-        case XK_Alt_L:
-        case XK_Alt_R:
-            return J_VK_ALT;
-        case XK_Pause:
-            return J_VK_PAUSE;
-        case XK_Caps_Lock:
-            return J_VK_CAPS_LOCK;
-        case XK_Escape:
-            return J_VK_ESCAPE;
-        case XK_space:
-        case XK_KP_Space:
-            return J_VK_SPACE;
-        case XK_Page_Up:
-        case XK_KP_Page_Up:
-            return J_VK_PAGE_UP;
-        case XK_Page_Down:
-        case XK_KP_Page_Down:
-            return J_VK_PAGE_DOWN;
-        case XK_End:
-        case XK_KP_End:
-            return J_VK_END;
-        case XK_Home:
-        case XK_KP_Home:
-            return J_VK_HOME;
-        case XK_Left:
-        case XK_KP_Left:
-            return J_VK_LEFT;
-        case XK_Up:
-        case XK_KP_Up:
-            return J_VK_UP;
-        case XK_Right:
-        case XK_KP_Right:
-            return J_VK_RIGHT;
-        case XK_Down:
-        case XK_KP_Down:
-            return J_VK_DOWN;
-        case XK_KP_Multiply:
-            return J_VK_MULTIPLY;
-        case XK_KP_Add:
-            return J_VK_ADD;
-        case XK_KP_Separator:
-            return J_VK_SEPARATOR;
-        case XK_KP_Subtract:
-            return J_VK_SUBTRACT;
-        case XK_KP_Decimal:
-            return J_VK_DECIMAL;
-        case XK_KP_Divide:
-            return J_VK_DIVIDE;
-        case XK_Delete:
-        case XK_KP_Delete:
-            return J_VK_DELETE;
-        case XK_Num_Lock:
-            return J_VK_NUM_LOCK;
-        case XK_Scroll_Lock:
-            return J_VK_SCROLL_LOCK;
-        case XK_Print:
-            return J_VK_PRINTSCREEN;
-        case XK_Insert:
-        case XK_KP_Insert:
-            return J_VK_INSERT;
-        case XK_Help:
-            return J_VK_HELP;
-    }
-    return keySym;
-}
-
-static jint X11InputState2NewtModifiers(unsigned int xstate) {
-    jint modifiers = 0;
-    if ((ControlMask & xstate) != 0) {
-        modifiers |= EVENT_CTRL_MASK;
-    }
-    if ((ShiftMask & xstate) != 0) {
-        modifiers |= EVENT_SHIFT_MASK;
-    }
-    if ((Mod1Mask & xstate) != 0) {
-        modifiers |= EVENT_ALT_MASK;
-    }
-    if ((Button1Mask & xstate) != 0) {
-        modifiers |= EVENT_BUTTON1_MASK;
-    }
-    if ((Button2Mask & xstate) != 0) {
-        modifiers |= EVENT_BUTTON2_MASK;
-    }
-    if ((Button3Mask & xstate) != 0) {
-        modifiers |= EVENT_BUTTON3_MASK;
-    }
-
-    return modifiers;
-}
-
-
-/**
- * Keycode
- */
-
-/*
- * Class:     jogamp_newt_driver_x11_X11Display
- * Method:    initIDs
- * Signature: (Z)Z
- */
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Display_initIDs0
-  (JNIEnv *env, jclass clazz, jboolean debug)
-{
-    jclass c;
-
-    if(debug) {
-        errorHandlerDebug = 1 ;
-    }
-    NewtCommon_init(env);
-
-    if(NULL==X11NewtWindowClazz) {
-        c = (*env)->FindClass(env, ClazzNameX11NewtWindow);
-        if(NULL==c) {
-            NewtCommon_FatalError(env, "NEWT X11Window: can't find %s", ClazzNameX11NewtWindow);
-        }
-        X11NewtWindowClazz = (jclass)(*env)->NewGlobalRef(env, c);
-        (*env)->DeleteLocalRef(env, c);
-        if(NULL==X11NewtWindowClazz) {
-            NewtCommon_FatalError(env, "NEWT X11Window: can't use %s", ClazzNameX11NewtWindow);
-        }
-    }
-
-    displayCompletedID = (*env)->GetMethodID(env, clazz, "displayCompleted", "(JJ)V");
-    getCurrentThreadNameID = (*env)->GetStaticMethodID(env, X11NewtWindowClazz, "getCurrentThreadName", "()Ljava/lang/String;");
-    dumpStackID = (*env)->GetStaticMethodID(env, X11NewtWindowClazz, "dumpStack", "()V");
-    insetsChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "insetsChanged", "(ZIIII)V");
-    sizeChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sizeChanged", "(ZIIZ)V");
-    positionChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "positionChanged", "(ZII)V");
-    focusChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "focusChanged", "(ZZ)V");
-    visibleChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "visibleChanged", "(ZZ)V");
-    reparentNotifyID = (*env)->GetMethodID(env, X11NewtWindowClazz, "reparentNotify", "(J)V");
-    windowDestroyNotifyID = (*env)->GetMethodID(env, X11NewtWindowClazz, "windowDestroyNotify", "(Z)Z");
-    windowRepaintID = (*env)->GetMethodID(env, X11NewtWindowClazz, "windowRepaint", "(ZIIII)V");
-    enqueueMouseEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "enqueueMouseEvent", "(ZIIIIII)V");
-    sendMouseEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendMouseEvent", "(IIIIII)V");
-    enqueueKeyEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "enqueueKeyEvent", "(ZIIIC)V");
-    sendKeyEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendKeyEvent", "(IIIC)V");
-    requestFocusID = (*env)->GetMethodID(env, X11NewtWindowClazz, "requestFocus", "(Z)V");
-
-    if (displayCompletedID == NULL ||
-        getCurrentThreadNameID == NULL ||
-        dumpStackID == NULL ||
-        insetsChangedID == NULL ||
-        sizeChangedID == NULL ||
-        positionChangedID == NULL ||
-        focusChangedID == NULL ||
-        visibleChangedID == NULL ||
-        reparentNotifyID == NULL ||
-        windowDestroyNotifyID == NULL ||
-        windowRepaintID == NULL ||
-        enqueueMouseEventID == NULL ||
-        sendMouseEventID == NULL ||
-        enqueueKeyEventID == NULL ||
-        sendKeyEventID == NULL ||
-        requestFocusID == NULL) {
-        return JNI_FALSE;
-    }
-
-
-    return JNI_TRUE;
-}
-
-/*
- * Class:     jogamp_newt_driver_x11_X11Display
- * Method:    CompleteDisplay
- * Signature: (J)V
- */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_CompleteDisplay0
-  (JNIEnv *env, jobject obj, jlong display)
-{
-    Display * dpy = (Display *)(intptr_t)display;
-    jlong javaObjectAtom;
-    jlong windowDeleteAtom;
-
-    if(dpy==NULL) {
-        NewtCommon_FatalError(env, "invalid display connection..");
-    }
-
-    javaObjectAtom = (jlong) XInternAtom(dpy, "NEWT_JAVA_OBJECT", False);
-    if(None==javaObjectAtom) {
-        NewtCommon_throwNewRuntimeException(env, "could not create Atom NEWT_JAVA_OBJECT, bail out!");
-        return;
-    }
-
-    windowDeleteAtom = (jlong) XInternAtom(dpy, "WM_DELETE_WINDOW", False);
-    if(None==windowDeleteAtom) {
-        NewtCommon_throwNewRuntimeException(env, "could not create Atom WM_DELETE_WINDOW, bail out!");
-        return;
-    }
-
-    // XSetCloseDownMode(dpy, RetainTemporary); // Just a try ..
-
-    DBG_PRINT("X11: X11Display_completeDisplay dpy %p\n", dpy);
-
-    (*env)->CallVoidMethod(env, obj, displayCompletedID, javaObjectAtom, windowDeleteAtom);
-}
-
-/*
- * Class:     jogamp_newt_driver_x11_X11Display
- * Method:    DisplayRelease0
- * Signature: (JJJ)V
- */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DisplayRelease0
-  (JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong windowDeleteAtom)
-{
-    Display * dpy = (Display *)(intptr_t)display;
-    Atom wm_javaobject_atom = (Atom)javaObjectAtom;
-    Atom wm_delete_atom = (Atom)windowDeleteAtom;
-
-    if(dpy==NULL) {
-        NewtCommon_FatalError(env, "invalid display connection..");
-    }
-
-    // nothing to do to free the atoms !
-    (void) wm_javaobject_atom;
-    (void) wm_delete_atom;
-
-    XSync(dpy, True); // discard all pending events
-    DBG_PRINT("X11: X11Display_DisplayRelease dpy %p\n", dpy);
-}
-
-/*
- * Class:     jogamp_newt_driver_x11_X11Display
- * Method:    DispatchMessages
- * Signature: (JIJJ)V
- */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0
-  (JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong windowDeleteAtom)
-{
-    Display * dpy = (Display *) (intptr_t) display;
+void X11EventPoll(JNIEnv *env, jobject obj, Display *dpy, jlong javaObjectAtom, jlong windowDeleteAtom) {
     Atom wm_delete_atom = (Atom)windowDeleteAtom;
     int num_events = 100;
+    int autoRepeatModifiers = 0;
 
     if ( NULL == dpy ) {
         return;
@@ -415,10 +20,12 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0
         char text[255];
 
         // XEventsQueued(dpy, X):
-        //   QueuedAlready                 : No I/O Flush or system call  doesn't work on some cards (eg ATI) ?) 
+        //   QueuedAlready    == XQLength(): No I/O Flush or system call  doesn't work on some cards (eg ATI) ?) 
         //   QueuedAfterFlush == XPending(): I/O Flush only if no already queued events are available
         //   QueuedAfterReading            : QueuedAlready + if queue==0, attempt to read more ..
-        if ( 0 >= XPending(dpy) ) {
+        // if ( 0 >= XPending(dpy) ) 
+        if ( 0 >= XEventsQueued(dpy, QueuedAfterFlush) )
+        {
             // DBG_PRINT( "X11: DispatchMessages 0x%X - Leave 1\n", dpy); 
             return;
         }
@@ -426,19 +33,17 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0
         XNextEvent(dpy, &evt);
         num_events--;
 
-        if( 0==evt.xany.window ) {
-            NewtCommon_throwNewRuntimeException(env, "event window NULL, bail out!");
-            return ;
-        }
-
         if(dpy!=evt.xany.display) {
             NewtCommon_throwNewRuntimeException(env, "wrong display, bail out!");
             return ;
         }
 
-        // DBG_PRINT( "X11: DispatchMessages dpy %p, win %p, Event %d\n", (void*)dpy, (void*)evt.xany.window, (int)evt.type);
+        if( 0==evt.xany.window ) {
+            DBG_PRINT( "X11: DispatchMessages dpy %p, Event %d - Window NULL, ignoring\n", (void*)dpy, (int)evt.type);
+            continue;
+        }
 
-        NewtDisplay_x11ErrorHandlerEnable(env, dpy, 1, 0, 0);
+        // DBG_PRINT( "X11: DispatchMessages dpy %p, win %p, Event %d\n", (void*)dpy, (void*)evt.xany.window, (int)evt.type);
 
         jwindow = getJavaWindowProperty(env, dpy, evt.xany.window, javaObjectAtom,
         #ifdef VERBOSE_ON
@@ -448,16 +53,26 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0
         #endif
             );
 
-        NewtDisplay_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
-
         if(NULL==jwindow) {
-            fprintf(stderr, "Warning: NEWT X11 DisplayDispatch %p, Couldn't handle event %d for X11 window %p\n", 
-                (void*)dpy, evt.type, (void*)evt.xany.window);
+            fprintf(stderr, "Warning: NEWT X11 DisplayDispatch %p, Couldn't handle event %d for X11 window %p\n", (void*)dpy, evt.type, (void*)evt.xany.window);
             continue;
         }
  
         switch(evt.type) {
             case KeyRelease:
+                if (XEventsQueued(dpy, QueuedAfterReading)) {
+                  XEvent nevt;
+                  XPeekEvent(dpy, &nevt);
+
+                  if (nevt.type == KeyPress && nevt.xkey.time == evt.xkey.time &&
+                      nevt.xkey.keycode == evt.xkey.keycode)
+                  {
+                    autoRepeatModifiers |= EVENT_AUTOREPEAT_MASK;
+                  } else {
+                    autoRepeatModifiers &= ~EVENT_AUTOREPEAT_MASK;
+                  }
+                }
+                // fall through intended
             case KeyPress:
                 if(XLookupString(&evt.xkey,text,255,&keySym,0)==1) {
                     KeySym lower_return = 0, upper_return = 0;
@@ -469,13 +84,13 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0
                     keyChar=0;
                     keySym = X11KeySym2NewtVKey(keySym);
                 }
-                modifiers = X11InputState2NewtModifiers(evt.xkey.state);
+                modifiers |= X11InputState2NewtModifiers(evt.xkey.state) | autoRepeatModifiers;
                 break;
 
             case ButtonPress:
             case ButtonRelease:
             case MotionNotify:
-                modifiers = X11InputState2NewtModifiers(evt.xbutton.state);
+                modifiers |= X11InputState2NewtModifiers(evt.xbutton.state);
                 break;
 
             default:
@@ -694,5 +309,3 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0
         }
     }
 }
-
-
diff --git a/src/newt/native/X11Event.h b/src/newt/native/X11Event.h
new file mode 100644
index 0000000..969bcde
--- /dev/null
+++ b/src/newt/native/X11Event.h
@@ -0,0 +1,9 @@
+
+#ifndef _X11Event_h
+#define _X11Event_h
+
+#include "X11Common.h"
+
+extern void X11EventPoll(JNIEnv *env, jobject obj, Display *dpy, jlong javaObjectAtom, jlong wmDeleteAtom);
+
+#endif /* _X11Event_h */
diff --git a/src/newt/native/X11Screen.c b/src/newt/native/X11Screen.c
index 698eed8..e8a3ca6 100644
--- a/src/newt/native/X11Screen.c
+++ b/src/newt/native/X11Screen.c
@@ -36,11 +36,11 @@
 #endif
 
 /*
- * Class:     jogamp_newt_driver_x11_X11Screen
+ * Class:     jogamp_newt_driver_x11_ScreenDriver
  * Method:    GetScreen
  * Signature: (JI)J
  */
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Screen_GetScreen0
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_GetScreen0
   (JNIEnv *env, jclass clazz, jlong display, jint screen_index)
 {
     Display * dpy = (Display *)(intptr_t)display;
@@ -60,14 +60,14 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Screen_GetScreen0
     return (jlong) (intptr_t) scrn;
 }
 
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getWidth0
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getWidth0
   (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
 {
     Display * dpy = (Display *) (intptr_t) display;
     return (jint) DisplayWidth( dpy, scrn_idx);
 }
 
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getHeight0
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getHeight0
   (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
 {
     Display * dpy = (Display *) (intptr_t) display;
@@ -112,11 +112,11 @@ static int NewtScreen_XRotation2Degree(JNIEnv *env, int xrotation) {
 }
 
 /*
- * Class:     jogamp_newt_driver_x11_X11Screen
+ * Class:     jogamp_newt_driver_x11_ScreenDriver
  * Method:    getAvailableScreenModeRotations0
  * Signature: (JI)I
  */
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getAvailableScreenModeRotations0
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getAvailableScreenModeRotations0
   (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
 {
     Display *dpy = (Display *) (intptr_t) display;
@@ -162,11 +162,11 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getAvailableSc
 }
 
 /*
- * Class:     jogamp_newt_driver_x11_X11Screen
+ * Class:     jogamp_newt_driver_x11_ScreenDriver
  * Method:    getNumScreenModeResolution0
  * Signature: (JI)I
  */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getNumScreenModeResolutions0
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getNumScreenModeResolutions0
   (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
 {
     Display *dpy = (Display *) (intptr_t) display;
@@ -177,7 +177,7 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getNumScreenModeRes
 #endif
     
     if(False == NewtScreen_hasRANDR(dpy)) {
-        DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getNumScreenModeResolutions0: RANDR not available\n");
+        DBG_PRINT("Java_jogamp_newt_driver_x11_ScreenDriver_getNumScreenModeResolutions0: RANDR not available\n");
         return 0;
     }
 
@@ -200,17 +200,17 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getNumScreenModeRes
 }
 
 /*
- * Class:     jogamp_newt_driver_x11_X11Screen
+ * Class:     jogamp_newt_driver_x11_ScreenDriver
  * Method:    getScreenModeResolutions0
  * Signature: (JII)[I
  */
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenModeResolution0
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getScreenModeResolution0
   (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx)
 {
     Display *dpy = (Display *) (intptr_t) display;
     
     if(False == NewtScreen_hasRANDR(dpy)) {
-        DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getScreenModeResolution0: RANDR not available\n");
+        DBG_PRINT("Java_jogamp_newt_driver_x11_ScreenDriver_getScreenModeResolution0: RANDR not available\n");
         return (*env)->NewIntArray(env, 0);
     }
 
@@ -242,17 +242,17 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenModeR
 }
 
 /*
- * Class:     jogamp_newt_driver_x11_X11Screen
+ * Class:     jogamp_newt_driver_x11_ScreenDriver
  * Method:    getScreenModeRates0
  * Signature: (JII)[I
  */
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenModeRates0
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getScreenModeRates0
   (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx)
 {
     Display *dpy = (Display *) (intptr_t) display;
     
     if(False == NewtScreen_hasRANDR(dpy)) {
-        DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getScreenModeRates0: RANDR not available\n");
+        DBG_PRINT("Java_jogamp_newt_driver_x11_ScreenDriver_getScreenModeRates0: RANDR not available\n");
         return (*env)->NewIntArray(env, 0);
     }
 
@@ -285,11 +285,11 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenModeR
 }
 
 /*
- * Class:     jogamp_newt_driver_x11_X11Screen
+ * Class:     jogamp_newt_driver_x11_ScreenDriver
  * Method:    getScreenConfiguration0
  * Signature: (JI)J
  */
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenConfiguration0
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getScreenConfiguration0
   (JNIEnv *env, jclass clazz, jlong display, jint screen_idx) 
 {
     Display *dpy = (Display *) (intptr_t) display;
@@ -301,7 +301,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenConfigura
 #endif
 
     if(False == NewtScreen_hasRANDR(dpy)) {
-        DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getScreenConfiguration0: RANDR not available\n");
+        DBG_PRINT("Java_jogamp_newt_driver_x11_ScreenDriver_getScreenConfiguration0: RANDR not available\n");
         return 0;
     }
 #ifdef DBG_PERF
@@ -320,22 +320,22 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenConfigura
 }
 
 /*
- * Class:     jogamp_newt_driver_x11_X11Screen
+ * Class:     jogamp_newt_driver_x11_ScreenDriver
  * Method:    freeScreenConfiguration0
  * Signature: (J)V
  */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Screen_freeScreenConfiguration0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_freeScreenConfiguration0
   (JNIEnv *env, jclass clazz, jlong screenConfiguration) 
 {
     XRRFreeScreenConfigInfo( (XRRScreenConfiguration *) (intptr_t) screenConfiguration );
 }
 
 /*
- * Class:     jogamp_newt_driver_x11_X11Screen
+ * Class:     jogamp_newt_driver_x11_ScreenDriver
  * Method:    getCurrentScreenRate0
  * Signature: (J)I
  */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRate0
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getCurrentScreenRate0
   (JNIEnv *env, jclass clazz, jlong screenConfiguration) 
 {
     XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration;
@@ -347,11 +347,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRat
 }
 
 /*
- * Class:     jogamp_newt_driver_x11_X11Screen
+ * Class:     jogamp_newt_driver_x11_ScreenDriver
  * Method:    getCurrentScreenRotation0
  * Signature: (J)I
  */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRotation0
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getCurrentScreenRotation0
   (JNIEnv *env, jclass clazz, jlong screenConfiguration)
 {
     XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration;
@@ -364,11 +364,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRot
 
 
 /*
- * Class:     jogamp_newt_driver_x11_X11Screen
+ * Class:     jogamp_newt_driver_x11_ScreenDriver
  * Method:    getCurrentScreenResolutionIndex0
  * Signature: (J)I
  */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenResolutionIndex0
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getCurrentScreenResolutionIndex0
   (JNIEnv *env, jclass clazz, jlong screenConfiguration)
 {
    XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration;
@@ -383,11 +383,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRes
 }
 
 /*
- * Class:     jogamp_newt_driver_x11_X11Screen
+ * Class:     jogamp_newt_driver_x11_ScreenDriver
  * Method:    setCurrentScreenModeStart0
  * Signature: (JIJIII)Z
  */
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModeStart0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_setCurrentScreenModeStart0
   (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jlong screenConfiguration, jint resMode_idx, jint freq, jint rotation)
 {
     Display *dpy = (Display *) (intptr_t) display;
@@ -432,11 +432,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScree
 }
 
 /*
- * Class:     jogamp_newt_driver_x11_X11Screen
+ * Class:     jogamp_newt_driver_x11_ScreenDriver
  * Method:    setCurrentScreenModePollEnd0
  * Signature: (J)Z
  */
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModePollEnd0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_setCurrentScreenModePollEnd0
   (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jint resMode_idx, jint freq, jint rotation)
 {
     Display *dpy = (Display *) (intptr_t) display;
@@ -445,7 +445,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScree
     XRRScreenChangeNotifyEvent * scn_event = (XRRScreenChangeNotifyEvent *) &evt;
 
     if(False == NewtScreen_hasRANDR(dpy)) {
-        DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModePollEnd0: RANDR not available\n");
+        DBG_PRINT("Java_jogamp_newt_driver_x11_ScreenDriver_setCurrentScreenModePollEnd0: RANDR not available\n");
         return JNI_FALSE;
     }
 
@@ -469,15 +469,22 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScree
 
         switch (evt.type - randr_event_base) {
             case RRScreenChangeNotify:
-                rot = NewtScreen_XRotation2Degree(env, (int)scn_event->rotation);
-                DBG_PRINT( "XRANDR: event . RRScreenChangeNotify call %p (root %p) resIdx %d rot %d %dx%d\n", 
-                            (void*)scn_event->window, (void*)scn_event->root, 
-                            (int)scn_event->size_index, rot, 
-                            scn_event->width, scn_event->height);
-                // done = scn_event->size_index == resMode_idx; // not reliable ..
-                done = rot == rotation && 
-                       scn_event->width == xrrs[resMode_idx].width && 
-                       scn_event->height == xrrs[resMode_idx].height;
+                if(0 < scn_event->rotation ) {
+                    rot = NewtScreen_XRotation2Degree(env, (int)scn_event->rotation);
+                    DBG_PRINT( "XRANDR: event . RRScreenChangeNotify call(1) %p (root %p) resIdx %d rot %d %dx%d\n", 
+                                (void*)scn_event->window, (void*)scn_event->root, 
+                                (int)scn_event->size_index, rot, 
+                                scn_event->width, scn_event->height);
+                    // done = scn_event->size_index == resMode_idx; // not reliable ..
+                    done = rot == rotation && 
+                           scn_event->width == xrrs[resMode_idx].width && 
+                           scn_event->height == xrrs[resMode_idx].height;
+                } else {
+                    DBG_PRINT( "XRANDR: event . RRScreenChangeNotify call(0) %p (root %p) resIdx %d %dx%d\n", 
+                                (void*)scn_event->window, (void*)scn_event->root, 
+                                (int)scn_event->size_index,
+                                scn_event->width, scn_event->height);
+                }
                 break;
             default:
                 DBG_PRINT("RANDR: event . unhandled %d 0x%X call %p\n", (int)evt.type, (int)evt.type, (void*)evt.xany.window);
diff --git a/src/newt/native/X11Screen.c b/src/newt/native/X11ScreenRandR11.c
similarity index 54%
copy from src/newt/native/X11Screen.c
copy to src/newt/native/X11ScreenRandR11.c
index 698eed8..bc7d91d 100644
--- a/src/newt/native/X11Screen.c
+++ b/src/newt/native/X11ScreenRandR11.c
@@ -26,97 +26,9 @@
  * or implied, of JogAmp Community.
  */
 
-// #define VERBOSE_ON 1
-// #define DBG_PERF 1
-
 #include "X11Common.h"
 
-#ifdef DBG_PERF
-    #include "timespec.h"
-#endif
-
-/*
- * Class:     jogamp_newt_driver_x11_X11Screen
- * Method:    GetScreen
- * Signature: (JI)J
- */
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Screen_GetScreen0
-  (JNIEnv *env, jclass clazz, jlong display, jint screen_index)
-{
-    Display * dpy = (Display *)(intptr_t)display;
-    Screen  * scrn= NULL;
-
-    DBG_PRINT("X11: X11Screen_GetScreen0 dpy %p START\n", dpy);
-
-    if(dpy==NULL) {
-        NewtCommon_FatalError(env, "invalid display connection..");
-    }
-
-    scrn = ScreenOfDisplay(dpy, screen_index);
-    if(scrn==NULL) {
-        fprintf(stderr, "couldn't get screen idx %d\n", screen_index);
-    }
-    DBG_PRINT("X11: X11Screen_GetScreen0 idx %d -> scrn %p DONE\n", screen_index, scrn);
-    return (jlong) (intptr_t) scrn;
-}
-
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getWidth0
-  (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
-{
-    Display * dpy = (Display *) (intptr_t) display;
-    return (jint) DisplayWidth( dpy, scrn_idx);
-}
-
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getHeight0
-  (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
-{
-    Display * dpy = (Display *) (intptr_t) display;
-    return (jint) DisplayHeight( dpy, scrn_idx);
-}
-
-static int showedRandRVersion = 0;
-
-static Bool NewtScreen_getRANDRVersion(Display *dpy, int *major, int *minor) {
-    if( 0 == XRRQueryVersion(dpy, major, minor) ) {
-        return False;
-    }
-    if(0 == showedRandRVersion) {
-        DBG_PRINT("X11 RandR Version %d.%d\n", *major, *minor);
-        showedRandRVersion = 1;
-    }
-    return True;
-}
-
-static Bool NewtScreen_hasRANDR(Display *dpy) {
-    int major, minor;
-    return NewtScreen_getRANDRVersion(dpy, &major, &minor);
-}
-
-static int NewtScreen_XRotation2Degree(JNIEnv *env, int xrotation) {
-    int rot;
-    if(xrotation == RR_Rotate_0) {
-      rot = 0;
-    }
-    else if(xrotation == RR_Rotate_90) {
-      rot = 90;
-    }
-    else if(xrotation == RR_Rotate_180) {
-      rot = 180;
-    }
-    else if(xrotation == RR_Rotate_270) {
-      rot = 270;
-    } else {
-      NewtCommon_throwNewRuntimeException(env, "invalid native rotation: %d", xrotation);
-    }
-    return rot;
-}
-
-/*
- * Class:     jogamp_newt_driver_x11_X11Screen
- * Method:    getAvailableScreenModeRotations0
- * Signature: (JI)I
- */
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getAvailableScreenModeRotations0
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getAvailableScreenModeRotations0_RandR11
   (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
 {
     Display *dpy = (Display *) (intptr_t) display;
@@ -161,59 +73,30 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getAvailableSc
     return properties;
 }
 
-/*
- * Class:     jogamp_newt_driver_x11_X11Screen
- * Method:    getNumScreenModeResolution0
- * Signature: (JI)I
- */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getNumScreenModeResolutions0
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getNumScreenModeResolutions0_RandR11
   (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
 {
     Display *dpy = (Display *) (intptr_t) display;
-#ifdef DBG_PERF
-    struct timespec t0, t1, td;
-    long td_ms;
-    timespec_now(&t0);
-#endif
+    Window root = RootWindow(dpy, (int)scrn_idx);
     
-    if(False == NewtScreen_hasRANDR(dpy)) {
-        DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getNumScreenModeResolutions0: RANDR not available\n");
-        return 0;
-    }
-
-#ifdef DBG_PERF
-    timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td);
-    fprintf(stderr, "X11Screen_getNumScreenModeResolution0.1: %ld ms\n", td_ms); fflush(NULL);
-#endif
-
     int num_sizes;   
     XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
     
-#ifdef DBG_PERF
-    timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td);
-    fprintf(stderr, "X11Screen_getNumScreenModeResolution0.2 (XRRSizes): %ld ms\n", td_ms); fflush(NULL);
-#endif
-
-    DBG_PRINT("getNumScreenModeResolutions0: %p:%d -> %d\n", dpy, (int)scrn_idx, num_sizes);
+    DBG_PRINT("getNumScreenModeResolutions0: %d\n", num_sizes);
 
     return num_sizes;
 }
 
 /*
- * Class:     jogamp_newt_driver_x11_X11Screen
- * Method:    getScreenModeResolutions0
+ * Class:     jogamp_newt_driver_x11_ScreenDriver
+ * Method:    getScreenModeResolutions0_RandR11
  * Signature: (JII)[I
  */
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenModeResolution0
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getScreenModeResolution0_RandR11
   (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx)
 {
     Display *dpy = (Display *) (intptr_t) display;
     
-    if(False == NewtScreen_hasRANDR(dpy)) {
-        DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getScreenModeResolution0: RANDR not available\n");
-        return (*env)->NewIntArray(env, 0);
-    }
-
     int num_sizes;   
     XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
 
@@ -242,20 +125,15 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenModeR
 }
 
 /*
- * Class:     jogamp_newt_driver_x11_X11Screen
- * Method:    getScreenModeRates0
+ * Class:     jogamp_newt_driver_x11_ScreenDriver
+ * Method:    getScreenModeRates0_RandR11
  * Signature: (JII)[I
  */
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenModeRates0
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getScreenModeRates0_RandR11
   (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx)
 {
     Display *dpy = (Display *) (intptr_t) display;
     
-    if(False == NewtScreen_hasRANDR(dpy)) {
-        DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getScreenModeRates0: RANDR not available\n");
-        return (*env)->NewIntArray(env, 0);
-    }
-
     int num_sizes;   
     XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
 
@@ -285,139 +163,100 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenModeR
 }
 
 /*
- * Class:     jogamp_newt_driver_x11_X11Screen
- * Method:    getScreenConfiguration0
- * Signature: (JI)J
+ * Class:     jogamp_newt_driver_x11_ScreenDriver
+ * Method:    getCurrentScreenRate0_RandR11
+ * Signature: (JI)I
  */
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenConfiguration0
-  (JNIEnv *env, jclass clazz, jlong display, jint screen_idx) 
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getCurrentScreenRate0_RandR11
+  (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx) 
 {
     Display *dpy = (Display *) (intptr_t) display;
-    Window root = RootWindow(dpy, (int)screen_idx);
-#ifdef DBG_PERF
-    struct timespec t0, t1, td;
-    long td_ms;
-    timespec_now(&t0);
-#endif
-
-    if(False == NewtScreen_hasRANDR(dpy)) {
-        DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getScreenConfiguration0: RANDR not available\n");
-        return 0;
-    }
-#ifdef DBG_PERF
-    timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td);
-    fprintf(stderr, "X11Screen_getScreenConfiguration0.1: %ld ms\n", td_ms); fflush(NULL);
-#endif
-
+    Window root = RootWindow(dpy, (int)scrn_idx);
+    
     // get current resolutions and frequencies
     XRRScreenConfiguration  *conf = XRRGetScreenInfo(dpy, root);
-#ifdef DBG_PERF
-    timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td);
-    fprintf(stderr, "X11Screen_getScreenConfiguration0.2 (XRRGetScreenInfo): %ld ms\n", td_ms); fflush(NULL);
-#endif
-
-    return (jlong) (intptr_t) conf;
-}
-
-/*
- * Class:     jogamp_newt_driver_x11_X11Screen
- * Method:    freeScreenConfiguration0
- * Signature: (J)V
- */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Screen_freeScreenConfiguration0
-  (JNIEnv *env, jclass clazz, jlong screenConfiguration) 
-{
-    XRRFreeScreenConfigInfo( (XRRScreenConfiguration *) (intptr_t) screenConfiguration );
-}
+    short original_rate = XRRConfigCurrentRate(conf);
 
-/*
- * Class:     jogamp_newt_driver_x11_X11Screen
- * Method:    getCurrentScreenRate0
- * Signature: (J)I
- */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRate0
-  (JNIEnv *env, jclass clazz, jlong screenConfiguration) 
-{
-    XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration;
+    //free
+    XRRFreeScreenConfigInfo(conf);
     
-    short original_rate = XRRConfigCurrentRate(conf);
     DBG_PRINT("getCurrentScreenRate0: %d\n", (int)original_rate);
 
     return (jint) original_rate;
 }
 
 /*
- * Class:     jogamp_newt_driver_x11_X11Screen
- * Method:    getCurrentScreenRotation0
- * Signature: (J)I
+ * Class:     jogamp_newt_driver_x11_ScreenDriver
+ * Method:    getCurrentScreenRotation0_RandR11
+ * Signature: (JI)I
  */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRotation0
-  (JNIEnv *env, jclass clazz, jlong screenConfiguration)
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getCurrentScreenRotation0_RandR11
+  (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
 {
-    XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration;
+    Display *dpy = (Display *) (intptr_t) display;
+    Window root = RootWindow(dpy, (int)scrn_idx);
+    
+    //get current resolutions and frequencies
+    XRRScreenConfiguration  *conf = XRRGetScreenInfo(dpy, root);
+    
     Rotation rotation;
-
     XRRConfigCurrentConfiguration(conf, &rotation);
 
+    //free
+    XRRFreeScreenConfigInfo(conf);
+    
     return NewtScreen_XRotation2Degree(env, rotation);
 }
 
 
 /*
- * Class:     jogamp_newt_driver_x11_X11Screen
- * Method:    getCurrentScreenResolutionIndex0
- * Signature: (J)I
+ * Class:     jogamp_newt_driver_x11_ScreenDriver
+ * Method:    getCurrentScreenResolutionIndex0_RandR11
+ * Signature: (JI)I
  */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenResolutionIndex0
-  (JNIEnv *env, jclass clazz, jlong screenConfiguration)
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getCurrentScreenResolutionIndex0_RandR11
+  (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
 {
-   XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration;
+   Display *dpy = (Display *) (intptr_t) display;
+   Window root = RootWindow(dpy, (int)scrn_idx);
   
+   // get current resolutions and frequency configuration
+   XRRScreenConfiguration  *conf = XRRGetScreenInfo(dpy, root);
    short original_rate = XRRConfigCurrentRate(conf);
    
    Rotation original_rotation;
    SizeID original_size_id = XRRConfigCurrentConfiguration(conf, &original_rotation);
    
+   //free
+   XRRFreeScreenConfigInfo(conf);
+   
    DBG_PRINT("getCurrentScreenResolutionIndex0: %d\n", (int)original_size_id);
-   return (jint)original_size_id; 
+   return (jint)original_size_id;   
 }
 
 /*
- * Class:     jogamp_newt_driver_x11_X11Screen
- * Method:    setCurrentScreenModeStart0
- * Signature: (JIJIII)Z
+ * Class:     jogamp_newt_driver_x11_ScreenDriver
+ * Method:    setCurrentScreenModeStart0_RandR11
+ * Signature: (JIIII)Z
  */
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModeStart0
-  (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jlong screenConfiguration, jint resMode_idx, jint freq, jint rotation)
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_setCurrentScreenModeStart0_RandR11
+  (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jint resMode_idx, jint freq, jint rotation)
 {
     Display *dpy = (Display *) (intptr_t) display;
-    XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration;
     Window root = RootWindow(dpy, (int)screen_idx);
 
     int num_sizes;   
     XRRScreenSize *xrrs = XRRSizes(dpy, (int)screen_idx, &num_sizes); //get possible screen resolutions
+    XRRScreenConfiguration *conf;
     int rot;
     
     if( 0 > resMode_idx || resMode_idx >= num_sizes ) {
         NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes);
     }
 
-    switch(rotation) {
-        case   0:
-            rot = RR_Rotate_0; 
-            break;
-        case  90:
-            rot = RR_Rotate_90; 
-            break;
-        case 180:
-            rot = RR_Rotate_180; 
-            break;
-        case 270:
-            rot = RR_Rotate_270; 
-            break;
-        default:
-            NewtCommon_throwNewRuntimeException(env, "Invalid rotation: %d", rotation);
-    }
+    conf = XRRGetScreenInfo(dpy, root);
+   
+    rot = int NewtScreen_Degree2XRotation(env, rotation);
     
     DBG_PRINT("X11Screen.setCurrentScreenMode0: CHANGED TO %d: %d x %d PIXELS, %d Hz, %d degree\n", 
         resMode_idx, xrrs[resMode_idx].width, xrrs[resMode_idx].height, (int)freq, rotation);
@@ -428,15 +267,19 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScree
     XRRSetScreenConfigAndRate(dpy, conf, root, (int)resMode_idx, rot, (short)freq, CurrentTime);   
     XSync(dpy, False);
 
+    //free
+    XRRFreeScreenConfigInfo(conf);
+    XSync(dpy, False);
+
     return JNI_TRUE;
 }
 
 /*
- * Class:     jogamp_newt_driver_x11_X11Screen
- * Method:    setCurrentScreenModePollEnd0
+ * Class:     jogamp_newt_driver_x11_ScreenDriver
+ * Method:    setCurrentScreenModePollEnd0_RandR11
  * Signature: (J)Z
  */
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModePollEnd0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_setCurrentScreenModePollEnd0_RandR11
   (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jint resMode_idx, jint freq, jint rotation)
 {
     Display *dpy = (Display *) (intptr_t) display;
@@ -444,11 +287,6 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScree
     XEvent evt;
     XRRScreenChangeNotifyEvent * scn_event = (XRRScreenChangeNotifyEvent *) &evt;
 
-    if(False == NewtScreen_hasRANDR(dpy)) {
-        DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModePollEnd0: RANDR not available\n");
-        return JNI_FALSE;
-    }
-
     int num_sizes;   
     XRRScreenSize *xrrs = XRRSizes(dpy, (int)screen_idx, &num_sizes); //get possible screen resolutions
     XRRScreenConfiguration *conf;
diff --git a/src/newt/native/X11Screen.c b/src/newt/native/X11ScreenRandR13.c
similarity index 55%
copy from src/newt/native/X11Screen.c
copy to src/newt/native/X11ScreenRandR13.c
index 698eed8..da90d15 100644
--- a/src/newt/native/X11Screen.c
+++ b/src/newt/native/X11ScreenRandR13.c
@@ -26,97 +26,36 @@
  * or implied, of JogAmp Community.
  */
 
-// #define VERBOSE_ON 1
-// #define DBG_PERF 1
-
 #include "X11Common.h"
 
-#ifdef DBG_PERF
-    #include "timespec.h"
-#endif
-
-/*
- * Class:     jogamp_newt_driver_x11_X11Screen
- * Method:    GetScreen
- * Signature: (JI)J
- */
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Screen_GetScreen0
-  (JNIEnv *env, jclass clazz, jlong display, jint screen_index)
-{
-    Display * dpy = (Display *)(intptr_t)display;
-    Screen  * scrn= NULL;
-
-    DBG_PRINT("X11: X11Screen_GetScreen0 dpy %p START\n", dpy);
-
-    if(dpy==NULL) {
-        NewtCommon_FatalError(env, "invalid display connection..");
-    }
-
-    scrn = ScreenOfDisplay(dpy, screen_index);
-    if(scrn==NULL) {
-        fprintf(stderr, "couldn't get screen idx %d\n", screen_index);
-    }
-    DBG_PRINT("X11: X11Screen_GetScreen0 idx %d -> scrn %p DONE\n", screen_index, scrn);
-    return (jlong) (intptr_t) scrn;
-}
-
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getWidth0
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getOrigin0_RandR13
   (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
 {
     Display * dpy = (Display *) (intptr_t) display;
-    return (jint) DisplayWidth( dpy, scrn_idx);
-}
-
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getHeight0
-  (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
-{
-    Display * dpy = (Display *) (intptr_t) display;
-    return (jint) DisplayHeight( dpy, scrn_idx);
-}
-
-static int showedRandRVersion = 0;
+    Window root = RootWindow(dpy, (int)scrn_idx);
+    int pos[] = { 0, 0 } ;
 
-static Bool NewtScreen_getRANDRVersion(Display *dpy, int *major, int *minor) {
-    if( 0 == XRRQueryVersion(dpy, major, minor) ) {
-        return False;
-    }
-    if(0 == showedRandRVersion) {
-        DBG_PRINT("X11 RandR Version %d.%d\n", *major, *minor);
-        showedRandRVersion = 1;
+    int i;
+    XRRScreenResources *xrrScreenResources = XRRGetScreenResources(dpy, root);
+    fprintf(stderr, "XRRScreenResources %p: RRCrtc crtcs %d\n", xrrScreenResources, xrrScreenResources->ncrtc);
+    for(i=0; i<xrrScreenResources->ncrtc; i++) {
+        RRCrtc crtc = xrrScreenResources->crtcs[i];
+        XRRCrtcInfo *xrrCrtcInfo = XRRGetCrtcInfo (dpy, xrrScreenResources, crtc);
+        fprintf(stderr, "RRCrtc %d: %d/%d %dx%d\n", i, xrrCrtcInfo->x, xrrCrtcInfo->y, xrrCrtcInfo->width, xrrCrtcInfo->height);
+        XRRFreeCrtcInfo(xrrCrtcInfo);
     }
-    return True;
-}
 
-static Bool NewtScreen_hasRANDR(Display *dpy) {
-    int major, minor;
-    return NewtScreen_getRANDRVersion(dpy, &major, &minor);
-}
-
-static int NewtScreen_XRotation2Degree(JNIEnv *env, int xrotation) {
-    int rot;
-    if(xrotation == RR_Rotate_0) {
-      rot = 0;
-    }
-    else if(xrotation == RR_Rotate_90) {
-      rot = 90;
-    }
-    else if(xrotation == RR_Rotate_180) {
-      rot = 180;
-    }
-    else if(xrotation == RR_Rotate_270) {
-      rot = 270;
-    } else {
-      NewtCommon_throwNewRuntimeException(env, "invalid native rotation: %d", xrotation);
+    jintArray jpos = (*env)->NewIntArray(env, num_rotations);
+    if (properties == NULL) {
+        NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", 2);
     }
-    return rot;
+        
+    // move from the temp structure to the java structure
+    (*env)->SetIntArrayRegion(env, jpos, 0, 2, pos);
+    return jpos;
 }
 
-/*
- * Class:     jogamp_newt_driver_x11_X11Screen
- * Method:    getAvailableScreenModeRotations0
- * Signature: (JI)I
- */
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getAvailableScreenModeRotations0
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getAvailableScreenModeRotations0_RandR13
   (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
 {
     Display *dpy = (Display *) (intptr_t) display;
@@ -161,59 +100,46 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getAvailableSc
     return properties;
 }
 
-/*
- * Class:     jogamp_newt_driver_x11_X11Screen
- * Method:    getNumScreenModeResolution0
- * Signature: (JI)I
- */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getNumScreenModeResolutions0
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getNumScreenModeResolutions0_RandR13
   (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
 {
     Display *dpy = (Display *) (intptr_t) display;
-#ifdef DBG_PERF
-    struct timespec t0, t1, td;
-    long td_ms;
-    timespec_now(&t0);
-#endif
+    Window root = RootWindow(dpy, (int)scrn_idx);
     
-    if(False == NewtScreen_hasRANDR(dpy)) {
-        DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getNumScreenModeResolutions0: RANDR not available\n");
-        return 0;
-    }
-
-#ifdef DBG_PERF
-    timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td);
-    fprintf(stderr, "X11Screen_getNumScreenModeResolution0.1: %ld ms\n", td_ms); fflush(NULL);
-#endif
-
     int num_sizes;   
     XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
     
-#ifdef DBG_PERF
-    timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td);
-    fprintf(stderr, "X11Screen_getNumScreenModeResolution0.2 (XRRSizes): %ld ms\n", td_ms); fflush(NULL);
-#endif
+    DBG_PRINT("getNumScreenModeResolutions0: %d\n", num_sizes);
 
-    DBG_PRINT("getNumScreenModeResolutions0: %p:%d -> %d\n", dpy, (int)scrn_idx, num_sizes);
+    int i;
+    XRRScreenResources *xrrScreenResources = XRRGetScreenResources(dpy, root);
+    fprintf(stderr, "XRRScreenResources %p: RRCrtc crtcs %d\n", xrrScreenResources, xrrScreenResources->ncrtc);
+    for(i=0; i<xrrScreenResources->ncrtc; i++) {
+        RRCrtc crtc = xrrScreenResources->crtcs[i];
+        XRRCrtcInfo *xrrCrtcInfo = XRRGetCrtcInfo (dpy, xrrScreenResources, crtc);
+        fprintf(stderr, "RRCrtc %d: %d/%d %dx%d\n", i, xrrCrtcInfo->x, xrrCrtcInfo->y, xrrCrtcInfo->width, xrrCrtcInfo->height);
+        XRRFreeCrtcInfo(xrrCrtcInfo);
+    }
+    fprintf(stderr, "XRRScreenResources %p: XRRModeInfo modes %d\n", xrrScreenResources, xrrScreenResources->nmode);
+    for(i=0; i<xrrScreenResources->nmode; i++) {
+        XRRModeInfo xrrModeInfo = xrrScreenResources->modes[i];
+        fprintf(stderr, "XRRModeInfo %d: %dx%d, %s, %X\n", i, xrrModeInfo.width, xrrModeInfo.height, xrrModeInfo.name, xrrModeInfo.id);
+    }
+    XRRFreeScreenResources(xrrScreenResources);
 
     return num_sizes;
 }
 
 /*
- * Class:     jogamp_newt_driver_x11_X11Screen
- * Method:    getScreenModeResolutions0
+ * Class:     jogamp_newt_driver_x11_ScreenDriver
+ * Method:    getScreenModeResolutions0_RandR13
  * Signature: (JII)[I
  */
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenModeResolution0
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getScreenModeResolution0_RandR13
   (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx)
 {
     Display *dpy = (Display *) (intptr_t) display;
     
-    if(False == NewtScreen_hasRANDR(dpy)) {
-        DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getScreenModeResolution0: RANDR not available\n");
-        return (*env)->NewIntArray(env, 0);
-    }
-
     int num_sizes;   
     XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
 
@@ -242,20 +168,15 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenModeR
 }
 
 /*
- * Class:     jogamp_newt_driver_x11_X11Screen
- * Method:    getScreenModeRates0
+ * Class:     jogamp_newt_driver_x11_ScreenDriver
+ * Method:    getScreenModeRates0_RandR13
  * Signature: (JII)[I
  */
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenModeRates0
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getScreenModeRates0_RandR13
   (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx)
 {
     Display *dpy = (Display *) (intptr_t) display;
     
-    if(False == NewtScreen_hasRANDR(dpy)) {
-        DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getScreenModeRates0: RANDR not available\n");
-        return (*env)->NewIntArray(env, 0);
-    }
-
     int num_sizes;   
     XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
 
@@ -285,139 +206,100 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenModeR
 }
 
 /*
- * Class:     jogamp_newt_driver_x11_X11Screen
- * Method:    getScreenConfiguration0
- * Signature: (JI)J
+ * Class:     jogamp_newt_driver_x11_ScreenDriver
+ * Method:    getCurrentScreenRate0_RandR13
+ * Signature: (JI)I
  */
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenConfiguration0
-  (JNIEnv *env, jclass clazz, jlong display, jint screen_idx) 
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getCurrentScreenRate0_RandR13
+  (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx) 
 {
     Display *dpy = (Display *) (intptr_t) display;
-    Window root = RootWindow(dpy, (int)screen_idx);
-#ifdef DBG_PERF
-    struct timespec t0, t1, td;
-    long td_ms;
-    timespec_now(&t0);
-#endif
-
-    if(False == NewtScreen_hasRANDR(dpy)) {
-        DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getScreenConfiguration0: RANDR not available\n");
-        return 0;
-    }
-#ifdef DBG_PERF
-    timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td);
-    fprintf(stderr, "X11Screen_getScreenConfiguration0.1: %ld ms\n", td_ms); fflush(NULL);
-#endif
-
+    Window root = RootWindow(dpy, (int)scrn_idx);
+    
     // get current resolutions and frequencies
     XRRScreenConfiguration  *conf = XRRGetScreenInfo(dpy, root);
-#ifdef DBG_PERF
-    timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td);
-    fprintf(stderr, "X11Screen_getScreenConfiguration0.2 (XRRGetScreenInfo): %ld ms\n", td_ms); fflush(NULL);
-#endif
-
-    return (jlong) (intptr_t) conf;
-}
-
-/*
- * Class:     jogamp_newt_driver_x11_X11Screen
- * Method:    freeScreenConfiguration0
- * Signature: (J)V
- */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Screen_freeScreenConfiguration0
-  (JNIEnv *env, jclass clazz, jlong screenConfiguration) 
-{
-    XRRFreeScreenConfigInfo( (XRRScreenConfiguration *) (intptr_t) screenConfiguration );
-}
+    short original_rate = XRRConfigCurrentRate(conf);
 
-/*
- * Class:     jogamp_newt_driver_x11_X11Screen
- * Method:    getCurrentScreenRate0
- * Signature: (J)I
- */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRate0
-  (JNIEnv *env, jclass clazz, jlong screenConfiguration) 
-{
-    XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration;
+    //free
+    XRRFreeScreenConfigInfo(conf);
     
-    short original_rate = XRRConfigCurrentRate(conf);
     DBG_PRINT("getCurrentScreenRate0: %d\n", (int)original_rate);
 
     return (jint) original_rate;
 }
 
 /*
- * Class:     jogamp_newt_driver_x11_X11Screen
- * Method:    getCurrentScreenRotation0
- * Signature: (J)I
+ * Class:     jogamp_newt_driver_x11_ScreenDriver
+ * Method:    getCurrentScreenRotation0_RandR13
+ * Signature: (JI)I
  */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRotation0
-  (JNIEnv *env, jclass clazz, jlong screenConfiguration)
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getCurrentScreenRotation0_RandR13
+  (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
 {
-    XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration;
+    Display *dpy = (Display *) (intptr_t) display;
+    Window root = RootWindow(dpy, (int)scrn_idx);
+    
+    //get current resolutions and frequencies
+    XRRScreenConfiguration  *conf = XRRGetScreenInfo(dpy, root);
+    
     Rotation rotation;
-
     XRRConfigCurrentConfiguration(conf, &rotation);
 
+    //free
+    XRRFreeScreenConfigInfo(conf);
+    
     return NewtScreen_XRotation2Degree(env, rotation);
 }
 
 
 /*
- * Class:     jogamp_newt_driver_x11_X11Screen
- * Method:    getCurrentScreenResolutionIndex0
- * Signature: (J)I
+ * Class:     jogamp_newt_driver_x11_ScreenDriver
+ * Method:    getCurrentScreenResolutionIndex0_RandR13
+ * Signature: (JI)I
  */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenResolutionIndex0
-  (JNIEnv *env, jclass clazz, jlong screenConfiguration)
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getCurrentScreenResolutionIndex0_RandR13
+  (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
 {
-   XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration;
+   Display *dpy = (Display *) (intptr_t) display;
+   Window root = RootWindow(dpy, (int)scrn_idx);
   
+   // get current resolutions and frequency configuration
+   XRRScreenConfiguration  *conf = XRRGetScreenInfo(dpy, root);
    short original_rate = XRRConfigCurrentRate(conf);
    
    Rotation original_rotation;
    SizeID original_size_id = XRRConfigCurrentConfiguration(conf, &original_rotation);
    
+   //free
+   XRRFreeScreenConfigInfo(conf);
+   
    DBG_PRINT("getCurrentScreenResolutionIndex0: %d\n", (int)original_size_id);
-   return (jint)original_size_id; 
+   return (jint)original_size_id;   
 }
 
 /*
- * Class:     jogamp_newt_driver_x11_X11Screen
- * Method:    setCurrentScreenModeStart0
- * Signature: (JIJIII)Z
+ * Class:     jogamp_newt_driver_x11_ScreenDriver
+ * Method:    setCurrentScreenModeStart0_RandR13
+ * Signature: (JIIII)Z
  */
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModeStart0
-  (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jlong screenConfiguration, jint resMode_idx, jint freq, jint rotation)
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_setCurrentScreenModeStart0_RandR13
+  (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jint resMode_idx, jint freq, jint rotation)
 {
     Display *dpy = (Display *) (intptr_t) display;
-    XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration;
     Window root = RootWindow(dpy, (int)screen_idx);
 
     int num_sizes;   
     XRRScreenSize *xrrs = XRRSizes(dpy, (int)screen_idx, &num_sizes); //get possible screen resolutions
+    XRRScreenConfiguration *conf;
     int rot;
     
     if( 0 > resMode_idx || resMode_idx >= num_sizes ) {
         NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes);
     }
 
-    switch(rotation) {
-        case   0:
-            rot = RR_Rotate_0; 
-            break;
-        case  90:
-            rot = RR_Rotate_90; 
-            break;
-        case 180:
-            rot = RR_Rotate_180; 
-            break;
-        case 270:
-            rot = RR_Rotate_270; 
-            break;
-        default:
-            NewtCommon_throwNewRuntimeException(env, "Invalid rotation: %d", rotation);
-    }
+    conf = XRRGetScreenInfo(dpy, root);
+   
+    rot = int NewtScreen_Degree2XRotation(env, rotation);
     
     DBG_PRINT("X11Screen.setCurrentScreenMode0: CHANGED TO %d: %d x %d PIXELS, %d Hz, %d degree\n", 
         resMode_idx, xrrs[resMode_idx].width, xrrs[resMode_idx].height, (int)freq, rotation);
@@ -428,15 +310,19 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScree
     XRRSetScreenConfigAndRate(dpy, conf, root, (int)resMode_idx, rot, (short)freq, CurrentTime);   
     XSync(dpy, False);
 
+    //free
+    XRRFreeScreenConfigInfo(conf);
+    XSync(dpy, False);
+
     return JNI_TRUE;
 }
 
 /*
- * Class:     jogamp_newt_driver_x11_X11Screen
- * Method:    setCurrentScreenModePollEnd0
+ * Class:     jogamp_newt_driver_x11_ScreenDriver
+ * Method:    setCurrentScreenModePollEnd0_RandR13
  * Signature: (J)Z
  */
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModePollEnd0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_setCurrentScreenModePollEnd0_RandR13
   (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jint resMode_idx, jint freq, jint rotation)
 {
     Display *dpy = (Display *) (intptr_t) display;
@@ -444,11 +330,6 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScree
     XEvent evt;
     XRRScreenChangeNotifyEvent * scn_event = (XRRScreenChangeNotifyEvent *) &evt;
 
-    if(False == NewtScreen_hasRANDR(dpy)) {
-        DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModePollEnd0: RANDR not available\n");
-        return JNI_FALSE;
-    }
-
     int num_sizes;   
     XRRScreenSize *xrrs = XRRSizes(dpy, (int)screen_idx, &num_sizes); //get possible screen resolutions
     XRRScreenConfiguration *conf;
diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c
index daf9f2b..202ad6f 100644
--- a/src/newt/native/X11Window.c
+++ b/src/newt/native/X11Window.c
@@ -467,11 +467,11 @@ static void NewtWindows_requestFocus (JNIEnv *env, jobject window, Display *dpy,
  */
 
 /*
- * Class:     jogamp_newt_driver_x11_X11Window
+ * Class:     jogamp_newt_driver_x11_WindowDriver
  * Method:    initIDs
  * Signature: ()Z
  */
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Window_initIDs0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_WindowDriver_initIDs0
   (JNIEnv *env, jclass clazz)
 {
     return JNI_TRUE;
@@ -505,10 +505,10 @@ static void NewtWindows_setPosSize(Display *dpy, Window w, jint x, jint y, jint
 }
 
 /*
- * Class:     jogamp_newt_driver_x11_X11Window
+ * Class:     jogamp_newt_driver_x11_WindowDriver
  * Method:    CreateWindow
  */
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Window_CreateWindow0
+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, 
@@ -666,11 +666,11 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Window_CreateWindow0
 }
 
 /*
- * Class:     jogamp_newt_driver_x11_X11Window
+ * Class:     jogamp_newt_driver_x11_WindowDriver
  * Method:    CloseWindow
  * Signature: (JJ)V
  */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_CloseWindow0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CloseWindow0
   (JNIEnv *env, jobject obj, jlong display, jlong window, jlong javaObjectAtom, jlong windowDeleteAtom)
 {
     Display * dpy = (Display *) (intptr_t) display;
@@ -683,16 +683,12 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_CloseWindow0
 
     DBG_PRINT( "X11: CloseWindow START dpy %p, win %p\n", (void*)dpy, (void*)w);
 
-    NewtDisplay_x11ErrorHandlerEnable(env, dpy, 1, 0, 0);
-
     jwindow = getJavaWindowProperty(env, dpy, w, javaObjectAtom, True);
     if(NULL==jwindow) {
-        NewtDisplay_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
         NewtCommon_throwNewRuntimeException(env, "could not fetch Java Window object, bail out!");
         return;
     }
     if ( JNI_FALSE == (*env)->IsSameObject(env, jwindow, obj) ) {
-        NewtDisplay_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
         NewtCommon_throwNewRuntimeException(env, "Internal Error .. Window global ref not the same!");
         return;
     }
@@ -700,13 +696,12 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_CloseWindow0
     XSync(dpy, False);
     XSelectInput(dpy, w, 0);
     XUnmapWindow(dpy, w);
-    NewtDisplay_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
 
     // Drain all events related to this window ..
-    Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0(env, obj, display, javaObjectAtom, windowDeleteAtom);
+    Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessages0(env, obj, display, javaObjectAtom, windowDeleteAtom);
 
     XDestroyWindow(dpy, w);
-    XSync(dpy, False);
+    XSync(dpy, True); // discard all events now, no more handler
 
     (*env)->DeleteGlobalRef(env, jwindow);
 
@@ -729,11 +724,11 @@ static Bool WaitForReparentNotify( Display *dpy, XEvent *event, XPointer arg ) {
  */
 
 /*
- * Class:     jogamp_newt_driver_x11_X11Window
+ * Class:     jogamp_newt_driver_x11_WindowDriver
  * Method:    reconfigureWindow0
  * Signature: (JIJJIIIII)V
  */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_reconfigureWindow0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindow0
   (JNIEnv *env, jobject obj, jlong jdisplay, jint screen_index,
    jlong jparent, jlong jwindow, jlong windowDeleteAtom,
    jint x, jint y, jint width, jint height, jint flags)
@@ -761,8 +756,6 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_reconfigureWindow0
         fsEWMHFlags |= _NET_WM_ABOVE;         // toggle above
     }
 
-    NewtDisplay_x11ErrorHandlerEnable(env, dpy, 1, 0, 0);
-
     DBG_PRINT( "X11: reconfigureWindow0 dpy %p, scrn %d, parent %p/%p, win %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, tempInvisible %d, fsEWMHFlags %d\n",
         (void*)dpy, screen_index, (void*) jparent, (void*)parent, (void*)w,
         x, y, width, height, 
@@ -779,7 +772,6 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_reconfigureWindow0
         ( TST_FLAG_CHANGE_FULLSCREEN(flags) || TST_FLAG_CHANGE_ALWAYSONTOP(flags) ) ) {
         Bool enable = TST_FLAG_CHANGE_FULLSCREEN(flags) ? TST_FLAG_IS_FULLSCREEN(flags) : TST_FLAG_IS_ALWAYSONTOP(flags) ;
         if( NewtWindows_setFullscreenEWMH(dpy, root, w, fsEWMHFlags, isVisible, enable) ) {
-            NewtDisplay_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
             #ifdef FS_GRAB_KEYBOARD
             if(TST_FLAG_CHANGE_FULLSCREEN(flags)) {
                 if(TST_FLAG_IS_FULLSCREEN(flags)) {
@@ -863,39 +855,37 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_reconfigureWindow0
         #endif
     }
 
-    NewtDisplay_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
-
     DBG_PRINT( "X11: reconfigureWindow0 X\n");
 }
 
 /*
- * Class:     jogamp_newt_driver_x11_X11Window
+ * Class:     jogamp_newt_driver_x11_WindowDriver
  * Method:    requestFocus0
  * Signature: (JJZ)V
  */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_requestFocus0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_requestFocus0
   (JNIEnv *env, jobject obj, jlong display, jlong window, jboolean force)
 {
     NewtWindows_requestFocus ( env, obj, (Display *) (intptr_t) display, (Window)window, force ) ;
 }
 
 /*
- * Class:     jogamp_newt_driver_x11_X11Window
+ * Class:     jogamp_newt_driver_x11_WindowDriver
  * Method:    getParentWindow0
  * Signature: (JJ)J
  */
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Window_getParentWindow0
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_WindowDriver_getParentWindow0
   (JNIEnv *env, jclass clazz, jlong display, jlong window)
 {
     return (jlong) NewtWindows_getParent ((Display *) (intptr_t) display, (Window)window);
 }
 
 /*
- * Class:     Java_jogamp_newt_driver_x11_X11Window
+ * Class:     Java_jogamp_newt_driver_x11_WindowDriver
  * Method:    setTitle0
  * Signature: (JJLjava/lang/String;)V
  */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_setTitle0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_setTitle0
   (JNIEnv *env, jclass clazz, jlong display, jlong window, jstring title)
 {
     Display * dpy = (Display *) (intptr_t) display;
@@ -942,11 +932,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_setTitle0
 }
 
 /*
- * Class:     Java_jogamp_newt_driver_x11_X11Window
+ * Class:     Java_jogamp_newt_driver_x11_WindowDriver
  * Method:    setPointerVisible0
  * Signature: (JJZ)Z
  */
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Window_setPointerVisible0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_WindowDriver_setPointerVisible0
   (JNIEnv *env, jclass clazz, jlong display, jlong window, jboolean mouseVisible)
 {
     static char noData[] = { 0,0,0,0,0,0,0,0 };
@@ -976,11 +966,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Window_setPointerVisib
 }
 
 /*
- * Class:     Java_jogamp_newt_driver_x11_X11Window
+ * Class:     Java_jogamp_newt_driver_x11_WindowDriver
  * Method:    confinePointer0
  * Signature: (JJZ)Z
  */
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Window_confinePointer0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_WindowDriver_confinePointer0
   (JNIEnv *env, jclass clazz, jlong display, jlong window, jboolean confine)
 {
     Display * dpy = (Display *) (intptr_t) display;
@@ -999,11 +989,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Window_confinePointer0
 }
 
 /*
- * Class:     Java_jogamp_newt_driver_x11_X11Window
+ * Class:     Java_jogamp_newt_driver_x11_WindowDriver
  * Method:    warpPointer0
  * Signature: (JJII)V
  */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_warpPointer0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_warpPointer0
   (JNIEnv *env, jclass clazz, jlong display, jlong window, jint x, jint y)
 {
     Display * dpy = (Display *) (intptr_t) display;
diff --git a/src/newt/native/XCBEvent.c b/src/newt/native/XCBEvent.c
new file mode 100644
index 0000000..77a3380
--- /dev/null
+++ b/src/newt/native/XCBEvent.c
@@ -0,0 +1,314 @@
+
+#define VERBOSE_ON 1
+
+#include "XCBEvent.h"
+
+#include <xcb/xcb.h>
+#include <xcb/xcb_event.h>
+#include <xcb/xproto.h>
+#include <xcb/xcb_keysyms.h>
+#include <X11/Xlib-xcb.h>
+
+void XCBSetEventQueueOwner(Display *dpy) {
+    XSetEventQueueOwner(dpy, XCBOwnsEventQueue);
+}
+
+void XCBEventPoll(JNIEnv *env, jobject obj, Display *dpy, jlong javaObjectAtom, jlong wmDeleteAtom) {
+    int num_events = 100;
+    xcb_connection_t *conn = NULL;
+
+    if ( NULL == dpy ) {
+        return;
+    }
+    conn = XGetXCBConnection(dpy);
+
+    // Periodically take a break
+    while( num_events > 0 ) {
+        jobject jwindow = NULL;
+        xcb_generic_event_t *evt;
+        // KeySym keySym = 0;
+        jint modifiers = 0;
+        char keyChar = 0;
+        // char text[255];
+
+        evt = xcb_poll_for_event(conn);
+        if(NULL == evt) {
+            // DBG_PRINT( "X11: DispatchMessages 0x%X - Leave 1\n", dpy); 
+            return;
+        }
+        num_events--;
+
+        /*if( 0==evt.xany.window ) {
+            free(evt);
+            NewtCommon_throwNewRuntimeException(env, "event window NULL, bail out!");
+            return ;
+        }
+
+        if(dpy!=evt.xany.display) {
+            free(evt);
+            NewtCommon_throwNewRuntimeException(env, "wrong display, bail out!");
+            return ;
+        }*/
+
+        // DBG_PRINT( "X11: DispatchMessages dpy %p, win %p, Event %d\n", (void*)dpy, (void*)evt.xany.window, evt.type);
+
+        // X11WindowDisplayErrorHandlerEnable(1, env);
+
+        // jwindow = X11WindowGetJavaWindowProperty(env, dpy, evt.xany.window, javaObjectAtom, VERBOSE_BOOL);
+
+        //X11WindowDisplayErrorHandlerEnable(0, env);
+
+        /*if(NULL==jwindow) {
+            fprintf(stderr, "Warning: NEWT X11 DisplayDispatch %p, Couldn't handle event %d for X11 window %p\n", 
+                (void*)dpy, evt.type, (void*)evt.xany.window);
+            continue;
+        }*/
+ 
+        uint8_t xcb_event_type = evt->response_type & ~0x80;
+        xcb_window_t event_window = 0;
+
+        switch( xcb_event_type ) {
+            case XCB_BUTTON_PRESS:
+            case XCB_BUTTON_RELEASE:
+                event_window = ((xcb_button_press_event_t *)evt)->event;
+                modifiers = X11InputState2NewtModifiers(((xcb_button_press_event_t *)evt)->state);
+                break;
+            case XCB_MOTION_NOTIFY:
+                event_window = ((xcb_motion_notify_event_t *)evt)->event;
+                break;
+            case XCB_KEY_PRESS:
+            case XCB_KEY_RELEASE: {
+                    xcb_key_press_event_t *_evt = (xcb_key_press_event_t *)evt;
+                    event_window = _evt->event;
+                    /*
+                    xcb_keycode_t   detail = _evt->detail;
+                    if(XLookupString(&evt.xkey,text,255,&keySym,0)==1) {
+                        KeySym lower_return = 0, upper_return = 0;
+                        keyChar=text[0];
+                        XConvertCase(keySym, &lower_return, &upper_return);
+                        // always return upper case, set modifier masks (SHIFT, ..)
+                        keySym = upper_return;
+                        modifiers = X11InputState2NewtModifiers(evt.xkey.state);
+                    } else {
+                        keyChar=0;
+                    }*/
+                }
+                break;
+            case  XCB_EXPOSE:
+                event_window = ((xcb_expose_event_t *)evt)->window;
+                break;
+            case XCB_MAP_NOTIFY:
+                event_window = ((xcb_map_notify_event_t *)evt)->window;
+                break;
+            case XCB_UNMAP_NOTIFY:
+                event_window = ((xcb_unmap_notify_event_t *)evt)->window;
+                break;
+        } 
+        if(0==event_window) {
+            fprintf(stderr, "Warning: NEWT X11 DisplayDispatch %p, Couldn't handle event %d, no X11 window associated\n", 
+                (void*)dpy, xcb_event_type);
+            continue;
+        }
+        jwindow = getJavaWindowProperty(env, dpy, event_window, javaObjectAtom,
+        #ifdef VERBOSE_ON
+                True
+        #else
+                False
+        #endif
+            );
+        if(NULL==jwindow) {
+            fprintf(stderr, "Warning: NEWT X11 DisplayDispatch %p, Couldn't handle event %d for X11 window %p\n", 
+                (void*)(intptr_t)dpy, xcb_event_type, (void*)(intptr_t)event_window);
+            continue;
+        }
+
+        switch( xcb_event_type ) {
+            case XCB_BUTTON_PRESS: {
+                    xcb_button_press_event_t *_evt = (xcb_button_press_event_t *)evt;
+                    (*env)->CallVoidMethod(env, jwindow, requestFocusID, JNI_FALSE);
+                    #ifdef USE_SENDIO_DIRECT
+                    (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_PRESSED, 
+                                          modifiers,
+                                          (jint) _evt->event_x, (jint) _evt->event_y, (jint) _evt->state, 0 /*rotation*/);
+                    #else
+                    (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_PRESSED, 
+                                          modifiers,
+                                          (jint) _evt->event_x, (jint) _evt->event_y, (jint) _evt->state, 0 /*rotation*/);
+                    #endif
+                } break;
+            case XCB_BUTTON_RELEASE: {
+                    xcb_button_release_event_t *_evt = (xcb_button_release_event_t *)evt;
+                    #ifdef USE_SENDIO_DIRECT
+                    (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_RELEASED, 
+                                          modifiers,
+                                          (jint) _evt->event_x, (jint) _evt->event_y, (jint) _evt->state, 0 /*rotation*/);
+                    #else
+                    (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_RELEASED, 
+                                          modifiers,
+                                          (jint) _evt->event_x, (jint) _evt->event_y, (jint) _evt->state, 0 /*rotation*/);
+                    #endif
+                } break;
+            case XCB_MOTION_NOTIFY: {
+                    xcb_motion_notify_event_t *_evt = (xcb_motion_notify_event_t *)evt;
+                    #ifdef USE_SENDIO_DIRECT
+                    (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_MOVED, 
+                                          modifiers,
+                                          (jint) _evt->event_x, (jint) _evt->event_y, (jint)0, 0 /*rotation*/);
+                    #else
+                    (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_MOVED, 
+                                          modifiers,
+                                          (jint) _evt->event_x, (jint) _evt->event_y, (jint)0, 0 /*rotation*/);
+                    #endif
+                } break;
+            case XCB_KEY_PRESS: {
+                    xcb_key_press_event_t *_evt = (xcb_key_press_event_t *)evt;
+                    #ifdef USE_SENDIO_DIRECT
+                    (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_PRESSED, 
+                                          modifiers, X11KeySym2NewtVKey(_evt->state), (jchar) keyChar);
+                    #else
+                    (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_PRESSED, 
+                                          modifiers, X11KeySym2NewtVKey(_evt->state), (jchar) keyChar);
+                    #endif
+                } break;
+            case XCB_KEY_RELEASE: {
+                    xcb_key_release_event_t *_evt = (xcb_key_release_event_t *)evt;
+                event_window = ((xcb_key_release_event_t *)evt)->event;
+                #ifdef USE_SENDIO_DIRECT
+                (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_RELEASED, 
+                                      modifiers, X11KeySym2NewtVKey(_evt->state), (jchar) keyChar);
+
+                (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_TYPED, 
+                                      modifiers, (jint) -1, (jchar) keyChar);
+                #else
+                (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_RELEASED, 
+                                      modifiers, X11KeySym2NewtVKey(_evt->state), (jchar) keyChar);
+
+                (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_TYPED, 
+                                      modifiers, (jint) -1, (jchar) keyChar);
+                #endif
+
+                } break;
+                /*
+            case DestroyNotify:
+                DBG_PRINT( "X11: event . DestroyNotify call %p, parent %p, child-event: %d\n", 
+                    (void*)evt.xdestroywindow.window, (void*)evt.xdestroywindow.event, evt.xdestroywindow.window != evt.xdestroywindow.event);
+                if ( evt.xdestroywindow.window == evt.xdestroywindow.event ) {
+                    // ignore child destroy notification
+                }
+                break;
+            case CreateNotify:
+                DBG_PRINT( "X11: event . CreateNotify call %p, parent %p, child-event: 1\n", 
+                    (void*)evt.xcreatewindow.window, (void*) evt.xcreatewindow.parent);
+                break;
+            case ConfigureNotify:
+                DBG_PRINT( "X11: event . ConfigureNotify call %p (parent %p, above %p) %d/%d %dx%d %d, child-event: %d\n", 
+                            (void*)evt.xconfigure.window, (void*)evt.xconfigure.event, (void*)evt.xconfigure.above,
+                            evt.xconfigure.x, evt.xconfigure.y, evt.xconfigure.width, evt.xconfigure.height, 
+                            evt.xconfigure.override_redirect, evt.xconfigure.window != evt.xconfigure.event);
+                if ( evt.xconfigure.window == evt.xconfigure.event ) {
+                    // ignore child window change notification
+                    (*env)->CallVoidMethod(env, jwindow, sizeChangedID, 
+                                            (jint) evt.xconfigure.width, (jint) evt.xconfigure.height, JNI_FALSE);
+                    (*env)->CallVoidMethod(env, jwindow, positionChangedID, 
+                                            (jint) evt.xconfigure.x, (jint) evt.xconfigure.y);
+                }
+                break;
+            case ClientMessage:
+                if (evt.xclient.send_event==True && evt.xclient.data.l[0]==(Atom)wmDeleteAtom) {
+                    DBG_PRINT( "X11: event . ClientMessage call %p type 0x%X !!!\n", 
+                        (void*)evt.xclient.window, (unsigned int)evt.xclient.message_type);
+                    (*env)->CallVoidMethod(env, jwindow, windowDestroyNotifyID);
+                    // Called by Window.java: CloseWindow(); 
+                    num_events = 0; // end loop in case of destroyed display
+                }
+                break;
+
+            case FocusIn:
+                DBG_PRINT( "X11: event . FocusIn call %p\n", (void*)evt.xvisibility.window);
+                (*env)->CallVoidMethod(env, jwindow, focusChangedID, JNI_TRUE);
+                break;
+
+            case FocusOut:
+                DBG_PRINT( "X11: event . FocusOut call %p\n", (void*)evt.xvisibility.window);
+                (*env)->CallVoidMethod(env, jwindow, focusChangedID, JNI_FALSE);
+                break;
+                */
+
+            case  XCB_EXPOSE: {
+                    xcb_expose_event_t *_evt = (xcb_expose_event_t *)evt;
+                    DBG_PRINT( "X11: event . Expose call %p %d/%d %dx%d count %d\n", (void*)(intptr_t)_evt->window,
+                        _evt->x, _evt->y, _evt->width, _evt->height, _evt->count);
+
+                    if (_evt->count == 0 && _evt->width > 0 && _evt->height > 0) {
+                        (*env)->CallVoidMethod(env, jwindow, windowRepaintID, 
+                            _evt->x, _evt->y, _evt->width, _evt->height);
+                    }
+                } break;
+
+            case XCB_MAP_NOTIFY: {
+                    xcb_map_notify_event_t *_evt = (xcb_map_notify_event_t *)evt;
+                    DBG_PRINT( "X11: event . MapNotify call Event %p, Window %p, override_redirect %d, child-event: %d\n", 
+                        (void*)(intptr_t)_evt->event, (void*)(intptr_t)_evt->window, (int)_evt->override_redirect,
+                        _evt->event!=_evt->window);
+                    if( _evt->event == _evt->window ) {
+                        // ignore child window notification
+                        (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_TRUE);
+                    }
+                } break;
+
+            case XCB_UNMAP_NOTIFY: {
+                    xcb_unmap_notify_event_t *_evt = (xcb_unmap_notify_event_t *)evt;
+                    DBG_PRINT( "X11: event . UnmapNotify call Event %p, Window %p, child-event: %d\n", 
+                        (void*)(intptr_t)_evt->event, (void*)(intptr_t)_evt->window,
+                        _evt->event!=_evt->window);
+                    if( _evt->event == _evt->window ) {
+                        // ignore child window notification
+                        (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_FALSE);
+                    }
+                } break;
+                /*
+
+            case ReparentNotify:
+                {
+                    jlong parentResult; // 0 if root, otherwise proper value
+                    Window winRoot, winTopParent;
+                    #ifdef VERBOSE_ON
+                        Window oldParentRoot, oldParentTopParent;
+                        Window parentRoot, parentTopParent;
+                        if( 0 == NewtWindows_getRootAndParent(dpy, evt.xreparent.event, &oldParentRoot, &oldParentTopParent) ) {
+                            oldParentRoot=0; oldParentTopParent = 0;
+                        }
+                        if( 0 == NewtWindows_getRootAndParent(dpy, evt.xreparent.parent, &parentRoot, &parentTopParent) ) {
+                            parentRoot=0; parentTopParent = 0;
+                        }
+                    #endif
+                    if( 0 == NewtWindows_getRootAndParent(dpy, evt.xreparent.window, &winRoot, &winTopParent) ) {
+                        winRoot=0; winTopParent = 0;
+                    }
+                    if(evt.xreparent.parent == winRoot) {
+                        parentResult = 0; // our java indicator for root window
+                    } else {
+                        parentResult = (jlong) (intptr_t) evt.xreparent.parent;
+                    }
+                    #ifdef VERBOSE_ON
+                        DBG_PRINT( "X11: event . ReparentNotify: call OldParent %p (root %p, top %p), NewParent %p (root %p, top %p), Window %p (root %p, top %p)\n", 
+                            (void*)evt.xreparent.event, (void*)oldParentRoot, (void*)oldParentTopParent,
+                            (void*)evt.xreparent.parent, (void*)parentRoot, (void*)parentTopParent,
+                            (void*)evt.xreparent.window, (void*)winRoot, (void*)winTopParent);
+                    #endif
+
+                    (*env)->CallVoidMethod(env, jwindow, windowReparentedID, parentResult);
+                }
+                break;
+                */
+
+            // unhandled events .. yet ..
+
+            default:
+                DBG_PRINT("XCB: event . unhandled %d 0x%X call %p\n", (int)xcb_event_type, (unsigned int)xcb_event_type, (void*)(intptr_t)event_window);
+        }
+        free(evt);
+    }
+}
+
+
diff --git a/src/newt/native/XCBEvent.h b/src/newt/native/XCBEvent.h
new file mode 100644
index 0000000..d707975
--- /dev/null
+++ b/src/newt/native/XCBEvent.h
@@ -0,0 +1,10 @@
+
+#ifndef _XCBEvent_h
+#define _XCBEvent_h
+
+#include "X11Common.h"
+
+extern void XCBSetEventQueueOwner(Display *dpy);
+extern void XCBEventPoll(JNIEnv *env, jobject obj, Display *dpy, jlong javaObjectAtom, jlong wmDeleteAtom);
+
+#endif /* _XCBDisplayXCBEvent_h */
diff --git a/src/newt/native/BroadcomEGL.c b/src/newt/native/bcm_egl.c
similarity index 90%
rename from src/newt/native/BroadcomEGL.c
rename to src/newt/native/bcm_egl.c
index df6aca6..9b960d2 100644
--- a/src/newt/native/BroadcomEGL.c
+++ b/src/newt/native/bcm_egl.c
@@ -37,7 +37,7 @@
 #include <stdio.h>
 #include <string.h>
 
-#include "jogamp_newt_driver_broadcom_egl_Window.h"
+#include "jogamp_newt_driver_bcm_egl_WindowDriver.h"
 
 #include "MouseEvent.h"
 #include "KeyEvent.h"
@@ -67,7 +67,7 @@ static jmethodID windowCreatedID = NULL;
  * Display
  */
 
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_broadcom_egl_Display_DispatchMessages
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_egl_DisplayDriver_DispatchMessages
   (JNIEnv *env, jobject obj)
 {
     // FIXME: n/a
@@ -75,7 +75,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_broadcom_egl_Display_DispatchMess
     (void) obj;
 }
 
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_broadcom_egl_Display_CreateDisplay
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_bcm_egl_DisplayDriver_CreateDisplay
   (JNIEnv *env, jobject obj, jint width, jint height)
 {
     (void) env;
@@ -89,7 +89,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_broadcom_egl_Display_CreateDispl
     return (jlong) (intptr_t) dpy;
 }
 
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_broadcom_egl_Display_DestroyDisplay
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_egl_DisplayDriver_DestroyDisplay
   (JNIEnv *env, jobject obj, jlong display)
 {
     EGLDisplay dpy  = (EGLDisplay)(intptr_t)display;
@@ -106,7 +106,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_broadcom_egl_Display_DestroyDispl
  * Window
  */
 
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_broadcom_egl_Window_initIDs
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_bcm_egl_WindowDriver_initIDs
   (JNIEnv *env, jclass clazz)
 {
     windowCreatedID = (*env)->GetMethodID(env, clazz, "windowCreated", "(III)V");
@@ -118,7 +118,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_broadcom_egl_Window_initIDs
     return JNI_TRUE;
 }
 
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_broadcom_egl_Window_CreateWindow
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_bcm_egl_WindowDriver_CreateWindow
   (JNIEnv *env, jobject obj, jlong display, jboolean chromaKey, jint width, jint height)
 {
     EGLDisplay dpy  = (EGLDisplay)(intptr_t)display;
@@ -162,7 +162,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_broadcom_egl_Window_CreateWindow
     return (jlong) (intptr_t) window;
 }
 
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_broadcom_egl_Window_CloseWindow
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_egl_WindowDriver_CloseWindow
   (JNIEnv *env, jobject obj, jlong display, jlong window)
 {
     EGLDisplay dpy  = (EGLDisplay) (intptr_t) display;
@@ -175,7 +175,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_broadcom_egl_Window_CloseWindow
     DBG_PRINT( "[CloseWindow] X\n");
 }
 
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_broadcom_egl_Window_SwapWindow
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_egl_WindowDriver_SwapWindow
   (JNIEnv *env, jobject obj, jlong display, jlong window)
 {
     EGLDisplay dpy  = (EGLDisplay) (intptr_t) display;
diff --git a/src/newt/native/bcm_vc_iv.c b/src/newt/native/bcm_vc_iv.c
new file mode 100644
index 0000000..0093da4
--- /dev/null
+++ b/src/newt/native/bcm_vc_iv.c
@@ -0,0 +1,219 @@
+/**
+ * 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.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#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
+
+#ifdef VERBOSE_ON
+    #define DBG_PRINT(...) fprintf(stdout, __VA_ARGS__)
+#else
+    #define DBG_PRINT(...)
+#endif
+
+static jmethodID setScreenSizeID = NULL;
+
+static jmethodID windowCreatedID = NULL;
+static jmethodID sizeChangedID = NULL;
+static jmethodID visibleChangedID = NULL;
+static jmethodID windowDestroyNotifyID = NULL;
+static jmethodID sendMouseEventID = NULL;
+static jmethodID sendKeyEventID = NULL;
+
+/**
+ * Display
+ */
+
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_bcm_vc_iv_DisplayDriver_initIDs
+  (JNIEnv *env, jclass clazz)
+{
+    bcm_host_init();
+    // TODO:  bcm_host_deinit();
+    DBG_PRINT( "BCM.Display initIDs ok\n" );
+    return JNI_TRUE;
+}
+
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_DisplayDriver_DispatchMessages
+  (JNIEnv *env, jobject obj)
+{
+}
+
+/**
+ * Screen
+ */
+
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_bcm_vc_iv_ScreenDriver_initIDs
+  (JNIEnv *env, jclass clazz)
+{
+    uint32_t screen_width;
+    uint32_t screen_height;
+    int32_t success = 0;
+
+    setScreenSizeID = (*env)->GetMethodID(env, clazz, "setScreenSize", "(II)V");
+    if (setScreenSizeID == NULL) {
+        DBG_PRINT( "BCM.Screen initIDs FALSE\n" );
+        return JNI_FALSE;
+    }
+    DBG_PRINT( "BCM.Screen initIDs ok\n" );
+    return JNI_TRUE;
+}
+
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_ScreenDriver_initNative
+  (JNIEnv *env, jobject obj)
+{
+    uint32_t screen_width;
+    uint32_t screen_height;
+    int32_t success = 0;
+
+    if( graphics_get_display_size(0 /* LCD */, &screen_width, &screen_height) >= 0 ) {
+        DBG_PRINT( "BCM.Screen initNative ok %dx%d\n", screen_width, screen_height );
+        (*env)->CallVoidMethod(env, obj, setScreenSizeID, (jint) screen_width, (jint) screen_height);
+    } else {
+        DBG_PRINT( "BCM.Screen initNative failed\n" );
+    }
+}
+
+/**
+ * Window
+ */
+
+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");
+    visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(ZZ)V");
+    windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "(Z)Z");
+    sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIII)V");
+    sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V");
+    if (windowCreatedID == NULL ||
+        sizeChangedID == NULL ||
+        visibleChangedID == NULL ||
+        windowDestroyNotifyID == NULL ||
+        sendMouseEventID == NULL ||
+        sendKeyEventID == NULL) {
+        DBG_PRINT( "initIDs failed\n" );
+        return JNI_FALSE;
+    }
+    DBG_PRINT( "BCM.Window initIDs ok\n" );
+    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)
+{
+   int32_t success = 0;
+   VC_RECT_T dst_rect;
+   VC_RECT_T src_rect;
+
+   dst_rect.x = 0;
+   dst_rect.y = 0;
+   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;   
+
+   VC_DISPMANX_ALPHA_T dispman_alpha;
+   memset(&dispman_alpha, 0x0, sizeof(VC_DISPMANX_ALPHA_T));
+
+   if( JNI_TRUE == opaque ) {
+       dispman_alpha.flags = DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS ;
+       dispman_alpha.opacity = 0xFF;
+       dispman_alpha.mask = 0;
+   } else {
+       dispman_alpha.flags = DISPMANX_FLAGS_ALPHA_FROM_SOURCE ;
+       dispman_alpha.opacity = 0xFF;
+       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*/);
+
+   EGL_DISPMANX_WINDOW_T * nativeWindowPtr = calloc(1, sizeof(EGL_DISPMANX_WINDOW_T));  
+   nativeWindowPtr->element = dispman_element;
+   nativeWindowPtr->width = width;
+   nativeWindowPtr->height = height;
+
+   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;
+}
+
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_RealizeWindow
+  (JNIEnv *env, jobject obj, jlong window)
+{
+    return (jlong) (intptr_t) 0;
+}
+
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_CloseWindow
+  (JNIEnv *env, jobject obj, jlong window, jlong juserData)
+{
+    EGL_DISPMANX_WINDOW_T * nativeWindowPtr = (EGL_DISPMANX_WINDOW_T *) (intptr_t) window ;
+    free( nativeWindowPtr );
+    return 0;
+}
+
+/*
+ * 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)
+{
+}
+
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_setFullScreen0
+  (JNIEnv *env, jobject obj, jlong window, jboolean fullscreen)
+{
+}
+
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_setSize0
+  (JNIEnv *env, jobject obj, jlong window, jint width, jint height)
+{
+    // FIXME RESIZE (*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
new file mode 100644
index 0000000..b43483c
--- /dev/null
+++ b/src/newt/native/bcm_vc_iv.h
@@ -0,0 +1,187 @@
+/**
+ * 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.
+ */
+
+#ifndef BCM_VC_IV_H
+#define BCM_VC_IV_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+typedef uint32_t DISPMANX_PROTECTION_T;
+typedef uint32_t DISPMANX_RESOURCE_HANDLE_T;
+typedef uint32_t DISPMANX_DISPLAY_HANDLE_T;
+typedef uint32_t DISPMANX_UPDATE_HANDLE_T;
+typedef uint32_t DISPMANX_ELEMENT_HANDLE_T;
+
+#define DISPMANX_NO_HANDLE 0
+
+#define DISPMANX_PROTECTION_MAX   0x0f
+#define DISPMANX_PROTECTION_NONE  0
+#define DISPMANX_PROTECTION_HDCP  11   // Derived from the WM DRM levels, 101-300
+
+
+
+/* Default display IDs.
+   Note: if you overwrite with you own dispmanx_platfrom_init function, you
+   should use IDs you provided during dispmanx_display_attach.
+*/
+#define DISPMANX_ID_MAIN_LCD  0
+#define DISPMANX_ID_AUX_LCD   1
+#define DISPMANX_ID_HDMI      2
+#define DISPMANX_ID_SDTV      3
+
+/* Return codes. Nonzero ones indicate failure. */
+typedef enum {
+  DISPMANX_SUCCESS      = 0,
+  DISPMANX_INVALID      = -1
+  /* XXX others TBA */
+} DISPMANX_STATUS_T;
+
+typedef enum {
+  /* Bottom 2 bits sets the orientation */
+  DISPMANX_NO_ROTATE = 0,
+  DISPMANX_ROTATE_90 = 1,
+  DISPMANX_ROTATE_180 = 2,
+  DISPMANX_ROTATE_270 = 3,
+
+  DISPMANX_FLIP_HRIZ = 1 << 16,
+  DISPMANX_FLIP_VERT = 1 << 17
+} DISPMANX_TRANSFORM_T;
+
+typedef enum {
+  /* Bottom 2 bits sets the alpha mode */
+  DISPMANX_FLAGS_ALPHA_FROM_SOURCE = 0,
+  DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS = 1,
+  DISPMANX_FLAGS_ALPHA_FIXED_NON_ZERO = 2,
+  DISPMANX_FLAGS_ALPHA_FIXED_EXCEED_0X07 = 3,
+
+  DISPMANX_FLAGS_ALPHA_PREMULT = 1 << 16,
+  DISPMANX_FLAGS_ALPHA_MIX = 1 << 17
+} DISPMANX_FLAGS_ALPHA_T;
+
+struct VC_IMAGE_T;
+typedef struct VC_IMAGE_T VC_IMAGE_T;
+
+typedef struct {
+  DISPMANX_FLAGS_ALPHA_T flags;
+  uint32_t opacity;
+  VC_IMAGE_T *mask;
+} DISPMANX_ALPHA_T;
+
+typedef struct {
+  DISPMANX_FLAGS_ALPHA_T flags;
+  uint32_t opacity;
+  DISPMANX_RESOURCE_HANDLE_T mask;
+} VC_DISPMANX_ALPHA_T;  /* for use with vmcs_host */
+
+
+typedef enum {
+  DISPMANX_FLAGS_CLAMP_NONE = 0,
+  DISPMANX_FLAGS_CLAMP_LUMA_TRANSPARENT = 1,
+#if __VCCOREVER__ >= 0x04000000
+  DISPMANX_FLAGS_CLAMP_TRANSPARENT = 2,
+  DISPMANX_FLAGS_CLAMP_REPLACE = 3
+#else
+  DISPMANX_FLAGS_CLAMP_CHROMA_TRANSPARENT = 2,
+  DISPMANX_FLAGS_CLAMP_TRANSPARENT = 3
+#endif
+} DISPMANX_FLAGS_CLAMP_T;
+
+typedef enum {
+  DISPMANX_FLAGS_KEYMASK_OVERRIDE = 1,
+  DISPMANX_FLAGS_KEYMASK_SMOOTH = 1 << 1,
+  DISPMANX_FLAGS_KEYMASK_CR_INV = 1 << 2,
+  DISPMANX_FLAGS_KEYMASK_CB_INV = 1 << 3,
+  DISPMANX_FLAGS_KEYMASK_YY_INV = 1 << 4
+} DISPMANX_FLAGS_KEYMASK_T;
+
+typedef union {
+  struct {
+    uint8_t yy_upper;
+    uint8_t yy_lower;
+    uint8_t cr_upper;
+    uint8_t cr_lower;
+    uint8_t cb_upper;
+    uint8_t cb_lower;
+  } yuv;
+  struct {
+    uint8_t red_upper;
+    uint8_t red_lower;
+    uint8_t blue_upper;
+    uint8_t blue_lower;
+    uint8_t green_upper;
+    uint8_t green_lower;
+  } rgb;
+} DISPMANX_CLAMP_KEYS_T;
+
+typedef struct {
+  DISPMANX_FLAGS_CLAMP_T mode;
+  DISPMANX_FLAGS_KEYMASK_T key_mask;
+  DISPMANX_CLAMP_KEYS_T key_value;
+  uint32_t replace_value;
+} 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;
+ int32_t width;
+ int32_t height;
+} VC_RECT_T;
+
+extern void bcm_host_init(void);
+extern void bcm_host_deinit(void);
+
+extern int32_t graphics_get_display_size( const uint16_t display_number,
+                                         uint32_t *width,
+                                         uint32_t *height);
+
+extern DISPMANX_DISPLAY_HANDLE_T vc_dispmanx_display_open( uint32_t device );
+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_update_submit_sync( DISPMANX_UPDATE_HANDLE_T update );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/test-native/contextRetargetDrawable01.c b/src/test-native/contextRetargetDrawable01.c
new file mode 100644
index 0000000..bad6c66
--- /dev/null
+++ b/src/test-native/contextRetargetDrawable01.c
@@ -0,0 +1,154 @@
+/**
+ * compile with: gcc -o contextRetargetDrawable01 contextRetargetDrawable01.c -lX11 -lGL
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <GL/glx.h>
+#include <GL/gl.h>
+
+static PFNGLXSWAPINTERVALSGIPROC _glXSwapIntervalSGI = NULL;
+
+static void testRetarget();
+
+static const char * msg = "contextRetargetDrawable01";
+
+static const useconds_t demodelay = 2 * 1000 * 1000;
+
+int main(int nargs, char **vargs) {
+    _glXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC) glXGetProcAddressARB("glXSwapIntervalSGI");
+    if(NULL == _glXSwapIntervalSGI) {
+        fprintf(stderr, "No glXSwapIntervalSGI avail, bail out\n");
+        return 1;
+    }
+    testRetarget();
+    return 0;
+}
+
+static void createGLWin(Display *dpy, int width, int height, Window *rWin, GLXContext *rCtx);
+static void useGL(Display *dpy, Window win, GLXContext ctx, int width, int height, float c, int swapInterval);
+
+static void testRetarget() {
+    int major, minor;
+    Display *disp1;
+    Window win1;
+    GLXContext ctx1;
+
+    Display *disp2;
+    Window win2;
+    GLXContext ctx2;
+
+    fprintf(stderr, "%s: Create #1\n", msg);
+    disp1 = XOpenDisplay(NULL);
+    createGLWin(disp1, 200, 200, &win1, &ctx1);
+
+    fprintf(stderr, "%s: Create #2\n", msg);
+    disp2 = disp1;
+    // disp2 = XOpenDisplay(NULL);
+    createGLWin(disp2, 300, 300, &win2, &ctx2);
+
+    fprintf(stderr, "%s: Use #1.1\n", msg);
+    useGL(disp1, win1, ctx1, 200, 200, 0.0f, 1); // OK
+
+    fprintf(stderr, "%s: Use #1.2\n", msg);
+    useGL(disp2, win2, ctx2, 300, 300, 1.0f, 1); // OK
+
+    usleep( demodelay );
+
+    fprintf(stderr, "%s: Retarget Drawable\n", msg);
+    {
+        Window _win = win2;
+        win2 = win1;
+        win1 = _win;
+    }
+
+    fprintf(stderr, "%s: Use #2.1\n", msg);
+    useGL(disp1, win1, ctx1, 200, 200, 0.0f, 0); // no setSwapInterval - OK
+
+    fprintf(stderr, "%s: Use #2.2\n", msg);
+    useGL(disp2, win2, ctx2, 300, 300, 1.0f, 0); // no setSwapInterval - OK
+
+    usleep( demodelay );
+
+    fprintf(stderr, "%s: Use #3.1\n", msg);
+    useGL(disp1, win1, ctx1, 200, 200, 0.1f, 1); // setSwapInterval - crash on Mesa 8.0.4 DRI2
+
+    fprintf(stderr, "%s: Use #3.2\n", msg);
+    useGL(disp2, win2, ctx2, 300, 300, 0.9f, 1); // setSwapInterval - crash on Mesa 8.0.4 DRI2
+
+    fprintf(stderr, "%s: Success - no bug\n", msg);
+
+    usleep( demodelay );
+
+    fprintf(stderr, "%s: Destroy #1.0\n", msg);
+    glXMakeContextCurrent(disp1, 0, 0, 0);
+    glXDestroyContext(disp1, ctx1);
+    if( disp1 != disp2 ) {
+        XCloseDisplay(disp1);
+    }
+    fprintf(stderr, "%s: Destroy #1.X\n", msg);
+
+    fprintf(stderr, "%s: Destroy #2.0\n", msg);
+    glXMakeContextCurrent(disp2, 0, 0, 0);
+    glXDestroyContext(disp2, ctx2);
+    XCloseDisplay(disp2);
+    fprintf(stderr, "%s: Destroy #2.X\n", msg);
+
+    fprintf(stderr, "%s: Exit - OK\n", msg);
+}
+
+static void useGL(Display *dpy, Window win, GLXContext ctx, int width, int height, float c, int swapInterval)
+{
+    glXMakeContextCurrent(dpy, win, win, ctx);
+    glViewport(0, 0, width, height);
+    if(0 < swapInterval) {
+        fprintf(stderr, "%s: glXSwapIntervalSGI(1)\n", msg);
+        _glXSwapIntervalSGI(1); // offending op after retargeting drawable
+    }
+    fprintf(stderr, "GL_VENDOR: %s\n", glGetString(GL_VENDOR));
+    fprintf(stderr, "GL_VERSION: %s\n", glGetString(GL_VERSION));
+    fprintf(stderr, "GL_RENDERER: %s\n", glGetString(GL_RENDERER));
+    glClearColor(c, c, c, 0.0f);
+    glClearDepth(1.0f);
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+    glXSwapBuffers(dpy, win);
+    glXMakeContextCurrent(dpy, 0, 0, 0);
+}
+
+/* attributes for a double buffered visual in RGBA format with at least
+ * 4 bits per color and a 16 bit depth buffer */
+static int attrListDbl[] = { GLX_RGBA, GLX_DOUBLEBUFFER, 
+    GLX_RED_SIZE, 4, 
+    GLX_GREEN_SIZE, 4, 
+    GLX_BLUE_SIZE, 4, 
+    GLX_DEPTH_SIZE, 16,
+    None };
+
+static void createGLWin(Display *dpy, int width, int height, Window *rWin, GLXContext *rCtx)
+{
+    int screen = DefaultScreen(dpy);
+    XVisualInfo *vi = glXChooseVisual(dpy, screen, attrListDbl);
+    Colormap cmap;
+    XSetWindowAttributes attr;
+
+    /* create a GLX context */
+    *rCtx = glXCreateContext(dpy, vi, 0, GL_TRUE);
+
+    /* create a color map */
+    cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone);
+    attr.colormap = cmap;
+    attr.border_pixel = 0;
+
+    /* create a window in window mode*/
+    attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask |
+        StructureNotifyMask;
+    *rWin = XCreateWindow(dpy, RootWindow(dpy, vi->screen),
+        0, 0, width, height, 0, vi->depth, InputOutput, vi->visual,
+        CWBorderPixel | CWColormap | CWEventMask, &attr);
+
+    XMapRaised(dpy, *rWin);
+}
+
diff --git a/src/test-native/contextRetargetDrawable02.c b/src/test-native/contextRetargetDrawable02.c
new file mode 100644
index 0000000..3d0807b
--- /dev/null
+++ b/src/test-native/contextRetargetDrawable02.c
@@ -0,0 +1,382 @@
+/**
+ * compile with: gcc -o contextRetargetDrawable02 contextRetargetDrawable02.c -lX11 -lGL
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <GL/glx.h>
+#include <GL/gl.h>
+
+typedef int bool;
+#define true 1
+#define false 0
+
+static PFNGLXSWAPINTERVALSGIPROC _glXSwapIntervalSGI = NULL;
+
+static void testRetarget(bool reverse);
+
+static const char * msg = "contextRetargetDrawable01";
+
+static const useconds_t demodelay = 2 * 1000 * 1000;
+
+int main(int nargs, char **vargs) {
+    _glXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC) glXGetProcAddressARB("glXSwapIntervalSGI");
+    if(NULL == _glXSwapIntervalSGI) {
+        fprintf(stderr, "No glXSwapIntervalSGI avail, bail out\n");
+        return 1;
+    }
+    testRetarget(false);
+    return 0;
+}
+
+static void createGLWin(Display *dpy, int width, int height, Window *rWin, GLXContext *rCtx);
+static void useGL(Display *dpy, Window win, GLXContext ctx, int width, int height, float c, int swapInterval);
+
+static void testRetarget(bool reverse) {
+    int major, minor;
+    Display *disp1;
+    Window win1;
+    GLXContext ctx1;
+
+    Display *disp2;
+    Window win2;
+    GLXContext ctx2;
+
+    fprintf(stderr, "%s: Create #1\n", msg);
+    disp1 = XOpenDisplay(NULL);
+    createGLWin(disp1, 200, 200, &win1, &ctx1);
+
+    fprintf(stderr, "%s: Create #2\n", msg);
+    disp2 = disp1;
+    // disp2 = XOpenDisplay(NULL);
+    createGLWin(disp2, 300, 300, &win2, &ctx2);
+
+    fprintf(stderr, "%s: Use #1.1\n", msg);
+    useGL(disp1, win1, ctx1, 200, 200, 0.0f, 1); // OK
+
+    fprintf(stderr, "%s: Use #1.2\n", msg);
+    useGL(disp2, win2, ctx2, 300, 300, 1.0f, 1); // OK
+
+    usleep( demodelay );
+
+    fprintf(stderr, "%s: Retarget Drawable\n", msg);
+    {
+        GLXContext _ctx = ctx2;
+        ctx2 = ctx1;
+        ctx1 = _ctx;
+    }
+
+    /**
+    if(reverse) {
+        fprintf(stderr, "%s: Use #2.2\n", msg);
+        useGL(disp2, win2, ctx2, 300, 300, 1.0f, 0); // no setSwapInterval - OK
+
+        fprintf(stderr, "%s: Use #2.1\n", msg);
+        useGL(disp1, win1, ctx1, 200, 200, 0.0f, 0); // no setSwapInterval - OK
+    } else {
+        fprintf(stderr, "%s: Use #2.1\n", msg);
+        useGL(disp1, win1, ctx1, 200, 200, 0.0f, 0); // no setSwapInterval - OK
+
+        fprintf(stderr, "%s: Use #2.2\n", msg);
+        useGL(disp2, win2, ctx2, 300, 300, 1.0f, 0); // no setSwapInterval - OK
+    }
+    usleep( demodelay ); */
+
+    if(reverse) {
+        fprintf(stderr, "%s: Use #3.2\n", msg);
+        useGL(disp2, win2, ctx2, 300, 300, 0.9f, 1); // setSwapInterval - crash on Mesa 8.0.4 DRI2
+
+        fprintf(stderr, "%s: Use #3.1\n", msg);
+        useGL(disp1, win1, ctx1, 200, 200, 0.1f, 1); // setSwapInterval - crash on Mesa 8.0.4 DRI2
+    } else {
+        fprintf(stderr, "%s: Use #3.1\n", msg);
+        useGL(disp1, win1, ctx1, 200, 200, 0.1f, 1); // setSwapInterval - crash on Mesa 8.0.4 DRI2
+
+        fprintf(stderr, "%s: Use #3.2\n", msg);
+        useGL(disp2, win2, ctx2, 300, 300, 0.9f, 1); // setSwapInterval - crash on Mesa 8.0.4 DRI2
+    }
+    fprintf(stderr, "%s: Success - no bug\n", msg);
+    usleep( demodelay );
+
+    fprintf(stderr, "%s: Destroy #1.0\n", msg);
+    glXMakeContextCurrent(disp1, 0, 0, 0);
+    glXDestroyContext(disp1, ctx1);
+    if( disp1 != disp2 ) {
+        XCloseDisplay(disp1);
+    }
+    fprintf(stderr, "%s: Destroy #1.X\n", msg);
+
+    fprintf(stderr, "%s: Destroy #2.0\n", msg);
+    glXMakeContextCurrent(disp2, 0, 0, 0);
+    glXDestroyContext(disp2, ctx2);
+    XCloseDisplay(disp2);
+    fprintf(stderr, "%s: Destroy #2.X\n", msg);
+
+    fprintf(stderr, "%s: Exit - OK\n", msg);
+}
+
+static void useGL(Display *dpy, Window win, GLXContext ctx, int width, int height, float c, int swapInterval)
+{
+    glXMakeContextCurrent(dpy, win, win, ctx);
+    glViewport(0, 0, width, height);
+    if(0 < swapInterval) {
+        fprintf(stderr, "%s: glXSwapIntervalSGI(1)\n", msg);
+        _glXSwapIntervalSGI(1); // offending op after retargeting drawable
+    }
+    fprintf(stderr, "GL_VENDOR: %s\n", glGetString(GL_VENDOR));
+    fprintf(stderr, "GL_VERSION: %s\n", glGetString(GL_VERSION));
+    fprintf(stderr, "GL_RENDERER: %s\n", glGetString(GL_RENDERER));
+    glClearColor(c, c, c, 0.0f);
+    glClearDepth(1.0f);
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+    glXSwapBuffers(dpy, win);
+    glXMakeContextCurrent(dpy, 0, 0, 0);
+}
+
+static volatile bool ctxErrorOccurred = false;
+static int ctxErrorHandler( Display *dpy, XErrorEvent *e )
+{
+    const char * errnoStr = strerror(errno);
+    char errCodeStr[80];
+    char reqCodeStr[80];
+
+    snprintf(errCodeStr, sizeof(errCodeStr), "%d", e->request_code);
+    XGetErrorDatabaseText(dpy, "XRequest", errCodeStr, "Unknown", reqCodeStr, sizeof(reqCodeStr));
+    XGetErrorText(dpy, e->error_code, errCodeStr, sizeof(errCodeStr));
+
+    fprintf(stderr, "X11 Error: %d - %s, dpy %p, id %x, # %d: %d:%d %s\n",
+        e->error_code, errCodeStr, e->display, (int)e->resourceid, (int)e->serial,
+        (int)e->request_code, (int)e->minor_code, reqCodeStr);
+    fflush(stderr);
+
+    ctxErrorOccurred = true;
+    return 0;
+}
+
+/* attributes for a double buffered visual in RGBA format with at least
+ * 8 bits per color and a 16 bit depth buffer */
+static int visual_attribs[] = {
+  GLX_X_RENDERABLE    , True,
+  GLX_DRAWABLE_TYPE   , GLX_WINDOW_BIT,
+  GLX_RENDER_TYPE     , GLX_RGBA_BIT,
+  GLX_RED_SIZE        , 8,
+  GLX_GREEN_SIZE      , 8,
+  GLX_BLUE_SIZE       , 8,
+  GLX_DEPTH_SIZE      , 16,
+  GLX_DOUBLEBUFFER    , True,
+  GLX_STEREO          , False,
+  GLX_TRANSPARENT_TYPE, GLX_NONE,
+  //GLX_SAMPLE_BUFFERS  , 1,
+  //GLX_SAMPLES         , 4,
+  None };
+
+static int context_attribs[] = {
+    GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
+    GLX_CONTEXT_MINOR_VERSION_ARB, 0,
+    GLX_RENDER_TYPE              , GLX_RGBA_TYPE,
+    GLX_CONTEXT_FLAGS_ARB        , 0,
+    // GLX_CONTEXT_FLAGS_ARB        , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
+    // GLX_CONTEXT_PROFILE_MASK_ARB , GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
+    None };
+
+static bool isExtensionSupported(const char *extList, const char *extension);
+
+static void createGLWin(Display *dpy, int width, int height, Window *rWin, GLXContext *rCtx)
+{
+    int glx_major, glx_minor;
+ 
+    // FBConfigs were added in GLX version 1.3.
+    if ( !glXQueryVersion( dpy, &glx_major, &glx_minor ) || 
+       ( ( glx_major == 1 ) && ( glx_minor < 3 ) ) || ( glx_major < 1 ) )
+    {
+        printf( "Invalid GLX version" );
+        exit(1);
+    }
+
+    int fbcount;
+    GLXFBConfig *fbc = glXChooseFBConfig( dpy, DefaultScreen( dpy ), 
+                                        visual_attribs, &fbcount );
+    if ( !fbc || 0 == fbcount )
+    {
+        printf( "Failed to retrieve a framebuffer config\n" );
+        exit(1);
+    }
+    printf( "Found %d matching FB configs.\n", fbcount );
+
+    GLXFBConfig bestFbc = fbc[ 0 ];
+    int bestFbcID = 0;
+    if( 0 != glXGetFBConfigAttrib( dpy, bestFbc, GLX_FBCONFIG_ID, &bestFbcID ) ) {
+        printf( "Invalid FBConfigID\n" );
+        exit(1);
+    }
+    printf( "Chosen FBConfigID = 0x%x\n", bestFbcID);
+
+    XVisualInfo *vi = glXGetVisualFromFBConfig( dpy, bestFbc );
+    printf( "Chosen visual ID = 0x%x\n", (int) vi->visualid );
+
+    XSetWindowAttributes swa;
+    Colormap cmap;
+    swa.colormap = cmap = XCreateColormap( dpy,
+                                         RootWindow( dpy, vi->screen ), 
+                                         vi->visual, AllocNone );
+    swa.background_pixmap = None ;
+    swa.border_pixel      = 0;
+    swa.event_mask        = StructureNotifyMask;
+
+    printf( "Creating window\n" );
+    Window win = XCreateWindow( dpy, RootWindow( dpy, vi->screen ), 
+                                0, 0, width, height, 0, vi->depth, InputOutput,
+                                vi->visual, 
+                                CWBorderPixel|CWColormap|CWEventMask, &swa );
+    if ( !win )
+    {
+        printf( "Failed to create window.\n" );
+        exit(1);
+    }
+
+    // Done with the visual info data
+    XFree( vi );
+
+    XStoreName( dpy, win, "GL Window" );
+
+    XMapWindow( dpy, win );
+
+    *rWin = win;
+
+    GLXContext ctx0 = glXCreateNewContext( dpy, bestFbc, GLX_RGBA_TYPE, 0, True );
+    if( !ctx0 ) {
+        printf( "Failed to create intermediate old OpenGL context\n" );
+        exit(1);
+    }
+    glXMakeContextCurrent(dpy, win, win, ctx0);
+
+
+    // Get the default screen's GLX extension list
+    const char *glxExts01 = glXQueryExtensionsString( dpy,
+                                                  DefaultScreen( dpy ) );
+    const char *glxExts02 = glXGetClientString( dpy, GLX_EXTENSIONS);
+    const char *glxExts03 = glXQueryServerString( dpy, DefaultScreen( dpy ), GLX_EXTENSIONS);
+
+    // NOTE: It is not necessary to create or make current to a context before
+    // calling glXGetProcAddressARB
+    PFNGLXCREATECONTEXTATTRIBSARBPROC _glXCreateContextAttribsARB = 0;
+    _glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)
+           glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" );
+
+    // Check for the GLX_ARB_create_context extension string and the function.
+    // If either is not present, use GLX 1.3 context creation method.
+    bool isGLX_ARB_create_contextAvail = isExtensionSupported( glxExts01, "GLX_ARB_create_context" ) || 
+                                         isExtensionSupported( glxExts02, "GLX_ARB_create_context" ) ||
+                                         isExtensionSupported( glxExts03, "GLX_ARB_create_context" );
+
+    glXMakeContextCurrent(dpy, 0, 0, 0);
+
+    GLXContext ctx = 0;
+
+    // Install an X error handler so the application won't exit if GL 3.0
+    // context allocation fails.
+    //
+    // Note this error handler is global.  All display connections in all threads
+    // of a process use the same error handler, so be sure to guard against other
+    // threads issuing X commands while this code is running.
+    int (*oldHandler)(Display*, XErrorEvent*) =
+      XSetErrorHandler(&ctxErrorHandler);
+
+    if ( !isGLX_ARB_create_contextAvail || !_glXCreateContextAttribsARB )
+    {
+        printf( "glXCreateContextAttribsARB() not found (ext %d, func %p)"
+                " ... using old-style GLX context\n", isGLX_ARB_create_contextAvail, _glXCreateContextAttribsARB );
+        printf( "extensions 01: %s\n", glxExts01);
+        printf( "extensions 02: %s\n", glxExts02);
+        printf( "extensions 03: %s\n", glxExts03);
+        ctx = ctx0;
+    }
+
+    // If it does, try to get a GL 3.0 context!
+    else
+    {
+        printf( "Creating context\n" );
+        XSync( dpy, False );
+        ctxErrorOccurred = false;
+        ctx = _glXCreateContextAttribsARB( dpy, bestFbc, 0, True, context_attribs );
+        XSync( dpy, False );
+
+        if ( !ctxErrorOccurred && ctx ) {
+          printf( "Created GL 3.0 context\n" );
+          glXDestroyContext(dpy, ctx0); // get rid of old ctx
+        } else
+        {
+          // Couldn't create GL 3.0 context.  Fall back to old-style 2.x context.
+          // When a context version below 3.0 is requested, implementations will
+          // return the newest context version compatible with OpenGL versions less
+          // than version 3.0.
+          // GLX_CONTEXT_MAJOR_VERSION_ARB = 1
+          context_attribs[1] = 1;
+          // GLX_CONTEXT_MINOR_VERSION_ARB = 0
+          context_attribs[3] = 0;
+
+          printf( "Failed to create GL 3.0 context (err %d, ctx %p)"
+                  " ... using old-style GLX context\n", ctxErrorOccurred, (void*)ctx );
+          ctx = ctx0;
+
+          ctxErrorOccurred = false;
+        }
+    }
+
+    // Sync to ensure any errors generated are processed.
+    XSync( dpy, False );
+
+    // Restore the original error handler
+    XSetErrorHandler( oldHandler );
+
+    if ( ctxErrorOccurred || !ctx )
+    {
+        printf( "Failed to create an OpenGL context\n" );
+        exit(1);
+    }
+
+    XFree( fbc );
+
+    *rCtx = ctx;
+}
+
+// Helper to check for extension string presence.  Adapted from:
+//   http://www.opengl.org/resources/features/OGLextensions/
+static bool isExtensionSupported(const char *extList, const char *extension)
+{
+
+  const char *start;
+  const char *where, *terminator;
+  
+  /* Extension names should not have spaces. */
+  where = strchr(extension, ' ');
+  if ( where || *extension == '\0' )
+    return false;
+
+  /* It takes a bit of care to be fool-proof about parsing the
+     OpenGL extensions string. Don't be fooled by sub-strings,
+     etc. */
+  for ( start = extList; ; ) {
+    where = strstr( start, extension );
+
+    if ( !where )
+      break;
+
+    terminator = where + strlen( extension );
+
+    if ( where == start || *(where - 1) == ' ' )
+      if ( *terminator == ' ' || *terminator == '\0' )
+        return true;
+
+    start = terminator;
+  }
+
+  return false;
+}
+
diff --git a/src/test-native/glExtensionsListGL2.c b/src/test-native/glExtensionsListGL2.c
index 89815e9..ea47b8c 100644
--- a/src/test-native/glExtensionsListGL2.c
+++ b/src/test-native/glExtensionsListGL2.c
@@ -77,6 +77,8 @@ void useGL(Display *dpy, Window win, GLXContext ctx, int width, int height)
     glXMakeCurrent(dpy, win, ctx);
 
     fprintf(stderr, "GL_VENDOR: %s\n", glGetString(GL_VENDOR));
+    fprintf(stderr, "GL_VERSION: %s\n", glGetString(GL_VERSION));
+    fprintf(stderr, "GL_RENDERER: %s\n", glGetString(GL_RENDERER));
 
     glGetIntegerv(GL_NUM_EXTENSIONS, &n);
     fprintf(stderr, "GL_NUM_EXTENSIONS: %d\n", n);
diff --git a/src/test-native/glExtensionsListGL3.c b/src/test-native/glExtensionsListGL3.c
index c531577..5875c10 100644
--- a/src/test-native/glExtensionsListGL3.c
+++ b/src/test-native/glExtensionsListGL3.c
@@ -59,6 +59,8 @@ void dumpGLExtension() {
     int i, n;
 
     fprintf(stderr, "GL_VENDOR: %s\n", glGetString(GL_VENDOR));
+    fprintf(stderr, "GL_VERSION: %s\n", glGetString(GL_VERSION));
+    fprintf(stderr, "GL_RENDERER: %s\n", glGetString(GL_RENDERER));
 
     glGetIntegerv(GL_NUM_EXTENSIONS, &n);
     fprintf(stderr, "GL_NUM_EXTENSIONS: %d\n", n);
@@ -153,9 +155,6 @@ int main (int argc, char ** argv)
 
   GLXFBConfig bestFbc = fbc[ best_fbc ];
 
-  // Be sure to free the FBConfig list allocated by glXChooseFBConfig()
-  XFree( fbc );
-
   // Get a visual
   XVisualInfo *vi = glXGetVisualFromFBConfig( display, bestFbc );
   printf( "Chosen visual ID = 0x%x\n", (int) vi->visualid );
@@ -190,8 +189,9 @@ int main (int argc, char ** argv)
   XMapWindow( display, win );
 
   // Get the default screen's GLX extension list
-  const char *glxExts = glXQueryExtensionsString( display,
-                                                  DefaultScreen( display ) );
+  const char *glxExts01 = glXQueryExtensionsString( display, DefaultScreen( display ) );
+  const char *glxExts02 = glXGetClientString( display, GLX_EXTENSIONS);
+  const char *glxExts03 = glXQueryServerString( display, DefaultScreen( display ), GLX_EXTENSIONS);
 
   // NOTE: It is not necessary to create or make current to a context before
   // calling glXGetProcAddressARB
@@ -213,11 +213,16 @@ int main (int argc, char ** argv)
 
   // Check for the GLX_ARB_create_context extension string and the function.
   // If either is not present, use GLX 1.3 context creation method.
-  if ( !isExtensionSupported( glxExts, "GLX_ARB_create_context" ) ||
-       !glXCreateContextAttribsARB )
+  bool isGLX_ARB_create_contextAvail = isExtensionSupported( glxExts01, "GLX_ARB_create_context" ) || 
+                                       isExtensionSupported( glxExts02, "GLX_ARB_create_context" ) ||
+                                       isExtensionSupported( glxExts03, "GLX_ARB_create_context" );
+  if ( !isGLX_ARB_create_contextAvail || !glXCreateContextAttribsARB )
   {
     printf( "glXCreateContextAttribsARB() not found"
             " ... using old-style GLX context\n" );
+    printf( "extensions 01: %s\n", glxExts01);
+    printf( "extensions 02: %s\n", glxExts02);
+    printf( "extensions 03: %s\n", glxExts03);
     ctx = glXCreateNewContext( display, bestFbc, GLX_RGBA_TYPE, 0, True );
   }
 
@@ -229,7 +234,8 @@ int main (int argc, char ** argv)
         GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
         GLX_CONTEXT_MINOR_VERSION_ARB, 0,
         GLX_RENDER_TYPE              , GLX_RGBA_TYPE,
-        GLX_CONTEXT_FLAGS_ARB        , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
+        // GLX_CONTEXT_FLAGS_ARB        , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
+        // GLX_CONTEXT_PROFILE_MASK_ARB , GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB
         None
       };
 
@@ -261,6 +267,9 @@ int main (int argc, char ** argv)
     }
   }
 
+  // Be sure to free the FBConfig list allocated by glXChooseFBConfig()
+  XFree( fbc );
+
   // Sync to ensure any errors generated are processed.
   XSync( display, False );
 
diff --git a/src/test-native/make.sh b/src/test-native/make.sh
index 20bd49e..269f09c 100755
--- a/src/test-native/make.sh
+++ b/src/test-native/make.sh
@@ -4,3 +4,5 @@ gcc -o displayMultiple01 displayMultiple01.c -lX11 -lGL
 gcc -o displayMultiple02 displayMultiple02.c -lX11 -lGL
 gcc -o glExtensionsListGL2 glExtensionsListGL2.c -lX11 -lGL
 gcc -o glExtensionsListGL3 glExtensionsListGL3.c -lX11 -lGL
+gcc -o contextRetargetDrawable01 contextRetargetDrawable01.c -lX11 -lGL
+gcc -o contextRetargetDrawable02 contextRetargetDrawable02.c -lX11 -lGL
diff --git a/src/test/com/jogamp/opengl/test/android/MovieCubeActivityLauncher0.java b/src/test/com/jogamp/opengl/test/android/MovieCubeActivityLauncher0.java
index 4f24fc9..c4b74c5 100644
--- a/src/test/com/jogamp/opengl/test/android/MovieCubeActivityLauncher0.java
+++ b/src/test/com/jogamp/opengl/test/android/MovieCubeActivityLauncher0.java
@@ -50,6 +50,8 @@ public class MovieCubeActivityLauncher0 extends LauncherUtil.BaseActivityLaunche
        // props.setProperty("jogamp.debug.NativeLibrary", "true");
        // props.setProperty("jogamp.debug.NativeLibrary.Lookup", "true");
        // props.setProperty("jogamp.debug.IOUtil", "true");       
+       // props.setProperty("jogamp.debug.Lock", "true");
+       // props.setProperty("jogamp.debug.Lock.TraceLock", "true");
        // props.setProperty("nativewindow.debug", "all");
        props.setProperty("nativewindow.debug.GraphicsConfiguration", "true");
        // props.setProperty("jogl.debug", "all");
diff --git a/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity0.java b/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity0.java
index 11babf1..89395e3 100644
--- a/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity0.java
+++ b/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity0.java
@@ -34,11 +34,11 @@ import java.util.Arrays;
 import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLProfile;
 
-import jogamp.newt.driver.android.AndroidWindow;
 import jogamp.newt.driver.android.NewtBaseActivity;
 
 import com.jogamp.common.util.IOUtil;
 import com.jogamp.newt.NewtFactory;
+import com.jogamp.newt.Window;
 import com.jogamp.newt.event.MouseAdapter;
 import com.jogamp.newt.event.MouseEvent;
 import com.jogamp.newt.opengl.GLWindow;
@@ -55,8 +55,8 @@ public class MovieSimpleActivity0 extends NewtBaseActivity {
    MouseAdapter toFrontMouseListener = new MouseAdapter() {
        public void mouseClicked(MouseEvent e) {
            Object src = e.getSource();
-           if(src instanceof AndroidWindow) {
-               ((AndroidWindow)src).requestFocus(false);
+           if(src instanceof Window) {
+               ((Window)src).requestFocus(false);
            }
        } };
    
diff --git a/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity1.java b/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity1.java
index a5e5f4c..a7fefd8 100644
--- a/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity1.java
+++ b/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity1.java
@@ -36,11 +36,11 @@ import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLProfile;
 import javax.media.opengl.GLRunnable;
 
-import jogamp.newt.driver.android.AndroidWindow;
 import jogamp.newt.driver.android.NewtBaseActivity;
 
 import com.jogamp.common.util.IOUtil;
 import com.jogamp.newt.NewtFactory;
+import com.jogamp.newt.Window;
 import com.jogamp.newt.event.MouseAdapter;
 import com.jogamp.newt.event.MouseEvent;
 import com.jogamp.newt.opengl.GLWindow;
@@ -59,8 +59,8 @@ public class MovieSimpleActivity1 extends NewtBaseActivity {
    MouseAdapter toFrontMouseListener = new MouseAdapter() {
        public void mouseClicked(MouseEvent e) {
            Object src = e.getSource();
-           if(src instanceof AndroidWindow) {
-               ((AndroidWindow)src).requestFocus(false);
+           if(src instanceof Window) {
+               ((Window)src).requestFocus(false);
            }
        } };
    
@@ -121,7 +121,7 @@ public class MovieSimpleActivity1 extends NewtBaseActivity {
            final GLWindow glWindowMain = GLWindow.create(scrn, capsMain);
            {
                final int padding = mPlayerHUD ? 32 : 0;
-               final android.view.View androidView = ((AndroidWindow)glWindowMain.getDelegatedWindow()).getAndroidView();
+               final android.view.View androidView = ((jogamp.newt.driver.android.WindowDriver)glWindowMain.getDelegatedWindow()).getAndroidView();
                glWindowMain.setSize(scrn.getWidth()-padding, scrn.getHeight()-padding);
                glWindowMain.setUndecorated(true);
                // setContentView(getWindow(), glWindowMain);
@@ -168,7 +168,7 @@ public class MovieSimpleActivity1 extends NewtBaseActivity {
 
                         viewGroup.post(new Runnable() {
                             public void run() {
-                                final android.view.View androidView = ((AndroidWindow)glWindowHUD.getDelegatedWindow()).getAndroidView();
+                                final android.view.View androidView = ((jogamp.newt.driver.android.WindowDriver)glWindowHUD.getDelegatedWindow()).getAndroidView();
                                 // addContentView(getWindow(), glWindowHUD, new android.view.ViewGroup.LayoutParams(glWindowHUD.getWidth(), glWindowHUD.getHeight()));
                                 viewGroup.addView(androidView, new android.widget.FrameLayout.LayoutParams(glWindowHUD.getWidth(), glWindowHUD.getHeight(), Gravity.TOP|Gravity.LEFT));
                                 registerNEWTWindow(glWindowHUD);  
diff --git a/src/test/com/jogamp/opengl/test/android/NEWTGearsES2ActivityLauncher.java b/src/test/com/jogamp/opengl/test/android/NEWTGearsES2ActivityLauncher.java
index 907be50..415efc7 100644
--- a/src/test/com/jogamp/opengl/test/android/NEWTGearsES2ActivityLauncher.java
+++ b/src/test/com/jogamp/opengl/test/android/NEWTGearsES2ActivityLauncher.java
@@ -53,10 +53,10 @@ public class NEWTGearsES2ActivityLauncher extends LauncherUtil.BaseActivityLaunc
        props.setProperty("jogl.debug.GLContext", "true");
        props.setProperty("jogl.debug.GLSLCode", "true");
        // props.setProperty("jogl.debug.CapabilitiesChooser", "true");       
-       // properties.setProperty("jogl.debug.GLSLState", "true");
-       // properties.setProperty("jogl.debug.DebugGL", "true");
-       // properties.setProperty("jogl.debug.TraceGL", "true");
-       // properties.setProperty("newt.debug", "all");
+       // props.setProperty("jogl.debug.GLSLState", "true");
+       // props.setProperty("jogl.debug.DebugGL", "true");
+       // props.setProperty("jogl.debug.TraceGL", "true");
+       // props.setProperty("newt.debug", "all");
        // props.setProperty("newt.debug.Window", "true");
        // props.setProperty("newt.debug.Window.MouseEvent", "true");
        props.setProperty("newt.debug.Window.KeyEvent", "true");
diff --git a/src/test/com/jogamp/opengl/test/android/NEWTGraphUI1pActivityLauncher.java b/src/test/com/jogamp/opengl/test/android/NEWTGraphUI1pActivityLauncher.java
index c75c229..5763058 100644
--- a/src/test/com/jogamp/opengl/test/android/NEWTGraphUI1pActivityLauncher.java
+++ b/src/test/com/jogamp/opengl/test/android/NEWTGraphUI1pActivityLauncher.java
@@ -14,23 +14,23 @@ public class NEWTGraphUI1pActivityLauncher extends LauncherUtil.BaseActivityLaun
        final OrderedProperties props = getProperties();       
        // props.setProperty("jogamp.debug.JNILibLoader", "true");
        // props.setProperty("jogamp.debug.NativeLibrary", "true");
-       // properties.setProperty("jogamp.debug.NativeLibrary.Lookup", "true");
-       // properties.setProperty("jogamp.debug.IOUtil", "true");       
-       // properties.setProperty("nativewindow.debug", "all");
+       // props.setProperty("jogamp.debug.NativeLibrary.Lookup", "true");
+       // props.setProperty("jogamp.debug.IOUtil", "true");       
+       // props.setProperty("nativewindow.debug", "all");
        props.setProperty("nativewindow.debug.GraphicsConfiguration", "true");
-       // properties.setProperty("jogl.debug", "all");
-       // properties.setProperty("jogl.debug.GLProfile", "true");
+       // props.setProperty("jogl.debug", "all");
+       // props.setProperty("jogl.debug.GLProfile", "true");
        props.setProperty("jogl.debug.GLDrawable", "true");
        props.setProperty("jogl.debug.GLContext", "true");
        props.setProperty("jogl.debug.GLSLCode", "true");
        props.setProperty("jogl.debug.CapabilitiesChooser", "true");       
-       // properties.setProperty("jogl.debug.GLSLState", "true");
-       // properties.setProperty("jogl.debug.DebugGL", "true");
-       // properties.setProperty("jogl.debug.TraceGL", "true");
-       // properties.setProperty("newt.debug", "all");
+       // props.setProperty("jogl.debug.GLSLState", "true");
+       // props.setProperty("jogl.debug.DebugGL", "true");
+       // props.setProperty("jogl.debug.TraceGL", "true");
+       // props.setProperty("newt.debug", "all");
        props.setProperty("newt.debug.Window", "true");
-       // properties.setProperty("newt.debug.Window.MouseEvent", "true");
-       // properties.setProperty("newt.debug.Window.KeyEvent", "true");
+       // props.setProperty("newt.debug.Window.MouseEvent", "true");
+       // props.setProperty("newt.debug.Window.KeyEvent", "true");
     }
     
     @Override
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestInitConcurrentNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/InitConcurrentBaseNEWT.java
similarity index 80%
rename from src/test/com/jogamp/opengl/test/junit/jogl/acore/TestInitConcurrentNEWT.java
rename to src/test/com/jogamp/opengl/test/junit/jogl/acore/InitConcurrentBaseNEWT.java
index 7127b0a..6b2de83 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestInitConcurrentNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/InitConcurrentBaseNEWT.java
@@ -28,8 +28,6 @@
  
 package com.jogamp.opengl.test.junit.jogl.acore;
 
-import java.io.IOException;
-
 import javax.media.nativewindow.Capabilities;
 import javax.media.nativewindow.util.InsetsImmutable;
 import javax.media.opengl.GLCapabilities;
@@ -37,17 +35,25 @@ import javax.media.opengl.GLProfile;
 
 import org.junit.Assert;
 import org.junit.BeforeClass;
-import org.junit.Test;
 
-import com.jogamp.common.os.Platform;
+import com.jogamp.newt.Display;
 import com.jogamp.newt.NewtFactory;
+import com.jogamp.newt.Screen;
 import com.jogamp.newt.Window;
 import com.jogamp.newt.opengl.GLWindow;
 import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
 import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.test.junit.util.ValidateLockListener;
 import com.jogamp.opengl.util.Animator;
 
-public class TestInitConcurrentNEWT extends UITestCase {
+/**
+ * Concurrent and lock-free initialization and rendering using exclusive NEWT Display EDT instances, or
+ * concurrent locked initialization and lock-free rendering using a shared NEWT Display EDT instances.
+ * <p>
+ * Rendering is always lock-free and independent of the EDT.
+ * </p>
+ */
+public class InitConcurrentBaseNEWT extends UITestCase {
 
     static final int demoSize = 128;
     
@@ -73,24 +79,29 @@ public class TestInitConcurrentNEWT extends UITestCase {
     }
     
     public class JOGLTask implements Runnable {
-        private int id;
-        private Object postSync;
+        private final int id;
+        private final Object postSync;
+        private final boolean reuse;
         private boolean done = false;
         
-        public JOGLTask(Object postSync, int id) {
+        public JOGLTask(Object postSync, int id, boolean reuse) {
             this.postSync = postSync;
             this.id = id;
+            this.reuse = reuse;
         }
         public void run() {
             int x = (  id          % num_x ) * ( demoSize + insets.getTotalHeight() );
             int y = ( (id / num_x) % num_y ) * ( demoSize + insets.getTotalHeight() );
             
-            System.err.println("JOGLTask "+id+": START: "+x+"/"+y+" - "+Thread.currentThread().getName());
-            GLWindow glWindow = GLWindow.create(new GLCapabilities(GLProfile.getDefault()));
+            System.err.println("JOGLTask "+id+": START: "+x+"/"+y+", reuse "+reuse+" - "+Thread.currentThread().getName());
+            final Display display = NewtFactory.createDisplay(null, reuse);
+            final Screen screen = NewtFactory.createScreen(display, 0);
+            final GLWindow glWindow = GLWindow.create(screen, new GLCapabilities(GLProfile.getDefault()));
             Assert.assertNotNull(glWindow);
             glWindow.setTitle("Task "+id);
             glWindow.setPosition(x + insets.getLeftWidth(), y + insets.getTopHeight() );
     
+            glWindow.addGLEventListener(new ValidateLockListener());
             glWindow.addGLEventListener(new GearsES2(0));
     
             Animator animator = new Animator(glWindow);
@@ -98,6 +109,9 @@ public class TestInitConcurrentNEWT extends UITestCase {
             glWindow.setSize(demoSize, demoSize);
             glWindow.setVisible(true);
             animator.setUpdateFPSFrames(60, null);
+            
+            System.err.println("JOGLTask "+id+": INITIALIZED: "+", "+display+" - "+Thread.currentThread().getName());
+            
             animator.start();
             Assert.assertEquals(true, animator.isAnimating());
             Assert.assertEquals(true, glWindow.isVisible());
@@ -169,67 +183,39 @@ public class TestInitConcurrentNEWT extends UITestCase {
         return sb.toString();
     }
     
-    protected void runJOGLTasks(int num) throws InterruptedException {
+    protected void runJOGLTasks(int num, boolean reuse) throws InterruptedException {
         final String currentThreadName = Thread.currentThread().getName();
-        final Object sync = new Object();
+        final Object syncDone = new Object();
         final JOGLTask[] tasks = new JOGLTask[num];
         final Thread[] threads = new Thread[num];
         int i;
         for(i=0; i<num; i++) {
-            tasks[i] = new JOGLTask(sync, i);
+            tasks[i] = new JOGLTask(syncDone, i, reuse);
             threads[i] = new Thread(tasks[i], currentThreadName+"-jt"+i);
         }
+        final long t0 = System.currentTimeMillis(); 
+        
         for(i=0; i<num; i++) {
             threads[i].start();
         }
-        synchronized (sync) {
+        synchronized (syncDone) {
             while(!done(tasks)) {
                 try {
-                    sync.wait();
+                    syncDone.wait();
                 } catch (InterruptedException e) {
                     throw new RuntimeException(e);
                 }
             }
         }
+        final long t1 = System.currentTimeMillis();
+        System.err.println("total: "+(t1-t0)/1000.0+"s");
+        
         Assert.assertTrue("Tasks are incomplete. Complete: "+doneDump(tasks), done(tasks));
         i=0;
         while(i<30 && !isDead(threads)) {
             Thread.sleep(100);
             i++;
         }
-        Assert.assertTrue("Threads are still alive after 3s. Alive: "+isAliveDump(threads), isDead(threads));
-    }
-    
-    @Test
-    public void test01OneThread() throws InterruptedException {
-        runJOGLTasks(1);
-    }
-
-    @Test
-    public void test02TwoThreads() throws InterruptedException {
-        runJOGLTasks(2);
-    }
-    
-    @Test
-    public void test16SixteenThreads() throws InterruptedException {
-        if( Platform.getCPUFamily() == Platform.CPUFamily.ARM ) {
-            runJOGLTasks(8);
-        } else {
-            runJOGLTasks(16);
-        }
-    }
-    
-    public static void main(String args[]) throws IOException {
-        for(int i=0; i<args.length; i++) {
-            if(args[i].equals("-time")) {
-                i++;
-                try {
-                    duration = Integer.parseInt(args[i]);
-                } catch (Exception ex) { ex.printStackTrace(); }
-            }
-        }
-        String tstname = TestInitConcurrentNEWT.class.getName();
-        org.junit.runner.JUnitCore.main(tstname);
-    }
-
+        Assert.assertTrue("Threads are still alive after 3s. Alive: "+isAliveDump(threads), isDead(threads));        
+    }    
 }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPBufferDeadlockAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOAutoDrawableDeadlockAWT.java
similarity index 92%
copy from src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPBufferDeadlockAWT.java
copy to src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOAutoDrawableDeadlockAWT.java
index 3a25d12..eab1a37 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPBufferDeadlockAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOAutoDrawableDeadlockAWT.java
@@ -33,7 +33,7 @@ import java.lang.reflect.InvocationTargetException;
 import javax.media.opengl.DefaultGLCapabilitiesChooser;
 import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLDrawableFactory;
-import javax.media.opengl.GLPbuffer;
+import javax.media.opengl.GLOffscreenAutoDrawable;
 import javax.media.opengl.GLProfile;
 
 import jogamp.nativewindow.jawt.JAWTUtil;
@@ -45,7 +45,7 @@ import org.junit.Test;
 import com.jogamp.common.util.RunnableTask;
 import com.jogamp.opengl.test.junit.util.UITestCase;
 
-public class TestPBufferDeadlockAWT extends UITestCase {
+public class TestFBOAutoDrawableDeadlockAWT extends UITestCase {
   static GLProfile glp;
   static int width, height;
 
@@ -58,7 +58,7 @@ public class TestPBufferDeadlockAWT extends UITestCase {
   }
 
   protected void runTestGL( GLCapabilities caps ) throws InterruptedException, InvocationTargetException {
-    final GLPbuffer pbuffer = GLDrawableFactory.getFactory( GLProfile.getGL2ES2() ).createGLPbuffer(
+    final GLOffscreenAutoDrawable fbod = GLDrawableFactory.getFactory(caps.getGLProfile()).createOffscreenAutoDrawable(        
         null,
         caps, new DefaultGLCapabilitiesChooser(),
         512, 512,
@@ -69,7 +69,7 @@ public class TestPBufferDeadlockAWT extends UITestCase {
     final Runnable pbufferCreationAction = new Runnable() {
       public void run() {
         System.err.println("AA.1");
-        pbuffer.display();
+        fbod.display();
         done[ 0 ] = true;
         System.err.println("AA.X");
       }
@@ -100,6 +100,7 @@ public class TestPBufferDeadlockAWT extends UITestCase {
         }        
     });
     Assert.assertTrue(done[0]);
+    fbod.destroy();
   }
 
   @Test(timeout = 2000) // 2s timeout
@@ -122,6 +123,6 @@ public class TestPBufferDeadlockAWT extends UITestCase {
         }
       }
     }
-    org.junit.runner.JUnitCore.main( TestPBufferDeadlockAWT.class.getName() );
+    org.junit.runner.JUnitCore.main( TestFBOAutoDrawableDeadlockAWT.class.getName() );
   }
 } 
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOAutoDrawableFactoryNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOAutoDrawableFactoryNEWT.java
new file mode 100644
index 0000000..2dc547f
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOAutoDrawableFactoryNEWT.java
@@ -0,0 +1,375 @@
+/**
+ * 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.test.junit.jogl.acore;
+
+import java.io.IOException;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLOffscreenAutoDrawable;
+import javax.media.opengl.GLProfile;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.jogamp.opengl.FBObject;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.FBOMix2DemosES2;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.MultisampleDemoES2;
+import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+
+/**
+ * Toolkit agnostic {@link GLOffscreenAutoDrawable.FBO} tests using the 
+ * {@link GLDrawableFactory#createOffscreenAutoDrawable(javax.media.nativewindow.AbstractGraphicsDevice, GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesChooser, int, int, GLContext) factory model}. 
+ * <p>
+ * The created {@link GLOffscreenAutoDrawable.FBO} is being used to run the {@link GLEventListener}.  
+ * </p>
+ * <p>
+ * Extensive FBO reconfiguration (size and sample buffer count) and validation are performed.
+ * </p> 
+ */
+public class TestFBOAutoDrawableFactoryNEWT extends UITestCase {
+    
+    static final int widthStep = 800/4;
+    static final int heightStep = 600/4;
+    volatile int szStep = 2;
+    
+    interface MyGLEventListener extends GLEventListener {
+        void setMakeSnapshot();
+    }
+    
+    @Test
+    public void testGL2ES2_Demo1_SingleBuffer_Normal() throws InterruptedException {    
+        final GLProfile glp = GLProfile.getGL2ES2();
+        final GLCapabilities caps = new GLCapabilities(glp);
+        caps.setDoubleBuffered(false);
+        testGLFBODrawableImpl(caps, new GearsES2(0));
+    }
+    
+    @Test
+    public void testGL2ES2_Demo1_DoubleBuffer_Normal() throws InterruptedException {    
+        final GLProfile glp = GLProfile.getGL2ES2();
+        final GLCapabilities caps = new GLCapabilities(glp);
+        caps.setDoubleBuffered(true); // default
+        testGLFBODrawableImpl(caps, new GearsES2(0));
+    }
+    
+    @Test
+    public void testGL2ES2_Demo2MSAA4() throws InterruptedException {    
+        final GLProfile glp = GLProfile.getGL2ES2();
+        final GLCapabilities caps = new GLCapabilities(glp);
+        caps.setSampleBuffers(true);
+        caps.setNumSamples(4);
+        testGLFBODrawableImpl(caps, new MultisampleDemoES2(true));
+    }
+    
+    @Test
+    public void testGL2ES2_FBODemoMSAA4() throws InterruptedException {    
+        final GLProfile glp = GLProfile.getGL2ES2();
+        final FBOMix2DemosES2 demo = new FBOMix2DemosES2(0);
+        demo.setDoRotation(false);
+        final GLCapabilities caps = new GLCapabilities(glp);
+        caps.setSampleBuffers(true);
+        caps.setNumSamples(4);
+        testGLFBODrawableImpl(caps, demo);
+    }
+    
+    @Test
+    public void testEGLES2_Demo0Normal() throws InterruptedException {    
+        if( GLProfile.isAvailable(GLProfile.GLES2) )  {
+            final GLProfile glp = GLProfile.get(GLProfile.GLES2);
+            final GLCapabilities caps = new GLCapabilities(glp);
+            testGLFBODrawableImpl(caps, new GearsES2(0));
+        } else {
+            System.err.println("EGL ES2 n/a");
+        }
+    }
+    
+    @Test
+    public void testEGLES2_Demo0MSAA4() throws InterruptedException {    
+        if( GLProfile.isAvailable(GLProfile.GLES2) )  {
+            final GLProfile glp = GLProfile.get(GLProfile.GLES2);
+            final GLCapabilities caps = new GLCapabilities(glp);
+            caps.setSampleBuffers(true);
+            caps.setNumSamples(4);
+            testGLFBODrawableImpl(caps, new GearsES2(0));
+        } else {
+            System.err.println("EGL ES2 n/a");
+        }
+    }
+
+    void testGLFBODrawableImpl(GLCapabilities caps, GLEventListener demo) throws InterruptedException {
+        caps.setFBO(true);
+        final GLDrawableFactory factory = GLDrawableFactory.getFactory(caps.getGLProfile());
+        final GLOffscreenAutoDrawable.FBO glad = (GLOffscreenAutoDrawable.FBO)
+                factory.createOffscreenAutoDrawable(null, caps, null, widthStep*szStep, heightStep*szStep, null);
+        Assert.assertNotNull(glad);
+        
+        System.out.println("Realized GLAD: "+glad);
+        System.out.println("Realized GLAD: "+glad.getChosenGLCapabilities());
+        Assert.assertTrue("FBO drawable is initialized before ctx creation", !glad.isInitialized());
+        
+        glad.display(); // initial display incl. init!
+        {
+            final GLContext context = glad.getContext();
+            Assert.assertNotNull(context);
+            Assert.assertTrue(context.isCreated());
+        }
+        Assert.assertTrue("FBO drawable is not initialized after ctx creation", glad.isInitialized());        
+        
+        //
+        // FBO incl. MSAA is fully initialized now
+        //
+        
+        final GLCapabilitiesImmutable chosenCaps = glad.getChosenGLCapabilities();
+        System.out.println("Init GLAD: "+glad);
+        System.out.println("Init GLAD: "+chosenCaps);
+        
+        final FBObject fboFront = glad.getFBObject(GL.GL_FRONT);
+        final FBObject fboBack  = glad.getFBObject(GL.GL_BACK);
+        
+        System.out.println("Init front FBO: "+fboFront);
+        System.out.println("Init back  FBO: "+fboBack);
+        
+        Assert.assertTrue("FBO drawable is not initialized before ctx creation", glad.isInitialized());
+        Assert.assertTrue("FBO Front is not initialized before ctx creation", fboFront.isInitialized());
+        Assert.assertTrue("FBO Back  is not initialized before ctx creation", fboBack.isInitialized());
+        
+        if( chosenCaps.getDoubleBuffered() ) {
+            Assert.assertTrue("FBO are equal: "+fboFront+" == "+fboBack, !fboFront.equals(fboBack));
+            Assert.assertNotSame(fboFront, fboBack);
+        } else {
+            Assert.assertTrue("FBO are not equal: "+fboFront+" != "+fboBack, fboFront.equals(fboBack));
+            Assert.assertSame(fboFront, fboBack);            
+        }
+        
+        final FBObject.TextureAttachment texAttachA, texAttachB;
+        
+        texAttachA = glad.getTextureBuffer(GL.GL_FRONT);
+        if(0==glad.getNumSamples()) {
+            texAttachB = glad.getTextureBuffer(GL.GL_BACK);
+        } else {
+            texAttachB = null;
+        }
+        
+        final FBObject.Colorbuffer colorA, colorB;
+        final FBObject.RenderAttachment depthA, depthB;
+        
+        colorA = fboFront.getColorbuffer(0);
+        Assert.assertNotNull(colorA);
+        colorB = fboBack.getColorbuffer(0);
+        Assert.assertNotNull(colorB);
+        
+        depthA = fboFront.getDepthAttachment();
+        Assert.assertNotNull(depthA);
+        depthB = fboBack.getDepthAttachment();
+        Assert.assertNotNull(depthB);
+
+        glad.display(); // SWAP_ODD
+        
+        if( chosenCaps.getDoubleBuffered() ) {
+            // double buffer or MSAA
+            Assert.assertTrue("Color attachments are equal: "+colorB+" == "+colorA, !colorB.equals(colorA));
+            Assert.assertNotSame(colorB, colorA);
+            Assert.assertTrue("Depth attachments are equal: "+depthB+" == "+depthA, !depthB.equals(depthA));
+            Assert.assertNotSame(depthB, depthA);
+        } else {
+            // single buffer
+            Assert.assertEquals(colorA, colorB);
+            Assert.assertSame(colorA, colorB);
+            Assert.assertEquals(depthA, depthB);
+            Assert.assertSame(depthA, depthB);
+        }
+        
+        Assert.assertEquals(texAttachA, colorA);
+        Assert.assertSame(texAttachA, colorA);
+        if(0==glad.getNumSamples()) {
+            Assert.assertEquals(texAttachB, colorB);
+            Assert.assertSame(texAttachB, colorB);            
+        }
+
+        if( chosenCaps.getNumSamples() > 0 ) {
+            // MSAA        
+            FBObject _fboFront = glad.getFBObject(GL.GL_FRONT);
+            FBObject _fboBack = glad.getFBObject(GL.GL_BACK);
+            Assert.assertTrue("FBO are not equal: "+fboFront+" != "+_fboFront, fboFront.equals(_fboFront));
+            Assert.assertSame(fboFront, _fboFront);
+            Assert.assertTrue("FBO are not equal: "+fboBack+" != "+_fboBack, fboBack.equals(_fboBack));
+            Assert.assertSame(fboBack, _fboBack);
+        } else if( chosenCaps.getDoubleBuffered() ) {
+            // real double buffer
+            FBObject _fboFront = glad.getFBObject(GL.GL_FRONT);
+            FBObject _fboBack = glad.getFBObject(GL.GL_BACK);
+            Assert.assertTrue("FBO are not equal: "+fboBack+" != "+_fboFront, fboBack.equals(_fboFront));
+            Assert.assertSame(fboBack, _fboFront);
+            Assert.assertTrue("FBO are not equal: "+fboFront+" != "+_fboBack, fboFront.equals(_fboBack));
+            Assert.assertSame(fboFront, _fboBack);
+        } else {
+            // single buffer
+            FBObject _fboFront = glad.getFBObject(GL.GL_FRONT);
+            FBObject _fboBack = glad.getFBObject(GL.GL_BACK);
+            Assert.assertTrue("FBO are not equal: "+fboFront+" != "+_fboFront, fboFront.equals(_fboFront));
+            Assert.assertSame(fboFront, _fboFront);
+            Assert.assertTrue("FBO are not equal: "+fboBack+" != "+_fboFront, fboBack.equals(_fboFront));
+            Assert.assertSame(fboBack, _fboFront);
+            Assert.assertTrue("FBO are not equal: "+fboBack+" != "+_fboBack, fboBack.equals(_fboBack));
+            Assert.assertSame(fboBack, _fboBack);
+            Assert.assertTrue("FBO are not equal: "+fboFront+" != "+_fboBack, fboFront.equals(_fboBack));
+            Assert.assertSame(fboFront, _fboBack);
+        }
+                
+        glad.addGLEventListener(demo);
+        
+        final SnapshotGLEventListener snapshotGLEventListener = new SnapshotGLEventListener();
+        glad.addGLEventListener(snapshotGLEventListener);
+        
+        glad.display(); // - SWAP_EVEN
+
+        // 1 - szStep = 2
+        snapshotGLEventListener.setMakeSnapshot();
+        glad.display(); // - SWAP_ODD
+        
+        // 2, 3 (resize + display)
+        szStep = 1;
+        glad.setSize(widthStep*szStep, heightStep*szStep); // SWAP_EVEN
+        Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(), 
+                          AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep));
+        snapshotGLEventListener.setMakeSnapshot();
+        glad.display();  //  - SWAP_ODD
+        glad.display();  //  - SWAP_EVEN
+        {
+            // Check whether the attachment reference are still valid!
+            final FBObject _fboFront = glad.getFBObject(GL.GL_FRONT);
+            final FBObject _fboBack = glad.getFBObject(GL.GL_BACK);
+            System.out.println("Resize1.oldFront: "+fboFront);
+            System.out.println("Resize1.nowFront: "+_fboFront);
+            System.out.println("Resize1.oldBack : "+fboBack);
+            System.out.println("Resize1.nowBack : "+_fboBack);
+            Assert.assertEquals(fboFront, _fboFront);
+            Assert.assertSame(fboFront, _fboFront);
+            Assert.assertEquals(fboBack,  _fboBack);
+            Assert.assertSame(fboBack,  _fboBack);
+            
+            FBObject.Colorbuffer _color = _fboFront.getColorbuffer(0);
+            Assert.assertNotNull(_color);
+            Assert.assertEquals(colorA, _color);
+            Assert.assertSame(colorA, _color);
+            
+            FBObject.RenderAttachment _depth = _fboFront.getDepthAttachment();
+            System.err.println("Resize1.oldDepth "+depthA);
+            System.err.println("Resize1.newDepth "+_depth);
+            Assert.assertNotNull(_depth);
+            
+            Assert.assertEquals(depthA, _depth);
+            Assert.assertSame(depthA, _depth);
+            _depth = _fboBack.getDepthAttachment();
+            Assert.assertNotNull(_depth);
+            Assert.assertEquals(depthB, _depth);
+            Assert.assertSame(depthB, _depth);
+            
+            _color = _fboFront.getColorbuffer(colorA);
+            Assert.assertNotNull(_color);
+            Assert.assertEquals(colorA, _color);
+            Assert.assertSame(colorA, _color);
+        }
+        
+        // 4, 5 (resize + display)
+        szStep = 4;
+        glad.setSize(widthStep*szStep, heightStep*szStep); // SWAP_ODD
+        Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(), 
+                          AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep));
+        snapshotGLEventListener.setMakeSnapshot();
+        glad.display(); //  - SWAP_EVEN
+        glad.display(); //  - SWAP_ODD
+        {
+            // Check whether the attachment reference are still valid!
+            final FBObject _fboFront = glad.getFBObject(GL.GL_FRONT);
+            final FBObject _fboBack = glad.getFBObject(GL.GL_BACK);
+            System.out.println("Resize2.oldFront: "+fboFront);
+            System.out.println("Resize2.nowFront: "+_fboFront);
+            System.out.println("Resize2.oldBack : "+fboBack);
+            System.out.println("Resize2.nowBack : "+_fboBack);
+            if(chosenCaps.getDoubleBuffered() && 0==chosenCaps.getNumSamples()) {
+                // real double buffer
+                Assert.assertEquals(fboBack,  _fboFront);
+                Assert.assertEquals(fboFront, _fboBack);
+            } else {
+                // single or MSAA
+                Assert.assertEquals(fboFront,  _fboFront);
+                Assert.assertEquals(fboBack,   _fboBack);                
+            }
+            
+            FBObject.Colorbuffer _color = fboBack.getColorbuffer(0);
+            Assert.assertNotNull(_color);
+            Assert.assertEquals(colorB, _color);
+            Assert.assertSame(colorB, _color);
+            
+            FBObject.RenderAttachment _depth = fboBack.getDepthAttachment();
+            Assert.assertNotNull(_depth); // MSAA back w/ depth 
+            Assert.assertEquals(depthB, _depth);
+            Assert.assertSame(depthB, _depth);
+            
+            _depth = fboFront.getDepthAttachment();
+            Assert.assertNotNull(_depth);
+            Assert.assertEquals(depthA, _depth);
+            Assert.assertSame(depthA, _depth);
+            
+            _color = fboBack.getColorbuffer(colorB);
+            Assert.assertNotNull(_color);
+            Assert.assertEquals(colorB, _color);
+            Assert.assertSame(colorB, _color);
+        }
+        
+        // 6 + 7 (samples + display)
+        glad.setNumSamples(glad.getGL(), chosenCaps.getNumSamples() > 0 ? 0 : 4); // triggers repaint
+        snapshotGLEventListener.setMakeSnapshot();
+        glad.display(); // actual screenshot
+        
+        // 8, 9 (resize + samples + display)
+        szStep = 3;
+        glad.setSize(widthStep*szStep, heightStep*szStep);
+        Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(), 
+                          AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep));
+        snapshotGLEventListener.setMakeSnapshot();
+        glad.display();
+                
+        glad.destroy();
+        System.out.println("Fin: "+glad);
+    }
+    
+    public static void main(String args[]) throws IOException {
+        org.junit.runner.JUnitCore.main(TestFBOAutoDrawableFactoryNEWT.class.getName());
+    }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBODrawableNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBODrawableNEWT.java
deleted file mode 100644
index 7977347..0000000
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBODrawableNEWT.java
+++ /dev/null
@@ -1,272 +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.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.GLDrawable;
-import javax.media.opengl.GLDrawableFactory;
-import javax.media.opengl.GLEventListener;
-import javax.media.opengl.GLProfile;
-
-import jogamp.opengl.GLFBODrawableImpl;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-import com.jogamp.opengl.FBObject;
-import com.jogamp.opengl.OffscreenAutoDrawable;
-import com.jogamp.opengl.test.junit.jogl.demos.es2.FBOMix2DemosES2;
-import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
-import com.jogamp.opengl.test.junit.jogl.demos.es2.MultisampleDemoES2;
-import com.jogamp.opengl.test.junit.util.UITestCase;
-import com.jogamp.opengl.util.GLReadBufferUtil;
-import com.jogamp.opengl.util.texture.TextureIO;
-
-public class TestFBODrawableNEWT extends UITestCase {
-    
-    static final int widthStep = 800/4;
-    static final int heightStep = 600/4;
-    volatile int szStep = 2;
-    
-    @Test
-    public void testGL2ES2_Demo1Normal() throws InterruptedException {    
-        final GLProfile glp = GLProfile.getGL2ES2();
-        final GLCapabilities caps = new GLCapabilities(glp);
-        testGLFBODrawableImpl(caps, new GearsES2(0));
-    }
-    
-    @Test
-    public void testGL2ES2_Demo1MSAA4() throws InterruptedException {    
-        final GLProfile glp = GLProfile.getGL2ES2();
-        final GLCapabilities caps = new GLCapabilities(glp);
-        caps.setSampleBuffers(true);
-        caps.setNumSamples(4);
-        testGLFBODrawableImpl(caps, new GearsES2(0));
-    }
-    
-    @Test
-    public void testGL2ES2_Demo2Normal() throws InterruptedException {    
-        final GLProfile glp = GLProfile.getGL2ES2();
-        final GLCapabilities caps = new GLCapabilities(glp);
-        testGLFBODrawableImpl(caps, new MultisampleDemoES2(false));
-    }
-    
-    @Test
-    public void testGL2ES2_Demo2MSAA4() throws InterruptedException {    
-        final GLProfile glp = GLProfile.getGL2ES2();
-        final GLCapabilities caps = new GLCapabilities(glp);
-        caps.setSampleBuffers(true);
-        caps.setNumSamples(4);
-        testGLFBODrawableImpl(caps, new MultisampleDemoES2(true));
-    }
-    
-    @Test
-    public void testGL2ES2_FBODemoNormal() throws InterruptedException {    
-        final GLProfile glp = GLProfile.getGL2ES2();
-        final FBOMix2DemosES2 demo = new FBOMix2DemosES2(0);
-        demo.setDoRotation(false);
-        final GLCapabilities caps = new GLCapabilities(glp);
-        testGLFBODrawableImpl(caps, demo);
-    }
-    
-    @Test
-    public void testGL2ES2_FBODemoMSAA4() throws InterruptedException {    
-        final GLProfile glp = GLProfile.getGL2ES2();
-        final FBOMix2DemosES2 demo = new FBOMix2DemosES2(0);
-        demo.setDoRotation(false);
-        final GLCapabilities caps = new GLCapabilities(glp);
-        caps.setSampleBuffers(true);
-        caps.setNumSamples(4);
-        testGLFBODrawableImpl(caps, demo);
-    }
-    
-    @Test
-    public void testEGLES2_Demo0Normal() throws InterruptedException {    
-        if( GLProfile.isAvailable(GLProfile.GLES2) )  {
-            final GLProfile glp = GLProfile.get(GLProfile.GLES2);
-            final GLCapabilities caps = new GLCapabilities(glp);
-            testGLFBODrawableImpl(caps, new GearsES2(0));
-        } else {
-            System.err.println("EGL ES2 n/a");
-        }
-    }
-    
-    @Test
-    public void testEGLES2_Demo0MSAA4() throws InterruptedException {    
-        if( GLProfile.isAvailable(GLProfile.GLES2) )  {
-            final GLProfile glp = GLProfile.get(GLProfile.GLES2);
-            final GLCapabilities caps = new GLCapabilities(glp);
-            caps.setSampleBuffers(true);
-            caps.setNumSamples(4);
-            testGLFBODrawableImpl(caps, new GearsES2(0));
-        } else {
-            System.err.println("EGL ES2 n/a");
-        }
-    }
-
-    boolean skipShot = false;
-    
-    void testGLFBODrawableImpl(GLCapabilities caps, GLEventListener demo) throws InterruptedException {
-        final GLReadBufferUtil screenshot = new GLReadBufferUtil(false, false);
-        caps.setFBO(true);
-        final GLDrawableFactory factory = GLDrawableFactory.getFactory(caps.getGLProfile());
-        final GLDrawable fboDrawable = factory.createOffscreenDrawable(null, caps, null, widthStep*szStep, heightStep*szStep);
-        Assert.assertNotNull(fboDrawable);
-        Assert.assertTrue("Not an FBO Drawable", fboDrawable instanceof GLFBODrawableImpl);
-        
-        fboDrawable.setRealized(true);
-        Assert.assertTrue(fboDrawable.isRealized());
-        
-        final FBObject fbo = ((GLFBODrawableImpl)fboDrawable).getFBObject();
-        
-        System.out.println("Realized: "+fboDrawable);
-        System.out.println("Realized: "+fboDrawable.getChosenGLCapabilities());
-        System.out.println("Realized: "+fbo);
-        
-        final GLContext context = fboDrawable.createContext(null);
-        Assert.assertNotNull(context);
-        
-        int res = context.makeCurrent();
-        Assert.assertTrue(GLContext.CONTEXT_CURRENT_NEW==res || GLContext.CONTEXT_CURRENT==res);
-        context.release();
-        
-        System.out.println("Post Create-Ctx: "+fbo);        
-        final FBObject.Colorbuffer colorA = fbo.getColorbuffer(0);
-        Assert.assertNotNull(colorA);
-        final FBObject.RenderAttachment depthA = fbo.getDepthAttachment();
-        Assert.assertNotNull(depthA);
-        
-        final OffscreenAutoDrawable glad = new OffscreenAutoDrawable(fboDrawable, context, true);
-
-        glad.addGLEventListener(demo);
-        glad.addGLEventListener(new GLEventListener() {
-            volatile int displayCount=0;
-            volatile int reshapeCount=0;
-            public void init(GLAutoDrawable drawable) {}
-            public void dispose(GLAutoDrawable drawable) {}
-            public void display(GLAutoDrawable drawable) {
-                final GL gl = drawable.getGL();
-                // System.err.println(Thread.currentThread().getName()+": ** display: "+displayCount+": step "+szStep+" "+drawable.getWidth()+"x"+drawable.getHeight());
-                // System.err.println(Thread.currentThread().getName()+": ** FBO-THIS: "+fbo);
-                // System.err.println(Thread.currentThread().getName()+": ** FBO-SINK: "+fbo.getSamplingSinkFBO());
-                // System.err.println(Thread.currentThread().getName()+": ** drawable-read: "+gl.getDefaultReadFramebuffer());
-                if(skipShot) {
-                    skipShot=false;
-                } else {
-                    snapshot(getSimpleTestName("."), displayCount, "msaa"+fbo.getNumSamples(), gl, screenshot, TextureIO.PNG, null);
-                }
-                Assert.assertEquals(drawable.getWidth(), widthStep*szStep);
-                Assert.assertEquals(drawable.getHeight(), heightStep*szStep); 
-                displayCount++;
-            }
-            public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
-                System.err.println(Thread.currentThread().getName()+": ** reshape: "+reshapeCount+": step "+szStep+" "+width+"x"+height+" - "+drawable.getWidth()+"x"+drawable.getHeight());
-                Assert.assertEquals(drawable.getWidth(), widthStep*szStep);
-                Assert.assertEquals(drawable.getHeight(), heightStep*szStep);                
-                reshapeCount++;
-            }
-        });
-
-        // 0 - szStep = 2
-        glad.display();
-        
-        // 1, 2 (resize + display)
-        szStep = 1;
-        skipShot=true;
-        glad.setSize(widthStep*szStep, heightStep*szStep);
-        glad.display();
-        Assert.assertEquals(glad.getWidth(), widthStep*szStep);
-        Assert.assertEquals(glad.getHeight(), heightStep*szStep);
-        {
-            // Check whether the attachment reference are still valid!
-            FBObject.Colorbuffer _colorA = fbo.getColorbuffer(0);
-            Assert.assertNotNull(_colorA);
-            Assert.assertTrue(colorA == _colorA);
-            Assert.assertTrue(colorA.equals(_colorA));
-            FBObject.RenderAttachment _depthA = fbo.getDepthAttachment();
-            Assert.assertNotNull(_depthA);
-            Assert.assertTrue(depthA == _depthA);
-            Assert.assertTrue(depthA.equals(_depthA));
-            
-            _colorA = fbo.getColorbuffer(colorA);
-            Assert.assertNotNull(_colorA);
-            Assert.assertTrue(colorA == _colorA);
-            Assert.assertTrue(colorA.equals(_colorA));
-        }
-        
-        // 3, 4 (resize + display)
-        szStep = 4;
-        skipShot=true;
-        glad.setSize(widthStep*szStep, heightStep*szStep);
-        glad.display();
-        Assert.assertEquals(glad.getWidth(), widthStep*szStep);
-        Assert.assertEquals(glad.getHeight(), heightStep*szStep);
-        {
-            // Check whether the attachment reference are still valid!
-            FBObject.Colorbuffer _colorA = fbo.getColorbuffer(0);
-            Assert.assertNotNull(_colorA);
-            Assert.assertTrue(colorA == _colorA);
-            final FBObject.RenderAttachment _depthA = fbo.getDepthAttachment();
-            Assert.assertNotNull(_depthA);
-            Assert.assertTrue(depthA == _depthA);
-            
-            _colorA = fbo.getColorbuffer(colorA);
-            Assert.assertNotNull(_colorA);
-            Assert.assertTrue(colorA == _colorA);
-        }
-        
-        // 5
-        glad.display();
-        Assert.assertEquals(glad.getWidth(), widthStep*szStep);
-        Assert.assertEquals(glad.getHeight(), heightStep*szStep);
-        
-        // 6, 7 (resize + display)
-        szStep = 3;
-        skipShot=true;
-        glad.setSize(widthStep*szStep, heightStep*szStep);
-        glad.display();
-        Assert.assertEquals(glad.getWidth(), widthStep*szStep);
-        Assert.assertEquals(glad.getHeight(), heightStep*szStep);
-        
-        glad.destroy();
-        System.out.println("Fin: "+fboDrawable);
-        
-        // final GLAutoDrawableDelegate glad = new GLAutoDrawableDelegate(fboDrawable, context);
-    }
-    
-    public static void main(String args[]) throws IOException {
-        org.junit.runner.JUnitCore.main(TestFBODrawableNEWT.class.getName());
-    }
-
-}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMRTNEWT01.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMRTNEWT01.java
index f7c83a0..e5075bb 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMRTNEWT01.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMRTNEWT01.java
@@ -50,7 +50,6 @@ import javax.media.opengl.GL2ES2;
 import javax.media.opengl.GL2GL3;
 import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLDrawable;
-import javax.media.opengl.GLPipelineFactory;
 import javax.media.opengl.GLProfile;
 import javax.media.opengl.GLUniformData;
 
@@ -74,7 +73,7 @@ public class TestFBOMRTNEWT01 extends UITestCase {
                 new GLCapabilities(GLProfile.getGL2GL3()), width/step, height/step, true);        
         final GLDrawable drawable = winctx.context.getGLDrawable();
         GL2GL3 gl = winctx.context.getGL().getGL2GL3();
-        gl = gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Debug", null, gl, null) ).getGL2GL3();
+        // gl = gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Debug", null, gl, null) ).getGL2GL3();
         System.err.println(winctx.context);
 
         Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
@@ -88,8 +87,8 @@ public class TestFBOMRTNEWT01 extends UITestCase {
                 "shader/bin", "fbo-mrt-1", false);
         final ShaderProgram sp0 = new ShaderProgram();
         sp0.add(gl, vp0, System.err);
-        sp0.add(gl, fp0, System.err);       
-        Assert.assertTrue(0<=sp0.program()); 
+        sp0.add(gl, fp0, System.err);
+        Assert.assertTrue(0 != sp0.program()); 
         Assert.assertTrue(!sp0.inUse());
         Assert.assertTrue(!sp0.linked());
         Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());        
@@ -102,7 +101,7 @@ public class TestFBOMRTNEWT01 extends UITestCase {
         final ShaderProgram sp1 = new ShaderProgram();
         sp1.add(gl, vp1, System.err);
         sp1.add(gl, fp1, System.err);       
-        Assert.assertTrue(0<=sp1.program()); 
+        Assert.assertTrue(0 != sp1.program()); 
         Assert.assertTrue(!sp1.inUse());
         Assert.assertTrue(!sp1.linked());
         Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());        
@@ -162,7 +161,13 @@ public class TestFBOMRTNEWT01 extends UITestCase {
         final FBObject fbo_mrt = new FBObject();
         fbo_mrt.reset(gl, drawable.getWidth(), drawable.getHeight());
         final TextureAttachment texA0 = fbo_mrt.attachTexture2D(gl, texA0Point, true, GL.GL_NEAREST, GL.GL_NEAREST, GL.GL_CLAMP_TO_EDGE, GL.GL_CLAMP_TO_EDGE);
-        final TextureAttachment texA1 = fbo_mrt.attachTexture2D(gl, texA1Point, true, GL.GL_NEAREST, GL.GL_NEAREST, GL.GL_CLAMP_TO_EDGE, GL.GL_CLAMP_TO_EDGE);
+        final TextureAttachment texA1;
+        if(fbo_mrt.getMaxColorAttachments() > 1) {
+            texA1 = fbo_mrt.attachTexture2D(gl, texA1Point, true, GL.GL_NEAREST, GL.GL_NEAREST, GL.GL_CLAMP_TO_EDGE, GL.GL_CLAMP_TO_EDGE);
+        } else {
+            texA1 = null;
+            System.err.println("FBO supports only one attachment, no MRT available!");
+        }
         fbo_mrt.attachRenderbuffer(gl, Type.DEPTH, 24);
         Assert.assertTrue( fbo_mrt.isStatusValid() ) ;
         fbo_mrt.unbind(gl);
@@ -216,8 +221,10 @@ public class TestFBOMRTNEWT01 extends UITestCase {
             
             gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit0.intValue());            
             fbo_mrt.use(gl, texA0);
-            gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit1.intValue());
-            fbo_mrt.use(gl, texA1);
+            if(null != texA1) {
+                gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit1.intValue());
+                fbo_mrt.use(gl, texA1);
+            }
             gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
             gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, 4);
             fbo_mrt.unuse(gl);
@@ -229,7 +236,7 @@ public class TestFBOMRTNEWT01 extends UITestCase {
                 final NativeSurface ns = gl.getContext().getGLReadDrawable().getNativeSurface();
                 if(last_snap_size[0] != ns.getWidth() && last_snap_size[1] != ns.getHeight()) {
                     gl.glFinish(); // sync .. no swap buffers yet!
-                    snapshot(getSimpleTestName("."), step_i, null, gl, screenshot, TextureIO.PNG, null); // overwrite ok
+                    snapshot(step_i, null, gl, screenshot, TextureIO.PNG, null); // overwrite ok
                     last_snap_size[0] = ns.getWidth();
                     last_snap_size[1] = ns.getHeight();
                 }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMix2DemosES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMix2DemosES2NEWT.java
index b384c93..b3c542c 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMix2DemosES2NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMix2DemosES2NEWT.java
@@ -106,7 +106,7 @@ public class TestFBOMix2DemosES2NEWT extends UITestCase {
                 if(dw<800) {
                     System.err.println("XXX: "+dw+"x"+dh+", c "+c);
                     if(0 == c%3) {
-                        snapshot(getSimpleTestName("."), i++, "msaa"+demo.getMSAA(), drawable.getGL(), screenshot, TextureIO.PNG, null);                        
+                        snapshot(i++, "msaa"+demo.getMSAA(), drawable.getGL(), screenshot, TextureIO.PNG, null);                        
                     }
                     if( 3 == c ) {
                         new Thread() { 
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMix2DemosES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOOffThreadSharedContextMix2DemosES2NEWT.java
similarity index 54%
copy from src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMix2DemosES2NEWT.java
copy to src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOOffThreadSharedContextMix2DemosES2NEWT.java
index b384c93..3ecf89b 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMix2DemosES2NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOOffThreadSharedContextMix2DemosES2NEWT.java
@@ -32,8 +32,6 @@ import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
 
-import com.jogamp.newt.event.KeyAdapter;
-import com.jogamp.newt.event.KeyEvent;
 import com.jogamp.newt.event.WindowEvent;
 import com.jogamp.newt.event.WindowAdapter;
 import com.jogamp.newt.opengl.GLWindow;
@@ -43,58 +41,134 @@ 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.FPSAnimator;
 import com.jogamp.opengl.util.GLReadBufferUtil;
 import com.jogamp.opengl.util.texture.TextureIO;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.Mix2TexturesES2;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.RedSquareES2;
 
-import com.jogamp.opengl.test.junit.jogl.demos.es2.FBOMix2DemosES2;
-
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.SurfaceUpdatedListener;
+import javax.media.opengl.GL;
 import javax.media.opengl.GLAutoDrawable;
 import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawableFactory;
 import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLOffscreenAutoDrawable;
 import javax.media.opengl.GLProfile;
 
 import org.junit.Assert;
 import org.junit.AfterClass;
 import org.junit.Test;
 
-public class TestFBOMix2DemosES2NEWT extends UITestCase {    
+/**
+ * Toolkit agnostic {@link GLOffscreenAutoDrawable.FBO} tests using the 
+ * {@link GLDrawableFactory#createOffscreenAutoDrawable(javax.media.nativewindow.AbstractGraphicsDevice, GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesChooser, int, int, GLContext) factory model}. 
+ * <p>
+ * The created {@link GLOffscreenAutoDrawable.FBO} is being used to run the {@link GLEventListener}.  
+ * </p>
+ * <p>
+ * This test simulates shared off-thread GL context / texture usage,
+ * where the producer use FBOs and delivers shared textures.
+ * The receiver blends the shared textures onscreen.
+ * In detail the test consist of:
+ * <ul>
+ *   <li>2 {@link GLOffscreenAutoDrawable.FBO} double buffered
+ *   <ul>
+ *     <li>each with their own {@link GLContext}, which is shares the {@link GLWindow} one (see below)</li> 
+ *     <li>both run within one {@link FPSAnimator} @ 30fps</li>
+ *     <li>produce a texture</li>
+ *     <li>notify the onscreen renderer about new textureID (swapping double buffer)</li>
+ *   </ul></li>
+ *   <li>1 onscreen {@link GLWindow}
+ *   <ul>
+ *     <li>shares it's {@link GLContext} w/ above FBOs</li>
+ *     <li>running within one {@link Animator} at v-sync</li>
+ *     <li>uses the shared FBO textures and blends them onscreen</li>
+ *   </ul></li>  
+ * </ul> 
+ * </p> 
+ */
+public class TestFBOOffThreadSharedContextMix2DemosES2NEWT extends UITestCase {    
     static long duration = 500; // ms
     static int swapInterval = 1;
     static boolean showFPS = false;
     static boolean forceES2 = false;
-    static boolean doRotate = true;
-    static boolean demo0Only = false;
-    static int globalNumSamples = 0;
     static boolean mainRun = false;
-    
+        
     @AfterClass
     public static void releaseClass() {
     }
 
-    protected void runTestGL(GLCapabilitiesImmutable caps, int numSamples) throws InterruptedException {
-        final GLReadBufferUtil screenshot = new GLReadBufferUtil(true, false);
+    protected void runTestGL(GLCapabilitiesImmutable caps) throws InterruptedException {
+        final GLReadBufferUtil screenshot = new GLReadBufferUtil(false, false);
         System.err.println("requested: vsync "+swapInterval+", "+caps);
+        
         final GLWindow glWindow = GLWindow.create(caps);
         Assert.assertNotNull(glWindow);
         glWindow.setTitle("Gears NEWT Test (translucent "+!caps.isBackgroundOpaque()+"), swapInterval "+swapInterval);
         if(mainRun) {
             glWindow.setSize(512, 512);            
         } else {
-            glWindow.setSize(128, 128);
+            glWindow.setSize(256, 256);
+        }
+        // eager initialization of context
+        glWindow.setVisible(true);
+        glWindow.display(); 
+
+        final int fbod1_texUnit = 0;
+        final int fbod2_texUnit = 1;
+        
+        final GLDrawableFactory factory = GLDrawableFactory.getFactory(caps.getGLProfile());
+        GLCapabilities fbodCaps = (GLCapabilities) caps.cloneMutable();
+        // fbodCaps.setDoubleBuffered(false);
+        
+        final Mix2TexturesES2 mixerDemo = new Mix2TexturesES2(1, fbod1_texUnit, fbod2_texUnit);
+
+        // FBOD1 
+        final GLOffscreenAutoDrawable.FBO fbod1 = (GLOffscreenAutoDrawable.FBO)
+                factory.createOffscreenAutoDrawable(null, fbodCaps, null, glWindow.getWidth(), glWindow.getHeight(), glWindow.getContext());
+        fbod1.setUpstreamWidget(glWindow); // connect the real GLWindow (mouse/key) to offscreen!
+        fbod1.setTextureUnit(fbod1_texUnit);
+        {
+            GearsES2 demo0 = new GearsES2(-1);
+            fbod1.addGLEventListener(demo0);
+            demo0.setIgnoreFocus(true);
         }
+        fbod1.getNativeSurface().addSurfaceUpdatedListener(new SurfaceUpdatedListener() {
+            @Override
+            public void surfaceUpdated(Object updater, NativeSurface ns, long when) {
+                mixerDemo.setTexID0(fbod1.getTextureBuffer(GL.GL_FRONT).getName());
+            } });
+        fbod1.display(); // init
+        System.err.println("FBOD1 "+fbod1);
+        Assert.assertTrue(fbod1.isInitialized());
+        
+        // FBOD2
+        final GLOffscreenAutoDrawable.FBO fbod2 = (GLOffscreenAutoDrawable.FBO)
+                factory.createOffscreenAutoDrawable(null, fbodCaps, null, glWindow.getWidth(), glWindow.getHeight(), glWindow.getContext());        
+        fbod2.setTextureUnit(fbod2_texUnit);
+        fbod2.addGLEventListener(new RedSquareES2(-1));
+        fbod2.getNativeSurface().addSurfaceUpdatedListener(new SurfaceUpdatedListener() {
+            @Override
+            public void surfaceUpdated(Object updater, NativeSurface ns, long when) {
+                mixerDemo.setTexID1(fbod2.getTextureBuffer(GL.GL_FRONT).getName());
+            } });
+        fbod2.display(); // init
+        System.err.println("FBOD2 "+fbod2);
+        Assert.assertTrue(fbod2.isInitialized());
 
-        final FBOMix2DemosES2 demo = new FBOMix2DemosES2(swapInterval);
-        demo.setMSAA(numSamples);
-        demo.setDoRotation(doRotate);
-        demo.setDemo0Only(demo0Only);
-        glWindow.addGLEventListener(demo);
+        // preinit texIDs
+        mixerDemo.setTexID0(fbod1.getTextureBuffer(GL.GL_FRONT).getName());
+        mixerDemo.setTexID1(fbod2.getTextureBuffer(GL.GL_FRONT).getName());
+        
+        glWindow.addGLEventListener(mixerDemo);
         glWindow.addGLEventListener(new GLEventListener() {
             int i=0, c=0;
-            int origS;
-            public void init(GLAutoDrawable drawable) {
-                origS = demo.getMSAA();
-            }
+            public void init(GLAutoDrawable drawable) {}
             public void dispose(GLAutoDrawable drawable) {}
             public void display(GLAutoDrawable drawable) {
                 if(mainRun) return;
@@ -105,36 +179,32 @@ public class TestFBOMix2DemosES2NEWT extends UITestCase {
                 
                 if(dw<800) {
                     System.err.println("XXX: "+dw+"x"+dh+", c "+c);
-                    if(0 == c%3) {
-                        snapshot(getSimpleTestName("."), i++, "msaa"+demo.getMSAA(), drawable.getGL(), screenshot, TextureIO.PNG, null);                        
+                    if(8 == c) {
+                        snapshot(i++, "msaa"+fbod1.getNumSamples(), drawable.getGL(), screenshot, TextureIO.PNG, null);                        
                     }
-                    if( 3 == c ) {
-                        new Thread() { 
-                            @Override
-                            public void run() {
-                                demo.setMSAA(4);
-                            } }.start();
-                    } else if( 6 == c ) {
-                        new Thread() { 
-                            @Override
-                            public void run() {
-                                demo.setMSAA(8);
-                            } }.start();
-                    } else if(9 == c) {
+                    if(9 == c) {
                         c=0;
                         new Thread() { 
                             @Override
                             public void run() {
                                 glWindow.setSize(dw+256, dh+256);
-                                demo.setMSAA(origS);
                             } }.start();                            
                     }
                 }
             }
-            public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
+            public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { 
+                fbod1.setSize(width, height);
+                fbod2.setSize(width, height);
+            }
         });
         
-        Animator animator = new Animator(glWindow);
+        final FPSAnimator animator0 = new FPSAnimator(30);
+        animator0.add(fbod1);
+        animator0.add(fbod2);
+        
+        final Animator animator1 = new Animator();
+        animator1.add(glWindow);
+        
         QuitAdapter quitAdapter = new QuitAdapter();
 
         //glWindow.addKeyListener(new TraceKeyAdapter(quitAdapter));
@@ -151,30 +221,8 @@ public class TestFBOMix2DemosES2NEWT extends UITestCase {
             }            
         });
         
-        glWindow.addKeyListener(new KeyAdapter() {
-            public void keyTyped(KeyEvent e) {
-                System.err.println("*** "+e);
-                if(e.getKeyChar()=='f') {
-                    new Thread() {
-                        public void run() {
-                            System.err.println("[set fullscreen  pre]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets());
-                            glWindow.setFullscreen(!glWindow.isFullscreen());
-                            System.err.println("[set fullscreen post]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets());
-                    } }.start();
-                } else if(e.getKeyChar()=='d') {
-                    demo.setDemo0Only(!demo.getDemo0Only());
-                } else {
-                    int num = e.getKeyChar() - '0';
-                    System.err.println("*** "+num);
-                    if(0 <= num && num <= 8) {
-                        System.err.println("MSAA: "+demo.getMSAA()+" -> "+num);
-                        demo.setMSAA(num);                        
-                    }
-                }
-            }
-        });
-
-        animator.start();
+        animator0.start();
+        animator1.start();
         // glWindow.setSkipContextReleaseThread(animator.getThread());
 
         glWindow.setVisible(true);
@@ -183,36 +231,35 @@ public class TestFBOMix2DemosES2NEWT extends UITestCase {
         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, showFPS ? System.err : null);
+        animator0.setUpdateFPSFrames(30, showFPS ? System.err : null);
+        animator1.setUpdateFPSFrames(60, showFPS ? System.err : null);
         
-        while(!quitAdapter.shouldQuit() && animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
+        while(!quitAdapter.shouldQuit() && animator1.isAnimating() && animator1.getTotalFPSDuration()<duration) {
             Thread.sleep(100);
         }
 
-        animator.stop();
-        Assert.assertFalse(animator.isAnimating());
-        Assert.assertFalse(animator.isStarted());
+        animator0.stop();
+        Assert.assertFalse(animator0.isAnimating());
+        Assert.assertFalse(animator0.isStarted());
+        
+        animator1.stop();
+        Assert.assertFalse(animator1.isAnimating());
+        Assert.assertFalse(animator1.isStarted());
+        
+        fbod1.destroy();
+        fbod2.destroy();
+        
         glWindow.destroy();
         Assert.assertEquals(true,  AWTRobotUtil.waitForRealized(glWindow, false));
     }
 
     @Test
-    public void test01_Main() throws InterruptedException {
-        if( mainRun ) {
-            GLCapabilities caps = new GLCapabilities(forceES2 ? GLProfile.get(GLProfile.GLES2) : GLProfile.getGL2ES2());
-            caps.setAlphaBits(1);
-            runTestGL(caps, globalNumSamples);            
-        }
-    }
-    
-    @Test
     public void test01() throws InterruptedException {
-        if( mainRun ) return ;
         GLCapabilities caps = new GLCapabilities(forceES2 ? GLProfile.get(GLProfile.GLES2) : GLProfile.getGL2ES2());
         caps.setAlphaBits(1);
-        runTestGL(caps, 0);
+        runTestGL(caps);            
     }
-
+    
     public static void main(String args[]) throws IOException {        
         boolean waitForKey = false;
         
@@ -229,13 +276,6 @@ public class TestFBOMix2DemosES2NEWT extends UITestCase {
                 forceES2 = true;
             } else if(args[i].equals("-showFPS")) {
                 showFPS = true;
-            } else if(args[i].equals("-samples")) {
-                i++;
-                globalNumSamples = MiscUtils.atoi(args[i], globalNumSamples);
-            } else if(args[i].equals("-norotate")) {
-                doRotate = false;
-            } else if(args[i].equals("-demo0Only")) {
-                demo0Only = true;
             } else if(args[i].equals("-wait")) {
                 waitForKey = true;
             } else if(args[i].equals("-nomain")) {
@@ -253,6 +293,6 @@ public class TestFBOMix2DemosES2NEWT extends UITestCase {
                 System.err.println(stdin.readLine());
             } catch (IOException e) { }
         }
-        org.junit.runner.JUnitCore.main(TestFBOMix2DemosES2NEWT.class.getName());
+        org.junit.runner.JUnitCore.main(TestFBOOffThreadSharedContextMix2DemosES2NEWT.class.getName());
     }
 }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMix2DemosES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOOnThreadSharedContext1DemoES2NEWT.java
similarity index 60%
copy from src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMix2DemosES2NEWT.java
copy to src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOOnThreadSharedContext1DemoES2NEWT.java
index b384c93..7d9a9c6 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMix2DemosES2NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOOnThreadSharedContext1DemoES2NEWT.java
@@ -32,8 +32,6 @@ import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
 
-import com.jogamp.newt.event.KeyAdapter;
-import com.jogamp.newt.event.KeyEvent;
 import com.jogamp.newt.event.WindowEvent;
 import com.jogamp.newt.event.WindowAdapter;
 import com.jogamp.newt.opengl.GLWindow;
@@ -45,56 +43,120 @@ import com.jogamp.opengl.test.junit.util.QuitAdapter;
 import com.jogamp.opengl.util.Animator;
 import com.jogamp.opengl.util.GLReadBufferUtil;
 import com.jogamp.opengl.util.texture.TextureIO;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.Mix2TexturesES2;
 
-import com.jogamp.opengl.test.junit.jogl.demos.es2.FBOMix2DemosES2;
-
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.SurfaceUpdatedListener;
+import javax.media.opengl.GL;
 import javax.media.opengl.GLAutoDrawable;
 import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawableFactory;
 import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLOffscreenAutoDrawable;
 import javax.media.opengl.GLProfile;
 
 import org.junit.Assert;
 import org.junit.AfterClass;
 import org.junit.Test;
 
-public class TestFBOMix2DemosES2NEWT extends UITestCase {    
+/**
+ * Toolkit agnostic {@link GLOffscreenAutoDrawable.FBO} tests using the 
+ * {@link GLDrawableFactory#createOffscreenAutoDrawable(javax.media.nativewindow.AbstractGraphicsDevice, GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesChooser, int, int, GLContext) factory model}. 
+ * <p>
+ * The created {@link GLOffscreenAutoDrawable.FBO} is being used to run the {@link GLEventListener}.  
+ * </p>
+ * <p>
+ * This test simulates shared on-thread GL context / texture usage,
+ * where the producer uses an FBO and delivers a shared texture.
+ * The receiver draws the shared texture onscreen.
+ * In detail the test consist of:
+ * <ul>
+ *   <li>1 {@link GLOffscreenAutoDrawable.FBO} double buffered
+ *   <ul>
+ *     <liwith its own {@link GLContext}, which is shares the {@link GLWindow} one (see below)</li> 
+ *     <li>running within common {@link Animator} @ 60fps</li>
+ *     <li>produce a texture</li>
+ *     <li>notify the onscreen renderer about new textureID (swapping double buffer)</li>
+ *   </ul></li>
+ *   <li>1 onscreen {@link GLWindow}
+ *   <ul>
+ *     <li>shares it's {@link GLContext} w/ above FBO</li>
+ *     <li>running within common {@link Animator} @ 60fps</li>
+ *     <li>uses the shared FBO texture and draws it onscreen</li>
+ *   </ul></li>  
+ * </ul> 
+ * </p> 
+ */
+public class TestFBOOnThreadSharedContext1DemoES2NEWT extends UITestCase {    
     static long duration = 500; // ms
     static int swapInterval = 1;
     static boolean showFPS = false;
     static boolean forceES2 = false;
-    static boolean doRotate = true;
-    static boolean demo0Only = false;
-    static int globalNumSamples = 0;
     static boolean mainRun = false;
-    
+        
     @AfterClass
     public static void releaseClass() {
     }
 
-    protected void runTestGL(GLCapabilitiesImmutable caps, int numSamples) throws InterruptedException {
-        final GLReadBufferUtil screenshot = new GLReadBufferUtil(true, false);
+    protected void runTestGL(GLCapabilitiesImmutable caps) throws InterruptedException {
+        final GLReadBufferUtil screenshot = new GLReadBufferUtil(false, false);
         System.err.println("requested: vsync "+swapInterval+", "+caps);
+        
         final GLWindow glWindow = GLWindow.create(caps);
         Assert.assertNotNull(glWindow);
         glWindow.setTitle("Gears NEWT Test (translucent "+!caps.isBackgroundOpaque()+"), swapInterval "+swapInterval);
         if(mainRun) {
             glWindow.setSize(512, 512);            
         } else {
-            glWindow.setSize(128, 128);
+            glWindow.setSize(256, 256);
         }
+        // eager initialization of context
+        glWindow.setVisible(true);
+        glWindow.display(); 
+
+        final int fbod1_texUnit = 0;
+        
+        final GLDrawableFactory factory = GLDrawableFactory.getFactory(caps.getGLProfile());
+        GLCapabilities fbodCaps = (GLCapabilities) caps.cloneMutable();
+        // fbodCaps.setDoubleBuffered(false);
+        
+        final Mix2TexturesES2 mixerDemo = new Mix2TexturesES2(1, fbod1_texUnit, 0);
 
-        final FBOMix2DemosES2 demo = new FBOMix2DemosES2(swapInterval);
-        demo.setMSAA(numSamples);
-        demo.setDoRotation(doRotate);
-        demo.setDemo0Only(demo0Only);
-        glWindow.addGLEventListener(demo);
+        // FBOD1 
+        final GLOffscreenAutoDrawable.FBO fbod1 = (GLOffscreenAutoDrawable.FBO)
+                factory.createOffscreenAutoDrawable(null, fbodCaps, null, glWindow.getWidth(), glWindow.getHeight(), glWindow.getContext());
+        fbod1.setUpstreamWidget(glWindow); // connect the real GLWindow (mouse/key) to offscreen!
+        fbod1.setTextureUnit(fbod1_texUnit);
+        {
+            GearsES2 demo0 = new GearsES2(-1);
+            fbod1.addGLEventListener(demo0);
+            demo0.setIgnoreFocus(true);
+        }
+        fbod1.getNativeSurface().addSurfaceUpdatedListener(new SurfaceUpdatedListener() {
+            @Override
+            public void surfaceUpdated(Object updater, NativeSurface ns, long when) {
+                mixerDemo.setTexID0(fbod1.getTextureBuffer(GL.GL_FRONT).getName());
+            } });
+        fbod1.display(); // init
+        System.err.println("FBOD1 "+fbod1);
+        Assert.assertTrue(fbod1.isInitialized());
+        
+        // preinit texIDs
+        mixerDemo.setTexID0(fbod1.getTextureBuffer(GL.GL_FRONT).getName());
+        
+        glWindow.addWindowListener(new WindowAdapter() {
+            @Override
+            public void windowResized(WindowEvent e) {
+                fbod1.setSize(glWindow.getWidth(), glWindow.getHeight());
+            }
+        });
+        glWindow.addGLEventListener(mixerDemo);
         glWindow.addGLEventListener(new GLEventListener() {
             int i=0, c=0;
-            int origS;
-            public void init(GLAutoDrawable drawable) {
-                origS = demo.getMSAA();
-            }
+            public void init(GLAutoDrawable drawable) {}
             public void dispose(GLAutoDrawable drawable) {}
             public void display(GLAutoDrawable drawable) {
                 if(mainRun) return;
@@ -105,36 +167,26 @@ public class TestFBOMix2DemosES2NEWT extends UITestCase {
                 
                 if(dw<800) {
                     System.err.println("XXX: "+dw+"x"+dh+", c "+c);
-                    if(0 == c%3) {
-                        snapshot(getSimpleTestName("."), i++, "msaa"+demo.getMSAA(), drawable.getGL(), screenshot, TextureIO.PNG, null);                        
+                    if(8 == c) {
+                        snapshot(i++, "msaa"+fbod1.getNumSamples(), drawable.getGL(), screenshot, TextureIO.PNG, null);                        
                     }
-                    if( 3 == c ) {
-                        new Thread() { 
-                            @Override
-                            public void run() {
-                                demo.setMSAA(4);
-                            } }.start();
-                    } else if( 6 == c ) {
-                        new Thread() { 
-                            @Override
-                            public void run() {
-                                demo.setMSAA(8);
-                            } }.start();
-                    } else if(9 == c) {
+                    if(9 == c) {
                         c=0;
                         new Thread() { 
                             @Override
                             public void run() {
                                 glWindow.setSize(dw+256, dh+256);
-                                demo.setMSAA(origS);
                             } }.start();                            
                     }
                 }
             }
-            public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
+            public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { } 
         });
         
-        Animator animator = new Animator(glWindow);
+        final Animator animator1 = new Animator();
+        animator1.add(fbod1);
+        animator1.add(glWindow);
+        
         QuitAdapter quitAdapter = new QuitAdapter();
 
         //glWindow.addKeyListener(new TraceKeyAdapter(quitAdapter));
@@ -151,30 +203,7 @@ public class TestFBOMix2DemosES2NEWT extends UITestCase {
             }            
         });
         
-        glWindow.addKeyListener(new KeyAdapter() {
-            public void keyTyped(KeyEvent e) {
-                System.err.println("*** "+e);
-                if(e.getKeyChar()=='f') {
-                    new Thread() {
-                        public void run() {
-                            System.err.println("[set fullscreen  pre]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets());
-                            glWindow.setFullscreen(!glWindow.isFullscreen());
-                            System.err.println("[set fullscreen post]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets());
-                    } }.start();
-                } else if(e.getKeyChar()=='d') {
-                    demo.setDemo0Only(!demo.getDemo0Only());
-                } else {
-                    int num = e.getKeyChar() - '0';
-                    System.err.println("*** "+num);
-                    if(0 <= num && num <= 8) {
-                        System.err.println("MSAA: "+demo.getMSAA()+" -> "+num);
-                        demo.setMSAA(num);                        
-                    }
-                }
-            }
-        });
-
-        animator.start();
+        animator1.start();
         // glWindow.setSkipContextReleaseThread(animator.getThread());
 
         glWindow.setVisible(true);
@@ -183,36 +212,29 @@ public class TestFBOMix2DemosES2NEWT extends UITestCase {
         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, showFPS ? System.err : null);
+        animator1.setUpdateFPSFrames(60, showFPS ? System.err : null);
         
-        while(!quitAdapter.shouldQuit() && animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
+        while(!quitAdapter.shouldQuit() && animator1.isAnimating() && animator1.getTotalFPSDuration()<duration) {
             Thread.sleep(100);
         }
 
-        animator.stop();
-        Assert.assertFalse(animator.isAnimating());
-        Assert.assertFalse(animator.isStarted());
+        animator1.stop();
+        Assert.assertFalse(animator1.isAnimating());
+        Assert.assertFalse(animator1.isStarted());
+        
+        fbod1.destroy();
+        
         glWindow.destroy();
         Assert.assertEquals(true,  AWTRobotUtil.waitForRealized(glWindow, false));
     }
 
     @Test
-    public void test01_Main() throws InterruptedException {
-        if( mainRun ) {
-            GLCapabilities caps = new GLCapabilities(forceES2 ? GLProfile.get(GLProfile.GLES2) : GLProfile.getGL2ES2());
-            caps.setAlphaBits(1);
-            runTestGL(caps, globalNumSamples);            
-        }
-    }
-    
-    @Test
     public void test01() throws InterruptedException {
-        if( mainRun ) return ;
         GLCapabilities caps = new GLCapabilities(forceES2 ? GLProfile.get(GLProfile.GLES2) : GLProfile.getGL2ES2());
         caps.setAlphaBits(1);
-        runTestGL(caps, 0);
+        runTestGL(caps);            
     }
-
+    
     public static void main(String args[]) throws IOException {        
         boolean waitForKey = false;
         
@@ -229,13 +251,6 @@ public class TestFBOMix2DemosES2NEWT extends UITestCase {
                 forceES2 = true;
             } else if(args[i].equals("-showFPS")) {
                 showFPS = true;
-            } else if(args[i].equals("-samples")) {
-                i++;
-                globalNumSamples = MiscUtils.atoi(args[i], globalNumSamples);
-            } else if(args[i].equals("-norotate")) {
-                doRotate = false;
-            } else if(args[i].equals("-demo0Only")) {
-                demo0Only = true;
             } else if(args[i].equals("-wait")) {
                 waitForKey = true;
             } else if(args[i].equals("-nomain")) {
@@ -253,6 +268,6 @@ public class TestFBOMix2DemosES2NEWT extends UITestCase {
                 System.err.println(stdin.readLine());
             } catch (IOException e) { }
         }
-        org.junit.runner.JUnitCore.main(TestFBOMix2DemosES2NEWT.class.getName());
+        org.junit.runner.JUnitCore.main(TestFBOOnThreadSharedContext1DemoES2NEWT.class.getName());
     }
 }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateNEWT.java
deleted file mode 100644
index 96d9b2e..0000000
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateNEWT.java
+++ /dev/null
@@ -1,152 +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.test.junit.jogl.acore;
-
-import java.io.IOException;
-
-import javax.media.opengl.GLAutoDrawable;
-import javax.media.opengl.GLAutoDrawableDelegate;
-import javax.media.opengl.GLCapabilities;
-import javax.media.opengl.GLContext;
-import javax.media.opengl.GLDrawable;
-import javax.media.opengl.GLDrawableFactory;
-import javax.media.opengl.GLException;
-import javax.media.opengl.GLProfile;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-import com.jogamp.newt.NewtFactory;
-import com.jogamp.newt.Window;
-import com.jogamp.newt.event.WindowAdapter;
-import com.jogamp.newt.event.WindowEvent;
-import com.jogamp.newt.event.WindowListener;
-import com.jogamp.newt.event.WindowUpdateEvent;
-import com.jogamp.opengl.util.Animator;
-
-import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
-import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
-import com.jogamp.opengl.test.junit.util.QuitAdapter;
-import com.jogamp.opengl.test.junit.util.UITestCase;
-
-/**
- * Demonstrates a full featured custom GLAutoDrawable implementation
- * utilizing {@link GLAutoDrawableDelegate}. 
- */
-public class TestGLAutoDrawableDelegateNEWT extends UITestCase {
-
-    /** Note: Creates a full featured GLAutoDrawable w/ all window events connected. */
-    private GLAutoDrawable createGLAutoDrawable(GLCapabilities caps, int x, int y, int width, int height, WindowListener wl) throws InterruptedException {
-        final Window window = NewtFactory.createWindow(caps);
-        Assert.assertNotNull(window);
-        window.setPosition(x, y);
-        window.setSize(width, height);
-        window.setVisible(true);
-        Assert.assertTrue(AWTRobotUtil.waitForVisible(window, true));
-        Assert.assertTrue(AWTRobotUtil.waitForRealized(window, true));
-            
-        GLDrawableFactory factory = GLDrawableFactory.getFactory(caps.getGLProfile());
-        GLDrawable drawable = factory.createGLDrawable(window);
-        Assert.assertNotNull(drawable);
-        
-        drawable.setRealized(true);
-        Assert.assertTrue(drawable.isRealized());
-        
-        GLContext context = drawable.createContext(null);
-        Assert.assertNotNull(context);
-        
-        int res = context.makeCurrent();
-        Assert.assertTrue(GLContext.CONTEXT_CURRENT_NEW==res || GLContext.CONTEXT_CURRENT==res);
-        context.release();
-        
-        final GLAutoDrawableDelegate glad = new GLAutoDrawableDelegate(drawable, context, window, false) {
-            @Override
-            protected void destroyImplInLock() {
-                super.destroyImplInLock();  // destroys drawable/context
-                window.destroy(); // destroys the actual window
-            }            
-        };
-        
-        // add basic window interaction
-        window.addWindowListener(new WindowAdapter() {
-            @Override
-            public void windowRepaint(WindowUpdateEvent e) {
-                glad.windowRepaintOp();
-            }
-            @Override
-            public void windowResized(WindowEvent e) {
-                glad.windowResizedOp();
-            }
-            @Override
-            public void windowDestroyNotify(WindowEvent e) {
-                glad.windowDestroyNotifyOp();
-            }
-        });
-        window.addWindowListener(wl);
-        
-        return glad;
-    }
-    
-    @Test
-    public void test01() throws GLException, InterruptedException {
-        final QuitAdapter quitAdapter = new QuitAdapter();
-        GLAutoDrawable glad = createGLAutoDrawable(new GLCapabilities(GLProfile.getGL2ES2()), 0, 0, 640, 480, quitAdapter);        
-        glad.addGLEventListener(new GearsES2(1));
-
-        final Animator animator = new Animator(glad);
-        animator.setUpdateFPSFrames(60, null);
-        animator.start();
-        
-        while(!quitAdapter.shouldQuit() && animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
-            Thread.sleep(100);
-        }
-
-        animator.stop();
-        
-        glad.destroy();
-    }
-
-    static long duration = 2000; // ms
-
-    public static void main(String args[]) throws IOException {
-        for(int i=0; i<args.length; i++) {
-            if(args[i].equals("-time")) {
-                i++;
-                try {
-                    duration = Integer.parseInt(args[i]);
-                } catch (Exception ex) { ex.printStackTrace(); }
-            }
-        }
-        /**
-        BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
-        System.err.println("Press enter to continue");
-        System.err.println(stdin.readLine()); */         
-        org.junit.runner.JUnitCore.main(TestGLAutoDrawableDelegateNEWT.class.getName());
-    }
-}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateOnOffscrnCapsNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateOnOffscrnCapsNEWT.java
new file mode 100644
index 0000000..d9e9b2b
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateOnOffscrnCapsNEWT.java
@@ -0,0 +1,385 @@
+/**
+ * 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.acore;
+
+import java.io.IOException;
+
+import javax.media.nativewindow.CapabilitiesImmutable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLProfile;
+
+import jogamp.opengl.GLGraphicsConfigurationUtil;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.jogamp.newt.NewtFactory;
+import com.jogamp.newt.Window;
+import com.jogamp.newt.event.WindowAdapter;
+import com.jogamp.newt.event.WindowEvent;
+import com.jogamp.newt.event.WindowUpdateEvent;
+import com.jogamp.opengl.GLAutoDrawableDelegate;
+import com.jogamp.opengl.JoglVersion;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+import com.jogamp.opengl.test.junit.jogl.demos.gl2.Gears;
+import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+
+/**
+ * Tests using a NEWT {@link Window} for on- and offscreen cases.
+ * <p>
+ * Each test creates a {@link GLDrawable} using the 
+ * {@link GLDrawableFactory#createGLDrawable(javax.media.nativewindow.NativeSurface) factory model}.
+ * The {@link GLContext} is derived {@link GLDrawable#createContext(GLContext) from the drawable}.
+ * </p>
+ * <p>
+ * Finally a {@link GLAutoDrawableDelegate} is created with the just created {@link GLDrawable} and {@link GLContext}.
+ * It is being used to run the {@link GLEventListener}.  
+ * </p> 
+ */
+public class TestGLAutoDrawableDelegateOnOffscrnCapsNEWT extends UITestCase {
+    static final int widthStep = 800/4;
+    static final int heightStep = 600/4;
+    volatile int szStep = 2;
+
+    static GLCapabilities getCaps(String profile) {
+        if( !GLProfile.isAvailable(profile) )  {
+            System.err.println("Profile "+profile+" n/a");
+            return null;
+        }
+        return new GLCapabilities(GLProfile.get(profile));
+    }
+    
+    void doTest(GLCapabilitiesImmutable reqGLCaps, GLEventListener demo) throws InterruptedException {
+        System.out.println("Requested  GL Caps: "+reqGLCaps);
+        final GLDrawableFactory factory = GLDrawableFactory.getFactory(reqGLCaps.getGLProfile());
+        final GLCapabilitiesImmutable expGLCaps = GLGraphicsConfigurationUtil.fixGLCapabilities(reqGLCaps, factory, null);
+        System.out.println("Expected   GL Caps: "+expGLCaps);
+        //
+        // Create native windowing resources .. X11/Win/OSX
+        // 
+        final Window window = NewtFactory.createWindow(reqGLCaps);
+        Assert.assertNotNull(window);
+        window.setSize(widthStep*szStep, heightStep*szStep);
+        window.setVisible(true);
+        Assert.assertTrue(AWTRobotUtil.waitForVisible(window, true));
+        Assert.assertTrue(AWTRobotUtil.waitForRealized(window, true));
+        System.out.println("Window: "+window.getClass().getName());
+        
+        // Check caps of NativeWindow config w/o GL
+        final CapabilitiesImmutable chosenCaps = window.getGraphicsConfiguration().getChosenCapabilities();
+        System.out.println("Window Caps Pre_GL: "+chosenCaps);
+        Assert.assertNotNull(chosenCaps);
+        Assert.assertTrue(chosenCaps.getGreenBits()>5);
+        Assert.assertTrue(chosenCaps.getBlueBits()>5);
+        Assert.assertTrue(chosenCaps.getRedBits()>5);
+
+        //
+        // Create native OpenGL resources .. XGL/WGL/CGL .. 
+        // equivalent to GLAutoDrawable methods: setVisible(true)
+        //         
+        final GLDrawable drawable = factory.createGLDrawable(window);
+        Assert.assertNotNull(drawable);
+        System.out.println("Drawable    Pre-GL(0): "+drawable.getClass().getName()+", "+drawable.getNativeSurface().getClass().getName());
+        
+        //
+        drawable.setRealized(true);
+        Assert.assertTrue(drawable.isRealized());
+
+        System.out.println("Window Caps PostGL   : "+window.getGraphicsConfiguration().getChosenCapabilities());
+        System.out.println("Drawable   Post-GL(1): "+drawable.getClass().getName()+", "+drawable.getNativeSurface().getClass().getName());
+
+        // Note: FBO Drawable realization happens at 1st context.makeCurrent(), 
+        //       and hence only then it's caps can _fully_ reflect expectations,
+        //       i.e. depth, stencil and MSAA will be valid only after makeCurrent(),
+        //       where on-/offscreen state after setRealized(true)
+        //       See GLFBODrawable API doc in this regard!
+        
+        
+        final GLCapabilitiesImmutable chosenGLCaps01 = drawable.getChosenGLCapabilities();
+        System.out.println("Chosen     GL Caps(1): "+chosenGLCaps01);
+        Assert.assertNotNull(chosenGLCaps01);
+        Assert.assertEquals(expGLCaps.isOnscreen(), chosenGLCaps01.isOnscreen());
+        Assert.assertEquals(expGLCaps.isFBO(), chosenGLCaps01.isFBO());
+        Assert.assertEquals(expGLCaps.isPBuffer(), chosenGLCaps01.isPBuffer());
+        Assert.assertEquals(expGLCaps.isBitmap(), chosenGLCaps01.isBitmap());
+        
+        final GLContext context = drawable.createContext(null);
+        Assert.assertNotNull(context);
+        int res = context.makeCurrent();
+        Assert.assertTrue(GLContext.CONTEXT_CURRENT_NEW==res || GLContext.CONTEXT_CURRENT==res);
+        context.release();
+        
+        // Check caps of GLDrawable after realization
+        final GLCapabilitiesImmutable chosenGLCaps02 = drawable.getChosenGLCapabilities();
+        System.out.println("Chosen     GL Caps(2): "+chosenGLCaps02);
+        System.out.println("Chosen     GL CTX (2): "+context.getGLVersion());
+        System.out.println("Drawable   Post-GL(2): "+drawable.getClass().getName()+", "+drawable.getNativeSurface().getClass().getName());
+        Assert.assertNotNull(chosenGLCaps02);
+        Assert.assertTrue(chosenGLCaps02.getGreenBits()>5);
+        Assert.assertTrue(chosenGLCaps02.getBlueBits()>5);
+        Assert.assertTrue(chosenGLCaps02.getRedBits()>5);
+        Assert.assertTrue(chosenGLCaps02.getDepthBits()>4);
+        Assert.assertEquals(expGLCaps.isOnscreen(), chosenGLCaps02.isOnscreen());
+        Assert.assertEquals(expGLCaps.isFBO(), chosenGLCaps02.isFBO());
+        Assert.assertEquals(expGLCaps.isPBuffer(), chosenGLCaps02.isPBuffer());
+        Assert.assertEquals(expGLCaps.isBitmap(), chosenGLCaps02.isBitmap());
+        /** Single/Double buffer cannot be checked since result may vary .. 
+        if(chosenGLCaps.isOnscreen() || chosenGLCaps.isFBO()) {
+            // dbl buffer may be disabled w/ offscreen pbuffer and bitmap
+            Assert.assertEquals(expGLCaps.getDoubleBuffered(), chosenGLCaps.getDoubleBuffered());
+        } */
+        
+        final GLAutoDrawableDelegate glad = new GLAutoDrawableDelegate(drawable, context, window, false, null) {
+                @Override
+                protected void destroyImplInLock() {
+                    super.destroyImplInLock();  // destroys drawable/context
+                    window.destroy(); // destroys the actual window, incl. the device
+                }
+            };
+        
+        window.addWindowListener(new WindowAdapter() {
+                @Override
+                public void windowRepaint(WindowUpdateEvent e) {
+                    glad.windowRepaintOp();
+                }
+
+                @Override
+                public void windowResized(WindowEvent e) {
+                    glad.windowResizedOp(window.getWidth(), window.getHeight());
+                }
+
+                @Override
+                public void windowDestroyNotify(WindowEvent e) {
+                    glad.windowDestroyNotifyOp();
+                }
+            });
+
+        glad.addGLEventListener(demo);
+        
+        final SnapshotGLEventListener snapshotGLEventListener = new SnapshotGLEventListener();
+        glad.addGLEventListener(snapshotGLEventListener);
+        
+        glad.display(); // initial resize/display
+        
+        // 1 - szStep = 2
+        Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(), 
+                          AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep));
+        snapshotGLEventListener.setMakeSnapshot();
+        glad.display();
+        
+        // 2, 3 (resize + display)
+        szStep = 1;
+        window.setSize(widthStep*szStep, heightStep*szStep);
+        Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(), 
+                          AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep));
+        snapshotGLEventListener.setMakeSnapshot();
+        glad.display();
+                
+        // 4, 5 (resize + display)
+        szStep = 4;
+        window.setSize(widthStep*szStep, heightStep*szStep);
+        Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(), 
+                          AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep));
+        snapshotGLEventListener.setMakeSnapshot();
+        glad.display();
+        
+        Thread.sleep(50);
+        
+        glad.destroy();
+        System.out.println("Fin Drawable: "+drawable);        
+        System.out.println("Fin Window: "+window);
+    }
+
+    @Test
+    public void testAvailableInfo() {
+        GLDrawableFactory f = GLDrawableFactory.getDesktopFactory();
+        if(null != f) {
+            System.err.println(JoglVersion.getDefaultOpenGLInfo(f.getDefaultDevice(), null, true).toString());
+        }
+        f = GLDrawableFactory.getEGLFactory();
+        if(null != f) {
+            System.err.println(JoglVersion.getDefaultOpenGLInfo(f.getDefaultDevice(), null, true).toString());
+        }
+    }
+    
+    @Test
+    public void testGL2OnScreenDblBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+        if(null == reqGLCaps) return;
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+    
+    @Test
+    public void testGL2OnScreenSglBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setDoubleBuffered(false);
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+  
+    @Test
+    public void testGL2OffScreenAutoDblBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+
+    @Test
+    public void testGL2OffScreenFBODblBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        reqGLCaps.setFBO(true);
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+    
+    @Test
+    public void testGL2OffScreenFBOSglBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        reqGLCaps.setFBO(true);
+        reqGLCaps.setDoubleBuffered(false);
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+    
+    @Test
+    public void testGL2OffScreenPbufferDblBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        reqGLCaps.setPBuffer(true);
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+    
+    @Test
+    public void testGL2OffScreenPbufferSglBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        reqGLCaps.setPBuffer(true);
+        reqGLCaps.setDoubleBuffered(false);
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+    
+    @Test
+    public void testGL2OffScreenBitmapSglBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        reqGLCaps.setBitmap(true);
+        reqGLCaps.setDoubleBuffered(false);
+        doTest(reqGLCaps, new Gears(1));
+    }
+    
+    @Test
+    public void testES2OnScreenDblBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+        if(null == reqGLCaps) return;
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+    
+    @Test
+    public void testES2OnScreenSglBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setDoubleBuffered(false);
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+    
+    @Test
+    public void testES2OffScreenAutoDblBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+
+    @Test
+    public void testES2OffScreenFBODblBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        reqGLCaps.setFBO(true);
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+    
+    @Test
+    public void testES2OffScreenFBOSglBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        reqGLCaps.setFBO(true);
+        reqGLCaps.setDoubleBuffered(false);
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+    
+    @Test
+    public void testES2OffScreenPbufferDblBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        reqGLCaps.setPBuffer(true);
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+    
+    @Test
+    public void testES2OffScreenPbufferSglBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        reqGLCaps.setPBuffer(true);
+        reqGLCaps.setDoubleBuffered(false);
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+    
+    /** Not implemented !
+    @Test
+    public void testES2OffScreenBitmapDblBuf() throws InterruptedException {
+        if(!checkProfile(GLProfile.GLES2)) {
+            return;
+        }
+        final GLCapabilities reqGLCaps = new GLCapabilities(GLProfile.get(GLProfile.GLES2));        
+        reqGLCaps.setOnscreen(false);
+        reqGLCaps.setBitmap(true);
+        doTest(reqGLCaps, new GearsES2(1));
+    } */
+    
+    public static void main(String args[]) throws IOException {
+        org.junit.runner.JUnitCore.main(TestGLAutoDrawableDelegateOnOffscrnCapsNEWT.class.getName());
+    }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableFactoryOffscrnCapsNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableFactoryOffscrnCapsNEWT.java
new file mode 100644
index 0000000..51f9cc4
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableFactoryOffscrnCapsNEWT.java
@@ -0,0 +1,306 @@
+/**
+ * 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.acore;
+
+import java.io.IOException;
+
+import javax.media.nativewindow.CapabilitiesImmutable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLOffscreenAutoDrawable;
+import javax.media.opengl.GLProfile;
+
+import jogamp.opengl.GLGraphicsConfigurationUtil;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.jogamp.opengl.JoglVersion;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+import com.jogamp.opengl.test.junit.jogl.demos.gl2.Gears;
+import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+
+/**
+ * Toolkit agnostic {@link GLOffscreenAutoDrawable} tests using the 
+ * {@link GLDrawableFactory#createOffscreenAutoDrawable(javax.media.nativewindow.AbstractGraphicsDevice, GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesChooser, int, int, GLContext) factory model}. 
+ * <p>
+ * The created {@link GLOffscreenAutoDrawable} is being used to run the {@link GLEventListener}.  
+ * </p> 
+ */
+public class TestGLAutoDrawableFactoryOffscrnCapsNEWT extends UITestCase {
+    static final int widthStep = 800/4;
+    static final int heightStep = 600/4;
+    volatile int szStep = 2;
+
+    static GLCapabilities getCaps(String profile) {
+        if( !GLProfile.isAvailable(profile) )  {
+            System.err.println("Profile "+profile+" n/a");
+            return null;
+        }
+        return new GLCapabilities(GLProfile.get(profile));
+    }
+    
+    void doTest(GLCapabilitiesImmutable reqGLCaps, GLEventListener demo) throws InterruptedException {
+        System.out.println("Requested  GL Caps: "+reqGLCaps);
+        final GLDrawableFactory factory = GLDrawableFactory.getFactory(reqGLCaps.getGLProfile());
+        final GLCapabilitiesImmutable expGLCaps = GLGraphicsConfigurationUtil.fixGLCapabilities(reqGLCaps, factory, null);
+        System.out.println("Expected   GL Caps: "+expGLCaps);
+
+        //
+        // Create native OpenGL resources .. XGL/WGL/CGL .. 
+        // equivalent to GLAutoDrawable methods: setVisible(true)
+        //
+        final GLOffscreenAutoDrawable glad = factory.createOffscreenAutoDrawable(null, reqGLCaps, null, widthStep*szStep, heightStep*szStep, null);
+        
+        Assert.assertNotNull(glad);
+        System.out.println("Drawable    Pre-GL(0): "+glad.getClass().getName()+", "+glad.getNativeSurface().getClass().getName());        
+        Assert.assertTrue(glad.isRealized());
+        
+        // Check caps of NativeWindow config w/o GL
+        final CapabilitiesImmutable chosenCaps = glad.getChosenGLCapabilities();
+        System.out.println("Drawable Caps Pre_GL : "+chosenCaps);
+        Assert.assertNotNull(chosenCaps);
+        Assert.assertTrue(chosenCaps.getGreenBits()>5);
+        Assert.assertTrue(chosenCaps.getBlueBits()>5);
+        Assert.assertTrue(chosenCaps.getRedBits()>5);
+        
+        glad.display(); // force native context creation
+
+        // Check caps of GLDrawable after realization
+        final GLCapabilitiesImmutable chosenGLCaps = glad.getChosenGLCapabilities();
+        System.out.println("Chosen     GL CTX (1): "+glad.getContext().getGLVersion());
+        System.out.println("Chosen     GL Caps(1): "+chosenGLCaps);
+        System.out.println("Chosen     GL Caps(2): "+glad.getNativeSurface().getGraphicsConfiguration().getChosenCapabilities());
+
+        Assert.assertNotNull(chosenGLCaps);
+        Assert.assertTrue(chosenGLCaps.getGreenBits()>5);
+        Assert.assertTrue(chosenGLCaps.getBlueBits()>5);
+        Assert.assertTrue(chosenGLCaps.getRedBits()>5);
+        Assert.assertTrue(chosenGLCaps.getDepthBits()>4);
+        Assert.assertEquals(expGLCaps.isOnscreen(), chosenGLCaps.isOnscreen());
+        Assert.assertEquals(expGLCaps.isFBO(), chosenGLCaps.isFBO());
+        Assert.assertEquals(expGLCaps.isPBuffer(), chosenGLCaps.isPBuffer());
+        Assert.assertEquals(expGLCaps.isBitmap(), chosenGLCaps.isBitmap());
+        /** Single/Double buffer cannot be checked since result may vary .. 
+        if(chosenGLCaps.isOnscreen() || chosenGLCaps.isFBO()) {
+            // dbl buffer may be disabled w/ offscreen pbuffer and bitmap
+            Assert.assertEquals(expGLCaps.getDoubleBuffered(), chosenGLCaps.getDoubleBuffered());
+        } */        
+
+        glad.addGLEventListener(demo);
+        
+        final SnapshotGLEventListener snapshotGLEventListener = new SnapshotGLEventListener();
+        glad.addGLEventListener(snapshotGLEventListener);
+        
+        glad.display(); // initial resize/display
+        
+        // 1 - szStep = 2
+        Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(), 
+                          AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep));
+        snapshotGLEventListener.setMakeSnapshot();
+        glad.display();
+        
+        // 2, 3 (resize + display)
+        szStep = 1;
+        glad.setSize(widthStep*szStep, heightStep*szStep);
+        Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(), 
+                          AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep));
+        snapshotGLEventListener.setMakeSnapshot();
+        glad.display();
+                
+        // 4, 5 (resize + display)
+        szStep = 4;
+        glad.setSize(widthStep*szStep, heightStep*szStep);
+        Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(), 
+                          AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep));
+        snapshotGLEventListener.setMakeSnapshot();
+        glad.display();
+        
+        Thread.sleep(50);
+        
+        glad.destroy();
+        System.out.println("Fin Drawable: "+glad);        
+    }
+
+    @Test
+    public void testAvailableInfo() {
+        GLDrawableFactory f = GLDrawableFactory.getDesktopFactory();
+        if(null != f) {
+            System.err.println(JoglVersion.getDefaultOpenGLInfo(f.getDefaultDevice(), null, true).toString());
+        }
+        f = GLDrawableFactory.getEGLFactory();
+        if(null != f) {
+            System.err.println(JoglVersion.getDefaultOpenGLInfo(f.getDefaultDevice(), null, true).toString());
+        }
+    }    
+    
+    @Test
+    public void testGL2OffScreenAutoDblBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+
+    @Test
+    public void testGL2OffScreenFBODblBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        reqGLCaps.setFBO(true);
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+    
+    @Test
+    public void testGL2OffScreenFBOSglBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        reqGLCaps.setFBO(true);
+        reqGLCaps.setDoubleBuffered(false);
+        doTest(reqGLCaps, new GearsES2(1));
+    }    
+    
+    @Test
+    public void testGL2OffScreenFBOStencil() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        reqGLCaps.setFBO(true);
+        reqGLCaps.setStencilBits(1);
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+    
+    @Test
+    public void testGL2OffScreenFBOStencilMSAA() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        reqGLCaps.setFBO(true);
+        reqGLCaps.setStencilBits(1);
+        reqGLCaps.setSampleBuffers(true);
+        doTest(reqGLCaps, new GearsES2(1));
+    }    
+        
+    @Test
+    public void testGL2OffScreenPbufferDblBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        reqGLCaps.setPBuffer(true);
+        doTest(reqGLCaps, new GearsES2(1));
+    }    
+    
+    @Test
+    public void testGL2OffScreenPbufferSglBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        reqGLCaps.setPBuffer(true);
+        reqGLCaps.setDoubleBuffered(false);
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+    
+    @Test
+    public void testGL2OffScreenBitmapSglBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        reqGLCaps.setBitmap(true);
+        reqGLCaps.setDoubleBuffered(false);
+        doTest(reqGLCaps, new Gears(1));
+    }
+    
+    @Test
+    public void testES2OffScreenAutoDblBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+
+    @Test
+    public void testES2OffScreenFBODblBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        reqGLCaps.setFBO(true);
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+    
+    @Test
+    public void testES2OffScreenFBOSglBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        reqGLCaps.setFBO(true);
+        reqGLCaps.setDoubleBuffered(false);
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+    
+    @Test
+    public void testES2OffScreenPbufferDblBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        reqGLCaps.setPBuffer(true);
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+    
+    @Test
+    public void testES2OffScreenPbufferSglBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        reqGLCaps.setPBuffer(true);
+        reqGLCaps.setDoubleBuffered(false);
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+    
+    /** Not implemented !
+    @Test
+    public void testES2OffScreenBitmapDblBuf() throws InterruptedException {
+        if(!checkProfile(GLProfile.GLES2)) {
+            return;
+        }
+        final GLCapabilities reqGLCaps = new GLCapabilities(GLProfile.get(GLProfile.GLES2));        
+        reqGLCaps.setOnscreen(false);
+        reqGLCaps.setBitmap(true);
+        doTest(reqGLCaps, new GearsES2(1));
+    } */
+    
+    public static void main(String args[]) throws IOException {
+        org.junit.runner.JUnitCore.main(TestGLAutoDrawableFactoryOffscrnCapsNEWT.class.getName());
+    }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableGLCanvasOnOffscrnCapsAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableGLCanvasOnOffscrnCapsAWT.java
new file mode 100644
index 0000000..a2ffa90
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableGLCanvasOnOffscrnCapsAWT.java
@@ -0,0 +1,324 @@
+/**
+ * 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.acore;
+
+import java.awt.Dimension;
+import java.awt.Frame;
+import java.io.IOException;
+
+import javax.media.nativewindow.CapabilitiesImmutable;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLProfile;
+import javax.media.opengl.awt.GLCanvas;
+
+import jogamp.nativewindow.jawt.JAWTUtil;
+import jogamp.opengl.GLGraphicsConfigurationUtil;
+
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Test;
+
+import com.jogamp.opengl.JoglVersion;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+
+/**
+ * Tests using an AWT {@link GLCanvas} {@link GLAutoDrawable auto drawable} for on- and offscreen cases.
+ * <p>
+ * The NEWT  {@link GLAutoDrawable} is being used to run the {@link GLEventListener}.  
+ * </p> 
+ */
+public class TestGLAutoDrawableGLCanvasOnOffscrnCapsAWT extends UITestCase {
+    static final int widthStep = 800/4;
+    static final int heightStep = 600/4;
+    volatile int szStep = 2;
+
+    static GLCapabilities getCaps(String profile) {
+        if( !GLProfile.isAvailable(profile) )  {
+            System.err.println("Profile "+profile+" n/a");
+            return null;
+        }
+        return new GLCapabilities(GLProfile.get(profile));
+    }
+    
+    static void setGLCanvasSize(final Frame frame, final GLCanvas glc, final int width, final int height) {
+        try {
+            javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+                public void run() {
+                    final Dimension new_sz = new Dimension(width, height);
+                    glc.setMinimumSize(new_sz);
+                    glc.setPreferredSize(new_sz);
+                    glc.setSize(new_sz);
+                    frame.pack();
+                    frame.validate();
+                } } );
+        } catch( Throwable throwable ) {
+            throwable.printStackTrace();
+            Assume.assumeNoException( throwable );
+        }       
+    }
+    
+    static interface MyGLEventListener extends GLEventListener {
+        void setMakeSnapshot();
+    }
+    
+    void doTest(GLCapabilitiesImmutable reqGLCaps, GLEventListener demo) throws InterruptedException {
+        if(reqGLCaps.isOnscreen() && JAWTUtil.isOffscreenLayerRequired()) {
+            System.err.println("onscreen layer n/a");
+            return;
+        }
+        if(!reqGLCaps.isOnscreen() && !JAWTUtil.isOffscreenLayerSupported()) {
+            System.err.println("offscreen layer n/a");
+            return;
+        }
+        System.out.println("Requested  GL Caps: "+reqGLCaps);
+        final GLDrawableFactory factory = GLDrawableFactory.getFactory(reqGLCaps.getGLProfile());
+        final GLCapabilitiesImmutable expGLCaps = GLGraphicsConfigurationUtil.fixGLCapabilities(reqGLCaps, factory, null);
+        System.out.println("Expected   GL Caps: "+expGLCaps);
+        //
+        // Create native windowing resources .. X11/Win/OSX
+        //
+        final GLCanvas glad = new GLCanvas(reqGLCaps); // will implicit trigger offscreen layer - if !onscreen && supported
+        Assert.assertNotNull(glad);
+        Dimension glc_sz = new Dimension(widthStep*szStep, heightStep*szStep);
+        glad.setMinimumSize(glc_sz);
+        glad.setPreferredSize(glc_sz);
+        glad.setSize(glc_sz);
+        final Frame frame = new Frame(getSimpleTestName("."));
+        Assert.assertNotNull(frame);
+        frame.add(glad);        
+        
+        try {
+            javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+                public void run() {
+                    frame.pack();
+                    frame.setVisible(true);
+                }});
+        } catch( Throwable throwable ) {
+            throwable.printStackTrace();
+            Assume.assumeNoException( throwable );
+        }
+        
+        Assert.assertTrue(AWTRobotUtil.waitForVisible(glad, true));
+        Assert.assertTrue(AWTRobotUtil.waitForRealized(glad, true));
+        System.out.println("Window: "+glad.getClass().getName());
+        
+        // Check caps of NativeWindow config w/o GL
+        final CapabilitiesImmutable chosenCaps = glad.getChosenGLCapabilities();
+        System.out.println("Window Caps Pre_GL: "+chosenCaps);
+        Assert.assertNotNull(chosenCaps);
+        Assert.assertTrue(chosenCaps.getGreenBits()>5);
+        Assert.assertTrue(chosenCaps.getBlueBits()>5);
+        Assert.assertTrue(chosenCaps.getRedBits()>5);
+
+        glad.display(); // force native context creation
+        
+        //
+        // Create native OpenGL resources .. XGL/WGL/CGL .. 
+        // equivalent to GLAutoDrawable methods: setVisible(true)
+        //         
+        {
+            final GLDrawable actualDrawable = glad.getDelegatedDrawable();
+            Assert.assertNotNull(actualDrawable);
+            System.out.println("Drawable    Pre-GL(0): "+actualDrawable.getClass().getName()+", "+actualDrawable.getNativeSurface().getClass().getName());
+        }
+        
+        System.out.println("Window Caps PostGL   : "+glad.getChosenGLCapabilities());
+        System.out.println("Drawable   Post-GL(1): "+glad.getClass().getName()+", "+glad.getNativeSurface().getClass().getName());
+        
+        // Check caps of GLDrawable after realization
+        final GLCapabilitiesImmutable chosenGLCaps = glad.getChosenGLCapabilities();
+        System.out.println("Chosen     GL Caps(1): "+chosenGLCaps);
+        Assert.assertNotNull(chosenGLCaps);
+        Assert.assertTrue(chosenGLCaps.getGreenBits()>5);
+        Assert.assertTrue(chosenGLCaps.getBlueBits()>5);
+        Assert.assertTrue(chosenGLCaps.getRedBits()>5);
+        Assert.assertTrue(chosenGLCaps.getDepthBits()>4);
+        Assert.assertEquals(expGLCaps.isOnscreen(), chosenGLCaps.isOnscreen());
+        Assert.assertEquals(expGLCaps.isFBO(), chosenGLCaps.isFBO());
+        Assert.assertEquals(expGLCaps.isPBuffer(), chosenGLCaps.isPBuffer());
+        Assert.assertEquals(expGLCaps.isBitmap(), chosenGLCaps.isBitmap());
+        /** Single/Double buffer cannot be checked since result may vary .. 
+        if(chosenGLCaps.isOnscreen() || chosenGLCaps.isFBO()) {
+            // dbl buffer may be disabled w/ offscreen pbuffer and bitmap
+            Assert.assertEquals(expGLCaps.getDoubleBuffered(), chosenGLCaps.getDoubleBuffered());
+        } */
+
+        {
+            GLContext context = glad.getContext();
+            System.out.println("Chosen     GL CTX (2): "+context.getGLVersion());
+            Assert.assertNotNull(context);
+            Assert.assertTrue(context.isCreated());
+        }
+        
+        System.out.println("Chosen     GL Caps(2): "+glad.getChosenGLCapabilities());
+        System.out.println("Drawable   Post-GL(2): "+glad.getClass().getName()+", "+glad.getNativeSurface().getClass().getName());
+        
+        glad.addGLEventListener(demo);
+        
+        final SnapshotGLEventListener snapshotGLEventListener = new SnapshotGLEventListener();
+        glad.addGLEventListener(snapshotGLEventListener);
+        
+        glad.display(); // initial resize/display
+        
+        // 1 - szStep = 2
+        Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(), 
+                          AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep));
+        snapshotGLEventListener.setMakeSnapshot();
+        glad.display();
+        
+        // 2, 3 (resize + display)
+        szStep = 1;
+        setGLCanvasSize(frame, glad, widthStep*szStep, heightStep*szStep);
+        Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(), 
+                          AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep));
+        glad.display();
+        snapshotGLEventListener.setMakeSnapshot();
+        glad.display();
+                
+        // 4, 5 (resize + display)
+        szStep = 4;
+        setGLCanvasSize(frame, glad, widthStep*szStep, heightStep*szStep);
+        Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(), 
+                          AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep));
+        glad.display();
+        snapshotGLEventListener.setMakeSnapshot();
+        glad.display();
+        
+        Thread.sleep(50);
+        
+        try {
+            javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+                public void run() {
+                    frame.setVisible(false);
+                    frame.remove(glad);
+                    frame.dispose();
+                }});
+        } catch( Throwable throwable ) {
+            throwable.printStackTrace();
+            Assume.assumeNoException( throwable );
+        }        
+        System.out.println("Fin: "+glad);
+    }
+
+    @Test
+    public void testAvailableInfo() {
+        GLDrawableFactory f = GLDrawableFactory.getDesktopFactory();
+        if(null != f) {
+            System.err.println(JoglVersion.getDefaultOpenGLInfo(f.getDefaultDevice(), null, true).toString());
+        }
+        f = GLDrawableFactory.getEGLFactory();
+        if(null != f) {
+            System.err.println(JoglVersion.getDefaultOpenGLInfo(f.getDefaultDevice(), null, true).toString());
+        }
+    }
+    
+    @Test
+    public void testGL2OnScreen() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+        if(null == reqGLCaps) return;
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+    
+    @Test
+    public void testGL2OffScreenAuto() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+
+    @Test
+    public void testGL2OffScreenFBOMSAA() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        reqGLCaps.setFBO(true);
+        reqGLCaps.setSampleBuffers(true);
+        reqGLCaps.setNumSamples(4);
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+    
+    @Test
+    public void testGL2OffScreenPbuffer() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        reqGLCaps.setPBuffer(true);
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+    
+    @Test
+    public void testES2OnScreen() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+        if(null == reqGLCaps) return;
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+    
+    @Test
+    public void testES2OffScreenAuto() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+    
+    @Test
+    public void testES2OffScreenFBOMSAA() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        reqGLCaps.setFBO(true);
+        reqGLCaps.setSampleBuffers(true);
+        reqGLCaps.setNumSamples(4);
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+    
+    @Test
+    public void testES2OffScreenPbuffer() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        reqGLCaps.setPBuffer(true);
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+    
+    
+    public static void main(String args[]) throws IOException {
+        org.junit.runner.JUnitCore.main(TestGLAutoDrawableGLCanvasOnOffscrnCapsAWT.class.getName());
+    }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableGLWindowOnOffscrnCapsNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableGLWindowOnOffscrnCapsNEWT.java
new file mode 100644
index 0000000..da54567
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableGLWindowOnOffscrnCapsNEWT.java
@@ -0,0 +1,339 @@
+/**
+ * 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.acore;
+
+import java.io.IOException;
+
+import javax.media.nativewindow.CapabilitiesImmutable;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLProfile;
+
+import jogamp.opengl.GLGraphicsConfigurationUtil;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.JoglVersion;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+import com.jogamp.opengl.test.junit.jogl.demos.gl2.Gears;
+import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+
+/**
+ * Tests using a NEWT {@link GLWindow} {@link GLAutoDrawable auto drawable} for on- and offscreen cases.
+ * <p>
+ * The NEWT  {@link GLAutoDrawable} is being used to run the {@link GLEventListener}.  
+ * </p> 
+ */
+public class TestGLAutoDrawableGLWindowOnOffscrnCapsNEWT extends UITestCase {
+    static final int widthStep = 800/4;
+    static final int heightStep = 600/4;
+    volatile int szStep = 2;
+
+    static interface MyGLEventListener extends GLEventListener {
+        void setMakeSnapshot();
+    }
+    
+    static GLCapabilities getCaps(String profile) {
+        if( !GLProfile.isAvailable(profile) )  {
+            System.err.println("Profile "+profile+" n/a");
+            return null;
+        }
+        return new GLCapabilities(GLProfile.get(profile));
+    }
+    
+    void doTest(GLCapabilitiesImmutable reqGLCaps, GLEventListener demo) throws InterruptedException {
+        System.out.println("Requested  GL Caps: "+reqGLCaps);
+        final GLDrawableFactory factory = GLDrawableFactory.getFactory(reqGLCaps.getGLProfile());
+        final GLCapabilitiesImmutable expGLCaps = GLGraphicsConfigurationUtil.fixGLCapabilities(reqGLCaps, factory, null);
+        System.out.println("Expected   GL Caps: "+expGLCaps);
+        //
+        // Create native windowing resources .. X11/Win/OSX
+        // 
+        final GLWindow glad = GLWindow.create(reqGLCaps);
+        Assert.assertNotNull(glad);
+        glad.setSize(widthStep*szStep, heightStep*szStep);
+        glad.setVisible(true);
+        Assert.assertTrue(AWTRobotUtil.waitForVisible(glad, true));
+        Assert.assertTrue(AWTRobotUtil.waitForRealized(glad, true));
+        System.out.println("Window: "+glad.getClass().getName());
+        
+        // Check caps of NativeWindow config w/o GL
+        final CapabilitiesImmutable chosenCaps = glad.getGraphicsConfiguration().getChosenCapabilities();
+        System.out.println("Window Caps Pre_GL: "+chosenCaps);
+        Assert.assertNotNull(chosenCaps);
+        Assert.assertTrue(chosenCaps.getGreenBits()>5);
+        Assert.assertTrue(chosenCaps.getBlueBits()>5);
+        Assert.assertTrue(chosenCaps.getRedBits()>5);
+
+        //
+        // Create native OpenGL resources .. XGL/WGL/CGL .. 
+        // equivalent to GLAutoDrawable methods: setVisible(true)
+        //         
+        {
+            final GLDrawable actualDrawable = glad.getDelegatedDrawable();
+            Assert.assertNotNull(actualDrawable);
+            System.out.println("Drawable    Pre-GL(0): "+actualDrawable.getClass().getName()+", "+actualDrawable.getNativeSurface().getClass().getName());
+        }
+        
+        System.out.println("Window Caps PostGL   : "+glad.getGraphicsConfiguration().getChosenCapabilities());
+        System.out.println("Drawable   Post-GL(1): "+glad.getClass().getName()+", "+glad.getNativeSurface().getClass().getName());
+        
+        // Check caps of GLDrawable after realization
+        final GLCapabilitiesImmutable chosenGLCaps = glad.getChosenGLCapabilities();
+        System.out.println("Chosen     GL Caps(1): "+chosenGLCaps);
+        Assert.assertNotNull(chosenGLCaps);
+        Assert.assertTrue(chosenGLCaps.getGreenBits()>5);
+        Assert.assertTrue(chosenGLCaps.getBlueBits()>5);
+        Assert.assertTrue(chosenGLCaps.getRedBits()>5);
+        Assert.assertTrue(chosenGLCaps.getDepthBits()>4);
+        Assert.assertEquals(expGLCaps.isOnscreen(), chosenGLCaps.isOnscreen());
+        Assert.assertEquals(expGLCaps.isFBO(), chosenGLCaps.isFBO());
+        Assert.assertEquals(expGLCaps.isPBuffer(), chosenGLCaps.isPBuffer());
+        Assert.assertEquals(expGLCaps.isBitmap(), chosenGLCaps.isBitmap());
+        /** Single/Double buffer cannot be checked since result may vary .. 
+        if(chosenGLCaps.isOnscreen() || chosenGLCaps.isFBO()) {
+            // dbl buffer may be disabled w/ offscreen pbuffer and bitmap
+            Assert.assertEquals(expGLCaps.getDoubleBuffered(), chosenGLCaps.getDoubleBuffered());
+        } */
+
+        glad.display();
+        {
+            GLContext context = glad.getContext();
+            System.out.println("Chosen     GL CTX (2): "+context.getGLVersion());
+            Assert.assertNotNull(context);
+            Assert.assertTrue(context.isCreated());
+        }
+        
+        System.out.println("Chosen     GL Caps(2): "+glad.getChosenGLCapabilities());
+        System.out.println("Drawable   Post-GL(2): "+glad.getClass().getName()+", "+glad.getNativeSurface().getClass().getName());
+        
+        glad.addGLEventListener(demo);
+        
+        final SnapshotGLEventListener snapshotGLEventListener = new SnapshotGLEventListener();
+        glad.addGLEventListener(snapshotGLEventListener);
+        
+        glad.display(); // initial resize/display
+        
+        // 1 - szStep = 2
+        Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(), 
+                          AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep));
+        snapshotGLEventListener.setMakeSnapshot();
+        glad.display();
+        
+        // 2, 3 (resize + display)
+        szStep = 1;
+        glad.setSize(widthStep*szStep, heightStep*szStep);
+        Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(), 
+                          AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep));
+        snapshotGLEventListener.setMakeSnapshot();
+        glad.display();
+                
+        // 4, 5 (resize + display)
+        szStep = 4;
+        glad.setSize(widthStep*szStep, heightStep*szStep);
+        Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(), 
+                          AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep));
+        snapshotGLEventListener.setMakeSnapshot();
+        glad.display();
+        
+        Thread.sleep(50);
+        
+        glad.destroy();
+        System.out.println("Fin: "+glad);
+    }
+
+    @Test
+    public void testAvailableInfo() {
+        GLDrawableFactory f = GLDrawableFactory.getDesktopFactory();
+        if(null != f) {
+            System.err.println(JoglVersion.getDefaultOpenGLInfo(f.getDefaultDevice(), null, true).toString());
+        }
+        f = GLDrawableFactory.getEGLFactory();
+        if(null != f) {
+            System.err.println(JoglVersion.getDefaultOpenGLInfo(f.getDefaultDevice(), null, true).toString());
+        }
+    }
+    
+    @Test
+    public void testGL2OnScreenDblBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+        if(null == reqGLCaps) return;
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+    
+    @Test
+    public void testGL2OnScreenSglBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setDoubleBuffered(false);
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+    
+    @Test
+    public void testGL2OffScreenAutoDblBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+
+    @Test
+    public void testGL2OffScreenFBODblBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        reqGLCaps.setFBO(true);
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+    
+    @Test
+    public void testGL2OffScreenFBOSglBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        reqGLCaps.setFBO(true);
+        reqGLCaps.setDoubleBuffered(false);
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+    
+    @Test
+    public void testGL2OffScreenPbufferDblBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        reqGLCaps.setPBuffer(true);
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+    
+    @Test
+    public void testGL2OffScreenPbufferSglBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        reqGLCaps.setPBuffer(true);
+        reqGLCaps.setDoubleBuffered(false);
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+    
+    @Test
+    public void testGL2OffScreenBitmapSglBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        reqGLCaps.setBitmap(true);
+        reqGLCaps.setDoubleBuffered(false);
+        doTest(reqGLCaps, new Gears(1));
+    }
+    
+    @Test
+    public void testES2OnScreenDblBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+        if(null == reqGLCaps) return;
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+    
+    @Test
+    public void testES2OnScreenSglBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setDoubleBuffered(false);
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+    
+    @Test
+    public void testES2OffScreenAutoDblBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+
+    @Test
+    public void testES2OffScreenFBODblBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        reqGLCaps.setFBO(true);
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+    
+    @Test
+    public void testES2OffScreenFBOSglBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        reqGLCaps.setFBO(true);
+        reqGLCaps.setDoubleBuffered(false);
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+    
+    @Test
+    public void testES2OffScreenPbufferDblBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        reqGLCaps.setPBuffer(true);
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+    
+    @Test
+    public void testES2OffScreenPbufferSglBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setOnscreen(false);
+        reqGLCaps.setPBuffer(true);
+        reqGLCaps.setDoubleBuffered(false);
+        doTest(reqGLCaps, new GearsES2(1));
+    }
+    
+    /** Not implemented !
+    @Test
+    public void testES2OffScreenBitmapDblBuf() throws InterruptedException {
+        if(!checkProfile(GLProfile.GLES2)) {
+            return;
+        }
+        final GLCapabilities reqGLCaps = new GLCapabilities(GLProfile.get(GLProfile.GLES2));        
+        reqGLCaps.setOnscreen(false);
+        reqGLCaps.setBitmap(true);
+        doTest(reqGLCaps, new GearsES2(1));
+    } */
+    
+    public static void main(String args[]) throws IOException {
+        org.junit.runner.JUnitCore.main(TestGLAutoDrawableGLWindowOnOffscrnCapsNEWT.class.getName());
+    }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableNewtCanvasAWTOnOffscrnCapsAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableNewtCanvasAWTOnOffscrnCapsAWT.java
new file mode 100644
index 0000000..37483f7
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableNewtCanvasAWTOnOffscrnCapsAWT.java
@@ -0,0 +1,299 @@
+/**
+ * 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.acore;
+
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Frame;
+import java.io.IOException;
+
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.CapabilitiesImmutable;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLProfile;
+
+import jogamp.nativewindow.jawt.JAWTUtil;
+import jogamp.opengl.GLGraphicsConfigurationUtil;
+
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Test;
+
+import com.jogamp.newt.awt.NewtCanvasAWT;
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.JoglVersion;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+
+/**
+ * Tests using a NEWT {@link GLWindow} {@link GLAutoDrawable auto drawable} for on- and offscreen cases.
+ * <p>
+ * The NEWT  {@link GLAutoDrawable} is being used to run the {@link GLEventListener}.  
+ * </p> 
+ */
+public class TestGLAutoDrawableNewtCanvasAWTOnOffscrnCapsAWT extends UITestCase {
+    static final int widthStep = 800/4;
+    static final int heightStep = 600/4;
+    volatile int szStep = 2;
+
+    static GLCapabilities getCaps(String profile) {
+        if( !GLProfile.isAvailable(profile) )  {
+            System.err.println("Profile "+profile+" n/a");
+            return null;
+        }
+        return new GLCapabilities(GLProfile.get(profile));
+    }
+    
+    static void setComponentSize(final Frame frame, final Component comp, final int width, final int height) {
+        try {
+            javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+                public void run() {
+                    final Dimension new_sz = new Dimension(width, height);
+                    comp.setMinimumSize(new_sz);
+                    comp.setPreferredSize(new_sz);
+                    comp.setSize(new_sz);
+                    frame.pack();
+                    frame.validate();
+                } } );
+        } catch( Throwable throwable ) {
+            throwable.printStackTrace();
+            Assume.assumeNoException( throwable );
+        }       
+    }
+    
+    static interface MyGLEventListener extends GLEventListener {
+        void setMakeSnapshot();
+    }
+    
+    void doTest(boolean offscreenLayer, GLCapabilitiesImmutable reqGLCaps, GLEventListener demo) throws InterruptedException {
+        if(!offscreenLayer && JAWTUtil.isOffscreenLayerRequired()) {
+            System.err.println("onscreen layer n/a");
+            return;
+        }
+        if(offscreenLayer && !JAWTUtil.isOffscreenLayerSupported()) {
+            System.err.println("offscreen layer n/a");
+            return;
+        }
+        System.out.println("Requested  GL Caps: "+reqGLCaps);
+        final GLDrawableFactory factory = GLDrawableFactory.getFactory(reqGLCaps.getGLProfile());
+        final AbstractGraphicsDevice device = factory.getDefaultDevice();        
+        final GLCapabilitiesImmutable expGLCaps = offscreenLayer ?
+                            GLGraphicsConfigurationUtil.fixOffscreenGLCapabilities(reqGLCaps, factory, device) :
+                            GLGraphicsConfigurationUtil.fixGLCapabilities(reqGLCaps, factory, device);
+        System.out.println("Expected   GL Caps: "+expGLCaps);
+        
+        final GLWindow glad = GLWindow.create(reqGLCaps);
+        Assert.assertNotNull(glad);
+
+        
+        final NewtCanvasAWT nca = new NewtCanvasAWT(glad);
+        Assert.assertNotNull(nca);
+        Dimension size0 = new Dimension(widthStep*szStep, heightStep*szStep);
+        nca.setShallUseOffscreenLayer(offscreenLayer); // trigger offscreen layer - if supported
+        nca.setPreferredSize(size0);
+        nca.setMinimumSize(size0);
+        nca.setSize(size0);
+        
+        final Frame frame = new Frame(getSimpleTestName("."));
+        Assert.assertNotNull(frame);
+        frame.add(nca);        
+        
+        try {
+            javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+                public void run() {
+                    frame.pack();
+                    frame.setVisible(true);
+                }});
+        } catch( Throwable throwable ) {
+            throwable.printStackTrace();
+            Assume.assumeNoException( throwable );
+        }
+        
+        Assert.assertTrue(AWTRobotUtil.waitForVisible(glad, true));
+        Assert.assertTrue(AWTRobotUtil.waitForRealized(glad, true));
+        System.out.println("Window: "+glad.getClass().getName());
+        
+        // Check caps of NativeWindow config w/o GL
+        final CapabilitiesImmutable chosenCaps = glad.getChosenGLCapabilities();
+        System.out.println("Window Caps Pre_GL: "+chosenCaps);
+        Assert.assertNotNull(chosenCaps);
+        Assert.assertTrue(chosenCaps.getGreenBits()>5);
+        Assert.assertTrue(chosenCaps.getBlueBits()>5);
+        Assert.assertTrue(chosenCaps.getRedBits()>5);
+
+        glad.display(); // force native context creation
+        
+        //
+        // Create native OpenGL resources .. XGL/WGL/CGL .. 
+        // equivalent to GLAutoDrawable methods: setVisible(true)
+        //         
+        {
+            final GLDrawable actualDrawable = glad.getDelegatedDrawable();
+            Assert.assertNotNull(actualDrawable);
+            System.out.println("Drawable    Pre-GL(0): "+actualDrawable.getClass().getName()+", "+actualDrawable.getNativeSurface().getClass().getName());
+        }
+        
+        System.out.println("Window Caps PostGL   : "+glad.getChosenGLCapabilities());
+        System.out.println("Drawable   Post-GL(1): "+glad.getClass().getName()+", "+glad.getNativeSurface().getClass().getName());
+        
+        // Check caps of GLDrawable after realization
+        final GLCapabilitiesImmutable chosenGLCaps = glad.getChosenGLCapabilities();
+        System.out.println("Chosen     GL Caps(1): "+chosenGLCaps);
+        Assert.assertNotNull(chosenGLCaps);
+        Assert.assertTrue(chosenGLCaps.getGreenBits()>5);
+        Assert.assertTrue(chosenGLCaps.getBlueBits()>5);
+        Assert.assertTrue(chosenGLCaps.getRedBits()>5);
+        Assert.assertTrue(chosenGLCaps.getDepthBits()>4);
+        Assert.assertEquals(expGLCaps.isOnscreen(), chosenGLCaps.isOnscreen());
+        Assert.assertEquals(expGLCaps.isFBO(), chosenGLCaps.isFBO());
+        Assert.assertEquals(expGLCaps.isPBuffer(), chosenGLCaps.isPBuffer());
+        Assert.assertEquals(expGLCaps.isBitmap(), chosenGLCaps.isBitmap());
+        /** Single/Double buffer cannot be checked since result may vary .. 
+        if(chosenGLCaps.isOnscreen() || chosenGLCaps.isFBO()) {
+            // dbl buffer may be disabled w/ offscreen pbuffer and bitmap
+            Assert.assertEquals(expGLCaps.getDoubleBuffered(), chosenGLCaps.getDoubleBuffered());
+        } */
+
+        {
+            GLContext context = glad.getContext();
+            System.out.println("Chosen     GL CTX (2): "+context.getGLVersion());
+            Assert.assertNotNull(context);
+            Assert.assertTrue(context.isCreated());
+        }
+        
+        System.out.println("Chosen     GL Caps(2): "+glad.getChosenGLCapabilities());
+        System.out.println("Drawable   Post-GL(2): "+glad.getClass().getName()+", "+glad.getNativeSurface().getClass().getName());
+        
+        glad.addGLEventListener(demo);
+        
+        final SnapshotGLEventListener snapshotGLEventListener = new SnapshotGLEventListener();
+        glad.addGLEventListener(snapshotGLEventListener);
+        
+        glad.display(); // initial resize/display
+        
+        // 1 - szStep = 2
+        Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(), 
+                          AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep));
+        snapshotGLEventListener.setMakeSnapshot();
+        glad.display();
+        
+        // 2, 3 (resize + display)
+        szStep = 1;
+        setComponentSize(frame, nca, widthStep*szStep, heightStep*szStep);
+        Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(), 
+                          AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep));
+        glad.display();
+        snapshotGLEventListener.setMakeSnapshot();
+        glad.display();
+                
+        // 4, 5 (resize + display)
+        szStep = 4;
+        setComponentSize(frame, nca, widthStep*szStep, heightStep*szStep);
+        Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(), 
+                          AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep));
+        glad.display();
+        snapshotGLEventListener.setMakeSnapshot();
+        glad.display();
+        
+        Thread.sleep(50);
+        
+        try {
+            javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+                public void run() {
+                    frame.setVisible(false);
+                    frame.remove(nca);
+                    frame.dispose();
+                }});
+        } catch( Throwable throwable ) {
+            throwable.printStackTrace();
+            Assume.assumeNoException( throwable );
+        }        
+        glad.destroy();
+        System.out.println("Fin: "+nca);
+        System.out.println("Fin: "+glad);
+    }
+
+    @Test
+    public void testAvailableInfo() {
+        GLDrawableFactory f = GLDrawableFactory.getDesktopFactory();
+        if(null != f) {
+            System.err.println(JoglVersion.getDefaultOpenGLInfo(f.getDefaultDevice(), null, true).toString());
+        }
+        f = GLDrawableFactory.getEGLFactory();
+        if(null != f) {
+            System.err.println(JoglVersion.getDefaultOpenGLInfo(f.getDefaultDevice(), null, true).toString());
+        }
+    }
+    
+    @Test
+    public void testGL2OnScreenDblBuf() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+        if(null == reqGLCaps) return;
+        doTest(false, reqGLCaps, new GearsES2(1));
+    }
+    
+    @Test
+    public void testGL2OffScreenLayerAuto() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+        if(null == reqGLCaps) return;
+        doTest(true, reqGLCaps, new GearsES2(1));
+    }
+
+    @Test
+    public void testGL2OffScreenFBOMSAA() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setFBO(true);
+        reqGLCaps.setOnscreen(true); // get native NEWT Window, not OffscreenWindow
+        reqGLCaps.setSampleBuffers(true);
+        reqGLCaps.setNumSamples(4);
+        doTest(true, reqGLCaps, new GearsES2(1));
+    }
+    
+    @Test
+    public void testGL2OffScreenPbuffer() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+        if(null == reqGLCaps) return;
+        reqGLCaps.setPBuffer(true);
+        reqGLCaps.setOnscreen(true); // get native NEWT Window, not OffscreenWindow
+        doTest(true, reqGLCaps, new GearsES2(1));
+    }
+    
+    public static void main(String args[]) throws IOException {
+        org.junit.runner.JUnitCore.main(TestGLAutoDrawableNewtCanvasAWTOnOffscrnCapsAWT.class.getName());
+    }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextDrawableSwitchNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextDrawableSwitchNEWT.java
index cece4c6..496be3d 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextDrawableSwitchNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextDrawableSwitchNEWT.java
@@ -39,13 +39,14 @@ import com.jogamp.newt.event.WindowUpdateEvent;
 import com.jogamp.newt.opengl.GLWindow;
 
 import javax.media.opengl.GLAutoDrawable;
-import javax.media.opengl.GLAutoDrawableDelegate;
 import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLContext;
 import javax.media.opengl.GLDrawable;
 import javax.media.opengl.GLDrawableFactory;
 import javax.media.opengl.GLEventListener;
 import javax.media.opengl.GLProfile;
+
+import com.jogamp.opengl.GLAutoDrawableDelegate;
 import com.jogamp.opengl.util.Animator;
 
 import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
@@ -81,14 +82,17 @@ public class TestGLContextDrawableSwitchNEWT extends UITestCase {
         Assert.assertTrue(AWTRobotUtil.waitForVisible(window, true));
         Assert.assertTrue(AWTRobotUtil.waitForRealized(window, true));
             
-        GLDrawableFactory factory = GLDrawableFactory.getFactory(caps.getGLProfile());
-        GLDrawable drawable = factory.createGLDrawable(window);
+        final GLDrawableFactory factory = GLDrawableFactory.getFactory(caps.getGLProfile());
+        final GLDrawable drawable = factory.createGLDrawable(window);
         Assert.assertNotNull(drawable);
         
         drawable.setRealized(true);
         Assert.assertTrue(drawable.isRealized());
         
-        final GLAutoDrawableDelegate glad = new GLAutoDrawableDelegate(drawable, null, window, false) {
+        final GLContext context = drawable.createContext(null);
+        Assert.assertNotNull(context);
+        
+        final GLAutoDrawableDelegate glad = new GLAutoDrawableDelegate(drawable, context, window, false, null) {
             @Override
             protected void destroyImplInLock() {
                 super.destroyImplInLock();
@@ -104,7 +108,7 @@ public class TestGLContextDrawableSwitchNEWT extends UITestCase {
             }
             @Override
             public void windowResized(WindowEvent e) {
-                glad.windowResizedOp();
+                glad.windowResizedOp(window.getWidth(), window.getHeight());
             }
             @Override
             public void windowDestroyNotify(WindowEvent e) {
@@ -120,12 +124,16 @@ public class TestGLContextDrawableSwitchNEWT extends UITestCase {
     public void testSwitch2WindowSingleContext() throws InterruptedException {
         final QuitAdapter quitAdapter = new QuitAdapter();
         
-        GLAutoDrawable glad1 = createGLAutoDrawable(caps,         64, 64,     width,     height, quitAdapter); // no GLContext!
-        GLAutoDrawable glad2 = createGLAutoDrawable(caps, 2*64+width, 64, width+100, height+100, quitAdapter); // no GLContext!
+        GLAutoDrawable glad1 = createGLAutoDrawable(caps,         64, 64,     width,     height, quitAdapter);
+        GLAutoDrawable glad2 = createGLAutoDrawable(caps, 2*64+width, 64, width+100, height+100, quitAdapter);
         
-        // create single context using glad1 and assign it to glad1 
+        // create single context using glad1 and assign it to glad1,
+        // after destroying the prev. context!
         {
-            GLContext singleCtx = glad1.createContext(null);
+            final GLContext oldCtx = glad1.getContext();
+            Assert.assertNotNull(oldCtx);
+            oldCtx.destroy();
+            final GLContext singleCtx = glad1.createContext(null);
             Assert.assertNotNull(singleCtx);        
             int res = singleCtx.makeCurrent();
             Assert.assertTrue(GLContext.CONTEXT_CURRENT_NEW==res || GLContext.CONTEXT_CURRENT==res);
@@ -151,15 +159,22 @@ public class TestGLContextDrawableSwitchNEWT extends UITestCase {
                 System.err.println(s+" - switch - START "+ ( t1 - t0 ));
                 animator.pause();
 
+                // switch context _and_ the demo synchronously
                 if(0 == s%2) {
-                    glad1.addGLEventListener(0, glad2.removeGLEventListener(0));
+                    final GLEventListener demo = glad2.removeGLEventListener(0);
                     GLContext ctx1 = glad1.setContext(glad2.getContext());
                     glad2.setContext(ctx1);
+                    glad1.addGLEventListener(0, demo);
                 } else {
-                    glad2.addGLEventListener(0, glad1.removeGLEventListener(0));
+                    final GLEventListener demo = glad1.removeGLEventListener(0);
                     GLContext ctx2 = glad2.setContext(glad1.getContext());                    
                     glad1.setContext(ctx2);
+                    glad2.addGLEventListener(0, demo);
                 }
+                System.err.println(s+" - switch - display-1");
+                glad1.display();
+                System.err.println(s+" - switch - display-2");
+                glad2.display();
                 
                 System.err.println(s+" - switch - END "+ ( t1 - t0 ));
                 
@@ -210,13 +225,16 @@ public class TestGLContextDrawableSwitchNEWT extends UITestCase {
                 System.err.println(s+" - switch - START "+ ( t1 - t0 ));
                 animator.pause();
 
+                // switch context _and_ the demo synchronously
                 if(0 == s%2) {
-                    glWindow1.addGLEventListener(0, glWindow2.removeGLEventListener(0));
+                    final GLEventListener demo = glWindow2.removeGLEventListener(0);
                     GLContext ctx1 = glWindow1.setContext(glWindow2.getContext());
+                    glWindow1.addGLEventListener(0, demo);
                     glWindow2.setContext(ctx1);
                 } else {
-                    glWindow2.addGLEventListener(0, glWindow1.removeGLEventListener(0));
+                    final GLEventListener demo = glWindow1.removeGLEventListener(0);
                     GLContext ctx2 = glWindow2.setContext(glWindow1.getContext());                    
+                    glWindow2.addGLEventListener(0, demo);
                     glWindow1.setContext(ctx2);
                 }
                 
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLExtensionQueryOffscreen.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLExtensionQueryOffscreen.java
index e4245ef..d4f3fec 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLExtensionQueryOffscreen.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLExtensionQueryOffscreen.java
@@ -32,14 +32,11 @@ import java.util.Collections;
 import java.util.SortedSet;
 import java.util.TreeSet;
 
-import javax.media.nativewindow.AbstractGraphicsDevice;
-import javax.media.opengl.DefaultGLCapabilitiesChooser;
 import javax.media.opengl.GL;
-import javax.media.opengl.GLAutoDrawable;
 import javax.media.opengl.GLCapabilities;
-import javax.media.opengl.GLCapabilitiesChooser;
 import javax.media.opengl.GLContext;
 import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLOffscreenAutoDrawable;
 import javax.media.opengl.GLProfile;
 
 import jogamp.opengl.GLDrawableFactoryImpl;
@@ -77,13 +74,11 @@ public class TestGLExtensionQueryOffscreen {
     
     @Test
     public void testJogl2ExtensionCheck2() {
-        GLCapabilities caps = new GLCapabilities(GLProfile.getDefault());
-        GLDrawableFactory factory = GLDrawableFactory.getDesktopFactory();
-        GLCapabilitiesChooser glCapsChooser = new DefaultGLCapabilitiesChooser();
-        AbstractGraphicsDevice agd = factory.getDefaultDevice();
+        final GLCapabilities caps = new GLCapabilities(GLProfile.getDefault());
+        final GLDrawableFactory factory = GLDrawableFactory.getFactory(caps.getGLProfile());        
+        final GLOffscreenAutoDrawable drawable = factory.createOffscreenAutoDrawable(null, caps, null, 256, 256, null);
         
-        GLAutoDrawable drawable = factory.createGLPbuffer(agd, caps, glCapsChooser, 256, 256, null);
-        GLContext context = drawable.getContext();
+        final GLContext context = drawable.getContext();
         context.makeCurrent();
         String extensions;
         try {
@@ -94,8 +89,8 @@ public class TestGLExtensionQueryOffscreen {
         String[] tabExtensions = extensions.split(" ");
         SortedSet<String> setExtensions = new TreeSet<String>();
         Collections.addAll(setExtensions, tabExtensions);
-        System.out.println("DefaulContext: "+context);
-        System.out.println("DefaulContext: "+setExtensions);
+        System.out.println("DefaultContext: "+context);
+        System.out.println("DefaultContext: "+setExtensions);
     }
 }
 
diff --git a/src/newt/classes/com/jogamp/newt/event/WindowUpdateEvent.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLProfile00NEWT.java
similarity index 72%
copy from src/newt/classes/com/jogamp/newt/event/WindowUpdateEvent.java
copy to src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLProfile00NEWT.java
index 505939d..19402c9 100644
--- a/src/newt/classes/com/jogamp/newt/event/WindowUpdateEvent.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLProfile00NEWT.java
@@ -1,5 +1,5 @@
 /**
- * Copyright 2010 JogAmp Community. All rights reserved.
+ * 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:
@@ -26,24 +26,26 @@
  * or implied, of JogAmp Community.
  */
  
-package com.jogamp.newt.event;
+package com.jogamp.opengl.test.junit.jogl.acore;
 
-import javax.media.nativewindow.util.Rectangle;
+import java.io.IOException;
 
-public class WindowUpdateEvent extends WindowEvent {
-    final Rectangle bounds;
+import org.junit.Test;
 
-    public WindowUpdateEvent(int eventType, Object source, long when, Rectangle bounds)
-    {
-        super(eventType, source, when);
-        this.bounds = bounds;
-    }
+import javax.media.opengl.*;
+
+import com.jogamp.opengl.test.junit.util.UITestCase;
 
-    public Rectangle getBounds() {
-        return bounds;
+public class TestGLProfile00NEWT extends UITestCase {
+
+    @Test
+    public void testInitSingleton() throws InterruptedException {
+        GLProfile.initSingleton();
     }
 
-    public String toString() {
-        return "WindowUpdateEvent["+super.toString()+", "+bounds+"]";
+    public static void main(String args[]) throws IOException {
+        String tstname = TestGLProfile00NEWT.class.getName();
+        org.junit.runner.JUnitCore.main(tstname);
     }
+
 }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGPUMemSec01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGPUMemSec01NEWT.java
index bebe353..6080343 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGPUMemSec01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGPUMemSec01NEWT.java
@@ -61,6 +61,8 @@ public class TestGPUMemSec01NEWT extends UITestCase {
                 new GLCapabilities(glp), width, height, true);
         final GL gl = winctx.context.getGL();
 
+        // System.err.println("Pre GL Error: 0x"+Integer.toHexString(gl.glGetError()));
+        // System.err.println(winctx.drawable);
         Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
         
         // misc GL setup
@@ -249,7 +251,7 @@ public class TestGPUMemSec01NEWT extends UITestCase {
         
         NEWTGLContext.destroyWindow(winctx);
     }
-    
+
     @Test
     public void testReadPixelsGL_99x100xRGBxUB() throws InterruptedException {
         GLProfile glp = GLProfile.getGL2ES2();
diff --git a/src/test/com/jogamp/opengl/test/junit/util/MiscUtils.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestInitConcurrent01NEWT.java
similarity index 50%
copy from src/test/com/jogamp/opengl/test/junit/util/MiscUtils.java
copy to src/test/com/jogamp/opengl/test/junit/jogl/acore/TestInitConcurrent01NEWT.java
index 9cbeabb..719d1fc 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/MiscUtils.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestInitConcurrent01NEWT.java
@@ -26,47 +26,59 @@
  * or implied, of JogAmp Community.
  */
  
+package com.jogamp.opengl.test.junit.jogl.acore;
 
-package com.jogamp.opengl.test.junit.util;
+import java.io.IOException;
 
-import java.lang.reflect.*;
+import org.junit.Test;
 
-public class MiscUtils {
-    public static int atoi(String str, int def) {
-        try {
-            return Integer.parseInt(str);
-        } catch (Exception ex) {
-            ex.printStackTrace();
-        }
-        return def;
+import com.jogamp.common.os.Platform;
+
+/**
+ * Concurrent initialization and lock-free rendering using shared NEWT Display EDT instances.
+ * <p>
+ * Rendering is always lock-free and independent of the EDT, however shared NEWT Display instances
+ * perform lifecycle actions (window creation etc) with locking.
+ * </p>
+ */
+public class TestInitConcurrent01NEWT extends InitConcurrentBaseNEWT {
+    static boolean mainRun = false;
+
+    @Test
+    public void test02TwoThreads() throws InterruptedException {
+        runJOGLTasks(2, true);
+    }
+    
+    @Test
+    public void test02FourThreads() throws InterruptedException {
+        runJOGLTasks(4, true);
     }
     
-    public static long atol(String str, long def) {
-        try {
-            return Long.parseLong(str);
-        } catch (Exception ex) {
-            ex.printStackTrace();
+    @Test
+    public void test16SixteenThreads() throws InterruptedException {
+        if( !mainRun &&
+            Platform.getCPUFamily() != Platform.CPUFamily.ARM &&
+            Platform.getOSType() != Platform.OSType.WINDOWS ) {
+            runJOGLTasks(16, true);
+        } else {
+            runJOGLTasks( 6, true);
         }
-        return def;
     }
-
-    public static boolean setFieldIfExists(Object instance, String fieldName, Object value) {
-        try {
-            Field f = instance.getClass().getField(fieldName);
-            if(value instanceof Boolean || f.getType().isInstance(value)) {
-                f.set(instance, value);
-                return true;
-            } else {
-                System.out.println(instance.getClass()+" '"+fieldName+"' field not assignable with "+value.getClass()+", it's a: "+f.getType());
+    
+    public static void main(String args[]) throws IOException {
+        mainRun = true;        
+        for(int i=0; i<args.length; i++) {
+            if(args[i].equals("-normalRun")) {
+                mainRun = false;
+            } else if(args[i].equals("-time")) {
+                i++;
+                try {
+                    duration = Integer.parseInt(args[i]);
+                } catch (Exception ex) { ex.printStackTrace(); }
             }
-        } catch (IllegalAccessException ex) {
-            throw new RuntimeException(ex);
-        } catch (NoSuchFieldException nsfe) {
-            // OK - throw new RuntimeException(instance.getClass()+" has no '"+fieldName+"' field", nsfe);
         }
-        return false;
+        String tstname = TestInitConcurrent01NEWT.class.getName();
+        org.junit.runner.JUnitCore.main(tstname);
     }
-}
-
-
 
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestInitConcurrent02NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestInitConcurrent02NEWT.java
new file mode 100644
index 0000000..f2871a6
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestInitConcurrent02NEWT.java
@@ -0,0 +1,96 @@
+/**
+ * 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.acore;
+
+import java.io.IOException;
+
+import org.junit.Test;
+
+import com.jogamp.common.os.Platform;
+
+/**
+ * Concurrent and lock-free initialization and rendering using exclusive NEWT Display EDT instances.
+ * <p>
+ * Rendering is always lock-free and independent of the EDT, however exclusive NEWT Display instances
+ * perform lifecycle actions (window creation etc) w/o locking.
+ * </p>
+ */
+public class TestInitConcurrent02NEWT extends InitConcurrentBaseNEWT {
+    static boolean mainRun = false;
+    
+    @Test
+    public void test02TwoThreads() throws InterruptedException {
+        if(!mainRun) {
+            System.err.println("Disabled for auto unit test until further analysis - Windows/ATI driver crash");
+            return;
+        }
+        runJOGLTasks(2, false);
+    }
+    
+    @Test
+    public void test02FourThreads() throws InterruptedException {
+        if(!mainRun) {
+            System.err.println("Disabled for auto unit test until further analysis - Windows/ATI driver crash");
+            return;
+        }
+        runJOGLTasks(4, false);
+    }
+    
+    @Test
+    public void test16SixteenThreads() throws InterruptedException {
+        if(!mainRun) {
+            System.err.println("Disabled for auto unit test until further analysis - Windows/ATI driver crash");
+            return;
+        }
+        if( !mainRun &&
+            Platform.getCPUFamily() != Platform.CPUFamily.ARM &&
+            Platform.getOSType() != Platform.OSType.WINDOWS ) {
+            runJOGLTasks(16, false);
+        } else {
+            runJOGLTasks( 6, false);
+        }
+    }
+    
+    public static void main(String args[]) throws IOException {
+        mainRun = true;        
+        for(int i=0; i<args.length; i++) {
+            if(args[i].equals("-normalRun")) {
+                mainRun = false;
+            } else if(args[i].equals("-time")) {
+                i++;
+                try {
+                    duration = Integer.parseInt(args[i]);
+                } catch (Exception ex) { ex.printStackTrace(); }
+            }
+        }
+        String tstname = TestInitConcurrent02NEWT.class.getName();
+        org.junit.runner.JUnitCore.main(tstname);
+    }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestNEWTCloseX11DisplayBug565.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestNEWTCloseX11DisplayBug565.java
index 33a9b77..c1b7464 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestNEWTCloseX11DisplayBug565.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestNEWTCloseX11DisplayBug565.java
@@ -11,12 +11,14 @@ import javax.media.opengl.DefaultGLCapabilitiesChooser;
 import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLCapabilitiesImmutable;
 import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLOffscreenAutoDrawable;
 import javax.media.opengl.GLPbuffer;
 import javax.media.opengl.GLProfile;
 
 /**
  * Tests the closing the device of GLWindow and GLPBuffer in JOGL
  */
+ at SuppressWarnings("deprecation")
 public class TestNEWTCloseX11DisplayBug565 {
 
   @Test
@@ -59,7 +61,7 @@ public class TestNEWTCloseX11DisplayBug565 {
 
 
   @Test
-  public void testX11WindowMemoryLeakOffscreenWindow() throws Exception {
+  public void testX11WindowMemoryLeakGLPbuffer() throws Exception {
     GLProfile.initSingleton(); // ensure shared resource runner is done
     try {
       for ( int j = 0; j < 10; j++ ) {
@@ -100,6 +102,48 @@ public class TestNEWTCloseX11DisplayBug565 {
     }
   }
 
+  @Test
+  public void testX11WindowMemoryLeakFBOAutoDrawable() throws Exception {
+    GLProfile.initSingleton(); // ensure shared resource runner is done
+    try {
+      for ( int j = 0; j < 10; j++ ) {
+        final int open0;
+        if(NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(false)) {        
+            open0 = X11Util.getOpenDisplayConnectionNumber();
+        } else {
+            open0 = 0;
+        }
+        final GLProfile glp = GLProfile.getDefault( );
+        GLCapabilitiesImmutable caps = new GLCapabilities( glp );
+
+
+        GLOffscreenAutoDrawable buffer = GLDrawableFactory.getFactory( glp ).createOffscreenAutoDrawable(
+            null,
+            caps,
+            new DefaultGLCapabilitiesChooser(),
+            256,
+            256,
+            null
+        );
+        buffer.display();
+        buffer.destroy();
+
+        if(NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(false)) {
+            final int openD = X11Util.getOpenDisplayConnectionNumber() - open0;
+            if(openD > 0) {
+                X11Util.dumpOpenDisplayConnections();
+                X11Util.dumpPendingDisplayConnections();
+                Assert.assertEquals("New display connection didn't close", 0, openD);
+            }
+        }
+      }
+    }
+    catch ( Exception e ) {
+      e.printStackTrace();
+      Assert.fail(e.getMessage());
+    }
+  }
+  
   public static void main(String args[]) {
     org.junit.runner.JUnitCore.main(TestNEWTCloseX11DisplayBug565.class.getName());
   }
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingOffscreenLayer01GLCanvasAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestOffscreenLayer01GLCanvasAWT.java
similarity index 70%
rename from src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingOffscreenLayer01GLCanvasAWT.java
rename to src/test/com/jogamp/opengl/test/junit/jogl/acore/TestOffscreenLayer01GLCanvasAWT.java
index 4542fa4..9040716 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingOffscreenLayer01GLCanvasAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestOffscreenLayer01GLCanvasAWT.java
@@ -26,19 +26,22 @@
  * or implied, of JogAmp Community.
  */
  
-package com.jogamp.opengl.test.junit.newt.parenting;
+package com.jogamp.opengl.test.junit.jogl.acore;
 
 import java.awt.BorderLayout;
 import java.awt.Button;
 import java.awt.Container;
 import java.awt.Dimension;
 import java.awt.Frame;
+import java.io.BufferedReader;
 import java.io.IOException;
+import java.io.InputStreamReader;
 import java.lang.reflect.InvocationTargetException;
 
 import javax.media.opengl.GLAnimatorControl;
 import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLProfile;
 import javax.media.opengl.awt.GLCanvas;
 
 import jogamp.nativewindow.jawt.JAWTUtil;
@@ -56,11 +59,16 @@ import com.jogamp.opengl.test.junit.util.MiscUtils;
 import com.jogamp.opengl.test.junit.util.UITestCase;
 import com.jogamp.opengl.util.Animator;
 
-public class TestParentingOffscreenLayer01GLCanvasAWT extends UITestCase {
+public class TestOffscreenLayer01GLCanvasAWT extends UITestCase {
+    static boolean singleBuffer = false;
+    static boolean useMSAA = false;
+    static boolean addComp = true;
+    static int swapInterval = 1;
+    static boolean shallUseOffscreenPBufferLayer = false;
+    static boolean noAnimation = false;
     static Dimension frameSize0;
     static Dimension frameSize1;
     static Dimension preferredGLSize;
-    static Dimension minGLSize;
     static long durationPerTest = 1000;
 
     @BeforeClass
@@ -68,7 +76,6 @@ public class TestParentingOffscreenLayer01GLCanvasAWT extends UITestCase {
         frameSize0 = new Dimension(500,300);
         frameSize1 = new Dimension(800,600);
         preferredGLSize = new Dimension(400,200);
-        minGLSize = new Dimension(200,100);
     }
 
     private void setupFrameAndShow(final Frame f, java.awt.Component comp) throws InterruptedException, InvocationTargetException {
@@ -90,10 +97,12 @@ public class TestParentingOffscreenLayer01GLCanvasAWT extends UITestCase {
         
         javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
             public void run() {
+                f.pack();
                 f.validate();
                 f.setVisible(true);
             }});        
     }
+    
     private void end(GLAnimatorControl actrl, final Frame f, Window w) throws InterruptedException, InvocationTargetException {
         actrl.stop();
         javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
@@ -114,49 +123,67 @@ public class TestParentingOffscreenLayer01GLCanvasAWT extends UITestCase {
     }
     
     @Test
-    public void testOnscreenLayerGLCanvas_Onscreen() throws InterruptedException, InvocationTargetException {
-        testOffscreenLayerGLCanvas_Impl(false);
+    public void test01_GLDefault() throws InterruptedException, InvocationTargetException {        
+        testOffscreenLayerGLCanvas_Impl(null);
     }
     
     @Test
-    public void testOffscreenLayerGLCanvas_OffscreenLayerWithOnscreenClass() throws InterruptedException, InvocationTargetException {        
-        testOffscreenLayerGLCanvas_Impl(true);
-    }
-    
-    private void testOffscreenLayerGLCanvas_Impl(boolean offscreenLayer) throws InterruptedException, InvocationTargetException {
-        if(!offscreenLayer && JAWTUtil.isOffscreenLayerRequired()) {
-            System.err.println("onscreen layer n/a");
+    public void test01_GL3() throws InterruptedException, InvocationTargetException {        
+        if( !GLProfile.isAvailable(GLProfile.GL3) ) {
+            System.err.println("GL3 n/a");
             return;
         }
-        if(offscreenLayer && !JAWTUtil.isOffscreenLayerSupported()) {
+        testOffscreenLayerGLCanvas_Impl(GLProfile.get(GLProfile.GL3));
+    }
+    
+    private void testOffscreenLayerGLCanvas_Impl(GLProfile glp) throws InterruptedException, InvocationTargetException {
+        if(!JAWTUtil.isOffscreenLayerSupported()) {
             System.err.println("offscreen layer n/a");
             return;
         }        
         final Frame frame1 = new Frame("AWT Parent Frame");
         
-        GLCapabilities glCaps = new GLCapabilities(null);
-        final GLCanvas glc = new GLCanvas(glCaps);
-        glc.setShallUseOffscreenLayer(offscreenLayer); // trigger offscreen layer - if supported
+        GLCapabilities caps = new GLCapabilities(glp);
+        if(singleBuffer) {
+            caps.setDoubleBuffered(false);
+        }
+        if(useMSAA) {
+            caps.setNumSamples(4);
+            caps.setSampleBuffers(true);
+        }
+        if(shallUseOffscreenPBufferLayer) {
+            caps.setPBuffer(true);
+            caps.setOnscreen(true); // simulate normal behavior ..
+        }
+        final GLCanvas glc = new GLCanvas(caps);
+        glc.setShallUseOffscreenLayer(true); // trigger offscreen layer - if supported
         glc.setPreferredSize(preferredGLSize);
-        glc.setMinimumSize(minGLSize);
+        glc.setMinimumSize(preferredGLSize);
+        glc.setSize(preferredGLSize);
         
-        GLEventListener demo1 = new GearsES2(1);
+        GearsES2 demo1 = new GearsES2(swapInterval);
+        if(noAnimation) {
+            demo1.setDoRotation(false);
+        }
         glc.addGLEventListener(demo1);
         
         frame1.setSize(frameSize0);
         setupFrameAndShow(frame1, glc);
         Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glc, true));
         Assert.assertEquals(true, AWTRobotUtil.waitForVisible(glc, true));
-        Assert.assertEquals(JAWTUtil.isOffscreenLayerSupported() && offscreenLayer,
-                            glc.isOffscreenLayerSurfaceEnabled());
+        Assert.assertEquals(true, glc.isOffscreenLayerSurfaceEnabled());
         
         GLAnimatorControl animator1 = new Animator(glc);
-        animator1.start();
+        if(!noAnimation) {
+            animator1.start();
+        }
+        animator1.setUpdateFPSFrames(60, System.err);
 
         Thread.sleep(durationPerTest/2);
         javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
             public void run() {
                 frame1.setSize(frameSize1);
+                frame1.pack();
                 frame1.validate();
             }});        
         
@@ -187,12 +214,33 @@ public class TestParentingOffscreenLayer01GLCanvasAWT extends UITestCase {
     }
 
     public static void main(String args[]) throws IOException {
+        boolean waitForKey = false;
         for(int i=0; i<args.length; i++) {
             if(args[i].equals("-time")) {
                 durationPerTest = atoi(args[++i]);
+            } else if(args[i].equals("-vsync")) {
+                i++;
+                swapInterval = MiscUtils.atoi(args[i], swapInterval);
+            } else if(args[i].equals("-layeredPBuffer")) {
+                shallUseOffscreenPBufferLayer = true;
+            } else if(args[i].equals("-msaa")) {
+                useMSAA = true;
+            } else if(args[i].equals("-single")) {
+                singleBuffer = true;
+            } else if(args[i].equals("-still")) {
+                noAnimation = true;
+            } else if(args[i].equals("-wait")) {
+                waitForKey = true;
             }
         }
-        String tstname = TestParentingOffscreenLayer01GLCanvasAWT.class.getName();
+        if(waitForKey) {
+            BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
+            System.err.println("Press enter to continue");
+            try {
+                System.err.println(stdin.readLine());
+            } catch (IOException e) { }
+        }
+        String tstname = TestOffscreenLayer01GLCanvasAWT.class.getName();
         /*
         org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(new String[] {
             tstname,
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingOffscreenLayer02NewtCanvasAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestOffscreenLayer02NewtCanvasAWT.java
similarity index 68%
rename from src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingOffscreenLayer02NewtCanvasAWT.java
rename to src/test/com/jogamp/opengl/test/junit/jogl/acore/TestOffscreenLayer02NewtCanvasAWT.java
index 6a1980b..e4a3bce 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingOffscreenLayer02NewtCanvasAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestOffscreenLayer02NewtCanvasAWT.java
@@ -26,19 +26,22 @@
  * or implied, of JogAmp Community.
  */
  
-package com.jogamp.opengl.test.junit.newt.parenting;
+package com.jogamp.opengl.test.junit.jogl.acore;
 
 import java.awt.BorderLayout;
 import java.awt.Button;
 import java.awt.Container;
 import java.awt.Dimension;
 import java.awt.Frame;
+import java.io.BufferedReader;
 import java.io.IOException;
+import java.io.InputStreamReader;
 import java.lang.reflect.InvocationTargetException;
 
 import javax.media.opengl.GLAnimatorControl;
 import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLProfile;
 
 import jogamp.nativewindow.jawt.JAWTUtil;
 
@@ -50,16 +53,22 @@ import com.jogamp.newt.Window;
 import com.jogamp.newt.awt.NewtCanvasAWT;
 import com.jogamp.newt.opengl.GLWindow;
 import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+import com.jogamp.opengl.test.junit.newt.parenting.NewtAWTReparentingKeyAdapter;
 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.util.Animator;
 
-public class TestParentingOffscreenLayer02NewtCanvasAWT extends UITestCase {
+public class TestOffscreenLayer02NewtCanvasAWT extends UITestCase {
+    static boolean singleBuffer = false;
+    static boolean useMSAA = false;
+    static boolean addComp = true;
+    static int swapInterval = 1;
+    static boolean shallUseOffscreenPBufferLayer = false;
+    static boolean noAnimation = false;
     static Dimension frameSize0;
     static Dimension frameSize1;
     static Dimension preferredGLSize;
-    static Dimension minGLSize;
     static long durationPerTest = 1000;
 
     @BeforeClass
@@ -67,7 +76,6 @@ public class TestParentingOffscreenLayer02NewtCanvasAWT extends UITestCase {
         frameSize0 = new Dimension(500,300);
         frameSize1 = new Dimension(800,600);
         preferredGLSize = new Dimension(400,200);
-        minGLSize = new Dimension(200,100);
     }
 
     private void setupFrameAndShow(final Frame f, java.awt.Component comp) throws InterruptedException, InvocationTargetException {
@@ -89,10 +97,12 @@ public class TestParentingOffscreenLayer02NewtCanvasAWT extends UITestCase {
         
         javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
             public void run() {
+                f.pack();
                 f.validate();
                 f.setVisible(true);
             }});        
     }
+    
     private void end(GLAnimatorControl actrl, final Frame f, Window w) throws InterruptedException, InvocationTargetException {
         actrl.stop();
         javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
@@ -105,49 +115,50 @@ public class TestParentingOffscreenLayer02NewtCanvasAWT extends UITestCase {
     }
     
     @Test
-    public void testOnscreenLayerNewtCanvas_Onscreen() throws InterruptedException, InvocationTargetException {
-        if(!JAWTUtil.isOffscreenLayerRequired()) {
-            testOffscreenLayerNewtCanvas_Impl(false, false);
-        } else {
-            System.err.println("onscreen layer n/a");
-        }
+    public void test01_GLDefault() throws InterruptedException, InvocationTargetException {        
+        testOffscreenLayerNewtCanvas_Impl(null);
     }
     
-    // @Test
-    public void testOffscreenLayerNewtCanvas_OffscreenLayerWithOffscreenClass() throws InterruptedException, InvocationTargetException {                
-        if(JAWTUtil.isOffscreenLayerSupported()) {
-            testOffscreenLayerNewtCanvas_Impl(true, true);
-        } else {
-            System.err.println("offscreen layer n/a");
-        }        
+    @Test
+    public void test02_GL3() throws InterruptedException, InvocationTargetException {
+        if( !GLProfile.isAvailable(GLProfile.GL3) ) {
+            System.err.println("GL3 n/a");
+            return;
+        }
+        testOffscreenLayerNewtCanvas_Impl(GLProfile.get(GLProfile.GL3));
     }
     
-    @Test
-    public void testOffscreenLayerNewtCanvas_OffscreenLayerWithOnscreenClass() throws InterruptedException, InvocationTargetException {        
-        if(JAWTUtil.isOffscreenLayerSupported()) {
-            testOffscreenLayerNewtCanvas_Impl(true, false);
-        } else {
+    private void testOffscreenLayerNewtCanvas_Impl(GLProfile glp) throws InterruptedException, InvocationTargetException {
+        if(!JAWTUtil.isOffscreenLayerSupported()) {
             System.err.println("offscreen layer n/a");
+            return;
         }        
-    }
-    
-    private void testOffscreenLayerNewtCanvas_Impl(boolean offscreenLayer, boolean offscreenClass) throws InterruptedException, InvocationTargetException {
         final Frame frame1 = new Frame("AWT Parent Frame");
         
-        GLCapabilities glCaps = new GLCapabilities(null);
-        if(offscreenClass) {
-            glCaps.setOnscreen(false);
-            glCaps.setPBuffer(true);
+        GLCapabilities caps = new GLCapabilities(glp);
+        if(singleBuffer) {
+            caps.setDoubleBuffered(false);
         }
-
-        GLWindow glWindow1 = GLWindow.create(glCaps);
+        if(useMSAA) {
+            caps.setNumSamples(4);
+            caps.setSampleBuffers(true);
+        }
+        if(shallUseOffscreenPBufferLayer) {
+            caps.setPBuffer(true);
+            caps.setOnscreen(true); // get native NEWT Window, not OffscreenWindow
+        }
+        GLWindow glWindow1 = GLWindow.create(caps);
         
         final NewtCanvasAWT newtCanvasAWT1 = new NewtCanvasAWT(glWindow1);
-        newtCanvasAWT1.setShallUseOffscreenLayer(offscreenLayer); // trigger offscreen layer - if supported
+        newtCanvasAWT1.setShallUseOffscreenLayer(true); // trigger offscreen layer - if supported
         newtCanvasAWT1.setPreferredSize(preferredGLSize);
-        newtCanvasAWT1.setMinimumSize(minGLSize);
+        newtCanvasAWT1.setMinimumSize(preferredGLSize);
+        newtCanvasAWT1.setSize(preferredGLSize);
         
-        GLEventListener demo1 = new GearsES2(1);
+        GearsES2 demo1 = new GearsES2(swapInterval);
+        if(noAnimation) {
+            demo1.setDoRotation(false);
+        }
         setDemoFields(demo1, glWindow1, false);
         glWindow1.addGLEventListener(demo1);
         glWindow1.addKeyListener(new NewtAWTReparentingKeyAdapter(frame1, newtCanvasAWT1, glWindow1));
@@ -157,16 +168,19 @@ public class TestParentingOffscreenLayer02NewtCanvasAWT extends UITestCase {
         Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glWindow1, true));
         Assert.assertEquals(true, AWTRobotUtil.waitForVisible(glWindow1, true));
         Assert.assertEquals(newtCanvasAWT1.getNativeWindow(),glWindow1.getParent());
-        Assert.assertEquals(JAWTUtil.isOffscreenLayerSupported() && offscreenLayer, 
-                            newtCanvasAWT1.isOffscreenLayerSurfaceEnabled());
+        Assert.assertEquals(true, newtCanvasAWT1.isOffscreenLayerSurfaceEnabled());
 
         GLAnimatorControl animator1 = new Animator(glWindow1);
-        animator1.start();
+        if(!noAnimation) {
+            animator1.start();
+        }
+        animator1.setUpdateFPSFrames(60, System.err);
 
         Thread.sleep(durationPerTest/2);
         javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
             public void run() {
                 frame1.setSize(frameSize1);
+                frame1.pack();
                 frame1.validate();
             }});        
         
@@ -197,12 +211,33 @@ public class TestParentingOffscreenLayer02NewtCanvasAWT extends UITestCase {
     }
 
     public static void main(String args[]) throws IOException {
+        boolean waitForKey = false;
         for(int i=0; i<args.length; i++) {
             if(args[i].equals("-time")) {
                 durationPerTest = atoi(args[++i]);
+            } else if(args[i].equals("-vsync")) {
+                i++;
+                swapInterval = MiscUtils.atoi(args[i], swapInterval);
+            } else if(args[i].equals("-layeredPBuffer")) {
+                shallUseOffscreenPBufferLayer = true;
+            } else if(args[i].equals("-msaa")) {
+                useMSAA = true;
+            } else if(args[i].equals("-single")) {
+                singleBuffer = true;
+            } else if(args[i].equals("-still")) {
+                noAnimation = true;
+            } else if(args[i].equals("-wait")) {
+                waitForKey = true;
             }
         }
-        String tstname = TestParentingOffscreenLayer02NewtCanvasAWT.class.getName();
+        if(waitForKey) {
+            BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
+            System.err.println("Press enter to continue");
+            try {
+                System.err.println(stdin.readLine());
+            } catch (IOException e) { }
+        }
+        String tstname = TestOffscreenLayer02NewtCanvasAWT.class.getName();
         /*
         org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(new String[] {
             tstname,
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPBufferDeadlockAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPBufferDeadlockAWT.java
index 3a25d12..90934f1 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPBufferDeadlockAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPBufferDeadlockAWT.java
@@ -45,6 +45,7 @@ import org.junit.Test;
 import com.jogamp.common.util.RunnableTask;
 import com.jogamp.opengl.test.junit.util.UITestCase;
 
+ at SuppressWarnings("deprecation")
 public class TestPBufferDeadlockAWT extends UITestCase {
   static GLProfile glp;
   static int width, height;
@@ -100,6 +101,7 @@ public class TestPBufferDeadlockAWT extends UITestCase {
         }        
     });
     Assert.assertTrue(done[0]);
+    pbuffer.destroy();
   }
 
   @Test(timeout = 2000) // 2s timeout
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPMVMatrix01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPMVMatrix01NEWT.java
new file mode 100644
index 0000000..c44a82a
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPMVMatrix01NEWT.java
@@ -0,0 +1,442 @@
+/**
+ * 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.test.junit.jogl.acore;
+
+import java.nio.FloatBuffer;
+
+import javax.media.opengl.GL2ES1;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLProfile;
+import javax.media.opengl.fixedfunc.GLMatrixFunc;
+
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.jogamp.common.os.Platform;
+import com.jogamp.opengl.FloatUtil;
+import com.jogamp.opengl.test.junit.util.MiscUtils;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.util.PMVMatrix;
+
+public class TestPMVMatrix01NEWT extends UITestCase {
+    
+    static final float epsilon = 0.00001f;
+
+    // matrix 2 rows x 3 columns - In row major order
+    static FloatBuffer matrix2x3R = FloatBuffer.wrap( new float[] {  1.0f,  2.0f,  3.0f,
+                                                                     4.0f,  5.0f,  6.0f } );
+    
+    // matrix 2 rows x 3 columns - In column major order
+    static FloatBuffer matrix2x3C = FloatBuffer.wrap( new float[] {  1.0f,  4.0f,  
+                                                                     2.0f,  5.0f,  
+                                                                     3.0f,  6.0f } );
+    
+    // matrix 3 rows x 2 columns - In row major order
+    static FloatBuffer matrix3x2R = FloatBuffer.wrap( new float[] {  1.0f,  2.0f,
+                                                                     3.0f,  4.0f,
+                                                                     5.0f,  6.0f  } );
+    
+    // matrix 3 rows x 2 columns - In column major order
+    static FloatBuffer matrix3x2C = FloatBuffer.wrap( new float[] {  1.0f,  3.0f, 5.0f,  
+                                                                     2.0f,  4.0f, 6.0f  } );
+    
+    // Translated xyz 123 - Row - In row major order !
+    static FloatBuffer translated123R = FloatBuffer.wrap( new float[] {  1.0f,  0.0f,  0.0f,  1.0f,
+                                                                         0.0f,  1.0f,  0.0f,  2.0f,
+                                                                         0.0f,  0.0f,  1.0f,  3.0f,
+                                                                         0.0f,  0.0f,  0.0f,  1.0f } );
+    
+    // Translated xyz 123 - Column - In column major order !
+    static FloatBuffer translated123C = FloatBuffer.wrap( new float[] {  1.0f,  0.0f,  0.0f,  0.0f,
+                                                                         0.0f,  1.0f,  0.0f,  0.0f,
+                                                                         0.0f,  0.0f,  1.0f,  0.0f,
+                                                                         1.0f,  2.0f,  3.0f,  1.0f } );
+    
+    // Translated xyz 123 - Inverse - In column major order !
+    static FloatBuffer translated123I = FloatBuffer.wrap( new float[] {  1.0f,  0.0f,  0.0f,  0.0f,
+                                                                         0.0f,  1.0f,  0.0f,  0.0f,
+                                                                         0.0f,  0.0f,  1.0f,  0.0f,
+                                                                        -1.0f, -2.0f, -3.0f,  1.0f } );
+    
+    // Translated xyz 123 - Inverse and Transposed - In column major order !
+    static FloatBuffer translated123IT = FloatBuffer.wrap( new float[] {  1.0f,  0.0f,  0.0f, -1.0f,
+                                                                          0.0f,  1.0f,  0.0f, -2.0f,
+                                                                          0.0f,  0.0f,  1.0f, -3.0f,
+                                                                          0.0f,  0.0f,  0.0f,  1.0f } );
+
+    @Test
+    public void test00MatrixToString() {
+        final String s4x4Cpmv = PMVMatrix.matrixToString(null, "%10.5f", translated123C).toString();
+        final String s4x4Cflu = FloatUtil.matrixToString(null, null, "%10.5f", translated123C, 0, 4, 4, false).toString();
+        final String s4x4Rflu = FloatUtil.matrixToString(null, null, "%10.5f", translated123R, 0, 4, 4, true).toString();
+        System.err.println("PMV-C-O 4x4: ");
+        System.err.println(s4x4Cpmv);
+        System.err.println();
+        System.err.println("FLU-C-O 4x4: ");
+        System.err.println(s4x4Cflu);
+        System.err.println();
+        System.err.println("FLU-R-O 4x4: ");
+        System.err.println(s4x4Rflu);
+        System.err.println();
+        Assert.assertEquals(s4x4Cpmv, s4x4Cflu);
+        Assert.assertEquals(s4x4Cflu, s4x4Rflu);
+        
+        final String s2x3Rflu = FloatUtil.matrixToString(null, null, "%10.5f", matrix2x3R, 0, 2, 3, true).toString();
+        final String s2x3Cflu = FloatUtil.matrixToString(null, null, "%10.5f", matrix2x3C, 0, 2, 3, false).toString();
+        System.err.println("FLU-R-O 2x3: ");
+        System.err.println(s2x3Rflu);
+        System.err.println();
+        System.err.println("FLU-C-O 2x3: ");
+        System.err.println(s2x3Cflu);
+        System.err.println();
+        Assert.assertEquals(s2x3Cflu, s2x3Rflu);
+        
+        final String s3x2Rflu = FloatUtil.matrixToString(null, null, "%10.5f", matrix3x2R, 0, 3, 2, true).toString();
+        final String s3x2Cflu = FloatUtil.matrixToString(null, null, "%10.5f", matrix3x2C, 0, 3, 2, false).toString();
+        System.err.println("FLU-R-O 3x2: ");
+        System.err.println(s3x2Rflu);
+        System.err.println();
+        System.err.println("FLU-C-O 3x2: ");
+        System.err.println(s3x2Cflu);
+        System.err.println();
+        Assert.assertEquals(s3x2Cflu, s3x2Rflu);                
+    }
+    
+    /**
+     * Test using traditional access workflow, i.e. 1) operation 2) get-matrix references
+     * <p>
+     * The Mvi and Mvit dirty-bits and request-mask will be validated.
+     * </p>
+     */
+    @SuppressWarnings("deprecation")
+    @Test
+    public void test01MviUpdateTraditionalAccess() {
+        FloatBuffer p, mv, mvi, mvit;
+        boolean b;
+        final PMVMatrix pmv = new PMVMatrix(true);
+        // System.err.println("P0: "+pmv.toString());
+        
+        Assert.assertTrue("Dirty bits clean, "+pmv.toString(), 0 != pmv.getDirtyBits());
+        Assert.assertEquals("Request bits not zero, "+pmv.toString(), 0, pmv.getRequestMask());
+        
+        //
+        // Action #0
+        //
+        final FloatBuffer ident;
+        {
+            pmv.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
+            pmv.glLoadIdentity();
+            ident = pmv.glGetPMatrixf();
+            
+            pmv.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
+            pmv.glLoadIdentity();
+        }        
+        Assert.assertTrue("Modified bits zero", 0 != pmv.getModifiedBits(true)); // clear & test
+        Assert.assertTrue("Dirty bits clean, "+pmv.toString(), 0 != pmv.getDirtyBits());
+        Assert.assertEquals("Request bits not zero, "+pmv.toString(), 0, pmv.getRequestMask());
+        
+        //
+        // Action #1
+        //
+        pmv.glTranslatef(1f, 2f, 3f); // all dirty !
+        Assert.assertTrue("Modified bits zero", 0 != pmv.getModifiedBits(true)); // clear & test
+        Assert.assertTrue("Dirty bits clean, "+pmv.toString(), 0 != pmv.getDirtyBits());
+        Assert.assertEquals("Request bits not zero, "+pmv.toString(), 0, pmv.getRequestMask());
+        // System.err.println("P1: "+pmv.toString());
+        
+        b = pmv.update(); // will not clean dirty bits, since no request has been made -> false
+        Assert.assertEquals("Update has been perfomed, but non requested", false, b);       
+        Assert.assertTrue("Dirty bits clean, "+pmv.toString(), 0 != pmv.getDirtyBits());
+        Assert.assertEquals("Request bits not zero, "+pmv.toString(), 0, pmv.getRequestMask());
+        // System.err.println("P2: "+pmv.toString());
+        
+        //
+        // Get
+        //
+        p = pmv.glGetPMatrixf();
+        MiscUtils.assertFloatBufferEquals("P not identity, "+pmv.toString(), ident, p, epsilon);
+        mv = pmv.glGetMvMatrixf();
+        MiscUtils.assertFloatBufferEquals("Mv not translated123, "+pmv.toString(), translated123C, mv, epsilon);        
+        mvi = pmv.glGetMviMatrixf();
+        MiscUtils.assertFloatBufferEquals("Mvi not translated123, "+pmv.toString(), translated123I, mvi, epsilon);
+        Assert.assertEquals("Remaining dirty bits not Mvit, "+pmv.toString(), PMVMatrix.DIRTY_INVERSE_TRANSPOSED_MODELVIEW, pmv.getDirtyBits());
+        Assert.assertEquals("Request bit Mvi not set, "+pmv.toString(), PMVMatrix.DIRTY_INVERSE_MODELVIEW, pmv.getRequestMask());
+        // System.err.println("P3: "+pmv.toString());
+        
+        mvit = pmv.glGetMvitMatrixf();
+        MiscUtils.assertFloatBufferEquals("Mvit not translated123, "+pmv.toString()+pmv.toString(), translated123IT, mvit, epsilon);
+        Assert.assertTrue("Dirty bits not clean, "+pmv.toString(), 0 == pmv.getDirtyBits());
+        Assert.assertEquals("Request bits Mvi and Mvit not set, "+pmv.toString(), PMVMatrix.DIRTY_INVERSE_MODELVIEW | PMVMatrix.DIRTY_INVERSE_TRANSPOSED_MODELVIEW, pmv.getRequestMask());        
+        // System.err.println("P4: "+pmv.toString());
+
+        //
+        // Action #2
+        //
+        pmv.glLoadIdentity(); // all dirty
+        Assert.assertTrue("Modified bits zero", 0 != pmv.getModifiedBits(true)); // clear & test
+        Assert.assertTrue("Dirty bits clean, "+pmv.toString(), 0 != pmv.getDirtyBits());
+        Assert.assertEquals("Request bits Mvi and Mvit not set, "+pmv.toString(), PMVMatrix.DIRTY_INVERSE_MODELVIEW | PMVMatrix.DIRTY_INVERSE_TRANSPOSED_MODELVIEW, pmv.getRequestMask());
+        MiscUtils.assertFloatBufferEquals("P not identity, "+pmv.toString(), ident, p, epsilon);
+        MiscUtils.assertFloatBufferEquals("Mv not identity, "+pmv.toString(), ident, mv, epsilon);        
+        MiscUtils.assertFloatBufferNotEqual("Mvi already identity w/o update, "+pmv.toString(), ident, mvi, epsilon);
+        MiscUtils.assertFloatBufferNotEqual("Mvit already identity w/o update, "+pmv.toString(), ident, mvit, epsilon);
+        MiscUtils.assertFloatBufferEquals("Mvi not translated123, "+pmv.toString()+pmv.toString(), translated123I, mvi, epsilon);
+        MiscUtils.assertFloatBufferEquals("Mvit not translated123, "+pmv.toString()+pmv.toString(), translated123IT, mvit, epsilon);
+     
+        b = pmv.update(); // will clean dirty bits, since request has been made -> true
+        Assert.assertEquals("Update has not been perfomed, but requested", true, b);       
+        Assert.assertTrue("Dirty bits not clean, "+pmv.toString(), 0 == pmv.getDirtyBits());
+        Assert.assertEquals("Request bits Mvi and Mvit not set, "+pmv.toString(), PMVMatrix.DIRTY_INVERSE_MODELVIEW | PMVMatrix.DIRTY_INVERSE_TRANSPOSED_MODELVIEW, pmv.getRequestMask());
+        MiscUtils.assertFloatBufferEquals("Mvi not identity after update, "+pmv.toString(), ident, mvi, epsilon);
+        MiscUtils.assertFloatBufferEquals("Mvit not identity after update, "+pmv.toString(), ident, mvit, epsilon);
+    }
+    
+    /**
+     * Test using shader access workflow, i.e. 1) get-matrix references 2) operations
+     * <p>
+     * The Mvi and Mvit dirty-bits and request-mask will be validated.
+     * </p>
+     */
+    @SuppressWarnings("deprecation")
+    @Test
+    public void test02MviUpdateShaderAccess() {
+        final FloatBuffer p, mv, mvi, mvit;
+        boolean b;
+        final PMVMatrix pmv = new PMVMatrix(true);
+        // System.err.println("P0: "+pmv.toString());
+        
+        Assert.assertTrue("Dirty bits clean, "+pmv.toString(), 0 != pmv.getDirtyBits());
+        Assert.assertEquals("Request bits not zero, "+pmv.toString(), 0, pmv.getRequestMask());
+        
+        //
+        // Action #0
+        //
+        final FloatBuffer ident;
+        {
+            pmv.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
+            pmv.glLoadIdentity();
+            ident = pmv.glGetPMatrixf();
+            
+            pmv.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
+            pmv.glLoadIdentity();
+        }        
+        // System.err.println("P0: "+pmv.toString());
+        Assert.assertTrue("Modified bits zero", 0 != pmv.getModifiedBits(true)); // clear & test
+        Assert.assertTrue("Dirty bits clean, "+pmv.toString(), 0 != pmv.getDirtyBits());
+        Assert.assertEquals("Request bits not zero, "+pmv.toString(), 0, pmv.getRequestMask());
+        // System.err.println("P1: "+pmv.toString());
+        
+        //
+        // Get
+        //
+        p    = pmv.glGetPMatrixf();
+        MiscUtils.assertFloatBufferEquals("P not identity, "+pmv.toString(), ident, p, epsilon);
+        mv   = pmv.glGetMvMatrixf();
+        MiscUtils.assertFloatBufferEquals("Mv not identity, "+pmv.toString(), ident, mv, epsilon);
+        Assert.assertTrue("Dirty bits clean, "+pmv.toString(), 0 != pmv.getDirtyBits());
+        Assert.assertEquals("Request bits not zero, "+pmv.toString(), 0, pmv.getRequestMask());
+        
+        mvi  = pmv.glGetMviMatrixf();
+        MiscUtils.assertFloatBufferEquals("Mvi not identity, "+pmv.toString(), ident, mvi, epsilon);        
+        Assert.assertEquals("Remaining dirty bits not Mvit, "+pmv.toString(), PMVMatrix.DIRTY_INVERSE_TRANSPOSED_MODELVIEW, pmv.getDirtyBits());
+        Assert.assertEquals("Request bit Mvi not set, "+pmv.toString(), PMVMatrix.DIRTY_INVERSE_MODELVIEW, pmv.getRequestMask());
+        
+        mvit = pmv.glGetMvitMatrixf();
+        MiscUtils.assertFloatBufferEquals("Mvi not identity, "+pmv.toString(), ident, mvit, epsilon);        
+        Assert.assertTrue("Dirty bits not clean, "+pmv.toString(), 0 == pmv.getDirtyBits());
+        Assert.assertEquals("Request bits Mvi and Mvit not set, "+pmv.toString(), PMVMatrix.DIRTY_INVERSE_MODELVIEW | PMVMatrix.DIRTY_INVERSE_TRANSPOSED_MODELVIEW, pmv.getRequestMask());
+
+        //
+        // Action #1
+        //
+        pmv.glTranslatef(1f, 2f, 3f); // all dirty !
+        Assert.assertTrue("Modified bits zero", 0 != pmv.getModifiedBits(true)); // clear & test
+        Assert.assertTrue("Dirty bits clean, "+pmv.toString(), 0 != pmv.getDirtyBits());
+        MiscUtils.assertFloatBufferEquals("P not identity, "+pmv.toString()+pmv.toString(), ident, p, epsilon);
+        MiscUtils.assertFloatBufferEquals("Mv not translated123, "+pmv.toString()+pmv.toString(), translated123C, mv, epsilon);
+        MiscUtils.assertFloatBufferNotEqual("Mvi already translated123 w/o update, "+pmv.toString()+pmv.toString(), translated123I, mvi, epsilon);
+        MiscUtils.assertFloatBufferNotEqual("Mvit already translated123 w/o update, "+pmv.toString()+pmv.toString(), translated123IT, mvit, epsilon);
+        MiscUtils.assertFloatBufferEquals("Mvi not identity, "+pmv.toString()+pmv.toString(), ident, mvi, epsilon);
+        MiscUtils.assertFloatBufferEquals("Mvit not identity, "+pmv.toString()+pmv.toString(), ident, mvit, epsilon);
+        
+        b = pmv.update(); // will clean dirty bits, since all requests has been made -> true        
+        Assert.assertEquals("Update has not been perfomed, but requested", true, b);       
+        Assert.assertTrue("Dirty bits not clean, "+pmv.toString(), 0 == pmv.getDirtyBits());
+        Assert.assertEquals("Request bits Mvi and Mvit not set, "+pmv.toString(), PMVMatrix.DIRTY_INVERSE_MODELVIEW | PMVMatrix.DIRTY_INVERSE_TRANSPOSED_MODELVIEW, pmv.getRequestMask());
+        MiscUtils.assertFloatBufferEquals("Mvi not translated123, "+pmv.toString()+pmv.toString(), translated123I, mvi, epsilon);
+        MiscUtils.assertFloatBufferEquals("Mvit not translated123, "+pmv.toString()+pmv.toString(), translated123IT, mvit, epsilon);
+        // System.err.println("P2: "+pmv.toString());        
+    }
+    
+    @SuppressWarnings("unused")
+    @Test
+    public void test03MvTranslate() {
+        final FloatBuffer pmvMv, pmvMvi, pmvMvit;
+        {
+            final PMVMatrix pmv = new PMVMatrix(true);
+            pmv.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
+            pmv.glLoadIdentity();
+            pmv.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
+            pmv.glLoadIdentity();
+            pmv.glTranslatef(5f, 6f, 7f);
+            
+            pmvMv = pmv.glGetMvMatrixf();
+            pmvMvi = pmv.glGetMviMatrixf();
+            pmvMvit = pmv.glGetMvitMatrixf();
+        }
+
+        final FloatBuffer glMv = FloatBuffer.allocate(16);
+        {
+            GL2ES1 gl = dc.glc.getGL().getGL2ES1();
+            gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
+            gl.glLoadIdentity();
+            gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
+            gl.glLoadIdentity();
+            gl.glTranslatef(5f, 6f, 7f);
+            
+            gl.glGetFloatv(GLMatrixFunc.GL_MODELVIEW_MATRIX, glMv);
+        }
+        // System.err.println(PMVMatrix.matrixToString(null, "%10.5f", glMv, pmvMv).toString());
+        
+        MiscUtils.assertFloatBufferEquals("Arrays not equal, expected"+Platform.NEWLINE+PMVMatrix.matrixToString(null, "%10.5f", glMv).toString()+
+                ", actual"+Platform.NEWLINE+PMVMatrix.matrixToString(null, "%10.5f", pmvMv).toString(),
+                glMv, pmvMv, epsilon);
+        
+        // System.err.println("pmvMvi:  "+Platform.NEWLINE+PMVMatrix.matrixToString(null, "%10.5f", pmvMvi));
+        // System.err.println("pmvMvit: "+Platform.NEWLINE+PMVMatrix.matrixToString(null, "%10.5f", pmvMvit));        
+    }
+    
+    @SuppressWarnings("unused")
+    @Test
+    public void test04MvTranslateRotate() {
+        final FloatBuffer pmvMv, pmvMvi, pmvMvit;
+        {
+            final PMVMatrix pmv = new PMVMatrix(true);
+            pmv.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
+            pmv.glLoadIdentity();
+            pmv.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
+            pmv.glLoadIdentity();
+            pmv.glTranslatef(5f, 6f, 7f);
+            pmv.glRotatef(90f, 1f, 0f, 0f);
+            
+            pmvMv = pmv.glGetMvMatrixf();
+            pmvMvi = pmv.glGetMviMatrixf();
+            pmvMvit = pmv.glGetMvitMatrixf();
+        }
+
+        final FloatBuffer glMv = FloatBuffer.allocate(16);
+        {
+            GL2ES1 gl = dc.glc.getGL().getGL2ES1();
+            gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
+            gl.glLoadIdentity();
+            gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
+            gl.glLoadIdentity();
+            gl.glTranslatef(5f, 6f, 7f);
+            gl.glRotatef(90f, 1f, 0f, 0f);
+            
+            gl.glGetFloatv(GLMatrixFunc.GL_MODELVIEW_MATRIX, glMv);
+        }
+        // System.err.println(PMVMatrix.matrixToString(null, "%10.5f", glMv, pmvMv).toString());
+        
+        MiscUtils.assertFloatBufferEquals("Arrays not equal, expected"+Platform.NEWLINE+PMVMatrix.matrixToString(null, "%10.5f", glMv).toString()+
+                ", actual"+Platform.NEWLINE+PMVMatrix.matrixToString(null, "%10.5f", pmvMv).toString(),
+                glMv, pmvMv, epsilon);
+        
+        // System.err.println("pmvMvi:  "+Platform.NEWLINE+PMVMatrix.matrixToString(null, "%10.5f", pmvMvi));
+        // System.err.println("pmvMvit: "+Platform.NEWLINE+PMVMatrix.matrixToString(null, "%10.5f", pmvMvit));        
+    }
+    
+    static DrawableContext dc;
+            
+    @BeforeClass
+    public static void setup() throws Throwable {
+        try {
+            dc = createOffscreenDrawableAndCurrentFFPContext();
+        } catch (Throwable t) {
+            setTestSupported(false);
+            throw t;
+        }
+    }
+
+    @AfterClass
+    public static void cleanup() {
+        destroyDrawableContext(dc);
+    }
+    
+    static class DrawableContext {
+        DrawableContext(GLDrawable d, GLContext glc) {
+            this.d = d;
+            this.glc = glc;
+        }
+        GLDrawable d;
+        GLContext glc;
+    }
+    
+    private static DrawableContext createOffscreenDrawableAndCurrentFFPContext() throws Throwable {
+        GLProfile glp = GLProfile.getMaxFixedFunc(true);
+        GLCapabilities glCaps = new GLCapabilities(glp);
+        glCaps.setOnscreen(false);
+        glCaps.setPBuffer(true);
+        GLDrawableFactory factory = GLDrawableFactory.getFactory(glp);
+        GLDrawable d = factory.createOffscreenDrawable(null, glCaps, null, 64, 64);
+        d.setRealized(true);
+        GLContext glc = null;
+        try {
+            glc = d.createContext(null);
+            Assert.assertTrue("Context could not be made current", GLContext.CONTEXT_NOT_CURRENT < glc.makeCurrent());
+            return new DrawableContext(d, glc);
+        } catch (Throwable t) {
+            if(null != glc) {
+                glc.destroy();
+            }
+            d.setRealized(false);
+            throw t;
+        }
+    }
+    
+    private static void destroyDrawableContext(DrawableContext dc) {
+        if(null != dc.glc) {
+            dc.glc.destroy();
+            dc.glc = null;
+        }
+        if(null != dc.d) {
+            dc.d.setRealized(false);
+            dc.d = null;
+        }
+    }
+    
+    public static void main(String args[]) {
+        org.junit.runner.JUnitCore.main(TestPMVMatrix01NEWT.class.getName());
+    }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPMVMatrix02NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPMVMatrix02NEWT.java
new file mode 100644
index 0000000..4e959d4
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPMVMatrix02NEWT.java
@@ -0,0 +1,109 @@
+/**
+ * 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.test.junit.jogl.acore;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.jogamp.opengl.util.PMVMatrix;
+
+import javax.media.opengl.fixedfunc.GLMatrixFunc;
+import java.nio.FloatBuffer;
+
+import static org.junit.Assert.assertArrayEquals;
+
+/**
+ * @author Thomas De Bodt
+ */
+public class TestPMVMatrix02NEWT {
+
+  private PMVMatrix fMat;
+
+  @Before
+  public void setUp() throws Exception {
+    fMat = new PMVMatrix();
+  }
+
+  @Test
+  public void testLookAtNegZIsNoOp() throws Exception {
+    fMat.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
+    // Look towards -z
+    fMat.gluLookAt(
+        0, 0, 0,
+        0, 0, -1,
+        0, 1, 0
+    );
+    FloatBuffer mvMatrix = fMat.glGetMvMatrixf();
+    float[] mvMatrixArr = new float[16];
+    mvMatrix.asReadOnlyBuffer().get(mvMatrixArr);
+    assertArrayEquals(
+        /**
+         * The 3 rows of the matrix (= the 3 columns of the array/buffer) should be: side, up, -forward.
+         */
+        new float[] {
+            1, 0, 0, 0,
+            0, 1, 0, 0,
+            0, 0, 1, 0,
+            0, 0, 0, 1
+        },
+        mvMatrixArr,
+        1e-6f
+    );
+  }
+  @Test
+  public void testLookAtPosY() throws Exception {
+    fMat.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
+    // Look towards +y
+    fMat.gluLookAt(
+        0, 0, 0,
+        0, 1, 0,
+        0, 0, 1
+    );
+    FloatBuffer mvMatrix = fMat.glGetMvMatrixf();
+    float[] mvMatrixArr = new float[16];
+    mvMatrix.asReadOnlyBuffer().get(mvMatrixArr);
+    assertArrayEquals(
+        /**
+         * The 3 rows of the matrix (= the 3 columns of the array/buffer) should be: side, up, -forward.
+         */
+        new float[] {
+            1, 0, 0, 0,
+            0, 0, -1, 0,
+            0, 1, 0, 0,
+            0, 0, 0, 1
+        },
+        mvMatrixArr,
+        1e-6f
+    );
+  }
+
+  public static void main(String args[]) {
+      org.junit.runner.JUnitCore.main(TestPMVMatrix02NEWT.class.getName());
+  }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPointsNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPointsNEWT.java
new file mode 100644
index 0000000..0ac75d4
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPointsNEWT.java
@@ -0,0 +1,156 @@
+/**
+ * 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 com.jogamp.opengl.test.junit.jogl.acore;
+
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+
+import com.jogamp.opengl.test.junit.jogl.demos.PointsDemo;
+import com.jogamp.opengl.test.junit.jogl.demos.es1.PointsDemoES1;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.PointsDemoES2;
+
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLProfile;
+
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.AfterClass;
+import org.junit.Test;
+
+public class TestPointsNEWT extends UITestCase {
+    static int width, height;
+
+    @BeforeClass
+    public static void initClass() {
+        width  = 512;
+        height = 512;
+    }
+
+    @AfterClass
+    public static void releaseClass() {
+    }
+
+    protected void runTestGL0(GLCapabilities caps, PointsDemo demo) throws InterruptedException {
+        GLWindow glWindow = GLWindow.create(caps);
+        Assert.assertNotNull(glWindow);
+        glWindow.setTitle(getSimpleTestName("."));
+
+        glWindow.addGLEventListener(demo);
+        final SnapshotGLEventListener snap = new SnapshotGLEventListener();
+        snap.setPostSNDetail(demo.getClass().getSimpleName());
+        glWindow.addGLEventListener(snap);
+
+        glWindow.setSize(width, height);
+        glWindow.setVisible(true);
+        
+        demo.setSmoothPoints(false);
+        snap.setMakeSnapshot();
+        snap.setPostSNDetail("flat");
+        glWindow.display();
+        
+        demo.setSmoothPoints(true);
+        snap.setMakeSnapshot();
+        snap.setPostSNDetail("smooth");
+        glWindow.display();
+        
+        demo.setPointParams(2f, 40f, 0.01f, 0.0f, 0.01f, 1f);        
+        snap.setMakeSnapshot();
+        snap.setPostSNDetail("attn0");
+        glWindow.display();
+        
+        glWindow.removeGLEventListener(demo);
+        
+        glWindow.destroy();
+    }
+    
+    protected void runTestGL(GLCapabilities caps, PointsDemo demo, boolean forceFFPEmu) throws InterruptedException {
+        // final PointsDemoES2 demo01 = new PointsDemoES2();
+        runTestGL0(caps, demo);        
+    }
+
+    @Test
+    public void test01FFP__GL2() throws InterruptedException {
+        if(!GLProfile.isAvailable(GLProfile.GL2)) { System.err.println("GL2 n/a"); return; }
+        GLCapabilities caps = new GLCapabilities(GLProfile.get(GLProfile.GL2));
+        runTestGL(caps, new PointsDemoES1(), false);
+    }
+    
+    @Test
+    public void test02FFP__ES1() throws InterruptedException {
+        if(!GLProfile.isAvailable(GLProfile.GLES1)) { System.err.println("GLES1 n/a"); return; }
+        GLCapabilities caps = new GLCapabilities(GLProfile.get(GLProfile.GLES1));
+        runTestGL(caps, new PointsDemoES1(), false);
+    }
+    
+    @Test
+    public void test03FFP__ES2() throws InterruptedException {
+        if(!GLProfile.isAvailable(GLProfile.GLES2)) { System.err.println("GLES2 n/a"); return; }
+        GLCapabilities caps = new GLCapabilities(GLProfile.get(GLProfile.GLES2));
+        PointsDemoES1 demo = new PointsDemoES1();
+        demo.setForceFFPEmu(true, false, false, false);
+        runTestGL(caps, demo, false);
+    }
+    
+    @Test
+    public void test04FFP__GL2ES2() throws InterruptedException {
+        if(!GLProfile.isAvailable(GLProfile.GL2ES2)) { System.err.println("GL2ES2 n/a"); return; }
+        GLCapabilities caps = new GLCapabilities(GLProfile.get(GLProfile.GL2ES2));
+        PointsDemoES1 demo = new PointsDemoES1();
+        demo.setForceFFPEmu(true, false, false, false);
+        runTestGL(caps, demo, false);
+    }
+    
+    @Test
+    public void test11GLSL_GL2() throws InterruptedException {
+        if(!GLProfile.isAvailable(GLProfile.GL2)) { System.err.println("GL2 n/a"); return; }
+        GLCapabilities caps = new GLCapabilities(GLProfile.get(GLProfile.GL2));
+        runTestGL(caps, new PointsDemoES2(), false);
+    }
+        
+    @Test
+    public void test12GLSL_ES2() throws InterruptedException {
+        if(!GLProfile.isAvailable(GLProfile.GLES2)) { System.err.println("GLES2 n/a"); return; }
+        GLCapabilities caps = new GLCapabilities(GLProfile.get(GLProfile.GLES2));
+        runTestGL(caps, new PointsDemoES2(), false); // should be FFPEmu implicit
+    }
+        
+    static long duration = 1000; // ms
+
+    public static void main(String args[]) {
+        for(int i=0; i<args.length; i++) {
+            if(args[i].equals("-time")) {
+                i++;
+                try {
+                    duration = Integer.parseInt(args[i]);
+                } catch (Exception ex) { ex.printStackTrace(); }
+            }
+        }
+        org.junit.runner.JUnitCore.main(TestPointsNEWT.class.getName());
+    }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListAWT.java
index 60502ba..67b70e1 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListAWT.java
@@ -30,11 +30,10 @@ package com.jogamp.opengl.test.junit.jogl.acore;
 
 import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLDrawableFactory;
-import javax.media.opengl.GLPbuffer;
+import javax.media.opengl.GLOffscreenAutoDrawable;
 import javax.media.opengl.GLProfile;
 import javax.media.opengl.awt.GLCanvas;
 
-import com.jogamp.common.os.Platform;
 import com.jogamp.opengl.util.Animator;
 
 import com.jogamp.opengl.test.junit.util.UITestCase;
@@ -53,17 +52,11 @@ public class TestSharedContextListAWT extends UITestCase {
     static GLProfile glp;
     static GLCapabilities caps;
     static int width, height;
-    GLPbuffer sharedDrawable;
+    GLOffscreenAutoDrawable sharedDrawable;
     Gears sharedGears;
 
     @BeforeClass
     public static void initClass() {
-        if(Platform.CPUFamily.X86 != Platform.CPU_ARCH.family) { // FIXME
-            // FIXME: Turns out on some mobile GL drivers and platforms 
-            // using shared context is instable, Linux ARM (Omap4, Tegra2, Mesa3d, ..)
-            setTestSupported(false);
-            return;
-        }
         if(GLProfile.isAvailable(GLProfile.GL2)) {
             glp = GLProfile.get(GLProfile.GL2);
             Assert.assertNotNull(glp);
@@ -77,7 +70,7 @@ public class TestSharedContextListAWT extends UITestCase {
     }
 
     private void initShared() {
-        sharedDrawable = GLDrawableFactory.getFactory(glp).createGLPbuffer(null, caps, null, width, height, null);
+        sharedDrawable = GLDrawableFactory.getFactory(glp).createOffscreenAutoDrawable(null, caps, null, width, height, null);
         Assert.assertNotNull(sharedDrawable);
         sharedGears = new Gears();
         Assert.assertNotNull(sharedGears);
@@ -159,10 +152,6 @@ public class TestSharedContextListAWT extends UITestCase {
         }
         animator.stop();
 
-        // here we go again: On AMD/X11 the create/destroy sequence must be the same
-        // even though this is agains the chicken/egg logic
-        releaseShared();
-
         try {
             javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
                 public void run() {
@@ -182,8 +171,7 @@ public class TestSharedContextListAWT extends UITestCase {
             Assume.assumeNoException( throwable );
         }                
         
-        // see above ..
-        //releaseShared();
+        releaseShared();
     }
 
     static long duration = 500; // ms
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListNEWT.java
index 39367d1..78c8fd0 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListNEWT.java
@@ -30,13 +30,12 @@ package com.jogamp.opengl.test.junit.jogl.acore;
 
 import java.io.IOException;
 
-import com.jogamp.common.os.Platform;
 import com.jogamp.newt.opengl.GLWindow;
 
 import javax.media.nativewindow.util.InsetsImmutable;
 import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLDrawableFactory;
-import javax.media.opengl.GLPbuffer;
+import javax.media.opengl.GLOffscreenAutoDrawable;
 import javax.media.opengl.GLProfile;
 import com.jogamp.opengl.util.Animator;
 
@@ -52,17 +51,11 @@ public class TestSharedContextListNEWT extends UITestCase {
     static GLProfile glp;
     static GLCapabilities caps;
     static int width, height;
-    GLPbuffer sharedDrawable;
+    GLOffscreenAutoDrawable sharedDrawable;
     Gears sharedGears;
 
     @BeforeClass
     public static void initClass() {
-        if(Platform.CPUFamily.X86 != Platform.CPU_ARCH.family) { // FIXME
-            // FIXME: Turns out on some mobile GL drivers and platforms 
-            // using shared context is instable, Linux ARM (Omap4, Tegra2, Mesa3d, ..)
-            setTestSupported(false);
-            return;
-        }
         if(GLProfile.isAvailable(GLProfile.GL2)) {
             glp = GLProfile.get(GLProfile.GL2);
             Assert.assertNotNull(glp);
@@ -76,7 +69,7 @@ public class TestSharedContextListNEWT extends UITestCase {
     }
 
     private void initShared() {
-        sharedDrawable = GLDrawableFactory.getFactory(glp).createGLPbuffer(null, caps, null, width, height, null);
+        sharedDrawable = GLDrawableFactory.getFactory(glp).createOffscreenAutoDrawable(null, caps, null, width, height, null);
         Assert.assertNotNull(sharedDrawable);
         sharedGears = new Gears();
         Assert.assertNotNull(sharedGears);
@@ -134,16 +127,11 @@ public class TestSharedContextListNEWT extends UITestCase {
         }
         animator.stop();
 
-        // here we go again: On AMD/X11 the create/destroy sequence must be the same
-        // even though this is against the chicken/egg logic here ..
-        releaseShared();
-
         f1.destroy();
         f2.destroy();
         f3.destroy();
 
-        // see above ..
-        // releaseShared();
+        releaseShared();
     }
 
     static long duration = 500; // ms
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListNEWT2.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListNEWT2.java
index 7dca314..7893c51 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListNEWT2.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListNEWT2.java
@@ -30,7 +30,6 @@ package com.jogamp.opengl.test.junit.jogl.acore;
 
 import java.io.IOException;
 
-import com.jogamp.common.os.Platform;
 import com.jogamp.newt.opengl.GLWindow;
 
 import javax.media.nativewindow.util.InsetsImmutable;
@@ -55,12 +54,6 @@ public class TestSharedContextListNEWT2 extends UITestCase {
 
     @BeforeClass
     public static void initClass() {
-        if(Platform.CPUFamily.X86 != Platform.CPU_ARCH.family) { // FIXME
-            // FIXME: Turns out on some mobile GL drivers and platforms 
-            // using shared context is instable, Linux ARM (Omap4, Tegra2, Mesa3d, ..)
-            setTestSupported(false);
-            return;
-        }
         if(GLProfile.isAvailable(GLProfile.GL2)) {
             glp = GLProfile.get(GLProfile.GL2);
             Assert.assertNotNull(glp);
@@ -135,16 +128,11 @@ public class TestSharedContextListNEWT2 extends UITestCase {
 			e.printStackTrace();
 		}
 
-        // here we go again: On AMD/X11 the create/destroy sequence must be the same
-        // even though this is against the chicken/egg logic here ..
-        releaseShared();
-
         f1.destroy();
         f2.destroy();
         f3.destroy();
 
-        // see above ..
-        // releaseShared();
+        releaseShared();
     }
 
     static long duration = 2000; // ms
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextNewtAWTBug523.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextNewtAWTBug523.java
index bc2eddb..7894f3e 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextNewtAWTBug523.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextNewtAWTBug523.java
@@ -45,7 +45,7 @@ import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLContext;
 import javax.media.opengl.GLDrawableFactory;
 import javax.media.opengl.GLEventListener;
-import javax.media.opengl.GLPbuffer;
+import javax.media.opengl.GLOffscreenAutoDrawable;
 import javax.media.opengl.GLProfile;
 import javax.media.opengl.awt.GLCanvas;
 import javax.media.opengl.glu.GLU;
@@ -64,7 +64,6 @@ import org.junit.BeforeClass;
 import org.junit.Test;
 
 import com.jogamp.common.nio.Buffers;
-import com.jogamp.common.os.Platform;
 import com.jogamp.newt.awt.NewtCanvasAWT;
 import com.jogamp.newt.opengl.GLWindow;
 import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
@@ -118,26 +117,20 @@ public class TestSharedContextNewtAWTBug523 extends UITestCase {
 
     @BeforeClass
     public static void initClass() {
-        if(Platform.CPUFamily.X86 != Platform.CPU_ARCH.family) { // FIXME
-            // FIXME: Turns out on some mobile GL drivers and platforms 
-            // using shared context is instable, Linux ARM (Omap4, Tegra2, Mesa3d, ..)
-            setTestSupported(false);
-            return;
-        }
         if(!GLProfile.isAvailable(GLProfile.GL2)) {
             setTestSupported(false);
         }
     }
     
-    static private GLPbuffer initShared(GLCapabilities caps) {
-        GLPbuffer sharedDrawable = GLDrawableFactory.getFactory(caps.getGLProfile()).createGLPbuffer(null, caps, null, 64, 64, null);
+    static private GLOffscreenAutoDrawable initShared(GLCapabilities caps) {
+        final GLOffscreenAutoDrawable sharedDrawable = GLDrawableFactory.getFactory(caps.getGLProfile()).createOffscreenAutoDrawable(null, caps, null, 64, 64, null);        
         Assert.assertNotNull(sharedDrawable);
         // init and render one frame, which will setup the Gears display lists
         sharedDrawable.display();
         return sharedDrawable;
     }
 
-    static private void releaseShared(GLPbuffer sharedDrawable) {
+    static private void releaseShared(GLOffscreenAutoDrawable sharedDrawable) {
         if(null != sharedDrawable) {
             sharedDrawable.destroy();
         }
@@ -522,7 +515,7 @@ public class TestSharedContextNewtAWTBug523 extends UITestCase {
         glCapabilities.setSampleBuffers(true);
         glCapabilities.setNumSamples(4);
 
-        final GLPbuffer sharedDrawable;
+        final GLOffscreenAutoDrawable sharedDrawable;
         final GLContext sharedContext; 
         if(shareContext) {
             sharedDrawable = initShared(glCapabilities);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES1NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES1NEWT.java
index 707bd5a..6f108d8 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES1NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES1NEWT.java
@@ -28,13 +28,12 @@
  
 package com.jogamp.opengl.test.junit.jogl.acore;
 
-import com.jogamp.common.os.Platform;
 import com.jogamp.newt.opengl.GLWindow;
 
 import javax.media.nativewindow.util.InsetsImmutable;
 import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLDrawableFactory;
-import javax.media.opengl.GLPbuffer;
+import javax.media.opengl.GLOffscreenAutoDrawable;
 import javax.media.opengl.GLProfile;
 import com.jogamp.opengl.util.Animator;
 
@@ -50,17 +49,11 @@ public class TestSharedContextVBOES1NEWT extends UITestCase {
     static GLProfile glp;
     static GLCapabilities caps;
     static int width, height;
-    GLPbuffer sharedDrawable;
+    GLOffscreenAutoDrawable sharedDrawable;
     GearsES1 sharedGears;
 
     @BeforeClass
     public static void initClass() {
-        if(Platform.CPUFamily.X86 != Platform.CPU_ARCH.family) { // FIXME
-            // FIXME: Turns out on some mobile GL drivers and platforms 
-            // using shared context is instable, Linux ARM (Omap4, Tegra2, Mesa3d, ..)
-            setTestSupported(false);
-            return;
-        }
         if(GLProfile.isAvailable(GLProfile.GL2ES1)) {
             glp = GLProfile.get(GLProfile.GL2ES1);
             Assert.assertNotNull(glp);
@@ -74,7 +67,7 @@ public class TestSharedContextVBOES1NEWT extends UITestCase {
     }
 
     private void initShared() {
-        sharedDrawable = GLDrawableFactory.getFactory(glp).createGLPbuffer(null, caps, null, width, height, null);
+        sharedDrawable = GLDrawableFactory.getFactory(glp).createOffscreenAutoDrawable(null, caps, null, width, height, null);        
         Assert.assertNotNull(sharedDrawable);
         sharedGears = new GearsES1();
         Assert.assertNotNull(sharedGears);
@@ -132,16 +125,11 @@ public class TestSharedContextVBOES1NEWT extends UITestCase {
         }
         animator.stop();
 
-        // here we go again: On AMD/X11 the create/destroy sequence must be the same
-        // even though this is agains the chicken/egg logic here ..
-        releaseShared();
-
         f1.destroy();
         f2.destroy();
         f3.destroy();
 
-        // see above ..
-        // releaseShared();
+        releaseShared();
     }
 
     static long duration = 500; // ms
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT.java
index ce2bd77..4aa977a 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT.java
@@ -29,12 +29,13 @@
 package com.jogamp.opengl.test.junit.jogl.acore;
 
 import com.jogamp.common.os.Platform;
+import com.jogamp.common.util.VersionNumber;
 import com.jogamp.newt.opengl.GLWindow;
 
 import javax.media.nativewindow.util.InsetsImmutable;
+import javax.media.opengl.GLAutoDrawable;
 import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLDrawableFactory;
-import javax.media.opengl.GLPbuffer;
 import javax.media.opengl.GLProfile;
 import com.jogamp.opengl.util.Animator;
 
@@ -50,17 +51,11 @@ public class TestSharedContextVBOES2NEWT extends UITestCase {
     static GLProfile glp;
     static GLCapabilities caps;
     static int width, height;
-    GLPbuffer sharedDrawable;
+    GLAutoDrawable sharedDrawable;
     GearsES2 sharedGears;
 
     @BeforeClass
     public static void initClass() {
-        if(Platform.CPUFamily.X86 != Platform.CPU_ARCH.family) { // FIXME
-            // FIXME: Turns out on some mobile GL drivers and platforms 
-            // using shared context is instable, Linux ARM (Omap4, Tegra2, Mesa3d, ..)
-            setTestSupported(false);
-            return;
-        }
         if(GLProfile.isAvailable(GLProfile.GL2ES2)) {
             glp = GLProfile.get(GLProfile.GL2ES2);
             Assert.assertNotNull(glp);
@@ -73,8 +68,16 @@ public class TestSharedContextVBOES2NEWT extends UITestCase {
         }
     }
 
-    private void initShared() {
-        sharedDrawable = GLDrawableFactory.getFactory(glp).createGLPbuffer(null, caps, null, width, height, null);
+    private void initShared(boolean onscreen) {
+        if(onscreen) {
+            GLWindow glWindow = GLWindow.create(caps);
+            Assert.assertNotNull(glWindow);
+            glWindow.setSize(width, height);
+            glWindow.setVisible(true);
+            sharedDrawable = glWindow;
+        } else {        
+            sharedDrawable = GLDrawableFactory.getFactory(glp).createOffscreenAutoDrawable(null, caps, null, width, height, null);
+        }
         Assert.assertNotNull(sharedDrawable);
         sharedGears = new GearsES2();
         Assert.assertNotNull(sharedGears);
@@ -86,6 +89,7 @@ public class TestSharedContextVBOES2NEWT extends UITestCase {
     private void releaseShared() {
         Assert.assertNotNull(sharedDrawable);
         sharedDrawable.destroy();
+        sharedDrawable = null;
     }
 
     protected GLWindow runTestGL(Animator animator, int x, int y, boolean useShared, boolean vsync) throws InterruptedException {
@@ -93,7 +97,7 @@ public class TestSharedContextVBOES2NEWT extends UITestCase {
         Assert.assertNotNull(glWindow);
         glWindow.setTitle("Shared Gears NEWT Test: "+x+"/"+y+" shared "+useShared);
         if(useShared) {
-            glWindow.setSharedContext(sharedDrawable.getContext());            
+            glWindow.setSharedContext(sharedDrawable.getContext());
         }
 
         glWindow.setSize(width, height);
@@ -105,46 +109,120 @@ public class TestSharedContextVBOES2NEWT extends UITestCase {
         glWindow.addGLEventListener(gears);
 
         animator.add(glWindow);
-
+        animator.start();        
         glWindow.setVisible(true);
         Assert.assertTrue(AWTRobotUtil.waitForRealized(glWindow, true));
         Assert.assertTrue(AWTRobotUtil.waitForVisible(glWindow, true));
-        
+
         glWindow.setPosition(x, y);
 
         return glWindow;
     }
 
     @Test
-    public void test01() throws InterruptedException {
-        initShared();
+    public void testCommonAnimatorSharedOnscreen() throws InterruptedException {
+        initShared(true);
         Animator animator = new Animator();
         GLWindow f1 = runTestGL(animator, 0, 0, true, false);
         InsetsImmutable insets = f1.getInsets();
         GLWindow f2 = runTestGL(animator, f1.getX()+width+insets.getTotalWidth(), 
                                           f1.getY()+0, true, false);
         GLWindow f3 = runTestGL(animator, f1.getX()+0, 
-                                          f1.getY()+height+insets.getTotalHeight(), false, true);
-        animator.setUpdateFPSFrames(1, null);        
-        animator.start();
-        while(animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
-            Thread.sleep(100);
+                                          f1.getY()+height+insets.getTotalHeight(), true, false);
+        try {
+            Thread.sleep(duration);
+        } catch(Exception e) {
+            e.printStackTrace();
         }
         animator.stop();
 
-        // here we go again: On AMD/X11 the create/destroy sequence must be the same
-        // even though this is agains the chicken/egg logic here ..
+        f1.destroy();
+        f2.destroy();
+        f3.destroy();
+        Assert.assertTrue(AWTRobotUtil.waitForVisible(f1, false));
+        Assert.assertTrue(AWTRobotUtil.waitForRealized(f1, false));
+        Assert.assertTrue(AWTRobotUtil.waitForVisible(f2, false));
+        Assert.assertTrue(AWTRobotUtil.waitForRealized(f2, false));
+        Assert.assertTrue(AWTRobotUtil.waitForVisible(f3, false));
+        Assert.assertTrue(AWTRobotUtil.waitForRealized(f3, false));
+
         releaseShared();
+    }
+
+    @Test
+    public void testCommonAnimatorSharedOffscreen() throws InterruptedException {
+        initShared(false);
+        Animator animator = new Animator();
+        GLWindow f1 = runTestGL(animator, 0, 0, true, false);
+        InsetsImmutable insets = f1.getInsets();
+        GLWindow f2 = runTestGL(animator, f1.getX()+width+insets.getTotalWidth(), 
+                                          f1.getY()+0, true, false);
+        GLWindow f3 = runTestGL(animator, f1.getX()+0, 
+                                          f1.getY()+height+insets.getTotalHeight(), true, false);
+        try {
+            Thread.sleep(duration);
+        } catch(Exception e) {
+            e.printStackTrace();
+        }
+        animator.stop();
 
         f1.destroy();
         f2.destroy();
         f3.destroy();
+        Assert.assertTrue(AWTRobotUtil.waitForVisible(f1, false));
+        Assert.assertTrue(AWTRobotUtil.waitForRealized(f1, false));
+        Assert.assertTrue(AWTRobotUtil.waitForVisible(f2, false));
+        Assert.assertTrue(AWTRobotUtil.waitForRealized(f2, false));
+        Assert.assertTrue(AWTRobotUtil.waitForVisible(f3, false));
+        Assert.assertTrue(AWTRobotUtil.waitForRealized(f3, false));
 
-        // see above ..
-        // releaseShared();
+        releaseShared();
     }
+    
+    @Test
+    public void testEachWithAnimatorSharedOffscreen() throws InterruptedException {
+        VersionNumber osx1070 = new VersionNumber(10,7,0);
+        if( Platform.getOSType() == Platform.OSType.MACOS && Platform.getOSVersionNumber().compareTo(osx1070) > 0 ) {
+            // instable on OSX .. driver/OS bug when multi threading (3 animator)
+            System.err.println("Shared context w/ 3 context each running in there own thread is instable here on OSX 10.7.4/NVidia,");
+            System.err.println("SIGSEGV @ glDrawArrays / glBindBuffer .. any shared VBO.");
+            System.err.println("Seems to run fine on 10.6.8/NVidia.");
+            return;
+        }
+        initShared(false);
+        Animator animator1 = new Animator();
+        Animator animator2 = new Animator();
+        Animator animator3 = new Animator();
+        GLWindow f1 = runTestGL(animator1, 0, 0, true, false);
+        InsetsImmutable insets = f1.getInsets();
+        GLWindow f2 = runTestGL(animator2, f1.getX()+width+insets.getTotalWidth(), 
+                                f1.getY()+0, true, false);
+        GLWindow f3 = runTestGL(animator3, f1.getX()+0, 
+                                f1.getY()+height+insets.getTotalHeight(), true, false);
+
+        try {
+            Thread.sleep(duration);
+        } catch(Exception e) {
+            e.printStackTrace();
+        }
+        animator1.stop();
+        animator2.stop();
+        animator3.stop();
+
+        f1.destroy();
+        f2.destroy();
+        f3.destroy();
+        Assert.assertTrue(AWTRobotUtil.waitForVisible(f1, false));
+        Assert.assertTrue(AWTRobotUtil.waitForRealized(f1, false));
+        Assert.assertTrue(AWTRobotUtil.waitForVisible(f2, false));
+        Assert.assertTrue(AWTRobotUtil.waitForRealized(f2, false));
+        Assert.assertTrue(AWTRobotUtil.waitForVisible(f3, false));
+        Assert.assertTrue(AWTRobotUtil.waitForRealized(f3, false));
 
-    static long duration = 500; // ms
+        releaseShared();
+    }
+    
+    static long duration = 2000; // ms
 
     public static void main(String args[]) {
         for(int i=0; i<args.length; i++) {
@@ -155,6 +233,10 @@ public class TestSharedContextVBOES2NEWT extends UITestCase {
                 } catch (Exception ex) { ex.printStackTrace(); }
             }
         }
+        /**
+        BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
+        System.err.println("Press enter to continue");
+        System.err.println(stdin.readLine()); */         
         org.junit.runner.JUnitCore.main(TestSharedContextVBOES2NEWT.class.getName());
     }
 }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT2.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT2.java
deleted file mode 100644
index 8911e73..0000000
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT2.java
+++ /dev/null
@@ -1,168 +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.acore;
-
-import java.io.IOException;
-
-import com.jogamp.common.os.Platform;
-import com.jogamp.newt.opengl.GLWindow;
-
-import javax.media.nativewindow.util.InsetsImmutable;
-import javax.media.opengl.GLCapabilities;
-import javax.media.opengl.GLProfile;
-import com.jogamp.opengl.util.Animator;
-
-import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
-import com.jogamp.opengl.test.junit.util.UITestCase;
-import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
-
-import org.junit.Assert;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-public class TestSharedContextVBOES2NEWT2 extends UITestCase {
-    static GLProfile glp;
-    static GLCapabilities caps;
-    static int width, height;
-    GLWindow sharedDrawable;
-    GearsES2 sharedGears;
-
-    @BeforeClass
-    public static void initClass() {
-        if(Platform.CPUFamily.X86 != Platform.CPU_ARCH.family) { // FIXME
-            // FIXME: Turns out on some mobile GL drivers and platforms 
-            // using shared context is instable, Linux ARM (Omap4, Tegra2, Mesa3d, ..)
-            setTestSupported(false);
-            return;
-        }
-        if(GLProfile.isAvailable(GLProfile.GL2ES2)) {
-            glp = GLProfile.get(GLProfile.GL2ES2);
-            Assert.assertNotNull(glp);
-            caps = new GLCapabilities(glp);
-            Assert.assertNotNull(caps);
-            width  = 256;
-            height = 256;
-        } else {
-            setTestSupported(false);
-        }
-    }
-
-    private void initShared() {
-    	sharedDrawable = GLWindow.create(caps);
-        Assert.assertNotNull(sharedDrawable);
-        // sharedGears = new Gears(0);
-        sharedGears = new GearsES2(0);
-        Assert.assertNotNull(sharedGears);
-        sharedDrawable.addGLEventListener(sharedGears);
-        sharedDrawable.setSize(width, height);
-        sharedDrawable.setVisible(true);
-        // init and render one frame, which will setup the Gears display lists
-        sharedDrawable.display();
-    }
-
-    private void releaseShared() {
-        Assert.assertNotNull(sharedDrawable);
-        sharedDrawable.destroy();
-        sharedDrawable = null;
-    }
-
-    protected GLWindow runTestGL(Animator animator, int x, int y, boolean useShared, boolean vsync) throws InterruptedException {
-        GLWindow glWindow = GLWindow.create(caps);
-        
-        Assert.assertNotNull(glWindow);
-        glWindow.setTitle("Shared Gears NEWT Test: "+x+"/"+y+" shared "+useShared);
-        if(useShared) {
-            glWindow.setSharedContext(sharedDrawable.getContext());
-        }
-
-        glWindow.setSize(width, height);
-
-        GearsES2 gears = new GearsES2(vsync ? 1 : 0);
-        if(useShared) {
-            gears.setGears(sharedGears.getGear1(), sharedGears.getGear2(), sharedGears.getGear3());
-        }
-        glWindow.addGLEventListener(gears);
-
-        animator.add(glWindow);
-        animator.start();
-        glWindow.setVisible(true);
-
-        Assert.assertTrue(AWTRobotUtil.waitForRealized(glWindow, true));
-        Assert.assertTrue(AWTRobotUtil.waitForVisible(glWindow, true));
-        glWindow.setPosition(x, y);
-        
-        return glWindow;
-    }
-
-    @Test
-    public void test01() throws InterruptedException {
-        initShared();
-        GLWindow f1 = runTestGL(new Animator(), 0, 0, true, false);
-        InsetsImmutable insets = f1.getInsets();
-        GLWindow f2 = runTestGL(new Animator(), f1.getX()+width+insets.getTotalWidth(), 
-                                f1.getY()+0, true, false);
-        GLWindow f3 = runTestGL(new Animator(), f1.getX()+0, 
-                                f1.getY()+height+insets.getTotalHeight(), true, false);
-
-        try {
-			Thread.sleep(duration);
-		} catch(Exception e) {
-			e.printStackTrace();
-		}
-
-        // here we go again: On AMD/X11 the create/destroy sequence must be the same
-        // even though this is against the chicken/egg logic here ..
-        releaseShared();
-
-        f1.destroy();
-        f2.destroy();
-        f3.destroy();
-
-        // see above ..
-        // releaseShared();
-    }
-
-    static long duration = 2000; // ms
-
-    public static void main(String args[]) throws IOException {
-        for(int i=0; i<args.length; i++) {
-            if(args[i].equals("-time")) {
-                i++;
-                try {
-                    duration = Integer.parseInt(args[i]);
-                } catch (Exception ex) { ex.printStackTrace(); }
-            }
-        }
-        /**
-        BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
-        System.err.println("Press enter to continue");
-        System.err.println(stdin.readLine()); */         
-        org.junit.runner.JUnitCore.main(TestSharedContextVBOES2NEWT2.class.getName());
-    }
-}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteAWT.java
index 9f2820a..976885d 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteAWT.java
@@ -93,12 +93,12 @@ public class TestShutdownCompleteAWT extends UITestCase {
         long t1 = System.nanoTime();
         runTestGL();        
         long t2 = System.nanoTime();
-        GLProfile.shutdown(GLProfile.ShutdownType.COMPLETE);        
+        GLProfile.shutdown();        
         long t3 = System.nanoTime();
         System.err.println("Total:                          "+ (t3-t0)/1e6 +"ms"); 
         System.err.println("  GLProfile.initSingleton():    "+ (t1-t0)/1e6 +"ms"); 
         System.err.println("  Demo Code:                    "+ (t2-t1)/1e6 +"ms"); 
-        System.err.println("  GLProfile.shutdown(COMPLETE): "+ (t3-t2)/1e6 +"ms"); 
+        System.err.println("  GLProfile.shutdown():         "+ (t3-t2)/1e6 +"ms"); 
     }
     
     @Test
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteNEWT.java
index b21ad5b..f376cd6 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteNEWT.java
@@ -48,8 +48,12 @@ public class TestShutdownCompleteNEWT extends UITestCase {
 
     static long duration = 300; // ms
     
-    protected void runTestGL() throws InterruptedException {
-        GLWindow glWindow = GLWindow.create(new GLCapabilities(GLProfile.getGL2ES2()));
+    protected void runTestGL(boolean onscreen) throws InterruptedException {
+        GLCapabilities caps = new GLCapabilities(GLProfile.getGL2ES2());
+        caps.setOnscreen(onscreen);
+        caps.setPBuffer(!onscreen);
+        
+        GLWindow glWindow = GLWindow.create(caps);
         Assert.assertNotNull(glWindow);
         glWindow.setTitle("Gears NEWT Test");
 
@@ -82,19 +86,19 @@ public class TestShutdownCompleteNEWT extends UITestCase {
         GLProfile.initSingleton();
         long t1 = System.nanoTime();
         if(!initOnly) {
-            runTestGL();
+            runTestGL(true);
         }
         long t2 = System.nanoTime();
         if(glInfo) {
             System.err.println(JoglVersion.getDefaultOpenGLInfo(null, null, false).toString());
         }
         long t3 = System.nanoTime();        
-        GLProfile.shutdown(GLProfile.ShutdownType.COMPLETE);        
+        GLProfile.shutdown();        
         long t4 = System.nanoTime();
         System.err.println("Total:                          "+ (t3-t0)/1e6 +"ms"); 
         System.err.println("  GLProfile.initSingleton():    "+ (t1-t0)/1e6 +"ms"); 
         System.err.println("  Demo Code:                    "+ (t2-t1)/1e6 +"ms"); 
-        System.err.println("  GLProfile.shutdown(COMPLETE): "+ (t4-t3)/1e6 +"ms"); 
+        System.err.println("  GLProfile.shutdown():         "+ (t4-t3)/1e6 +"ms"); 
     }
     
     @Test
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownSharedAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownSharedAWT.java
deleted file mode 100644
index 3274ea8..0000000
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownSharedAWT.java
+++ /dev/null
@@ -1,124 +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.acore;
-
-import java.awt.Frame;
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-
-import javax.media.opengl.GLCapabilities;
-import javax.media.opengl.GLProfile;
-import javax.media.opengl.awt.GLCanvas;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
-import com.jogamp.opengl.test.junit.util.UITestCase;
-import com.jogamp.opengl.util.Animator;
-
-public class TestShutdownSharedAWT extends UITestCase {
-
-    static long duration = 300; // ms
-    
-    protected void runTestGL() throws InterruptedException, InvocationTargetException {
-        final Frame frame = new Frame("Gears AWT Test");
-        Assert.assertNotNull(frame);
-
-        final GLCanvas glCanvas = new GLCanvas(new GLCapabilities(GLProfile.getGL2ES2()));
-        Assert.assertNotNull(glCanvas);
-        frame.add(glCanvas);
-        frame.setSize(256, 256);
-
-        glCanvas.addGLEventListener(new GearsES2(1));
-
-        Animator animator = new Animator(glCanvas);
-
-        javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
-            public void run() {
-                frame.setVisible(true);
-            }});
-        animator.setUpdateFPSFrames(60, System.err);        
-        animator.start();
-        Assert.assertEquals(true, animator.isAnimating());
-        Assert.assertEquals(true, glCanvas.isVisible());
-        Assert.assertEquals(true, glCanvas.isDisplayable());
-
-        while(animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
-            Thread.sleep(100);
-        }
-        Assert.assertEquals(true, glCanvas.isRealized());
-
-        animator.stop();
-        Assert.assertEquals(false, animator.isAnimating());
-        frame.setVisible(false);
-        Assert.assertEquals(false, frame.isVisible());
-        javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
-            public void run() {
-                frame.remove(glCanvas);
-                frame.dispose();
-            }});
-    }
-
-    protected void oneLife() throws InterruptedException, InvocationTargetException {
-        long t0 = System.nanoTime();
-        GLProfile.initSingleton();
-        long t1 = System.nanoTime();
-        runTestGL();        
-        long t2 = System.nanoTime();
-        GLProfile.shutdown(GLProfile.ShutdownType.SHARED_ONLY);        
-        long t3 = System.nanoTime();
-        System.err.println("Total:                          "+ (t3-t0)/1e6 +"ms"); 
-        System.err.println("  GLProfile.initSingleton():    "+ (t1-t0)/1e6 +"ms"); 
-        System.err.println("  Demo Code:                    "+ (t2-t1)/1e6 +"ms"); 
-        System.err.println("  GLProfile.shutdown(SHARED):   "+ (t3-t2)/1e6 +"ms"); 
-    }
-    
-    @Test
-    public void test01OneLife() throws InterruptedException, InvocationTargetException {
-        oneLife();
-    }
-
-    @Test
-    public void test01AnotherLife() throws InterruptedException, InvocationTargetException {
-        oneLife();
-    }
-    
-    @Test
-    public void test01TwoLifes() throws InterruptedException, InvocationTargetException {
-        oneLife();
-        oneLife();
-    }
-    
-    public static void main(String args[]) throws IOException {
-        String tstname = TestShutdownSharedAWT.class.getName();
-        org.junit.runner.JUnitCore.main(tstname);
-    }
-
-}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownSharedNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownSharedNEWT.java
deleted file mode 100644
index 8db7dff..0000000
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownSharedNEWT.java
+++ /dev/null
@@ -1,127 +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.acore;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-
-import javax.media.opengl.GLCapabilities;
-import javax.media.opengl.GLProfile;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-import com.jogamp.newt.opengl.GLWindow;
-import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
-import com.jogamp.opengl.test.junit.util.UITestCase;
-import com.jogamp.opengl.util.Animator;
-
-public class TestShutdownSharedNEWT extends UITestCase {
-
-    static long duration = 300; // ms
-    
-    protected void runTestGL() throws InterruptedException {
-        GLWindow glWindow = GLWindow.create(new GLCapabilities(GLProfile.getGL2ES2()));
-        Assert.assertNotNull(glWindow);
-        glWindow.setTitle("Gears NEWT Test");
-
-        glWindow.addGLEventListener(new GearsES2());
-
-        Animator animator = new Animator(glWindow);
-
-        glWindow.setSize(256, 256);
-        glWindow.setVisible(true);
-        animator.setUpdateFPSFrames(60, System.err);
-        animator.start();
-        Assert.assertEquals(true, animator.isAnimating());
-        Assert.assertEquals(true, glWindow.isVisible());
-        Assert.assertEquals(true, glWindow.isNativeValid());
-        Assert.assertEquals(true, glWindow.isRealized());
-
-        while(animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
-            Thread.sleep(100);
-        }
-
-        animator.stop();
-        glWindow.destroy();
-    }
-
-    protected void oneLife() throws InterruptedException {
-        long t0 = System.nanoTime();
-        GLProfile.initSingleton();
-        long t1 = System.nanoTime();
-        runTestGL();        
-        long t2 = System.nanoTime();
-        GLProfile.shutdown(GLProfile.ShutdownType.SHARED_ONLY);        
-        long t3 = System.nanoTime();
-        System.err.println("Total:                          "+ (t3-t0)/1e6 +"ms"); 
-        System.err.println("  GLProfile.initSingleton():    "+ (t1-t0)/1e6 +"ms"); 
-        System.err.println("  Demo Code:                    "+ (t2-t1)/1e6 +"ms"); 
-        System.err.println("  GLProfile.shutdown(SHARED):   "+ (t3-t2)/1e6 +"ms"); 
-    }
-    
-    @Test
-    public void test01OneLife() throws InterruptedException {
-        oneLife();
-    }
-
-    @Test
-    public void test01AnotherLife() throws InterruptedException {
-        oneLife();
-    }
-    
-    @Test
-    public void test01TwoLifes() throws InterruptedException {
-        oneLife();
-        oneLife();
-    }
-    
-    public static void main(String args[]) throws IOException {
-        boolean waitForKey = false;
-        
-        for(int i=0; i<args.length; i++) {
-            if(args[i].equals("-wait")) {
-                waitForKey = true;
-            }
-        }
-        
-        if(waitForKey) {
-            BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
-            System.err.println("Press enter to continue");
-            try {
-                System.err.println(stdin.readLine());
-            } catch (IOException e) { }
-        }
-        
-        String tstname = TestShutdownSharedNEWT.class.getName();
-        org.junit.runner.JUnitCore.main(tstname);
-    }
-
-}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestAWT01GLn.java b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestAWT01GLn.java
index 64a1a01..e1048c2 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestAWT01GLn.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestAWT01GLn.java
@@ -40,49 +40,23 @@ import java.awt.Frame;
 
 import org.junit.Assert;
 import org.junit.Assume;
-import org.junit.Before;
 import org.junit.BeforeClass;
-import org.junit.After;
 import org.junit.Test;
 
 
 public class TestAWT01GLn extends UITestCase {
-    Frame frame=null;
-    GLCanvas glCanvas=null;
-
     @BeforeClass
     public static void startup() {
         System.out.println("GLProfile "+GLProfile.glAvailabilityToString());
     }
 
-    @Before
-    public void init() {
-        frame = new Frame("Texture Test");
-        Assert.assertNotNull(frame);
-    }
-
-    @After
-    public void release() {
-        Assert.assertNotNull(frame);
-        Assert.assertNotNull(glCanvas);
-        try {
-            javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
-                public void run() {
-                    frame.setVisible(false);
-                    frame.remove(glCanvas);
-                    frame.dispose();
-                }});
-        } catch (Throwable t) {
-            t.printStackTrace();
-            Assume.assumeNoException(t);
-        }
-        frame=null;
-        glCanvas=null;
-    }
-
     protected void runTestGL(GLCapabilities caps) throws InterruptedException {
-        glCanvas = new GLCanvas(caps);
+        final Frame frame = new Frame("Texture Test");
+        Assert.assertNotNull(frame);
+        
+        final GLCanvas glCanvas = new GLCanvas(caps);
         Assert.assertNotNull(glCanvas);
+        
         glCanvas.addGLEventListener(new GearsES2());
         frame.add(glCanvas);
 
@@ -110,6 +84,18 @@ public class TestAWT01GLn extends UITestCase {
         Thread.sleep(500); // 500 ms
 
         animator.stop();
+        
+        try {
+            javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+                public void run() {
+                    frame.setVisible(false);
+                    frame.remove(glCanvas);
+                    frame.dispose();
+                }});
+        } catch (Throwable t) {
+            t.printStackTrace();
+            Assume.assumeNoException(t);
+        }
     }
 
     @Test
@@ -136,6 +122,18 @@ public class TestAWT01GLn extends UITestCase {
         }
     }
 
+    @Test
+    public void test02ES2() throws InterruptedException {
+        if(GLProfile.isAvailable(GLProfile.GLES2)) {
+            GLProfile glprofile = GLProfile.get(GLProfile.GLES2);
+            System.out.println( "GLProfile GLES2: " + glprofile );
+            GLCapabilities caps = new GLCapabilities(glprofile);
+            runTestGL(caps);
+        } else {
+            System.out.println("GLES2 n/a");
+        }
+    }
+    
     public static void main(String args[]) {
         org.junit.runner.JUnitCore.main(TestAWT01GLn.class.getName());
     }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug461OffscreenSupersamplingSwingAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug461FBOSupersamplingSwingAWT.java
similarity index 92%
copy from src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug461OffscreenSupersamplingSwingAWT.java
copy to src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug461FBOSupersamplingSwingAWT.java
index 6a315c6..42949af 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug461OffscreenSupersamplingSwingAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug461FBOSupersamplingSwingAWT.java
@@ -40,7 +40,7 @@ import javax.media.opengl.GLAutoDrawable;
 import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLDrawableFactory;
 import javax.media.opengl.GLEventListener;
-import javax.media.opengl.GLPbuffer;
+import javax.media.opengl.GLOffscreenAutoDrawable;
 import javax.media.opengl.GLProfile;
 import javax.swing.ImageIcon;
 import javax.swing.JFrame;
@@ -57,9 +57,10 @@ import com.jogamp.opengl.test.junit.util.UITestCase;
  *
  * @author Wade Walker (from code sample provided by Owen Dimond)
  */
-public class TestBug461OffscreenSupersamplingSwingAWT extends UITestCase implements GLEventListener {
+ at SuppressWarnings("deprecation")
+public class TestBug461FBOSupersamplingSwingAWT extends UITestCase implements GLEventListener {
     JFrame jframe;
-    GLPbuffer offScreenBuffer;
+    GLOffscreenAutoDrawable offScreenBuffer;
     
     private void render(GLAutoDrawable drawable) {
         GL2 gl = drawable.getGL().getGL2();
@@ -140,7 +141,7 @@ public class TestBug461OffscreenSupersamplingSwingAWT extends UITestCase impleme
         glCap.setStencilBits(1);
 
         //makes a new buffer
-        offScreenBuffer = fac.createGLPbuffer(GLProfile.getDefaultDevice(), glCap, null, 200, 200, null);
+        offScreenBuffer = fac.createOffscreenAutoDrawable(GLProfile.getDefaultDevice(), glCap, null, 200, 200, null);
         Assert.assertNotNull(offScreenBuffer);
         offScreenBuffer.addGLEventListener(this);        
         offScreenBuffer.display();
@@ -148,10 +149,11 @@ public class TestBug461OffscreenSupersamplingSwingAWT extends UITestCase impleme
             public void run() {
                 jframe.setVisible(true);
             }});
+        offScreenBuffer.destroy();
     }
 
     public static void main(String args[]) {
-        org.junit.runner.JUnitCore.main(TestBug461OffscreenSupersamplingSwingAWT.class.getName());
+        org.junit.runner.JUnitCore.main(TestBug461FBOSupersamplingSwingAWT.class.getName());
     }
 }
 
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug461OffscreenSupersamplingSwingAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug461PBufferSupersamplingSwingAWT.java
similarity index 95%
rename from src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug461OffscreenSupersamplingSwingAWT.java
rename to src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug461PBufferSupersamplingSwingAWT.java
index 6a315c6..5b7052c 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug461OffscreenSupersamplingSwingAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug461PBufferSupersamplingSwingAWT.java
@@ -57,7 +57,8 @@ import com.jogamp.opengl.test.junit.util.UITestCase;
  *
  * @author Wade Walker (from code sample provided by Owen Dimond)
  */
-public class TestBug461OffscreenSupersamplingSwingAWT extends UITestCase implements GLEventListener {
+ at SuppressWarnings("deprecation")
+public class TestBug461PBufferSupersamplingSwingAWT extends UITestCase implements GLEventListener {
     JFrame jframe;
     GLPbuffer offScreenBuffer;
     
@@ -148,10 +149,11 @@ public class TestBug461OffscreenSupersamplingSwingAWT extends UITestCase impleme
             public void run() {
                 jframe.setVisible(true);
             }});
+        offScreenBuffer.destroy();
     }
 
     public static void main(String args[]) {
-        org.junit.runner.JUnitCore.main(TestBug461OffscreenSupersamplingSwingAWT.class.getName());
+        org.junit.runner.JUnitCore.main(TestBug461PBufferSupersamplingSwingAWT.class.getName());
     }
 }
 
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug572AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug572AWT.java
new file mode 100644
index 0000000..b3abc41
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug572AWT.java
@@ -0,0 +1,127 @@
+/**
+ * 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.test.junit.jogl.awt;
+
+import java.awt.Window;
+import java.lang.reflect.InvocationTargetException;
+
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLProfile;
+import javax.media.opengl.awt.GLCanvas;
+import javax.swing.JFrame;
+import javax.swing.SwingUtilities;
+
+import junit.framework.Assert;
+
+import org.junit.Assume;
+import org.junit.Test;
+
+import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+
+/**
+ * Tests context creation + display on various kinds of Window implementations.
+ */
+public class TestBug572AWT extends UITestCase {
+
+    protected void runTestGL() throws InterruptedException, InvocationTargetException {
+        final Window window = new JFrame(this.getSimpleTestName(" - "));
+        final GLCapabilities caps = new GLCapabilities(GLProfile.getGL2ES2());        
+        final GLCanvas glCanvas = new GLCanvas(caps);
+        final SnapshotGLEventListener snapshooter = new SnapshotGLEventListener();
+        snapshooter.setMakeSnapshotAlways(true);
+        glCanvas.addGLEventListener(new GearsES2());
+        glCanvas.addGLEventListener(snapshooter);
+        window.add(glCanvas);
+
+        // Revalidate size/layout.
+        // Always validate if component added/removed.
+        // Ensure 1st paint of GLCanvas will have a valid size, hence drawable gets created.
+        window.setSize(512, 512);
+        window.validate();
+
+        window.setVisible(true);
+        System.err.println("XXXX-0 "+glCanvas.getDelegatedDrawable().isRealized()+", "+glCanvas);
+        
+        // Immediately displayable after issuing initial setVisible(true) .. even not within AWT-EDT ?
+        Assert.assertTrue("GLCanvas didn't become displayable", glCanvas.isDisplayable());
+        Assert.assertTrue("GLCanvas didn't become realized", glCanvas.isRealized());
+        
+        // Would be required if not immediately displayable ...   
+        // Assert.assertTrue("GLCanvas didn't become displayable and realized", AWTRobotUtil.waitForRealized(glCanvas, true));
+        // System.err.println("XXXX-1 "+glCanvas.getDelegatedDrawable().isRealized()+", "+glCanvas);
+        
+        // The AWT-EDT reshape/repaint events happen offthread later ..
+        System.err.println("XXXX-1 reshapeCount "+snapshooter.getReshapeCount());
+        System.err.println("XXXX-1 displayCount "+snapshooter.getDisplayCount());
+        
+        // Wait unitl AWT-EDT has issued reshape/repaint
+        for (int wait=0; wait<AWTRobotUtil.POLL_DIVIDER &&
+                         ( 0 == snapshooter.getReshapeCount() || 0 == snapshooter.getDisplayCount() ); 
+             wait++) {
+            Thread.sleep(AWTRobotUtil.TIME_SLICE);
+        }
+        System.err.println("XXXX-2 reshapeCount "+snapshooter.getReshapeCount());
+        System.err.println("XXXX-2 displayCount "+snapshooter.getDisplayCount());
+        
+        Assert.assertTrue("GLCanvas didn't reshape", snapshooter.getReshapeCount()>0);
+        Assert.assertTrue("GLCanvas didn't display", snapshooter.getDisplayCount()>0);
+        
+        // After initial 'setVisible(true)' all AWT manipulation needs to be done
+        // via the AWT EDT, according to the AWT spec.
+
+        Runnable cleanup = new Runnable() {
+            public void run() {
+                System.err.println("cleaning up...");
+                window.setVisible(false);
+                try {
+                    window.removeAll();
+                } catch (Throwable t) {
+                    Assume.assumeNoException(t);
+                    t.printStackTrace();
+                }
+                window.dispose();
+            }
+
+        };
+
+        // AWT / Swing on EDT..
+        SwingUtilities.invokeAndWait(cleanup);
+    }
+
+    @Test
+    public void test01() throws InterruptedException, InvocationTargetException {
+        runTestGL();
+    }
+
+    public static void main(String args[]) {
+        org.junit.runner.JUnitCore.main(TestBug572AWT.class.getName());
+    }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug611AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug611AWT.java
new file mode 100644
index 0000000..b6a7639
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug611AWT.java
@@ -0,0 +1,81 @@
+
+package com.jogamp.opengl.test.junit.jogl.awt;
+
+import java.awt.Desktop;
+import java.io.File;
+
+import javax.media.opengl.GLProfile;
+
+import org.junit.Test;
+
+import com.jogamp.common.os.Platform;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+
+/**
+ * As reported in Bug 611, on Windows XP is a performance issue:
+ * After JOGL initialization there seems to be a huge time lag 
+ * when trying to open the Desktop folder.
+ * <p>
+ * Test disabled since showing the Desktop folder will
+ * disturb the 'desktop' .. if there is another way to show 
+ * the performance bug, pls do so.
+ * </p>
+ * <p>
+ * Since Windows XP is out of life .. we may not care ..
+ * </p> 
+ */
+public class TestBug611AWT extends UITestCase {
+    
+    @Test
+    public void test00() {
+        // make junit happy 
+    }
+    
+    // @Test
+    public void test01() {
+        try {
+            // System.setProperty("jogamp.gluegen.UseTempJarCache", "false");
+            GLProfile.initSingleton();
+            Desktop desktop;
+            if (Desktop.isDesktopSupported()) {
+                desktop = Desktop.getDesktop();
+            } else {
+                desktop = null;
+            }
+            if(null != desktop) {
+                String home = System.getProperty("user.home");
+                File homeFolder = null;
+                if(null != home) {
+                    {
+                        File tst = new File(home + "/Desktop");
+                        if( tst.canRead() ) {
+                            homeFolder = tst;
+                        }
+                    }
+                    if(null == homeFolder) {
+                        File tst = new File(home);
+                        if( tst.canRead() ) {
+                            homeFolder = tst;
+                        }
+                    }
+                }
+                if(null == homeFolder) {
+                    if(Platform.getOSType() == Platform.OSType.WINDOWS) {
+                        homeFolder = new File("c:\\");
+                    } else {
+                        homeFolder = new File("/");
+                    }
+                }
+                if(null != homeFolder) {
+                    desktop.open(homeFolder);
+                }
+            }
+        } catch(Exception ex) {
+            ex.printStackTrace();
+        }
+    }
+    
+    public static void main(String args[]) {
+        org.junit.runner.JUnitCore.main(TestBug611AWT.class.getName());
+    }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestJScrollPaneMixHwLw01AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestJScrollPaneMixHwLw01AWT.java
new file mode 100644
index 0000000..bb525c9
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestJScrollPaneMixHwLw01AWT.java
@@ -0,0 +1,172 @@
+package com.jogamp.opengl.test.junit.jogl.awt;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.GraphicsConfiguration;
+import java.awt.Rectangle;
+import java.awt.ScrollPane;
+import java.awt.Shape;
+import java.io.IOException;
+
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLProfile;
+import javax.media.opengl.awt.GLCanvas;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.WindowConstants;
+
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Test;
+
+import com.jogamp.common.util.ReflectionUtil;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+import com.jogamp.opengl.test.junit.util.MiscUtils;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.util.Animator;
+
+/**
+ * Documenting Bug 586
+ * 
+ * <p>
+ * JScrollPane cannot mix hw/lw components, only if setting property '-Dsun.awt.disableMixing=true'.
+ * </p>
+ * <p>
+ * You can use ScrollPane, or maybe a slider and fwd the panning to the GLCanvas,
+ * which could change it's GL viewport accordingly.
+ * </p>
+ * See git commit '8df12ca151dfc577c90b485d4ebfe491b88e55aa'.
+ */
+public class TestJScrollPaneMixHwLw01AWT extends UITestCase {
+    static long durationPerTest = 500;
+    
+    static {
+        // too late: use at cmd-line '-Dsun.awt.disableMixing=true' works
+        // System.setProperty("sun.awt.disableMixing", "true");
+    }
+
+    /**
+     * Doesn't work either .. 
+     */
+    @SuppressWarnings("serial")
+    public static class TransparentJScrollPane extends JScrollPane {
+
+        public TransparentJScrollPane(Component view) {
+            super(view);
+    
+            setOpaque(false);
+       
+            try {
+                ReflectionUtil.callStaticMethod(
+                                            "com.sun.awt.AWTUtilities", "setComponentMixingCutoutShape", 
+                                            new Class<?>[] { Component.class, Shape.class }, 
+                                            new Object[] { this, new Rectangle() } , 
+                                            GraphicsConfiguration.class.getClassLoader());
+                System.err.println("com.sun.awt.AWTUtilities.setComponentMixingCutoutShape(..) passed");
+            } catch (RuntimeException re) {
+                System.err.println("com.sun.awt.AWTUtilities.setComponentMixingCutoutShape(..) failed: "+re.getMessage());
+            }
+        }
+    
+        @Override
+        public void setOpaque(boolean isOpaque) {
+        }
+    }
+    
+    protected void runTestGL(GLCapabilities caps, boolean useJScroll) throws InterruptedException {
+        final JFrame frame = new JFrame("Mix Hw/Lw Swing");
+        Assert.assertNotNull(frame);
+        
+        final Dimension f_sz = new Dimension(600,400);
+        final Dimension glc_sz = new Dimension(500,600);
+        
+        final GLCanvas glCanvas = new GLCanvas(caps);
+        Assert.assertNotNull(glCanvas);        
+        glCanvas.addGLEventListener(new GearsES2());
+        glCanvas.setPreferredSize(glc_sz);
+        
+        JPanel panel = new JPanel(new BorderLayout());
+        panel.setOpaque(false);
+        if(useJScroll) {
+            final JScrollPane scrollPane = new TransparentJScrollPane(glCanvas);      
+            panel.add(scrollPane, BorderLayout.CENTER);
+        } else {
+            ScrollPane scrollPane = new ScrollPane();
+            scrollPane.add(glCanvas);
+            panel.add(scrollPane, BorderLayout.CENTER);
+        }
+        
+        JTextArea textArea = new JTextArea();
+        textArea.setText("Test\nTest\nTest\nTest\n");
+
+        panel.add(textArea, BorderLayout.NORTH);
+
+        frame.add(panel);
+        frame.setLocationRelativeTo(null);
+        frame.setTitle("GLCanvas in JScrollPane example");
+        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
+
+        try {
+            javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+                public void run() {
+                    frame.setSize(f_sz);
+                    frame.setVisible(true);
+                }});
+        } catch (Throwable t) {
+            t.printStackTrace();
+            Assume.assumeNoException(t);
+        }
+
+        Animator animator = new Animator(glCanvas);
+        animator.start();
+
+        Thread.sleep(durationPerTest);
+
+        animator.stop();
+        
+        try {
+            javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+                public void run() {
+                    frame.setVisible(false);
+                    frame.dispose();
+                }});
+        } catch (Throwable t) {
+            t.printStackTrace();
+            Assume.assumeNoException(t);
+        }
+    }
+
+    // @Test doesn't work
+    public void test01JScrollPane() throws InterruptedException {
+        GLProfile glp = GLProfile.getGL2ES2();
+        GLCapabilities caps = new GLCapabilities(glp);
+        runTestGL(caps, true);
+    }
+
+    @Test
+    public void test01ScrollPane() throws InterruptedException {
+        GLProfile glp = GLProfile.getGL2ES2();
+        GLCapabilities caps = new GLCapabilities(glp);
+        runTestGL(caps, false);
+    }
+    
+    public static void main(String args[]) throws IOException {
+        for(int i=0; i<args.length; i++) {
+            if(args[i].equals("-time")) {
+                durationPerTest = MiscUtils.atol(args[++i], durationPerTest);
+            }
+        }
+        /**
+        BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
+        System.err.println("Press enter to continue");
+        System.err.println(stdin.readLine()); 
+        */
+        System.out.println("durationPerTest: "+durationPerTest);
+        String tstname = TestJScrollPaneMixHwLw01AWT.class.getName();
+        org.junit.runner.JUnitCore.main(tstname);
+    }
+    
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestBug605FlippedImageAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestBug605FlippedImageAWT.java
new file mode 100644
index 0000000..b949bc3
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestBug605FlippedImageAWT.java
@@ -0,0 +1,185 @@
+/**
+ * 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.test.junit.jogl.caps;
+
+import java.io.File;
+import java.io.IOException;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2;
+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 javax.media.opengl.GLException;
+import javax.media.opengl.GLProfile;
+
+import com.jogamp.opengl.util.awt.Screenshot;
+import com.jogamp.opengl.util.texture.TextureIO;
+
+import java.awt.image.BufferedImage;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+
+import com.jogamp.opengl.test.junit.util.UITestCase;
+
+public class TestBug605FlippedImageAWT extends UITestCase {
+    class FlippedImageTest implements GLEventListener {
+        public void display(GLAutoDrawable drawable) {
+            GL2 gl = drawable.getGL().getGL2();
+            
+            gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+            gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT | GL.GL_STENCIL_BUFFER_BIT | GL2.GL_ACCUM_BUFFER_BIT );
+            
+            gl.glMatrixMode(GL2.GL_PROJECTION);
+            gl.glLoadIdentity();
+            gl.glMatrixMode(GL2.GL_MODELVIEW);
+            gl.glLoadIdentity();
+    
+            // red below
+            gl.glColor3f(1, 0, 0);
+            gl.glRectf(-1, -1, 1, 0);
+    
+            // green above
+            gl.glColor3f(0, 1, 0);
+            gl.glRectf(-1, 0, 1, 1);
+            gl.glFinish();
+
+            final GLCapabilitiesImmutable caps = drawable.getChosenGLCapabilities();
+            if(caps.getAccumGreenBits() > 0) {
+                gl.glAccum(GL2.GL_ACCUM, 1.0f);
+                gl.glAccum(GL2.GL_RETURN, 1.0f);
+            }    
+            gl.glFinish();
+            
+            final int width = drawable.getWidth();
+            final int height = drawable.getHeight();
+            
+            final String fname = getSnapshotFilename(0, null, caps, width, height, false, TextureIO.PNG, null);
+            try {
+                Screenshot.writeToFile(new File(fname), width, height, false);
+            } catch (GLException e) {
+                throw e;
+            } catch (IOException e) {
+                throw new GLException(e);
+            }            
+            testFlipped(width, height);
+        }
+    
+        public void init(GLAutoDrawable drawable) {
+            final GL gl = drawable.getGL();
+            System.err.println("GL_RENDERER: "+gl.glGetString(GL.GL_RENDERER));
+            System.err.println("GL_VERSION: "+gl.glGetString(GL.GL_VERSION));
+        }    
+        public void reshape(GLAutoDrawable glDrawable, int x, int y, int w, int h) {}    
+        public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {}    
+        public void dispose(GLAutoDrawable drawable) {}
+    }
+    
+    static final int green = 0x0000ff00; // above
+    static final int red   = 0x00ff0000; // below
+
+    private void testFlipped(int width, int height) {
+        // Default origin 0/0 is lower left corner, so is the memory layout
+        // However AWT origin 0/0 is upper left corner 
+        final BufferedImage image = Screenshot.readToBufferedImage(width, height);
+        
+        final int below = image.getRGB(0, height-1) & 0x00ffffff;
+        System.err.println("below: 0x"+Integer.toHexString(below));
+        
+        final int above = image.getRGB(0, 0) & 0x00ffffff;
+        System.err.println("above: 0x"+Integer.toHexString(above));
+        
+        if (above == green && below == red) {
+            System.out.println("Image right side up");
+        } else if (above == red && below == green) {
+            Assert.assertTrue("Image is flipped", false);
+        } else {
+            Assert.assertTrue("Error in test", false);
+        }        
+    }
+    
+    private void test(GLCapabilitiesImmutable caps) {
+        
+        final GLDrawableFactory glFactory = GLDrawableFactory.getFactory(caps.getGLProfile());
+        final GLAutoDrawable glad = glFactory.createOffscreenAutoDrawable(null, caps, null, 256, 256, null);
+        final FlippedImageTest tglel = new FlippedImageTest();
+        glad.addGLEventListener(tglel);
+        
+        // 1 frame incl. snapshot to memory & file
+        glad.display();
+        System.err.println("XXX "+glad.getChosenGLCapabilities());
+        System.err.println("XXX "+glad.getContext().getGLVersion());
+                            
+        glad.destroy();        
+    }
+    
+    @Test
+    public void test01DefaultFBO() {
+        final GLProfile glp = GLProfile.get(GLProfile.GL2);
+        final GLCapabilities caps = new GLCapabilities(glp);
+        caps.setFBO(true);        
+        test(caps);        
+    }
+    
+    @Test
+    public void test01StencilFBO() {
+        final GLProfile glp = GLProfile.get(GLProfile.GL2);
+        final GLCapabilities caps = new GLCapabilities(glp);
+        caps.setStencilBits(8);
+        caps.setFBO(true);        
+        test(caps);        
+    }
+    
+    @Test
+    public void test01DefaultPBuffer() {
+        final GLProfile glp = GLProfile.get(GLProfile.GL2);
+        final GLCapabilities caps = new GLCapabilities(glp);
+        caps.setPBuffer(true);        
+        test(caps);        
+    }
+    
+    @Test
+    public void test01AccumStencilPBuffer() {
+        final GLProfile glp = GLProfile.get(GLProfile.GL2);
+        final GLCapabilities caps = new GLCapabilities(glp);
+        caps.setAccumRedBits(16);
+        caps.setAccumGreenBits(16);
+        caps.setAccumBlueBits(16);
+        caps.setStencilBits(8);
+        caps.setPBuffer(true);        
+        test(caps);        
+    }
+    
+    public static void main(String[] args) {
+        org.junit.runner.JUnitCore.main(TestBug605FlippedImageAWT.class.getName());
+    }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestBug605FlippedImageNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestBug605FlippedImageNEWT.java
new file mode 100644
index 0000000..837d94c
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestBug605FlippedImageNEWT.java
@@ -0,0 +1,176 @@
+/**
+ * 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.test.junit.jogl.caps;
+
+import java.nio.ByteBuffer;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2;
+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 javax.media.opengl.GLProfile;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+
+import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.util.GLReadBufferUtil;
+
+public class TestBug605FlippedImageNEWT extends UITestCase {
+    static class FlippedImageTest implements GLEventListener {
+        public void display(GLAutoDrawable drawable) {
+            GL2 gl = drawable.getGL().getGL2();
+            
+            gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+            gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT | GL.GL_STENCIL_BUFFER_BIT | GL2.GL_ACCUM_BUFFER_BIT );
+            
+            gl.glMatrixMode(GL2.GL_PROJECTION);
+            gl.glLoadIdentity();
+            gl.glMatrixMode(GL2.GL_MODELVIEW);
+            gl.glLoadIdentity();
+    
+            // red below
+            gl.glColor3f(1, 0, 0);
+            gl.glRectf(-1, -1, 1, 0);
+    
+            // green above
+            gl.glColor3f(0, 1, 0);
+            gl.glRectf(-1, 0, 1, 1);
+            gl.glFinish();
+    
+            final GLCapabilitiesImmutable caps = drawable.getChosenGLCapabilities();
+            if(caps.getAccumGreenBits() > 0) {
+                gl.glAccum(GL2.GL_ACCUM, 1.0f);
+                gl.glAccum(GL2.GL_RETURN, 1.0f);
+            }    
+            gl.glFinish();
+        }
+    
+        public void init(GLAutoDrawable drawable) {
+            final GL gl = drawable.getGL();
+            System.err.println("GL_RENDERER: "+gl.glGetString(GL.GL_RENDERER));
+            System.err.println("GL_VERSION: "+gl.glGetString(GL.GL_VERSION));
+        }    
+        public void reshape(GLAutoDrawable glDrawable, int x, int y, int w, int h) {}    
+        public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {}    
+        public void dispose(GLAutoDrawable drawable) {}
+    }
+    
+    static final int green = 0x0000ff00; // above
+    static final int red   = 0x00ff0000; // below
+
+    private int getRGB(ByteBuffer bb, int o) {
+        return ( (int)bb.get(o+0) & 0x000000ff ) << 16 | 
+               ( (int)bb.get(o+1) & 0x000000ff ) << 8 | 
+               ( (int)bb.get(o+2) & 0x000000ff );
+    }
+    
+    private void testFlipped(ByteBuffer bb, int width, int height, int comp) {
+        // Default origin 0/0 is lower left corner, so is the memory layout
+        
+        // x=0, y=0: RGB -> _RGB [high-byte .. low-byte]
+        final int below = getRGB(bb, 0);
+        System.err.println("below: 0x"+Integer.toHexString(below));
+        
+        // x=0, y=height-1: RGB -> _RGB [high-byte .. low-byte]
+        final int above= getRGB(bb, ( height - 1 ) * ( width * comp ));
+        System.err.println("above: 0x"+Integer.toHexString(above));
+        
+        if (above == green && below == red) {
+            System.out.println("Image right side up");
+        } else if (above == red && below == green) {
+            Assert.assertTrue("Image is flipped", false);
+        } else {
+            Assert.assertTrue("Error in test", false);
+        }        
+    }
+    
+    private void test(GLCapabilitiesImmutable caps) {
+        final GLReadBufferUtil rbu = new GLReadBufferUtil(false, false);
+        final GLDrawableFactory glFactory = GLDrawableFactory.getFactory(caps.getGLProfile());
+        final GLAutoDrawable glad = glFactory.createOffscreenAutoDrawable(null, caps, null, 256, 256, null);
+        final FlippedImageTest tglel = new FlippedImageTest();
+        glad.addGLEventListener(tglel);
+        final SnapshotGLEventListener snap = new SnapshotGLEventListener(rbu);
+        glad.addGLEventListener(snap);
+        snap.setMakeSnapshotAlways(true);        
+        
+        // 1 frame incl. snapshot to memory & file
+        glad.display();
+        System.err.println("XXX "+glad.getChosenGLCapabilities());
+        System.err.println("XXX "+glad.getContext().getGLVersion());
+        testFlipped(rbu.getPixelBuffer(), glad.getWidth(), glad.getHeight(), 3);        
+        
+        glad.destroy();        
+    }
+    
+    @Test
+    public void test01DefaultFBO() {
+        final GLProfile glp = GLProfile.get(GLProfile.GL2);
+        final GLCapabilities caps = new GLCapabilities(glp);
+        caps.setFBO(true);        
+        test(caps);        
+    }
+    
+    @Test
+    public void test01StencilFBO() {
+        final GLProfile glp = GLProfile.get(GLProfile.GL2);
+        final GLCapabilities caps = new GLCapabilities(glp);
+        caps.setStencilBits(8);
+        caps.setFBO(true);        
+        test(caps);        
+    }
+    
+    @Test
+    public void test01DefaultPBuffer() {
+        final GLProfile glp = GLProfile.get(GLProfile.GL2);
+        final GLCapabilities caps = new GLCapabilities(glp);
+        caps.setPBuffer(true);        
+        test(caps);        
+    }
+    
+    @Test
+    public void test01AccumStencilPBuffer() {
+        final GLProfile glp = GLProfile.get(GLProfile.GL2);
+        final GLCapabilities caps = new GLCapabilities(glp);
+        caps.setAccumRedBits(16);
+        caps.setAccumGreenBits(16);
+        caps.setAccumBlueBits(16);
+        caps.setStencilBits(8);
+        caps.setPBuffer(true);        
+        test(caps);        
+    }
+    
+    public static void main(String[] args) {
+        org.junit.runner.JUnitCore.main(TestBug605FlippedImageNEWT.class.getName());
+    }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1AWT.java
index 478bd45..c5bdfb5 100755
--- a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1AWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1AWT.java
@@ -108,7 +108,7 @@ public class TestMultisampleES1AWT extends UITestCase {
         public void init(GLAutoDrawable drawable) {}
         public void dispose(GLAutoDrawable drawable) {}
         public void display(GLAutoDrawable drawable) {
-            snapshot(getSimpleTestName("."), displayCount++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
+            snapshot(displayCount++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
         }
         public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
     });
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1NEWT.java
index ed8e2bd..5bbd673 100755
--- a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1NEWT.java
@@ -133,7 +133,7 @@ public class TestMultisampleES1NEWT extends UITestCase {
         public void init(GLAutoDrawable drawable) {}
         public void dispose(GLAutoDrawable drawable) {}
         public void display(GLAutoDrawable drawable) {
-            snapshot(getSimpleTestName("."), displayCount++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
+            snapshot(displayCount++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
         }
         public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
     });
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES2NEWT.java
index 02fcae6..c2e3215 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES2NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES2NEWT.java
@@ -126,7 +126,7 @@ public class TestMultisampleES2NEWT extends UITestCase {
         public void init(GLAutoDrawable drawable) {}
         public void dispose(GLAutoDrawable drawable) {}
         public void display(GLAutoDrawable drawable) {
-            snapshot(getSimpleTestName("."), displayCount++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
+            snapshot(displayCount++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
         }
         public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
     });
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 b098e1d..44a74a3 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
@@ -117,18 +117,20 @@ public abstract class GearsObject {
 
         s[4] = 0; // sin(0f)
         c[4] = 1; // cos(0f)
+        
+        final int vboUsage = GL.GL_STATIC_DRAW;
 
-        frontFace = createInterleaved(6, GL.GL_FLOAT, false, 4*teeth+2, GL.GL_STATIC_DRAW);
+        frontFace = createInterleaved(6, GL.GL_FLOAT, false, 4*teeth+2, vboUsage);
         addInterleavedVertexAndNormalArrays(frontFace, 3);
-        backFace = createInterleaved(6, GL.GL_FLOAT, false, 4*teeth+2, GL.GL_STATIC_DRAW);
+        backFace = createInterleaved(6, GL.GL_FLOAT, false, 4*teeth+2, vboUsage);
         addInterleavedVertexAndNormalArrays(backFace, 3);
-        frontSide = createInterleaved(6, GL.GL_FLOAT, false, 6*teeth, GL.GL_STATIC_DRAW);
+        frontSide = createInterleaved(6, GL.GL_FLOAT, false, 6*teeth, vboUsage);
         addInterleavedVertexAndNormalArrays(frontSide, 3);
-        backSide = createInterleaved(6, GL.GL_FLOAT, false, 6*teeth, GL.GL_STATIC_DRAW);
+        backSide = createInterleaved(6, GL.GL_FLOAT, false, 6*teeth, vboUsage);
         addInterleavedVertexAndNormalArrays(backSide, 3);
-        outwardFace = createInterleaved(6, GL.GL_FLOAT, false, 4*4*teeth+2, GL.GL_STATIC_DRAW);
+        outwardFace = createInterleaved(6, GL.GL_FLOAT, false, 4*4*teeth+2, vboUsage);
         addInterleavedVertexAndNormalArrays(outwardFace, 3);
-        insideRadiusCyl = createInterleaved(6, GL.GL_FLOAT, false, 2*teeth+2, GL.GL_STATIC_DRAW);
+        insideRadiusCyl = createInterleaved(6, GL.GL_FLOAT, false, 2*teeth+2, vboUsage);
         addInterleavedVertexAndNormalArrays(insideRadiusCyl, 3);
 
         for (i = 0; i < teeth; i++) {
diff --git a/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/PointsDemo.java
similarity index 69%
copy from src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java
copy to src/test/com/jogamp/opengl/test/junit/jogl/demos/PointsDemo.java
index 30f9660..4f2e415 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/PointsDemo.java
@@ -1,5 +1,5 @@
 /**
- * Copyright 2010 JogAmp Community. All rights reserved.
+ * 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:
@@ -25,20 +25,24 @@
  * 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;
 
-package javax.media.nativewindow;
+import javax.media.opengl.GLEventListener;
 
-import jogamp.nativewindow.Debug;
+public abstract class PointsDemo implements GLEventListener {
+    int swapInterval = 0;
+    final int edge = 8; // 8*8
+    
+    public PointsDemo(int swapInterval) {
+        this.swapInterval = swapInterval;
+    }
 
-/**
- * Marker for a singleton global recursive blocking lock implementation,
- * optionally locking a native windowing toolkit as well.
- * <br>
- * One use case is the AWT locking on X11, see {@link jogamp.nativewindow.jawt.JAWTToolkitLock}.
- */
-public interface ToolkitLock {
-    public static final boolean TRACE_LOCK = Debug.isPropertyDefined("nativewindow.debug.ToolkitLock.TraceLock", true);
-
-    public void lock();
-    public void unlock();
+    public PointsDemo() {
+        this.swapInterval = 1;
+    }
+    
+    public abstract void setSmoothPoints(boolean v);
+    
+    public abstract void setPointParams(float minSize, float maxSize, float distAttenConst, float distAttenLinear, float distAttenQuadratic, float fadeThreshold);    
+        
 }
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 e81d1b4..5186fd7 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
@@ -24,8 +24,10 @@ package com.jogamp.opengl.test.junit.jogl.demos.es1;
 import javax.media.nativewindow.NativeWindow;
 import javax.media.opengl.GL;
 import javax.media.opengl.GL2ES1;
+import javax.media.opengl.GL2ES2;
 import javax.media.opengl.GLAutoDrawable;
 import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLPipelineFactory;
 import javax.media.opengl.GLProfile;
 
 import com.jogamp.newt.Window;
@@ -36,12 +38,21 @@ import com.jogamp.newt.event.MouseAdapter;
 import com.jogamp.newt.event.MouseEvent;
 import com.jogamp.newt.event.MouseListener;
 import com.jogamp.opengl.test.junit.jogl.demos.GearsObject;
+import com.jogamp.opengl.util.glsl.fixedfunc.FixedFuncUtil;
+import com.jogamp.opengl.util.glsl.fixedfunc.ShaderSelectionMode;
 
 /**
  * GearsES1.java <BR>
  * @author Brian Paul (converted to Java by Ron Cemer and Sven Gothel) <P>
  */
 public class GearsES1 implements GLEventListener {
+  private boolean debugFFPEmu = false;
+  private boolean verboseFFPEmu = false;
+  private boolean traceFFPEmu = false;
+  private boolean forceFFPEmu = false;
+  private boolean debug = false ;
+  private boolean trace = false ;
+  
   private final float pos[] = { 5.0f, 5.0f, 10.0f, 0.0f };
 
   private float view_rotx = 20.0f, view_roty = 30.0f, view_rotz = 0.0f;
@@ -62,6 +73,13 @@ public class GearsES1 implements GLEventListener {
     this.swapInterval = 1;
   }
   
+  public void setForceFFPEmu(boolean forceFFPEmu, boolean verboseFFPEmu, boolean debugFFPEmu, boolean traceFFPEmu) {
+    this.forceFFPEmu = forceFFPEmu;
+    this.verboseFFPEmu = verboseFFPEmu;
+    this.debugFFPEmu = debugFFPEmu;
+    this.traceFFPEmu = traceFFPEmu;
+  }
+  
   public void setGears(GearsObject g1, GearsObject g2, GearsObject g3) {
       gear1 = g1;
       gear2 = g2;
@@ -90,14 +108,42 @@ public class GearsES1 implements GLEventListener {
     // drawable.setGL(new DebugGL(drawable.getGL()));
 
     GL _gl = drawable.getGL();
-    // GL2ES1 gl = FixedFuncUtil.wrapFixedFuncEmul(_gl /*, true*/);
-    GL2ES1 gl = _gl.getGL2ES1();
     
+    if(debugFFPEmu) {
+        // Debug ..
+        _gl = _gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Debug", GL2ES2.class, _gl, null) );
+        debug = false;
+    }
+    if(traceFFPEmu) {
+        // Trace ..
+        _gl = _gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Trace", GL2ES2.class, _gl, new Object[] { System.err } ) );
+        trace = false;
+    }
+    GL2ES1 gl = FixedFuncUtil.wrapFixedFuncEmul(_gl, ShaderSelectionMode.AUTO, null, forceFFPEmu, verboseFFPEmu);
+    
+    if(debug) {
+        try {
+            // Debug ..
+            gl = (GL2ES1) gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Debug", GL2ES1.class, gl, null) );
+        } catch (Exception e) {e.printStackTrace();} 
+    }
+    if(trace) {
+        try {
+            // Trace ..
+            gl = (GL2ES1) gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Trace", GL2ES1.class, gl, new Object[] { System.err } ) );
+        } catch (Exception e) {e.printStackTrace();}
+    }
+    
+    System.err.println("GearsES1 init on "+Thread.currentThread());
     System.err.println("Chosen GLCapabilities: " + drawable.getChosenGLCapabilities());
     System.err.println("INIT GL IS: " + gl.getClass().getName());
     System.err.println("GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR));
     System.err.println("GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER));
     System.err.println("GL_VERSION: " + gl.glGetString(GL.GL_VERSION));
+    System.err.println("GL GLSL: "+gl.hasGLSL()+", has-compiler: "+gl.isFunctionAvailable("glCompileShader")+", version "+(gl.hasGLSL() ? gl.glGetString(GL2ES2.GL_SHADING_LANGUAGE_VERSION) : "none"));
+    System.err.println("GL FBO: basic "+ gl.hasBasicFBOSupport()+", full "+gl.hasFullFBOSupport());
+    System.err.println("GL Profile: "+gl.getGLProfile());
+    System.err.println("GL:" + gl + ", " + gl.getContext().getGLVersion());
 
     gl.glLightfv(GL2ES1.GL_LIGHT0, GL2ES1.GL_POSITION, pos, 0);
     gl.glEnable(GL.GL_CULL_FACE);
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 1208dad..8276c6b 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
@@ -47,10 +47,9 @@ public class GearsObjectES1 extends GearsObject {
     }
     
     @Override
-    public void addInterleavedVertexAndNormalArrays(GLArrayDataServer array,
-            int components) {
-        array.addFixedSubArray(GLPointerFunc.GL_VERTEX_ARRAY, 3, GL.GL_ARRAY_BUFFER);
-        array.addFixedSubArray(GLPointerFunc.GL_NORMAL_ARRAY, 3, GL.GL_ARRAY_BUFFER);
+    public void addInterleavedVertexAndNormalArrays(GLArrayDataServer array, int components) {
+        array.addFixedSubArray(GLPointerFunc.GL_VERTEX_ARRAY, components, GL.GL_ARRAY_BUFFER);
+        array.addFixedSubArray(GLPointerFunc.GL_NORMAL_ARRAY, components, GL.GL_ARRAY_BUFFER);
     }
 
     private void draw(GL2ES1 gl, GLArrayDataServer array, int mode) {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/MultisampleDemoES1.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/MultisampleDemoES1.java
index aad5658..4b4c7f2 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/MultisampleDemoES1.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/MultisampleDemoES1.java
@@ -77,11 +77,12 @@ public class MultisampleDemoES1 implements GLEventListener {
         if (multisample) {
             gl.glDisable(GL.GL_MULTISAMPLE);
         }
-        immModeSink = ImmModeSink.createFixed(gl, GL.GL_STATIC_DRAW, 40, 
-                                              3, GL.GL_FLOAT,  // vertex
-                                              0, GL.GL_FLOAT,  // color
-                                              0, GL.GL_FLOAT,// normal
-                                              0, GL.GL_FLOAT); // texture
+        immModeSink = ImmModeSink.createFixed(40, 
+                                              3, GL.GL_FLOAT, // vertex
+                                              0, GL.GL_FLOAT, // color
+                                              0, GL.GL_FLOAT, // normal
+                                              0, GL.GL_FLOAT, // texCoords 
+                                              GL.GL_STATIC_DRAW);
         final int numSteps = 20;
         final double increment = Math.PI / numSteps;
         final double radius = 1;
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/OneTriangle.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/OneTriangle.java
index 8c9f53b..4b05f1a 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/OneTriangle.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/OneTriangle.java
@@ -61,11 +61,12 @@ public class OneTriangle {
         // draw a triangle filling the window
         gl.glLoadIdentity();
         
-        ImmModeSink immModeSink = ImmModeSink.createFixed(gl, GL.GL_STATIC_DRAW, 3, 
-                                              3, GL.GL_FLOAT,  // vertex
-                                              3, GL.GL_FLOAT,  // color
-                                              0, GL.GL_FLOAT,// normal
-                                              0, GL.GL_FLOAT); // texture
+        ImmModeSink immModeSink = ImmModeSink.createFixed(3*3, 
+                                                          3, GL.GL_FLOAT, // vertex
+                                                          3, GL.GL_FLOAT, // color
+                                                          0, GL.GL_FLOAT, // normal
+                                                          0, GL.GL_FLOAT, // texCoords 
+                                                          GL.GL_STATIC_DRAW);
         immModeSink.glBegin(GL.GL_TRIANGLES);
         immModeSink.glColor3f( 1, 0, 0 );
         immModeSink.glVertex2f( 0, 0 );
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/PointsDemoES1.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/PointsDemoES1.java
new file mode 100644
index 0000000..097784f
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/PointsDemoES1.java
@@ -0,0 +1,198 @@
+/**
+ * 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.test.junit.jogl.demos.es1;
+
+import java.nio.FloatBuffer;
+
+import com.jogamp.common.nio.Buffers;
+import com.jogamp.opengl.test.junit.jogl.demos.PointsDemo;
+import com.jogamp.opengl.util.GLArrayDataServer;
+import com.jogamp.opengl.util.PMVMatrix;
+import com.jogamp.opengl.util.glsl.fixedfunc.FixedFuncUtil;
+import com.jogamp.opengl.util.glsl.fixedfunc.ShaderSelectionMode;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES1;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLPipelineFactory;
+import javax.media.opengl.glu.GLU;
+import javax.media.opengl.glu.gl2es1.GLUgl2es1;
+
+public class PointsDemoES1 extends PointsDemo {
+    final static GLU glu = new GLUgl2es1();
+    private boolean debugFFPEmu = false;
+    private boolean verboseFFPEmu = false;
+    private boolean traceFFPEmu = false;
+    private boolean forceFFPEmu = false;
+    private boolean debug = false ;
+    private boolean trace = false ;
+    GLArrayDataServer vertices ;
+    float[] pointSizes ;
+    private int swapInterval = 0;
+    final int edge = 8; // 8*8
+    boolean smooth = false;
+
+    public PointsDemoES1(int swapInterval) {
+        this.swapInterval = swapInterval;
+    }
+
+    public PointsDemoES1() {
+        this.swapInterval = 1;
+    }
+        
+    public void setForceFFPEmu(boolean forceFFPEmu, boolean verboseFFPEmu, boolean debugFFPEmu, boolean traceFFPEmu) {
+        this.forceFFPEmu = forceFFPEmu;
+        this.verboseFFPEmu = verboseFFPEmu;
+        this.debugFFPEmu = debugFFPEmu;
+        this.traceFFPEmu = traceFFPEmu;
+    }
+    
+    public void setSmoothPoints(boolean v) { smooth = v; }
+    
+    public void init(GLAutoDrawable glad) {
+        GL _gl = glad.getGL();
+
+        if(debugFFPEmu) {
+            // Debug ..
+            _gl = _gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Debug", GL2ES2.class, _gl, null) );
+            debug = false;
+        }
+        if(traceFFPEmu) {
+            // Trace ..
+            _gl = _gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Trace", GL2ES2.class, _gl, new Object[] { System.err } ) );
+            trace = false;
+        }
+        GL2ES1 gl = FixedFuncUtil.wrapFixedFuncEmul(_gl, ShaderSelectionMode.AUTO, null, forceFFPEmu, verboseFFPEmu);
+        
+        if(debug) {
+            try {
+                // Debug ..
+                gl = (GL2ES1) gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Debug", GL2ES1.class, gl, null) );
+            } catch (Exception e) {e.printStackTrace();} 
+        }
+        if(trace) {
+            try {
+                // Trace ..
+                gl = (GL2ES1) gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Trace", GL2ES1.class, gl, new Object[] { System.err } ) );
+            } catch (Exception e) {e.printStackTrace();}
+        }                
+        
+        System.err.println("GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR));
+        System.err.println("GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER));
+        System.err.println("GL_VERSION: " + gl.glGetString(GL.GL_VERSION));
+        System.err.println("GL Profile: "+gl.getGLProfile());
+        
+        // Allocate Vertex Array
+        vertices = GLArrayDataServer.createFixed(GL2ES1.GL_VERTEX_ARRAY, 3, GL.GL_FLOAT, false, edge*edge, GL.GL_STATIC_DRAW);
+        pointSizes = new float[edge*edge];
+        for(int i=0; i<edge; i++) {
+            for(int j=0; j<edge; j++) {
+                final float x = -3+j*0.7f;
+                final float y = -3+i*0.7f;
+                final float p = (i*edge+j)*0.5f;
+                // System.err.println("["+j+"/"+i+"]: "+x+"/"+y+": "+p);
+                vertices.putf(x); vertices.putf(y); vertices.putf( 0);
+                pointSizes[(i*edge+j)] = p;
+            }
+        }
+        vertices.seal(gl, true);
+        vertices.enableBuffer(gl, false);
+
+        // OpenGL Render Settings
+        gl.glEnable(GL2ES1.GL_DEPTH_TEST);
+    }
+
+    public void setPointParams(float minSize, float maxSize, float distAttenConst, float distAttenLinear, float distAttenQuadratic, float fadeThreshold) {
+        pointMinSize = minSize;
+        pointMaxSize = maxSize;
+        pointFadeThreshold = fadeThreshold;
+        pointDistAtten.put(0, distAttenConst);
+        pointDistAtten.put(1, distAttenLinear);
+        pointDistAtten.put(2, distAttenQuadratic);
+    }
+    
+    /** default values */
+    private float pointMinSize = 0.0f;
+    private float pointMaxSize = 4096.0f;
+    private float pointFadeThreshold = 1.0f;
+    private final FloatBuffer pointDistAtten = Buffers.newDirectFloatBuffer(new float[] {  1.0f, 0.0f, 0.0f });
+
+    public void display(GLAutoDrawable glad) {
+        GL2ES1 gl = glad.getGL().getGL2ES1();
+        gl.glClearColor(0f, 0f, 0f, 0f);
+        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
+        gl.glMatrixMode(GL2ES1.GL_MODELVIEW);
+        gl.glLoadIdentity();
+        gl.glTranslatef(0, 0, -10);
+
+        gl.glColor4f(1.0f, 1.0f, 1.0f, 1.0f );
+        
+        vertices.enableBuffer(gl, true);
+        
+        gl.glEnable ( GL.GL_BLEND );
+        gl.glBlendFunc ( GL.GL_SRC_ALPHA, GL.GL_ONE );
+        if(smooth) {
+            gl.glEnable(GL2ES1.GL_POINT_SMOOTH);
+        } else {
+            gl.glDisable(GL2ES1.GL_POINT_SMOOTH);
+        }
+        gl.glPointParameterf(GL2ES1.GL_POINT_SIZE_MIN, pointMinSize );
+        gl.glPointParameterf(GL2ES1.GL_POINT_SIZE_MAX, pointMaxSize );
+        gl.glPointParameterf(GL2ES1.GL_POINT_FADE_THRESHOLD_SIZE, pointFadeThreshold);
+        gl.glPointParameterfv(GL2ES1.GL_POINT_DISTANCE_ATTENUATION, pointDistAtten );
+        
+        for(int i=edge*edge-1; i>=0; i--) {
+            gl.glPointSize(pointSizes[i]);
+            gl.glDrawArrays(GL.GL_POINTS, i, 1);            
+        }        
+        
+        vertices.enableBuffer(gl, false);
+    }
+
+    public void reshape(GLAutoDrawable glad, int x, int y, int width, int height) {
+        // Thread.dumpStack();
+        GL2ES1 gl = glad.getGL().getGL2ES1();
+        
+        if(-1 != swapInterval) {        
+            gl.setSwapInterval(swapInterval); // in case switching the drawable (impl. may bound attribute there)
+        }
+        
+        // Set location in front of camera
+        gl.glMatrixMode(PMVMatrix.GL_PROJECTION);
+        gl.glLoadIdentity();
+        glu.gluPerspective(45.0F, ( (float) width / (float) height ) / 1.0f, 1.0F, 100.0F);
+        //gl.glOrthof(-4.0f, 4.0f, -4.0f, 4.0f, 1.0f, 100.0f);
+    }
+
+    public void dispose(GLAutoDrawable glad) {
+        GL2ES1 gl = glad.getGL().getGL2ES1();
+        vertices.destroy(gl);
+        vertices = null;
+    }    
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/RedSquareES1.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/RedSquareES1.java
index 8d1c708..37ed83e 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/RedSquareES1.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/RedSquareES1.java
@@ -10,11 +10,14 @@ import com.jogamp.opengl.util.glsl.fixedfunc.*;
 
 public class RedSquareES1 implements GLEventListener {
 
-    public static boolean glDebugEmu = false;
-    public static boolean glDebug = false ;
-    public static boolean glTrace = false ;
     public static boolean oneThread = false;
     public static boolean useAnimator = false;
+    private boolean debugFFPEmu = false;
+    private boolean verboseFFPEmu = false;
+    private boolean traceFFPEmu = false;
+    private boolean forceFFPEmu = false;
+    private boolean debug = false ;
+    private boolean trace = false ;
     private int swapInterval = 0;
 
     long startTime = 0;
@@ -28,6 +31,13 @@ public class RedSquareES1 implements GLEventListener {
         this.swapInterval = 1;
     }
     
+    public void setForceFFPEmu(boolean forceFFPEmu, boolean verboseFFPEmu, boolean debugFFPEmu, boolean traceFFPEmu) {
+        this.forceFFPEmu = forceFFPEmu;
+        this.verboseFFPEmu = verboseFFPEmu;
+        this.debugFFPEmu = debugFFPEmu;
+        this.traceFFPEmu = traceFFPEmu;
+    }
+    
     // FIXME: we must add storage of the pointers in the GL state to
     // the GLImpl classes. The need for this can be seen by making
     // these variables method local instead of instance members. The
@@ -42,44 +52,41 @@ public class RedSquareES1 implements GLEventListener {
         System.err.println(Thread.currentThread()+" RedSquareES1.init ...");
         GL _gl = drawable.getGL();
 
-        if(glDebugEmu) {
-            try {
-                // Debug ..
-                _gl = _gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Debug", GL2ES2.class, _gl, null) );
-
-                if(glTrace) {
-                    // Trace ..
-                    _gl = _gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Trace", GL2ES2.class, _gl, new Object[] { System.err } ) );
-                }
-            } catch (Exception e) {e.printStackTrace();} 
-            glDebug = false;
-            glTrace = false;
+        if(debugFFPEmu) {
+            // Debug ..
+            _gl = _gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Debug", GL2ES2.class, _gl, null) );
+            debug = false;
         }
-
-        GL2ES1 gl = FixedFuncUtil.wrapFixedFuncEmul(_gl);
-        if(glDebug) {
+        if(traceFFPEmu) {
+            // Trace ..
+            _gl = _gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Trace", GL2ES2.class, _gl, new Object[] { System.err } ) );
+            trace = false;
+        }
+        GL2ES1 gl = FixedFuncUtil.wrapFixedFuncEmul(_gl, ShaderSelectionMode.AUTO, null, forceFFPEmu, verboseFFPEmu);
+        
+        if(debug) {
             try {
                 // Debug ..
                 gl = (GL2ES1) gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Debug", GL2ES1.class, gl, null) );
             } catch (Exception e) {e.printStackTrace();} 
         }
-
-        if(glTrace) {
+        if(trace) {
             try {
                 // Trace ..
                 gl = (GL2ES1) gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Trace", GL2ES1.class, gl, new Object[] { System.err } ) );
             } catch (Exception e) {e.printStackTrace();}
         }
 
-        System.err.println(Thread.currentThread()+"Chosen GLCapabilities: " + drawable.getChosenGLCapabilities());
-        System.err.println(Thread.currentThread()+"INIT GL IS: " + gl.getClass().getName());
-        System.err.println(Thread.currentThread()+"GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR));
-        System.err.println(Thread.currentThread()+"GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER));
-        System.err.println(Thread.currentThread()+"GL_VERSION: " + gl.glGetString(GL.GL_VERSION));
-        
-        System.err.println(Thread.currentThread()+" GL Profile: "+gl.getGLProfile());
-        System.err.println(Thread.currentThread()+" GL:" + gl);
-        System.err.println(Thread.currentThread()+" GL_VERSION=" + gl.glGetString(GL.GL_VERSION));
+        System.err.println("RedSquareES1 init on "+Thread.currentThread());
+        System.err.println("Chosen GLCapabilities: " + drawable.getChosenGLCapabilities());
+        System.err.println("INIT GL IS: " + gl.getClass().getName());
+        System.err.println("GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR));
+        System.err.println("GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER));
+        System.err.println("GL_VERSION: " + gl.glGetString(GL.GL_VERSION));
+        System.err.println("GL GLSL: "+gl.hasGLSL()+", has-compiler: "+gl.isFunctionAvailable("glCompileShader")+", version "+(gl.hasGLSL() ? gl.glGetString(GL2ES2.GL_SHADING_LANGUAGE_VERSION) : "none"));
+        System.err.println("GL FBO: basic "+ gl.hasBasicFBOSupport()+", full "+gl.hasFullFBOSupport());
+        System.err.println("GL Profile: "+gl.getGLProfile());
+        System.err.println("GL:" + gl + ", " + gl.getContext().getGLVersion());
 
         // Allocate vertex arrays
         colors   = Buffers.newDirectFloatBuffer(16);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/newt/TestGearsES1NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/newt/TestGearsES1NEWT.java
index ff168d9..9e0bbae 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/newt/TestGearsES1NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/newt/TestGearsES1NEWT.java
@@ -48,6 +48,8 @@ import org.junit.Test;
 
 public class TestGearsES1NEWT extends UITestCase {
     static int width, height;
+    static boolean forceES2 = false;
+    static boolean forceFFPEmu = false;
 
     @BeforeClass
     public static void initClass() {
@@ -59,12 +61,16 @@ public class TestGearsES1NEWT extends UITestCase {
     public static void releaseClass() {
     }
 
-    protected void runTestGL(GLCapabilities caps) throws InterruptedException {
+    protected void runTestGL(GLCapabilities caps, boolean forceFFPEmu) throws InterruptedException {
         GLWindow glWindow = GLWindow.create(caps);
         Assert.assertNotNull(glWindow);
         glWindow.setTitle("Gears NEWT Test");
 
-        glWindow.addGLEventListener(new GearsES1());
+        final GearsES1 demo = new GearsES1();
+        demo.setForceFFPEmu(forceFFPEmu, forceFFPEmu, false, false);
+        glWindow.addGLEventListener(demo);
+        final SnapshotGLEventListener snap = new SnapshotGLEventListener();
+        glWindow.addGLEventListener(snap);
 
         Animator animator = new Animator(glWindow);
         QuitAdapter quitAdapter = new QuitAdapter();
@@ -95,6 +101,7 @@ public class TestGearsES1NEWT extends UITestCase {
         glWindow.setVisible(true);
         animator.setUpdateFPSFrames(1, null);
         animator.start();
+        snap.setMakeSnapshot();
 
         while(!quitAdapter.shouldQuit() && animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
             Thread.sleep(100);
@@ -105,13 +112,13 @@ public class TestGearsES1NEWT extends UITestCase {
     }
 
     @Test
-    public void test01() throws InterruptedException {
-        GLCapabilities caps = new GLCapabilities(GLProfile.getGL2ES1());
-        runTestGL(caps);
+    public void test00() throws InterruptedException {
+        GLCapabilities caps = new GLCapabilities(forceES2 ? GLProfile.get(GLProfile.GLES2) : GLProfile.getGL2ES1());
+        runTestGL(caps, forceFFPEmu);
     }
-
-    static long duration = 500; // ms
-
+    
+    static long duration = 1000; // ms
+    
     public static void main(String args[]) {
         for(int i=0; i<args.length; i++) {
             if(args[i].equals("-time")) {
@@ -119,6 +126,10 @@ public class TestGearsES1NEWT extends UITestCase {
                 try {
                     duration = Integer.parseInt(args[i]);
                 } catch (Exception ex) { ex.printStackTrace(); }
+            } else if(args[i].equals("-es2")) {
+                forceES2 = true;
+            } else if(args[i].equals("-ffpemu")) {
+                forceFFPEmu = true;
             }
         }
         org.junit.runner.JUnitCore.main(TestGearsES1NEWT.class.getName());
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/newt/TestRedSquareES1NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/newt/TestRedSquareES1NEWT.java
index c327a30..b0e6b2b 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/newt/TestRedSquareES1NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/newt/TestRedSquareES1NEWT.java
@@ -48,6 +48,8 @@ import org.junit.Test;
 
 public class TestRedSquareES1NEWT extends UITestCase {
     static int width, height;
+    static boolean forceES2 = false;
+    static boolean forceFFPEmu = false;
 
     @BeforeClass
     public static void initClass() {
@@ -59,12 +61,16 @@ public class TestRedSquareES1NEWT extends UITestCase {
     public static void releaseClass() {
     }
 
-    protected void runTestGL(GLCapabilities caps) throws InterruptedException {
+    protected void runTestGL(GLCapabilities caps, boolean forceFFPEmu) throws InterruptedException {
         GLWindow glWindow = GLWindow.create(caps);
         Assert.assertNotNull(glWindow);
         glWindow.setTitle("Gears NEWT Test");
 
-        glWindow.addGLEventListener(new RedSquareES1());
+        final RedSquareES1 demo = new RedSquareES1();
+        demo.setForceFFPEmu(forceFFPEmu, forceFFPEmu, false, false);
+        glWindow.addGLEventListener(demo);
+        final SnapshotGLEventListener snap = new SnapshotGLEventListener();
+        glWindow.addGLEventListener(snap);
 
         Animator animator = new Animator(glWindow);
         QuitAdapter quitAdapter = new QuitAdapter();
@@ -95,6 +101,7 @@ public class TestRedSquareES1NEWT extends UITestCase {
         glWindow.setVisible(true);
         animator.setUpdateFPSFrames(1, null);
         animator.start();
+        snap.setMakeSnapshot();
 
         while(!quitAdapter.shouldQuit() && animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
             Thread.sleep(100);
@@ -105,20 +112,24 @@ public class TestRedSquareES1NEWT extends UITestCase {
     }
 
     @Test
-    public void test01() throws InterruptedException {
-        GLCapabilities caps = new GLCapabilities(GLProfile.getGL2ES1());
-        runTestGL(caps);
+    public void test00() throws InterruptedException {
+        GLCapabilities caps = new GLCapabilities(forceES2 ? GLProfile.get(GLProfile.GLES2) : GLProfile.getGL2ES1());
+        runTestGL(caps, forceFFPEmu);
     }
+    
+    static long duration = 1000; // ms
 
-    static long duration = 500; // ms
-
-    public static void main(String args[]) {
+    public static void main(String args[]) {        
         for(int i=0; i<args.length; i++) {
             if(args[i].equals("-time")) {
                 i++;
                 try {
                     duration = Integer.parseInt(args[i]);
                 } catch (Exception ex) { ex.printStackTrace(); }
+            } else if(args[i].equals("-es2")) {
+                forceES2 = true;
+            } else if(args[i].equals("-ffpemu")) {
+                forceFFPEmu = true;
             }
         }
         org.junit.runner.JUnitCore.main(TestRedSquareES1NEWT.class.getName());
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/FBOMix2DemosES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/FBOMix2DemosES2.java
index 3dfbb48..9d2c73f 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/FBOMix2DemosES2.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/FBOMix2DemosES2.java
@@ -63,9 +63,8 @@ public class FBOMix2DemosES2 implements GLEventListener {
     
     public FBOMix2DemosES2(int swapInterval) {
         demo0 = new GearsES2(-1);
-        demo0.setIsFBOSlave(true);
+        demo0.setIgnoreFocus(true);
         demo1 = new RedSquareES2(-1);
-        demo1.setIsFBOSlave(true);
         this.swapInterval = swapInterval;
         
         st = new ShaderState();
@@ -158,26 +157,19 @@ public class FBOMix2DemosES2 implements GLEventListener {
         st.useProgram(gl, false);
         
         System.err.println("**** Init");
-        resetFBOs(gl, drawable);
+        initFBOs(gl, drawable);
         
-        fbo0.attachRenderbuffer(gl, Type.DEPTH, 24);
-        fbo0.unbind(gl);
-        fbo1.attachRenderbuffer(gl, Type.DEPTH, 24);
-        fbo1.unbind(gl);
-        gl.glEnable(GL2ES2.GL_DEPTH_TEST);
-        
-        numSamples=fbo0.getNumSamples();
+        gl.glEnable(GL2ES2.GL_DEPTH_TEST);        
     }
     
-    /** Since we switch MSAA and non-MSAA we need to take extra care, i.e. sync msaa for both FBOs ..*/
-    private void resetFBOs(GL gl, GLAutoDrawable drawable) {
+    private void initFBOs(GL gl, GLAutoDrawable drawable) {
         // remove all texture attachments, since MSAA uses just color-render-buffer
         // and non-MSAA uses texture2d-buffer
         fbo0.detachAllColorbuffer(gl);
         fbo1.detachAllColorbuffer(gl);
             
-        fbo0.reset(gl, drawable.getWidth(), drawable.getHeight(), numSamples);
-        fbo1.reset(gl, drawable.getWidth(), drawable.getHeight(), numSamples);
+        fbo0.reset(gl, drawable.getWidth(), drawable.getHeight(), numSamples, false);
+        fbo1.reset(gl, drawable.getWidth(), drawable.getHeight(), numSamples, false);
         if(fbo0.getNumSamples() != fbo1.getNumSamples()) {
             throw new InternalError("sample size mismatch: \n\t0: "+fbo0+"\n\t1: "+fbo1);
         }        
@@ -185,15 +177,38 @@ public class FBOMix2DemosES2 implements GLEventListener {
         
         if(numSamples>0) {
             fbo0.attachColorbuffer(gl, 0, true);
+            fbo0.resetSamplingSink(gl);
             fbo1.attachColorbuffer(gl, 0, true);
+            fbo1.resetSamplingSink(gl);
             fbo0Tex = fbo0.getSamplingSink();
             fbo1Tex = fbo1.getSamplingSink();
         } else {
             fbo0Tex = fbo0.attachTexture2D(gl, 0, true);
             fbo1Tex = fbo1.attachTexture2D(gl, 0, true);
         }        
+        numSamples=fbo0.getNumSamples();
+        fbo0.attachRenderbuffer(gl, Type.DEPTH, 24);
+        fbo0.unbind(gl);
+        fbo1.attachRenderbuffer(gl, Type.DEPTH, 24);
+        fbo1.unbind(gl);
     }
 
+    private void resetFBOs(GL gl, GLAutoDrawable drawable) {
+        fbo0.reset(gl, drawable.getWidth(), drawable.getHeight(), numSamples, true);
+        fbo1.reset(gl, drawable.getWidth(), drawable.getHeight(), numSamples, true);
+        if(fbo0.getNumSamples() != fbo1.getNumSamples()) {
+            throw new InternalError("sample size mismatch: \n\t0: "+fbo0+"\n\t1: "+fbo1);
+        }        
+        numSamples = fbo0.getNumSamples();
+        if(numSamples>0) {
+            fbo0Tex = fbo0.getSamplingSink();
+            fbo1Tex = fbo1.getSamplingSink();
+        } else {
+            fbo0Tex = (TextureAttachment) fbo0.getColorbuffer(0);
+            fbo1Tex = (TextureAttachment) fbo1.getColorbuffer(0);
+        }        
+    }
+    
     @Override
     public void dispose(GLAutoDrawable drawable) {
         final GL2ES2 gl = drawable.getGL().getGL2ES2();
@@ -245,6 +260,8 @@ public class FBOMix2DemosES2 implements GLEventListener {
         }
         interleavedVBO.enableBuffer(gl, true);
         
+        gl.glEnable(GL.GL_TEXTURE_2D);
+        
         gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, 4);
         
         interleavedVBO.enableBuffer(gl, false);
@@ -264,10 +281,8 @@ public class FBOMix2DemosES2 implements GLEventListener {
             gl.setSwapInterval(swapInterval); // in case switching the drawable (impl. may bound attribute there)
         }
         
-        // if(drawable.getWidth() == fbo0.getWidth() && drawable.getHeight() == fbo0.getHeight() ) {
-            System.err.println("**** Reshape: "+width+"x"+height);
-            resetFBOs(gl, drawable);            
-        //}        
+        System.err.println("**** Reshape: "+width+"x"+height);
+        resetFBOs(gl, drawable);            
         
         fbo0.bind(gl);
         demo0.reshape(drawable, x, y, width, height);
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 38e8a15..e703b6f 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
@@ -64,8 +64,9 @@ public class GearsES2 implements GLEventListener {
     private KeyListener gearsKeys = new GearsKeyAdapter();
 
     private int prevMouseX, prevMouseY;
+    private boolean doRotate = true;
     private boolean isInitialized = false;
-    boolean isFBOSlave = false;
+    boolean ignoreFocus = false;
 
     public GearsES2(int swapInterval) {
         this.swapInterval = swapInterval;
@@ -75,7 +76,8 @@ public class GearsES2 implements GLEventListener {
         this.swapInterval = 1;
     }
 
-    public void setIsFBOSlave(boolean v) { isFBOSlave = v; }
+    public void setIgnoreFocus(boolean v) { ignoreFocus = v; }
+    public void setDoRotation(boolean rotate) { this.doRotate = rotate; }
     
     public void setPMVUseBackingArray(boolean pmvUseBackingArray) {
         this.pmvUseBackingArray = pmvUseBackingArray;
@@ -112,27 +114,35 @@ public class GearsES2 implements GLEventListener {
         System.err.println(Thread.currentThread()+" GearsES2.init ...");
         GL2ES2 gl = drawable.getGL().getGL2ES2();
 
+        System.err.println("GearsES2 init on "+Thread.currentThread());
         System.err.println("Chosen GLCapabilities: " + drawable.getChosenGLCapabilities());
         System.err.println("INIT GL IS: " + gl.getClass().getName());
         System.err.println("GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR));
         System.err.println("GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER));
         System.err.println("GL_VERSION: " + gl.glGetString(GL.GL_VERSION));
+        System.err.println("GL GLSL: "+gl.hasGLSL()+", has-compiler: "+gl.isFunctionAvailable("glCompileShader")+", version "+(gl.hasGLSL() ? gl.glGetString(GL2ES2.GL_SHADING_LANGUAGE_VERSION) : "none")+", "+gl.getContext().getGLSLVersionNumber());
+        System.err.println("GL FBO: basic "+ gl.hasBasicFBOSupport()+", full "+gl.hasFullFBOSupport());
+        System.err.println("GL Profile: "+gl.getGLProfile());
+        System.err.println("GL Renderer Quirks:" + gl.getContext().getRendererQuirks().toString());
+        System.err.println("GL:" + gl + ", " + gl.getContext().getGLVersion());
 
         gl.glEnable(GL.GL_DEPTH_TEST);
         
         st = new ShaderState();
         // st.setVerbose(true);
         final ShaderCode vp0 = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, this.getClass(), "shader",
-                "shader/bin", "gears", false);
+                "shader/bin", "gears", true);
         final ShaderCode fp0 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, this.getClass(), "shader",
-                "shader/bin", "gears", false);
+                "shader/bin", "gears", true);
+        vp0.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_vp);
+        fp0.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_fp);
         final ShaderProgram sp0 = new ShaderProgram();
         sp0.add(gl, vp0, System.err);
         sp0.add(gl, fp0, System.err);
         st.attachShaderProgram(gl, sp0, true);
         // Use debug pipeline
         // drawable.setGL(new DebugGL(drawable.getGL()));
-
+        
         pmvMatrix = new PMVMatrix(pmvUseBackingArray);
         st.attachObject("pmvMatrix", pmvMatrix);
         pmvMatrixUniform = new GLUniformData("pmvMatrix", 4, 4, pmvMatrix.glGetPMvMvitMatrixf()); // P, Mv, Mvi and Mvit
@@ -169,7 +179,7 @@ public class GearsES2 implements GLEventListener {
         } else {
             gear3 = new GearsObjectES2(gear3, pmvMatrix, pmvMatrixUniform, colorU);
             System.err.println("gear3 reused: "+gear3);
-        }                
+        }
     
         final Object upstreamWidget = drawable.getUpstreamWidget();
         if (upstreamWidget instanceof Window) {
@@ -187,7 +197,8 @@ public class GearsES2 implements GLEventListener {
     }
 
     public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
-        System.err.println(Thread.currentThread()+" GearsES2.reshape "+x+"/"+y+" "+width+"x"+height+", swapInterval "+swapInterval);
+        System.err.println(Thread.currentThread()+" GearsES2.reshape "+x+"/"+y+" "+width+"x"+height+", swapInterval "+swapInterval+", drawable 0x"+Long.toHexString(drawable.getHandle()));
+        // Thread.dumpStack();
         GL2ES2 gl = drawable.getGL().getGL2ES2();
 
         if(-1 != swapInterval) {
@@ -241,13 +252,15 @@ public class GearsES2 implements GLEventListener {
         colorU = null;        
         st.destroy(gl);
         st = null;
-
+        
         System.err.println(Thread.currentThread()+" GearsES2.dispose FIN");
     }
 
     public void display(GLAutoDrawable drawable) {
         // Turn the gears' teeth
-        angle += 2.0f;
+        if(doRotate) {
+            angle += 2.0f;
+        }
 
         // Get the GL corresponding to the drawable we are animating
         GL2ES2 gl = drawable.getGL().getGL2ES2();
@@ -262,7 +275,7 @@ public class GearsES2 implements GLEventListener {
         
         gl.glEnable(GL.GL_CULL_FACE);
         
-        if( isFBOSlave || hasFocus ) {
+        if( ignoreFocus || hasFocus ) {
           gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
         } else {
           gl.glClearColor(0.2f, 0.2f, 0.2f, 0.0f);
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 82485ea..32cc4c4 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
@@ -26,7 +26,6 @@ import javax.media.opengl.GL;
 import javax.media.opengl.GL2ES2;
 import javax.media.opengl.GLUniformData;
 
-
 import com.jogamp.opengl.test.junit.jogl.demos.GearsObject;
 import com.jogamp.opengl.util.GLArrayDataServer;
 import com.jogamp.opengl.util.PMVMatrix;
@@ -53,7 +52,7 @@ public class GearsObjectES2 extends GearsObject {
         this.colorUniform = colorUniform;
     }
 
-    public GearsObjectES2(GearsObject shared,
+    public GearsObjectES2(GearsObjectES2 shared,
                           PMVMatrix pmvMatrix, 
                           GLUniformData pmvMatrixUniform,
                           GLUniformData colorUniform) 
@@ -70,10 +69,9 @@ public class GearsObjectES2 extends GearsObject {
     }
     
     @Override
-    public void addInterleavedVertexAndNormalArrays(GLArrayDataServer array,
-            int components) {
-        array.addGLSLSubArray("vertices", 3, GL.GL_ARRAY_BUFFER);
-        array.addGLSLSubArray("normals", 3, GL.GL_ARRAY_BUFFER);
+    public void addInterleavedVertexAndNormalArrays(GLArrayDataServer array, int components) {
+        array.addGLSLSubArray("vertices", components, GL.GL_ARRAY_BUFFER);
+        array.addGLSLSubArray("normals", components, GL.GL_ARRAY_BUFFER);
     }
 
     private void draw(GL2ES2 gl, GLArrayDataServer array, int mode) {
@@ -89,8 +87,11 @@ public class GearsObjectES2 extends GearsObject {
         pmvMatrix.glPushMatrix();
         pmvMatrix.glTranslatef(x, y, 0f);
         pmvMatrix.glRotatef(angle, 0f, 0f, 1f);
-        pmvMatrix.update();
-        st.uniform(gl, pmvMatrixUniform);
+        if( pmvMatrix.update() ) {
+            st.uniform(gl, pmvMatrixUniform);
+        } else {
+            throw new InternalError("PMVMatrix.update() returns false after mutable operations");
+        }
 
         colorUniform.setData(color);
         st.uniform(gl, colorUniform);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/FBOMix2DemosES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/Mix2TexturesES2.java
similarity index 59%
copy from src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/FBOMix2DemosES2.java
copy to src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/Mix2TexturesES2.java
index 3dfbb48..26e7e23 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/FBOMix2DemosES2.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/Mix2TexturesES2.java
@@ -29,68 +29,49 @@ import javax.media.opengl.GLEventListener;
 import javax.media.opengl.GLUniformData;
 import javax.media.opengl.fixedfunc.GLMatrixFunc;
 
-import com.jogamp.opengl.FBObject;
-import com.jogamp.opengl.FBObject.TextureAttachment;
-import com.jogamp.opengl.FBObject.Attachment.Type;
 import com.jogamp.opengl.util.GLArrayDataServer;
 import com.jogamp.opengl.util.PMVMatrix;
 import com.jogamp.opengl.util.glsl.ShaderCode;
 import com.jogamp.opengl.util.glsl.ShaderProgram;
 import com.jogamp.opengl.util.glsl.ShaderState;
 
-public class FBOMix2DemosES2 implements GLEventListener {
-    private final GearsES2 demo0;
-    private final RedSquareES2 demo1;
+public class Mix2TexturesES2 implements GLEventListener {
     private final int swapInterval;
-    private int numSamples;
-    private boolean demo0Only;
-    
     
     private final ShaderState st;
     private final PMVMatrix pmvMatrix;
+    private final GLUniformData texUnit0, texUnit1;
     
-    private final FBObject fbo0;    
-    private final FBObject fbo1;
-    
-    private TextureAttachment fbo0Tex;
-    private TextureAttachment fbo1Tex;
-        
+    private volatile int texID0, texID1;
     private ShaderProgram sp0;
     private GLUniformData pmvMatrixUniform;
     private GLArrayDataServer interleavedVBO;
-    private GLUniformData texUnit0;
-    private GLUniformData texUnit1;
     
-    public FBOMix2DemosES2(int swapInterval) {
-        demo0 = new GearsES2(-1);
-        demo0.setIsFBOSlave(true);
-        demo1 = new RedSquareES2(-1);
-        demo1.setIsFBOSlave(true);
+    public Mix2TexturesES2(int swapInterval, int texUnit0, int texUnit1) {
         this.swapInterval = swapInterval;
         
         st = new ShaderState();
         // st.setVerbose(true);        
         pmvMatrix = new PMVMatrix();
         
-        fbo0 = new FBObject();        
-        fbo1 = new FBObject();
-        
-        numSamples = 0;
-        demo0Only = false;
+        if(0 == texUnit1) {
+            this.texUnit0 = new GLUniformData("mgl_ActiveTexture", texUnit0);
+            this.texUnit1 = null;
+        } else {
+            this.texUnit0 = new GLUniformData("mgl_Texture0", texUnit0);
+            this.texUnit1 = new GLUniformData("mgl_Texture1", texUnit1);
+        }
+        this.texID0 = 0;
+        this.texID1 = 0;
     }
     
-    public void setDemo0Only(boolean v) { 
-        this.demo0Only = v; 
+    public void setTexID0(int texID) {
+        this.texID0 = texID;
     }
-    public boolean getDemo0Only() { return demo0Only; }
-    
-    public void setMSAA(int numSamples) { 
-        this.numSamples=numSamples; 
+    public void setTexID1(int texID) {
+        this.texID1 = texID;
     }
-    public int getMSAA() { return numSamples; }
-    
-    public void setDoRotation(boolean rotate) { demo1.setDoRotation(rotate); }
-    
+        
     static final String[] es2_prelude = { "#version 100\n", "precision mediump float;\n" };
     static final String gl2_prelude = "#version 110\n";
     
@@ -98,13 +79,10 @@ public class FBOMix2DemosES2 implements GLEventListener {
     public void init(GLAutoDrawable drawable) {
         final GL2ES2 gl = drawable.getGL().getGL2ES2();
         
-        demo0.init(drawable);
-        demo1.init(drawable);
-        
-        final ShaderCode vp0 = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, FBOMix2DemosES2.class, "shader",
+        final ShaderCode vp0 = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, Mix2TexturesES2.class, "shader",
                 "shader/bin", "texture01_xxx", true);
-        final ShaderCode fp0 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, FBOMix2DemosES2.class, "shader",
-                "shader/bin", "texture02_xxx", true);
+        final ShaderCode fp0 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, Mix2TexturesES2.class, "shader",
+                "shader/bin", null == texUnit1 ? "texture01_xxx" : "texture02_xxx", true);
         
         // Prelude shader code w/ GLSL profile specifics [ 1. pre-proc, 2. other ]
         int fp0Pos;
@@ -148,63 +126,21 @@ public class FBOMix2DemosES2 implements GLEventListener {
         interleavedVBO.enableBuffer(gl, false);
         st.ownAttribute(interleavedVBO, true);
                 
-        texUnit0 = new GLUniformData("mgl_Texture0", 0);
-        st.ownUniform(texUnit0);       
+        st.ownUniform(texUnit0);
         st.uniform(gl, texUnit0);
-        texUnit1 = new GLUniformData("mgl_Texture1", 1);
-        st.ownUniform(texUnit1);       
-        st.uniform(gl, texUnit1);
-        
-        st.useProgram(gl, false);
-        
-        System.err.println("**** Init");
-        resetFBOs(gl, drawable);
-        
-        fbo0.attachRenderbuffer(gl, Type.DEPTH, 24);
-        fbo0.unbind(gl);
-        fbo1.attachRenderbuffer(gl, Type.DEPTH, 24);
-        fbo1.unbind(gl);
-        gl.glEnable(GL2ES2.GL_DEPTH_TEST);
+        if(null != texUnit1) {
+            st.ownUniform(texUnit1);       
+            st.uniform(gl, texUnit1);
+        }
         
-        numSamples=fbo0.getNumSamples();
+        st.useProgram(gl, false);        
     }
     
-    /** Since we switch MSAA and non-MSAA we need to take extra care, i.e. sync msaa for both FBOs ..*/
-    private void resetFBOs(GL gl, GLAutoDrawable drawable) {
-        // remove all texture attachments, since MSAA uses just color-render-buffer
-        // and non-MSAA uses texture2d-buffer
-        fbo0.detachAllColorbuffer(gl);
-        fbo1.detachAllColorbuffer(gl);
-            
-        fbo0.reset(gl, drawable.getWidth(), drawable.getHeight(), numSamples);
-        fbo1.reset(gl, drawable.getWidth(), drawable.getHeight(), numSamples);
-        if(fbo0.getNumSamples() != fbo1.getNumSamples()) {
-            throw new InternalError("sample size mismatch: \n\t0: "+fbo0+"\n\t1: "+fbo1);
-        }        
-        numSamples = fbo0.getNumSamples();
-        
-        if(numSamples>0) {
-            fbo0.attachColorbuffer(gl, 0, true);
-            fbo1.attachColorbuffer(gl, 0, true);
-            fbo0Tex = fbo0.getSamplingSink();
-            fbo1Tex = fbo1.getSamplingSink();
-        } else {
-            fbo0Tex = fbo0.attachTexture2D(gl, 0, true);
-            fbo1Tex = fbo1.attachTexture2D(gl, 0, true);
-        }        
-    }
-
     @Override
     public void dispose(GLAutoDrawable drawable) {
         final GL2ES2 gl = drawable.getGL().getGL2ES2();
-        demo0.dispose(drawable);
-        demo1.dispose(drawable);
-        fbo0.destroy(gl);
-        fbo1.destroy(gl);
         st.destroy(gl);
         
-        fbo0Tex = null;
-        fbo1Tex = null;
         sp0 = null;
         pmvMatrixUniform = null;
         interleavedVBO = null;
@@ -214,44 +150,27 @@ public class FBOMix2DemosES2 implements GLEventListener {
     public void display(GLAutoDrawable drawable) {
         final GL2ES2 gl = drawable.getGL().getGL2ES2();
 
-        if( fbo0.getNumSamples() != numSamples ) {
-            System.err.println("**** NumSamples: "+fbo0.getNumSamples()+" -> "+numSamples);
-            resetFBOs(gl, drawable);
-        }
-        
-        if(0 < numSamples) {
-            gl.glEnable(GL.GL_MULTISAMPLE);
-        }
-        
-        fbo0.bind(gl);
-        demo0.display(drawable);
-        fbo0.unbind(gl);
-        
-        if(!demo0Only) {
-            fbo1.bind(gl);
-            demo1.display(drawable);
-            fbo1.unbind(gl);
-        }
-        
         st.useProgram(gl, true);
         gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
         gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
         
-        gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit0.intValue());
-        fbo0.use(gl, fbo0Tex);
-        if(!demo0Only) {
+        interleavedVBO.enableBuffer(gl, true);
+        
+        if(0<texID0) {
+            gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit0.intValue());
+            gl.glBindTexture(GL.GL_TEXTURE_2D, texID0);
+        }
+        
+        if(0<texID1 && null != texUnit1) {
             gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit1.intValue());
-            fbo1.use(gl, fbo1Tex);
+            gl.glBindTexture(GL.GL_TEXTURE_2D, texID1);
         }
-        interleavedVBO.enableBuffer(gl, true);
+        
+        gl.glEnable(GL.GL_TEXTURE_2D);
         
         gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, 4);
         
         interleavedVBO.enableBuffer(gl, false);
-        fbo0.unuse(gl);
-        if(!demo0Only) {
-            fbo1.unuse(gl);
-        }
         
         st.useProgram(gl, false);        
     }
@@ -264,18 +183,6 @@ public class FBOMix2DemosES2 implements GLEventListener {
             gl.setSwapInterval(swapInterval); // in case switching the drawable (impl. may bound attribute there)
         }
         
-        // if(drawable.getWidth() == fbo0.getWidth() && drawable.getHeight() == fbo0.getHeight() ) {
-            System.err.println("**** Reshape: "+width+"x"+height);
-            resetFBOs(gl, drawable);            
-        //}        
-        
-        fbo0.bind(gl);
-        demo0.reshape(drawable, x, y, width, height);
-        fbo0.unbind(gl);
-        fbo1.bind(gl);
-        demo1.reshape(drawable, x, y, width, height);
-        fbo1.unbind(gl);
-        
         pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
         pmvMatrix.glLoadIdentity();
         pmvMatrix.glOrthof(-1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 10.0f);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/MultisampleDemoES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/MultisampleDemoES2.java
index 5facc1a..691e08e 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/MultisampleDemoES2.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/MultisampleDemoES2.java
@@ -74,12 +74,15 @@ public class MultisampleDemoES2 implements GLEventListener {
     
     public void init(GLAutoDrawable glad) {
         final GL2ES2 gl = glad.getGL().getGL2ES2();
+                
         System.err.println();
+        System.err.println("req. msaa: "+multisample);
         System.err.println("Requested: " + glad.getNativeSurface().getGraphicsConfiguration().getRequestedCapabilities());
-        System.err.println();
+        multisample = multisample & glad.getChosenGLCapabilities().getNumSamples() > 0 ;
         System.err.println("Chosen   : " + glad.getChosenGLCapabilities());
+        System.err.println("has  msaa: "+multisample);
         System.err.println();
-        
+                
         final ShaderCode vp0 = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, MultisampleDemoES2.class, "shader",
                 "shader/bin", "mgl_default_xxx", true);
         final ShaderCode fp0 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, MultisampleDemoES2.class, "shader",
@@ -109,11 +112,12 @@ public class MultisampleDemoES2 implements GLEventListener {
         
         // Using predef array names, see 
         //    GLPointerFuncUtil.getPredefinedArrayIndexName(glArrayIndex);
-        immModeSink = ImmModeSink.createGLSL(gl, GL.GL_STATIC_DRAW, 40, 
+        immModeSink = ImmModeSink.createGLSL(40, 
                                               3, GL.GL_FLOAT,  // vertex
                                               4, GL.GL_FLOAT,  // color
-                                              0, GL.GL_FLOAT,// normal
-                                              0, GL.GL_FLOAT); // texture
+                                              0, GL.GL_FLOAT,  // normal
+                                              0, GL.GL_FLOAT,  // texCoords
+                                              GL.GL_STATIC_DRAW);
         final int numSteps = 20;
         final double increment = Math.PI / numSteps;
         final double radius = 1;
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/PointsDemoES2.java
similarity index 55%
copy from src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java
copy to src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/PointsDemoES2.java
index a956fe1..1e0f959 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/PointsDemoES2.java
@@ -1,5 +1,5 @@
 /**
- * Copyright 2010 JogAmp Community. All rights reserved.
+ * 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:
@@ -27,69 +27,75 @@
  */
 package com.jogamp.opengl.test.junit.jogl.demos.es2;
 
-import com.jogamp.newt.Window;
+import java.nio.FloatBuffer;
+
+import com.jogamp.common.nio.Buffers;
+import com.jogamp.opengl.test.junit.jogl.demos.PointsDemo;
 import com.jogamp.opengl.util.GLArrayDataServer;
 import com.jogamp.opengl.util.PMVMatrix;
 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.GL2ES1;
 import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GL2GL3;
 import javax.media.opengl.GLAutoDrawable;
-import javax.media.opengl.GLEventListener;
 import javax.media.opengl.GLUniformData;
 
-public class RedSquareES2 implements GLEventListener {
+public class PointsDemoES2 extends PointsDemo {
     ShaderState st;
     PMVMatrix pmvMatrix;
     GLUniformData pmvMatrixUniform;
     GLArrayDataServer vertices ;
-    GLArrayDataServer colors ;
-    long t0;
+    GLArrayDataServer pointSizes ;
     private int swapInterval = 0;
-    Window window = null;
-    float aspect = 1.0f;
-    boolean doRotate = true;
-    boolean isInitialized = false;
-    boolean isFBOSlave = false;
+    final int edge = 8; // 8*8
+    /** vec4[2]: { (sz, smooth, attnMinSz, attnMaxSz), (attnCoeff(3), attnFadeTs) } */
+    private static final String mgl_PointParams     = "mgl_PointParams";
+    
+    /** ( pointSize, pointSmooth, attn. pointMinSize, attn. pointMaxSize ) , ( attenuation coefficients 1f 0f 0f, attenuation fade theshold 1f )   */
+    private final FloatBuffer pointParams = Buffers.newDirectFloatBuffer(new float[] {  1.0f, 0.0f, 0.0f, 4096.0f, 1.0f, 0.0f, 0.0f, 1.0f }); 
 
-    public RedSquareES2(int swapInterval) {
+    public PointsDemoES2(int swapInterval) {
         this.swapInterval = swapInterval;
     }
 
-    public RedSquareES2() {
+    public PointsDemoES2() {
         this.swapInterval = 1;
     }
+    
+    public void setSmoothPoints(boolean v) { 
+        pointParams.put(1, v ? 1.0f : 0.0f); 
+    }
         
-    public void setIsFBOSlave(boolean v) { isFBOSlave = v; }
-    public void setAspect(float aspect) { this.aspect = aspect; }
-    public void setDoRotation(boolean rotate) { this.doRotate = rotate; }
+    public void setPointParams(float minSize, float maxSize, float distAttenConst, float distAttenLinear, float distAttenQuadratic, float fadeThreshold) {
+        pointParams.put(2, minSize);
+        pointParams.put(3, maxSize);
+        pointParams.put(4+0, distAttenConst);
+        pointParams.put(4+1, distAttenLinear);
+        pointParams.put(4+2, distAttenQuadratic);
+        pointParams.put(4+3, fadeThreshold);        
+    }
     
     public void init(GLAutoDrawable glad) {
-        if(isInitialized) {
-            System.err.println(Thread.currentThread()+" RedSquareES2.init skipped!");
-            return; 
-        }
-        isInitialized = true;
-        System.err.println(Thread.currentThread()+" RedSquareES2.init ...");
         GL2ES2 gl = glad.getGL().getGL2ES2();
         
-        System.err.println(Thread.currentThread()+"Chosen GLCapabilities: " + glad.getChosenGLCapabilities());
-        System.err.println(Thread.currentThread()+"INIT GL IS: " + gl.getClass().getName());
-        System.err.println(Thread.currentThread()+"GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR));
-        System.err.println(Thread.currentThread()+"GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER));
-        System.err.println(Thread.currentThread()+"GL_VERSION: " + gl.glGetString(GL.GL_VERSION));
-        
-        System.err.println(Thread.currentThread()+" GL Profile: "+gl.getGLProfile());
-        System.err.println(Thread.currentThread()+" GL:" + gl);
-        System.err.println(Thread.currentThread()+" GL_VERSION=" + gl.glGetString(GL.GL_VERSION));
+        System.err.println("GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR));
+        System.err.println("GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER));
+        System.err.println("GL_VERSION: " + gl.glGetString(GL.GL_VERSION));
+        System.err.println("GL GLSL: "+gl.hasGLSL()+", has-compiler: "+gl.isFunctionAvailable("glCompileShader")+", version "+(gl.hasGLSL() ? gl.glGetString(GL2ES2.GL_SHADING_LANGUAGE_VERSION) : "none"));
+        System.err.println("GL Profile: "+gl.getGLProfile());
         
         st = new ShaderState();
         st.setVerbose(true);
         final ShaderCode vp0 = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, this.getClass(), "shader",
-                "shader/bin", "RedSquareShader", false);
+                "shader/bin", "PointsShader", true);
         final ShaderCode fp0 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, this.getClass(), "shader",
-                "shader/bin", "RedSquareShader", false);
+                "shader/bin", "PointsShader", true);
+        vp0.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_vp);
+        fp0.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_fp);
         final ShaderProgram sp0 = new ShaderProgram();
         sp0.add(gl, vp0, System.err);
         sp0.add(gl, fp0, System.err);
@@ -105,63 +111,78 @@ public class RedSquareES2 implements GLEventListener {
         st.ownUniform(pmvMatrixUniform);
         st.uniform(gl, pmvMatrixUniform);        
         
+        st.uniform(gl, new GLUniformData(mgl_PointParams, 4, pointParams));
+        
+        final GLUniformData colorStaticUniform = new GLUniformData("mgl_ColorStatic", 4, Buffers.newDirectFloatBuffer(new float[] { 1.0f, 1.0f, 1.0f, 1.0f }) );
+        st.uniform(gl, colorStaticUniform);
+        st.ownUniform(colorStaticUniform);
+        
         // Allocate Vertex Array
-        vertices = GLArrayDataServer.createGLSL("mgl_Vertex", 3, GL.GL_FLOAT, false, 4, GL.GL_STATIC_DRAW);
-        vertices.putf(-2); vertices.putf( 2); vertices.putf( 0);
-        vertices.putf( 2); vertices.putf( 2); vertices.putf( 0);
-        vertices.putf(-2); vertices.putf(-2); vertices.putf( 0);
-        vertices.putf( 2); vertices.putf(-2); vertices.putf( 0);
+        vertices = GLArrayDataServer.createGLSL("mgl_Vertex", 3, GL.GL_FLOAT, false, edge*edge, GL.GL_STATIC_DRAW);
+        pointSizes = GLArrayDataServer.createGLSL("mgl_PointSize", 1, GL.GL_FLOAT, false, edge*edge, GL.GL_STATIC_DRAW);
+        for(int i=0; i<edge; i++) {
+            for(int j=0; j<edge; j++) {
+                final float x = -3+j*0.7f;
+                final float y = -3+i*0.7f;
+                final float p = (i*edge+j)*0.5f;
+                // System.err.println("["+j+"/"+i+"]: "+x+"/"+y+": "+p);
+                vertices.putf(x); vertices.putf(y); vertices.putf( 0);
+                pointSizes.putf(p);
+            }
+        }
         vertices.seal(gl, true);
         st.ownAttribute(vertices, true);
         vertices.enableBuffer(gl, false);
-        
-        // Allocate Color Array
-        colors= GLArrayDataServer.createGLSL("mgl_Color", 4, GL.GL_FLOAT, false, 4, GL.GL_STATIC_DRAW);
-        colors.putf(1); colors.putf(0); colors.putf(0); colors.putf(1);
-        colors.putf(0); colors.putf(0); colors.putf(1); colors.putf(1);
-        colors.putf(1); colors.putf(0); colors.putf(0); colors.putf(1);
-        colors.putf(1); colors.putf(0); colors.putf(0); colors.putf(1);
-        colors.seal(gl, true);          
-        st.ownAttribute(colors, true);
-        colors.enableBuffer(gl, false);
-        
+        pointSizes.seal(gl, true);
+        st.ownAttribute(pointSizes, true);
+        pointSizes.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");
     }
 
     public void display(GLAutoDrawable glad) {
-        long t1 = System.currentTimeMillis();
-
         GL2ES2 gl = glad.getGL().getGL2ES2();
-        gl.glClearColor(0, 0, 0, 0);
+        gl.glClearColor(0f, 0f, 0f, 0f);
         gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
         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 = ((float) (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
+        GLUniformData ud = st.getUniform(mgl_PointParams);
+        if(null!=ud) {
+            // same data object 
+            st.uniform(gl, ud);
+        }
+        
         vertices.enableBuffer(gl, true);
-        colors.enableBuffer(gl, true);
-        gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, 4);
+        pointSizes.enableBuffer(gl, true);
+        
+        if(gl.isGL2GL3()) {
+            gl.glEnable(GL2GL3.GL_VERTEX_PROGRAM_POINT_SIZE);
+        }
+        if(gl.isGL2ES1()) {
+            gl.glEnable(GL2ES1.GL_POINT_SPRITE); // otherwise no gl_PointCoord
+        }
+        gl.glEnable ( GL.GL_BLEND );
+        gl.glBlendFunc ( GL.GL_SRC_ALPHA, GL.GL_ONE );
+
+        gl.glDrawArrays(GL.GL_POINTS, 0, edge*edge);
+        
+        if(gl.isGL2GL3()) {
+            gl.glDisable(GL2GL3.GL_VERTEX_PROGRAM_POINT_SIZE);
+        }
+        
+        pointSizes.enableBuffer(gl, false);
         vertices.enableBuffer(gl, false);
-        colors.enableBuffer(gl, false);
         st.useProgram(gl, false);
     }
 
     public void reshape(GLAutoDrawable glad, int x, int y, int width, int height) {
-        System.err.println(Thread.currentThread()+" RedSquareES2.reshape "+x+"/"+y+" "+width+"x"+height+", swapInterval "+swapInterval);        
+        // Thread.dumpStack();
         GL2ES2 gl = glad.getGL().getGL2ES2();
         
         if(-1 != swapInterval) {        
@@ -172,26 +193,17 @@ public class RedSquareES2 implements GLEventListener {
         // Set location in front of camera
         pmvMatrix.glMatrixMode(PMVMatrix.GL_PROJECTION);
         pmvMatrix.glLoadIdentity();
-        pmvMatrix.gluPerspective(45.0F, ( (float) width / (float) height ) / aspect, 1.0F, 100.0F);
+        pmvMatrix.gluPerspective(45.0F, ( (float) width / (float) height ) / 1.0f, 1.0F, 100.0F);
         //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");
     }
 
     public void dispose(GLAutoDrawable glad) {
-        if(!isInitialized) {
-            System.err.println(Thread.currentThread()+" RedSquareES2.dispose skipped!");
-            return; 
-        }
-        isInitialized = false;
-        System.err.println(Thread.currentThread()+" RedSquareES2.dispose ... ");
         GL2ES2 gl = glad.getGL().getGL2ES2();
         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/RedSquareES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java
index a956fe1..bf1ca5c 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java
@@ -51,7 +51,6 @@ public class RedSquareES2 implements GLEventListener {
     float aspect = 1.0f;
     boolean doRotate = true;
     boolean isInitialized = false;
-    boolean isFBOSlave = false;
 
     public RedSquareES2(int swapInterval) {
         this.swapInterval = swapInterval;
@@ -61,7 +60,6 @@ public class RedSquareES2 implements GLEventListener {
         this.swapInterval = 1;
     }
         
-    public void setIsFBOSlave(boolean v) { isFBOSlave = v; }
     public void setAspect(float aspect) { this.aspect = aspect; }
     public void setDoRotation(boolean rotate) { this.doRotate = rotate; }
     
@@ -74,22 +72,26 @@ public class RedSquareES2 implements GLEventListener {
         System.err.println(Thread.currentThread()+" RedSquareES2.init ...");
         GL2ES2 gl = glad.getGL().getGL2ES2();
         
-        System.err.println(Thread.currentThread()+"Chosen GLCapabilities: " + glad.getChosenGLCapabilities());
-        System.err.println(Thread.currentThread()+"INIT GL IS: " + gl.getClass().getName());
-        System.err.println(Thread.currentThread()+"GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR));
-        System.err.println(Thread.currentThread()+"GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER));
-        System.err.println(Thread.currentThread()+"GL_VERSION: " + gl.glGetString(GL.GL_VERSION));
-        
-        System.err.println(Thread.currentThread()+" GL Profile: "+gl.getGLProfile());
-        System.err.println(Thread.currentThread()+" GL:" + gl);
-        System.err.println(Thread.currentThread()+" GL_VERSION=" + gl.glGetString(GL.GL_VERSION));
+        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("GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR));
+        System.err.println("GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER));
+        System.err.println("GL_VERSION: " + gl.glGetString(GL.GL_VERSION));
+        System.err.println("GL GLSL: "+gl.hasGLSL()+", has-compiler: "+gl.isFunctionAvailable("glCompileShader")+", version "+(gl.hasGLSL() ? gl.glGetString(GL2ES2.GL_SHADING_LANGUAGE_VERSION) : "none"));
+        System.err.println("GL FBO: basic "+ gl.hasBasicFBOSupport()+", full "+gl.hasFullFBOSupport());
+        System.err.println("GL Profile: "+gl.getGLProfile());
+        System.err.println("GL Renderer Quirks:" + gl.getContext().getRendererQuirks().toString());
+        System.err.println("GL:" + gl + ", " + gl.getContext().getGLVersion());
         
         st = new ShaderState();
         st.setVerbose(true);
         final ShaderCode vp0 = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, this.getClass(), "shader",
-                "shader/bin", "RedSquareShader", false);
+                "shader/bin", "RedSquareShader", true);
         final ShaderCode fp0 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, this.getClass(), "shader",
-                "shader/bin", "RedSquareShader", false);
+                "shader/bin", "RedSquareShader", true);
+        vp0.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_vp);
+        fp0.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_fp);
         final ShaderProgram sp0 = new ShaderProgram();
         sp0.add(gl, vp0, System.err);
         sp0.add(gl, fp0, System.err);
@@ -161,7 +163,8 @@ public class RedSquareES2 implements GLEventListener {
     }
 
     public void reshape(GLAutoDrawable glad, int x, int y, int width, int height) {
-        System.err.println(Thread.currentThread()+" RedSquareES2.reshape "+x+"/"+y+" "+width+"x"+height+", swapInterval "+swapInterval);        
+        System.err.println(Thread.currentThread()+" RedSquareES2.reshape "+x+"/"+y+" "+width+"x"+height+", swapInterval "+swapInterval+", drawable 0x"+Long.toHexString(glad.getHandle()));
+        // Thread.dumpStack();
         GL2ES2 gl = glad.getGL().getGL2ES2();
         
         if(-1 != swapInterval) {        
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureDraw01ES2Listener.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureDraw01ES2Listener.java
index 6e70165..4bcb073 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureDraw01ES2Listener.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureDraw01ES2Listener.java
@@ -62,8 +62,6 @@ public class TextureDraw01ES2Listener implements GLEventListener, TextureDraw01A
         this.textureData = td;
     }
 
-    static final String[] es2_prelude = { "#version 100\n", "precision mediump float;\n" };
-    static final String gl2_prelude = "#version 110\n";
     static final String shaderBasename = "texture01_xxx";
     
     private void initShader(GL2ES2 gl, boolean use_program) {
@@ -72,19 +70,8 @@ public class TextureDraw01ES2Listener implements GLEventListener, TextureDraw01A
                                             "shader", "shader/bin", shaderBasename, true);
         ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, this.getClass(), 
                                             "shader", "shader/bin", shaderBasename, true);
-        
-        // Prelude shader code w/ GLSL profile specifics [ 1. pre-proc, 2. other ]
-        int rsFpPos;
-        if(gl.isGLES2()) {
-            rsVp.insertShaderSource(0, 0, es2_prelude[0]);
-            rsFpPos = rsFp.insertShaderSource(0, 0, es2_prelude[0]);
-        } else {
-            rsVp.insertShaderSource(0, 0, gl2_prelude);
-            rsFpPos = rsFp.insertShaderSource(0, 0, gl2_prelude);
-        }
-        if(gl.isGLES2()) {
-            rsFpPos = rsFp.insertShaderSource(0, rsFpPos, es2_prelude[1]);
-        }        
+        rsVp.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_vp);
+        rsFp.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_fp);
         
         // Create & Link the shader program
         ShaderProgram sp = new ShaderProgram();
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2AWT.java
index b3fdaa0..07899b7 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2AWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2AWT.java
@@ -60,12 +60,16 @@ import org.junit.Test;
 
 public class TestGearsES2AWT extends UITestCase {
     static int width, height;
-    static boolean firstUIActionOnProcess = false;
     static boolean forceES2 = false;
+    static boolean forceGL3 = false;
     static boolean shallUseOffscreenLayer = false;
+    static boolean shallUseOffscreenPBufferLayer = false;
+    static boolean useMSAA = false;
     static boolean addComp = true;
+    static boolean shutdownRemoveGLCanvas = true;
+    static boolean shutdownDisposeFrame = true;
+    static boolean shutdownSystemExit = false;
     static int swapInterval = 1;
-    static boolean showFPS = false;    
 
     @BeforeClass
     public static void initClass() {
@@ -83,7 +87,6 @@ public class TestGearsES2AWT extends UITestCase {
 
         final GLCanvas glCanvas = new GLCanvas(caps);
         Assert.assertNotNull(glCanvas);
-        glCanvas.setShallUseOffscreenLayer(shallUseOffscreenLayer);
         Dimension glc_sz = new Dimension(width, height);
         glCanvas.setMinimumSize(glc_sz);
         glCanvas.setPreferredSize(glc_sz);
@@ -112,8 +115,8 @@ public class TestGearsES2AWT extends UITestCase {
                 frame.pack();
                 frame.setVisible(true);
             }});
-        animator.setUpdateFPSFrames(60, System.err);
         animator.start();
+        animator.setUpdateFPSFrames(60, System.err);
 
         while(!quitAdapter.shouldQuit() /* && animator.isAnimating() */ && animator.getTotalFPSDuration()<duration) {
             Thread.sleep(100);
@@ -129,14 +132,39 @@ public class TestGearsES2AWT extends UITestCase {
         Assert.assertEquals(false, frame.isVisible());
         javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
             public void run() {
-                frame.remove(glCanvas);
-                frame.dispose();
+                if(shutdownRemoveGLCanvas) {
+                    frame.remove(glCanvas);
+                }
+                if(shutdownDisposeFrame) {
+                    frame.dispose();
+                }
+                if(shutdownSystemExit) {
+                    System.exit(0);
+                }
             }});
     }
 
     @Test
     public void test01() throws InterruptedException, InvocationTargetException {
-        GLCapabilities caps = new GLCapabilities(forceES2 ? GLProfile.get(GLProfile.GLES2) : GLProfile.getGL2ES2());        
+        final GLProfile glp;
+        if(forceGL3) {
+            glp = GLProfile.get(GLProfile.GL3);
+        } else if(forceES2) {
+            glp = GLProfile.get(GLProfile.GLES2);
+        } else {
+            glp = GLProfile.getGL2ES2();
+        }
+        final GLCapabilities caps = new GLCapabilities(glp);
+        if(useMSAA) {
+            caps.setNumSamples(4);
+            caps.setSampleBuffers(true);
+        }
+        if(shallUseOffscreenLayer) {
+            caps.setOnscreen(false);
+        }
+        if(shallUseOffscreenPBufferLayer) {
+            caps.setPBuffer(true);
+        }
         runTestGL(caps);
     }
 
@@ -153,22 +181,34 @@ public class TestGearsES2AWT extends UITestCase {
                 } catch (Exception ex) { ex.printStackTrace(); }
             } else if(args[i].equals("-es2")) {
                 forceES2 = true;
+            } else if(args[i].equals("-gl3")) {
+                forceGL3 = true;
             } else if(args[i].equals("-vsync")) {
                 i++;
                 swapInterval = MiscUtils.atoi(args[i], swapInterval);
             } else if(args[i].equals("-layered")) {
                 shallUseOffscreenLayer = true;
-            } else if(args[i].equals("-showFPS")) {
-                showFPS = true;
-            } else if(args[i].equals("-firstUIAction")) {
-                firstUIActionOnProcess = true;
+            } else if(args[i].equals("-layeredPBuffer")) {
+                shallUseOffscreenPBufferLayer = true;
+            } else if(args[i].equals("-msaa")) {
+                useMSAA = true;
             } else if(args[i].equals("-wait")) {
                 waitForKey = true;
             } else if(args[i].equals("-justGears")) {
                 addComp = false;
+            } else if(args[i].equals("-shutdownKeepGLCanvas")) {
+                shutdownRemoveGLCanvas = false;
+            } else if(args[i].equals("-shutdownKeepFrame")) {
+                shutdownDisposeFrame = false;
+            } else if(args[i].equals("-shutdownKeepAll")) {
+                shutdownRemoveGLCanvas = false;
+                shutdownDisposeFrame = false;
+            } else if(args[i].equals("-shutdownSystemExit")) {
+                shutdownSystemExit = true;
             }
         }
         System.err.println("forceES2 "+forceES2);
+        System.err.println("forceGL3 "+forceGL3);
         System.err.println("swapInterval "+swapInterval);
         System.err.println("shallUseOffscreenLayer "+shallUseOffscreenLayer);
         
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 fab5bf9..86831a6 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
@@ -75,6 +75,7 @@ public class TestGearsES2NEWT extends UITestCase {
 
     static long duration = 500; // ms
     static boolean opaque = true;
+    static int forceAlpha = -1;
     static boolean undecorated = false;
     static boolean alwaysOnTop = false;
     static boolean fullscreen = false;
@@ -85,8 +86,10 @@ public class TestGearsES2NEWT extends UITestCase {
     static boolean mouseConfined = false;
     static boolean showFPS = false;
     static int loops = 1;
-    static GLProfile.ShutdownType loop_shutdown = null;
+    static boolean loop_shutdown = false;
     static boolean forceES2 = false;
+    static boolean forceGL3 = false;
+    static boolean mainRun = false;
     
     @BeforeClass
     public static void initClass() {
@@ -255,16 +258,41 @@ public class TestGearsES2NEWT extends UITestCase {
     public void test01GL2ES2() throws InterruptedException {
         for(int i=1; i<=loops; i++) {
             System.err.println("Loop "+i+"/"+loops);
-            GLCapabilities caps = new GLCapabilities(forceES2 ? GLProfile.get(GLProfile.GLES2) : GLProfile.getGL2ES2());
+            final GLProfile glp;
+            if(forceGL3) {
+                glp = GLProfile.get(GLProfile.GL3);
+            } else if(forceES2) {
+                glp = GLProfile.get(GLProfile.GLES2);
+            } else {
+                glp = GLProfile.getGL2ES2();
+            }
+            final GLCapabilities caps = new GLCapabilities( glp );
             caps.setBackgroundOpaque(opaque);
+            if(-1 < forceAlpha) {
+                caps.setAlphaBits(forceAlpha); 
+            }
             runTestGL(caps, undecorated);
-            if(null != loop_shutdown) {
-                GLProfile.shutdown(loop_shutdown);
+            if(loop_shutdown) {
+                GLProfile.shutdown();
             }
         }
     }
 
-    public static void main(String args[]) throws IOException {        
+    @Test
+    public void test02GL3() throws InterruptedException {
+        if(mainRun) return;
+        
+        if( !GLProfile.isAvailable(GLProfile.GL3) ) {
+            System.err.println("GL3 n/a");
+        }
+        final GLProfile glp = GLProfile.get(GLProfile.GL3);
+        final GLCapabilities caps = new GLCapabilities( glp );
+        runTestGL(caps, undecorated);
+    }
+    
+    public static void main(String args[]) throws IOException {
+        mainRun = true;
+        
         int x=0, y=0, w=640, h=480;
         boolean usePos = false;
         
@@ -274,6 +302,9 @@ public class TestGearsES2NEWT extends UITestCase {
                 duration = MiscUtils.atol(args[i], duration);
             } else if(args[i].equals("-translucent")) {
                 opaque = false;
+            } else if(args[i].equals("-forceAlpha")) {
+                i++;
+                forceAlpha = MiscUtils.atoi(args[i], 0);
             } else if(args[i].equals("-undecorated")) {
                 undecorated = true;
             } else if(args[i].equals("-atop")) {
@@ -287,6 +318,8 @@ public class TestGearsES2NEWT extends UITestCase {
                 swapInterval = MiscUtils.atoi(args[i], swapInterval);
             } else if(args[i].equals("-es2")) {
                 forceES2 = true;
+            } else if(args[i].equals("-gl3")) {
+                forceGL3 = true;
             } else if(args[i].equals("-wait")) {
                 waitForKey = true;
             } else if(args[i].equals("-mouseInvisible")) {
@@ -316,12 +349,7 @@ public class TestGearsES2NEWT extends UITestCase {
                 i++;
                 loops = MiscUtils.atoi(args[i], 1);
             } else if(args[i].equals("-loop-shutdown")) {
-                i++;
-                switch(MiscUtils.atoi(args[i], 0)) {
-                    case 1: loop_shutdown = GLProfile.ShutdownType.SHARED_ONLY; break; 
-                    case 2: loop_shutdown = GLProfile.ShutdownType.COMPLETE; break;
-                    default: throw new IllegalArgumentException("should be [0..2], 0-off, 1-shared, 2-complete");
-                }
+                loop_shutdown = true;
             }
         }
         wsize = new Dimension(w, h);
@@ -333,6 +361,7 @@ public class TestGearsES2NEWT extends UITestCase {
         System.err.println("size "+wsize);
         System.err.println("screen "+screenIdx);
         System.err.println("translucent "+(!opaque));
+        System.err.println("forceAlpha "+forceAlpha);        
         System.err.println("undecorated "+undecorated);
         System.err.println("atop "+alwaysOnTop);
         System.err.println("fullscreen "+fullscreen);
@@ -343,6 +372,7 @@ public class TestGearsES2NEWT extends UITestCase {
         System.err.println("loops "+loops);
         System.err.println("loop shutdown "+loop_shutdown);
         System.err.println("forceES2 "+forceES2);
+        System.err.println("forceGL3 "+forceGL3);
 
         if(waitForKey) {
             BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
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 ff231ef..dbba4fa 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
@@ -51,9 +51,11 @@ import org.junit.Test;
 public class TestRedSquareES2NEWT extends UITestCase {
     static int width, height;
     static int loops = 1;
-    static GLProfile.ShutdownType loop_shutdown = null;
+    static boolean loop_shutdown = false;
     static boolean vsync = false;
     static boolean forceES2 = false;
+    static boolean forceGL3 = false;
+    static boolean mainRun = false;
     static boolean doRotate = true;
 
     @BeforeClass
@@ -127,17 +129,38 @@ public class TestRedSquareES2NEWT extends UITestCase {
     public void test01GL2ES2() throws InterruptedException {
         for(int i=1; i<=loops; i++) {
             System.err.println("Loop "+i+"/"+loops);
-            GLCapabilities caps = new GLCapabilities(forceES2 ? GLProfile.get(GLProfile.GLES2) : GLProfile.getGL2ES2());
+            final GLProfile glp;
+            if(forceGL3) {
+                glp = GLProfile.get(GLProfile.GL3);
+            } else if(forceES2) {
+                glp = GLProfile.get(GLProfile.GLES2);
+            } else {
+                glp = GLProfile.getGL2ES2();
+            }
+            final GLCapabilities caps = new GLCapabilities(glp);
             runTestGL(caps);
-            if(null != loop_shutdown) {
-                GLProfile.shutdown(loop_shutdown);
+            if(loop_shutdown) {
+                GLProfile.shutdown();
             }
         }
     }
+    
+    @Test
+    public void test02GL3() throws InterruptedException {
+        if(mainRun) return;
+        
+        if( !GLProfile.isAvailable(GLProfile.GL3) ) {
+            System.err.println("GL3 n/a");
+        }
+        final GLProfile glp = GLProfile.get(GLProfile.GL3);
+        final GLCapabilities caps = new GLCapabilities( glp );
+        runTestGL(caps);
+    }    
 
     static long duration = 500; // ms
 
     public static void main(String args[]) {
+        mainRun = true;
         for(int i=0; i<args.length; i++) {
             if(args[i].equals("-time")) {
                 i++;
@@ -146,23 +169,21 @@ public class TestRedSquareES2NEWT extends UITestCase {
                 } catch (Exception ex) { ex.printStackTrace(); }
             } else if(args[i].equals("-es2")) {
                 forceES2 = true;
+            } else if(args[i].equals("-gl3")) {
+                forceGL3 = true;
             } else if(args[i].equals("-norotate")) {
                 doRotate = false;
             } else if(args[i].equals("-loops")) {
                 i++;
                 loops = MiscUtils.atoi(args[i], 1);
             } else if(args[i].equals("-loop-shutdown")) {
-                i++;
-                switch(MiscUtils.atoi(args[i], 0)) {
-                    case 1: loop_shutdown = GLProfile.ShutdownType.SHARED_ONLY; break; 
-                    case 2: loop_shutdown = GLProfile.ShutdownType.COMPLETE; break;
-                    default: throw new IllegalArgumentException("should be [0..2], 0-off, 1-shared, 2-complete");
-                }
+                loop_shutdown = true;
             }
         }
         System.err.println("loops "+loops);
         System.err.println("loop shutdown "+loop_shutdown);
         System.err.println("forceES2 "+forceES2);
+        System.err.println("forceGL3 "+forceGL3);
         org.junit.runner.JUnitCore.main(TestRedSquareES2NEWT.class.getName());
     }
 }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/PointsShader.fp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/PointsShader.fp
new file mode 100644
index 0000000..3210762
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/PointsShader.fp
@@ -0,0 +1,47 @@
+
+#if __VERSION__ >= 130
+  #define varying in
+  out vec4 mgl_FragColor;
+#else
+  #define mgl_FragColor gl_FragColor   
+#endif
+
+// [0].rgba: 0, smooth, attnMinSz, attnMaxSz
+// [1].rgba: attnCoeff(3), attnFadeTs
+uniform vec4 mgl_PointParams[2]; 
+
+#define pointSmooth                 (mgl_PointParams[0].g)
+
+varying vec4 frontColor;
+
+// #define TEST 1
+
+void main (void)
+{ 
+  mgl_FragColor = frontColor;
+
+  if( pointSmooth > 0.5 ) {
+      // smooth (AA)
+      const float border = 0.90; // take/give 10% for AA
+
+      // origin to 0/0, [-1/-1 .. 1/1]
+      vec2 pointPos = 2.0 * gl_PointCoord - 1.0 ;
+      float r = length( pointPos ); // one-circle sqrt(x * x + y * y), range: in-circle [0..1], out >1
+      float r1 = 1.0 - ( step(border, r) * 10.0 * ( r - border ) ) ; // [0..1]
+      #ifndef TEST
+          if( r1 < 0.0 ) {
+            discard;
+          }
+      #endif
+
+      #ifndef TEST
+          mgl_FragColor.a *= r1;
+      #else
+          mgl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
+          mgl_FragColor.r = r1 < 0.0 ? 1.0 : 0.0;
+          mgl_FragColor.g = r > 1.0 ? 1.0 : 0.0;
+          mgl_FragColor.b = r > border ? 1.0 : 0.0;
+      #endif
+  }
+}
+
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/PointsShader.vp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/PointsShader.vp
new file mode 100644
index 0000000..4fa49b9
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/PointsShader.vp
@@ -0,0 +1,47 @@
+
+#if __VERSION__ >= 130
+  #define attribute in
+  #define varying out
+#endif
+
+uniform vec4 mgl_ColorStatic;
+uniform mat4 mgl_PMVMatrix[4]; // P, Mv, Mvi and Mvit (transpose(inverse(ModelView)) == normalMatrix)
+
+// [0].rgba: 0, smooth, attnMinSz, attnMaxSz
+// [1].rgba: attnCoeff(3), attnFadeTs
+uniform vec4 mgl_PointParams[2]; 
+
+#define pointSmooth                 (mgl_PointParams[0].g)
+#define pointSizeMin                (mgl_PointParams[0].b)
+#define pointSizeMax                (mgl_PointParams[0].a)
+#define pointDistanceConstantAtten  (mgl_PointParams[1].r)
+#define pointDistanceLinearAtten    (mgl_PointParams[1].g)
+#define pointDistanceQuadraticAtten (mgl_PointParams[1].b)
+#define pointFadeThresholdSize      (mgl_PointParams[1].a)
+
+attribute vec4 mgl_Vertex;
+attribute float mgl_PointSize;
+
+varying vec4 frontColor;
+
+void main(void)
+{
+  frontColor = mgl_ColorStatic;
+
+  vec4 eyeCoord = mgl_PMVMatrix[1] * mgl_Vertex;
+  gl_Position = mgl_PMVMatrix[0] * eyeCoord;
+
+  float dist = distance(eyeCoord, vec4(0.0, 0.0, 0.0, 1.0));
+  float atten = sqrt( 1.0 / ( pointDistanceConstantAtten +
+                              ( pointDistanceLinearAtten +
+                                pointDistanceQuadraticAtten * dist
+                              ) * dist
+                            )
+                    );
+  float size = clamp(mgl_PointSize * atten, pointSizeMin, pointSizeMax);
+  gl_PointSize = max(size, pointFadeThresholdSize);
+
+  float fade = min(size, pointFadeThresholdSize) / pointFadeThresholdSize;
+  frontColor.a *= fade * fade;
+}
+
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/RedSquareShader.fp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/RedSquareShader.fp
index d3cfecd..60b9240 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/RedSquareShader.fp
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/RedSquareShader.fp
@@ -1,23 +1,16 @@
 // Copyright 2010 JogAmp Community. All rights reserved.
 
-/**
- * AMD complains: #version must occur before any other statement in the program
-#ifdef GL_ES
-    #version 100
+#if __VERSION__ >= 130
+  #define varying in
+  out vec4 mgl_FragColor;
 #else
-    #version 110
+  #define mgl_FragColor gl_FragColor   
 #endif
- */
 
-#ifdef GL_ES
-  precision mediump float;
-  precision mediump int;
-#endif
-
-varying   vec4    frontColor;
+varying vec4 frontColor;
 
 void main (void)
 {
-    gl_FragColor = frontColor;
+    mgl_FragColor = frontColor;
 }
 
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/RedSquareShader.vp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/RedSquareShader.vp
index bfd44c8..9283dd7 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/RedSquareShader.vp
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/RedSquareShader.vp
@@ -1,17 +1,8 @@
 // Copyright 2010 JogAmp Community. All rights reserved.
 
-/**
- * AMD complains: #version must occur before any other statement in the program
-#ifdef GL_ES
-    #version 100
-#else
-    #version 110
-#endif
- */
-
-#ifdef GL_ES
-  precision mediump float;
-  precision mediump int;
+#if __VERSION__ >= 130
+  #define attribute in
+  #define varying out
 #endif
 
 uniform mat4    mgl_PMVMatrix[2];
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/RedSquareShader2.fp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/RedSquareShader2.fp
index 01e4b09..25a2df2 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/RedSquareShader2.fp
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/RedSquareShader2.fp
@@ -1,26 +1,16 @@
 // Copyright 2010 JogAmp Community. All rights reserved.
 
-/**
- * AMD complains: #version must occur before any other statement in the program
-#ifdef GL_ES
-    #version 100
+#if __VERSION__ >= 130
+  #define varying in
+  out vec4 mgl_FragColor;
 #else
-    #version 110
+  #define mgl_FragColor gl_FragColor   
 #endif
- */
 
-#ifdef GL_ES
-  #define MEDIUMP mediump
-  #define HIGHP highp
-#else
-  #define MEDIUMP
-  #define HIGHP
-#endif
-
-varying   HIGHP vec4    frontColor;
+varying vec4 frontColor;
 
 void main (void)
 {
-    gl_FragColor = vec4(0.0, frontColor.g, frontColor.b, 1.0);
+    mgl_FragColor = vec4(0.0, frontColor.g, frontColor.b, 1.0);
 }
 
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/default.vp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/default.vp
index 99ad6e4..2037086 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/default.vp
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/default.vp
@@ -1,5 +1,10 @@
 //Copyright 2010 JogAmp Community. All rights reserved.
 
+#if __VERSION__ >= 130
+  #define attribute in
+  #define varying out
+#endif
+
 #ifdef GL_ES
   #define MEDIUMP mediump
   #define HIGHP highp
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/elektronenmultiplizierer_development.fp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/elektronenmultiplizierer_development.fp
index 22fb65e..60f054b 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/elektronenmultiplizierer_development.fp
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/elektronenmultiplizierer_development.fp
@@ -9,6 +9,14 @@
  * author: Dominik Stroehlein (DemoscenePassivist) 
  **/
 
+#if __VERSION__ >= 130
+  #define varying in
+  out vec4 mgl_FragColor;
+  #define texture2D texture
+#else
+  #define mgl_FragColor gl_FragColor   
+#endif
+
 #ifdef GL_ES
   precision mediump float;
   precision mediump sampler2D;
@@ -343,7 +351,7 @@ void main() {
         color = raymarch_orbittrap_image(oglFragCoord.xy);
     } 
     if (en==2 || en==7) {
-        gl_FragColor = color;
+        mgl_FragColor = color;
     } else {
         //do normal rendering ...    
         //analog-tv distortion ...
@@ -376,6 +384,6 @@ void main() {
         //tv flicker effect
         color_tv *= 0.97+0.13*sin(2.5*tm);
         color_tv *= br;
-        gl_FragColor = vec4(color_tv,1.0);
+        mgl_FragColor = vec4(color_tv,1.0);
     }       
 }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/elektronenmultiplizierer_port.fp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/elektronenmultiplizierer_port.fp
index d3df819..77c34f7 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/elektronenmultiplizierer_port.fp
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/elektronenmultiplizierer_port.fp
@@ -12,6 +12,14 @@
 //When I wrote this, only God and I understood what I was doing ...
 // ... now only God knows! X-)
 
+#if __VERSION__ >= 130
+  #define varying in
+  out vec4 mgl_FragColor;
+  #define texture2D texture
+#else
+  #define mgl_FragColor gl_FragColor   
+#endif
+
 uniform int en;
 uniform float et;
 uniform sampler2D fb;
@@ -209,7 +217,7 @@ void main() {
     } else
         n=D(c.xy);
     if(en==2||en==7)
-        gl_FragColor=n;
+        mgl_FragColor=n;
     else {
         vec2 i=c.xy/v.xy;
         i.y*=-1.;
@@ -229,6 +237,6 @@ void main() {
         x*=.9+.1*sin(1.5*tm+i.y*1000.);
         x*=.97+.13*sin(2.5*tm);
         x*=br;
-        gl_FragColor=vec4(x,1.);
+        mgl_FragColor=vec4(x,1.);
     }
 }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/gears.fp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/gears.fp
index f41adda..14328dc 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/gears.fp
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/gears.fp
@@ -1,9 +1,11 @@
 // Copyright (C) 2011 JogAmp Community. All rights reserved.
 // Details see GearsES2.java
 
-#ifdef GL_ES
-  precision mediump float;
-  precision mediump int;
+#if __VERSION__ >= 130
+  #define varying in
+  out vec4 mgl_FragColor;
+#else
+  #define mgl_FragColor gl_FragColor   
 #endif
 
 uniform vec4 color;
@@ -42,5 +44,5 @@ void main()
         specular += color * pow(NdotHV, matShininess) * attenuation * matSpecular;
     }
         
-    gl_FragColor = ambient + diffuse + specular ;
+    mgl_FragColor = ambient + diffuse + specular ;
 }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/gears.vp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/gears.vp
index b2d7708..24f4f9c 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/gears.vp
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/gears.vp
@@ -1,10 +1,11 @@
 // Copyright (C) 2011 JogAmp Community. All rights reserved.
 // Details see GearsES2.java
 
-#ifdef GL_ES
-  precision mediump float;
-  precision mediump int;
+#if __VERSION__ >= 130
+  #define attribute in
+  #define varying out
 #endif
+
 uniform mat4 pmvMatrix[4]; // P, Mv, Mvi and Mvit
 uniform vec3 lightPos;
 
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/mgl_default_xxx.fp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/mgl_default_xxx.fp
index a26dc97..a2abf9e 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/mgl_default_xxx.fp
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/mgl_default_xxx.fp
@@ -1,10 +1,16 @@
 // Copyright 2012 JogAmp Community. All rights reserved.
 
+#if __VERSION__ >= 130
+  #define varying in
+  out vec4 mgl_FragColor;
+#else
+  #define mgl_FragColor gl_FragColor   
+#endif
+
 varying  vec4          frontColor;
 
 void main (void)
 {
-  gl_FragColor = frontColor;
-  // gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+  mgl_FragColor = frontColor;
 }
 
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/mgl_default_xxx.vp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/mgl_default_xxx.vp
index 097a73e..98e7916 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/mgl_default_xxx.vp
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/mgl_default_xxx.vp
@@ -1,5 +1,9 @@
 //Copyright 2012 JogAmp Community. All rights reserved.
 
+#if __VERSION__ >= 130
+  #define attribute in
+  #define varying out
+#endif
 
 uniform mat4    mgl_PMVMatrix[2]; // P, Mv
 attribute vec4  mgl_Vertex;
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/ruler.fp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/ruler.fp
index b2f4d7a..f16a3ee 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/ruler.fp
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/ruler.fp
@@ -1,5 +1,12 @@
 //Copyright 2010 JogAmp Community. All rights reserved.
 
+#if __VERSION__ >= 130
+  #define varying in
+  out vec4 mgl_FragColor;
+#else
+  #define mgl_FragColor gl_FragColor   
+#endif
+
 #ifdef GL_ES
   #define MEDIUMP mediump
   #define HIGHP highp
@@ -19,7 +26,7 @@ void main (void)
 {
   MEDIUMP vec2 c = step( onev2, mod(gl_FragCoord.xy, gcu_RulerPixFreq) );
   if( c.s == 0.0 || c.t == 0.0 ) {
-    gl_FragColor = vec4(gcu_RulerColor, 1.0);
+    mgl_FragColor = vec4(gcu_RulerColor, 1.0);
   } else {
     discard;
   }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texsequence_xxx.fp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texsequence_xxx.fp
index adde23d..5e7bd28 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texsequence_xxx.fp
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texsequence_xxx.fp
@@ -1,5 +1,12 @@
 // Copyright 2012 JogAmp Community. All rights reserved.
 
+#if __VERSION__ >= 130
+  #define varying in
+  out vec4 mgl_FragColor;
+#else
+  #define mgl_FragColor gl_FragColor   
+#endif
+
 varying  vec2          mgl_texCoord;
 varying  vec4          frontColor;
 
@@ -17,6 +24,6 @@ void main (void)
   }
 
   // mix frontColor with texture ..
-  gl_FragColor = vec4(frontColor*texColor);
+  mgl_FragColor = vec4(frontColor*texColor);
 }
 
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texsequence_xxx.vp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texsequence_xxx.vp
index c521e37..1030dab 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texsequence_xxx.vp
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texsequence_xxx.vp
@@ -1,5 +1,10 @@
 // Copyright 2012 JogAmp Community. All rights reserved.
 
+#if __VERSION__ >= 130
+  #define attribute in
+  #define varying out
+#endif
+
 uniform   mat4    mgl_PMVMatrix[2];
 // uniform  mat4  mgl_STMatrix;
 attribute vec4    mgl_Vertex;
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texture01_xxx.fp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texture01_xxx.fp
index 1a42541..c213f3a 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texture01_xxx.fp
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texture01_xxx.fp
@@ -1,5 +1,13 @@
 // Copyright 2012 JogAmp Community. All rights reserved.
 
+#if __VERSION__ >= 130
+  #define varying in
+  out vec4 mgl_FragColor;
+  #define texture2D texture
+#else
+  #define mgl_FragColor gl_FragColor   
+#endif
+
 varying  vec2          mgl_texCoord;
 varying  vec4          frontColor;
 
@@ -15,6 +23,6 @@ void main (void)
   }
 
   // mix frontColor with texture ..
-  gl_FragColor = vec4(frontColor*texColor);
+  mgl_FragColor = vec4(frontColor*texColor);
 }
 
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texture01_xxx.vp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texture01_xxx.vp
index c521e37..1030dab 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texture01_xxx.vp
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texture01_xxx.vp
@@ -1,5 +1,10 @@
 // Copyright 2012 JogAmp Community. All rights reserved.
 
+#if __VERSION__ >= 130
+  #define attribute in
+  #define varying out
+#endif
+
 uniform   mat4    mgl_PMVMatrix[2];
 // uniform  mat4  mgl_STMatrix;
 attribute vec4    mgl_Vertex;
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texture02_xxx.fp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texture02_xxx.fp
index d222606..10073e8 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texture02_xxx.fp
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texture02_xxx.fp
@@ -1,5 +1,13 @@
 // Copyright 2012 JogAmp Community. All rights reserved.
 
+#if __VERSION__ >= 130
+  #define varying in
+  out vec4 mgl_FragColor;
+  #define texture2D texture
+#else
+  #define mgl_FragColor gl_FragColor   
+#endif
+
 varying  vec2          mgl_texCoord;
 varying  vec4          frontColor;
 
@@ -13,8 +21,8 @@ void main (void)
   vec4 texColor0 = texture2D(mgl_Texture0, mgl_texCoord);
   vec4 texColor1 = texture2D(mgl_Texture1, mgl_texCoord);
 
-  // gl_FragColor = ( ( texColor0 + texColor1 ) / 2.0 ) * frontColor;
-  // gl_FragColor = mix(texColor0, texColor1, One/2.0) * frontColor;
-  gl_FragColor = min(One, mix(texColor0, texColor1, One/2.0) * 1.6) * frontColor;
+  // mgl_FragColor = ( ( texColor0 + texColor1 ) / 2.0 ) * frontColor;
+  // mgl_FragColor = mix(texColor0, texColor1, One/2.0) * frontColor;
+  mgl_FragColor = min(One, mix(texColor0, texColor1, One/2.0) * 1.6) * frontColor;
 }
 
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/Gears.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/Gears.java
index b3166b0..9c1293e 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/Gears.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/Gears.java
@@ -1,7 +1,9 @@
 
 package com.jogamp.opengl.test.junit.jogl.demos.gl2;
 
+import javax.media.opengl.GL;
 import javax.media.opengl.GL2;
+import javax.media.opengl.GL2ES2;
 import javax.media.opengl.GLAutoDrawable;
 import javax.media.opengl.GLEventListener;
 import javax.media.opengl.GLProfile;
@@ -71,11 +73,16 @@ public class Gears implements GLEventListener {
 
     GL2 gl = drawable.getGL().getGL2();
 
+    System.err.println("Gears (GL2) init on "+Thread.currentThread());
     System.err.println("Chosen GLCapabilities: " + drawable.getChosenGLCapabilities());
     System.err.println("INIT GL IS: " + gl.getClass().getName());
-    System.err.println("GL_VENDOR: " + gl.glGetString(GL2.GL_VENDOR));
-    System.err.println("GL_RENDERER: " + gl.glGetString(GL2.GL_RENDERER));
-    System.err.println("GL_VERSION: " + gl.glGetString(GL2.GL_VERSION));
+    System.err.println("GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR));
+    System.err.println("GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER));
+    System.err.println("GL_VERSION: " + gl.glGetString(GL.GL_VERSION));
+    System.err.println("GL GLSL: "+gl.hasGLSL()+", has-compiler: "+gl.isFunctionAvailable("glCompileShader")+", version "+(gl.hasGLSL() ? gl.glGetString(GL2ES2.GL_SHADING_LANGUAGE_VERSION) : "none"));
+    System.err.println("GL FBO: basic "+ gl.hasBasicFBOSupport()+", full "+gl.hasFullFBOSupport());
+    System.err.println("GL Profile: "+gl.getGLProfile());
+    System.err.println("GL:" + gl + ", " + gl.getContext().getGLVersion());
 
     float pos[] = { 5.0f, 5.0f, 10.0f, 0.0f };
     float red[] = { 0.8f, 0.1f, 0.0f, 0.7f };
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/awt/TestGLJPanelAWTBug450.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/awt/TestGLJPanelAWTBug450.java
index 4f97feb..bd9b7ca 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/awt/TestGLJPanelAWTBug450.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/awt/TestGLJPanelAWTBug450.java
@@ -117,7 +117,7 @@ public class TestGLJPanelAWTBug450 extends UITestCase {
                 }
                 if(0 == f) {
                     System.err.println("BGR ("+r_x+"/"+r_y+"): "+byte0+", "+byte1+", "+byte2+" - OK "+(!failed));
-                    snapshot(getSimpleTestName("."), f, null, gl, screenshot, TextureIO.PNG, null);
+                    snapshot(f, null, gl, screenshot, TextureIO.PNG, null);
                 }
                 f++;
             }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/newt/TestGearsNewtAWTWrapper.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/newt/TestGearsNewtAWTWrapper.java
index 62914bd..cc20cc2 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/newt/TestGearsNewtAWTWrapper.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/newt/TestGearsNewtAWTWrapper.java
@@ -33,6 +33,7 @@ import javax.media.opengl.*;
 
 import com.jogamp.opengl.util.Animator;
 
+import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
 import com.jogamp.opengl.test.junit.util.UITestCase;
 import com.jogamp.opengl.test.junit.util.QuitAdapter;
 import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
@@ -78,8 +79,25 @@ public class TestGearsNewtAWTWrapper extends UITestCase {
         glWindow.addKeyListener(new TraceKeyAdapter(quitAdapter));
         glWindow.addWindowListener(new TraceWindowAdapter(quitAdapter));
 
-        glWindow.setSize(width, height);
+        int div = 3;
+        glWindow.setSize(width/div, height/div);
         glWindow.setVisible(true);
+        glWindow.display();
+        Assert.assertTrue("Size not reached: Expected "+(width/div)+"x"+(height/div)+", Is "+glWindow.getWidth()+"x"+glWindow.getHeight(), 
+                          AWTRobotUtil.waitForSize(glWindow, width/div, height/div));
+        
+        div = 2;
+        glWindow.setSize(width/div, height/div);
+        glWindow.display();
+        Assert.assertTrue("Size not reached: Expected "+(width/div)+"x"+(height/div)+", Is "+glWindow.getWidth()+"x"+glWindow.getHeight(), 
+                          AWTRobotUtil.waitForSize(glWindow, width/div, height/div));
+
+        div = 1;
+        glWindow.setSize(width/div, height/div);
+        glWindow.display();
+        Assert.assertTrue("Size not reached: Expected "+(width/div)+"x"+(height/div)+", Is "+glWindow.getWidth()+"x"+glWindow.getHeight(), 
+                          AWTRobotUtil.waitForSize(glWindow, width/div, height/div));
+
         animator.setUpdateFPSFrames(1, null);        
         animator.start();
 
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/drawable/TestDrawable01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/drawable/TestDrawable01NEWT.java
deleted file mode 100644
index 731f7c8..0000000
--- a/src/test/com/jogamp/opengl/test/junit/jogl/drawable/TestDrawable01NEWT.java
+++ /dev/null
@@ -1,183 +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.drawable;
-
-import com.jogamp.opengl.test.junit.util.UITestCase;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.AfterClass;
-import org.junit.Test;
-
-import javax.media.opengl.*;
-
-import com.jogamp.newt.*;
-import java.io.IOException;
-
-public class TestDrawable01NEWT extends UITestCase {
-    static GLProfile glp;
-    static GLDrawableFactory factory;
-    static int width, height;
-    GLCapabilities caps;
-    Window window;
-    GLDrawable drawable;
-    GLContext context;
-
-    @BeforeClass
-    public static void initClass() {
-        glp = GLProfile.getDefault();
-        Assert.assertNotNull(glp);
-        factory = GLDrawableFactory.getFactory(glp);
-        Assert.assertNotNull(factory);
-        width  = 640;
-        height = 480;
-    }
-
-    @AfterClass
-    public static void releaseClass() {
-        Assert.assertNotNull(factory);
-        factory=null;
-    }
-
-    @Before
-    public void initTest() {
-        caps = new GLCapabilities(glp);
-        Assert.assertNotNull(caps);
-    }
-
-    void createWindow(boolean onscreen, boolean pbuffer, boolean undecorated) {
-        caps.setOnscreen(onscreen);
-        caps.setPBuffer(!onscreen && pbuffer);
-        caps.setDoubleBuffered(onscreen);
-        // System.out.println("Requested: "+caps);
-
-        //
-        // Create native windowing resources .. X11/Win/OSX
-        // 
-        Display display = NewtFactory.createDisplay(null); // local display
-        Assert.assertNotNull(display);
-
-        Screen screen  = NewtFactory.createScreen(display, 0); // screen 0
-        Assert.assertNotNull(screen);
-
-        window = NewtFactory.createWindow(screen, caps);
-        Assert.assertNotNull(window);
-        window.setUndecorated(onscreen && undecorated);
-        window.setSize(width, height);
-        window.setVisible(true);
-        // System.out.println("Created: "+window);
-
-        //
-        // Create native OpenGL resources .. XGL/WGL/CGL .. 
-        // equivalent to GLAutoDrawable methods: setVisible(true)
-        // 
-        GLCapabilities glCaps = (GLCapabilities) window.getGraphicsConfiguration().getChosenCapabilities();
-        Assert.assertNotNull(glCaps);
-        Assert.assertTrue(glCaps.getGreenBits()>5);
-        Assert.assertTrue(glCaps.getBlueBits()>5);
-        Assert.assertTrue(glCaps.getRedBits()>5);
-        Assert.assertEquals(glCaps.isOnscreen(),onscreen);
-        Assert.assertTrue(onscreen || !pbuffer || glCaps.isPBuffer()); // pass if onscreen, or !pbuffer req. or have pbuffer
-        Assert.assertEquals(glCaps.getDoubleBuffered(),onscreen);
-        Assert.assertTrue(glCaps.getDepthBits()>4);
-
-        drawable = factory.createGLDrawable(window);
-        Assert.assertNotNull(drawable);
-        // System.out.println("Pre: "+drawable);
-        //
-        drawable.setRealized(true);
-        // Assert.assertEquals(width,drawable.getWidth());
-        // Assert.assertEquals(height,drawable.getHeight());
-        // Assert.assertEquals(glCaps,drawable.getChosenGLCapabilities());
-        Assert.assertEquals(window,drawable.getNativeSurface());
-        // System.out.println("Post: "+drawable);
-
-        context = drawable.createContext(null);
-        Assert.assertNotNull(context);
-        // System.out.println(context);
-        
-        int res = context.makeCurrent();
-        Assert.assertTrue(GLContext.CONTEXT_CURRENT_NEW==res || GLContext.CONTEXT_CURRENT==res);
-
-        // draw something ..
-
-        drawable.swapBuffers();
-        context.release();
-
-        // System.out.println("Final: "+window);
-    }
-
-    void destroyWindow() {
-        // GLWindow.dispose(..) sequence
-        Assert.assertNotNull(context);
-        context.destroy();
-
-        Assert.assertNotNull(drawable);
-        drawable.setRealized(false);
-
-        // GLWindow.destroy(..) sequence cont..
-        Assert.assertNotNull(window);
-        window.destroy();
-
-        drawable = null;
-        context = null;
-        window = null;
-    }
-
-    @Test
-    public void testOnScreenDecorated() throws InterruptedException {
-        createWindow(true, false, false);
-        Thread.sleep(1000); // 1000 ms
-        destroyWindow();
-    }
-
-    @Test
-    public void testOnScreenUndecorated() throws InterruptedException {
-        createWindow(true, false, true);
-        Thread.sleep(1000); // 1000 ms
-        destroyWindow();
-    }
-
-    public static void main(String args[]) throws IOException {
-        String tstname = TestDrawable01NEWT.class.getName();
-        org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(new String[] {
-            tstname,
-            "filtertrace=true",
-            "haltOnError=false",
-            "haltOnFailure=false",
-            "showoutput=true",
-            "outputtoformatters=true",
-            "logfailedtests=true",
-            "logtestlistenerevents=true",
-            "formatter=org.apache.tools.ant.taskdefs.optional.junit.PlainJUnitResultFormatter",
-            "formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter,TEST-"+tstname+".xml" } );
-    }
-
-}
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 297cbbb..c2285ba 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
@@ -132,7 +132,7 @@ public class GLSLMiscHelper {
         Assert.assertTrue(vertices0.sealed());
         Assert.assertEquals(4, vertices0.getElementCount());
         Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());        
-        Assert.assertEquals(vertices0.getVBOName(), gl.glGetBoundBuffer(GL.GL_ARRAY_BUFFER));
+        Assert.assertEquals(0, gl.glGetBoundBuffer(GL.GL_ARRAY_BUFFER)); // should be cleared ASAP
         validateGLArrayDataServerState(gl, vertices0);
         return vertices0;
     }
@@ -152,7 +152,7 @@ public class GLSLMiscHelper {
         Assert.assertTrue(vertices1.sealed());
         Assert.assertEquals(4, vertices1.getElementCount());
         Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
-        Assert.assertEquals(vertices1.getVBOName(), gl.glGetBoundBuffer(GL.GL_ARRAY_BUFFER));
+        Assert.assertEquals(0, gl.glGetBoundBuffer(GL.GL_ARRAY_BUFFER)); // should be cleared ASAP
         validateGLArrayDataServerState(gl, vertices1);
         return vertices1;
     }
@@ -173,7 +173,7 @@ public class GLSLMiscHelper {
         Assert.assertTrue(colors0.isVBOWritten());
         Assert.assertTrue(colors0.sealed());
         Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
-        Assert.assertEquals(colors0.getVBOName(), gl.glGetBoundBuffer(GL.GL_ARRAY_BUFFER));
+        Assert.assertEquals(0, gl.glGetBoundBuffer(GL.GL_ARRAY_BUFFER)); // should be cleared ASAP
         validateGLArrayDataServerState(gl, colors0);
         return colors0;
     }
@@ -191,7 +191,7 @@ public class GLSLMiscHelper {
         Assert.assertTrue(colors1.isVBOWritten());
         Assert.assertTrue(colors1.sealed());
         Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
-        Assert.assertEquals(colors1.getVBOName(), gl.glGetBoundBuffer(GL.GL_ARRAY_BUFFER));
+        Assert.assertEquals(0, gl.glGetBoundBuffer(GL.GL_ARRAY_BUFFER)); // should be cleared ASAP
         validateGLArrayDataServerState(gl, colors1);
         return colors1;        
     }    
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState01NEWT.java
index 987dedc..ab4b2d8 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState01NEWT.java
@@ -74,17 +74,19 @@ public class TestGLSLShaderState01NEWT extends UITestCase {
         final ShaderState st = new ShaderState();
         
         final ShaderCode rsVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, RedSquareES2.class, "shader",
-                "shader/bin", "RedSquareShader", false);
+                "shader/bin", "RedSquareShader", true);
         final ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, RedSquareES2.class, "shader",
-                "shader/bin", "RedSquareShader", false);
+                "shader/bin", "RedSquareShader", true);
+        rsVp.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_vp);
+        rsFp.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_fp);
 
         final ShaderProgram sp = new ShaderProgram();
-        Assert.assertTrue(0>sp.program());
+        Assert.assertTrue(0 == sp.program());
         
         sp.add(gl, rsVp, System.err);
         sp.add(gl, rsFp, System.err);
         
-        Assert.assertTrue(0<=sp.program()); 
+        Assert.assertTrue(0 != sp.program()); 
         Assert.assertTrue(!sp.inUse());
         Assert.assertTrue(!sp.linked());
         Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState02NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState02NEWT.java
index 91dcfc3..7022b74 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState02NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState02NEWT.java
@@ -81,19 +81,22 @@ public class TestGLSLShaderState02NEWT extends UITestCase {
         final ShaderState st = new ShaderState();
         
         final ShaderCode rsVp0 = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, RedSquareES2.class, "shader",
-                "shader/bin", "RedSquareShader", false);
+                "shader/bin", "RedSquareShader", true);
         final ShaderCode rsFp0 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, RedSquareES2.class, "shader",
-                "shader/bin", "RedSquareShader", false);
+                "shader/bin", "RedSquareShader", true);
         final ShaderCode rsFp1 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, RedSquareES2.class, "shader",
-                "shader/bin", "RedSquareShader2", false);
+                "shader/bin", "RedSquareShader2", true);
+        rsVp0.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_vp);
+        rsFp0.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_fp);
+        rsFp1.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_fp);
 
         final ShaderProgram sp1 = new ShaderProgram();
         sp1.add(rsVp0);
         sp1.add(rsFp1);
         Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
-        Assert.assertTrue(0>sp1.program());        
-        sp1.init(gl);
-        Assert.assertTrue(0<=sp1.program()); 
+        Assert.assertTrue(0 == sp1.program());        
+        Assert.assertTrue(sp1.init(gl));
+        Assert.assertTrue(0 != sp1.program()); 
         Assert.assertTrue(!sp1.inUse());
         Assert.assertTrue(!sp1.linked());
         Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
@@ -108,9 +111,9 @@ public class TestGLSLShaderState02NEWT extends UITestCase {
         sp0.add(rsFp0);
         Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
         
-        Assert.assertTrue(0>sp0.program());        
-        sp0.init(gl);
-        Assert.assertTrue(0<=sp0.program()); 
+        Assert.assertTrue(0 == sp0.program());        
+        Assert.assertTrue(sp0.init(gl));
+        Assert.assertTrue(0 != sp0.program()); 
         Assert.assertTrue(!sp0.inUse());
         Assert.assertTrue(!sp0.linked());
         Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());        
@@ -262,15 +265,16 @@ public class TestGLSLShaderState02NEWT extends UITestCase {
         sp1.add(rsVp0);
         sp1.add(rsFp1);
         Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
-        Assert.assertTrue(0>sp1.program());        
-        sp1.init(gl);
+        Assert.assertTrue(0 == sp1.program());        
+        Assert.assertTrue(sp1.init(gl));
+        Assert.assertTrue(0 != sp1.program());
         Assert.assertTrue(sp1.link(gl, System.err));
         
         final ShaderProgram sp0 = new ShaderProgram();
         sp0.add(rsVp0);
         sp0.add(rsFp0);
         
-        sp0.init(gl);
+        Assert.assertTrue(sp0.init(gl));
         Assert.assertTrue(sp0.link(gl, System.err));
         
         st.attachShaderProgram(gl, sp0, true);        
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestRulerNEWT01.java b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestRulerNEWT01.java
index 87d3170..98620e0 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestRulerNEWT01.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestRulerNEWT01.java
@@ -74,14 +74,16 @@ public class TestRulerNEWT01 extends UITestCase {
         final ShaderState st = new ShaderState();
         
         final ShaderCode vp0 = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, RedSquareES2.class, "shader",
-                "shader/bin", "default", false);
+                "shader/bin", "default", true);
         final ShaderCode fp0 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, RedSquareES2.class, "shader",
-                "shader/bin", "ruler", false);
+                "shader/bin", "ruler", true);
+        vp0.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_vp);
+        fp0.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_fp);
 
         final ShaderProgram sp0 = new ShaderProgram();
         sp0.add(gl, vp0, System.err);
         sp0.add(gl, fp0, System.err);       
-        Assert.assertTrue(0<=sp0.program()); 
+        Assert.assertTrue(0 != sp0.program()); 
         Assert.assertTrue(!sp0.inUse());
         Assert.assertTrue(!sp0.linked());
         Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/ReadBufferBase.java b/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/ReadBufferBase.java
index 4ef7b27..f8e064a 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/ReadBufferBase.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/ReadBufferBase.java
@@ -70,7 +70,7 @@ public class ReadBufferBase implements GLEventListener {
 
         _gl.getContext().setGLReadDrawable(externalRead);
         if(_gl.isGL2GL3()) {
-            _gl.getGL2GL3().glReadBuffer(GL2GL3.GL_FRONT);
+            _gl.getGL2GL3().glReadBuffer(GL.GL_FRONT);
         }
         System.out.println("---------------------------");
         System.out.println(_gl.getContext());
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTGLn.java b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTGLn.java
index 6a27e6f..fe40cec 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTGLn.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTGLn.java
@@ -139,7 +139,7 @@ public class TestNewtCanvasSWTGLn extends UITestCase {
            public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) { }
            public void display(final GLAutoDrawable drawable) {
               if(displayCount < 3) {
-                  snapshot(getSimpleTestName("."), displayCount++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
+                  snapshot(displayCount++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
               }
            }
            public void dispose(final GLAutoDrawable drawable) { }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTAccessor03AWTGLn.java b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTAccessor03AWTGLn.java
index ad8da8a..91902a8 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTAccessor03AWTGLn.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTAccessor03AWTGLn.java
@@ -49,13 +49,13 @@ import org.eclipse.swt.widgets.Shell;
 
 import org.junit.Assert;
 import org.junit.Assume;
-import org.junit.Before;
 import org.junit.BeforeClass;
-import org.junit.After;
 import org.junit.Test;
 
+import com.jogamp.common.os.Platform;
 import com.jogamp.nativewindow.swt.SWTAccessor;
 import com.jogamp.opengl.test.junit.jogl.demos.es1.OneTriangle;
+import com.jogamp.opengl.test.junit.util.MiscUtils;
 import com.jogamp.opengl.test.junit.util.UITestCase;
 
 /**
@@ -65,7 +65,7 @@ import com.jogamp.opengl.test.junit.util.UITestCase;
  */
 public class TestSWTAccessor03AWTGLn extends UITestCase {
 
-    static final int duration = 250;
+    static int duration = 250;
 
     Display display = null;
     Shell shell = null;
@@ -75,6 +75,13 @@ public class TestSWTAccessor03AWTGLn extends UITestCase {
 
     @BeforeClass
     public static void startup() {
+        if( Platform.getOSType() == Platform.OSType.MACOS ) {
+            // NSLocking issues on OSX and AWT, able to freeze whole test suite!
+            // Since this test is merely a technical nature to validate the accessor w/ SWT
+            // we can drop it w/o bothering.
+            UITestCase.setTestSupported(false);
+            return;
+        }
         System.out.println( "GLProfile " + GLProfile.glAvailabilityToString() ); 
         Frame f0 = new Frame("Test - AWT 1st");
         f0.add(new java.awt.Label("AWT was here 1st"));
@@ -85,8 +92,7 @@ public class TestSWTAccessor03AWTGLn extends UITestCase {
         }
     }
 
-    @Before
-    public void init() throws InterruptedException, InvocationTargetException {
+    protected void init() throws InterruptedException, InvocationTargetException {
         SWTAccessor.invoke(true, new Runnable() {
             public void run() {        
                 display = new Display();
@@ -102,8 +108,7 @@ public class TestSWTAccessor03AWTGLn extends UITestCase {
             }});
     }
 
-    @After
-    public void release() throws InterruptedException, InvocationTargetException {
+    protected void release() throws InterruptedException, InvocationTargetException {
         Assert.assertNotNull( display );
         Assert.assertNotNull( shell );
         Assert.assertNotNull( composite );
@@ -129,71 +134,81 @@ public class TestSWTAccessor03AWTGLn extends UITestCase {
             }});
     }
 
-    protected void runTestGL( GLProfile glprofile ) throws InterruptedException {
-        GLCapabilities glcapabilities = new GLCapabilities( glprofile );
-        glcanvas = new GLCanvas( glcapabilities );
-        Assert.assertNotNull( glcanvas );
-        frame.add( glcanvas );
-
-        glcanvas.addGLEventListener( new GLEventListener() {
-            /* @Override */
-            public void init( GLAutoDrawable glautodrawable ) {
-            }
-
-            /* @Override */
-            public void dispose( GLAutoDrawable glautodrawable ) {
-            }
-
-            /* @Override */
-            public void display( GLAutoDrawable glautodrawable ) {
-                Rectangle rectangle = new Rectangle( 0, 0, glautodrawable.getWidth(), glautodrawable.getHeight() );
-                GL2ES1 gl = glautodrawable.getGL().getGL2ES1();
-                OneTriangle.render( gl, rectangle.width, rectangle.height );
-            }
-
-            /* @Override */
-            public void reshape( GLAutoDrawable glautodrawable, int x, int y, int width, int height ) {
-                Rectangle rectangle = new Rectangle( 0, 0, glautodrawable.getWidth(), glautodrawable.getHeight() );
-                GL2ES1 gl = glautodrawable.getGL().getGL2ES1();
-                OneTriangle.setup( gl, rectangle.width, rectangle.height );
-            }
-        });
-
-        SWTAccessor.invoke(true, new Runnable() {
-            public void run() {
-                shell.setText( getClass().getName() );
-                shell.setSize( 640, 480 );
-                shell.open();
-            }});
-
-        long lStartTime = System.currentTimeMillis();
-        long lEndTime = lStartTime + duration;
+    protected void runTestGL( GLProfile glprofile ) throws InterruptedException, InvocationTargetException {
+        init();
         try {
-            while( (System.currentTimeMillis() < lEndTime) && !composite.isDisposed() ) {
-                SWTAccessor.invoke(true, new Runnable() {
-                    public void run() {
-                        if( !display.readAndDispatch() ) {
-                            // blocks on linux .. display.sleep();
-                            try {
-                                Thread.sleep(10);
-                            } catch (InterruptedException e) { }
-                        }
-                    }});
+            GLCapabilities glcapabilities = new GLCapabilities( glprofile );
+            glcanvas = new GLCanvas( glcapabilities );
+            Assert.assertNotNull( glcanvas );
+            frame.add( glcanvas );
+    
+            glcanvas.addGLEventListener( new GLEventListener() {
+                /* @Override */
+                public void init( GLAutoDrawable glautodrawable ) {
+                }
+    
+                /* @Override */
+                public void dispose( GLAutoDrawable glautodrawable ) {
+                }
+    
+                /* @Override */
+                public void display( GLAutoDrawable glautodrawable ) {
+                    Rectangle rectangle = new Rectangle( 0, 0, glautodrawable.getWidth(), glautodrawable.getHeight() );
+                    GL2ES1 gl = glautodrawable.getGL().getGL2ES1();
+                    OneTriangle.render( gl, rectangle.width, rectangle.height );
+                }
+    
+                /* @Override */
+                public void reshape( GLAutoDrawable glautodrawable, int x, int y, int width, int height ) {
+                    Rectangle rectangle = new Rectangle( 0, 0, glautodrawable.getWidth(), glautodrawable.getHeight() );
+                    GL2ES1 gl = glautodrawable.getGL().getGL2ES1();
+                    OneTriangle.setup( gl, rectangle.width, rectangle.height );
+                }
+            });
+    
+            SWTAccessor.invoke(true, new Runnable() {
+                public void run() {
+                    shell.setText( getClass().getName() );
+                    shell.setSize( 640, 480 );
+                    shell.open();
+                }});
+    
+            long lStartTime = System.currentTimeMillis();
+            long lEndTime = lStartTime + duration;
+            try {
+                while( (System.currentTimeMillis() < lEndTime) && !composite.isDisposed() ) {
+                    SWTAccessor.invoke(true, new Runnable() {
+                        public void run() {
+                            if( !display.readAndDispatch() ) {
+                                // blocks on linux .. display.sleep();
+                                try {
+                                    Thread.sleep(10);
+                                } catch (InterruptedException e) { }
+                            }
+                        }});
+                }
             }
-        }
-        catch( Throwable throwable ) {
-            throwable.printStackTrace();
-            Assume.assumeNoException( throwable );
+            catch( Throwable throwable ) {
+                throwable.printStackTrace();
+                Assume.assumeNoException( throwable );
+            }
+        } finally {
+            release();
         }
     }
 
     @Test
-    public void test() throws InterruptedException {
+    public void test() throws InterruptedException, InvocationTargetException {
         GLProfile glprofile = GLProfile.getGL2ES1();
         runTestGL( glprofile );
     }
 
     public static void main(String args[]) {
+        for(int i=0; i<args.length; i++) {
+            if(args[i].equals("-time")) {
+                duration = MiscUtils.atoi(args[++i], duration);
+            }
+        }
         org.junit.runner.JUnitCore.main( TestSWTAccessor03AWTGLn.class.getName() );
     }
 }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTJOGLGLCanvas01GLn.java b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTJOGLGLCanvas01GLn.java
index 4ca1dae..6d9e221 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTJOGLGLCanvas01GLn.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTJOGLGLCanvas01GLn.java
@@ -134,7 +134,7 @@ public class TestSWTJOGLGLCanvas01GLn extends UITestCase {
            public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) { }
            public void display(final GLAutoDrawable drawable) {
               if(displayCount < 3) {
-                  snapshot(getSimpleTestName("."), displayCount++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
+                  snapshot(displayCount++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
               }
            }
            public void dispose(final GLAutoDrawable drawable) { }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/DemoGL2ES1ImmModeSink.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/DemoGL2ES1ImmModeSink.java
new file mode 100644
index 0000000..276fb17
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/DemoGL2ES1ImmModeSink.java
@@ -0,0 +1,97 @@
+package com.jogamp.opengl.test.junit.jogl.util;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES1;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLPipelineFactory;
+import javax.media.opengl.glu.GLU;
+import javax.media.opengl.glu.gl2es1.GLUgl2es1;
+
+import com.jogamp.opengl.util.ImmModeSink;
+import com.jogamp.opengl.util.glsl.fixedfunc.FixedFuncUtil;
+import com.jogamp.opengl.util.glsl.fixedfunc.ShaderSelectionMode;
+
+class DemoGL2ES1ImmModeSink implements GLEventListener {
+    private boolean debugFFPEmu = false;
+    private boolean verboseFFPEmu = false;
+    private boolean traceFFPEmu = false;
+    private boolean forceFFPEmu = false;
+    final ImmModeSink ims;
+    final GLU glu;
+    
+    DemoGL2ES1ImmModeSink(boolean useVBO) {
+        ims = ImmModeSink.createFixed(3*3, 
+                                      3, GL.GL_FLOAT, // vertex
+                                      3, GL.GL_FLOAT, // color
+                                      0, GL.GL_FLOAT, // normal
+                                      0, GL.GL_FLOAT, // texCoords 
+                                      useVBO ? GL.GL_STATIC_DRAW : 0);
+        glu = new GLUgl2es1();
+    }
+    
+    public void setForceFFPEmu(boolean forceFFPEmu, boolean verboseFFPEmu, boolean debugFFPEmu, boolean traceFFPEmu) {
+        this.forceFFPEmu = forceFFPEmu;
+        this.verboseFFPEmu = verboseFFPEmu;
+        this.debugFFPEmu = debugFFPEmu;
+        this.traceFFPEmu = traceFFPEmu;
+    }
+
+    @Override
+    public void init(GLAutoDrawable drawable) {
+        GL _gl = drawable.getGL();
+        if(debugFFPEmu) {
+            // Debug ..
+            _gl = _gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Debug", GL2ES2.class, _gl, null) );
+        }
+        if(traceFFPEmu) {
+            // Trace ..
+            _gl = _gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Trace", GL2ES2.class, _gl, new Object[] { System.err } ) );
+        }
+        GL2ES1 gl = FixedFuncUtil.wrapFixedFuncEmul(_gl, ShaderSelectionMode.AUTO, null, forceFFPEmu, verboseFFPEmu);
+        
+        System.err.println("GL_VENDOR   "+gl.glGetString(GL.GL_VENDOR));
+        System.err.println("GL_RENDERER "+gl.glGetString(GL.GL_RENDERER));
+        System.err.println("GL_VERSION  "+gl.glGetString(GL.GL_VERSION));
+    }
+
+    @Override
+    public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
+        GL2ES1 gl = drawable.getGL().getGL2ES1();
+        
+        gl.glMatrixMode( GL2ES1.GL_PROJECTION );
+        gl.glLoadIdentity();
+
+        // coordinate system origin at lower left with width and height same as the window
+        glu.gluOrtho2D( 0.0f, width, 0.0f, height );
+
+        gl.glMatrixMode( GL2ES1.GL_MODELVIEW );
+        gl.glLoadIdentity();
+
+        gl.glViewport( 0, 0, width, height );        
+    }
+    
+    @Override
+    public void display(GLAutoDrawable drawable) {
+        GL2ES1 gl = drawable.getGL().getGL2ES1();
+        
+        gl.glClear( GL.GL_COLOR_BUFFER_BIT );
+
+        // draw a triangle filling the window
+        gl.glLoadIdentity();
+        
+        ims.glBegin(GL.GL_TRIANGLES);
+        ims.glColor3f( 1, 0, 0 );
+        ims.glVertex2f( 0, 0 );
+        ims.glColor3f( 0, 1, 0 );
+        ims.glVertex2f( TestImmModeSinkES1NEWT.iWidth, 0 );
+        ims.glColor3f( 0, 0, 1 );
+        ims.glVertex2f( TestImmModeSinkES1NEWT.iWidth / 2, TestImmModeSinkES1NEWT.iHeight );
+        ims.glEnd(gl, true);
+    }
+
+    @Override
+    public void dispose(GLAutoDrawable drawable) {
+    }        
+}
\ No newline at end of file
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/DemoGL2ES1Plain.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/DemoGL2ES1Plain.java
new file mode 100644
index 0000000..b66a095
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/DemoGL2ES1Plain.java
@@ -0,0 +1,161 @@
+package com.jogamp.opengl.test.junit.jogl.util;
+
+import java.nio.ByteBuffer;
+import java.nio.FloatBuffer;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES1;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLException;
+import javax.media.opengl.fixedfunc.GLPointerFunc;
+import javax.media.opengl.glu.GLU;
+import javax.media.opengl.glu.gl2es1.GLUgl2es1;
+
+import com.jogamp.common.nio.Buffers;
+import com.jogamp.opengl.util.GLArrayDataWrapper;
+import com.jogamp.opengl.util.GLBuffers;
+
+class DemoGL2ES1Plain implements GLEventListener {
+    final boolean useArrayData;
+    final boolean useVBO;
+    final GLU glu;
+    
+    final float[] vertices = new float[] { 0,          0,       0,
+                                           TestImmModeSinkES1NEWT.iWidth,     0,       0,
+                                           TestImmModeSinkES1NEWT.iWidth / 2, TestImmModeSinkES1NEWT.iHeight, 0 };
+    
+    final float[] colors = new float[] { 1, 0, 0, 
+                                         0, 1, 0, 
+                                         0, 0, 1 };
+    
+    final ByteBuffer bufferAll;
+    final int bufferVOffset, bufferCOffset;
+    final int bufferVSize, bufferCSize;
+    final FloatBuffer bufferC, bufferV;
+    final int[] vboName = new int[] { 0 };
+    final GLArrayDataWrapper arrayC, arrayV;
+    
+    DemoGL2ES1Plain(boolean useArrayData, boolean useVBO) {
+        this.useArrayData = useArrayData;
+        this.useVBO = useVBO;            
+        this.glu = new GLUgl2es1();
+        
+        bufferAll = Buffers.newDirectByteBuffer( ( colors.length + vertices.length ) * Buffers.SIZEOF_FLOAT );
+        
+        bufferVOffset = 0;
+        bufferVSize = 3*3*GLBuffers.sizeOfGLType(GL.GL_FLOAT);
+        bufferCOffset = bufferVSize;
+        bufferCSize = 3*3*GLBuffers.sizeOfGLType(GL.GL_FLOAT);
+        
+        bufferV = (FloatBuffer) GLBuffers.sliceGLBuffer(bufferAll, bufferVOffset, bufferVSize, GL.GL_FLOAT);
+        bufferV.put(vertices, 0, vertices.length).rewind();
+        bufferC = (FloatBuffer) GLBuffers.sliceGLBuffer(bufferAll, bufferCOffset, bufferCSize, GL.GL_FLOAT);
+        bufferC.put(colors, 0, colors.length).rewind();
+        
+        System.err.println("bufferAll: "+bufferAll+", byteOffset "+Buffers.getDirectBufferByteOffset(bufferAll));
+        System.err.println("bufferV: off "+bufferVOffset+", size "+bufferVSize+": "+bufferV+", byteOffset "+Buffers.getDirectBufferByteOffset(bufferV));
+        System.err.println("bufferC: off "+bufferCOffset+", size "+bufferCSize+": "+bufferC+", byteOffset "+Buffers.getDirectBufferByteOffset(bufferC));
+    
+        if(useArrayData) {            
+            arrayV = GLArrayDataWrapper.createFixed(GLPointerFunc.GL_VERTEX_ARRAY, 3, GL.GL_FLOAT, false, 0,
+                                                    bufferV, 0, bufferVOffset, GL.GL_STATIC_DRAW, GL.GL_ARRAY_BUFFER);
+            
+            arrayC = GLArrayDataWrapper.createFixed(GLPointerFunc.GL_COLOR_ARRAY, 3, GL.GL_FLOAT, false, 0,
+                                                    bufferC, 0, bufferCOffset, GL.GL_STATIC_DRAW, GL.GL_ARRAY_BUFFER);
+        } else {
+            arrayV = null;
+            arrayC = null;                
+        }
+    }
+    
+    @Override
+    public void init(GLAutoDrawable drawable) {
+        GL gl = drawable.getGL();
+        System.err.println("GL_VENDOR   "+gl.glGetString(GL.GL_VENDOR));
+        System.err.println("GL_RENDERER "+gl.glGetString(GL.GL_RENDERER));
+        System.err.println("GL_VERSION  "+gl.glGetString(GL.GL_VERSION));
+        if(useVBO) {
+            gl.glGenBuffers(1, vboName, 0);
+            if(0 == vboName[0]) {
+                throw new GLException("glGenBuffers didn't return valid VBO name");
+            }
+        }
+    }
+
+    @Override
+    public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
+        GL2ES1 gl = drawable.getGL().getGL2ES1();
+        
+        gl.glMatrixMode( GL2ES1.GL_PROJECTION );
+        gl.glLoadIdentity();
+
+        // coordinate system origin at lower left with width and height same as the window
+        glu.gluOrtho2D( 0.0f, width, 0.0f, height );
+
+        gl.glMatrixMode( GL2ES1.GL_MODELVIEW );
+        gl.glLoadIdentity();
+
+        gl.glViewport( 0, 0, width, height );        
+    }
+    
+    @Override
+    public void display(GLAutoDrawable drawable) {
+        GL2ES1 gl = drawable.getGL().getGL2ES1();
+        
+        gl.glClear( GL.GL_COLOR_BUFFER_BIT );
+
+        // draw a triangle filling the window
+        gl.glLoadIdentity();
+
+        if(useVBO) {
+            gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vboName[0]);
+            gl.glBufferData(GL.GL_ARRAY_BUFFER, bufferAll.limit(), bufferAll, GL.GL_STATIC_DRAW);
+            if(useArrayData) {
+                arrayV.setVBOName(vboName[0]);
+                arrayC.setVBOName(vboName[0]);
+            }
+        }
+        
+        gl.glEnableClientState(GLPointerFunc.GL_VERTEX_ARRAY);
+        if(useArrayData) {
+            gl.glVertexPointer(arrayV);
+        } else {
+            if(useVBO) {            
+                gl.glVertexPointer(3, GL.GL_FLOAT, 0, bufferVOffset);
+            } else {
+                gl.glVertexPointer(3, GL.GL_FLOAT, 0, bufferV);
+            }
+        }
+                    
+        gl.glEnableClientState(GLPointerFunc.GL_COLOR_ARRAY);            
+        if(useArrayData) {
+            gl.glColorPointer(arrayC);
+        } else {
+            if(useVBO) {            
+                gl.glColorPointer(3, GL.GL_FLOAT, 0, bufferCOffset);
+            } else {
+                gl.glColorPointer(3, GL.GL_FLOAT, 0, bufferC);
+            }
+        }
+                    
+        if(useVBO) {
+            gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
+        }
+        
+        gl.glDrawArrays(GL.GL_TRIANGLES, 0, 3);
+        gl.glFlush();
+        
+        gl.glDisableClientState(GLPointerFunc.GL_COLOR_ARRAY);
+        gl.glDisableClientState(GLPointerFunc.GL_VERTEX_ARRAY);
+    }
+
+    @Override
+    public void dispose(GLAutoDrawable drawable) {
+        GL gl = drawable.getGL();
+        if(0 != vboName[0]) {
+            gl.glDeleteBuffers(1, vboName, 0);
+            vboName[0] = 0;
+        }
+    }        
+}
\ No newline at end of file
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
new file mode 100644
index 0000000..75a98ed
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/DemoGL2ES1TextureImmModeSink.java
@@ -0,0 +1,142 @@
+/**
+ * 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;
+
+import java.io.InputStream;
+import java.net.URLConnection;
+
+import com.jogamp.common.util.IOUtil;
+import com.jogamp.opengl.test.junit.jogl.demos.TextureDraw01Accessor;
+import com.jogamp.opengl.util.ImmModeSink;
+import com.jogamp.opengl.util.glsl.fixedfunc.FixedFuncUtil;
+import com.jogamp.opengl.util.glsl.fixedfunc.ShaderSelectionMode;
+import com.jogamp.opengl.util.texture.Texture;
+import com.jogamp.opengl.util.texture.TextureCoords;
+import com.jogamp.opengl.util.texture.TextureData;
+import com.jogamp.opengl.util.texture.TextureIO;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES1;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLPipelineFactory;
+import javax.media.opengl.glu.GLU;
+
+public class DemoGL2ES1TextureImmModeSink implements GLEventListener, TextureDraw01Accessor {
+    private boolean debugFFPEmu = false;
+    private boolean verboseFFPEmu = false;
+    private boolean traceFFPEmu = false;
+    private boolean forceFFPEmu = false;
+    private ImmModeSink ims;
+    private GLU      glu = new GLU();
+    private TextureData textureData;
+    private Texture  texture;
+
+    public DemoGL2ES1TextureImmModeSink() {
+        this.ims = ImmModeSink.createFixed(32, 3, GL.GL_FLOAT, 4, GL.GL_FLOAT, 0, GL.GL_FLOAT, 2, GL.GL_FLOAT, GL.GL_STATIC_DRAW);
+    }
+
+    public void setForceFFPEmu(boolean forceFFPEmu, boolean verboseFFPEmu, boolean debugFFPEmu, boolean traceFFPEmu) {
+        this.forceFFPEmu = forceFFPEmu;
+        this.verboseFFPEmu = verboseFFPEmu;
+        this.debugFFPEmu = debugFFPEmu;
+        this.traceFFPEmu = traceFFPEmu;
+    }
+
+    public void init(GLAutoDrawable drawable) {
+        GL _gl = drawable.getGL();
+        if(debugFFPEmu) {
+            // Debug ..
+            _gl = _gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Debug", GL2ES2.class, _gl, null) );
+        }
+        if(traceFFPEmu) {
+            // Trace ..
+            _gl = _gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Trace", GL2ES2.class, _gl, new Object[] { System.err } ) );
+        }
+        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());
+        try {
+            InputStream  testTextureStream = testTextureUrlConn.getInputStream();
+            textureData = TextureIO.newTextureData(gl.getGLProfile(), testTextureStream , false /* mipmap */, TextureIO.PNG);
+            texture = TextureIO.newTexture(gl, textureData);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public Texture getTexture( ) {
+        return this.texture;
+    }
+
+    public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
+        GL2ES1 gl = drawable.getGL().getGL2ES1();
+        gl.glMatrixMode(GL2ES1.GL_PROJECTION);
+        gl.glLoadIdentity();
+        glu.gluOrtho2D(0, 1, 0, 1);
+        gl.glMatrixMode(GL2ES1.GL_MODELVIEW);
+        gl.glLoadIdentity();
+    }
+
+    public void dispose(GLAutoDrawable drawable) {
+        GL2ES1 gl = drawable.getGL().getGL2ES1();
+        if(null!=texture) {
+            texture.disable(gl);
+            texture.destroy(gl);
+        }
+        if(null!=textureData) {
+            textureData.destroy();
+        }
+    }
+
+    public void display(GLAutoDrawable drawable) {
+        GL2ES1 gl = drawable.getGL().getGL2ES1();
+
+        // draw one quad with the texture
+        if(null!=texture) {
+            texture.enable(gl);
+            texture.bind(gl);
+            // gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL2.GL_REPLACE);
+            TextureCoords coords = texture.getImageTexCoords();
+            ims.glBegin(ImmModeSink.GL_QUADS);
+            ims.glTexCoord2f(coords.left(), coords.bottom());
+            ims.glVertex3f(0, 0, 0);
+            ims.glTexCoord2f(coords.right(), coords.bottom());
+            ims.glVertex3f(1, 0, 0);
+            ims.glTexCoord2f(coords.right(), coords.top());
+            ims.glVertex3f(1, 1, 0);
+            ims.glTexCoord2f(coords.left(), coords.top());
+            ims.glVertex3f(0, 1, 0);
+            ims.glEnd(gl);
+            texture.disable(gl);
+        }
+    }
+}
+
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/newt/TestRedSquareES1NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/TestES1FixedFunctionPipelineNEWT.java
similarity index 53%
copy from src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/newt/TestRedSquareES1NEWT.java
copy to src/test/com/jogamp/opengl/test/junit/jogl/util/TestES1FixedFunctionPipelineNEWT.java
index c327a30..9d84bc5 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/newt/TestRedSquareES1NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/TestES1FixedFunctionPipelineNEWT.java
@@ -26,19 +26,19 @@
  * or implied, of JogAmp Community.
  */
  
-package com.jogamp.opengl.test.junit.jogl.demos.es1.newt;
+package com.jogamp.opengl.test.junit.jogl.util;
 
-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.UITestCase;
 import com.jogamp.opengl.test.junit.util.QuitAdapter;
 
 import com.jogamp.opengl.util.Animator;
 
+import com.jogamp.opengl.test.junit.jogl.demos.es1.GearsES1;
 import com.jogamp.opengl.test.junit.jogl.demos.es1.RedSquareES1;
 
 import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLEventListener;
 import javax.media.opengl.GLProfile;
 
 import org.junit.Assert;
@@ -46,7 +46,7 @@ import org.junit.BeforeClass;
 import org.junit.AfterClass;
 import org.junit.Test;
 
-public class TestRedSquareES1NEWT extends UITestCase {
+public class TestES1FixedFunctionPipelineNEWT extends UITestCase {
     static int width, height;
 
     @BeforeClass
@@ -59,58 +59,83 @@ public class TestRedSquareES1NEWT extends UITestCase {
     public static void releaseClass() {
     }
 
-    protected void runTestGL(GLCapabilities caps) throws InterruptedException {
+    protected void runTestGL0(GLCapabilities caps, GLEventListener demo) throws InterruptedException {
         GLWindow glWindow = GLWindow.create(caps);
         Assert.assertNotNull(glWindow);
-        glWindow.setTitle("Gears NEWT Test");
+        glWindow.setTitle(getSimpleTestName("."));
 
-        glWindow.addGLEventListener(new RedSquareES1());
+        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();
-
-        //glWindow.addKeyListener(new TraceKeyAdapter(quitAdapter));
-        //glWindow.addWindowListener(new TraceWindowAdapter(quitAdapter));
         glWindow.addKeyListener(quitAdapter);
         glWindow.addWindowListener(quitAdapter);
 
-        final GLWindow f_glWindow = glWindow;
-        glWindow.addKeyListener(new KeyAdapter() {
-            public void keyTyped(KeyEvent e) {
-                if(e.getKeyChar()=='f') {
-                    new Thread() {
-                        public void run() {
-                            f_glWindow.setFullscreen(!f_glWindow.isFullscreen());
-                    } }.start();
-                } else if(e.getKeyChar()=='d') {
-                    new Thread() {
-                        public void run() {
-                            f_glWindow.setUndecorated(!f_glWindow.isUndecorated());
-                    } }.start();
-                }
-            }
-        });
-
         glWindow.setSize(width, height);
         glWindow.setVisible(true);
         animator.setUpdateFPSFrames(1, null);
         animator.start();
-
+        
+        snap.setMakeSnapshot();
         while(!quitAdapter.shouldQuit() && animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
             Thread.sleep(100);
         }
-
+        glWindow.removeGLEventListener(demo);
+        
         animator.stop();
         glWindow.destroy();
     }
+    
+    protected void runTestGL(GLCapabilities caps, boolean forceFFPEmu) throws InterruptedException {
+        final RedSquareES1 demo01 = new RedSquareES1();
+        demo01.setForceFFPEmu(forceFFPEmu, false, false, false);
+        runTestGL0(caps, demo01);
+        
+        final GearsES1 demo02 = new GearsES1();
+        demo02.setForceFFPEmu(forceFFPEmu, false, false, false);
+        runTestGL0(caps, demo02);
+        
+        final DemoGL2ES1ImmModeSink demo03 = new DemoGL2ES1ImmModeSink(true);
+        demo03.setForceFFPEmu(forceFFPEmu, false, false, false);
+        runTestGL0(caps, demo03);
+        
+        final DemoGL2ES1TextureImmModeSink demo04 = new DemoGL2ES1TextureImmModeSink();
+        demo04.setForceFFPEmu(forceFFPEmu, false, false, false);
+        runTestGL0(caps, demo04);
+    }
 
     @Test
-    public void test01() throws InterruptedException {
-        GLCapabilities caps = new GLCapabilities(GLProfile.getGL2ES1());
-        runTestGL(caps);
+    public void test01GL2Normal() throws InterruptedException {
+        if(!GLProfile.isAvailable(GLProfile.GL2)) { System.err.println("GL2 n/a"); return; }
+        GLCapabilities caps = new GLCapabilities(GLProfile.get(GLProfile.GL2));
+        runTestGL(caps, false);
     }
-
-    static long duration = 500; // ms
+    
+    @Test
+    public void test03GL2FFPEmu() throws InterruptedException {
+        if(!GLProfile.isAvailable(GLProfile.GL2)) { System.err.println("GL2 n/a"); return; }
+        GLCapabilities caps = new GLCapabilities(GLProfile.get(GLProfile.GL2));
+        runTestGL(caps, true);
+    }
+    
+    @Test
+    public void test04GL2ES1Normal() throws InterruptedException {
+        if(!GLProfile.isAvailable(GLProfile.GL2ES1)) { System.err.println("GL2ES1 n/a"); return; }
+        GLCapabilities caps = new GLCapabilities(GLProfile.get(GLProfile.GL2ES1));
+        runTestGL(caps, false);
+    }
+    
+    @Test
+    public void test05ES2FFPEmu() throws InterruptedException {
+        if(!GLProfile.isAvailable(GLProfile.GLES2)) { System.err.println("GLES2 n/a"); return; }
+        GLCapabilities caps = new GLCapabilities(GLProfile.get(GLProfile.GLES2));
+        runTestGL(caps, false); // should be FFPEmu implicit
+    }
+    
+    static long duration = 1000; // ms
 
     public static void main(String args[]) {
         for(int i=0; i<args.length; i++) {
@@ -121,6 +146,6 @@ public class TestRedSquareES1NEWT extends UITestCase {
                 } catch (Exception ex) { ex.printStackTrace(); }
             }
         }
-        org.junit.runner.JUnitCore.main(TestRedSquareES1NEWT.class.getName());
+        org.junit.runner.JUnitCore.main(TestES1FixedFunctionPipelineNEWT.class.getName());
     }
 }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/TestImmModeSinkES1NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/TestImmModeSinkES1NEWT.java
new file mode 100644
index 0000000..d8bdf8a
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/TestImmModeSinkES1NEWT.java
@@ -0,0 +1,140 @@
+/**
+ * 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;
+
+import java.io.IOException;
+
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLProfile;
+
+import org.junit.Test;
+
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.test.junit.util.MiscUtils;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+
+/**
+ * Testing the ImmModeSink w/ GL2ES1 context
+ */
+public class TestImmModeSinkES1NEWT extends UITestCase {
+    static int duration = 100;
+    static final int iWidth = 400;
+    static final int iHeight = 400;
+
+    static GLCapabilities getCaps(String profile) {
+        if( !GLProfile.isAvailable(profile) )  {
+            System.err.println("Profile "+profile+" n/a");
+            return null;
+        }
+        return new GLCapabilities(GLProfile.get(profile));
+    }
+    
+    void doTest(GLCapabilitiesImmutable reqGLCaps, GLEventListener demo) throws InterruptedException {
+        System.out.println("Requested  GL Caps: "+reqGLCaps);
+        
+        //
+        // Create native windowing resources .. X11/Win/OSX
+        // 
+        final GLWindow glad = GLWindow.create(reqGLCaps);
+        glad.addGLEventListener(demo);
+        
+        final SnapshotGLEventListener snapshotGLEventListener = new SnapshotGLEventListener();
+        glad.addGLEventListener(snapshotGLEventListener);
+        glad.setSize(iWidth, iHeight);
+        glad.setVisible(true);
+        
+        snapshotGLEventListener.setMakeSnapshot();
+        glad.display(); // initial resize/display
+                
+        Thread.sleep(duration);
+        
+        glad.destroy();
+    }
+    
+    @Test
+    public void test01Plain__GL2ES1_VBOOffUsePlain() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2ES1);
+        if(null == reqGLCaps) return;
+        doTest(reqGLCaps, new DemoGL2ES1Plain(false, false));
+    }
+    
+    @Test
+    public void test02Plain__GL2ES1_VBOOffUseArrayData() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2ES1);
+        if(null == reqGLCaps) return;
+        doTest(reqGLCaps, new DemoGL2ES1Plain(true, false));
+    }
+    
+    @Test
+    public void test03Plain__GL2ES1_VBOOnUsePlain() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2ES1);
+        if(null == reqGLCaps) return;
+        doTest(reqGLCaps, new DemoGL2ES1Plain(false, true));
+    }
+    
+    @Test
+    public void test04Plain__GL2ES1_VBOOnUseArrayData() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2ES1);
+        if(null == reqGLCaps) return;
+        doTest(reqGLCaps, new DemoGL2ES1Plain(true, true));
+    }
+    
+    @Test
+    public void test05ImmSinkGL2ES1_VBOOff() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2ES1);
+        if(null == reqGLCaps) return;
+        doTest(reqGLCaps, new DemoGL2ES1ImmModeSink(false));
+    }
+    
+    @Test
+    public void test06ImmSinkGL2ES1_VBOOn() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2ES1);
+        if(null == reqGLCaps) return;
+        doTest(reqGLCaps, new DemoGL2ES1ImmModeSink(true));
+    }
+        
+    @Test
+    public void test07ImmSinkGL2ES1_VBOOnTexture() throws InterruptedException {
+        final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2ES1);
+        if(null == reqGLCaps) return;
+        doTest(reqGLCaps, new DemoGL2ES1TextureImmModeSink());
+    }
+        
+    public static void main(String args[]) throws IOException {
+        for(int i=0; i<args.length; i++) {
+            if(args[i].equals("-time")) {
+                duration = MiscUtils.atoi(args[++i], duration);
+            }
+        }
+        org.junit.runner.JUnitCore.main(TestImmModeSinkES1NEWT.class.getName());
+    }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite01AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite01AWT.java
index 6cee319..e2252d6 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite01AWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite01AWT.java
@@ -96,8 +96,8 @@ public class TestGLReadBufferUtilTextureIOWrite01AWT extends UITestCase {
             public void init(GLAutoDrawable drawable) {}
             public void dispose(GLAutoDrawable drawable) {}
             public void display(GLAutoDrawable drawable) {
-                snapshot(getSimpleTestName("."), f, null, drawable.getGL(), screenshotRGBA, TextureIO.PNG, null);
-                snapshot(getSimpleTestName("."), f, null,  drawable.getGL(), screenshotRGB, TextureIO.PNG, null);
+                snapshot(f, null, drawable.getGL(), screenshotRGBA, TextureIO.PNG, null);
+                snapshot(f, null, drawable.getGL(),  screenshotRGB, TextureIO.PNG, null);
                 f++;
             }
             public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite01NEWT.java
index 5681df0..16bd94c 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite01NEWT.java
@@ -75,12 +75,12 @@ public class TestGLReadBufferUtilTextureIOWrite01NEWT extends UITestCase {
             public void init(GLAutoDrawable drawable) {}
             public void dispose(GLAutoDrawable drawable) {}
             public void display(GLAutoDrawable drawable) {
-                snapshot(getSimpleTestName("."), f++, null, drawable.getGL(), screenshotRGBA, TextureIO.PNG, null);
-                snapshot(getSimpleTestName("."), f++, null,  drawable.getGL(), screenshotRGB, TextureIO.PNG, null);                
-                snapshot(getSimpleTestName("."), f++, null, drawable.getGL(), screenshotRGBA, TextureIO.TGA, null);
-                snapshot(getSimpleTestName("."), f++, null,  drawable.getGL(), screenshotRGB, TextureIO.TGA, null);                
-                snapshot(getSimpleTestName("."), f++, null, drawable.getGL(), screenshotRGBA, TextureIO.PAM, null);
-                snapshot(getSimpleTestName("."), f++, null,  drawable.getGL(), screenshotRGB, TextureIO.PAM, null);                
+                snapshot(f++, null, drawable.getGL(), screenshotRGBA, TextureIO.PNG, null);
+                snapshot(f++, null, drawable.getGL(),  screenshotRGB, TextureIO.PNG, null);                
+                snapshot(f++, null, drawable.getGL(), screenshotRGBA, TextureIO.TGA, null);
+                snapshot(f++, null, drawable.getGL(),  screenshotRGB, TextureIO.TGA, null);                
+                snapshot(f++, null, drawable.getGL(), screenshotRGBA, TextureIO.PAM, null);
+                snapshot(f++, null, drawable.getGL(),  screenshotRGB, TextureIO.PAM, null);                
             }
             public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
         });
@@ -103,8 +103,8 @@ public class TestGLReadBufferUtilTextureIOWrite01NEWT extends UITestCase {
             public void init(GLAutoDrawable drawable) {}
             public void dispose(GLAutoDrawable drawable) {}
             public void display(GLAutoDrawable drawable) {
-                snapshot(getSimpleTestName("."), f, null, drawable.getGL(), screenshotRGBA, TextureIO.PNG, null);
-                snapshot(getSimpleTestName("."), f, null,  drawable.getGL(), screenshotRGB, TextureIO.PNG, null);
+                snapshot(f, null, drawable.getGL(), screenshotRGBA, TextureIO.PNG, null);
+                snapshot(f, null, drawable.getGL(),  screenshotRGB, TextureIO.PNG, null);
                 f++;
             }
             public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite02AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite02AWT.java
index 43641fe..bec55d8 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite02AWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite02AWT.java
@@ -111,7 +111,7 @@ public class TestGLReadBufferUtilTextureIOWrite02AWT extends UITestCase {
                 if(snap) {
                     System.err.println("XXX: ["+fw_old+", "+dw_old+"], "+fw+"x"+fh+", "+dw+"x"+dh+", sz_changed "+sz_changed+", snap "+snap);
                     c=0;
-                    snapshot(getSimpleTestName("."), i++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
+                    snapshot(i++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
                     dw_old = dw;
                     fw_old = fw;
                     Threading.invoke(true, new Runnable() {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite02NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite02NEWT.java
index d1ffa84..36d905a 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite02NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite02NEWT.java
@@ -94,7 +94,7 @@ public class TestGLReadBufferUtilTextureIOWrite02NEWT extends UITestCase {
                 if(snap) {
                     System.err.println("XXX: ["+dw_old+"], "+dw+"x"+dh+", sz_changed "+sz_changed+", snap "+snap);
                     c=0;
-                    snapshot(getSimpleTestName("."), i++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
+                    snapshot(i++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
                     dw_old = dw;
                     new Thread() { 
                         @Override
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileAWT.java
index 0d4f2b0..7dbccd5 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileAWT.java
@@ -140,7 +140,7 @@ public class TestPNGTextureFromFileAWT extends UITestCase {
                 // 1 snapshot
                 if(null!=((TextureDraw01Accessor)gle).getTexture() && !shot) {
                     shot = true;
-                    snapshot(getSimpleTestName("."), 0, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
+                    snapshot(0, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
                 }
             }
 
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileNEWT.java
index b4faafb..e9ef9b9 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileNEWT.java
@@ -112,7 +112,7 @@ public class TestPNGTextureFromFileNEWT extends UITestCase {
                 // 1 snapshot
                 if(null!=((TextureDraw01Accessor)gle).getTexture() && !shot) {
                     shot = true;
-                    snapshot(getSimpleTestName("."), 0, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
+                    snapshot(0, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
                 }
             }
             
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java b/src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java
index bb67e77..5d6218d 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java
@@ -35,6 +35,7 @@ import org.junit.Assume;
 import java.awt.AWTException;
 import java.awt.BorderLayout;
 import java.awt.Button;
+import java.awt.Container;
 import java.awt.Robot;
 import java.lang.reflect.InvocationTargetException;
 
@@ -55,6 +56,15 @@ import com.jogamp.opengl.test.junit.jogl.demos.es2.RedSquareES2;
 
 import com.jogamp.opengl.test.junit.util.*;
 
+/**
+ * Testing focus traversal of an AWT component tree with {@link NewtCanvasAWT} attached.
+ * <p> 
+ * {@link JFrame} . {@link Container}+ . {@link NewtCanvasAWT} . {@link GLWindow}
+ * </p>
+ * <p>
+ * <i>+ Container is the JFrame's implicit root content pane</i><br/> 
+ * </p>
+ */
 public class TestFocus01SwingAWTRobot extends UITestCase {
     static int width, height;
     static long durationPerTest = 10;
@@ -125,6 +135,10 @@ public class TestFocus01SwingAWTRobot extends UITestCase {
         AWTKeyAdapter buttonKA = new AWTKeyAdapter("Button");
         button.addKeyListener(buttonKA);
         eventCountAdapters.add(buttonKA);
+        AWTMouseAdapter buttonMA = new AWTMouseAdapter("Button");
+        button.addMouseListener(buttonMA);
+        eventCountAdapters.add(buttonMA);
+        
         frame1.getContentPane().add(button, BorderLayout.NORTH);
         frame1.setSize(width, height);
         javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
@@ -149,22 +163,27 @@ public class TestFocus01SwingAWTRobot extends UITestCase {
         animator.start();
 
         // Button Focus
-        Thread.sleep(100); // allow event sync
+        Thread.sleep(200); // allow event sync
         
         System.err.println("FOCUS AWT  Button request");
         EventCountAdapterUtil.reset(eventCountAdapters);
-        AWTRobotUtil.assertRequestFocusAndWait(robot, button, button, buttonFA, frame1FA);
+        AWTRobotUtil.assertRequestFocusAndWait(robot, button, button, buttonFA, frame1FA); // OSX sporadically button did not gain - major UI failure
         Assert.assertEquals(false, glWindow1FA.focusGained());
         Assert.assertEquals(false, newtCanvasAWTFA.focusGained());
         System.err.println("FOCUS AWT  Button sync");
         AWTRobotUtil.assertKeyType(robot, java.awt.event.KeyEvent.VK_A, 2, button, buttonKA);
+        AWTRobotUtil.assertMouseClick(robot, java.awt.event.InputEvent.BUTTON1_MASK, 1, 
+                                      button, buttonMA);
+        AWTRobotUtil.assertMouseClick(robot, java.awt.event.InputEvent.BUTTON1_MASK, 2, 
+                                      button, buttonMA);
 
         // Request the AWT focus, which should automatically provide the NEWT window with focus.
         Thread.sleep(100); // allow event sync
         System.err.println("FOCUS NEWT Canvas/GLWindow request");
         EventCountAdapterUtil.reset(eventCountAdapters);
-        AWTRobotUtil.assertRequestFocusAndWait(robot, newtCanvasAWT, newtCanvasAWT.getNEWTChild(), glWindow1FA, buttonFA);
-        Assert.assertEquals(false, newtCanvasAWTFA.focusGained());
+        AWTRobotUtil.assertRequestFocusAndWait(robot, newtCanvasAWT, newtCanvasAWT.getNEWTChild(), glWindow1FA, buttonFA); // OSX sporadically button did not loose - minor UI failure
+        Assert.assertTrue("Focus prev. gained, but NewtCanvasAWT didn't loose it. Gainer: "+glWindow1FA+"; Looser "+newtCanvasAWTFA, 
+                AWTRobotUtil.waitForFocus(glWindow1FA, newtCanvasAWTFA));
         System.err.println("FOCUS NEWT Canvas/GLWindow sync");
         AWTRobotUtil.assertKeyType(robot, java.awt.event.KeyEvent.VK_A, 2, glWindow1, glWindow1KA);
         Assert.assertEquals("AWT parent canvas received keyboard events", 0, newtCanvasAWTKA.getCount());
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestFocus02SwingAWTRobot.java b/src/test/com/jogamp/opengl/test/junit/newt/TestFocus02SwingAWTRobot.java
index a0efa53..0e87144 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestFocus02SwingAWTRobot.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestFocus02SwingAWTRobot.java
@@ -56,6 +56,15 @@ import java.io.IOException;
 import com.jogamp.opengl.test.junit.util.*;
 import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
 
+/**
+ * Testing focus traversal of an AWT component tree with {@link NewtCanvasAWT} attached.
+ * <p> 
+ * {@link JFrame} . {@link JPanel}+ . {@link Container} . {@link NewtCanvasAWT} . {@link GLWindow}
+ * </p>
+ * <p>
+ * <i>+ JPanel is set as JFrame's root content pane</i><br/> 
+ * </p>
+ */
 public class TestFocus02SwingAWTRobot extends UITestCase {
     static int width, height;
     static long durationPerTest = 10;
@@ -85,9 +94,6 @@ public class TestFocus02SwingAWTRobot extends UITestCase {
 
         ArrayList<EventCountAdapter> eventCountAdapters = new ArrayList<EventCountAdapter>();
 
-        /**
-         * JFrame . JPanel . Container . NewtCanvasAWT . GLWindow
-         */
         GLWindow glWindow1 = GLWindow.create(glCaps);
         glWindow1.setTitle("testWindowParenting01CreateVisibleDestroy");
         GLEventListener demo1 = new GearsES2();
@@ -177,12 +183,12 @@ public class TestFocus02SwingAWTRobot extends UITestCase {
         Thread.sleep(100); // allow event sync
         System.err.println("FOCUS AWT  Button Outer request");
         EventCountAdapterUtil.reset(eventCountAdapters);
-        AWTRobotUtil.assertRequestFocusAndWait(robot, buttonNorthOuter, buttonNorthOuter, buttonNorthOuterFA, jFrame1FA);
+        AWTRobotUtil.assertRequestFocusAndWait(robot, buttonNorthOuter, buttonNorthOuter, buttonNorthOuterFA, jFrame1FA); // OSX sporadically buttonNorthOuter did not gain - major UI failure
         Assert.assertEquals(false, glWindow1FA.focusGained());
         Assert.assertEquals(false, newtCanvasAWTFA.focusGained());
         Assert.assertEquals(false, buttonNorthInnerFA.focusGained());
         System.err.println("FOCUS AWT  Button Outer sync");
-        AWTRobotUtil.assertKeyType(robot, java.awt.event.KeyEvent.VK_A, 2, buttonNorthOuter, buttonNorthOuterKA);
+        AWTRobotUtil.assertKeyType(robot, java.awt.event.KeyEvent.VK_A, 2, buttonNorthOuter, buttonNorthOuterKA); // OSX sporadically won't receive the keyboard input - major UI failure
         AWTRobotUtil.assertMouseClick(robot, java.awt.event.InputEvent.BUTTON1_MASK, 1, 
                                       buttonNorthOuter, buttonNorthOuterMA);
         AWTRobotUtil.assertMouseClick(robot, java.awt.event.InputEvent.BUTTON1_MASK, 2, 
@@ -225,7 +231,9 @@ public class TestFocus02SwingAWTRobot extends UITestCase {
         System.err.println("FOCUS NEWT Canvas/GLWindow request");
         EventCountAdapterUtil.reset(eventCountAdapters);
         AWTRobotUtil.assertRequestFocusAndWait(robot, newtCanvasAWT, newtCanvasAWT.getNEWTChild(), glWindow1FA, buttonNorthInnerFA);
-        Assert.assertTrue(AWTRobotUtil.waitForFocusCount(false, newtCanvasAWTFA));
+        Assert.assertTrue("Focus prev. gained, but NewtCanvasAWT didn't loose it. Gainer: "+glWindow1FA+"; Looser "+newtCanvasAWTFA, 
+                AWTRobotUtil.waitForFocus(glWindow1FA, newtCanvasAWTFA));
+        
         Assert.assertEquals(false, newtCanvasAWTFA.focusGained());
         Assert.assertEquals(false, buttonNorthOuterFA.focusGained());
         Assert.assertEquals(false, jFrame1FA.focusGained());
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyCodeModifiersAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyCodeModifiersAWT.java
new file mode 100644
index 0000000..b067883
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyCodeModifiersAWT.java
@@ -0,0 +1,275 @@
+/**
+ * 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.test.junit.newt;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.AfterClass;
+import org.junit.Assume;
+import org.junit.Before;
+
+import java.awt.AWTException;
+import java.awt.BorderLayout;
+import java.awt.Robot;
+import java.lang.reflect.InvocationTargetException;
+import java.util.EventObject;
+import java.util.List;
+
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLEventListener;
+import javax.swing.JFrame;
+
+import java.io.IOException;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.jogamp.newt.awt.NewtCanvasAWT;
+import com.jogamp.newt.event.InputEvent;
+import com.jogamp.newt.event.KeyEvent;
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.util.Animator;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.RedSquareES2;
+
+import com.jogamp.opengl.test.junit.util.*;
+
+/**
+ * Testing combinations of key code modifiers of key event.
+ */
+public class TestNewtKeyCodeModifiersAWT extends UITestCase {
+    static int width, height;
+    static long durationPerTest = 100;
+    static long awtWaitTimeout = 1000;
+
+    static GLCapabilities glCaps;
+
+    @BeforeClass
+    public static void initClass() {
+        width = 640;
+        height = 480;
+        glCaps = new GLCapabilities(null);
+    }
+
+    @AfterClass
+    public static void release() {
+    }
+    
+    @Before
+    public void initTest() {        
+    }
+
+    @After
+    public void releaseTest() {        
+    }
+    
+    @Test
+    public void test01NEWT() throws AWTException, InterruptedException, InvocationTargetException {
+        GLWindow glWindow = GLWindow.create(glCaps);
+        glWindow.setSize(width, height);
+        glWindow.setVisible(true);
+        
+        testImpl(glWindow);
+        
+        glWindow.destroy();
+    }
+        
+    @Test
+    public void test02NewtCanvasAWT() throws AWTException, InterruptedException, InvocationTargetException {
+        GLWindow glWindow = GLWindow.create(glCaps);
+        
+        // Wrap the window in a canvas.
+        final NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow);
+        
+        // Add the canvas to a frame, and make it all visible.
+        final JFrame frame1 = new JFrame("Swing AWT Parent Frame: "+ glWindow.getTitle());
+        frame1.getContentPane().add(newtCanvasAWT, BorderLayout.CENTER);
+        frame1.setSize(width, height);
+        javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+            public void run() {
+                frame1.setVisible(true);
+            } } );
+        
+        Assert.assertEquals(true,  AWTRobotUtil.waitForVisible(frame1, true));
+        
+        testImpl(glWindow);
+        
+        try {
+            javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+                public void run() {
+                    frame1.setVisible(false);
+                    frame1.dispose();
+                }});
+        } catch( Throwable throwable ) {
+            throwable.printStackTrace();
+            Assume.assumeNoException( throwable );
+        }        
+        glWindow.destroy();
+    }
+        
+    static void testKeyCodeModifier(Robot robot, NEWTKeyAdapter keyAdapter, int modifierKey, int modifierMask) {
+        keyAdapter.reset();
+        AWTRobotUtil.keyPress(0, robot, true, KeyEvent.VK_P, 10);   // press P
+        AWTRobotUtil.keyPress(0, robot, false, KeyEvent.VK_P, 100); // release+typed P
+        robot.waitForIdle();        
+        for(int j=0; j < 10 && keyAdapter.getQueueSize() < 3; j++) { // wait until events are collected
+            robot.delay(100);
+        }
+        
+        AWTRobotUtil.keyPress(0, robot, true, modifierKey, 10);     // press MOD
+        AWTRobotUtil.keyPress(0, robot, true, KeyEvent.VK_P, 10);   // press P
+        AWTRobotUtil.keyPress(0, robot, false, KeyEvent.VK_P, 10);  // release+typed P 
+        AWTRobotUtil.keyPress(0, robot, false, modifierKey, 100);   // release+typed MOD
+        robot.waitForIdle();        
+        for(int j=0; j < 10 && keyAdapter.getQueueSize() < 3+6; j++) { // wait until events are collected
+            robot.delay(100);
+        }
+        NEWTKeyUtil.validateKeyAdapterStats(keyAdapter, 3+6, 0);        
+        
+        final List<EventObject> queue = keyAdapter.getQueued();        
+        int i=0;
+        NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED, 0, KeyEvent.VK_P);
+        NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, 0, KeyEvent.VK_P);
+        NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_TYPED, 0, KeyEvent.VK_P);
+        
+        NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED, modifierMask, modifierKey);
+        NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED, modifierMask, KeyEvent.VK_P);
+        NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, modifierMask, KeyEvent.VK_P);
+        NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_TYPED, modifierMask, KeyEvent.VK_P);                
+        NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, modifierMask, modifierKey);
+        NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_TYPED, modifierMask, modifierKey);                
+    }
+    
+    static void testKeyCodeAllModifierV1(Robot robot, NEWTKeyAdapter keyAdapter) {
+        final int m1k = KeyEvent.VK_ALT;
+        final int m1m = InputEvent.ALT_MASK;
+        final int m2k = KeyEvent.VK_CONTROL;
+        final int m2m = InputEvent.CTRL_MASK;
+        final int m3k = KeyEvent.VK_SHIFT;
+        final int m3m = InputEvent.SHIFT_MASK;
+        
+        keyAdapter.reset();
+        AWTRobotUtil.keyPress(0, robot, true, m1k, 10);     // press MOD1
+        AWTRobotUtil.keyPress(0, robot, true, m2k, 10);     // press MOD2
+        AWTRobotUtil.keyPress(0, robot, true, m3k, 10);     // press MOD3
+        AWTRobotUtil.keyPress(0, robot, true, KeyEvent.VK_P, 10);   // press P
+        
+        AWTRobotUtil.keyPress(0, robot, false, KeyEvent.VK_P, 100);  // release+typed P        
+        AWTRobotUtil.keyPress(0, robot, false, m3k, 10);   // release+typed MOD
+        AWTRobotUtil.keyPress(0, robot, false, m2k, 10);   // release+typed MOD
+        AWTRobotUtil.keyPress(0, robot, false, m1k, 10);   // release+typed MOD
+        
+        robot.waitForIdle();        
+        for(int j=0; j < 10 && keyAdapter.getQueueSize() < 3*4; j++) { // wait until events are collected
+            robot.delay(100);
+        }
+        NEWTKeyUtil.validateKeyAdapterStats(keyAdapter, 3*4, 0);        
+        
+        final List<EventObject> queue = keyAdapter.getQueued();        
+        int i=0;
+        NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED,  m1m,         m1k);
+        NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED,  m1m|m2m,     m2k);
+        NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED,  m1m|m2m|m3m, m3k);
+        
+        NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED,  m1m|m2m|m3m, KeyEvent.VK_P);
+        NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, m1m|m2m|m3m, KeyEvent.VK_P);
+        NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_TYPED,    m1m|m2m|m3m, KeyEvent.VK_P);
+        
+        NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, m1m|m2m|m3m, m3k);
+        NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_TYPED,    m1m|m2m|m3m, m3k);
+        NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, m1m|m2m,     m2k);
+        NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_TYPED,    m1m|m2m,     m2k);
+        NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, m1m,         m1k);
+        NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_TYPED,    m1m,         m1k);                
+    }
+    
+    void testImpl(GLWindow glWindow) throws AWTException, InterruptedException, InvocationTargetException {
+        final Robot robot = new Robot();
+        robot.setAutoWaitForIdle(true);
+
+        GLEventListener demo1 = new RedSquareES2();
+        TestListenerCom01AWT.setDemoFields(demo1, glWindow, false);
+        glWindow.addGLEventListener(demo1);
+
+        // NEWTFocusAdapter glWindow1FA = new NEWTFocusAdapter("GLWindow1");
+        // glWindow.addWindowListener(glWindow1FA);
+        NEWTKeyAdapter glWindow1KA = new NEWTKeyAdapter("GLWindow1");
+        glWindow1KA.setVerbose(false);
+        glWindow.addKeyListener(glWindow1KA);
+
+        Assert.assertEquals(true,  AWTRobotUtil.waitForRealized(glWindow, true));        
+
+        // Continuous animation ..
+        Animator animator = new Animator(glWindow);
+        animator.start();
+
+        Thread.sleep(durationPerTest); // manual testing
+        
+        AWTRobotUtil.assertRequestFocusAndWait(null, glWindow, glWindow, null, null);  // programmatic
+        AWTRobotUtil.requestFocus(robot, glWindow, false); // within unit framework, prev. tests (TestFocus02SwingAWTRobot) 'confuses' Windows keyboard input
+        glWindow1KA.reset();        
+
+        testKeyCodeModifier(robot, glWindow1KA, KeyEvent.VK_SHIFT, InputEvent.SHIFT_MASK);
+        testKeyCodeModifier(robot, glWindow1KA, KeyEvent.VK_CONTROL, InputEvent.CTRL_MASK);
+        testKeyCodeModifier(robot, glWindow1KA, KeyEvent.VK_ALT, InputEvent.ALT_MASK);
+        
+        testKeyCodeAllModifierV1(robot, glWindow1KA);
+        
+        // Remove listeners to avoid logging during dispose/destroy.
+        glWindow.removeKeyListener(glWindow1KA);
+
+        // Shutdown the test.
+        animator.stop();
+    }
+
+    static int atoi(String a) {
+        int i=0;
+        try {
+            i = Integer.parseInt(a);
+        } catch (Exception ex) { ex.printStackTrace(); }
+        return i;
+    }
+
+    public static void main(String args[]) throws IOException {
+        for(int i=0; i<args.length; i++) {
+            if(args[i].equals("-time")) {
+                durationPerTest = atoi(args[++i]);
+            }
+        }
+        /**
+        BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
+        System.err.println("Press enter to continue");
+        System.err.println(stdin.readLine()); 
+        */
+        System.out.println("durationPerTest: "+durationPerTest);
+        String tstname = TestNewtKeyCodeModifiersAWT.class.getName();
+        org.junit.runner.JUnitCore.main(tstname);
+    }
+
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java b/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyCodesAWT.java
similarity index 50%
copy from src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java
copy to src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyCodesAWT.java
index bb67e77..e786eaf 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyCodesAWT.java
@@ -1,5 +1,5 @@
 /**
- * Copyright 2010 JogAmp Community. All rights reserved.
+ * 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:
@@ -28,21 +28,24 @@
  
 package com.jogamp.opengl.test.junit.newt;
 
+import org.junit.After;
 import org.junit.Assert;
 import org.junit.AfterClass;
 import org.junit.Assume;
+import org.junit.Before;
 
 import java.awt.AWTException;
 import java.awt.BorderLayout;
-import java.awt.Button;
 import java.awt.Robot;
 import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.EventObject;
+import java.util.List;
 
 import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLEventListener;
 import javax.swing.JFrame;
 
-import java.util.ArrayList;
 import java.io.IOException;
 
 import org.junit.BeforeClass;
@@ -54,10 +57,14 @@ import com.jogamp.opengl.util.Animator;
 import com.jogamp.opengl.test.junit.jogl.demos.es2.RedSquareES2;
 
 import com.jogamp.opengl.test.junit.util.*;
+import com.jogamp.opengl.test.junit.util.NEWTKeyUtil.CodeSeg;
 
-public class TestFocus01SwingAWTRobot extends UITestCase {
+/**
+ * Testing key code of key events.
+ */
+public class TestNewtKeyCodesAWT extends UITestCase {
     static int width, height;
-    static long durationPerTest = 10;
+    static long durationPerTest = 100;
     static long awtWaitTimeout = 1000;
 
     static GLCapabilities glCaps;
@@ -72,111 +79,46 @@ public class TestFocus01SwingAWTRobot extends UITestCase {
     @AfterClass
     public static void release() {
     }
-
-    @Test
-    public void testFocus01ProgrFocus() throws AWTException, InterruptedException, InvocationTargetException {
-        testFocus01ProgrFocusImpl(null);
+    
+    @Before
+    public void initTest() {        
     }
 
+    @After
+    public void releaseTest() {        
+    }
+    
     @Test
-    public void testFocus02RobotFocus() throws AWTException, InterruptedException, InvocationTargetException {
-        Robot robot = new Robot();
-        robot.setAutoWaitForIdle(true);
-        testFocus01ProgrFocusImpl(robot);
+    public void test01NEWT() throws AWTException, InterruptedException, InvocationTargetException {
+        GLWindow glWindow = GLWindow.create(glCaps);
+        glWindow.setSize(width, height);
+        glWindow.setVisible(true);
+        
+        testImpl(glWindow);
+        
+        glWindow.destroy();
     }
-
-    private void testFocus01ProgrFocusImpl(Robot robot) throws AWTException,
-            InvocationTargetException, InterruptedException {
-        ArrayList<EventCountAdapter> eventCountAdapters = new ArrayList<EventCountAdapter>();
-
-        // Create a window.
-        GLWindow glWindow1 = GLWindow.create(glCaps);
-        glWindow1.setTitle("testNewtChildFocus");
-        GLEventListener demo1 = new RedSquareES2();
-        TestListenerCom01AWT.setDemoFields(demo1, glWindow1, false);
-        glWindow1.addGLEventListener(demo1);
-        NEWTFocusAdapter glWindow1FA = new NEWTFocusAdapter("GLWindow1");
-        glWindow1.addWindowListener(glWindow1FA);
-
-        // Monitor NEWT focus and keyboard events.
-        NEWTKeyAdapter glWindow1KA = new NEWTKeyAdapter("GLWindow1");
-        eventCountAdapters.add(glWindow1KA);
-        glWindow1.addKeyListener(glWindow1KA);
-
+        
+    @Test
+    public void test02NewtCanvasAWT() throws AWTException, InterruptedException, InvocationTargetException {
+        GLWindow glWindow = GLWindow.create(glCaps);
+        
         // Wrap the window in a canvas.
-        final NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow1);
-
-        // Monitor AWT focus and keyboard events.
-        AWTKeyAdapter newtCanvasAWTKA = new AWTKeyAdapter("NewtCanvasAWT");
-        newtCanvasAWT.addKeyListener(newtCanvasAWTKA);
-        eventCountAdapters.add(newtCanvasAWTKA);
-        AWTFocusAdapter newtCanvasAWTFA = new AWTFocusAdapter("NewtCanvasAWT");
-        newtCanvasAWT.addFocusListener(newtCanvasAWTFA);
-
+        final NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow);
+        
         // Add the canvas to a frame, and make it all visible.
-        final JFrame frame1 = new JFrame("Swing AWT Parent Frame: "
-                                         + glWindow1.getTitle());
-        AWTFocusAdapter frame1FA = new AWTFocusAdapter("frame1");
-        frame1.addFocusListener(frame1FA);
+        final JFrame frame1 = new JFrame("Swing AWT Parent Frame: "+ glWindow.getTitle());
         frame1.getContentPane().add(newtCanvasAWT, BorderLayout.CENTER);
-        final Button button = new Button("Click me ..");
-        AWTFocusAdapter buttonFA = new AWTFocusAdapter("Button");
-        button.addFocusListener(buttonFA);
-        AWTKeyAdapter buttonKA = new AWTKeyAdapter("Button");
-        button.addKeyListener(buttonKA);
-        eventCountAdapters.add(buttonKA);
-        frame1.getContentPane().add(button, BorderLayout.NORTH);
         frame1.setSize(width, height);
         javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
             public void run() {
                 frame1.setVisible(true);
             } } );
+        
         Assert.assertEquals(true,  AWTRobotUtil.waitForVisible(frame1, true));
-        Assert.assertEquals(true,  AWTRobotUtil.waitForRealized(glWindow1, true));        
-        AWTRobotUtil.clearAWTFocus(robot);
-        Assert.assertTrue(AWTRobotUtil.toFrontAndRequestFocus(robot, frame1));
-
-        Thread.sleep(durationPerTest); // manual testing
         
-        int wait=0;
-        while(wait<awtWaitTimeout/100 && glWindow1.getTotalFPSFrames()<1) { Thread.sleep(awtWaitTimeout/10); wait++; }
-        System.err.println("Frames for initial setVisible(true): "+glWindow1.getTotalFPSFrames());
-        Assert.assertTrue(glWindow1.isVisible());
-        Assert.assertTrue(0 < glWindow1.getTotalFPSFrames());
-
-        // Continuous animation ..
-        Animator animator = new Animator(glWindow1);
-        animator.start();
-
-        // Button Focus
-        Thread.sleep(100); // allow event sync
+        testImpl(glWindow);
         
-        System.err.println("FOCUS AWT  Button request");
-        EventCountAdapterUtil.reset(eventCountAdapters);
-        AWTRobotUtil.assertRequestFocusAndWait(robot, button, button, buttonFA, frame1FA);
-        Assert.assertEquals(false, glWindow1FA.focusGained());
-        Assert.assertEquals(false, newtCanvasAWTFA.focusGained());
-        System.err.println("FOCUS AWT  Button sync");
-        AWTRobotUtil.assertKeyType(robot, java.awt.event.KeyEvent.VK_A, 2, button, buttonKA);
-
-        // Request the AWT focus, which should automatically provide the NEWT window with focus.
-        Thread.sleep(100); // allow event sync
-        System.err.println("FOCUS NEWT Canvas/GLWindow request");
-        EventCountAdapterUtil.reset(eventCountAdapters);
-        AWTRobotUtil.assertRequestFocusAndWait(robot, newtCanvasAWT, newtCanvasAWT.getNEWTChild(), glWindow1FA, buttonFA);
-        Assert.assertEquals(false, newtCanvasAWTFA.focusGained());
-        System.err.println("FOCUS NEWT Canvas/GLWindow sync");
-        AWTRobotUtil.assertKeyType(robot, java.awt.event.KeyEvent.VK_A, 2, glWindow1, glWindow1KA);
-        Assert.assertEquals("AWT parent canvas received keyboard events", 0, newtCanvasAWTKA.getCount());
-
-        // Remove listeners to avoid logging during dispose/destroy.
-        glWindow1.removeKeyListener(glWindow1KA);
-        glWindow1.removeWindowListener(glWindow1FA);
-        newtCanvasAWT.removeKeyListener(newtCanvasAWTKA);
-        newtCanvasAWT.removeFocusListener(newtCanvasAWTFA);
-
-        // Shutdown the test.
-        animator.stop();
         try {
             javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
                 public void run() {
@@ -187,7 +129,93 @@ public class TestFocus01SwingAWTRobot extends UITestCase {
             throwable.printStackTrace();
             Assume.assumeNoException( throwable );
         }        
-        glWindow1.destroy();
+        glWindow.destroy();
+    }
+        
+    static CodeSeg[] codeSegments = new CodeSeg[] {
+      new CodeSeg(0x008, 0x008, "bs"),
+      // new CodeSeg(0x009, 0x009, "tab"), // TAB functions as focus traversal key
+      new CodeSeg(0x00a, 0x00a, "cr"),
+      new CodeSeg(0x010, 0x012, "shift, ctrl, alt"),
+      new CodeSeg(0x01B, 0x01B, "esc"),
+      new CodeSeg(0x020, 0x024, "space, up, down, end, home"),
+      new CodeSeg(0x025, 0x028, "cursor"),
+      new CodeSeg(0x02C, 0x02F, ", - . /"),
+      new CodeSeg(0x030, 0x039, "0 - 9"),
+      new CodeSeg(0x03B, 0x03B, ";"),
+      new CodeSeg(0x03D, 0x03D, "="),
+      new CodeSeg(0x041, 0x05A, "a - z"),
+      new CodeSeg(0x05B, 0x05D, "[ \\ ]"),
+      // new CodeSeg(0x060, 0x06B, "numpad1"), // can be mapped to normal keycodes
+      // new CodeSeg(0x06D, 0x06F, "numpad2"), // can be mapped to normal keycodes
+      new CodeSeg(0x07F, 0x07F, "del"),
+      // new CodeSeg(0x090, 0x091, "num lock, scroll lock"),
+      // new CodeSeg(0x070, 0x07B, "F1 - F12"),
+      // new CodeSeg(0x09A, 0x09D, "prt ins hlp meta"),
+      new CodeSeg(0x0C0, 0x0C0, "back quote"),
+      new CodeSeg(0x0DE, 0x0DE, "quote"),
+      // new CodeSeg(0x0E0, 0x0E3, "cursor kp"),
+      // new CodeSeg(0x080, 0x08F, "dead-1"),
+      // new CodeSeg(0x096, 0x0A2, "& ^ \" < > { }"), 
+      // new CodeSeg(0x200, 0x20D, "extra-2"), // @ ; ..
+    };
+    
+    static void testKeyCodes(Robot robot, NEWTKeyAdapter keyAdapter) {
+        final List<List<EventObject>> cse = new ArrayList<List<EventObject>>();
+        
+        for(int i=0; i<codeSegments.length; i++) {
+            keyAdapter.reset();
+            final CodeSeg codeSeg = codeSegments[i];
+            // System.err.println("*** Segment "+codeSeg.description);
+            for(int c=codeSeg.min; c<=codeSeg.max; c++) {
+                // System.err.println("*** KeyCode 0x"+Integer.toHexString(c));
+                AWTRobotUtil.keyPress(0, robot, true, c, 10);
+                AWTRobotUtil.keyPress(0, robot, false, c, 100);
+                robot.waitForIdle();
+            }
+            final int codeCount = codeSeg.max - codeSeg.min + 1;
+            for(int j=0; j < 10 && keyAdapter.getQueueSize() < 3 * codeCount; j++) { // wait until events are collected
+                robot.delay(100);
+            }
+            final ArrayList<EventObject> events = new ArrayList<EventObject>(keyAdapter.getQueued());
+            cse.add(events);
+        }
+        Assert.assertEquals("KeyCode impl. incomplete", true, NEWTKeyUtil.validateKeyCodes(codeSegments, cse, true));        
+    }
+        
+    void testImpl(GLWindow glWindow) throws AWTException, InterruptedException, InvocationTargetException {
+        final Robot robot = new Robot();
+        robot.setAutoWaitForIdle(true);
+
+        GLEventListener demo1 = new RedSquareES2();
+        TestListenerCom01AWT.setDemoFields(demo1, glWindow, false);
+        glWindow.addGLEventListener(demo1);
+
+        // NEWTFocusAdapter glWindow1FA = new NEWTFocusAdapter("GLWindow1");
+        // glWindow.addWindowListener(glWindow1FA);
+        NEWTKeyAdapter glWindow1KA = new NEWTKeyAdapter("GLWindow1");
+        glWindow1KA.setVerbose(false);
+        glWindow.addKeyListener(glWindow1KA);
+
+        Assert.assertEquals(true,  AWTRobotUtil.waitForRealized(glWindow, true));        
+
+        // Continuous animation ..
+        Animator animator = new Animator(glWindow);
+        animator.start();
+
+        Thread.sleep(durationPerTest); // manual testing
+        
+        AWTRobotUtil.assertRequestFocusAndWait(null, glWindow, glWindow, null, null);  // programmatic
+        AWTRobotUtil.requestFocus(robot, glWindow, false); // within unit framework, prev. tests (TestFocus02SwingAWTRobot) 'confuses' Windows keyboard input
+        glWindow1KA.reset();        
+
+        testKeyCodes(robot, glWindow1KA);
+        
+        // Remove listeners to avoid logging during dispose/destroy.
+        glWindow.removeKeyListener(glWindow1KA);
+
+        // Shutdown the test.
+        animator.stop();
     }
 
     static int atoi(String a) {
@@ -210,7 +238,7 @@ public class TestFocus01SwingAWTRobot extends UITestCase {
         System.err.println(stdin.readLine()); 
         */
         System.out.println("durationPerTest: "+durationPerTest);
-        String tstname = TestFocus01SwingAWTRobot.class.getName();
+        String tstname = TestNewtKeyCodesAWT.class.getName();
         org.junit.runner.JUnitCore.main(tstname);
     }
 
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyEventAutoRepeatAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyEventAutoRepeatAWT.java
new file mode 100644
index 0000000..7b6fe05
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyEventAutoRepeatAWT.java
@@ -0,0 +1,320 @@
+/**
+ * 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.test.junit.newt;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.AfterClass;
+import org.junit.Assume;
+import org.junit.Before;
+
+import java.awt.AWTException;
+import java.awt.BorderLayout;
+import java.awt.Robot;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Arrays;
+import java.util.EventObject;
+import java.util.List;
+
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLEventListener;
+import javax.swing.JFrame;
+
+import java.io.IOException;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.jogamp.newt.awt.NewtCanvasAWT;
+import com.jogamp.newt.event.InputEvent;
+import com.jogamp.newt.event.KeyEvent;
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.util.Animator;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.RedSquareES2;
+
+import com.jogamp.opengl.test.junit.util.*;
+
+/**
+ * Testing key event order incl. auto-repeat (Bug 601)
+ * 
+ * <p>
+ * Note Event order:
+ * <ol>
+ *   <li>{@link #EVENT_KEY_PRESSED}</li>
+ *   <li>{@link #EVENT_KEY_RELEASED}</li>
+ *   <li>{@link #EVENT_KEY_TYPED}</li>
+ * </ol>
+ * </p>
+ * <p>
+ * Auto-Repeat shall behave as follow:
+ * <pre>
+    D = pressed, U = released, T = typed
+    0 = normal, 1 = auto-repeat
+
+    D(0), [ U(1), T(1), D(1), U(1) T(1) ..], U(0) T(0)
+ * </pre>
+ *
+ * The idea is if you mask out auto-repeat in your event listener
+ * you just get one long pressed key D/U/T triple.
+ */
+public class TestNewtKeyEventAutoRepeatAWT extends UITestCase {
+    static int width, height;
+    static long durationPerTest = 100;
+    static long awtWaitTimeout = 1000;
+
+    static GLCapabilities glCaps;
+
+    @BeforeClass
+    public static void initClass() {
+        width = 640;
+        height = 480;
+        glCaps = new GLCapabilities(null);
+    }
+
+    @AfterClass
+    public static void release() {
+    }
+    
+    @Before
+    public void initTest() {        
+    }
+
+    @After
+    public void releaseTest() {        
+    }
+    
+    @Test
+    public void test01NEWT() throws AWTException, InterruptedException, InvocationTargetException {
+        GLWindow glWindow = GLWindow.create(glCaps);
+        glWindow.setSize(width, height);
+        glWindow.setVisible(true);
+        
+        testImpl(glWindow);
+        
+        glWindow.destroy();
+    }
+        
+    @Test
+    public void test02NewtCanvasAWT() throws AWTException, InterruptedException, InvocationTargetException {
+        GLWindow glWindow = GLWindow.create(glCaps);
+        
+        // Wrap the window in a canvas.
+        final NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow);
+        
+        // Add the canvas to a frame, and make it all visible.
+        final JFrame frame1 = new JFrame("Swing AWT Parent Frame: "+ glWindow.getTitle());
+        frame1.getContentPane().add(newtCanvasAWT, BorderLayout.CENTER);
+        frame1.setSize(width, height);
+        javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+            public void run() {
+                frame1.setVisible(true);
+            } } );
+        
+        Assert.assertEquals(true,  AWTRobotUtil.waitForVisible(frame1, true));
+        
+        testImpl(glWindow);
+        
+        try {
+            javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+                public void run() {
+                    frame1.setVisible(false);
+                    frame1.dispose();
+                }});
+        } catch( Throwable throwable ) {
+            throwable.printStackTrace();
+            Assume.assumeNoException( throwable );
+        }        
+        glWindow.destroy();
+    }
+    
+    static void testKeyEventAutoRepeat(Robot robot, NEWTKeyAdapter keyAdapter, int loops, int pressDurationMS) {
+        System.err.println("KEY Event Auto-Repeat Test: "+loops);
+        EventObject[][] first = new EventObject[loops][3];
+        EventObject[][] last = new EventObject[loops][3];
+        
+        keyAdapter.reset();
+        int firstIdx = 0;
+        for(int i=0; i<loops; i++) {
+            System.err.println("+++ KEY Event Auto-Repeat START Input Loop: "+i);
+            AWTRobotUtil.keyPress(0, robot, true, java.awt.event.KeyEvent.VK_A, pressDurationMS);
+            robot.waitForIdle();
+            AWTRobotUtil.keyPress(0, robot, false, java.awt.event.KeyEvent.VK_A, 500); // 1s .. no AR anymore
+            robot.waitForIdle();            
+            final int minCodeCount = firstIdx + 3;
+            final int desiredCodeCount = firstIdx + 6;
+            for(int j=0; j < 10 && keyAdapter.getQueueSize() < desiredCodeCount; j++) { // wait until events are collected
+                robot.delay(100);
+            }
+            Assert.assertTrue("AR Test didn't collect enough key events: required min "+minCodeCount+", received "+(keyAdapter.getQueueSize()-firstIdx)+", "+keyAdapter.getQueued(), 
+                              keyAdapter.getQueueSize() >= minCodeCount );
+            final List<EventObject> keyEvents = keyAdapter.getQueued();
+            first[i][0] = (KeyEvent) keyEvents.get(firstIdx+0);
+            first[i][1] = (KeyEvent) keyEvents.get(firstIdx+1);
+            first[i][2] = (KeyEvent) keyEvents.get(firstIdx+2);
+            firstIdx = keyEvents.size() - 3;
+            last[i][0] = (KeyEvent) keyEvents.get(firstIdx+0);
+            last[i][1] = (KeyEvent) keyEvents.get(firstIdx+1);
+            last[i][2] = (KeyEvent) keyEvents.get(firstIdx+2);
+            System.err.println("+++ KEY Event Auto-Repeat END   Input Loop: "+i);
+            
+            // add a pair of normal press/release in between auto-repeat!
+            firstIdx = keyEvents.size();
+            AWTRobotUtil.keyPress(0, robot, true, java.awt.event.KeyEvent.VK_B, 10);
+            robot.waitForIdle();
+            AWTRobotUtil.keyPress(0, robot, false, java.awt.event.KeyEvent.VK_B, 250);
+            robot.waitForIdle();
+            for(int j=0; j < 10 && keyAdapter.getQueueSize() < firstIdx+3; j++) { // wait until events are collected
+                robot.delay(100);
+            }
+            firstIdx = keyEvents.size();
+        }
+        // dumpKeyEvents(keyEvents);
+        final List<EventObject> keyEvents = keyAdapter.getQueued();
+        NEWTKeyUtil.validateKeyEventOrder(keyEvents);
+        
+        final boolean hasAR = 0 < keyAdapter.getKeyPressedCount(true) ;
+        
+        {
+            final int expTotal = keyEvents.size();
+            final int expAR = hasAR ? expTotal - 3 * 2 * loops : 0; // per loop: 3 for non AR events and 3 for non AR 'B'
+            NEWTKeyUtil.validateKeyAdapterStats(keyAdapter, expTotal, expAR);
+        }
+        
+        if( !hasAR ) {
+            System.err.println("No AUTO-REPEAT triggered by AWT Robot .. aborting test analysis");
+            return;
+        }
+        
+        for(int i=0; i<loops; i++) {
+            System.err.println("Auto-Repeat Loop "+i+" - Head:");
+            NEWTKeyUtil.dumpKeyEvents(Arrays.asList(first[i]));
+            System.err.println("Auto-Repeat Loop "+i+" - Tail:");
+            NEWTKeyUtil.dumpKeyEvents(Arrays.asList(last[i]));
+        }
+        for(int i=0; i<loops; i++) {
+            KeyEvent e = (KeyEvent) first[i][0];
+            Assert.assertTrue("1st Shall be A, but is "+e, KeyEvent.VK_A == e.getKeyCode() );
+            Assert.assertTrue("1st Shall be PRESSED, but is "+e, KeyEvent.EVENT_KEY_PRESSED == e.getEventType() );
+            Assert.assertTrue("1st Shall not be AR, but is "+e, 0 == ( InputEvent.AUTOREPEAT_MASK & e.getModifiers() ) );
+            
+            e = (KeyEvent) first[i][1];
+            Assert.assertTrue("2nd Shall be A, but is "+e, KeyEvent.VK_A == e.getKeyCode() );
+            Assert.assertTrue("2nd Shall be RELEASED, but is "+e, KeyEvent.EVENT_KEY_RELEASED == e.getEventType() );
+            Assert.assertTrue("2nd Shall be AR, but is "+e, 0 != ( InputEvent.AUTOREPEAT_MASK & e.getModifiers() ) );
+            
+            e = (KeyEvent) first[i][2];
+            Assert.assertTrue("3rd Shall be A, but is "+e, KeyEvent.VK_A == e.getKeyCode() );
+            Assert.assertTrue("3rd Shall be TYPED, but is "+e, KeyEvent.EVENT_KEY_TYPED == e.getEventType() );
+            Assert.assertTrue("3rd Shall be AR, but is "+e, 0 != ( InputEvent.AUTOREPEAT_MASK & e.getModifiers() ) );
+            
+            e = (KeyEvent) last[i][0];
+            Assert.assertTrue("last-2 Shall be A, but is "+e, KeyEvent.VK_A == e.getKeyCode() );
+            Assert.assertTrue("last-2 Shall be PRESSED, but is "+e, KeyEvent.EVENT_KEY_PRESSED == e.getEventType() );
+            Assert.assertTrue("last-2 Shall be AR, but is "+e, 0 != ( InputEvent.AUTOREPEAT_MASK & e.getModifiers() ) );
+            
+            e = (KeyEvent) last[i][1];
+            Assert.assertTrue("last-1 Shall be A, but is "+e, KeyEvent.VK_A == e.getKeyCode() );
+            Assert.assertTrue("last-1 Shall be RELEASED, but is "+e, KeyEvent.EVENT_KEY_RELEASED == e.getEventType() );
+            Assert.assertTrue("last-1 Shall not be AR, but is "+e, 0 == ( InputEvent.AUTOREPEAT_MASK & e.getModifiers() ) );
+            
+            e = (KeyEvent) last[i][2];
+            Assert.assertTrue("last-0 Shall be A, but is "+e, KeyEvent.VK_A == e.getKeyCode() );
+            Assert.assertTrue("last-0 Shall be TYPED, but is "+e, KeyEvent.EVENT_KEY_TYPED == e.getEventType() );
+            Assert.assertTrue("last-0 Shall not be AR, but is "+e, 0 == ( InputEvent.AUTOREPEAT_MASK & e.getModifiers() ) );
+        }
+    }
+    
+    void testImpl(GLWindow glWindow) throws AWTException, InterruptedException, InvocationTargetException {
+        final Robot robot = new Robot();
+        robot.setAutoWaitForIdle(true);
+
+        GLEventListener demo1 = new RedSquareES2();
+        TestListenerCom01AWT.setDemoFields(demo1, glWindow, false);
+        glWindow.addGLEventListener(demo1);
+
+        NEWTKeyAdapter glWindow1KA = new NEWTKeyAdapter("GLWindow1");
+        glWindow1KA.setVerbose(false);
+        glWindow.addKeyListener(glWindow1KA);
+
+        Assert.assertEquals(true,  AWTRobotUtil.waitForRealized(glWindow, true));        
+
+        // Continuous animation ..
+        Animator animator = new Animator(glWindow);
+        animator.start();
+
+        Thread.sleep(durationPerTest); // manual testing
+        
+        AWTRobotUtil.assertRequestFocusAndWait(null, glWindow, glWindow, null, null);  // programmatic
+        AWTRobotUtil.requestFocus(robot, glWindow, false); // within unit framework, prev. tests (TestFocus02SwingAWTRobot) 'confuses' Windows keyboard input
+        glWindow1KA.reset();
+
+        // 
+        // Test the key event order w/ auto-repeat
+        //
+        final int origAutoDelay = robot.getAutoDelay();
+        robot.setAutoDelay(10);
+        try {
+            testKeyEventAutoRepeat(robot, glWindow1KA, 3, 1000);
+        } finally {        
+            robot.setAutoDelay(origAutoDelay);
+        }
+        
+        // Remove listeners to avoid logging during dispose/destroy.
+        glWindow.removeKeyListener(glWindow1KA);
+
+        // Shutdown the test.
+        animator.stop();
+    }
+
+    static int atoi(String a) {
+        int i=0;
+        try {
+            i = Integer.parseInt(a);
+        } catch (Exception ex) { ex.printStackTrace(); }
+        return i;
+    }
+
+    public static void main(String args[]) throws IOException {
+        for(int i=0; i<args.length; i++) {
+            if(args[i].equals("-time")) {
+                durationPerTest = atoi(args[++i]);
+            }
+        }
+        /**
+        BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
+        System.err.println("Press enter to continue");
+        System.err.println(stdin.readLine()); 
+        */
+        System.out.println("durationPerTest: "+durationPerTest);
+        String tstname = TestNewtKeyEventAutoRepeatAWT.class.getName();
+        org.junit.runner.JUnitCore.main(tstname);
+    }
+
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java b/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyEventOrderAWT.java
similarity index 52%
copy from src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java
copy to src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyEventOrderAWT.java
index bb67e77..cf50161 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyEventOrderAWT.java
@@ -1,5 +1,5 @@
 /**
- * Copyright 2010 JogAmp Community. All rights reserved.
+ * 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:
@@ -28,13 +28,14 @@
  
 package com.jogamp.opengl.test.junit.newt;
 
+import org.junit.After;
 import org.junit.Assert;
 import org.junit.AfterClass;
 import org.junit.Assume;
+import org.junit.Before;
 
 import java.awt.AWTException;
 import java.awt.BorderLayout;
-import java.awt.Button;
 import java.awt.Robot;
 import java.lang.reflect.InvocationTargetException;
 
@@ -42,7 +43,6 @@ import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLEventListener;
 import javax.swing.JFrame;
 
-import java.util.ArrayList;
 import java.io.IOException;
 
 import org.junit.BeforeClass;
@@ -55,9 +55,21 @@ import com.jogamp.opengl.test.junit.jogl.demos.es2.RedSquareES2;
 
 import com.jogamp.opengl.test.junit.util.*;
 
-public class TestFocus01SwingAWTRobot extends UITestCase {
+/**
+ * Testing key event order excl. auto-repeat (Bug 601)
+ * 
+ * <p>
+ * Note Event order:
+ * <ol>
+ *   <li>{@link #EVENT_KEY_PRESSED}</li>
+ *   <li>{@link #EVENT_KEY_RELEASED}</li>
+ *   <li>{@link #EVENT_KEY_TYPED}</li>
+ * </ol>
+ * </p>
+ */
+public class TestNewtKeyEventOrderAWT extends UITestCase {
     static int width, height;
-    static long durationPerTest = 10;
+    static long durationPerTest = 100;
     static long awtWaitTimeout = 1000;
 
     static GLCapabilities glCaps;
@@ -72,111 +84,46 @@ public class TestFocus01SwingAWTRobot extends UITestCase {
     @AfterClass
     public static void release() {
     }
-
-    @Test
-    public void testFocus01ProgrFocus() throws AWTException, InterruptedException, InvocationTargetException {
-        testFocus01ProgrFocusImpl(null);
+    
+    @Before
+    public void initTest() {        
     }
 
+    @After
+    public void releaseTest() {        
+    }
+    
     @Test
-    public void testFocus02RobotFocus() throws AWTException, InterruptedException, InvocationTargetException {
-        Robot robot = new Robot();
-        robot.setAutoWaitForIdle(true);
-        testFocus01ProgrFocusImpl(robot);
+    public void test01NEWT() throws AWTException, InterruptedException, InvocationTargetException {
+        GLWindow glWindow = GLWindow.create(glCaps);
+        glWindow.setSize(width, height);
+        glWindow.setVisible(true);
+        
+        testImpl(glWindow);
+        
+        glWindow.destroy();
     }
-
-    private void testFocus01ProgrFocusImpl(Robot robot) throws AWTException,
-            InvocationTargetException, InterruptedException {
-        ArrayList<EventCountAdapter> eventCountAdapters = new ArrayList<EventCountAdapter>();
-
-        // Create a window.
-        GLWindow glWindow1 = GLWindow.create(glCaps);
-        glWindow1.setTitle("testNewtChildFocus");
-        GLEventListener demo1 = new RedSquareES2();
-        TestListenerCom01AWT.setDemoFields(demo1, glWindow1, false);
-        glWindow1.addGLEventListener(demo1);
-        NEWTFocusAdapter glWindow1FA = new NEWTFocusAdapter("GLWindow1");
-        glWindow1.addWindowListener(glWindow1FA);
-
-        // Monitor NEWT focus and keyboard events.
-        NEWTKeyAdapter glWindow1KA = new NEWTKeyAdapter("GLWindow1");
-        eventCountAdapters.add(glWindow1KA);
-        glWindow1.addKeyListener(glWindow1KA);
-
+        
+    @Test
+    public void test02NewtCanvasAWT() throws AWTException, InterruptedException, InvocationTargetException {
+        GLWindow glWindow = GLWindow.create(glCaps);
+        
         // Wrap the window in a canvas.
-        final NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow1);
-
-        // Monitor AWT focus and keyboard events.
-        AWTKeyAdapter newtCanvasAWTKA = new AWTKeyAdapter("NewtCanvasAWT");
-        newtCanvasAWT.addKeyListener(newtCanvasAWTKA);
-        eventCountAdapters.add(newtCanvasAWTKA);
-        AWTFocusAdapter newtCanvasAWTFA = new AWTFocusAdapter("NewtCanvasAWT");
-        newtCanvasAWT.addFocusListener(newtCanvasAWTFA);
-
+        final NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow);
+        
         // Add the canvas to a frame, and make it all visible.
-        final JFrame frame1 = new JFrame("Swing AWT Parent Frame: "
-                                         + glWindow1.getTitle());
-        AWTFocusAdapter frame1FA = new AWTFocusAdapter("frame1");
-        frame1.addFocusListener(frame1FA);
+        final JFrame frame1 = new JFrame("Swing AWT Parent Frame: "+ glWindow.getTitle());
         frame1.getContentPane().add(newtCanvasAWT, BorderLayout.CENTER);
-        final Button button = new Button("Click me ..");
-        AWTFocusAdapter buttonFA = new AWTFocusAdapter("Button");
-        button.addFocusListener(buttonFA);
-        AWTKeyAdapter buttonKA = new AWTKeyAdapter("Button");
-        button.addKeyListener(buttonKA);
-        eventCountAdapters.add(buttonKA);
-        frame1.getContentPane().add(button, BorderLayout.NORTH);
         frame1.setSize(width, height);
         javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
             public void run() {
                 frame1.setVisible(true);
             } } );
+        
         Assert.assertEquals(true,  AWTRobotUtil.waitForVisible(frame1, true));
-        Assert.assertEquals(true,  AWTRobotUtil.waitForRealized(glWindow1, true));        
-        AWTRobotUtil.clearAWTFocus(robot);
-        Assert.assertTrue(AWTRobotUtil.toFrontAndRequestFocus(robot, frame1));
-
-        Thread.sleep(durationPerTest); // manual testing
         
-        int wait=0;
-        while(wait<awtWaitTimeout/100 && glWindow1.getTotalFPSFrames()<1) { Thread.sleep(awtWaitTimeout/10); wait++; }
-        System.err.println("Frames for initial setVisible(true): "+glWindow1.getTotalFPSFrames());
-        Assert.assertTrue(glWindow1.isVisible());
-        Assert.assertTrue(0 < glWindow1.getTotalFPSFrames());
-
-        // Continuous animation ..
-        Animator animator = new Animator(glWindow1);
-        animator.start();
-
-        // Button Focus
-        Thread.sleep(100); // allow event sync
+        testImpl(glWindow);
         
-        System.err.println("FOCUS AWT  Button request");
-        EventCountAdapterUtil.reset(eventCountAdapters);
-        AWTRobotUtil.assertRequestFocusAndWait(robot, button, button, buttonFA, frame1FA);
-        Assert.assertEquals(false, glWindow1FA.focusGained());
-        Assert.assertEquals(false, newtCanvasAWTFA.focusGained());
-        System.err.println("FOCUS AWT  Button sync");
-        AWTRobotUtil.assertKeyType(robot, java.awt.event.KeyEvent.VK_A, 2, button, buttonKA);
-
-        // Request the AWT focus, which should automatically provide the NEWT window with focus.
-        Thread.sleep(100); // allow event sync
-        System.err.println("FOCUS NEWT Canvas/GLWindow request");
-        EventCountAdapterUtil.reset(eventCountAdapters);
-        AWTRobotUtil.assertRequestFocusAndWait(robot, newtCanvasAWT, newtCanvasAWT.getNEWTChild(), glWindow1FA, buttonFA);
-        Assert.assertEquals(false, newtCanvasAWTFA.focusGained());
-        System.err.println("FOCUS NEWT Canvas/GLWindow sync");
-        AWTRobotUtil.assertKeyType(robot, java.awt.event.KeyEvent.VK_A, 2, glWindow1, glWindow1KA);
-        Assert.assertEquals("AWT parent canvas received keyboard events", 0, newtCanvasAWTKA.getCount());
-
-        // Remove listeners to avoid logging during dispose/destroy.
-        glWindow1.removeKeyListener(glWindow1KA);
-        glWindow1.removeWindowListener(glWindow1FA);
-        newtCanvasAWT.removeKeyListener(newtCanvasAWTKA);
-        newtCanvasAWT.removeFocusListener(newtCanvasAWTFA);
-
-        // Shutdown the test.
-        animator.stop();
         try {
             javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
                 public void run() {
@@ -187,7 +134,76 @@ public class TestFocus01SwingAWTRobot extends UITestCase {
             throwable.printStackTrace();
             Assume.assumeNoException( throwable );
         }        
-        glWindow1.destroy();
+        glWindow.destroy();
+    }
+    
+    static void testKeyEventOrder(Robot robot, NEWTKeyAdapter keyAdapter, int loops) {
+        System.err.println("KEY Event Order Test: "+loops);
+        keyAdapter.reset();
+        for(int i=0; i<loops; i++) {
+            // 1
+            AWTRobotUtil.keyPress(0, robot, true, java.awt.event.KeyEvent.VK_A, 10);
+            AWTRobotUtil.keyPress(0, robot, false, java.awt.event.KeyEvent.VK_A, 100);
+            robot.waitForIdle();
+            // 2
+            AWTRobotUtil.keyPress(0, robot, true, java.awt.event.KeyEvent.VK_B, 10);
+            AWTRobotUtil.keyPress(0, robot, false, java.awt.event.KeyEvent.VK_B, 100);
+            robot.waitForIdle();
+            // 3 + 4
+            AWTRobotUtil.keyPress(0, robot, true, java.awt.event.KeyEvent.VK_A, 10);
+            AWTRobotUtil.keyPress(0, robot, true, java.awt.event.KeyEvent.VK_B, 10);
+            AWTRobotUtil.keyPress(0, robot, false, java.awt.event.KeyEvent.VK_A, 10);
+            AWTRobotUtil.keyPress(0, robot, false, java.awt.event.KeyEvent.VK_B, 10);
+            robot.waitForIdle();
+            // 5 + 6
+            AWTRobotUtil.keyPress(0, robot, true, java.awt.event.KeyEvent.VK_A, 10);
+            AWTRobotUtil.keyPress(0, robot, true, java.awt.event.KeyEvent.VK_B, 10);
+            AWTRobotUtil.keyPress(0, robot, false, java.awt.event.KeyEvent.VK_B, 10);
+            AWTRobotUtil.keyPress(0, robot, false, java.awt.event.KeyEvent.VK_A, 10);
+            robot.waitForIdle();            
+        }
+        robot.delay(250);
+        // dumpKeyEvents(keyAdapter.getQueued());
+        
+        NEWTKeyUtil.validateKeyEventOrder(keyAdapter.getQueued());
+        
+        NEWTKeyUtil.validateKeyAdapterStats(keyAdapter, 6*3*loops, 0);        
+    }
+        
+    void testImpl(GLWindow glWindow) throws AWTException, InterruptedException, InvocationTargetException {
+        final Robot robot = new Robot();
+        robot.setAutoWaitForIdle(true);
+
+        GLEventListener demo1 = new RedSquareES2();
+        TestListenerCom01AWT.setDemoFields(demo1, glWindow, false);
+        glWindow.addGLEventListener(demo1);
+
+        NEWTKeyAdapter glWindow1KA = new NEWTKeyAdapter("GLWindow1");
+        glWindow1KA.setVerbose(false);
+        glWindow.addKeyListener(glWindow1KA);
+
+        Assert.assertEquals(true,  AWTRobotUtil.waitForRealized(glWindow, true));        
+
+        // Continuous animation ..
+        Animator animator = new Animator(glWindow);
+        animator.start();
+
+        Thread.sleep(durationPerTest); // manual testing
+        
+        AWTRobotUtil.assertRequestFocusAndWait(null, glWindow, glWindow, null, null);  // programmatic
+        AWTRobotUtil.requestFocus(robot, glWindow, false); // within unit framework, prev. tests (TestFocus02SwingAWTRobot) 'confuses' Windows keyboard input
+        glWindow1KA.reset();
+
+        // 
+        // Test the key event order w/o auto-repeat
+        //
+        testKeyEventOrder(robot, glWindow1KA, 6);
+        
+        // Remove listeners to avoid logging during dispose/destroy.
+        glWindow.removeKeyListener(glWindow1KA);
+
+        // Shutdown the test.
+        animator.stop();
     }
 
     static int atoi(String a) {
@@ -210,7 +226,7 @@ public class TestFocus01SwingAWTRobot extends UITestCase {
         System.err.println(stdin.readLine()); 
         */
         System.out.println("durationPerTest: "+durationPerTest);
-        String tstname = TestFocus01SwingAWTRobot.class.getName();
+        String tstname = TestNewtKeyEventOrderAWT.class.getName();
         org.junit.runner.JUnitCore.main(tstname);
     }
 
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java b/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyPressReleaseUnmaskRepeatAWT.java
similarity index 51%
copy from src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java
copy to src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyPressReleaseUnmaskRepeatAWT.java
index bb67e77..c275139 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyPressReleaseUnmaskRepeatAWT.java
@@ -1,5 +1,5 @@
 /**
- * Copyright 2010 JogAmp Community. All rights reserved.
+ * 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:
@@ -28,13 +28,14 @@
  
 package com.jogamp.opengl.test.junit.newt;
 
+import org.junit.After;
 import org.junit.Assert;
 import org.junit.AfterClass;
 import org.junit.Assume;
+import org.junit.Before;
 
 import java.awt.AWTException;
 import java.awt.BorderLayout;
-import java.awt.Button;
 import java.awt.Robot;
 import java.lang.reflect.InvocationTargetException;
 
@@ -42,22 +43,27 @@ import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLEventListener;
 import javax.swing.JFrame;
 
-import java.util.ArrayList;
 import java.io.IOException;
 
 import org.junit.BeforeClass;
 import org.junit.Test;
 
 import com.jogamp.newt.awt.NewtCanvasAWT;
+import com.jogamp.newt.event.InputEvent;
+import com.jogamp.newt.event.KeyEvent;
+import com.jogamp.newt.event.KeyListener;
 import com.jogamp.newt.opengl.GLWindow;
 import com.jogamp.opengl.util.Animator;
 import com.jogamp.opengl.test.junit.jogl.demos.es2.RedSquareES2;
 
 import com.jogamp.opengl.test.junit.util.*;
 
-public class TestFocus01SwingAWTRobot extends UITestCase {
+/**
+ * Testing key press and release events w/o AUTO-REPEAT
+ */
+public class TestNewtKeyPressReleaseUnmaskRepeatAWT extends UITestCase {
     static int width, height;
-    static long durationPerTest = 10;
+    static long durationPerTest = 100;
     static long awtWaitTimeout = 1000;
 
     static GLCapabilities glCaps;
@@ -72,111 +78,46 @@ public class TestFocus01SwingAWTRobot extends UITestCase {
     @AfterClass
     public static void release() {
     }
-
-    @Test
-    public void testFocus01ProgrFocus() throws AWTException, InterruptedException, InvocationTargetException {
-        testFocus01ProgrFocusImpl(null);
+    
+    @Before
+    public void initTest() {        
     }
 
+    @After
+    public void releaseTest() {        
+    }
+    
     @Test
-    public void testFocus02RobotFocus() throws AWTException, InterruptedException, InvocationTargetException {
-        Robot robot = new Robot();
-        robot.setAutoWaitForIdle(true);
-        testFocus01ProgrFocusImpl(robot);
+    public void test01NEWT() throws AWTException, InterruptedException, InvocationTargetException {
+        GLWindow glWindow = GLWindow.create(glCaps);
+        glWindow.setSize(width, height);
+        glWindow.setVisible(true);
+        
+        testImpl(glWindow);
+        
+        glWindow.destroy();
     }
-
-    private void testFocus01ProgrFocusImpl(Robot robot) throws AWTException,
-            InvocationTargetException, InterruptedException {
-        ArrayList<EventCountAdapter> eventCountAdapters = new ArrayList<EventCountAdapter>();
-
-        // Create a window.
-        GLWindow glWindow1 = GLWindow.create(glCaps);
-        glWindow1.setTitle("testNewtChildFocus");
-        GLEventListener demo1 = new RedSquareES2();
-        TestListenerCom01AWT.setDemoFields(demo1, glWindow1, false);
-        glWindow1.addGLEventListener(demo1);
-        NEWTFocusAdapter glWindow1FA = new NEWTFocusAdapter("GLWindow1");
-        glWindow1.addWindowListener(glWindow1FA);
-
-        // Monitor NEWT focus and keyboard events.
-        NEWTKeyAdapter glWindow1KA = new NEWTKeyAdapter("GLWindow1");
-        eventCountAdapters.add(glWindow1KA);
-        glWindow1.addKeyListener(glWindow1KA);
-
+        
+    @Test
+    public void test02NewtCanvasAWT() throws AWTException, InterruptedException, InvocationTargetException {
+        GLWindow glWindow = GLWindow.create(glCaps);
+        
         // Wrap the window in a canvas.
-        final NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow1);
-
-        // Monitor AWT focus and keyboard events.
-        AWTKeyAdapter newtCanvasAWTKA = new AWTKeyAdapter("NewtCanvasAWT");
-        newtCanvasAWT.addKeyListener(newtCanvasAWTKA);
-        eventCountAdapters.add(newtCanvasAWTKA);
-        AWTFocusAdapter newtCanvasAWTFA = new AWTFocusAdapter("NewtCanvasAWT");
-        newtCanvasAWT.addFocusListener(newtCanvasAWTFA);
-
+        final NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow);
+        
         // Add the canvas to a frame, and make it all visible.
-        final JFrame frame1 = new JFrame("Swing AWT Parent Frame: "
-                                         + glWindow1.getTitle());
-        AWTFocusAdapter frame1FA = new AWTFocusAdapter("frame1");
-        frame1.addFocusListener(frame1FA);
+        final JFrame frame1 = new JFrame("Swing AWT Parent Frame: "+ glWindow.getTitle());
         frame1.getContentPane().add(newtCanvasAWT, BorderLayout.CENTER);
-        final Button button = new Button("Click me ..");
-        AWTFocusAdapter buttonFA = new AWTFocusAdapter("Button");
-        button.addFocusListener(buttonFA);
-        AWTKeyAdapter buttonKA = new AWTKeyAdapter("Button");
-        button.addKeyListener(buttonKA);
-        eventCountAdapters.add(buttonKA);
-        frame1.getContentPane().add(button, BorderLayout.NORTH);
         frame1.setSize(width, height);
         javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
             public void run() {
                 frame1.setVisible(true);
             } } );
+        
         Assert.assertEquals(true,  AWTRobotUtil.waitForVisible(frame1, true));
-        Assert.assertEquals(true,  AWTRobotUtil.waitForRealized(glWindow1, true));        
-        AWTRobotUtil.clearAWTFocus(robot);
-        Assert.assertTrue(AWTRobotUtil.toFrontAndRequestFocus(robot, frame1));
-
-        Thread.sleep(durationPerTest); // manual testing
         
-        int wait=0;
-        while(wait<awtWaitTimeout/100 && glWindow1.getTotalFPSFrames()<1) { Thread.sleep(awtWaitTimeout/10); wait++; }
-        System.err.println("Frames for initial setVisible(true): "+glWindow1.getTotalFPSFrames());
-        Assert.assertTrue(glWindow1.isVisible());
-        Assert.assertTrue(0 < glWindow1.getTotalFPSFrames());
-
-        // Continuous animation ..
-        Animator animator = new Animator(glWindow1);
-        animator.start();
-
-        // Button Focus
-        Thread.sleep(100); // allow event sync
+        testImpl(glWindow);
         
-        System.err.println("FOCUS AWT  Button request");
-        EventCountAdapterUtil.reset(eventCountAdapters);
-        AWTRobotUtil.assertRequestFocusAndWait(robot, button, button, buttonFA, frame1FA);
-        Assert.assertEquals(false, glWindow1FA.focusGained());
-        Assert.assertEquals(false, newtCanvasAWTFA.focusGained());
-        System.err.println("FOCUS AWT  Button sync");
-        AWTRobotUtil.assertKeyType(robot, java.awt.event.KeyEvent.VK_A, 2, button, buttonKA);
-
-        // Request the AWT focus, which should automatically provide the NEWT window with focus.
-        Thread.sleep(100); // allow event sync
-        System.err.println("FOCUS NEWT Canvas/GLWindow request");
-        EventCountAdapterUtil.reset(eventCountAdapters);
-        AWTRobotUtil.assertRequestFocusAndWait(robot, newtCanvasAWT, newtCanvasAWT.getNEWTChild(), glWindow1FA, buttonFA);
-        Assert.assertEquals(false, newtCanvasAWTFA.focusGained());
-        System.err.println("FOCUS NEWT Canvas/GLWindow sync");
-        AWTRobotUtil.assertKeyType(robot, java.awt.event.KeyEvent.VK_A, 2, glWindow1, glWindow1KA);
-        Assert.assertEquals("AWT parent canvas received keyboard events", 0, newtCanvasAWTKA.getCount());
-
-        // Remove listeners to avoid logging during dispose/destroy.
-        glWindow1.removeKeyListener(glWindow1KA);
-        glWindow1.removeWindowListener(glWindow1FA);
-        newtCanvasAWT.removeKeyListener(newtCanvasAWTKA);
-        newtCanvasAWT.removeFocusListener(newtCanvasAWTFA);
-
-        // Shutdown the test.
-        animator.stop();
         try {
             javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
                 public void run() {
@@ -187,7 +128,36 @@ public class TestFocus01SwingAWTRobot extends UITestCase {
             throwable.printStackTrace();
             Assume.assumeNoException( throwable );
         }        
-        glWindow1.destroy();
+        glWindow.destroy();
+    }
+    
+    void testImpl(GLWindow glWindow) throws AWTException, InterruptedException, InvocationTargetException {
+        final Robot robot = new Robot();
+        robot.setAutoWaitForIdle(true);
+
+        GLEventListener demo1 = new RedSquareES2();
+        TestListenerCom01AWT.setDemoFields(demo1, glWindow, false);
+        glWindow.addGLEventListener(demo1);
+
+        SimpleKeyPressRelease simpleKeyPressRelease = new SimpleKeyPressRelease();
+        glWindow.addKeyListener(simpleKeyPressRelease);
+
+        Assert.assertEquals(true,  AWTRobotUtil.waitForRealized(glWindow, true));        
+
+        // Continuous animation ..
+        Animator animator = new Animator(glWindow);
+        animator.start();
+
+        Thread.sleep(durationPerTest); // manual testing
+        
+        AWTRobotUtil.assertRequestFocusAndWait(null, glWindow, glWindow, null, null);  // programmatic
+        AWTRobotUtil.requestFocus(robot, glWindow, false); // within unit framework, prev. tests (TestFocus02SwingAWTRobot) 'confuses' Windows keyboard input
+
+        // Remove listeners to avoid logging during dispose/destroy.
+        glWindow.removeKeyListener(simpleKeyPressRelease);
+
+        // Shutdown the test.
+        animator.stop();
     }
 
     static int atoi(String a) {
@@ -197,6 +167,39 @@ public class TestFocus01SwingAWTRobot extends UITestCase {
         } catch (Exception ex) { ex.printStackTrace(); }
         return i;
     }
+    
+    static class SimpleKeyPressRelease implements KeyListener {
+        int seq;
+
+        SimpleKeyPressRelease() {
+            reset();
+        }
+        
+        public void reset() {
+            seq=0;
+        }
+        
+        @Override
+        public void keyPressed(KeyEvent e) {
+            if( 0 == ( InputEvent.AUTOREPEAT_MASK & e.getModifiers() ) ) {
+                seq++;
+                System.err.println(seq+": "+e);
+            }
+        }
+
+        @Override
+        public void keyReleased(KeyEvent e) {
+            if( 0 == ( InputEvent.AUTOREPEAT_MASK & e.getModifiers() ) ) {
+                seq++;
+                System.err.println(seq+": "+e);
+            }
+        }
+
+        @Override
+        public void keyTyped(KeyEvent e) {
+        }
+        
+    }
 
     public static void main(String args[]) throws IOException {
         for(int i=0; i<args.length; i++) {
@@ -210,7 +213,7 @@ public class TestFocus01SwingAWTRobot extends UITestCase {
         System.err.println(stdin.readLine()); 
         */
         System.out.println("durationPerTest: "+durationPerTest);
-        String tstname = TestFocus01SwingAWTRobot.class.getName();
+        String tstname = TestNewtKeyPressReleaseUnmaskRepeatAWT.class.getName();
         org.junit.runner.JUnitCore.main(tstname);
     }
 
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteGLWindows01NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteGLWindows01NEWT.java
index 35e2440..ef830b6 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteGLWindows01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteGLWindows01NEWT.java
@@ -30,7 +30,6 @@ package com.jogamp.opengl.test.junit.newt;
 
 import org.junit.Assert;
 import org.junit.Assume;
-import org.junit.BeforeClass;
 import org.junit.Test;
 
 import javax.media.opengl.*;
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteWindow01NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteWindow01NEWT.java
index eb65258..53995e8 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteWindow01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteWindow01NEWT.java
@@ -47,7 +47,7 @@ public class TestRemoteWindow01NEWT extends UITestCase {
 
     @BeforeClass
     public static void initClass() {
-        NativeWindowFactory.initSingleton(true);
+        NativeWindowFactory.initSingleton();
         width  = 640;
         height = 480;
     }
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00NEWT.java
index a5b7a76..577119b 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00NEWT.java
@@ -59,7 +59,7 @@ public class TestScreenMode00NEWT extends UITestCase {
 
     @BeforeClass
     public static void initClass() {
-        NativeWindowFactory.initSingleton(true);
+        NativeWindowFactory.initSingleton();
         width  = 640;
         height = 480;
     }
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00bNEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00bNEWT.java
index e9e66da..75a3126 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00bNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00bNEWT.java
@@ -57,7 +57,7 @@ public class TestScreenMode00bNEWT extends UITestCase {
         
     @BeforeClass
     public static void initClass() {
-        NativeWindowFactory.initSingleton(true);
+        NativeWindowFactory.initSingleton();
         width  = 640;
         height = 480;
     }
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode01NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode01NEWT.java
index c3c68e4..f253f3b 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode01NEWT.java
@@ -34,7 +34,6 @@ import javax.media.opengl.GLProfile;
 
 import com.jogamp.opengl.util.Animator;
 
-import org.junit.After;
 import org.junit.AfterClass;
 import org.junit.Assert;
 import org.junit.BeforeClass;
@@ -48,6 +47,7 @@ import com.jogamp.newt.ScreenMode;
 import com.jogamp.newt.opengl.GLWindow;
 import com.jogamp.newt.util.ScreenModeUtil;
 import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
 import com.jogamp.opengl.test.junit.util.UITestCase;
 
 import java.util.List;
@@ -109,10 +109,12 @@ public class TestScreenMode01NEWT extends UITestCase {
      * Remedy B) is shown in {@link TestScreenMode01bNEWT}
      * </pre>
      */
-    @After
-    public void cleanupGL() throws InterruptedException {
-        GLProfile.shutdown(GLProfile.ShutdownType.COMPLETE);
+    private void cleanupGL() throws InterruptedException {
+        System.err.println("*** cleanupGL.shutdown");
+        GLProfile.shutdown();
+        System.err.println("*** cleanupGL.initSingleton");
         GLProfile.initSingleton();
+        System.err.println("*** cleanupGL.DONE");
     }
     
     static GLWindow createWindow(Screen screen, GLCapabilities caps, int width, int height, boolean onscreen, boolean undecorated) {
@@ -166,7 +168,15 @@ public class TestScreenMode01NEWT extends UITestCase {
         Thread.sleep(waitTimeShort);
 
         animator.stop();
-        destroyWindow(window);        
+        Assert.assertEquals(false, animator.isAnimating());
+        Assert.assertEquals(false, animator.isStarted());
+        
+        destroyWindow(window);
+        Assert.assertTrue(AWTRobotUtil.waitForRealized(window, false));
+        Assert.assertEquals(false, window.isRealized());
+        Assert.assertEquals(false, window.isNativeValid());
+        
+        cleanupGL();
     }
 
     @Test
@@ -230,11 +240,15 @@ public class TestScreenMode01NEWT extends UITestCase {
         Assert.assertEquals(true,window.isNativeValid());
         Assert.assertEquals(true,window.isVisible());
 
-        animator.stop();
+        animator.stop();        
+        Assert.assertEquals(false, animator.isAnimating());
+        Assert.assertEquals(false, animator.isStarted());
+        
         destroyWindow(window);
-        Thread.sleep(waitTimeShort);
+        Assert.assertTrue(AWTRobotUtil.waitForRealized(window, false));
 
         Assert.assertEquals(false,window.isVisible());
+        Assert.assertEquals(false,window.isRealized());
         Assert.assertEquals(false,window.isNativeValid());
         Assert.assertEquals(false,screen.isNativeValid());
         Assert.assertEquals(false,display.isNativeValid());
@@ -246,14 +260,15 @@ public class TestScreenMode01NEWT extends UITestCase {
 
         smCurrent = screen.getCurrentScreenMode();
         System.err.println("[1] current/orig: "+smCurrent);
+        screen.destroy();
+        Assert.assertEquals(false,screen.isNativeValid());
+        Assert.assertEquals(false,display.isNativeValid());
 
         Assert.assertNotNull(smCurrent);
         Assert.assertEquals(smCurrent, smOrig);
 
-        screen.destroy();
-
-        Assert.assertEquals(false,screen.isNativeValid());
-        Assert.assertEquals(false,display.isNativeValid());
+        
+        cleanupGL();
     }
 
     @Test
@@ -326,10 +341,14 @@ public class TestScreenMode01NEWT extends UITestCase {
         Assert.assertEquals(true,window.isVisible());
 
         animator.stop();
+        Assert.assertEquals(false, animator.isAnimating());
+        Assert.assertEquals(false, animator.isStarted());
+        
         destroyWindow(window);
-        Thread.sleep(waitTimeShort);
+        Assert.assertTrue(AWTRobotUtil.waitForRealized(window, false));
 
         Assert.assertEquals(false,window.isVisible());
+        Assert.assertEquals(false,window.isRealized());
         Assert.assertEquals(false,window.isNativeValid());
         Assert.assertEquals(false,screen.isNativeValid());
         Assert.assertEquals(false,display.isNativeValid());
@@ -341,11 +360,14 @@ public class TestScreenMode01NEWT extends UITestCase {
         
         smCurrent = screen.getCurrentScreenMode();
         System.err.println("[1] current/orig: "+smCurrent);
+        screen.destroy();
+        Assert.assertEquals(false,screen.isNativeValid());
+        Assert.assertEquals(false,display.isNativeValid());
 
         Assert.assertNotNull(smCurrent);
         Assert.assertEquals(smCurrent, smOrig);
-
-        screen.destroy();
+        
+        cleanupGL();
     }
 
     public static void main(String args[]) throws IOException {
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestWindows01NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestWindows01NEWT.java
index a99edfa..e03b5e7 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestWindows01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestWindows01NEWT.java
@@ -33,7 +33,6 @@ import org.junit.BeforeClass;
 import org.junit.Test;
 
 import javax.media.nativewindow.*;
-import javax.media.nativewindow.util.Point;
 
 import com.jogamp.newt.*;
 import java.io.IOException;
@@ -45,7 +44,7 @@ public class TestWindows01NEWT extends UITestCase {
 
     @BeforeClass
     public static void initClass() {
-        NativeWindowFactory.initSingleton(true);
+        NativeWindowFactory.initSingleton();
         width  = 256;
         height = 256;
     }
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 473f2f5..15393e8 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
@@ -36,7 +36,7 @@ import com.jogamp.newt.event.KeyAdapter;
 import com.jogamp.newt.event.KeyEvent;
 import com.jogamp.newt.opengl.GLWindow;
 
-class NewtAWTReparentingKeyAdapter extends KeyAdapter {
+public class NewtAWTReparentingKeyAdapter extends KeyAdapter {
     Frame frame;
     NewtCanvasAWT newtCanvasAWT;
     GLWindow glWindow;
@@ -48,7 +48,9 @@ class NewtAWTReparentingKeyAdapter extends KeyAdapter {
     }
     
     public void keyTyped(KeyEvent e) {
-        if(e.getKeyChar()=='d') {
+        if(e.getKeyChar()=='i') {
+            System.err.println(glWindow);
+        } else if(e.getKeyChar()=='d') {
             glWindow.setUndecorated(!glWindow.isUndecorated());
         } else if(e.getKeyChar()=='f') {
             glWindow.setFullscreen(!glWindow.isFullscreen());
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingFocusTraversal01AWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingFocusTraversal01AWT.java
index f39b5df..d6f1f81 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingFocusTraversal01AWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingFocusTraversal01AWT.java
@@ -68,12 +68,13 @@ public class TestParentingFocusTraversal01AWT extends UITestCase {
     static long durationPerTest = numFocus * 200;
     static GLCapabilities glCaps;
     static boolean manual = false;
+    static boolean forceGL3 = false;
 
     @BeforeClass
     public static void initClass() {
         glSize = new Dimension(200,200);
         fSize = new Dimension(300,300);
-        glCaps = new GLCapabilities(null);
+        glCaps = new GLCapabilities( forceGL3 ? GLProfile.get(GLProfile.GL3) : null );
     }
 
     @Test
@@ -314,6 +315,8 @@ public class TestParentingFocusTraversal01AWT extends UITestCase {
                 durationPerTest = atoi(args[++i]);
             } else if(args[i].equals("-manual")) {
                 manual = true;
+            } else if(args[i].equals("-gl3")) {
+                forceGL3 = true;
             }
         }
         String tstname = TestParentingFocusTraversal01AWT.class.getName();
diff --git a/src/test/com/jogamp/opengl/test/junit/util/AWTFocusAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/AWTFocusAdapter.java
index fe0f2ac..32ff602 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/AWTFocusAdapter.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/AWTFocusAdapter.java
@@ -36,12 +36,15 @@ public class AWTFocusAdapter implements FocusEventCountAdapter, FocusListener {
     String prefix;
     int focusCount;
     boolean wasTemporary;
+    boolean verbose = true;
 
     public AWTFocusAdapter(String prefix) {
         this.prefix = prefix;
         reset();
     }
 
+    public void setVerbose(boolean v) { verbose = false; }
+
     public boolean focusLost() {
         return focusCount<0;        
     }
@@ -65,7 +68,9 @@ public class AWTFocusAdapter implements FocusEventCountAdapter, FocusListener {
         if(focusCount<0) { focusCount=0; }
         focusCount++;
         wasTemporary = e.isTemporary();
-        System.err.println("FOCUS AWT  GAINED "+(wasTemporary?"TEMP":"PERM")+" [fc "+focusCount+"]: "+prefix+", "+e);
+        if( verbose ) {
+            System.err.println("FOCUS AWT  GAINED "+(wasTemporary?"TEMP":"PERM")+" [fc "+focusCount+"]: "+prefix+", "+e);
+        }
     }
 
     /* @Override */
@@ -73,7 +78,9 @@ public class AWTFocusAdapter implements FocusEventCountAdapter, FocusListener {
         if(focusCount>0) { focusCount=0; }
         focusCount--;
         wasTemporary = e.isTemporary();
-        System.err.println("FOCUS AWT  LOST   "+(wasTemporary?"TEMP":"PERM")+" [fc "+focusCount+"]: "+prefix+", "+e);
+        if( verbose ) {
+            System.err.println("FOCUS AWT  LOST   "+(wasTemporary?"TEMP":"PERM")+" [fc "+focusCount+"]: "+prefix+", "+e);
+        }
     }
     
     public String toString() { return prefix+"[focusCount "+focusCount +", temp "+wasTemporary+"]"; }    
diff --git a/src/test/com/jogamp/opengl/test/junit/util/AWTKeyAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/AWTKeyAdapter.java
index 6c01561..837ba5d 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/AWTKeyAdapter.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/AWTKeyAdapter.java
@@ -29,44 +29,85 @@
 package com.jogamp.opengl.test.junit.util;
 
 import java.awt.event.KeyEvent;
+import java.util.ArrayList;
+import java.util.EventObject;
+import java.util.List;
 
-public class AWTKeyAdapter extends java.awt.event.KeyAdapter implements InputEventCountAdapter {
+public class AWTKeyAdapter extends java.awt.event.KeyAdapter implements KeyEventCountAdapter {
 
     String prefix;
-    int keyTyped;
+    int keyPressed, keyReleased, keyTyped;
     boolean pressed;
+    List<EventObject> queue = new ArrayList<EventObject>();
+    boolean verbose = true;
 
     public AWTKeyAdapter(String prefix) {
         this.prefix = prefix;
         reset();
     }
 
-    public boolean isPressed() {
+    public synchronized void setVerbose(boolean v) { verbose = false; }
+
+    public synchronized boolean isPressed() {
         return pressed;
     }
     
-    public int getCount() {
+    public synchronized int getCount() {
         return keyTyped;
     }
 
-    public void reset() {
+    public synchronized int getKeyPressedCount(boolean autoRepeatOnly) {
+        return keyPressed; 
+    }
+    
+    public synchronized int getKeyReleasedCount(boolean autoRepeatOnly) {
+        return keyReleased; 
+    }
+    
+    public synchronized int getKeyTypedCount(boolean autoRepeatOnly) {
+        return keyTyped; 
+    }
+    
+    public synchronized List<EventObject> getQueued() {
+        return queue;
+    }
+    
+    public synchronized int getQueueSize() {
+        return queue.size();
+    }
+    
+    public synchronized void reset() {
         keyTyped = 0;
+        keyPressed = 0;
+        keyReleased = 0;
         pressed = false;
+        queue.clear();
     }
 
-    public void keyPressed(KeyEvent e) {
+    public synchronized void keyPressed(KeyEvent e) {
         pressed = true;
-        System.err.println("KEY AWT PRESSED ["+pressed+"]: "+prefix+", "+e);
+        keyPressed++;
+        queue.add(e);
+        if( verbose ) {
+            System.err.println("KEY AWT PRESSED ["+pressed+"]: "+prefix+", "+e);
+        }
     }
 
-    public void keyReleased(KeyEvent e) {
+    public synchronized void keyReleased(KeyEvent e) {
         pressed = false;
-        System.err.println("KEY AWT RELEASED ["+pressed+"]: "+prefix+", "+e);
+        keyReleased++;
+        queue.add(e);
+        if( verbose ) {
+            System.err.println("KEY AWT RELEASED ["+pressed+"]: "+prefix+", "+e);
+        }
     }
 
-    public void keyTyped(java.awt.event.KeyEvent e) {
-        ++keyTyped;
-        System.err.println("KEY AWT  TYPED ["+keyTyped+"]: "+prefix+", "+e);
+    public synchronized void keyTyped(java.awt.event.KeyEvent e) {
+        keyTyped++;
+        queue.add(e);
+        if( verbose ) {
+            System.err.println("KEY AWT  TYPED ["+keyTyped+"]: "+prefix+", "+e);
+        }
     }
     
     public String toString() { return prefix+"[pressed "+pressed+", typed "+keyTyped+"]"; }
diff --git a/src/test/com/jogamp/opengl/test/junit/util/AWTMouseAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/AWTMouseAdapter.java
index b948023..31362bf 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/AWTMouseAdapter.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/AWTMouseAdapter.java
@@ -29,43 +29,68 @@
 package com.jogamp.opengl.test.junit.util;
 
 import java.awt.event.MouseEvent;
+import java.util.ArrayList;
+import java.util.EventObject;
+import java.util.List;
 
 public class AWTMouseAdapter extends java.awt.event.MouseAdapter implements InputEventCountAdapter {
     String prefix;
     int mouseClicked;
     boolean pressed;
+    List<EventObject> queue = new ArrayList<EventObject>();
+    boolean verbose = true;
 
     public AWTMouseAdapter(String prefix) {
         this.prefix = prefix;
         reset();
     }
 
-    public boolean isPressed() {
+    public synchronized void setVerbose(boolean v) { verbose = false; }
+    
+    public synchronized boolean isPressed() {
         return pressed;
     }
     
-    public int getCount() {
+    public synchronized int getCount() {
         return mouseClicked;
     }
     
-    public void reset() {
+    public synchronized List<EventObject> getQueued() {
+        return queue;
+    }
+    
+    public synchronized int getQueueSize() {
+        return queue.size();
+    }
+
+    public synchronized void reset() {
         mouseClicked = 0;
         pressed = false;
+        queue.clear();
     }
 
-    public void mousePressed(MouseEvent e) {
+    public synchronized void mousePressed(MouseEvent e) {
         pressed = true;
-        System.err.println("MOUSE AWT PRESSED ["+pressed+"]: "+prefix+", "+e);
+        queue.add(e);
+        if( verbose ) {
+            System.err.println("MOUSE AWT PRESSED ["+pressed+"]: "+prefix+", "+e);
+        }
     }
 
-    public void mouseReleased(MouseEvent e) {
+    public synchronized void mouseReleased(MouseEvent e) {
         pressed = false;
-        System.err.println("MOUSE AWT RELEASED ["+pressed+"]: "+prefix+", "+e);
+        queue.add(e);
+        if( verbose ) {
+            System.err.println("MOUSE AWT RELEASED ["+pressed+"]: "+prefix+", "+e);
+        }
     }
     
-    public void mouseClicked(java.awt.event.MouseEvent e) {
+    public synchronized void mouseClicked(java.awt.event.MouseEvent e) {
         mouseClicked+=e.getClickCount();
-        System.err.println("MOUSE AWT CLICKED ["+mouseClicked+"]: "+prefix+", "+e);
+        queue.add(e);
+        if( verbose ) {
+            System.err.println("MOUSE AWT CLICKED ["+mouseClicked+"]: "+prefix+", "+e);
+        }
     }    
     
     public String toString() { return prefix+"[pressed "+pressed+", clicked "+mouseClicked+"]"; }
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 35a2d96..e64b320 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java
@@ -29,6 +29,7 @@
 package com.jogamp.opengl.test.junit.util;
 
 import jogamp.newt.WindowImplAccess;
+
 import java.lang.reflect.InvocationTargetException;
 import java.awt.AWTException;
 import java.awt.Component;
@@ -38,6 +39,7 @@ import java.awt.Robot;
 import java.awt.Toolkit;
 
 import javax.media.nativewindow.NativeWindow;
+import javax.media.opengl.GLDrawable;
 import javax.media.opengl.awt.GLCanvas;
 
 import org.junit.Assert;
@@ -194,10 +196,20 @@ public class AWTRobotUtil {
     
     /**
      * requestFocus, if robot is valid, use mouse operation,
-     * otherwise programatic, ie call requestFocus
+     * otherwise programmatic, ie call requestFocus
      */
     public static void requestFocus(Robot robot, Object obj) 
         throws AWTException, InterruptedException, InvocationTargetException {
+        requestFocus(robot, obj, true);
+    }
+    
+    /**
+     * requestFocus, if robot is valid, use mouse operation,
+     * otherwise programmatic, ie call requestFocus
+     */
+    public static void requestFocus(Robot robot, Object obj, boolean onTitleBarIfWindow) 
+        throws AWTException, InterruptedException, InvocationTargetException {
+    
         final Component comp;
         final com.jogamp.newt.Window win;
 
@@ -211,7 +223,7 @@ public class AWTRobotUtil {
             throw new RuntimeException("Neither AWT nor NEWT: "+obj);
         }
         
-        if(null == robot) {        
+        if(null == robot) {            
             if(null!=comp) {
                 javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
                     public void run() {
@@ -224,7 +236,7 @@ public class AWTRobotUtil {
             }
         } else {
             final int mouseButton = java.awt.event.InputEvent.BUTTON1_MASK;    
-            centerMouse(robot, obj, true);
+            centerMouse(robot, obj, onTitleBarIfWindow);
     
             robot.waitForIdle();
             robot.mousePress(mouseButton);
@@ -274,24 +286,29 @@ public class AWTRobotUtil {
      *
      * @return True if the Window became the global focused Window within TIME_OUT
      */
-    public static boolean waitForFocus(Object obj, FocusEventCountAdapter gain, 
-                                                   FocusEventCountAdapter lost) throws InterruptedException {
-        if(!waitForFocus(obj)) {
-            return false;
-        }
-        if(null == gain) {
-            return true;
-        }
-        
+    public static boolean waitForFocus(FocusEventCountAdapter gain, 
+                                       FocusEventCountAdapter lost) throws InterruptedException {
         int wait;
         for (wait=0; wait<POLL_DIVIDER; wait++) {
-            if( ( null == lost || lost.focusLost() ) && gain.focusGained() ) {
+            if( ( null == lost || lost.focusLost() ) && ( null == gain || gain.focusGained() ) ) {
                 return true;
             }
             Thread.sleep(TIME_SLICE);
         }
         return false;
     }
+        
+    /**
+     *
+     * @return True if the Window became the global focused Window within TIME_OUT
+     */
+    public static boolean waitForFocus(Object obj, FocusEventCountAdapter gain, 
+                                                   FocusEventCountAdapter lost) throws InterruptedException {
+        if(!waitForFocus(obj)) {
+            return false;
+        }
+        return waitForFocus(gain, lost);
+    }
 
     public static void assertRequestFocusAndWait(Robot robot, Object requestFocus, Object waitForFocus, 
                                               FocusEventCountAdapter gain, FocusEventCountAdapter lost)
@@ -306,7 +323,7 @@ public class AWTRobotUtil {
         }
         if(!hasFocus) {
             System.err.print("*** AWTRobotUtil.assertRequestFocusAndWait() ");
-            if(gain.focusGained() && !lost.focusLost()) {
+            if( ( null == gain || gain.focusGained() ) && ( null == lost || !lost.focusLost() ) ) {
                 // be error tolerant here, some impl. may lack focus-lost events (OS X) 
                 System.err.println("minor UI failure");
                 hasFocus = true;
@@ -331,11 +348,12 @@ public class AWTRobotUtil {
     }
 
     public static int keyType(int i, Robot robot, int keyCode,
-                              Object obj, InputEventCountAdapter counter) throws InterruptedException, AWTException, InvocationTargetException 
+                              Object obj, KeyEventCountAdapter counter) throws InterruptedException, AWTException, InvocationTargetException 
     {
         int tc = 0;
         int j;
         final long t0 = System.currentTimeMillis();
+        final int c0 = null!=counter ? counter.getCount() : 0;
         
         for(j=0; 1 > tc && j<RETRY_NUMBER; j++) {
             if(!hasFocus(obj)) {
@@ -343,11 +361,12 @@ public class AWTRobotUtil {
                 if(DEBUG) { System.err.println(i+":"+j+" KC1.0: "+counter+" - regain focus"); }
                 requestFocus(null, obj);
             }
-            final int c0 = null!=counter ? counter.getCount() : 0;
             if(DEBUG) { System.err.println(i+":"+j+" KC1.1: "+counter); }
             robot.waitForIdle();
             robot.keyPress(keyCode);
+            robot.delay(10);
             robot.keyRelease(keyCode);
+            robot.delay(100);
             if(DEBUG) { System.err.println(i+":"+j+" KC1.2: "+counter); }
             tc = ( null!=counter ? counter.getCount() : 1 ) - c0;
             for (int wait=0; wait<POLL_DIVIDER && 1 > tc; wait++) {
@@ -359,13 +378,26 @@ public class AWTRobotUtil {
         Assert.assertEquals("Key ("+i+":"+j+") not typed one time", 1, tc);
         return (int) ( System.currentTimeMillis() - t0 ) ;
     }
+
+    /** No validation is performed .. */ 
+    public static int keyPress(int i, Robot robot, boolean press, int keyCode, int msDelay) {
+        final long t0 = System.currentTimeMillis();        
+        if(press) {
+            robot.keyPress(keyCode);
+        } else {
+            robot.keyRelease(keyCode);
+        }
+        robot.delay(msDelay);
+        
+        return (int) ( System.currentTimeMillis() - t0 ) ;
+    }
     
     /**
      * @param keyCode TODO
      * @param counter shall return the number of keys typed (press + release)
      */
     public static void assertKeyType(Robot robot, int keyCode, int typeCount, 
-                                     Object obj, InputEventCountAdapter counter) 
+                                     Object obj, KeyEventCountAdapter counter) 
         throws AWTException, InterruptedException, InvocationTargetException {
 
         if(null == robot) {
@@ -392,6 +424,38 @@ public class AWTRobotUtil {
         Assert.assertEquals("Wrong key count", typeCount, counter.getCount()-c0);
     }
 
+    /**
+     * @param keyCode TODO
+     * @param counter shall return the number of keys typed (press + release)
+     */
+    public static void assertKeyPress(Robot robot, int keyCode, int typeCount, 
+                                      Object obj, KeyEventCountAdapter counter) 
+        throws AWTException, InterruptedException, InvocationTargetException {
+
+        if(null == robot) {
+            robot = new Robot();
+            robot.setAutoWaitForIdle(true);
+        }
+
+        centerMouse(robot, obj, false);
+
+        Assert.assertEquals("Key already pressed", false, counter.isPressed());
+        
+        if(DEBUG) {
+            System.err.println("**************************************");
+            System.err.println("KC0: "+counter);
+        }
+        
+        final int c0 = counter.getCount();
+
+        for(int i=0; i<typeCount; i++) {
+            keyType(i, robot, keyCode, obj, counter); 
+        }
+
+        if(DEBUG) { System.err.println("KC3.0: "+counter); }
+        Assert.assertEquals("Wrong key count", typeCount, counter.getCount()-c0);
+    }
+    
     static int mouseClick(int i, Robot robot, int mouseButton,
                           Object obj, InputEventCountAdapter counter) throws InterruptedException, AWTException, InvocationTargetException 
     {
@@ -460,20 +524,6 @@ public class AWTRobotUtil {
 
     /**
      *
-     * @return True if the FocusEventCountAdapter became the desired value within TIME_OUT
-     */
-    public static boolean waitForFocusCount(boolean desired, FocusEventCountAdapter eca) throws InterruptedException {
-        for (int wait=0; wait<POLL_DIVIDER; wait++) {
-            if( desired && eca.focusGained() || !desired && eca.focusLost() ) {
-                return true;
-            }
-            Thread.sleep(TIME_SLICE);
-        }
-        return false;
-    }
-
-    /**
-     *
      * @return True if the Component becomes <code>visible</code> within TIME_OUT
      */
     public static boolean waitForVisible(Object obj, boolean visible) throws InterruptedException {
@@ -496,6 +546,18 @@ public class AWTRobotUtil {
 
     /**
      *
+     * @return True if the GLDrawable recives the expected size within TIME_OUT
+     */
+    public static boolean waitForSize(GLDrawable drawable, int width, int height) throws InterruptedException {
+        int wait;
+        for (wait=0; wait<POLL_DIVIDER && ( width != drawable.getWidth() || height != drawable.getHeight() ) ; wait++) {
+            Thread.sleep(TIME_SLICE);
+        }
+        return wait<POLL_DIVIDER;
+    }
+
+    /**
+     *
      * @return True if the Component becomes realized (not displayable, native invalid) within TIME_OUT
      */
     public static boolean waitForRealized(Object obj, boolean realized) throws InterruptedException {
diff --git a/src/test/com/jogamp/opengl/test/junit/util/AWTWindowFocusAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/AWTWindowFocusAdapter.java
index 16aacd2..2e74dfa 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/AWTWindowFocusAdapter.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/AWTWindowFocusAdapter.java
@@ -35,12 +35,15 @@ public class AWTWindowFocusAdapter implements FocusEventCountAdapter, WindowFocu
 
     String prefix;
     int focusCount;
+    boolean verbose = true;
 
     public AWTWindowFocusAdapter(String prefix) {
         this.prefix = prefix;
         reset();
     }
 
+    public void setVerbose(boolean v) { verbose = false; }
+
     public boolean focusLost() {
         return focusCount<0;        
     }
@@ -57,14 +60,18 @@ public class AWTWindowFocusAdapter implements FocusEventCountAdapter, WindowFocu
     public void windowGainedFocus(WindowEvent e) {
         if(focusCount<0) { focusCount=0; }
         focusCount++;
-        System.err.println("FOCUS AWT  GAINED (Window) [fc "+focusCount+"]: "+prefix+", "+e);
+        if( verbose ) {
+            System.err.println("FOCUS AWT  GAINED (Window) [fc "+focusCount+"]: "+prefix+", "+e);
+        }
     }
 
     /* @Override */
     public void windowLostFocus(WindowEvent e) {
         if(focusCount>0) { focusCount=0; }
         focusCount--;
-        System.err.println("FOCUS AWT  LOST   (Window) [fc "+focusCount+"]: "+prefix+", "+e);
+        if( verbose ) {
+            System.err.println("FOCUS AWT  LOST   (Window) [fc "+focusCount+"]: "+prefix+", "+e);
+        }
     }
     
     public String toString() { return prefix+"[focusCount "+focusCount +"]"; }
diff --git a/src/test/com/jogamp/opengl/test/junit/util/EventCountAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/EventCountAdapter.java
index 76a1884..906e4a7 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/EventCountAdapter.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/EventCountAdapter.java
@@ -28,7 +28,16 @@
  
 package com.jogamp.opengl.test.junit.util;
 
+/**
+ * Base event count adapter.
+ * <p>
+ * Instance starts in verbose mode.
+ * </p>
+ */
 public interface EventCountAdapter {
     void reset();
+    
+    /** Instance starts in verbose mode, call w/ false to disable verbosity. */
+    void setVerbose(boolean v);
 }
 
diff --git a/src/test/com/jogamp/opengl/test/junit/util/InputEventCountAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/InputEventCountAdapter.java
index 27f3d7e..c407843 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/InputEventCountAdapter.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/InputEventCountAdapter.java
@@ -28,8 +28,14 @@
  
 package com.jogamp.opengl.test.junit.util;
 
+import java.util.EventObject;
+import java.util.List;
+
 public interface InputEventCountAdapter extends  EventCountAdapter {
     int getCount();
     boolean isPressed();
+    
+    public List<EventObject> getQueued(); 
+    public int getQueueSize();
 }
 
diff --git a/src/test/com/jogamp/opengl/test/junit/util/InputEventCountAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/KeyEventCountAdapter.java
similarity index 83%
copy from src/test/com/jogamp/opengl/test/junit/util/InputEventCountAdapter.java
copy to src/test/com/jogamp/opengl/test/junit/util/KeyEventCountAdapter.java
index 27f3d7e..832f5ae 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/InputEventCountAdapter.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/KeyEventCountAdapter.java
@@ -1,5 +1,5 @@
 /**
- * Copyright 2010 JogAmp Community. All rights reserved.
+ * 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:
@@ -28,8 +28,11 @@
  
 package com.jogamp.opengl.test.junit.util;
 
-public interface InputEventCountAdapter extends  EventCountAdapter {
-    int getCount();
-    boolean isPressed();
+public interface KeyEventCountAdapter extends  InputEventCountAdapter {
+    public int getKeyPressedCount(boolean autoRepeatOnly);
+    
+    public int getKeyReleasedCount(boolean autoRepeatOnly);
+    
+    public int getKeyTypedCount(boolean autoRepeatOnly);    
 }
 
diff --git a/src/test/com/jogamp/opengl/test/junit/util/MiscUtils.java b/src/test/com/jogamp/opengl/test/junit/util/MiscUtils.java
index 9cbeabb..c230f0a 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/MiscUtils.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/MiscUtils.java
@@ -30,6 +30,7 @@
 package com.jogamp.opengl.test.junit.util;
 
 import java.lang.reflect.*;
+import java.nio.FloatBuffer;
 
 public class MiscUtils {
     public static int atoi(String str, int def) {
@@ -50,6 +51,53 @@ public class MiscUtils {
         return def;
     }
 
+    public static void assertFloatBufferEquals(String errmsg, FloatBuffer expected, FloatBuffer actual, float delta) {
+        if(null == expected && null == actual) {
+            return;
+        }
+        String msg = null != errmsg ? errmsg + " " : "";
+        if(null == expected) {
+            throw new AssertionError(msg+"; Expected is null, but actual not: "+actual);
+        }
+        if(null == actual) {
+            throw new AssertionError(msg+"; Actual is null, but expected not: "+expected);
+        }
+        if(expected.remaining() != actual.remaining()) {
+            throw new AssertionError(msg+"; Expected has "+expected.remaining()+" remaining, but actual has "+actual.remaining());            
+        }
+        final int a0 = expected.position();
+        final int b0 = actual.position();
+        for(int i=0; i<expected.remaining(); i++) {
+            final float ai = expected.get(a0 + i);
+            final float bi = actual.get(b0 + i);
+            final float daibi = Math.abs(ai - bi);  
+            if( daibi > delta ) {
+                throw new AssertionError(msg+"; Expected @ ["+a0+"+"+i+"] has "+ai+", but actual @ ["+b0+"+"+i+"] has "+bi+", it's delta "+daibi+" > "+delta);
+            }
+        }
+    }
+    
+    public static void assertFloatBufferNotEqual(String errmsg, FloatBuffer expected, FloatBuffer actual, float delta) {
+        if(null == expected || null == actual) {
+            return;
+        }
+        if(expected.remaining() != actual.remaining()) {
+            return;            
+        }
+        String msg = null != errmsg ? errmsg + " " : "";
+        final int a0 = expected.position();
+        final int b0 = actual.position();
+        for(int i=0; i<expected.remaining(); i++) {
+            final float ai = expected.get(a0 + i);
+            final float bi = actual.get(b0 + i);
+            final float daibi = Math.abs(ai - bi);  
+            if( daibi > delta ) {
+                return;
+            }
+        }
+        throw new AssertionError(msg+"; Expected and actual are equal.");
+    }
+    
     public static boolean setFieldIfExists(Object instance, String fieldName, Object value) {
         try {
             Field f = instance.getClass().getField(fieldName);
diff --git a/src/test/com/jogamp/opengl/test/junit/util/NEWTFocusAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/NEWTFocusAdapter.java
index 27d4abd..ccb1bde 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/NEWTFocusAdapter.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/NEWTFocusAdapter.java
@@ -36,12 +36,15 @@ public class NEWTFocusAdapter implements WindowListener, FocusEventCountAdapter
 
     String prefix;
     int focusCount;
+    boolean verbose = true;
 
     public NEWTFocusAdapter(String prefix) {
         this.prefix = prefix;
         reset();
     }
 
+    public void setVerbose(boolean v) { verbose = false; }
+
     public boolean focusLost() {
         return focusCount<0;        
     }
@@ -57,13 +60,17 @@ public class NEWTFocusAdapter implements WindowListener, FocusEventCountAdapter
     public void windowGainedFocus(WindowEvent e) {
         if(focusCount<0) { focusCount=0; }
         focusCount++;
-        System.err.println("FOCUS NEWT GAINED [fc "+focusCount+"]: "+prefix+", "+e);
+        if( verbose ) {
+            System.err.println("FOCUS NEWT GAINED [fc "+focusCount+"]: "+prefix+", "+e);
+        }
     }
 
     public void windowLostFocus(WindowEvent e) {
         if(focusCount>0) { focusCount=0; }
         focusCount--;
-        System.err.println("FOCUS NEWT LOST   [fc "+focusCount+"]: "+prefix+", "+e);
+        if( verbose ) {
+            System.err.println("FOCUS NEWT LOST   [fc "+focusCount+"]: "+prefix+", "+e);
+        }
     }
 
     public void windowResized(WindowEvent e) { }
diff --git a/src/test/com/jogamp/opengl/test/junit/util/NEWTGLContext.java b/src/test/com/jogamp/opengl/test/junit/util/NEWTGLContext.java
index 3f989bf..a76b67d 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/NEWTGLContext.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/NEWTGLContext.java
@@ -70,8 +70,8 @@ public class NEWTGLContext {
         Assert.assertNotNull(window);
         window.setSize(width, height);
         window.setVisible(true);
-        AWTRobotUtil.waitForVisible(window, true);
-        AWTRobotUtil.waitForRealized(window, true);
+        Assert.assertTrue(AWTRobotUtil.waitForVisible(window, true));
+        Assert.assertTrue(AWTRobotUtil.waitForRealized(window, true));
             
         GLDrawableFactory factory = GLDrawableFactory.getFactory(caps.getGLProfile());
         GLDrawable drawable = factory.createGLDrawable(window);
diff --git a/src/test/com/jogamp/opengl/test/junit/util/NEWTKeyAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/NEWTKeyAdapter.java
index 32b392c..f19169b 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/NEWTKeyAdapter.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/NEWTKeyAdapter.java
@@ -28,47 +28,103 @@
  
 package com.jogamp.opengl.test.junit.util;
 
+import java.util.ArrayList;
+import java.util.EventObject;
+import java.util.List;
+
+import com.jogamp.newt.event.InputEvent;
 import com.jogamp.newt.event.KeyAdapter;
 import com.jogamp.newt.event.KeyEvent;
 
-public class NEWTKeyAdapter extends KeyAdapter implements InputEventCountAdapter {
+public class NEWTKeyAdapter extends KeyAdapter implements KeyEventCountAdapter {
 
     String prefix;
-    int keyTyped;
+    int keyPressed, keyReleased, keyTyped;
+    int keyPressedAR, keyReleasedAR, keyTypedAR;
     boolean pressed;
+    List<EventObject> queue = new ArrayList<EventObject>();
+    boolean verbose = true;
 
     public NEWTKeyAdapter(String prefix) {
         this.prefix = prefix;
         reset();
     }
+    
+    public synchronized void setVerbose(boolean v) { verbose = false; }
 
-    public boolean isPressed() {
+    public synchronized boolean isPressed() {
         return pressed;
     }
     
-    public int getCount() {
+    public synchronized int getCount() {
         return keyTyped;
     }
 
-    public void reset() {
+    public synchronized int getKeyPressedCount(boolean autoRepeatOnly) {
+        return autoRepeatOnly ? keyPressedAR: keyPressed; 
+    }
+    
+    public synchronized int getKeyReleasedCount(boolean autoRepeatOnly) {
+        return autoRepeatOnly ? keyReleasedAR: keyReleased; 
+    }
+    
+    public synchronized int getKeyTypedCount(boolean autoRepeatOnly) {
+        return autoRepeatOnly ? keyTypedAR: keyTyped; 
+    }
+    
+    public synchronized List<EventObject> getQueued() {
+        return queue;
+    }
+    
+    public synchronized int getQueueSize() {
+        return queue.size();
+    }
+
+    public synchronized void reset() {
         keyTyped = 0;
+        keyPressed = 0;
+        keyReleased = 0;
+        keyTypedAR = 0;
+        keyPressedAR = 0;
+        keyReleasedAR = 0;
         pressed = false;
+        queue.clear();
     }
 
-    public void keyPressed(KeyEvent e) {
+    public synchronized void keyPressed(KeyEvent e) {
         pressed = true;
-        System.err.println("NEWT AWT PRESSED ["+pressed+"]: "+prefix+", "+e);
+        keyPressed++;
+        if( 0 != ( e.getModifiers() & InputEvent.AUTOREPEAT_MASK ) ) {
+            keyPressedAR++;
+        }
+        queue.add(e);
+        if( verbose ) {
+            System.err.println("NEWT AWT PRESSED ["+pressed+"]: "+prefix+", "+e);
+        }
     }
     
-    public void keyReleased(KeyEvent e) {
+    public synchronized void keyReleased(KeyEvent e) {
         pressed = false;
-        System.err.println("NEWT AWT RELEASED ["+pressed+"]: "+prefix+", "+e);
+        keyReleased++;
+        if( 0 != ( e.getModifiers() & InputEvent.AUTOREPEAT_MASK ) ) {
+            keyReleasedAR++;
+        }
+        queue.add(e);
+        if( verbose ) {
+            System.err.println("NEWT AWT RELEASED ["+pressed+"]: "+prefix+", "+e);
+        }
     }
      
     @Override
-    public void keyTyped(KeyEvent e) {
-        ++keyTyped;
-        System.err.println("KEY NEWT TYPED ["+keyTyped+"]: "+prefix+", "+e);
+    public synchronized void keyTyped(KeyEvent e) {
+        keyTyped++;
+        if( 0 != ( e.getModifiers() & InputEvent.AUTOREPEAT_MASK ) ) {
+            keyTypedAR++;
+        }
+        queue.add(e);
+        if( verbose ) {
+            System.err.println("KEY NEWT TYPED ["+keyTyped+"]: "+prefix+", "+e);
+        }
     }
     
     public String toString() { return prefix+"[pressed "+pressed+", typed "+keyTyped+"]"; }
diff --git a/src/test/com/jogamp/opengl/test/junit/util/NEWTKeyUtil.java b/src/test/com/jogamp/opengl/test/junit/util/NEWTKeyUtil.java
new file mode 100644
index 0000000..e090ed4
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/util/NEWTKeyUtil.java
@@ -0,0 +1,185 @@
+/**
+ * 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.test.junit.util;
+
+import java.util.ArrayList;
+import java.util.EventObject;
+import java.util.List;
+
+import org.junit.Assert;
+
+import com.jogamp.common.util.IntIntHashMap;
+import com.jogamp.newt.event.KeyEvent;
+
+public class NEWTKeyUtil {
+    public static class CodeSeg {
+        public final int min;
+        public final int max;
+        public final String description;
+        
+        public CodeSeg(int min, int max, String description) {
+            this.min = min;
+            this.max = max;
+            this.description = description;
+        }
+    }
+    public static class CodeEvent {
+        public final int code;
+        public final String description;
+        public final KeyEvent event;
+        
+        public CodeEvent(int code, String description, KeyEvent event) {
+            this.code = code;
+            this.description = description;
+            this.event = event;
+        }
+        public String toString() {
+            return "Code 0x"+Integer.toHexString(code)+" != "+event+" // "+description;
+        }
+    }
+            
+    public static void dumpKeyEvents(List<EventObject> keyEvents) {
+        for(int i=0; i<keyEvents.size(); i++) {
+            System.err.println(i+": "+keyEvents.get(i));
+        }        
+    }
+        
+    public static boolean validateKeyCodes(CodeSeg[] codeSegments, List<List<EventObject>> keyEventsList, boolean verbose) {
+        final List<CodeEvent> missCodes = new ArrayList<CodeEvent>();
+        int totalCodeCount = 0;
+        boolean res = true;
+        for(int i=0; i<codeSegments.length; i++) {
+            final CodeSeg codeSeg = codeSegments[i];
+            totalCodeCount += codeSeg.max - codeSeg.min + 1;
+            final List<EventObject> keyEvents = keyEventsList.get(i);
+            res &= validateKeyCodes(missCodes, codeSeg, keyEvents, verbose);
+        }        
+        if(verbose) {
+            System.err.println("*** Total KeyCode Misses "+missCodes.size()+" / "+totalCodeCount+", valid "+res);
+            for(int i=0; i<missCodes.size(); i++) {
+                System.err.println("Miss["+i+"]: "+missCodes.get(i));
+            }
+        }
+        return res;
+    }
+    public static boolean validateKeyCodes(List<CodeEvent> missCodes, CodeSeg codeSeg, List<EventObject> keyEvents, boolean verbose) {
+        final int codeCount = codeSeg.max - codeSeg.min + 1;
+        int misses = 0;
+        for(int i=0; i<codeCount; i++) {
+            final int c = codeSeg.min + i;
+            final int j = i*3+0; // KEY_PRESSED
+            final KeyEvent e = (KeyEvent) ( j < keyEvents.size() ? keyEvents.get(j) : null );
+            if( null == e || c != e.getKeyCode() ) {
+                missCodes.add(new CodeEvent(c, codeSeg.description, e));
+                misses++;
+            }
+        }
+        final boolean res = 3*codeCount == keyEvents.size() && 0 == missCodes.size();
+        if(verbose) {
+            System.err.println("+++ Code Segment "+codeSeg.description+", Misses: "+misses+" / "+codeCount+", events "+keyEvents.size()+", valid "+res);
+        }
+        return res;
+    }
+    
+    public static void validateKeyEvent(KeyEvent e, int eventType, int modifier, int keyCode) {
+        if(0 <= keyCode) {
+            Assert.assertTrue("KeyEvent code mismatch, expected 0x"+Integer.toHexString(keyCode)+", has "+e, keyCode == e.getKeyCode());
+        }
+        if(0 <= eventType) {
+            Assert.assertTrue("KeyEvent type mismatch, expected 0x"+Integer.toHexString(eventType)+", has "+e, eventType == e.getEventType());
+        }
+        if(0 <= modifier) {
+            Assert.assertTrue("KeyEvent modifier mismatch, expected 0x"+Integer.toHexString(modifier)+", has "+e, modifier == e.getModifiers());
+        }
+    }
+    
+    public static int getNextKeyEventType(int et) {
+        switch( et ) {
+            case KeyEvent.EVENT_KEY_PRESSED:
+                return KeyEvent.EVENT_KEY_RELEASED;
+            case KeyEvent.EVENT_KEY_RELEASED:
+                return KeyEvent.EVENT_KEY_TYPED;
+            case KeyEvent.EVENT_KEY_TYPED:
+                return KeyEvent.EVENT_KEY_PRESSED;
+            default:
+                Assert.assertTrue("Invalid event type "+et, false);
+                return 0;
+        }        
+    }
+    
+    public static void validateKeyEventOrder(List<EventObject> keyEvents) {
+        IntIntHashMap keyCode2NextEvent = new IntIntHashMap(); 
+        for(int i=0; i<keyEvents.size(); i++) {
+            final KeyEvent e = (KeyEvent) keyEvents.get(i);
+            int eet = keyCode2NextEvent.get(e.getKeyCode());
+            if( 0 >= eet ) {
+                eet = KeyEvent.EVENT_KEY_PRESSED;
+            }
+            final int et = e.getEventType();
+            Assert.assertEquals("Key event not in proper order", eet, et);
+            eet = getNextKeyEventType(et);
+            keyCode2NextEvent.put(e.getKeyCode(), eet);
+        }        
+    }
+    
+    /**
+     * 
+     * @param keyAdapter
+     * @param expTotalCount number of key press/release/types events
+     * @param expARCount number of key press/release/types Auto-Release events
+     */
+    public static void validateKeyAdapterStats(NEWTKeyAdapter keyAdapter, int expTotalCount, int expARCount) {
+        final int keyPressed = keyAdapter.getKeyPressedCount(false);
+        final int keyPressedAR = keyAdapter.getKeyPressedCount(true);
+        final int keyReleased = keyAdapter.getKeyReleasedCount(false);
+        final int keyReleasedAR = keyAdapter.getKeyReleasedCount(true);
+        final int keyTyped = keyAdapter.getKeyTypedCount(false);
+        final int keyTypedAR = keyAdapter.getKeyTypedCount(true);
+        final int keyPressedNR = keyPressed-keyPressedAR;
+        final int keyReleasedNR = keyReleased-keyReleasedAR;
+        final int keyTypedNR = keyTyped-keyTypedAR;
+        System.err.println("Total Press "+keyPressed  +", Release "+keyReleased  +", Typed "+keyTyped);
+        System.err.println("AutoR Press "+keyPressedAR+", Release "+keyReleasedAR+", Typed "+keyTypedAR);
+        System.err.println("No AR Press "+keyPressedNR+", Release "+keyReleasedNR+", Typed "+keyTypedNR);
+        
+        final List<EventObject> keyEvents = keyAdapter.getQueued();
+        Assert.assertEquals("Key event count not multiple of 3", 0, keyEvents.size()%3);
+        Assert.assertEquals("Key event count not 3 * press_release_count", expTotalCount, keyEvents.size());        
+        Assert.assertEquals("Key press count failure", expTotalCount/3, keyPressed);
+        Assert.assertEquals("Key press count failure (AR)", expARCount/3, keyPressedAR);
+        Assert.assertEquals("Key released count failure", expTotalCount/3, keyReleased);
+        Assert.assertEquals("Key released count failure (AR)", expARCount/3, keyReleasedAR);
+        Assert.assertEquals("Key typed count failure", expTotalCount/3, keyTyped);
+        Assert.assertEquals("Key typed count failure (AR)", expARCount/3, keyTypedAR);
+        
+        // should be true - always, reaching this point - duh!
+        Assert.assertEquals( ( expTotalCount - expARCount ) / 3, keyPressedNR);
+        Assert.assertEquals( ( expTotalCount - expARCount ) / 3, keyReleasedNR);
+        Assert.assertEquals( ( expTotalCount - expARCount ) / 3, keyTypedNR);
+    }        
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/util/NEWTMouseAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/NEWTMouseAdapter.java
index d98b9ca..6445237 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/NEWTMouseAdapter.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/NEWTMouseAdapter.java
@@ -28,6 +28,10 @@
  
 package com.jogamp.opengl.test.junit.util;
 
+import java.util.ArrayList;
+import java.util.EventObject;
+import java.util.List;
+
 import com.jogamp.newt.event.MouseAdapter;
 import com.jogamp.newt.event.MouseEvent;
 
@@ -36,38 +40,60 @@ public class NEWTMouseAdapter extends MouseAdapter implements InputEventCountAda
     String prefix;
     int mouseClicked;
     boolean pressed;
+    List<EventObject> queue = new ArrayList<EventObject>();
+    boolean verbose = true;
 
     public NEWTMouseAdapter(String prefix) {
         this.prefix = prefix;
         reset();
     }
 
-    public boolean isPressed() {
+    public synchronized void setVerbose(boolean v) { verbose = false; }
+    
+    public synchronized boolean isPressed() {
         return pressed;
     }
     
-    public int getCount() {
+    public synchronized int getCount() {
         return mouseClicked;
     }
 
-    public void reset() {
+    public synchronized List<EventObject> getQueued() {
+        return queue;
+    }
+    
+    public synchronized int getQueueSize() {
+        return queue.size();
+    }
+
+    public synchronized void reset() {
         mouseClicked = 0;
         pressed = false;
+        queue.clear();
     }
 
-    public void mousePressed(MouseEvent e) {
+    public synchronized void mousePressed(MouseEvent e) {
         pressed = true;
-        System.err.println("MOUSE NEWT PRESSED ["+pressed+"]: "+prefix+", "+e);
+        queue.add(e);
+        if( verbose ) {
+            System.err.println("MOUSE NEWT PRESSED ["+pressed+"]: "+prefix+", "+e);
+        }
     }
     
-    public void mouseReleased(MouseEvent e) {
+    public synchronized void mouseReleased(MouseEvent e) {
         pressed = false;
-        System.err.println("MOUSE NEWT RELEASED ["+pressed+"]: "+prefix+", "+e);
+        queue.add(e);
+        if( verbose ) {
+            System.err.println("MOUSE NEWT RELEASED ["+pressed+"]: "+prefix+", "+e);
+        }
     }
     
-    public void mouseClicked(MouseEvent e) {
+    public synchronized void mouseClicked(MouseEvent e) {
         mouseClicked+=e.getClickCount();
-        System.err.println("MOUSE NEWT CLICKED ["+mouseClicked+"]: "+prefix+", "+e);
+        queue.add(e);
+        if( verbose ) {
+            System.err.println("MOUSE NEWT CLICKED ["+mouseClicked+"]: "+prefix+", "+e);
+        }
     }
     
     public String toString() { return prefix+"[pressed "+pressed+", clicked "+mouseClicked+"]"; }
diff --git a/src/test/com/jogamp/opengl/test/junit/util/UITestCase.java b/src/test/com/jogamp/opengl/test/junit/util/UITestCase.java
index c07d5b7..b028df3 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/UITestCase.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/UITestCase.java
@@ -29,12 +29,14 @@
 package com.jogamp.opengl.test.junit.util;
 
 import java.io.File;
-import java.io.PrintWriter;
-import java.io.StringWriter;
+import java.util.Iterator;
+import java.util.List;
 
 import javax.media.opengl.GL;
+import javax.media.opengl.GLAutoDrawable;
 import javax.media.opengl.GLCapabilitiesImmutable;
 import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLEventListener;
 
 import com.jogamp.common.util.locks.SingletonInstance;
 import com.jogamp.opengl.util.GLReadBufferUtil;
@@ -47,6 +49,8 @@ import org.junit.After;
 import org.junit.AfterClass;
 import org.junit.Rule;
 import org.junit.rules.TestName;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.TestClass;
 
 
 public abstract class UITestCase {
@@ -58,9 +62,11 @@ public abstract class UITestCase {
     public static final long SINGLE_INSTANCE_LOCK_TO   = 3*60*1000; // wait up to 3 min
     public static final long SINGLE_INSTANCE_LOCK_POLL =      1000; // poll every 1s
 
-    static volatile SingletonInstance singletonInstance;
+    private static volatile SingletonInstance singletonInstance;
     
-    static volatile boolean testSupported = true;
+    private static volatile boolean testSupported = true;
+    
+    private static volatile int maxMethodNameLen = 0;
 
     private static final synchronized void initSingletonInstance() {
         if( null == singletonInstance )  {
@@ -72,11 +78,29 @@ public abstract class UITestCase {
         }
     }
     
+    public static boolean isTestSupported() {
+        return testSupported;
+    }
+    
     public static void setTestSupported(boolean v) {
         System.err.println("setTestSupported: "+v);
         testSupported = v;
     }
 
+    public int getMaxTestNameLen() {
+        if(0 == maxMethodNameLen) {
+            int ml = 0;
+            final TestClass tc = new TestClass(getClass());
+            final List<FrameworkMethod> testMethods = tc.getAnnotatedMethods(org.junit.Test.class);
+            for(Iterator<FrameworkMethod> iter=testMethods.iterator(); iter.hasNext(); ) {
+                final int l = iter.next().getName().length();
+                if( ml < l ) { ml = l; }
+            }
+            maxMethodNameLen = ml;
+        }
+        return maxMethodNameLen; 
+    }
+    
     public final String getTestMethodName() {
         return _unitTestName.getMethodName();
     }
@@ -107,7 +131,7 @@ public abstract class UITestCase {
         System.err.print("++++ UITestCase.setUp: "+getFullTestName(" - "));
         if(!testSupported) {
             System.err.println(" - "+unsupportedTestMsg);
-            Assume.assumeTrue(testSupported);
+            Assume.assumeTrue(testSupported); // abort
         }
         System.err.println();      
     }
@@ -118,15 +142,52 @@ public abstract class UITestCase {
     }
     
     static final String unsupportedTestMsg = "Test not supported on this platform.";
+
+    public String getSnapshotFilename(int sn, String postSNDetail, GLCapabilitiesImmutable caps, int width, int height, boolean sinkHasAlpha, String fileSuffix, String destPath) {
+        if(null == fileSuffix) {
+            fileSuffix = TextureIO.PNG;
+        }
+        final int maxSimpleTestNameLen = getMaxTestNameLen()+getClass().getSimpleName().length()+1;
+        final String simpleTestName = this.getSimpleTestName(".");
+        final String filenameBaseName;
+        {            
+            final String accel = caps.getHardwareAccelerated() ? "hw" : "sw" ;
+            final String scrnm;
+            if(caps.isOnscreen()) {
+                scrnm = "onscreen";
+            } else if(caps.isFBO()) {
+                scrnm = "fbobject";
+            } else if(caps.isPBuffer()) {
+                scrnm = "pbuffer_";
+            } else if(caps.isBitmap()) {
+                scrnm = "bitmap__";
+            } else {
+                scrnm = "unknown_";
+            }
+            final String dblb = caps.getDoubleBuffered() ? "dbl" : "one";
+            final String F_pfmt = sinkHasAlpha ? "rgba" : "rgb_";
+            final String pfmt = caps.getAlphaBits() > 0 ? "rgba" : "rgb_";
+            final int depthBits = caps.getDepthBits();
+            final int stencilBits = caps.getStencilBits();
+            final int samples = caps.getNumSamples() ;
+            final String aaext = caps.getSampleExtension();
+            postSNDetail = null != postSNDetail ? "-"+postSNDetail : "";
+
+            filenameBaseName = String.format("%-"+maxSimpleTestNameLen+"s-n%04d%s-%-6s-%s-%s-B%s-F%s_I%s-D%02d-St%02d-Sa%02d_%s-%04dx%04d.%s", 
+                    simpleTestName, sn, postSNDetail, caps.getGLProfile().getName(), accel, 
+                    scrnm, dblb, F_pfmt, pfmt, depthBits, stencilBits, samples, aaext,  
+                    width, height, fileSuffix).replace(' ', '_');
+        }
+        return null != destPath ? destPath + File.separator + filenameBaseName : filenameBaseName;        
+    }
     
     /**
-     * Takes a snapshot of the drawable's current framebuffer. Example filenames: 
+     * Takes a snapshot of the drawable's current front framebuffer. Example filenames: 
      * <pre>
-     * TestFBODrawableNEWT.test01-F_rgba-I_rgba-S0_default-GL2-n0004-0800x0600.png
-     * TestFBODrawableNEWT.test01-F_rgba-I_rgba-S0_default-GL2-n0005-0800x0600.png
+     * TestGLDrawableAutoDelegateOnOffscrnCapsNEWT.testES2OffScreenFBOSglBuf____-n0001-msaa0-GLES2_-sw-fbobject-Bdbl-Frgb__Irgb_-D24-St00-Sa00_default-0400x0300.png
+     * TestGLDrawableAutoDelegateOnOffscrnCapsNEWT.testES2OffScreenPbufferDblBuf-n0003-msaa0-GLES2_-sw-pbuffer_-Bdbl-Frgb__Irgb_-D24-St00-Sa00_default-0200x0150.png
+     * TestGLDrawableAutoDelegateOnOffscrnCapsNEWT.testGL2OffScreenPbufferSglBuf-n0003-msaa0-GL2___-hw-pbuffer_-Bone-Frgb__Irgb_-D24-St00-Sa00_default-0200x0150.png
      * </pre>
-     * 
-     * @param simpleTestName will be used as the filename prefix
      * @param sn sequential number 
      * @param postSNDetail optional detail to be added to the filename after <code>sn</code>
      * @param gl the current GL context object. It's read drawable is being used as the pixel source and to gather some details which will end up in the filename.
@@ -137,30 +198,68 @@ public abstract class UITestCase {
      *                 It shall not end with a directory separator, {@link File#separatorChar}.
      *                 If <code>null</code> the current working directory is being used.  
      */
-    public static void snapshot(String simpleTestName, int sn, String postSNDetail, GL gl, GLReadBufferUtil readBufferUtil, String fileSuffix, String destPath) {
-        if(null == fileSuffix) {
-            fileSuffix = TextureIO.PNG;
-        }
-        final StringWriter filenameSW = new StringWriter();
-        {
-            final GLDrawable drawable = gl.getContext().getGLReadDrawable();
-            final GLCapabilitiesImmutable caps = drawable.getChosenGLCapabilities();
-            final String F_pfmt = readBufferUtil.hasAlpha() ? "rgba" : "rgb_";
-            final String pfmt = caps.getAlphaBits() > 0 ? "rgba" : "rgb_";
-            final String aaext = caps.getSampleExtension();
-            final int samples = caps.getNumSamples() ;
-            postSNDetail = null != postSNDetail ? "-"+postSNDetail : "";
-            final PrintWriter pw = new PrintWriter(filenameSW);
-            pw.printf("%s-n%04d%s-F_%s-I_%s-S%d_%s-%s-%04dx%04d.%s", 
-                    simpleTestName, sn, postSNDetail, F_pfmt, pfmt, samples, aaext, drawable.getGLProfile().getName(), 
-                    drawable.getWidth(), drawable.getHeight(), fileSuffix);
-        }
-        final String filename = null != destPath ? destPath + File.separator + filenameSW.toString() : filenameSW.toString();
+    public void snapshot(int sn, String postSNDetail, GL gl, GLReadBufferUtil readBufferUtil, String fileSuffix, String destPath) {
+        final GLDrawable drawable = gl.getContext().getGLReadDrawable();
+        final String filename = getSnapshotFilename(sn, postSNDetail, 
+                                                    drawable.getChosenGLCapabilities(), drawable.getWidth(), drawable.getHeight(), 
+                                                    readBufferUtil.hasAlpha(), fileSuffix, destPath);
         System.err.println(Thread.currentThread().getName()+": ** screenshot: "+filename);
         gl.glFinish(); // just make sure rendering finished ..
         if(readBufferUtil.readPixels(gl, false)) {
             readBufferUtil.write(new File(filename));
         }                
-    }    
+    }
+    
+    public class SnapshotGLEventListener implements GLEventListener {
+        private final GLReadBufferUtil screenshot;
+        private volatile boolean makeShot = false;
+        private volatile boolean makeShotAlways = false;
+        private volatile boolean verbose = false;
+        private volatile int displayCount=0;
+        private volatile int reshapeCount=0;
+        private volatile String postSNDetail = null;
+        public SnapshotGLEventListener(GLReadBufferUtil screenshot) {
+            this.screenshot = screenshot;
+        }
+        public SnapshotGLEventListener() {
+            this.screenshot = new GLReadBufferUtil(false, false);
+        }
+        public int getDisplayCount() { return displayCount; }
+        public int getReshapeCount() { return reshapeCount; }
+        public GLReadBufferUtil getGLReadBufferUtil() { return screenshot; }
+        public void init(GLAutoDrawable drawable) {}
+        public void dispose(GLAutoDrawable drawable) {}
+        public void display(GLAutoDrawable drawable) {
+            final GL gl = drawable.getGL();
+            final boolean _makeShot = makeShot || makeShotAlways;
+            if(verbose) {
+                System.err.println(Thread.currentThread().getName()+": ** display: "+displayCount+": "+drawable.getWidth()+"x"+drawable.getHeight()+", makeShot "+_makeShot);
+            }
+            if(_makeShot) {
+                makeShot=false;
+                snapshot(displayCount, postSNDetail, gl, screenshot, TextureIO.PNG, null);
+            }
+            displayCount++;
+        }
+        public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
+            if(verbose) {
+                System.err.println(Thread.currentThread().getName()+": ** reshape: "+reshapeCount+": "+width+"x"+height+" - "+drawable.getWidth()+"x"+drawable.getHeight());
+            }
+            reshapeCount++;
+        }
+        public void setMakeSnapshot() {
+            makeShot=true;
+        }
+        public void setMakeSnapshotAlways(boolean v) {
+            makeShotAlways=v;
+        }
+        public void setVerbose(boolean v) {
+            verbose=v;
+        }
+        public void setPostSNDetail(String v) {
+            postSNDetail = v;
+        }
+    };
+    
 }
 
diff --git a/src/test/com/jogamp/opengl/test/junit/util/MiscUtils.java b/src/test/com/jogamp/opengl/test/junit/util/ValidateLockListener.java
similarity index 54%
copy from src/test/com/jogamp/opengl/test/junit/util/MiscUtils.java
copy to src/test/com/jogamp/opengl/test/junit/util/ValidateLockListener.java
index 9cbeabb..73c1ad7 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/MiscUtils.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/ValidateLockListener.java
@@ -1,5 +1,5 @@
 /**
- * Copyright 2010 JogAmp Community. All rights reserved.
+ * 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:
@@ -26,47 +26,46 @@
  * or implied, of JogAmp Community.
  */
  
-
 package com.jogamp.opengl.test.junit.util;
 
-import java.lang.reflect.*;
 
-public class MiscUtils {
-    public static int atoi(String str, int def) {
-        try {
-            return Integer.parseInt(str);
-        } catch (Exception ex) {
-            ex.printStackTrace();
+import javax.media.nativewindow.NativeSurface;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLEventListener;
+
+
+public class ValidateLockListener implements GLEventListener {
+
+    private void validateLock(GLAutoDrawable drawable) {
+        final NativeSurface ns = drawable.getNativeSurface();
+        ns.getGraphicsConfiguration().getScreen().getDevice().validateLocked();
+        
+        final Thread current = Thread.currentThread();
+        final Thread owner = ns.getSurfaceLockOwner();
+        if( ns.isSurfaceLockedByOtherThread() ) {
+            throw new RuntimeException(current.getName()+": Locked by another thread(1), owner "+owner+", "+ns);
+        }
+        if( current != owner ) {
+            if( null == owner ) {
+                throw new RuntimeException(current.getName()+": Not locked: "+ns);
+            }
+            throw new RuntimeException(current.getName()+": Locked by another thread(2), owner "+owner+", "+ns);            
         }
-        return def;
     }
     
-    public static long atol(String str, long def) {
-        try {
-            return Long.parseLong(str);
-        } catch (Exception ex) {
-            ex.printStackTrace();
-        }
-        return def;
+    public void init(GLAutoDrawable drawable) {
+        validateLock(drawable);
     }
 
-    public static boolean setFieldIfExists(Object instance, String fieldName, Object value) {
-        try {
-            Field f = instance.getClass().getField(fieldName);
-            if(value instanceof Boolean || f.getType().isInstance(value)) {
-                f.set(instance, value);
-                return true;
-            } else {
-                System.out.println(instance.getClass()+" '"+fieldName+"' field not assignable with "+value.getClass()+", it's a: "+f.getType());
-            }
-        } catch (IllegalAccessException ex) {
-            throw new RuntimeException(ex);
-        } catch (NoSuchFieldException nsfe) {
-            // OK - throw new RuntimeException(instance.getClass()+" has no '"+fieldName+"' field", nsfe);
-        }
-        return false;
+    public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
+        validateLock(drawable);
     }
-}
-
 
+    public void display(GLAutoDrawable drawable) {
+        validateLock(drawable);
+    }
 
+    public void dispose(GLAutoDrawable drawable) {
+        validateLock(drawable);
+    }
+}

-- 
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