diff --git a/lib/native/linux-64/libjnawtrenderer.so b/lib/native/linux-64/libjnawtrenderer.so
index 45cf80b7b3e5013ac938613d236c181bfb25b4cb..f6c61a4ff2d534e7e6350fa43e6b85abb5b712a3 100755
Binary files a/lib/native/linux-64/libjnawtrenderer.so and b/lib/native/linux-64/libjnawtrenderer.so differ
diff --git a/lib/native/linux/libjnawtrenderer.so b/lib/native/linux/libjnawtrenderer.so
index 1d164d2746e0b7a9897c068dec2b5e539009f1f0..9285b223974048497bed4d0165d400110eeb8099 100755
Binary files a/lib/native/linux/libjnawtrenderer.so and b/lib/native/linux/libjnawtrenderer.so differ
diff --git a/lib/native/mac/libjnawtrenderer.jnilib b/lib/native/mac/libjnawtrenderer.jnilib
index 1f7e95feda0cbd6d913ad74b2d58579d42a93fc8..6ed7922fa292f68bc364bece78af059dc1e34f40 100755
Binary files a/lib/native/mac/libjnawtrenderer.jnilib and b/lib/native/mac/libjnawtrenderer.jnilib differ
diff --git a/lib/native/windows-64/jnawtrenderer.dll b/lib/native/windows-64/jnawtrenderer.dll
index 9fa486a4ce8724895c4745ccfb1fdf1b4ba5a1cc..57548dbe3e98e949cb93807b9a68d7b37f393735 100755
Binary files a/lib/native/windows-64/jnawtrenderer.dll and b/lib/native/windows-64/jnawtrenderer.dll differ
diff --git a/lib/native/windows/jnawtrenderer.dll b/lib/native/windows/jnawtrenderer.dll
index 6163f058f9fc10b9c5a94eb526117012ccf53f36..e5465904230447c901d1ea3540cfa256b538b16d 100644
Binary files a/lib/native/windows/jnawtrenderer.dll and b/lib/native/windows/jnawtrenderer.dll differ
diff --git a/src/native/build.xml b/src/native/build.xml
index 69960938907559f975cd5141ec584642eb30308e..45102fa614676bce29a9ba00cc2f1c2524842aaf 100644
--- a/src/native/build.xml
+++ b/src/native/build.xml
@@ -174,79 +174,72 @@
   </target>
 
   <!-- compile jnawtrenderer library -->
-  <target name="jawtrenderer" description="Build jnawtrenderer shared library" depends="init-native,jawtrenderer-windows"
-    unless="is.running.windows">
+  <target name="jawtrenderer" description="Build jnawtrenderer shared library" depends="init-native">
     <cc outtype="shared" name="gcc" outfile="${native_install_dir}/jnawtrenderer" objdir="${obj}">
 
       <!-- common compiler flags -->
+      <compilerarg value="-D_JNI_IMPLEMENTATION_" />
+      <compilerarg value="-m32" if="cross_32" unless="is.running.macos" />
+      <compilerarg value="-m64" if="cross_64" unless="is.running.macos" />
+      <compilerarg value="-O2" />
       <compilerarg value="-std=c99" />
       <compilerarg value="-Wall" />
-      <compilerarg value="-O2" />
 
-      <linkerarg value="-L${system.JAVA_HOME}/jre/lib/amd64" />
-      <linkerarg value="-L${system.JAVA_HOME}/jre/lib/x86" />
+      <compilerarg value="-I${system.JAVA_HOME}/include" unless="is.running.macos" />
+
+      <linkerarg value="-m32" if="cross_32" unless="is.running.macos" />
+      <linkerarg value="-m64" if="cross_64" unless="is.running.macos" />
       <linkerarg value="-ljawt" location="end" />
 
-      <!-- Linux specific flags -->
-      <compilerarg value="-m32" if="cross_32" unless="is.running.macos" />
-      <compilerarg value="-m64" if="cross_64" unless="is.running.macos" />
-      <compilerarg value="-I${system.JAVA_HOME}/include" if="is.running.linux" />
+      <!-- Linux-specific flags -->
       <compilerarg value="-I${system.JAVA_HOME}/include/linux" if="is.running.linux" />
 
-      <linkerarg value="-m32" if="cross_32" unless="is.running.macos" />
-      <linkerarg value="-m64" if="cross_64" unless="is.running.macos" />
+      <linkerarg value="-L${system.JAVA_HOME}/jre/lib/i386" if="is.running.linux" />
+      <linkerarg value="-L${system.JAVA_HOME}/jre/lib/amd64" if="is.running.linux" />
       <linkerarg value="-lXv" location="end" if="is.running.linux" />
       <linkerarg value="-lX11" location="end" if="is.running.linux" />
 
-      <fileset dir="${src}/native/jawtrenderer" includes="net*.c JAWTRenderer_Linux.c" if="is.running.linux"/>
+      <fileset dir="${src}/native/jawtrenderer" includes="org*.c JAWTRenderer_Linux.c" if="is.running.linux"/>
 
-      <!-- Mac OS X specific flags -->
+      <!-- Mac OS X-specific flags -->
       <compilerarg value="-mmacosx-version-min=10.5" if="is.running.macos"/>
       <compilerarg value="-arch" if="is.running.macos" />
-      <compilerarg value="x86_64" if="is.running.macos" />
-      <compilerarg value="-arch" if="is.running.macos" />
       <compilerarg value="i386" if="is.running.macos" />
+      <compilerarg value="-arch" if="is.running.macos" />
+      <compilerarg value="x86_64" if="is.running.macos" />
       <compilerarg value="-I/System/Library/Frameworks/JavaVM.framework/Headers" if="is.running.macos" />
 
       <linkerarg value="-o" location="end" if="is.running.macos" />
       <linkerarg value="libjnawtrenderer.jnilib" location="end" if="is.running.macos" />
-      <linkerarg value="-arch" if="is.running.macos" />
-      <linkerarg value="x86_64" if="is.running.macos" />
+      <linkerarg value="-dynamiclib" if="is.running.macos" />
       <linkerarg value="-arch" if="is.running.macos" />
       <linkerarg value="i386" if="is.running.macos" />
+      <linkerarg value="-arch" if="is.running.macos" />
+      <linkerarg value="x86_64" if="is.running.macos" />
       <linkerarg value="-framework" if="is.running.macos" />
       <linkerarg value="OpenGL" if="is.running.macos" />
       <linkerarg value="-framework" if="is.running.macos" />
       <linkerarg value="Foundation" if="is.running.macos" />
       <linkerarg value="-framework" if="is.running.macos" />
       <linkerarg value="AppKit" if="is.running.macos" />
+      <linkerarg value="-framework" if="is.running.macos" />
+      <linkerarg value="QuartzCore" if="is.running.macos" />
       <linkerarg value="-L/System/Library/Frameworks/JavaVM.framework/Libraries/" if="is.running.macos" />
 
-      <fileset dir="${src}/native/jawtrenderer" includes="net*.c JAWTRenderer_MacOSX.m" if="is.running.macos" />
-
-    </cc>
-  </target>
+      <fileset dir="${src}/native/jawtrenderer" includes="org*.c JAWTRenderer_MacOSX.m" if="is.running.macos" />
 
-  <!-- compile jnawtrenderer library for Windows -->
-  <target name="jawtrenderer-windows" description="Build jnawtrenderer shared library for Windows" depends="init-native"
-    if="is.running.windows">
-    <cc outtype="shared" name="msvc" outfile="${native_install_dir}/jnawtrenderer" objdir="${obj}">
-      <compilerarg value="/O2" />
-      <compilerarg value="/MT" location="end" />
-      <compilerarg value="/IC:\Program Files\Microsoft DirectX SDK (February 2010)\Include" />
-      <compilerarg value="/IC:\Program Files (x86)\Microsoft DirectX SDK (February 2010)\Include" />
-      <compilerarg value="-I${system.JAVA_HOME}/include" />
-      <compilerarg value="-I${system.JAVA_HOME}/include/win32" />
+      <!-- Windows-specific flags -->
+      <compilerarg value="-D_WIN32_WINNT=0x0502" if="is.running.windows" />
+      <compilerarg value="-DWINVER=0x0502" if="is.running.windows" />
+      <compilerarg value="-I${system.JAVA_HOME}/include/win32" if="is.running.windows" />
 
-      <!-- <linkerarg value="/LD" /> -->
-      <linkerarg value="/LIBPATH:C:\Program Files\Microsoft DirectX SDK (February 2010)\lib\x86" />
-      <linkerarg value="/LIBPATH:C:\Program Files (x86)\Microsoft DirectX SDK (February 2010)\lib\x64" />
-      <linkerarg value="/LIBPATH:${system.JAVA_HOME}\\lib" />
-      <linkerarg value="d3d9.lib" location="end" />
-      <linkerarg value="user32.lib" location="end" />
-      <linkerarg value="jawt.lib" location="end" />
+      <linkerarg value="-ojnawtrenderer.dll" if="is.running.windows" />
+      <linkerarg value="-Wl,--kill-at" if="is.running.windows" />
+      <linkerarg value="-L${system.JAVA_HOME}/lib" if="is.running.windows" />
+      <linkerarg value="-ld3d9" location="end" if="is.running.windows" />
+      <linkerarg value="-ld3dx9" location="end" if="is.running.windows" />
 
-      <fileset dir="${src}/native/jawtrenderer" includes="net*.c JAWTRenderer_Windows.cpp windows/*.cpp windows/*.c"/>
+      <fileset dir="${src}/native/jawtrenderer" includes="org*.c JAWTRenderer_Windows.c" if="is.running.windows"/>
     </cc>
   </target>
 
diff --git a/src/native/jawtrenderer/JAWTRenderer.h b/src/native/jawtrenderer/JAWTRenderer.h
index a493c29350cc6321f57bbde540639fea8a6aa631..a5105e9e84da0966d8b9515f202cf830dd969156 100644
--- a/src/native/jawtrenderer/JAWTRenderer.h
+++ b/src/native/jawtrenderer/JAWTRenderer.h
@@ -16,26 +16,17 @@ extern "C" {
 #endif
 
 void JAWTRenderer_close
-    (JNIEnv *jniEnv, jclass clazz, jlong handle, jobject component);
-jlong JAWTRenderer_open(JNIEnv *jniEnv, jclass clazz, jobject component);
+    (JNIEnv *env, jclass clazz, jlong handle, jobject component);
+jlong JAWTRenderer_open(JNIEnv *env, jclass clazz, jobject component);
 jboolean JAWTRenderer_paint
-    (JAWT_DrawingSurfaceInfo *dsi, jclass clazz, jlong handle, jobject g);
+    (jint version, JAWT_DrawingSurfaceInfo *dsi, jclass clazz, jlong handle,
+        jobject g, jint zOrder);
 jboolean JAWTRenderer_process
-    (JNIEnv *jniEnv, jclass clazz,
-     jlong handle, jobject component,
-     jint *data, jint length,
-     jint width, jint height);
+    (JNIEnv *env, jclass clazz,jlong handle, jobject component, jint *data,
+        jint length, jint width, jint height);
 
 #ifdef __APPLE__
-void JAWTRenderer_addNotifyLightweightComponent
-    (jlong handle, jobject component, jlong parentHandle);
-jboolean JAWTRenderer_paintLightweightComponent
-    (jlong handle, jobject component, jobject g);
-void JAWTRenderer_processLightweightComponentEvent
-    (jlong handle, jint x, jint y, jint width, jint height);
-void JAWTRenderer_removeNotifyLightweightComponent
-    (jlong handle, jobject component);
-jstring JAWTRenderer_sysctlbyname(JNIEnv *jniEnv, jstring name);
+jstring JAWTRenderer_sysctlbyname(JNIEnv *env, jstring name);
 #endif /* #ifdef __APPLE__ */
 
 #ifdef __cplusplus
diff --git a/src/native/jawtrenderer/JAWTRenderer_Linux.c b/src/native/jawtrenderer/JAWTRenderer_Linux.c
index dde3bc29ea4a1c5d63d9e5e21fe6f91e4d44df37..e2d8554c0fce808fcef508cc767e6591eac73370 100644
--- a/src/native/jawtrenderer/JAWTRenderer_Linux.c
+++ b/src/native/jawtrenderer/JAWTRenderer_Linux.c
@@ -91,7 +91,8 @@ JAWTRenderer_open(JNIEnv *jniEnv, jclass clazz, jobject component)
 
 jboolean
 JAWTRenderer_paint
-    (JAWT_DrawingSurfaceInfo *dsi, jclass clazz, jlong handle, jobject g)
+    (jint version, JAWT_DrawingSurfaceInfo *dsi, jclass clazz, jlong handle,
+        jobject g, jint zOrder)
 {
     JAWT_X11DrawingSurfaceInfo *x11dsi;
     JAWTRenderer *renderer;
diff --git a/src/native/jawtrenderer/JAWTRenderer_MacOSX.m b/src/native/jawtrenderer/JAWTRenderer_MacOSX.m
index 81e3a545d34c955609163614bf94601a89893749..51d4e50a02c0a4e1aa2516736bc7b38dd06e2d83 100644
--- a/src/native/jawtrenderer/JAWTRenderer_MacOSX.m
+++ b/src/native/jawtrenderer/JAWTRenderer_MacOSX.m
@@ -16,324 +16,247 @@
 #include <sys/types.h>
 #include <sys/sysctl.h>
 
-#import <AppKit/NSOpenGL.h>
 #import <AppKit/NSView.h>
-#import <Foundation/NSArray.h>
 #import <Foundation/NSAutoreleasePool.h>
-#import <Foundation/NSNotification.h>
 #import <Foundation/NSObject.h>
 #import <OpenGL/gl.h>
 #import <OpenGL/OpenGL.h>
+#import <QuartzCore/CALayer.h>
+#import <QuartzCore/CAOpenGLLayer.h>
 
 #define JAWT_RENDERER_TEXTURE GL_TEXTURE_RECTANGLE_EXT
 #define JAWT_RENDERER_TEXTURE_FORMAT GL_BGRA
 #define JAWT_RENDERER_TEXTURE_TYPE GL_UNSIGNED_BYTE
 
-@interface JAWTRenderer : NSObject
+@interface JAWTRendererLayer : CAOpenGLLayer
 {
+/*
+ * XXX The fields of JAWTRendererLayer are declared public for the sake of
+ * performance so that the function JAWTRenderer_process may effectively be
+ * implemented as a member of the class.
+ */
 @public
-    /**
-     * The OpenGL context of this <tt>JAWTRenderer</tt> which shares
-     * <tt>texture</tt> with the OpenGL contexts of <tt>subrenderers</tt> and
-     * enables this <tt>JAWTRederer</tt> to not directly access the OpenGL
-     * contexts of <tt>subrenderers</tt> because it cannot guarantee
-     * synchronized access to them anyway.
-     */
-    NSOpenGLContext *glContext;
-
-    jint height;
-    GLuint texture;
-    jint width;
-
-    CGFloat frameHeight;
-    CGFloat frameWidth;
-    CGFloat frameX;
-    CGFloat frameY;
-
-    CGFloat boundsHeight;
-    CGFloat boundsWidth;
-    CGFloat boundsX;
-    CGFloat boundsY;
-
-    NSView *view;
-
-    /**
-     * The <tt>JAWTRenderer</tt>s which are to have their <tt>layer</tt>s
-     * contained in the <tt>layer</tt> of this <tt>JAWTRenderer</tt>.
-     */
-    NSMutableArray *subrenderers;
-    /**
-     * The <tt>JAWTRenderer</tt> which has this <tt>JAWTRenderer</tt> in its
-     * <tt>subrenderers</tt>.
-     */
-    JAWTRenderer *superrenderer;
+    CGLContextObj _glContext;
+    jint _height;
+    CGLPixelFormatObj _pixelFormat;
+    GLuint _texture;
+    jint _width;
 }
 
-- (void)addSubrenderer:(JAWTRenderer *)subrenderer;
-- (void)boundsDidChange:(NSNotification *)notification;
-- (void)copyCGLContext:(NSOpenGLContext *)glContext
-        forPixelFormat:(CGLPixelFormatObj)pixelFormat;
+- (CGLContextObj)copyCGLContextForPixelFormat:(CGLPixelFormatObj)pixelFormat;
+- (CGLPixelFormatObj)copyCGLPixelFormatForDisplayMask:(uint32_t)mask;
 - (void)dealloc;
-- (void)frameDidChange:(NSNotification *)notification;
+- (void)drawInCGLContext:(CGLContextObj)glContext
+             pixelFormat:(CGLPixelFormatObj)pixelFormat
+            forLayerTime:(CFTimeInterval)timeInterval
+             displayTime:(const CVTimeStamp *)timeStamp;
 - (id)init;
-- (void)paint;
-- (void)removeFromSuperrenderer;
-- (void)removeSubrenderer:(JAWTRenderer *)subrenderer;
-- (void)removeSubrendererAtIndex:(NSUInteger)index;
-- (void)reshape;
-- (void)setSuperrenderer:(JAWTRenderer *)aSuperrenderer;
-- (void)setView:(NSView *)aView;
-- (void)update;
-@end /* JAWTRenderer */
-
-void
-JAWTRenderer_addNotifyLightweightComponent
-    (jlong handle, jobject component, jlong parentHandle)
-{
-    JAWTRenderer *renderer;
-    JAWTRenderer *parentRenderer;
-    NSAutoreleasePool *autoreleasePool;
-
-    renderer = (JAWTRenderer *) (intptr_t) handle;
-    parentRenderer = (JAWTRenderer *) (intptr_t) parentHandle;
-    autoreleasePool = [[NSAutoreleasePool alloc] init];
-
-    if (parentRenderer)
-        [parentRenderer addSubrenderer:renderer];
-    [renderer copyCGLContext:nil forPixelFormat:0];
-
-    [autoreleasePool release];
-}
+@end /* JAWTRendererLayer */
 
 void
-JAWTRenderer_close
-    (JNIEnv *jniEnv, jclass clazz, jlong handle, jobject component)
+JAWTRenderer_close(JNIEnv *env, jclass clazz, jlong handle, jobject component)
 {
-    JAWTRenderer *renderer;
+    JAWTRendererLayer **thiz;
     NSAutoreleasePool *autoreleasePool;
 
-    renderer = (JAWTRenderer *) (intptr_t) handle;
+    thiz = (JAWTRendererLayer **) (intptr_t) handle;
     autoreleasePool = [[NSAutoreleasePool alloc] init];
 
-    JAWTRenderer_removeNotifyLightweightComponent(handle, component);
-    [renderer release];
+    if (*thiz)
+        [*thiz release];
+    free(thiz);
 
     [autoreleasePool release];
 }
 
 jlong
-JAWTRenderer_open(JNIEnv *jniEnv, jclass clazz, jobject component)
+JAWTRenderer_open(JNIEnv *env, jclass clazz, jobject component)
 {
-    NSAutoreleasePool *autoreleasePool;
-    JAWTRenderer *renderer;
-
-    autoreleasePool = [[NSAutoreleasePool alloc] init];
-
-    renderer = [[JAWTRenderer alloc] init];
-
-    [autoreleasePool release];
-    return (jlong) (intptr_t) renderer;
+    return (jlong) (intptr_t) calloc(1, sizeof(JAWTRendererLayer *));
 }
 
 jboolean
 JAWTRenderer_paint
-    (JAWT_DrawingSurfaceInfo *dsi, jclass clazz, jlong handle, jobject g)
+    (jint version, JAWT_DrawingSurfaceInfo *dsi, jclass clazz, jlong handle,
+        jobject g, jint zOrder)
 {
-    NSView *component;
+    NSAutoreleasePool *autoreleasePool;
+    JAWTRendererLayer *thizLayer;
+    jboolean wantsPaint = JNI_TRUE;
+    JAWTRendererLayer **thiz;
 
-    component
-        = ((JAWT_MacOSXDrawingSurfaceInfo *) (dsi->platformInfo))->cocoaViewRef;
-    if (component)
-    {
-        JAWTRenderer *renderer;
-        NSAutoreleasePool *autoreleasePool;
+    autoreleasePool = [[NSAutoreleasePool alloc] init];
 
-        renderer = (JAWTRenderer *) (intptr_t) handle;
-        autoreleasePool = [[NSAutoreleasePool alloc] init];
+    /*
+     * The native peer of the AWT Canvas that is the component of this
+     * JAWTRenderer should be a JAWTRendererLayer.
+     */
+    if (JAWT_MACOSX_USE_CALAYER == (version & JAWT_MACOSX_USE_CALAYER))
+    {
+        id<JAWT_SurfaceLayers> surfaceLayers
+            = (id<JAWT_SurfaceLayers>) (dsi->platformInfo);
+        CALayer *layer = surfaceLayers.layer;
 
-        if (renderer->view != component)
-                [renderer setView:component];
+        if (layer && [layer isKindOfClass:[JAWTRendererLayer class]])
+            thizLayer = (JAWTRendererLayer *) layer;
         else
         {
-            // update
-            NSRect frame;
-
-            frame = [component frame];
-            if ((renderer->frameX != frame.origin.x)
-                    || (renderer->frameY != frame.origin.y)
-                    || (renderer->frameWidth != frame.size.width)
-                    || (renderer->frameHeight != frame.size.height))
-                [renderer update];
+            thizLayer = [JAWTRendererLayer layer];
+            if (thizLayer)
+                surfaceLayers.layer = thizLayer;
             else
+                wantsPaint = JNI_FALSE;
+        }
+    }
+    else
+    {
+        NSView *view
+            = ((JAWT_MacOSXDrawingSurfaceInfo *) (dsi->platformInfo))
+                ->cocoaViewRef;
+        CALayer *layer = [view layer];
+
+        if (layer && [layer isKindOfClass:[JAWTRendererLayer class]])
+            thizLayer = (JAWTRendererLayer *) layer;
+        else
+        {
+            thizLayer = [JAWTRendererLayer layer];
+            if (thizLayer)
             {
-                // reshape
-                NSRect bounds;
-
-                bounds = [component bounds];
-                if ((renderer->boundsX != bounds.origin.x)
-                        || (renderer->boundsY != bounds.origin.y)
-                        || (renderer->boundsWidth != bounds.size.width)
-                        || (renderer->boundsHeight != bounds.size.height))
-                    [renderer reshape];
+                [view setLayer:thizLayer];
+                [view setWantsLayer:YES];
             }
+            else
+                wantsPaint = JNI_FALSE;
         }
-
-        [renderer paint];
-
-        [autoreleasePool release];
     }
-    return JNI_TRUE;
-}
 
-jboolean
-JAWTRenderer_paintLightweightComponent
-    (jlong handle, jobject component, jobject g)
-{
-    JAWTRenderer *renderer;
-    NSAutoreleasePool *autoreleasePool;
-
-    renderer = (JAWTRenderer *) (intptr_t) handle;
-    autoreleasePool = [[NSAutoreleasePool alloc] init];
+    /*
+     * This JAWTRenderer should paint into the JAWTRendererLayer which is the
+     * native peer of the AWT Canvas that is the component of this JAWTRenderer.
+     */
+    thiz = (JAWTRendererLayer **) (intptr_t) handle;
+    if (*thiz != thizLayer)
+    {
+        if (*thiz)
+            [*thiz release];
+        *thiz = thizLayer;
+        if (thizLayer)
+            [thizLayer retain];
+    }
 
-    // TODO Auto-generated method stub
+    /*
+     * Forward the paint request from the AWT Canvas to the JAWTRendererLayer
+     * that is the former's native peer.
+     */
+    if (thizLayer)
+    {
+        if (zOrder > -1)
+            thizLayer.zPosition = zOrder;
+        [thizLayer setNeedsDisplay];
+    }
 
     [autoreleasePool release];
-    return JNI_TRUE;
+    return wantsPaint;
 }
 
 jboolean
 JAWTRenderer_process
-    (JNIEnv *jniEnv, jclass clazz,
-     jlong handle, jobject component,
-     jint *data, jint length,
-     jint width, jint height)
+    (JNIEnv *env, jclass clazz, jlong handle, jobject component, jint *data,
+        jint length, jint width, jint height)
 {
-    JAWTRenderer *renderer;
-    NSAutoreleasePool *autoreleasePool;
+    JAWTRendererLayer *thiz = *((JAWTRendererLayer **) (intptr_t) handle);
 
-    renderer = (JAWTRenderer *) (intptr_t) handle;
-    autoreleasePool = [[NSAutoreleasePool alloc] init];
-
-    if (data && length)
+    if (thiz && data && length)
     {
-        @synchronized (renderer)
-        {
-            if (renderer->glContext)
-            {
-                [renderer->glContext makeCurrentContext];
+        NSAutoreleasePool *autoreleasePool = [[NSAutoreleasePool alloc] init];
+        CGLContextObj glContext = thiz->_glContext;
 
-                if (renderer->texture
-                        && ((width != renderer->width)
-                                || (height != renderer->height)))
-                {
-                    glDeleteTextures(1, &(renderer->texture));
-                    renderer->texture = 0;
-                }
-                if (renderer->texture)
-                {
-                    glBindTexture(JAWT_RENDERER_TEXTURE, renderer->texture);
-                    glTexSubImage2D(
-                        JAWT_RENDERER_TEXTURE,
-                        0,
-                        0, 0, width, height,
-                        JAWT_RENDERER_TEXTURE_FORMAT,
-                        JAWT_RENDERER_TEXTURE_TYPE,
-                        data);
-                }
-                else
-                {
-                    glGenTextures(1, &(renderer->texture));
-                    glBindTexture(JAWT_RENDERER_TEXTURE, renderer->texture);
-                    glTexParameterf(
-                        JAWT_RENDERER_TEXTURE,
-                        GL_TEXTURE_PRIORITY,
-                        1.0);
-                    glTexParameteri(
-                        JAWT_RENDERER_TEXTURE,
-                        GL_TEXTURE_WRAP_S,
-                        GL_CLAMP_TO_EDGE);
-                    glTexParameteri(
-                        JAWT_RENDERER_TEXTURE,
-                        GL_TEXTURE_WRAP_T,
-                        GL_CLAMP_TO_EDGE);
-                    glTexParameteri(
-                        JAWT_RENDERER_TEXTURE,
-                        GL_TEXTURE_MAG_FILTER,
-                        GL_LINEAR);
-                    glTexParameteri(
-                        JAWT_RENDERER_TEXTURE,
-                        GL_TEXTURE_MIN_FILTER,
-                        GL_LINEAR);
-
-                    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-
-                    glTexParameteri(
-                        JAWT_RENDERER_TEXTURE,
-                        GL_TEXTURE_STORAGE_HINT_APPLE,
-                        GL_STORAGE_SHARED_APPLE);
-
-                    glTexImage2D(
-                        JAWT_RENDERER_TEXTURE,
-                        0,
-                        4,
-                        width, height,
-                        0,
-                        JAWT_RENDERER_TEXTURE_FORMAT,
-                        JAWT_RENDERER_TEXTURE_TYPE,
-                        data);
-                }
-                renderer->width = width;
-                renderer->height = height;
-            }
-        }
-    }
+        if (glContext && (kCGLNoError == CGLLockContext(glContext)))
+        {
+            GLuint texture = thiz->_texture;
 
-    [autoreleasePool release];
-    return JNI_TRUE;
-}
+            CGLSetCurrentContext(glContext);
 
-void
-JAWTRenderer_processLightweightComponentEvent
-    (jlong handle, jint x, jint y, jint width, jint height)
-{
-    JAWTRenderer *renderer;
-    NSAutoreleasePool *autoreleasePool;
+            if (texture
+                    && ((width != thiz->_width) || (height != thiz->_height)))
+            {
+                glDeleteTextures(1, &texture);
+                thiz->_texture = texture = 0;
+            }
+            if (texture)
+            {
+                glBindTexture(JAWT_RENDERER_TEXTURE, texture);
+                glTexSubImage2D(
+                    JAWT_RENDERER_TEXTURE,
+                    0,
+                    0, 0, width, height,
+                    JAWT_RENDERER_TEXTURE_FORMAT,
+                    JAWT_RENDERER_TEXTURE_TYPE,
+                    data);
+            }
+            else
+            {
+                glGenTextures(1, &texture);
+                thiz->_texture = texture;
+
+                glBindTexture(JAWT_RENDERER_TEXTURE, texture);
+                glTexParameterf(
+                    JAWT_RENDERER_TEXTURE,
+                    GL_TEXTURE_PRIORITY,
+                    1.0);
+                glTexParameteri(
+                    JAWT_RENDERER_TEXTURE,
+                    GL_TEXTURE_WRAP_S,
+                    GL_CLAMP_TO_EDGE);
+                glTexParameteri(
+                    JAWT_RENDERER_TEXTURE,
+                    GL_TEXTURE_WRAP_T,
+                    GL_CLAMP_TO_EDGE);
+                glTexParameteri(
+                    JAWT_RENDERER_TEXTURE,
+                    GL_TEXTURE_MAG_FILTER,
+                    GL_LINEAR);
+                glTexParameteri(
+                    JAWT_RENDERER_TEXTURE,
+                    GL_TEXTURE_MIN_FILTER,
+                    GL_LINEAR);
+
+                glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+                glTexParameteri(
+                    JAWT_RENDERER_TEXTURE,
+                    GL_TEXTURE_STORAGE_HINT_APPLE,
+                    GL_STORAGE_SHARED_APPLE);
+
+                glTexImage2D(
+                    JAWT_RENDERER_TEXTURE,
+                    0,
+                    4,
+                    width, height,
+                    0,
+                    JAWT_RENDERER_TEXTURE_FORMAT,
+                    JAWT_RENDERER_TEXTURE_TYPE,
+                    data);
+            }
+            thiz->_width = width;
+            thiz->_height = height;
 
-    renderer = (JAWTRenderer *) (intptr_t) handle;
-    autoreleasePool = [[NSAutoreleasePool alloc] init];
+            CGLUnlockContext(glContext);
+        }
 
-    @synchronized (renderer)
-    {
-        renderer->boundsX = x;
-        renderer->boundsY = y;
-        renderer->boundsWidth = width;
-        renderer->boundsHeight = height;
+        [autoreleasePool release];
     }
 
-    [autoreleasePool release];
-}
-
-void
-JAWTRenderer_removeNotifyLightweightComponent(jlong handle, jobject component)
-{
-    JAWTRenderer *renderer;
-    NSAutoreleasePool *autoreleasePool;
-
-    renderer = (JAWTRenderer *) (intptr_t) handle;
-    autoreleasePool = [[NSAutoreleasePool alloc] init];
-
-    [renderer removeFromSuperrenderer];
-
-    [autoreleasePool release];
+    return JNI_TRUE;
 }
 
 jstring
-JAWTRenderer_sysctlbyname(JNIEnv *jniEnv, jstring name)
+JAWTRenderer_sysctlbyname(JNIEnv *env, jstring name)
 {
     const char *_name;
     jstring value = NULL;
 
-    _name = (*jniEnv)->GetStringUTFChars(jniEnv, name, NULL);
+    _name = (*env)->GetStringUTFChars(env, name, NULL);
     if (_name)
     {
         size_t valueLength;
@@ -357,443 +280,144 @@ JAWTRenderer_sysctlbyname(JNIEnv *jniEnv, jstring name)
         }
         else
             _value = NULL;
-        (*jniEnv)->ReleaseStringUTFChars(jniEnv, name, _name);
+        (*env)->ReleaseStringUTFChars(env, name, _name);
 
         if (_value)
         {
-            value = (*jniEnv)->NewStringUTF(jniEnv, _value);
+            value = (*env)->NewStringUTF(env, _value);
             free(_value);
         }
     }
     return value;
 }
 
-@implementation JAWTRenderer
-- (void)addSubrenderer:(JAWTRenderer *)subrenderer
+@implementation JAWTRendererLayer
+- (CGLContextObj)copyCGLContextForPixelFormat:(CGLPixelFormatObj)pixelFormat
 {
-    @synchronized (self)
+    CGLContextObj glContext = CGLRetainContext(_glContext);
+
+    /*
+     * Perform any one-time configuration/preparation of the newly-initialized
+     * OpenGL context which this CAOpenGLLayer will be drawing into
+     * (in the future).
+     */
+    if (glContext && (kCGLNoError == CGLLockContext(glContext)))
     {
-        if (!subrenderers)
-            subrenderers = [[NSMutableArray arrayWithCapacity:1] retain];
-        if (NSNotFound == [subrenderers indexOfObject:subrenderer])
-        {
-            [subrenderers addObject:subrenderer];
-            [subrenderer retain];
-            [subrenderer setSuperrenderer:self];
-        }
+        GLint param;
+
+        CGLSetCurrentContext(glContext);
+
+        param = 1;
+        CGLSetParameter(glContext, kCGLCPSurfaceOpacity, &param);
+        param = 0;
+        CGLSetParameter(glContext, kCGLCPSwapInterval, &param);
+
+        glDisable(GL_ALPHA_TEST);
+        glDisable(GL_BLEND);
+        glDisable(GL_CULL_FACE);
+        glDisable(GL_DEPTH_TEST);
+        glDisable(GL_DITHER);
+        glDisable(GL_LIGHTING);
+        glDisable(GL_SCISSOR_TEST);
+        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+        glDepthMask(GL_FALSE);
+        glStencilMask(0);
+        glHint(GL_TRANSFORM_HINT_APPLE, GL_FASTEST);
+        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+        glClear(GL_COLOR_BUFFER_BIT);
+
+        CGLUnlockContext(glContext);
     }
-}
 
-- (void)boundsDidChange:(NSNotification *)notification
-{
-    if ([notification object] == view)
-        [self reshape];
+    return glContext;
 }
 
-- (void)copyCGLContext:(NSOpenGLContext *)glContext
-        forPixelFormat:(CGLPixelFormatObj)pixelFormat
+- (CGLPixelFormatObj)copyCGLPixelFormatForDisplayMask:(uint32_t)mask
 {
-    @synchronized (self)
-    {
-        if (self->glContext)
-        {
-            [self->glContext makeCurrentContext];
-            if (texture)
-            {
-                glDeleteTextures(1, &texture);
-                texture = 0;
-            }
-            [NSOpenGLContext clearCurrentContext];
-
-            [self->glContext release];
-            self->glContext = nil;
-        }
-
-        if (glContext)
-        {
-            NSOpenGLPixelFormat *format = [NSOpenGLPixelFormat alloc];
-
-            /*
-             * Unfortunately, initWithCGLPixelFormatObj: is available starting
-             * with Mac OS X 10.6.
-             */
-            if ([format
-                    respondsToSelector:@selector(initWithCGLPixelFormatObj:)])
-            {
-                format = [format initWithCGLPixelFormatObj:pixelFormat];
-            }
-            else
-            {
-                NSOpenGLPixelFormatAttribute pixelFormatAttribs[]
-                    = { NSOpenGLPFAWindow, 0 };
-
-                format = [format initWithAttributes:pixelFormatAttribs];
-            }
-
-            self->glContext
-                = [[NSOpenGLContext alloc]
-                        initWithFormat:format
-                          shareContext:glContext];
-            [format release];
-        }
-    }
+    return CGLRetainPixelFormat(_pixelFormat);
 }
 
 - (void)dealloc
 {
-    /* subrenderers */
-    @synchronized (self)
-    {
-        if (subrenderers)
-        {
-            NSUInteger subrendererCount = [subrenderers count];
-
-            while (subrendererCount > 0)
-            {
-                --subrendererCount;
-                [self removeSubrendererAtIndex:subrendererCount];
-            }
-            [subrenderers release];
-            subrenderers = nil;
-        }
-    }
-
-    [self setView:nil];
+    if (_glContext)
+        CGLReleaseContext(_glContext);
+    if (_pixelFormat)
+        CGLReleasePixelFormat(_pixelFormat);
 
     [super dealloc];
 }
 
-- (void)frameDidChange:(NSNotification *)notification
-{
-    if ([notification object] == view)
-        [self update];
-}
-
-- (id)init
+- (void)drawInCGLContext:(CGLContextObj)glContext
+             pixelFormat:(CGLPixelFormatObj)pixelFormat
+            forLayerTime:(CFTimeInterval)timeInterval
+             displayTime:(const CVTimeStamp *)timeStamp
 {
-    if ((self = [super init]))
+    if (kCGLNoError == CGLLockContext(glContext))
     {
+        glClear(GL_COLOR_BUFFER_BIT);
 
-        glContext = nil;
-
-        height = 0;
-        texture = 0;
-        width = 0;
-
-        frameHeight = 0;
-        frameWidth = 0;
-        frameX = 0;
-        frameY = 0;
-
-        boundsHeight = 0;
-        boundsWidth = 0;
-        boundsX = 0;
-        boundsY = 0;
-
-        view = nil;
-
-        subrenderers = nil;
-        superrenderer = nil;
-    }
-    return self;
-}
-
-- (void)paint
-{
-    if (!glContext)
-        return;
-
-    [glContext makeCurrentContext];
-
-    // drawRect:
-    glClear(GL_COLOR_BUFFER_BIT);
-
-    @synchronized (self)
-    {
-        if (texture)
+        if (_texture)
         {
             /*
              * It may be a misunderstanding of OpenGL context sharing but
              * JAWT_RENDERER_TEXTURE does not seem to work in glContext unless
              * it is explicitly bound to texture while glContext is current.
              */
-            glBindTexture(JAWT_RENDERER_TEXTURE, texture);
+            glBindTexture(JAWT_RENDERER_TEXTURE, _texture);
             glEnable(JAWT_RENDERER_TEXTURE);
             glBegin(GL_QUADS);
             glTexCoord2f(0, 0);
             glVertex2f(-1.0, 1.0);
-            glTexCoord2f(width, 0);
+            glTexCoord2f(_width, 0);
             glVertex2f(1.0, 1.0);
-            glTexCoord2f(width, height);
+            glTexCoord2f(_width, _height);
             glVertex2f(1.0, -1.0);
-            glTexCoord2f(0, height);
+            glTexCoord2f(0, _height);
             glVertex2f(-1.0, -1.0);
             glEnd();
             glDisable(JAWT_RENDERER_TEXTURE);
         }
-            
-        /* Draw the subrenderers of this JAWTRenderer. */
-        if (subrenderers)
-        {
-            NSUInteger subrendererIndex = 0;
-            NSUInteger subrendererCount = [subrenderers count];
-            CGLPixelFormatObj pixelFormat = 0;
 
-            for (;
-                    subrendererIndex < subrendererCount;
-                    subrendererIndex++)
-            {
-                JAWTRenderer *subrenderer
-                    = [subrenderers objectAtIndex:subrendererIndex];
-
-                @synchronized (subrenderer)
-                {
-                    GLfloat subrendererBoundsHeight;
-                    GLfloat subrendererBoundsWidth;
-
-                    /*
-                     * Make sure the subrenderer has an NSOpenGLContext
-                     * which is compatible with glContext and shares its
-                     * object state.
-                     */
-                    if (!(subrenderer->glContext))
-                    {
-                        if (!pixelFormat)
-                            pixelFormat
-                                = CGLGetPixelFormat([glContext CGLContextObj]);
-                        [subrenderer copyCGLContext:glContext
-                                     forPixelFormat:pixelFormat];
-                    }
-
-                    subrendererBoundsHeight = subrenderer->boundsHeight;
-                    subrendererBoundsWidth = subrenderer->boundsWidth;
-                    if (subrenderer->texture
-                            && (subrendererBoundsHeight > 0)
-                            && (subrendererBoundsWidth > 0))
-                    {
-                        GLfloat x_1
-                            = -1.0 + 2 * subrenderer->boundsX / boundsWidth;
-                        GLfloat y1
-                            = 1 - 2 * subrenderer->boundsY / boundsHeight;
-                        GLfloat x1
-                            = x_1 + 2 * subrendererBoundsWidth / boundsWidth;
-                        GLfloat y_1
-                            = y1 - 2 * subrendererBoundsHeight / boundsHeight;
-
-                        glBindTexture(
-                            JAWT_RENDERER_TEXTURE,
-                            subrenderer->texture);
-                        glEnable(JAWT_RENDERER_TEXTURE);
-                        glBegin(GL_QUADS);
-                        glTexCoord2f(0, 0);
-                        glVertex2f(x_1, y1);
-                        glTexCoord2f(subrenderer->width, 0);
-                        glVertex2f(x1, y1);
-                        glTexCoord2f(subrenderer->width, subrenderer->height);
-                        glVertex2f(x1, y_1);
-                        glTexCoord2f(0, subrenderer->height);
-                        glVertex2f(x_1, y_1);
-                        glEnd();
-                        glDisable(JAWT_RENDERER_TEXTURE);
-                    }
-                }
-            }
-        }
+        CGLUnlockContext(glContext);
     }
 
-    glFlush();
+    [super drawInCGLContext:glContext
+                pixelFormat:pixelFormat
+               forLayerTime:timeInterval
+                displayTime:timeStamp];
 }
 
-- (void)removeFromSuperrenderer
-{
-    if (superrenderer)
-        [superrenderer removeSubrenderer:self];
-    [self copyCGLContext:nil forPixelFormat:nil];
-}
-
-- (void)removeSubrenderer:(JAWTRenderer *)subrenderer
-{
-    @synchronized (self)
-    {
-        if (subrenderers)
-        {
-            NSUInteger index = [subrenderers indexOfObject:subrenderer];
-
-            if (NSNotFound != index)
-                [self removeSubrendererAtIndex:index];
-        }
-    }
-}
-
-- (void)removeSubrendererAtIndex:(NSUInteger)index
-{
-    @synchronized (self)
-    {
-        if (subrenderers)
-        {
-            JAWTRenderer *subrenderer = [subrenderers objectAtIndex:index];
-
-            [subrenderers removeObjectAtIndex:index];
-            [subrenderer setSuperrenderer:nil];
-            [subrenderer release];
-        }
-    }
-}
-
-- (void)reshape
-{
-    NSRect bounds;
-
-    bounds = [view bounds];
-    boundsHeight = bounds.size.height;
-    boundsWidth = bounds.size.width;
-    boundsX = bounds.origin.x;
-    boundsY = bounds.origin.y;
-    if ((bounds.size.width > 0) && (bounds.size.height > 0) && glContext)
-    {
-        [glContext makeCurrentContext];
-
-        glViewport(
-            bounds.origin.x, bounds.origin.y,
-            bounds.size.width, bounds.size.height);
-    }
-}
-
-- (void)setSuperrenderer:(JAWTRenderer *)aSuperrenderer
-{
-    if (superrenderer != aSuperrenderer)
-    {
-        if (superrenderer)
-            [superrenderer release];
-
-        superrenderer = aSuperrenderer;
-
-        if (superrenderer)
-            [superrenderer retain];
-    }
-}
-
-- (void)setView:(NSView *)aView
+- (id)init
 {
-    if (view != aView)
+    if ((self = [super init]))
     {
-        if (view)
+        CGLPixelFormatAttribute attribs[]
+            = { kCGLPFAAccelerated, kCGLPFAWindow, 0 };
+        GLint npix;
+
+        _glContext = NULL;
+        _height = 0;
+        _pixelFormat = NULL;
+        _texture = 0;
+        _width = 0;
+
+        if ((kCGLNoError == CGLChoosePixelFormat(attribs, &_pixelFormat, &npix))
+                && (kCGLNoError
+                        == CGLCreateContext(_pixelFormat, NULL, &_glContext)))
         {
-#ifdef JAWT_RENDERER_USE_NSNOTIFICATIONCENTER
-            NSNotificationCenter *notificationCenter;
-
-            notificationCenter = [NSNotificationCenter defaultCenter];
-            if (notificationCenter)
-            {
-                [notificationCenter
-                    removeObserver:self
-                    name:NSViewBoundsDidChangeNotification
-                    object:view];
-                [notificationCenter
-                    removeObserver:self
-                    name:NSViewFrameDidChangeNotification
-                    object:view];
-            }
-#endif /* JAWT_RENDERER_USE_NSNOTIFICATIONCENTER */
-
-            [self copyCGLContext:nil forPixelFormat:0];
-
-            [view release];
+            self.asynchronous = YES;
+            /*
+             * The AWT Canvas that corresponds to this CAOpenGLLayer will ensure
+             * that the latter will be displayed on bounds changes.
+             */
+            self.needsDisplayOnBoundsChange = NO;
         }
-
-        view = aView;
-
-        if (view)
+        else
         {
-            NSOpenGLPixelFormatAttribute pixelFormatAttribs[]
-                = { NSOpenGLPFAWindow, 0 };
-            NSOpenGLPixelFormat *pixelFormat;
-
-#ifdef JAWT_RENDERER_USE_NSNOTIFICATIONCENTER
-            NSNotificationCenter *notificationCenter;
-#endif /* JAWT_RENDERER_USE_NSNOTIFICATIONCENTER */
-
-            [view retain];
-            
-            pixelFormat
-                = [[NSOpenGLPixelFormat alloc]
-                        initWithAttributes:pixelFormatAttribs];
-            if (pixelFormat)
-            {
-                glContext
-                    = [[NSOpenGLContext alloc] initWithFormat:pixelFormat
-                                                 shareContext:nil];
-                if (glContext)
-                {
-                    GLint surfaceOpacity;
-                    GLint swapInterval;
-
-                    // prepareOpenGL
-                    [glContext makeCurrentContext];
-
-                    surfaceOpacity = 1;
-                    [glContext setValues:&surfaceOpacity
-                            forParameter:NSOpenGLCPSurfaceOpacity];
-                    swapInterval = 0;
-                    [glContext setValues:&swapInterval
-                            forParameter:NSOpenGLCPSwapInterval];
-                    
-                    glDisable(GL_ALPHA_TEST);
-                    glDisable(GL_BLEND);
-                    glDisable(GL_CULL_FACE);
-                    glDisable(GL_DEPTH_TEST);
-                    glDisable(GL_DITHER);
-                    glDisable(GL_LIGHTING);
-                    glDisable(GL_SCISSOR_TEST);
-                    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-                    glDepthMask(GL_FALSE);
-                    glStencilMask(0);
-                    glHint(GL_TRANSFORM_HINT_APPLE, GL_FASTEST);
-                    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
-                    glClear(GL_COLOR_BUFFER_BIT);
-                }
-                [pixelFormat release];
-            }
-
-            if (glContext && ([glContext view] != view))
-                [glContext setView:view];
-
-#ifdef JAWT_RENDERER_USE_NSNOTIFICATIONCENTER
-            notificationCenter = [NSNotificationCenter defaultCenter];
-            if (notificationCenter)
-            {
-                [view setPostsBoundsChangedNotifications:YES];
-                [notificationCenter
-                    addObserver:self
-                    selector:@selector(boundsDidChange:)
-                    name:NSViewBoundsDidChangeNotification
-                    object:view];
-                [view setPostsFrameChangedNotifications:YES];
-                [notificationCenter
-                    addObserver:self
-                    selector:@selector(frameDidChange:)
-                    name:NSViewFrameDidChangeNotification
-                    object:view];
-            }
-#endif /* JAWT_RENDERER_USE_NSNOTIFICATIONCENTER */
-
-            [self update];
+            [self release];
+            self = nil;
         }
     }
+    return self;
 }
-
-- (void)update
-{
-    NSRect frame;
-
-    frame = [view frame];
-    frameHeight = frame.size.height;
-    frameWidth = frame.size.width;
-    frameX = frame.origin.x;
-    frameY = frame.origin.y;
-    if (glContext)
-        [glContext update];
-
-    [self reshape];
-}
-@end /* JAWTRenderer */
+@end /* JAWTRendererLayer */
diff --git a/src/native/jawtrenderer/JAWTRenderer_Windows.c b/src/native/jawtrenderer/JAWTRenderer_Windows.c
new file mode 100644
index 0000000000000000000000000000000000000000..bf161c0dedf6088a46e641dda53bbe45e0054c59
--- /dev/null
+++ b/src/native/jawtrenderer/JAWTRenderer_Windows.c
@@ -0,0 +1,279 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+
+#include "JAWTRenderer.h"
+
+#include <d3d9.h>
+#include <d3dx9tex.h>
+#include <jawt_md.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+typedef struct _JAWTRenderer
+{
+    LPDIRECT3D9 d3d;
+    LPDIRECT3DDEVICE9 device;
+    jint height;
+    HWND hwnd;
+    BOOL lost;
+    LPDIRECT3DSURFACE9 surface;
+    jint width;
+}
+JAWTRenderer;
+
+HRESULT _JAWTRenderer_createDevice(JAWTRenderer *thiz, jint width, jint height);
+
+void
+JAWTRenderer_close(JNIEnv *env, jclass clazz, jlong handle, jobject component)
+{
+    JAWTRenderer *thiz = (JAWTRenderer *) (intptr_t) handle;
+
+    if (thiz->surface)
+        IDirect3DSurface9_Release(thiz->surface);
+    if (thiz->device)
+        IDirect3DDevice9_Release(thiz->device);
+    IDirect3D9_Release(thiz->d3d);
+    free(thiz);
+}
+
+jlong
+JAWTRenderer_open(JNIEnv *env, jclass clazz, jobject component)
+{
+    LPDIRECT3D9 d3d = Direct3DCreate9(D3D_SDK_VERSION);
+    JAWTRenderer *thiz;
+
+    if (d3d)
+    {
+        thiz = calloc(1, sizeof(JAWTRenderer));
+        if (thiz)
+            thiz->d3d = d3d;
+        else
+            IDirect3D9_Release(d3d);
+    }
+    else
+        thiz = NULL;
+    return (jlong) (intptr_t) thiz;
+}
+
+jboolean
+JAWTRenderer_paint
+    (jint version, JAWT_DrawingSurfaceInfo *dsi, jclass clazz, jlong handle,
+        jobject g, jint zOrder)
+{ 
+    HDC hdc = ((JAWT_Win32DrawingSurfaceInfo *) (dsi->platformInfo))->hdc;
+    JAWTRenderer *thiz = (JAWTRenderer *) (intptr_t) handle;
+
+    LPDIRECT3DDEVICE9 device = thiz->device;
+    HWND hwnd = WindowFromDC(hdc);
+
+    if (device && (thiz->hwnd == hwnd))
+    {
+        HRESULT hr;
+
+        /*
+         * Check whether Direct3D considers the device of this JAWTRenderer
+         * functional/valid.
+         */
+        hr = IDirect3DDevice9_TestCooperativeLevel(device);
+        if (SUCCEEDED(hr))
+        {
+            /*
+             * If we do not have a Direct3D surface to present, we will make
+             * sure that the display is cleared. Otherwise, we do not have to
+             * clear it because we render complete frames in the whole viewport
+             * with transparency.
+             */
+            BOOL clear = TRUE;
+
+            /* Copy the Direct3D surface into the back buffer. */
+            if (thiz->surface)
+            {
+                LPDIRECT3DSURFACE9 backBuffer;
+
+                hr
+                    = IDirect3DDevice9_GetBackBuffer(
+                        device,
+                        0, 0, D3DBACKBUFFER_TYPE_MONO, &backBuffer);
+                if (SUCCEEDED(hr))
+                {
+                    hr = IDirect3DDevice9_BeginScene(device);
+                    if (SUCCEEDED(hr))
+                    {
+                        IDirect3DDevice9_UpdateSurface(
+                            device,
+                            thiz->surface, NULL, backBuffer, NULL);
+                        IDirect3DDevice9_EndScene(device);
+                        clear = FALSE;
+                    }
+                    IDirect3DSurface9_Release(backBuffer);
+                }
+            }
+            if (clear)
+            {
+                /* Clear the Direct3D back buffer. */
+                IDirect3DDevice9_Clear(
+                    device,
+                    0,
+                    0,
+                    D3DCLEAR_TARGET,
+                    D3DCOLOR_XRGB(0xff, 0xff, 0xff),
+                    0.0f,
+                    0);
+            }
+
+            /* Present the Direct3D back buffer. */
+            IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
+        }
+        else
+            thiz->lost = TRUE;
+    }
+    else
+    {
+        thiz->hwnd = hwnd;
+        thiz->lost = TRUE;
+    }
+
+    return JNI_TRUE;
+}
+
+jboolean
+JAWTRenderer_process
+    (JNIEnv *env, jclass clazz, jlong handle, jobject component, jint *data,
+        jint length, jint width, jint height)
+{
+    JAWTRenderer *thiz = (JAWTRenderer *) (intptr_t) handle;
+
+    if (!(thiz->device)
+            || (thiz->width != width)
+            || (thiz->height != height)
+            || thiz->lost)
+    {
+        /*
+         * Release the device and the surface if any because it appears we have
+         * to re-create them.
+         */
+        thiz->lost = FALSE;
+        if (thiz->surface)
+        {
+            IDirect3DSurface9_Release(thiz->surface);
+            thiz->surface = NULL;
+        }
+        if (thiz->device)
+        {
+            IDirect3DDevice9_Release(thiz->device);
+            thiz->device = NULL;
+        }
+
+        if (thiz->hwnd)
+        {
+            HRESULT hr;
+
+            hr = _JAWTRenderer_createDevice(thiz, width, height);
+            if (SUCCEEDED(hr))
+            {
+                hr
+                    = IDirect3DDevice9_CreateOffscreenPlainSurface(
+                        thiz->device,
+                        width,
+                        height,
+                        D3DFMT_X8R8G8B8,
+                        D3DPOOL_SYSTEMMEM,
+                        &(thiz->surface),
+                        NULL);
+                if (SUCCEEDED(hr))
+                {
+                    thiz->width = width;
+                    thiz->height = height;
+                }
+                else
+                {
+                    thiz->surface = NULL;
+                    /*
+                     * Well, we do not know why we would fail to create the
+                     * surface but such a scenario seems grave enough to us to
+                     * give up this JAWTRenderer.
+                     */
+                    return JNI_FALSE;
+                }
+            }
+            /*
+             * If we failed to create the Direct3D device, we will try again
+             * next time in the hope that we will succeed eventually.
+             */
+        }
+    }
+
+    if (thiz->surface)
+    {
+        RECT rect;
+
+        rect.bottom = height;
+        rect.left = 0;
+        rect.right = width;
+        rect.top = 0;
+        D3DXLoadSurfaceFromMemory(
+            thiz->surface,
+            NULL,
+            NULL,
+            data,
+            D3DFMT_A8R8G8B8,
+            width * 4,
+            NULL,
+            &rect,
+            D3DX_FILTER_NONE,
+            0);
+    }
+
+    return JNI_TRUE;
+}
+
+HRESULT
+_JAWTRenderer_createDevice(JAWTRenderer *thiz, jint width, jint height)
+{
+    D3DPRESENT_PARAMETERS params;
+    HRESULT hr;
+
+    ZeroMemory(&params, sizeof(D3DPRESENT_PARAMETERS));
+
+    params.AutoDepthStencilFormat = D3DFMT_D16;
+    params.BackBufferCount = 1;
+    params.BackBufferFormat = D3DFMT_UNKNOWN;
+    params.BackBufferHeight = height;
+    params.BackBufferWidth = width;
+    params.EnableAutoDepthStencil = FALSE;
+    params.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
+    params.FullScreen_RefreshRateInHz = 0;
+    params.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
+    params.SwapEffect = D3DSWAPEFFECT_DISCARD;
+    params.Windowed = TRUE;
+
+    hr
+        = IDirect3D9_CheckDeviceMultiSampleType(
+            thiz->d3d,
+            D3DADAPTER_DEFAULT,
+            D3DDEVTYPE_HAL,
+            params.BackBufferFormat,
+            params.Windowed,
+            D3DMULTISAMPLE_2_SAMPLES,
+            NULL);
+    params.MultiSampleQuality
+        = SUCCEEDED(hr) ? D3DMULTISAMPLE_2_SAMPLES : D3DMULTISAMPLE_NONE;
+
+    hr
+        = IDirect3D9_CreateDevice(
+            thiz->d3d,
+            D3DADAPTER_DEFAULT,
+            D3DDEVTYPE_HAL,
+            thiz->hwnd,
+            D3DCREATE_SOFTWARE_VERTEXPROCESSING,
+            &params,
+            &(thiz->device));
+    if (FAILED(hr))
+        thiz->device = NULL;
+
+    return hr;
+}
diff --git a/src/native/jawtrenderer/JAWTRenderer_Windows.cpp b/src/native/jawtrenderer/JAWTRenderer_Windows.cpp
deleted file mode 100644
index e150d571f922bbf2aad4182a8737103f6bc7cd04..0000000000000000000000000000000000000000
--- a/src/native/jawtrenderer/JAWTRenderer_Windows.cpp
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-
-#include "jawt_md.h"
-#include "JAWTRenderer.h"
-
-#include "windows/d3d_context.h"
-#include "windows/d3d_device.h"
-#include "windows/d3d_surface.h"
-
-struct D3DBlitter
-{
-    D3DContext* d3d;
-    D3DDevice* device;
-    D3DSurface* surface;
-    HWND hwnd;
-    size_t width;
-    size_t height;
-    bool lost;
-};
-
-void JAWTRenderer_close
-    (JNIEnv *jniEnv, jclass clazz, jlong handle, jobject component)
-{
-    D3DBlitter* blitter = reinterpret_cast<D3DBlitter*>(handle);
-
-    if(!blitter)
-    {
-        return;
-    }
-
-    if(blitter->surface)
-    {
-        delete blitter->surface;
-        blitter->surface = NULL;
-    }
-
-    if(blitter->device)
-    {
-        delete blitter->device;
-        blitter->device = NULL;
-    }
-
-    if(blitter->d3d)
-    {
-        delete blitter->d3d;
-        blitter->d3d = NULL;
-    }
-
-    delete blitter;
-}
-
-jlong JAWTRenderer_open(JNIEnv *jniEnv, jclass clazz, jobject component)
-{
-    D3DBlitter* ret = new D3DBlitter();
-
-    ret->d3d = D3DContext::createD3DContext();
-    ret->surface = NULL;
-    ret->device = NULL; 
-    ret->width = 0;
-    ret->height = 0;
-    ret->lost = false;
-
-    /* failed to initialize Direct3D */
-    if(!ret->d3d)
-    {
-        delete ret;
-        ret = NULL;
-    }
-
-    return (jlong)ret;
-}
-
-jboolean JAWTRenderer_paint
-    (JAWT_DrawingSurfaceInfo *dsi, jclass clazz, jlong handle, jobject g)
-{ 
-    JAWT_Win32DrawingSurfaceInfo* dsi_win = 
-        reinterpret_cast<JAWT_Win32DrawingSurfaceInfo*>(dsi->platformInfo);
-    D3DBlitter* blitter = reinterpret_cast<D3DBlitter*>(handle);
-    HWND hwnd = WindowFromDC(dsi_win->hdc);
-    
-    if(!blitter)
-        return JNI_FALSE;
-
-    if(blitter->device == NULL || blitter->hwnd != hwnd)
-    {
-        blitter->hwnd = hwnd;
-        blitter->lost = true;
-        return JNI_TRUE;
-    }
-
-    if(!blitter->device->validate())
-    {
-      blitter->lost = true;
-      return JNI_TRUE;
-    }
-    
-    blitter->device->render(blitter->surface);
-    return JNI_TRUE;
-}
-
-jboolean JAWTRenderer_process
-    (JNIEnv *jniEnv, jclass clazz,
-     jlong handle, jobject component,
-     jint *data, jint length,
-     jint width, jint height)
-{
-    D3DBlitter* blitter = reinterpret_cast<D3DBlitter*>(handle);
-
-    if(!blitter)
-    {
-        return JNI_FALSE;
-    }
-
-    if(!blitter->device || blitter->width != width || blitter->height != height
-            || blitter->lost)
-    {
-        D3DSurface* oldSurface = NULL;
-        D3DDevice* oldDevice = NULL;
-
-        blitter->lost = false;
-
-        /* size has changed, recreate our device and surface */
-        if(blitter->surface)
-        {
-            delete blitter->surface;
-            blitter->surface = NULL;
-        }
-
-        if(blitter->device)
-        {
-            delete blitter->device;
-            blitter->device = NULL;
-        }
-
-        if(blitter->hwnd == NULL)
-        {
-            return JNI_TRUE;
-        }
-
-        blitter->device = blitter->d3d->createDevice(blitter->hwnd, width,
-                height);
-
-        if(!blitter->device)
-        {
-            /* device creation failed */
-
-            blitter->surface = NULL;
-            /* maybe we go fullscreen and/or hwnd of the window has changed
-             * so we return true to force native method to be called and so
-             * update blitter->hwnd for the next call
-             */
-            return JNI_TRUE;
-        }
-
-        blitter->surface = blitter->device->createSurface(width, height);
-
-        if(!blitter->surface)
-        {
-            return JNI_FALSE;
-        }
-
-        blitter->width = width;
-        blitter->height = height;
-    }
-
-    if(blitter->surface)
-    {
-        blitter->surface->loadData(reinterpret_cast<char*>(data),
-                width, height);
-    }
-    return JNI_TRUE;
-}
-
diff --git a/src/native/jawtrenderer/org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer.c b/src/native/jawtrenderer/org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer.c
index 465923003de1c8433e28c91b4b27c4a958f42abb..236350e28ebc05ba279f7492b5598fe4ea77ec29 100644
--- a/src/native/jawtrenderer/org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer.c
+++ b/src/native/jawtrenderer/org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer.c
@@ -8,45 +8,57 @@
 #include "org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer.h"
 #include "JAWTRenderer.h"
 
-JNIEXPORT void JNICALL
-Java_org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer_addNotifyLightweightComponent
-    (JNIEnv *jniEnv, jclass clazz,
-    jlong handle, jobject component,
-    jlong parentHandle)
-{
-#ifdef __APPLE__
-    JAWTRenderer_addNotifyLightweightComponent(handle, component, parentHandle);
-#endif /* #ifdef __APPLE__ */
-}
-
 JNIEXPORT void JNICALL
 Java_org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer_close
-    (JNIEnv *jniEnv, jclass clazz, jlong handle, jobject component)
+    (JNIEnv *env, jclass clazz, jlong handle, jobject component)
 {
-    JAWTRenderer_close(jniEnv, clazz, handle, component);
+    JAWTRenderer_close(env, clazz, handle, component);
 }
 
 JNIEXPORT jlong JNICALL
 Java_org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer_open
-    (JNIEnv *jniEnv, jclass clazz, jobject component)
+    (JNIEnv *env, jclass clazz, jobject component)
 {
-    return JAWTRenderer_open(jniEnv, clazz, component);
+    return JAWTRenderer_open(env, clazz, component);
 }
 
 JNIEXPORT jboolean JNICALL
 Java_org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer_paint
-    (JNIEnv *jniEnv, jclass clazz, jlong handle, jobject component, jobject g)
+    (JNIEnv *env, jclass clazz, jlong handle, jobject component, jobject g,
+        jint zOrder)
 {
     JAWT awt;
+    jboolean awtIsAvailable;
     jboolean wantsPaint;
 
-    awt.version = JAWT_VERSION_1_3;
+    awt.version = JAWT_VERSION_1_4;
+#ifdef __APPLE__
+#ifndef JAWT_MACOSX_USE_CALAYER
+#define JAWT_MACOSX_USE_CALAYER 0x80000000
+#endif /* #ifndef JAWT_MACOSX_USE_CALAYER */
+
+    awt.version |= JAWT_MACOSX_USE_CALAYER;
+    awtIsAvailable = JAWT_GetAWT(env, &awt);
+    /*
+     * We do not know whether JAWT_GetAWT will fail when JAWT_MACOSX_USE_CALAYER
+     * is specified and not supported or it will rather remove the flag from the
+     * version field of JAWT. That's why we will call the function in question
+     * again in case of failure with the flag removed.
+     */
+    if (JNI_FALSE == awtIsAvailable)
+    {
+        awt.version &= ~JAWT_MACOSX_USE_CALAYER;
+        awtIsAvailable = JAWT_GetAWT(env, &awt);
+    }
+#else /* #ifdef __APPLE__ */
+    awtIsAvailable = JAWT_GetAWT(env, &awt);
+#endif /* #ifdef __APPLE__ */
     wantsPaint = JNI_TRUE;
-    if (JAWT_GetAWT(jniEnv, &awt) != JNI_FALSE)
+    if (JNI_TRUE == awtIsAvailable)
     {
         JAWT_DrawingSurface *ds;
 
-        ds = awt.GetDrawingSurface(jniEnv, component);
+        ds = awt.GetDrawingSurface(env, component);
         if (ds)
         {
             jint dsLock;
@@ -60,12 +72,19 @@ Java_org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer_paint
                 if (dsi && dsi->platformInfo)
                 {
                     /*
-                     * The function arguments jniEnv and component are now
+                     * The function arguments env and component are now
                      * available as the fields env and target, respectively, of
                      * the JAWT_DrawingSurface which is itself the value of the
                      * field ds of the JAWT_DrawingSurfaceInfo.
                      */
-                    wantsPaint = JAWTRenderer_paint(dsi, clazz, handle, g);
+                    wantsPaint
+                        = JAWTRenderer_paint(
+                            awt.version,
+                            dsi,
+                            clazz,
+                            handle,
+                            g,
+                            zOrder);
                     ds->FreeDrawingSurfaceInfo(dsi);
                 }
                 ds->Unlock(ds);
@@ -76,45 +95,25 @@ Java_org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer_paint
     return wantsPaint;
 }
 
-JNIEXPORT jboolean JNICALL
-Java_org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer_paintLightweightComponent
-    (JNIEnv *jniEnv, jclass clazz, jlong handle, jobject component, jobject g)
-{
-    jboolean wantsPaint;
-
-#ifdef __APPLE__
-    wantsPaint = JAWTRenderer_paintLightweightComponent(handle, component, g);
-#else /* #ifdef __APPLE__ */
-    /*
-     * There is really no point in delivering any paint events/notifications
-     * because there is no implementation.
-     */
-    wantsPaint = JNI_FALSE;
-#endif /* #ifdef __APPLE__ */
-    return wantsPaint;
-}
-
 JNIEXPORT jboolean JNICALL
 Java_org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer_process
-    (JNIEnv *jniEnv, jclass clazz,
-     jlong handle, jobject component,
-     jintArray data, jint offset, jint length,
-     jint width, jint height)
+    (JNIEnv *env, jclass clazz, jlong handle, jobject component, jintArray data,
+        jint offset, jint length, jint width, jint height)
 {
     jint *dataPtr;
     jboolean processed;
 
-    dataPtr = (*jniEnv)->GetPrimitiveArrayCritical(jniEnv, data, NULL);
+    dataPtr = (*env)->GetPrimitiveArrayCritical(env, data, NULL);
     if (dataPtr)
     {
         processed
             = JAWTRenderer_process(
-                    jniEnv, clazz,
+                    env, clazz,
                     handle, component,
                     dataPtr + offset, length,
                     width, height);
-        (*jniEnv)->ReleasePrimitiveArrayCritical(
-                jniEnv,
+        (*env)->ReleasePrimitiveArrayCritical(
+                env,
                 data, dataPtr,
                 JNI_ABORT);
     }
@@ -123,32 +122,12 @@ Java_org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer_process
     return processed;
 }
 
-JNIEXPORT void JNICALL
-Java_org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer_processLightweightComponentEvent
-    (JNIEnv *jniEnv, jclass clazz,
-    jlong handle,
-    jint x, jint y, jint width, jint height)
-{
-#ifdef __APPLE__
-    JAWTRenderer_processLightweightComponentEvent(handle, x, y, width, height);
-#endif /* #ifdef __APPLE__ */
-}
-
-JNIEXPORT void JNICALL
-Java_org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer_removeNotifyLightweightComponent
-    (JNIEnv *jniEnv, jclass clazz, jlong handle, jobject component)
-{
-#ifdef __APPLE__
-    JAWTRenderer_removeNotifyLightweightComponent(handle, component);
-#endif /* #ifdef __APPLE__ */
-}
-
 JNIEXPORT jstring JNICALL
 Java_org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer_sysctlbyname
-    (JNIEnv *jniEnv, jclass clazz, jstring name)
+    (JNIEnv *env, jclass clazz, jstring name)
 {
 #ifdef __APPLE__
-    return JAWTRenderer_sysctlbyname(jniEnv, name);
+    return JAWTRenderer_sysctlbyname(env, name);
 #else /* #ifdef __APPLE__ */
     return NULL;
 #endif /* #ifdef __APPLE__ */
diff --git a/src/native/jawtrenderer/org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer.h b/src/native/jawtrenderer/org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer.h
index a2508d2da44d2d7b8cd5a438f224e1569285160e..29d983bb95635042069b52671615be8e15249a38 100644
--- a/src/native/jawtrenderer/org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer.h
+++ b/src/native/jawtrenderer/org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer.h
@@ -7,14 +7,6 @@
 #ifdef __cplusplus
 extern "C" {
 #endif
-/*
- * Class:     org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer
- * Method:    addNotifyLightweightComponent
- * Signature: (JLjava/awt/Component;J)V
- */
-JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer_addNotifyLightweightComponent
-  (JNIEnv *, jclass, jlong, jobject, jlong);
-
 /*
  * Class:     org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer
  * Method:    close
@@ -34,18 +26,10 @@ JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_renderer_video
 /*
  * Class:     org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer
  * Method:    paint
- * Signature: (JLjava/awt/Component;Ljava/awt/Graphics;)Z
+ * Signature: (JLjava/awt/Component;Ljava/awt/Graphics;I)Z
  */
 JNIEXPORT jboolean JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer_paint
-  (JNIEnv *, jclass, jlong, jobject, jobject);
-
-/*
- * Class:     org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer
- * Method:    paintLightweightComponent
- * Signature: (JLjava/awt/Component;Ljava/awt/Graphics;)Z
- */
-JNIEXPORT jboolean JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer_paintLightweightComponent
-  (JNIEnv *, jclass, jlong, jobject, jobject);
+  (JNIEnv *, jclass, jlong, jobject, jobject, jint);
 
 /*
  * Class:     org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer
@@ -55,22 +39,6 @@ JNIEXPORT jboolean JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_renderer_vi
 JNIEXPORT jboolean JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer_process
   (JNIEnv *, jclass, jlong, jobject, jintArray, jint, jint, jint, jint);
 
-/*
- * Class:     org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer
- * Method:    processLightweightComponentEvent
- * Signature: (JIIII)V
- */
-JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer_processLightweightComponentEvent
-  (JNIEnv *, jclass, jlong, jint, jint, jint, jint);
-
-/*
- * Class:     org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer
- * Method:    removeNotifyLightweightComponent
- * Signature: (JLjava/awt/Component;)V
- */
-JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer_removeNotifyLightweightComponent
-  (JNIEnv *, jclass, jlong, jobject);
-
 /*
  * Class:     org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer
  * Method:    sysctlbyname
diff --git a/src/native/jawtrenderer/windows/d3d_context.cpp b/src/native/jawtrenderer/windows/d3d_context.cpp
deleted file mode 100644
index 218d9e912b7a980e97ea6226d17f3761527198ae..0000000000000000000000000000000000000000
--- a/src/native/jawtrenderer/windows/d3d_context.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-
-/**
- * \file d3d_context.cpp
- * \brief Direct3D context.
- * \author Sebastien Vincent
- * \date 2010
- */
-
-#include "d3d_context.h"
-
-D3DContext* D3DContext::createD3DContext()
-{
-    D3DContext* ret = new D3DContext();
-
-    if(ret->getDirect3D())
-    {
-        return ret;
-    }
-    else
-    {
-        /* fail to initialize Direct3D */
-        delete ret;
-        return NULL;
-    }
-}
-
-D3DContext::D3DContext()
-{
-    m_d3d = Direct3DCreate9(D3D_SDK_VERSION);
-}
-
-D3DContext::~D3DContext()
-{
-    if(m_d3d)
-    {
-        m_d3d->Release();
-        m_d3d = NULL;
-    }
-}
-
-LPDIRECT3D9 D3DContext::getDirect3D() const
-{
-    return m_d3d;
-}
-
-D3DDevice* D3DContext::createDevice(HWND hwnd, size_t width, size_t height)
-{
-    D3DDevice* ret = NULL;
-
-    ret = new D3DDevice(hwnd, getDirect3D(), width, height, false);
-    if(ret->getDevice())
-    {
-        return ret;
-    }
-    else
-    {
-        /* problem to create Direct3D device */
-        delete ret;
-        return NULL;
-    }
-}
-
diff --git a/src/native/jawtrenderer/windows/d3d_context.h b/src/native/jawtrenderer/windows/d3d_context.h
deleted file mode 100644
index 36a044bb203cd60256c3a307c32b1e814d941eb9..0000000000000000000000000000000000000000
--- a/src/native/jawtrenderer/windows/d3d_context.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-
-/**
- * \file d3d_context.h
- * \brief Direct3D context.
- * \author Sebastien Vincent
- * \date 2010
- */
-
-#ifndef D3D_CONTEXT_H
-#define D3D_CONTEXT_H
-
-#include <cstdlib>
-
-#include <d3d9.h>
-#include <d3dx9.h>
-
-#include "d3d_device.h"
-
-/**
- * \class D3DContext
- * \brief Direct3D context.
- */
-class D3DContext
-{
-    public:
-        /**
-         * \briefCreate a Direct3D context.
-         * \return Direct3D context pointer or NULL if failed
-         */
-        static D3DContext* createD3DContext();
-
-        /**
-         * \brief Constructor.
-         */
-        D3DContext();
-
-        /**
-         * \brief Destructor.
-         */
-        ~D3DContext();
-
-        /**
-         * \brief Get raw Direct3D context pointer.
-         * \return Direct3D
-         */
-        LPDIRECT3D9 getDirect3D() const;
-
-        /**
-         * \brief Create Direct3D device.
-         * \param hwnd handle of a window
-         * \param width width of the device
-         * \param height height of the device
-         * \return Direct3D device
-         */
-        D3DDevice* createDevice(HWND hwnd, size_t width, size_t height);
-
-    private:
-        /**
-         * \brief Direct3D context pointer.
-         */
-        LPDIRECT3D9 m_d3d;
-};
-
-#endif /* D3D_CONTEXT_H */
-
diff --git a/src/native/jawtrenderer/windows/d3d_device.cpp b/src/native/jawtrenderer/windows/d3d_device.cpp
deleted file mode 100644
index 45b981c270e8764d9ec31a61e70616b8af0505da..0000000000000000000000000000000000000000
--- a/src/native/jawtrenderer/windows/d3d_device.cpp
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-
-/**
- * \file d3d_device.cpp
- * \brief Direct3D device.
- * \author Sebastien Vincent
- * \date 2010
- */
-
-#include "d3d_device.h"
-
-D3DDevice::D3DDevice(HWND hwnd, LPDIRECT3D9 d3d, size_t width, size_t height,
-        bool fullscreen)
-{
-    HRESULT ret = 0;
-    D3DPRESENT_PARAMETERS settings;
-    D3DDISPLAYMODE dmode;
-
-    ZeroMemory(&settings, sizeof(D3DPRESENT_PARAMETERS));
-
-    ret = d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &dmode);
-    if(FAILED(ret))
-    {
-        return;
-    }
-
-    settings.BackBufferWidth = width;
-    settings.BackBufferHeight = height;
-    settings.BackBufferFormat = fullscreen ? dmode.Format : D3DFMT_UNKNOWN;
-    settings.BackBufferCount = 1;
-    //settings.hDeviceWindow = hwnd;
-    settings.Windowed = !fullscreen;
-    settings.SwapEffect = D3DSWAPEFFECT_DISCARD;
-
-    if(SUCCEEDED(d3d->CheckDeviceMultiSampleType(D3DADAPTER_DEFAULT, 
-                    D3DDEVTYPE_HAL, settings.BackBufferFormat, !fullscreen,
-                    D3DMULTISAMPLE_2_SAMPLES, NULL)))
-    {
-        settings.MultiSampleQuality = D3DMULTISAMPLE_2_SAMPLES;
-    }
-    else
-    {
-        settings.MultiSampleQuality = D3DMULTISAMPLE_NONE;
-    }
-
-    settings.EnableAutoDepthStencil = false;
-    settings.AutoDepthStencilFormat = D3DFMT_D16;
-    settings.FullScreen_RefreshRateInHz = 0;
-    settings.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; //0;
-    settings.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
-
-    ret = d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
-            D3DCREATE_SOFTWARE_VERTEXPROCESSING, &settings, &m_device);
-
-    if(FAILED(ret))
-    {
-        m_device = NULL;
-        /* TODO */
-        return;
-    }
-
-    /* copy settings */
-    memcpy(&m_settings, &settings, sizeof(settings));
-}
-
-D3DDevice::~D3DDevice()
-{
-    if(m_backSurface)
-    {
-        //m_backSurface->Release();
-    }
-
-    if(m_device)
-    {
-        m_device->Release();
-        m_device = NULL;
-    }
-}
-
-LPDIRECT3DDEVICE9 D3DDevice::getDevice() const
-{
-    return m_device;
-}
-
-bool D3DDevice::validate()
-{
-    HRESULT ret = 0;
-
-    ret = m_device->TestCooperativeLevel();
-
-    if(FAILED(ret))
-    {
-        /* device is lost (window not shown) */
-        if(ret == D3DERR_DEVICELOST)
-        {
-            return false;
-        }
-
-        /* ready to reset */
-        if(ret == D3DERR_DEVICENOTRESET)
-        {
-            /* XXX in this case we simply delete and recreate device since
-             * it always failed to Reset in JAWT but not in pure Windows
-             * binary
-             */
-
-#if 0
-            if(m_backSurface)
-            {
-                m_backSurface->Release();
-                m_backSurface = NULL;
-            }
-
-            ret = m_device->Reset(&m_settings);
-
-            if(FAILED(ret))
-            {
-                return false;
-            }
-
-            ret = m_device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO,
-                    &m_backSurface);
-
-            if(FAILED(ret))
-            {
-                return false;
-            }
-#endif
-        }
-    }
-    return true;
-}
-
-D3DSurface* D3DDevice::createSurface(size_t width, size_t height)
-{
-    D3DSurface* ret = NULL;
-
-    ret = new D3DSurface(getDevice(), width, height);
-
-    if(ret->getSurface())
-    {
-        return ret;
-    }
-    else
-    {
-        /* problem allocating surface */
-        delete ret;
-        return NULL;
-    }
-}
-
-void D3DDevice::render(D3DSurface* surface)
-{
-    HRESULT ret = 0;
-    LPDIRECT3DSURFACE9 surfacePointer = surface->getSurface();
-
-    if(!surfacePointer)
-    {
-        return;
-    }
-
-    /* clear the back buffer */
-    m_device->Clear(0, 0, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0xff, 0xff, 0xff),
-            0.0f, 0);
-
-    /* Get the back buffer */
-    ret = m_device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO,
-            &m_backSurface);
-    if(FAILED(ret))
-    {
-        return;
-    }
-
-    ret = m_device->BeginScene();
-    if(FAILED(ret))
-    {
-        return;
-    }
-
-    /* copy content on surface */
-    m_device->UpdateSurface(surfacePointer, NULL, m_backSurface, NULL);
-
-    /* finish scene and cleanup */
-    m_device->EndScene();
-    m_backSurface->Release();
-    m_backSurface = NULL;
-
-    /* present the back buffer to the display adapter to be drawn */
-    m_device->Present(NULL, NULL, NULL, NULL);
-}
-
diff --git a/src/native/jawtrenderer/windows/d3d_device.h b/src/native/jawtrenderer/windows/d3d_device.h
deleted file mode 100644
index 61a191cf32689fde255b5876432effe52d49ca63..0000000000000000000000000000000000000000
--- a/src/native/jawtrenderer/windows/d3d_device.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-
-/**
- * \file d3d_device.h
- * \brief Direct3D device.
- * \author Sebastien Vincent
- * \date 2010
- */
-
-#ifndef D3D_DEVICE_H
-#define D3D_DEVICE_H
-
-#include <cstdlib>
-
-#include <d3d9.h>
-#include <d3dx9.h>
-
-#include "d3d_surface.h"
-
-/**
- * \class D3DDevice
- * \brief Direct3D device.
- *
- * It is used to render contents on screen.
- */
-class D3DDevice
-{
-    public:
-        /**
-         * \brief Constructor.
-         * \param hwnd Handle of the Window
-         * \param d3d raw Direct3D context
-         * \param width width of the future device
-         * \param height height of the future device
-         * \param fullscreen create device for fullscreen mode
-         */
-        D3DDevice(HWND hwnd, LPDIRECT3D9 d3d, size_t width, size_t height, bool fullscreen);
-
-        /**
-         * \brief Destructor.
-         */
-        ~D3DDevice();
-
-        /**
-         * \brief Get raw Direct3D device pointer.
-         * \return Direct3D device pointer
-         */
-        LPDIRECT3DDEVICE9 getDevice() const;
-
-        /**
-         * \brief Validate the device.
-         * \return true if validation succeed, false otherwise
-         */
-        bool validate();
-
-        /**
-         * \brief Create a surface.
-         * \param width width of the surface
-         * \param height height of the surface
-         * \return surface or NULL if problem
-         */
-        D3DSurface* createSurface(size_t width, size_t height);
-
-        /**
-         * \brief Render a surface on the screen.
-         * \param surface surface to render on the screen
-         */
-        void render(D3DSurface* surface);
-
-    private:
-        /**
-         * \brief Raw Direct3D device.
-         */
-        LPDIRECT3DDEVICE9 m_device;
-
-        /**
-         * \brief Settings of the device.
-         */
-        D3DPRESENT_PARAMETERS m_settings;
-
-        /**
-         * \brief Back surface.
-         */
-        LPDIRECT3DSURFACE9 m_backSurface;
-
-        /**
-         * \brief Width of the device.
-         */
-        size_t m_width;
-
-        /**
-         * \brief Height of the device.
-         */
-        size_t m_height;
-};
-
-#endif /* D3D_DEVICE_H */
-
diff --git a/src/native/jawtrenderer/windows/d3d_surface.cpp b/src/native/jawtrenderer/windows/d3d_surface.cpp
deleted file mode 100644
index c892e02e4cb905ef31c4569bed60590f3056f6b2..0000000000000000000000000000000000000000
--- a/src/native/jawtrenderer/windows/d3d_surface.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-
-/**
- * \file d3d_surface.cpp
- * \brief Direct3D surface.
- * \author Sebastien Vincent
- * \date 2010
- */
-
-#include "d3d_surface.h"
-#include "d3dx9_utils.h"
-
-D3DSurface::D3DSurface(LPDIRECT3DDEVICE9 device, size_t width, size_t height)
-{
-    HRESULT ret = device->CreateOffscreenPlainSurface(width, height,
-            D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &m_surface, NULL);
-
-    if(FAILED(ret))
-    {
-        m_surface = NULL;
-        return;
-    }
-
-    m_width = width;
-    m_height = height;
-}
-
-D3DSurface::~D3DSurface()
-{
-    if(m_surface)
-    {
-        m_surface->Release();
-        m_surface = NULL;
-    }
-}
-
-LPDIRECT3DSURFACE9 D3DSurface::getSurface() const
-{
-    return m_surface;
-}
-
-size_t D3DSurface::getWidth()
-{
-    return m_width;
-}
-
-size_t D3DSurface::getHeight()
-{
-    return m_height;
-}
-
-bool D3DSurface::loadData(char *data, size_t width, size_t height)
-{
-    HRESULT ret = 0;
-    RECT rect;
-
-    rect.left = 0;
-    rect.top = 0;
-    rect.right = width;
-    rect.bottom = height;
-
-    if(!m_surface)
-    {
-        return false;
-    }
-
-    /* load image from memory */
-    ret = D3DXLoadSurfaceFromMemory(m_surface, NULL, NULL, data, 
-            D3DFMT_A8R8G8B8, width * 4, NULL, &rect, D3DX_FILTER_NONE, NULL);
-    return !FAILED(ret);
-}
-
diff --git a/src/native/jawtrenderer/windows/d3d_surface.h b/src/native/jawtrenderer/windows/d3d_surface.h
deleted file mode 100644
index b9074f782ecc5fb4fee54ae9742f78cffc982d1c..0000000000000000000000000000000000000000
--- a/src/native/jawtrenderer/windows/d3d_surface.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-
-/**
- * \file d3d_surface.h
- * \brief Direct3D surface.
- * \author Sebastien Vincent
- * \date 2010
- */
-
-#ifndef D3D_SURFACE_H
-#define D3D_SURFACE_H
-
-#include <cstdlib>
-
-#include <d3d9.h>
-#include <d3dx9.h>
-
-class D3DDevice;
-
-/**
- * \class D3DSurface
- * \brief Direct3D surface.
- */
-class D3DSurface
-{
-    public:
-        /**
-         * \brief Constructor.
-         * \param device device that will create surface
-         * \param width width of the surface
-         * \param height height of the surface
-         */
-        D3DSurface(LPDIRECT3DDEVICE9 device, size_t width, size_t height);
-
-        /**
-         * \brief Destructor.
-         */
-        ~D3DSurface();
-
-        /**
-         * \brief Get raw pointer of Direct3D surface.
-         * \return Direct3D surface.
-         */
-        LPDIRECT3DSURFACE9 getSurface() const;
-
-        /**
-         * \brief Load data into surface.
-         * \param data array of bytes
-         * \param width width of image
-         * \param height height of image
-         * \return true if data is loaded, false otherwise
-         */
-        bool loadData(char* data, size_t width, size_t height);
-
-        /**
-         * \brief Get surface width.
-         * \return surface width
-         */
-        size_t getWidth();
-
-        /**
-         * \brief Get surface height.
-         * \return surface height
-         */
-        size_t getHeight();
-
-    private:
-        /**
-         * \brief Raw Direct3D surface.
-         */
-        LPDIRECT3DSURFACE9 m_surface;
-
-        /**
-         * \brief Width of surface.
-         */
-        size_t m_width;
-
-        /**
-         * \brief Height of surface.
-         */
-        size_t m_height;
-};
-
-#endif /* D3D_SURFACE_H */
-
diff --git a/src/native/jawtrenderer/windows/d3dx9_utils.c b/src/native/jawtrenderer/windows/d3dx9_utils.c
deleted file mode 100644
index d974f5eee6ed7da93ac33f1874d77d5b3a29856c..0000000000000000000000000000000000000000
--- a/src/native/jawtrenderer/windows/d3dx9_utils.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-
-/*
- * Copyright (C) 2009 Tony Wasserka
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- */
-
-/**
- * \file d3dx9_utils.c
- * \brief DirectX functions implementation coming from Wine project.
- * \author Wine project
- */
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <d3d9.h>
-#include <d3dx9.h>
-
-#ifdef __cplusplus
-extern "C" { /* } */
-#endif
-
-/* Following structures and functions functions comes from the Wine project.
- * There are used to avoid linking to d3dx9_xx.dll since this DLL cannot be
- * redistributed directly (it must be installed using DirectXSetup).
- */
-
-typedef enum _FormatType
-{
-    FORMAT_ARGB,   /* unsigned */
-    FORMAT_UNKNOWN
-
-} FormatType;
-
-typedef struct _PixelFormatDesc 
-{
-    D3DFORMAT format;
-    BYTE bits[4];
-    BYTE shift[4];
-    UINT bytes_per_pixel;
-    FormatType type;
-} PixelFormatDesc;
-
-/************************************************************
- * pixel format table providing info about number of bytes per pixel,
- * number of bits per channel and format type.
- *
- * Call get_format_info to request information about a specific format.
- */
-static const PixelFormatDesc formats[] =
-{
-   /* format                    bits per channel        shifts per channel   bpp   type        */
-    { D3DFMT_R8G8B8,          {  0,   8,   8,   8 },  {  0,  16,   8,   0 },   3,  FORMAT_ARGB },
-    { D3DFMT_A8R8G8B8,        {  8,   8,   8,   8 },  { 24,  16,   8,   0 },   4,  FORMAT_ARGB },
-    { D3DFMT_X8R8G8B8,        {  0,   8,   8,   8 },  {  0,  16,   8,   0 },   4,  FORMAT_ARGB },
-    { D3DFMT_A8B8G8R8,        {  8,   8,   8,   8 },  { 24,   0,   8,  16 },   4,  FORMAT_ARGB },
-    { D3DFMT_X8B8G8R8,        {  0,   8,   8,   8 },  {  0,   0,   8,  16 },   4,  FORMAT_ARGB },
-    { D3DFMT_R5G6B5,          {  0,   5,   6,   5 },  {  0,  11,   5,   0 },   2,  FORMAT_ARGB },
-    { D3DFMT_X1R5G5B5,        {  0,   5,   5,   5 },  {  0,  10,   5,   0 },   2,  FORMAT_ARGB },
-    { D3DFMT_A1R5G5B5,        {  1,   5,   5,   5 },  { 15,  10,   5,   0 },   2,  FORMAT_ARGB },
-    { D3DFMT_R3G3B2,          {  0,   3,   3,   2 },  {  0,   5,   2,   0 },   1,  FORMAT_ARGB },
-    { D3DFMT_A8R3G3B2,        {  8,   3,   3,   2 },  {  8,   5,   2,   0 },   2,  FORMAT_ARGB },
-    { D3DFMT_A4R4G4B4,        {  4,   4,   4,   4 },  { 12,   8,   4,   0 },   2,  FORMAT_ARGB },
-    { D3DFMT_X4R4G4B4,        {  0,   4,   4,   4 },  {  0,   8,   4,   0 },   2,  FORMAT_ARGB },
-    { D3DFMT_A2R10G10B10,     {  2,  10,  10,  10 },  { 30,  20,  10,   0 },   4,  FORMAT_ARGB },
-    { D3DFMT_A2B10G10R10,     {  2,  10,  10,  10 },  { 30,   0,  10,  20 },   4,  FORMAT_ARGB },
-    { D3DFMT_G16R16,          {  0,  16,  16,   0 },  {  0,   0,  16,   0 },   4,  FORMAT_ARGB },
-    { D3DFMT_A8,              {  8,   0,   0,   0 },  {  0,   0,   0,   0 },   1,  FORMAT_ARGB },
-    { D3DFMT_UNKNOWN,         {  0,   0,   0,   0 },  {  0,   0,   0,   0 },   0,  FORMAT_UNKNOWN }, /* marks last element */
-};
-
-/************************************************************
- * get_format_info
- *
- * Returns information about the specified format.
- * If the format is unsupported, it's filled with the D3DFMT_UNKNOWN desc.
- *
- * PARAMS
- *   format [I] format whose description is queried
- *   desc   [O] pointer to a StaticPixelFormatDesc structure
- *
- */
-const PixelFormatDesc *get_format_info(D3DFORMAT format)
-{
-    unsigned int i = 0;
-    while(formats[i].format != format && formats[i].format != D3DFMT_UNKNOWN) i++;
-    return &formats[i];
-}
-
-/************************************************************
- * copy_simple_data
- *
- * Copies the source buffer to the destination buffer, performing
- * any necessary format conversion and color keying.
- * Works only for ARGB formats with 1 - 4 bytes per pixel.
- */
-static void copy_simple_data(CONST BYTE *src,  UINT  srcpitch, POINT  srcsize, CONST PixelFormatDesc  *srcformat,
-                             CONST BYTE *dest, UINT destpitch, POINT destsize, CONST PixelFormatDesc *destformat,
-                             DWORD dwFilter)
-{
-    DWORD srcshift[4], destshift[4];
-    DWORD srcmask[4], destmask[4];
-    BOOL process_channel[4];
-    DWORD channels[4];
-    DWORD channelmask = 0;
-
-    UINT minwidth, minheight;
-    BYTE *srcptr, *destptr;
-    UINT i, x, y;
-
-    ZeroMemory(channels, sizeof(channels));
-    ZeroMemory(process_channel, sizeof(process_channel));
-
-    for(i = 0;i < 4;i++) {
-        /* srcshift is used to extract the _relevant_ components */
-        srcshift[i]  =  srcformat->shift[i] + max( srcformat->bits[i] - destformat->bits[i], 0);
-
-        /* destshift is used to move the components to the correct position */
-        destshift[i] = destformat->shift[i] + max(destformat->bits[i] -  srcformat->bits[i], 0);
-
-        srcmask[i]  = ((1 <<  srcformat->bits[i]) - 1) <<  srcformat->shift[i];
-        destmask[i] = ((1 << destformat->bits[i]) - 1) << destformat->shift[i];
-
-        /* channelmask specifies bits which aren't used in the source format but in the destination one */
-        if(destformat->bits[i]) {
-            if(srcformat->bits[i]) process_channel[i] = TRUE;
-            else channelmask |= destmask[i];
-        }
-    }
-
-    minwidth  = (srcsize.x < destsize.x) ? srcsize.x : destsize.x;
-    minheight = (srcsize.y < destsize.y) ? srcsize.y : destsize.y;
-
-    for(y = 0;y < minheight;y++) {
-        srcptr  = (BYTE*)( src + y *  srcpitch);
-        destptr = (BYTE*)(dest + y * destpitch);
-        for(x = 0;x < minwidth;x++) {
-            /* extract source color components */
-            if(srcformat->type == FORMAT_ARGB) {
-                const DWORD col = *(DWORD*)srcptr;
-                for(i = 0;i < 4;i++)
-                    if(process_channel[i])
-                        channels[i] = (col & srcmask[i]) >> srcshift[i];
-            }
-
-            /* recombine the components */
-            if(destformat->type == FORMAT_ARGB) {
-                DWORD* const pixel = (DWORD*)destptr;
-                *pixel = 0;
-
-                for(i = 0;i < 4;i++) {
-                    if(process_channel[i]) {
-                        /* necessary to make sure that e.g. an X4R4G4B4 white maps to an R8G8B8 white instead of 0xf0f0f0 */
-                        signed int shift;
-                        for(shift = destshift[i]; shift > destformat->shift[i]; shift -= srcformat->bits[i]) *pixel |= channels[i] << shift;
-                        *pixel |= (channels[i] >> (destformat->shift[i] - shift)) << destformat->shift[i];
-                    }
-                }
-                *pixel |= channelmask;   /* new channels are set to their maximal value */
-            }
-            srcptr  +=  srcformat->bytes_per_pixel;
-            destptr += destformat->bytes_per_pixel;
-        }
-    }
-}
-
-/************************************************************
- * D3DXLoadSurfaceFromMemory
- *
- * Loads data from a given memory chunk into a surface,
- * applying any of the specified filters.
- *
- * PARAMS
- *   pDestSurface [I] pointer to the surface
- *   pDestPalette [I] palette to use
- *   pDestRect    [I] to be filled area of the surface
- *   pSrcMemory   [I] pointer to the source data
- *   SrcFormat    [I] format of the source pixel data
- *   SrcPitch     [I] number of bytes in a row
- *   pSrcPalette  [I] palette used in the source image
- *   pSrcRect     [I] area of the source data to load
- *   dwFilter     [I] filter to apply on stretching
- *   Colorkey     [I] colorkey
- *
- * RETURNS
- *   Success: D3D_OK, if we successfully load the pixel data into our surface or
- *                    if pSrcMemory is NULL but the other parameters are valid
- *   Failure: D3DERR_INVALIDCALL, if pDestSurface, SrcPitch or pSrcRect are NULL or
- *                                if SrcFormat is an invalid format (other than D3DFMT_UNKNOWN)
- *            D3DXERR_INVALIDDATA, if we fail to lock pDestSurface
- *            E_FAIL, if SrcFormat is D3DFMT_UNKNOWN or the dimensions of pSrcRect are invalid
- *
- * NOTES
- *   pSrcRect specifies the dimensions of the source data;
- *   negative values for pSrcRect are allowed as we're only looking at the width and height anyway.
- *
- */
-HRESULT WINAPI D3DXLoadSurfaceFromMemory(LPDIRECT3DSURFACE9 pDestSurface,
-                                         CONST PALETTEENTRY *pDestPalette,
-                                         CONST RECT *pDestRect,
-                                         LPCVOID pSrcMemory,
-                                         D3DFORMAT SrcFormat,
-                                         UINT SrcPitch,
-                                         CONST PALETTEENTRY *pSrcPalette,
-                                         CONST RECT *pSrcRect,
-                                         DWORD dwFilter,
-                                         D3DCOLOR Colorkey)
-{
-    CONST PixelFormatDesc *srcformatdesc, *destformatdesc;
-    D3DSURFACE_DESC surfdesc;
-    D3DLOCKED_RECT lockrect;
-    POINT srcsize, destsize;
-    HRESULT hr;
-
-    //TRACE("(%p, %p, %p, %p, %x, %u, %p, %p %u, %#x)\n", pDestSurface, pDestPalette, pDestRect, pSrcMemory,
-    //    SrcFormat, SrcPitch, pSrcPalette, pSrcRect, dwFilter, Colorkey);
-
-    if( !pDestSurface || !pSrcMemory || !pSrcRect ) return D3DERR_INVALIDCALL;
-    if(SrcFormat == D3DFMT_UNKNOWN || pSrcRect->left >= pSrcRect->right || pSrcRect->top >= pSrcRect->bottom) return E_FAIL;
-
-    if(dwFilter != D3DX_FILTER_NONE) return E_NOTIMPL;
-
-    IDirect3DSurface9_GetDesc(pDestSurface, &surfdesc);
-
-    srcformatdesc = get_format_info(SrcFormat);
-    destformatdesc = get_format_info(surfdesc.Format);
-    if( srcformatdesc->type == FORMAT_UNKNOWN ||  srcformatdesc->bytes_per_pixel > 4) return E_NOTIMPL;
-    if(destformatdesc->type == FORMAT_UNKNOWN || destformatdesc->bytes_per_pixel > 4) return E_NOTIMPL;
-
-    srcsize.x = pSrcRect->right - pSrcRect->left;
-    srcsize.y = pSrcRect->bottom - pSrcRect->top;
-    if( !pDestRect ) {
-        destsize.x = surfdesc.Width;
-        destsize.y = surfdesc.Height;
-    } else {
-        destsize.x = pDestRect->right - pDestRect->left;
-        destsize.y = pDestRect->bottom - pDestRect->top;
-    }
-
-    hr = IDirect3DSurface9_LockRect(pDestSurface, &lockrect, pDestRect, 0);
-    if(FAILED(hr)) return D3DXERR_INVALIDDATA;
-
-    copy_simple_data((CONST BYTE*)pSrcMemory, SrcPitch, srcsize, srcformatdesc,
-                     (CONST BYTE*)lockrect.pBits, lockrect.Pitch, destsize, destformatdesc,
-                     dwFilter);
-
-    IDirect3DSurface9_UnlockRect(pDestSurface);
-    return D3D_OK;
-}
-
-#ifdef __cplusplus
-}
-#endif
-
diff --git a/src/native/jawtrenderer/windows/d3dx9_utils.h b/src/native/jawtrenderer/windows/d3dx9_utils.h
deleted file mode 100644
index d49457daf1272d2dd334196d7e0fcd645ac564ec..0000000000000000000000000000000000000000
--- a/src/native/jawtrenderer/windows/d3dx9_utils.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-
-/*
- * Copyright (C) 2009 Tony Wasserka
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- */
-
-/**
- * \file d3dx9_utils.h
- * \brief DirectX functions implementation coming from Wine project.
- * \author Wine project
- */
-
-#ifdef __cplusplus
-extern "C" { /* } */
-#endif
-
-/************************************************************
- * D3DXLoadSurfaceFromMemory
- *
- * Loads data from a given memory chunk into a surface,
- * applying any of the specified filters.
- *
- * PARAMS
- *   pDestSurface [I] pointer to the surface
- *   pDestPalette [I] palette to use
- *   pDestRect    [I] to be filled area of the surface
- *   pSrcMemory   [I] pointer to the source data
- *   SrcFormat    [I] format of the source pixel data
- *   SrcPitch     [I] number of bytes in a row
- *   pSrcPalette  [I] palette used in the source image
- *   pSrcRect     [I] area of the source data to load
- *   dwFilter     [I] filter to apply on stretching
- *   Colorkey     [I] colorkey
- *
- * RETURNS
- *   Success: D3D_OK, if we successfully load the pixel data into our surface or
- *                    if pSrcMemory is NULL but the other parameters are valid
- *   Failure: D3DERR_INVALIDCALL, if pDestSurface, SrcPitch or pSrcRect are NULL or
- *                                if SrcFormat is an invalid format (other than D3DFMT_UNKNOWN)
- *            D3DXERR_INVALIDDATA, if we fail to lock pDestSurface
- *            E_FAIL, if SrcFormat is D3DFMT_UNKNOWN or the dimensions of pSrcRect are invalid
- *
- * NOTES
- *   pSrcRect specifies the dimensions of the source data;
- *   negative values for pSrcRect are allowed as we're only looking at the width and height anyway.
- *
- */
-HRESULT WINAPI D3DXLoadSurfaceFromMemory(LPDIRECT3DSURFACE9 pDestSurface,
-                                         CONST PALETTEENTRY *pDestPalette,
-                                         CONST RECT *pDestRect,
-                                         LPCVOID pSrcMemory,
-                                         D3DFORMAT SrcFormat,
-                                         UINT SrcPitch,
-                                         CONST PALETTEENTRY *pSrcPalette,
-                                         CONST RECT *pSrcRect,
-                                         DWORD dwFilter,
-                                         D3DCOLOR Colorkey);
-
-#ifdef __cplusplus
-}
-#endif
-
diff --git a/src/org/jitsi/impl/neomedia/AudioMediaStreamImpl.java b/src/org/jitsi/impl/neomedia/AudioMediaStreamImpl.java
index 26f6d1792904ccdc84728a52dacaa10d182158af..dafadd8be2ba045313cec640e7f9df546cc971ea 100644
--- a/src/org/jitsi/impl/neomedia/AudioMediaStreamImpl.java
+++ b/src/org/jitsi/impl/neomedia/AudioMediaStreamImpl.java
@@ -35,7 +35,7 @@
 public class AudioMediaStreamImpl
     extends MediaStreamImpl
     implements AudioMediaStream,
-                PropertyChangeListener
+               PropertyChangeListener
 {
 
     /**
@@ -73,21 +73,22 @@ public class AudioMediaStreamImpl
         = Logger.getLogger(AudioMediaStreamImpl.class);
 
     /**
-     * A property change notifier which will inform this stream if a selected
-     * audio device (capture, playback or notification device) has changed. We
-     * want to listen to these events, especially for those generated after the
-     * audio system has changed.
+     * A <tt>PropertyChangeNotifier<tt> which will inform this
+     * <tt>AudioStream</tt> if a selected audio device (capture, playback or
+     * notification device) has changed. We want to listen to these events,
+     * especially for those generated after the <tt>AudioSystem</tt> has
+     * changed.
      */
-    private PropertyChangeNotifier audioSystemChangeNotifier;
+    private final PropertyChangeNotifier audioSystemChangeNotifier;
 
     /**
      * The listener that gets notified of changes in the audio level of
      * remote conference participants.
      */
-    private CsrcAudioLevelListener csrcAudioLevelListener = null;
+    private CsrcAudioLevelListener csrcAudioLevelListener;
 
     /**
-     * The list of DTMF listeners;
+     * The list of DTMF listeners.
      */
     private final List<DTMFListener> dtmfListeners
         = new ArrayList<DTMFListener>();
@@ -95,7 +96,21 @@ public class AudioMediaStreamImpl
     /**
      * The transformer that we use for sending and receiving DTMF packets.
      */
-    private DtmfTransformEngine dtmfTransfrmEngine ;
+    private DtmfTransformEngine dtmfTransfrmEngine;
+
+    /**
+     * The listener which has been set on this instance to get notified of
+     * changes in the levels of the audio that the local peer/user is sending to
+     * the remote peer(s).
+     */
+    private SimpleAudioLevelListener localUserAudioLevelListener;
+
+    /**
+     * The listener which has been set on this instance to get notified of
+     * changes in the levels of the audios that the local peer/user is receiving
+     * from the remote peer(s).
+     */
+    private SimpleAudioLevelListener streamAudioLevelListener;
 
     /**
      * Initializes a new <tt>AudioMediaStreamImpl</tt> instance which will use
@@ -109,20 +124,23 @@ public class AudioMediaStreamImpl
      * <tt>StreamConnector</tt>
      * @param srtpControl a control which is already created, used to control
      * the srtp operations.
-     * @param audioSystemChangeNotifier A property change notifier which will
-     * inform this stream if a selected audio device (capture, playback or
-     * notification device) has changed. We want to listen to these events,
-     * especially for those generated after the audio system has changed.
      */
-    public AudioMediaStreamImpl(StreamConnector connector,
-                                MediaDevice     device,
-                                SrtpControl srtpControl,
-                                PropertyChangeNotifier audioSystemChangeNotifier
-                                )
+    public AudioMediaStreamImpl(
+            StreamConnector connector,
+            MediaDevice device,
+            SrtpControl srtpControl)
     {
         super(connector, device, srtpControl);
-        this.audioSystemChangeNotifier = audioSystemChangeNotifier;
-        this.audioSystemChangeNotifier.addPropertyChangeListener(this);
+
+        MediaService mediaService = LibJitsi.getMediaService();
+
+        if (mediaService instanceof PropertyChangeNotifier)
+        {
+            audioSystemChangeNotifier = (PropertyChangeNotifier) mediaService;
+            audioSystemChangeNotifier.addPropertyChangeListener(this);
+        }
+        else
+            audioSystemChangeNotifier = null;
     }
 
     /**
@@ -167,6 +185,23 @@ public void addRTPExtension(byte extensionID, RTPExtension rtpExtension)
         }
     }
 
+    /**
+     * Delivers the <tt>audioLevels</tt> map to whoever's interested. This
+     * method is meant for use primarily by the transform engine handling
+     * incoming RTP packets (currently <tt>CsrcTransformEngine</tt>).
+     *
+     * @param audioLevels a array mapping CSRC IDs to audio levels in
+     * consecutive elements.
+     */
+    public void audioLevelsReceived(long[] audioLevels)
+    {
+        CsrcAudioLevelListener csrcAudioLevelListener
+            = this.csrcAudioLevelListener;
+
+        if (csrcAudioLevelListener != null)
+            csrcAudioLevelListener.audioLevelsReceived(audioLevels);
+    }
+
     /**
      * Releases the resources allocated by this instance in the course of its
      * execution and prepares it to be garbage collected.
@@ -180,10 +215,12 @@ public void close()
 
         if(dtmfTransfrmEngine != null)
         {
-           dtmfTransfrmEngine = null;
+            dtmfTransfrmEngine.close();
+            dtmfTransfrmEngine = null;
         }
 
-        this.audioSystemChangeNotifier.removePropertyChangeListener(this);
+        if (audioSystemChangeNotifier != null)
+            audioSystemChangeNotifier.removePropertyChangeListener(this);
     }
 
     /**
@@ -264,20 +301,44 @@ protected DtmfTransformEngine createDtmfTransformEngine()
     }
 
     /**
-     * Delivers the <tt>audioLevels</tt> map to whoever's interested. This
-     * method is meant for use primarily by the transform engine handling
-     * incoming RTP packets (currently <tt>CsrcTransformEngine</tt>).
+     * {@inheritDoc}
      *
-     * @param audioLevels a array mapping CSRC IDs to audio levels in
-     * consecutive elements.
+     * Makes sure that {@link #localUserAudioLevelListener} and
+     * {@link #streamAudioLevelListener} which have been set on this
+     * <tt>AudioMediaStream</tt> will be automatically updated when a new
+     * <tt>MediaDevice</tt> is set on this instance.
      */
-    public void fireConferenceAudioLevelEvent(long[] audioLevels)
+    @Override
+    protected void deviceSessionChanged(
+            MediaDeviceSession oldValue,
+            MediaDeviceSession newValue)
     {
-        CsrcAudioLevelListener csrcAudioLevelListener
-            = this.csrcAudioLevelListener;
+        if (oldValue != null)
+        {
+            AudioMediaDeviceSession deviceSession
+                = (AudioMediaDeviceSession) oldValue;
 
-        if (csrcAudioLevelListener != null)
-            csrcAudioLevelListener.audioLevelsReceived(audioLevels);
+            if (localUserAudioLevelListener != null)
+                deviceSession.setLocalUserAudioLevelListener(null);
+            if (streamAudioLevelListener != null)
+                deviceSession.setStreamAudioLevelListener(null);
+        }
+        if (newValue != null)
+        {
+            AudioMediaDeviceSession deviceSession
+                = (AudioMediaDeviceSession) newValue;
+
+            if (localUserAudioLevelListener != null)
+            {
+                deviceSession.setLocalUserAudioLevelListener(
+                        localUserAudioLevelListener);
+            }
+            if (streamAudioLevelListener != null)
+            {
+                deviceSession.setStreamAudioLevelListener(
+                        streamAudioLevelListener);
+            }
+        }
     }
 
     /**
@@ -352,14 +413,20 @@ protected int getPriority()
     /**
      * Receives and reacts to property change events: if the selected device
      * (for capture, playback or notifications) has changed, then create or
-     * recreate the streams in order to use it.
-     * We want to listen to these events, especially for those generated after
-     * the audio system has changed.
+     * recreate the streams in order to use it. We want to listen to these
+     * events, especially for those generated after the audio system has
+     * changed.
      *
-     * @param evt The event which may contain a audio system change event.
+     * @param ev The event which may contain a audio system change event.
      */
-    public void propertyChange(PropertyChangeEvent evt)
+    public void propertyChange(PropertyChangeEvent ev)
     {
+        /*
+         * FIXME It is very wrong to do the following upon every
+         * PropertyChangeEvent fired by MediaServiceImpl. Moreover, it does not
+         * seem right that we'd want to start this MediaStream upon a
+         * PropertyChangeEvent (regardless of its specifics).
+         */
         if (sendStreamsAreCreated)
             recreateSendStreams();
         else
@@ -421,7 +488,7 @@ public void removeDTMFListener(DTMFListener listener)
      */
     public void setCsrcAudioLevelListener(CsrcAudioLevelListener listener)
     {
-        this.csrcAudioLevelListener = listener;
+        csrcAudioLevelListener = listener;
     }
 
     /**
@@ -434,9 +501,20 @@ public void setCsrcAudioLevelListener(CsrcAudioLevelListener listener)
      * measurements.
      */
     public void setLocalUserAudioLevelListener(
-                                            SimpleAudioLevelListener listener)
+            SimpleAudioLevelListener listener)
     {
-        getDeviceSession().setLocalUserAudioLevelListener(listener);
+        if (localUserAudioLevelListener != listener)
+        {
+            localUserAudioLevelListener = listener;
+
+            AudioMediaDeviceSession deviceSession = getDeviceSession();
+
+            if (deviceSession != null)
+            {
+                deviceSession.setLocalUserAudioLevelListener(
+                        localUserAudioLevelListener);
+            }
+        }
     }
 
     /**
@@ -450,7 +528,18 @@ public void setLocalUserAudioLevelListener(
      */
     public void setStreamAudioLevelListener(SimpleAudioLevelListener listener)
     {
-        getDeviceSession().setStreamAudioLevelListener(listener);
+        if (streamAudioLevelListener != listener)
+        {
+            streamAudioLevelListener = listener;
+
+            AudioMediaDeviceSession deviceSession = getDeviceSession();
+
+            if (deviceSession != null)
+            {
+                deviceSession.setStreamAudioLevelListener(
+                        streamAudioLevelListener);
+            }
+        }
     }
 
     /**
@@ -518,8 +607,8 @@ public void stopSendingDTMF(DTMFMethod dtmfMethod)
         switch (dtmfMethod)
         {
         case INBAND_DTMF:
-            // The INBAND DTMF is send by impluse of constant duration and
-            // does not need to be stopped explecitely.
+            // The INBAND DTMF is sent by impluse of constant duration and does
+            // not need to be stopped explicitly.
             break;
 
         case RTP_DTMF:
@@ -528,7 +617,7 @@ public void stopSendingDTMF(DTMFMethod dtmfMethod)
             break;
 
         case SIP_INFO_DTMF:
-            // The SIP-INFO DTMF is not managed directly by the
+            // The SIP-INFO DTMF is managed directly by the
             // OperationSetDTMFSipImpl.
             break;
 
diff --git a/src/org/jitsi/impl/neomedia/MediaServiceImpl.java b/src/org/jitsi/impl/neomedia/MediaServiceImpl.java
index 438f844e6ad84a0e9c9538af88b156e6400fd972..861ca1a2337a735f43d718c9c3e5ffca7a0f1ecc 100644
--- a/src/org/jitsi/impl/neomedia/MediaServiceImpl.java
+++ b/src/org/jitsi/impl/neomedia/MediaServiceImpl.java
@@ -359,8 +359,7 @@ else if ((device != null) && !mediaType.equals(device.getMediaType()))
         switch (mediaType)
         {
         case AUDIO:
-            return
-                new AudioMediaStreamImpl(connector, device, srtpControl, this);
+            return new AudioMediaStreamImpl(connector, device, srtpControl);
         case VIDEO:
             return new VideoMediaStreamImpl(connector, device, srtpControl);
         default:
@@ -1006,8 +1005,10 @@ public Object getVideoPreviewComponent(
         final JComponent videoContainer = new VideoContainer(noPreview, false);
 
         if ((preferredWidth > 0) && (preferredHeight > 0))
+        {
             videoContainer.setPreferredSize(
                     new Dimension(preferredWidth, preferredHeight));
+        }
 
         try
         {
@@ -1015,7 +1016,7 @@ public Object getVideoPreviewComponent(
 
             if ((device != null) &&
                     ((captureDeviceInfo
-                                = ((MediaDeviceImpl)device)
+                                = ((MediaDeviceImpl) device)
                                     .getCaptureDeviceInfo())
                             != null))
             {
@@ -1059,7 +1060,8 @@ public void controllerUpdate(ControllerEvent event)
         {
             if (t instanceof ThreadDeath)
                 throw (ThreadDeath) t;
-            logger.error("Failed to create video preview", t);
+            else
+                logger.error("Failed to create video preview", t);
         }
 
         return videoContainer;
@@ -1231,8 +1233,13 @@ public void windowClosing(WindowEvent event)
 
             previewContainer.add(preview);
 
-            previewContainer.revalidate();
-            previewContainer.repaint();
+            if (previewContainer.isDisplayable())
+            {
+                previewContainer.revalidate();
+                previewContainer.repaint();
+            }
+            else
+                previewContainer.doLayout();
         }
         else
             disposePlayer(player);
diff --git a/src/org/jitsi/impl/neomedia/device/AudioMediaDeviceSession.java b/src/org/jitsi/impl/neomedia/device/AudioMediaDeviceSession.java
index df731e0c4bd130ab1c0acbb9eda672c321d8a450..3548ebfd3b3cfef4fa1260bf0fae2281e250d44c 100644
--- a/src/org/jitsi/impl/neomedia/device/AudioMediaDeviceSession.java
+++ b/src/org/jitsi/impl/neomedia/device/AudioMediaDeviceSession.java
@@ -243,7 +243,7 @@ private void registerStreamAudioLevelJMFEffect(TrackControl trackControl)
     public void setLocalUserAudioLevelListener(
             SimpleAudioLevelListener listener)
     {
-        this.localUserAudioLevelEffect.setAudioLevelListener(listener);
+        localUserAudioLevelEffect.setAudioLevelListener(listener);
     }
 
     /**
@@ -261,6 +261,6 @@ public void setLocalUserAudioLevelListener(
      */
     public void setStreamAudioLevelListener(SimpleAudioLevelListener listener)
     {
-        this.streamAudioLevelEffect.setAudioLevelListener(listener);
+        streamAudioLevelEffect.setAudioLevelListener(listener);
     }
 }
diff --git a/src/org/jitsi/impl/neomedia/device/AudioMixerMediaDevice.java b/src/org/jitsi/impl/neomedia/device/AudioMixerMediaDevice.java
index 697e800003b6c92835448458909dd0c6ec3ea36a..ccd5a5ec7dc61331b01bb000315c6e5bdc7452aa 100644
--- a/src/org/jitsi/impl/neomedia/device/AudioMixerMediaDevice.java
+++ b/src/org/jitsi/impl/neomedia/device/AudioMixerMediaDevice.java
@@ -1149,7 +1149,7 @@ public void setLocalUserAudioLevelListener(SimpleAudioLevelListener l)
 
             if (l != null)
             {
-                this.localUserAudioLevelListener = l;
+                localUserAudioLevelListener = l;
 
                 // add the listener only if we are not muted
                 // this happens when holding a conversation, stream is muted
diff --git a/src/org/jitsi/impl/neomedia/device/DeviceConfiguration.java b/src/org/jitsi/impl/neomedia/device/DeviceConfiguration.java
index 85a67b23c3898c22a25202c7db7097a91f5bef29..92df100f899b782657f947e7a8c633ae35a153e7 100644
--- a/src/org/jitsi/impl/neomedia/device/DeviceConfiguration.java
+++ b/src/org/jitsi/impl/neomedia/device/DeviceConfiguration.java
@@ -67,11 +67,11 @@ public class DeviceConfiguration
     private static final String[] CUSTOM_RENDERERS
         = new String[]
         {
-            OSUtils.IS_ANDROID ? "org.jitsi.impl.neomedia.jmfext.media.renderer.audio.AudioTrackRenderer" : null,
-            OSUtils.IS_ANDROID ? "org.jitsi.impl.neomedia.jmfext.media.renderer.audio.OpenSLESRenderer" : null,
+            OSUtils.IS_ANDROID ? ".audio.AudioTrackRenderer" : null,
+            OSUtils.IS_ANDROID ? ".audio.OpenSLESRenderer" : null,
             OSUtils.IS_LINUX ? ".audio.PulseAudioRenderer" : null,
             OSUtils.IS_ANDROID ? null : ".audio.PortAudioRenderer",
-            "net.java.sip.communicator.impl.neomedia.jmfext.media.renderer.video.JAWTRenderer"
+            ".video.JAWTRenderer"
         };
 
     /**
diff --git a/src/org/jitsi/impl/neomedia/format/MediaFormatImpl.java b/src/org/jitsi/impl/neomedia/format/MediaFormatImpl.java
index 29dc9cee58efb9bd2ade1d94f58a1f84ebba5518..8aa72515fd365a64f3379544d6d74e14ea86bbb0 100644
--- a/src/org/jitsi/impl/neomedia/format/MediaFormatImpl.java
+++ b/src/org/jitsi/impl/neomedia/format/MediaFormatImpl.java
@@ -39,14 +39,6 @@ public abstract class MediaFormatImpl<T extends Format>
     static final Map<String, String> EMPTY_FORMAT_PARAMETERS
         = Collections.emptyMap();
 
-    /**
-     * The value of the <tt>codecSettings</tt> property of
-     * <tt>MediaFormatImpl</tt> when no codec-specific settings.
-     * Explicitly defined in order to reduce unnecessary allocations.
-     */
-    static final Map<String, String> EMPTY_CODEC_SETTINGS
-        = Collections.emptyMap();
-
     /**
      * The name of the <tt>encoding</tt> property of <tt>MediaFormatImpl</tt>.
      */
@@ -58,11 +50,6 @@ public abstract class MediaFormatImpl<T extends Format>
      */
     public static final String FORMAT_PARAMETERS_PNAME = "fmtps";
 
-    /**
-     * The additional codec settings.
-     */
-    private Map<String, String> codecSettings = EMPTY_CODEC_SETTINGS;
-
     /**
      * Creates a new <tt>MediaFormat</tt> instance for a specific JMF
      * <tt>Format</tt>.
@@ -96,7 +83,7 @@ else if (format instanceof VideoFormat)
      * @param clockRate the clock rate of the new instance
      * @param formatParameters the set of format-specific parameters of the new
      * instance
-     * @param advancedAttrs advanced attributes of the new instance
+     * @param advancedAttributess advanced attributes of the new instance
      * @return a new <tt>MediaFormat</tt> instance for the specified JMF
      * <tt>Format</tt> and with the specified clock rate and set of
      * format-specific parameters
@@ -105,7 +92,7 @@ public static MediaFormatImpl<? extends Format> createInstance(
             Format format,
             double clockRate,
             Map<String, String> formatParameters,
-            Map<String, String> advancedAttrs)
+            Map<String, String> advancedAttributess)
     {
         if (format instanceof AudioFormat)
         {
@@ -122,88 +109,22 @@ public static MediaFormatImpl<? extends Format> createInstance(
                         (AudioFormat)
                             clockRateAudioFormat.intersects(audioFormat),
                         formatParameters,
-                        advancedAttrs);
+                        advancedAttributess);
         }
         else if (format instanceof VideoFormat)
+        {
             return
                 new VideoMediaFormatImpl(
                         (VideoFormat) format,
                         clockRate,
                         -1,
                         formatParameters,
-                        advancedAttrs);
+                        advancedAttributess);
+        }
         else
             return null;
     }
 
-    /**
-     * Determines whether a specific set of advanced attributes is equal to
-     * another set of advanced attributes in the sense that they define an equal
-     * number of parameters and assign them equal values. Since the values are
-     * <tt>String</tt>s, presumes that a value of <tt>null</tt> is equal to the
-     * empty <tt>String</tt>.
-     * <p>
-     *
-     * @param adv the first set of advanced attributes to be tested for
-     * equality
-     * @param adv2 the second set of advanced attributes to be tested for
-     * equality
-     * @return <tt>true</tt> if the specified sets of advanced attributes
-     * equal; <tt>false</tt>, otherwise
-     */
-    public boolean advancedAttributesAreEqual(Map<String, String> adv,
-            Map<String, String> adv2)
-    {
-        if(adv == null && adv2 != null || adv != null && adv2 == null)
-            return false;
-
-        if(adv == null && adv2 == null)
-            return true;
-
-        if(adv.size() != adv2.size())
-            return false;
-
-        for(Map.Entry<String, String> a : adv.entrySet())
-        {
-            String value = adv2.get(a.getKey());
-            if(value == null)
-                return false;
-            else
-                if(!value.equals(a.getValue()))
-                        return false;
-        }
-        return true;
-    }
-
-    /**
-     * Determines whether a specific set of format parameters is equal to
-     * another set of format parameters in the sense that they define an equal
-     * number of parameters and assign them equal values. Since the values are
-     * <tt>String</tt>s, presumes that a value of <tt>null</tt> is equal to the
-     * empty <tt>String</tt>.
-     * <p>
-     * The two <tt>Map</tt> instances of format parameters to be checked for
-     * equality are presumed to be modifiable in the sense that if the lack of a
-     * format parameter in a given <tt>Map</tt> is equivalent to it having a
-     * specific value, an association of the format parameter to the value in
-     * question may be added to or removed from the respective <tt>Map</tt>
-     * instance for the purposes of determining equality.
-     * </p>
-     *
-     * @param fmtps1 the first set of format parameters to be tested for
-     * equality
-     * @param fmtps2 the second set of format parameters to be tested for
-     * equality
-     * @return <tt>true</tt> if the specified sets of format parameters are
-     * equal; <tt>false</tt>, otherwise
-     */
-    protected boolean formatParametersAreEqual(
-            Map<String, String> fmtps1,
-            Map<String, String> fmtps2)
-    {
-        return formatParametersAreEqual(getEncoding(), fmtps1, fmtps2);
-    }
-
     /**
      * Determines whether a specific set of format parameters is equal to
      * another set of format parameters in the sense that they define an equal
@@ -267,17 +188,15 @@ else if (!value1.equals(value2))
     }
 
     /**
-     * {@inheritDoc}
-     * <p>
-     * The default implementation of <tt>MediaFormatImpl</tt> always returns
-     * <tt>true</tt> because format parameters in general do not cause the
-     * distinction of payload types.
-     * </p>
+     * The advanced parameters of this instance which have been received
+     * via SIP/SDP or XMPP/Jingle.
      */
-    public boolean formatParametersMatch(Map<String, String> fmtps)
-    {
-        return true;
-    }
+    private final Map<String, String> advancedAttributes;
+
+    /**
+     * The additional codec settings.
+     */
+    private Map<String, String> codecSettings = EMPTY_FORMAT_PARAMETERS;
 
     /**
      * The JMF <tt>Format</tt> this instance wraps and provides an
@@ -291,12 +210,6 @@ public boolean formatParametersMatch(Map<String, String> fmtps)
      */
     private final Map<String, String> formatParameters;
 
-    /**
-     * The advanced parameters of this instance which have been received
-     * via SIP/SDP or XMPP/Jingle.
-     */
-    private final Map<String, String> advancedParameters;
-
     /**
      * Initializes a new <tt>MediaFormatImpl</tt> instance which is to provide
      * an implementation of <tt>MediaFormat</tt> for a specific <tt>Format</tt>.
@@ -318,13 +231,13 @@ protected MediaFormatImpl(T format)
      * implementation of <tt>MediaFormat</tt> for
      * @param formatParameters any codec-specific parameters that have been
      * received via SIP/SDP or XMPP/Jingle
-     * @param advancedParameters any parameters that have been
+     * @param advancedAttributes any parameters that have been
      * received via SIP/SDP or XMPP/Jingle
      */
     protected MediaFormatImpl(
             T format,
             Map<String, String> formatParameters,
-            Map<String, String> advancedParameters)
+            Map<String, String> advancedAttributes)
     {
         if (format == null)
             throw new NullPointerException("format");
@@ -334,10 +247,49 @@ protected MediaFormatImpl(
             = ((formatParameters == null) || formatParameters.isEmpty())
                 ? EMPTY_FORMAT_PARAMETERS
                 : new HashMap<String, String>(formatParameters);
-        this.advancedParameters
-            = ((advancedParameters == null) || advancedParameters.isEmpty())
+        this.advancedAttributes
+            = ((advancedAttributes == null) || advancedAttributes.isEmpty())
                 ? EMPTY_FORMAT_PARAMETERS
-                : new HashMap<String, String>(advancedParameters);
+                : new HashMap<String, String>(advancedAttributes);
+    }
+
+    /**
+     * Determines whether a specific set of advanced attributes is equal to
+     * another set of advanced attributes in the sense that they define an equal
+     * number of parameters and assign them equal values. Since the values are
+     * <tt>String</tt>s, presumes that a value of <tt>null</tt> is equal to the
+     * empty <tt>String</tt>.
+     * <p>
+     *
+     * @param adv the first set of advanced attributes to be tested for
+     * equality
+     * @param adv2 the second set of advanced attributes to be tested for
+     * equality
+     * @return <tt>true</tt> if the specified sets of advanced attributes
+     * equal; <tt>false</tt>, otherwise
+     */
+    public boolean advancedAttributesAreEqual(Map<String, String> adv,
+            Map<String, String> adv2)
+    {
+        if(adv == null && adv2 != null || adv != null && adv2 == null)
+            return false;
+
+        if(adv == null && adv2 == null)
+            return true;
+
+        if(adv.size() != adv2.size())
+            return false;
+
+        for(Map.Entry<String, String> a : adv.entrySet())
+        {
+            String value = adv2.get(a.getKey());
+            if(value == null)
+                return false;
+            else
+                if(!value.equals(a.getValue()))
+                        return false;
+        }
+        return true;
     }
 
     /**
@@ -368,6 +320,94 @@ && formatParametersAreEqual(
                         mediaFormatImpl.getFormatParameters());
     }
 
+    /**
+     * Determines whether a specific set of format parameters is equal to
+     * another set of format parameters in the sense that they define an equal
+     * number of parameters and assign them equal values. Since the values are
+     * <tt>String</tt>s, presumes that a value of <tt>null</tt> is equal to the
+     * empty <tt>String</tt>.
+     * <p>
+     * The two <tt>Map</tt> instances of format parameters to be checked for
+     * equality are presumed to be modifiable in the sense that if the lack of a
+     * format parameter in a given <tt>Map</tt> is equivalent to it having a
+     * specific value, an association of the format parameter to the value in
+     * question may be added to or removed from the respective <tt>Map</tt>
+     * instance for the purposes of determining equality.
+     * </p>
+     *
+     * @param fmtps1 the first set of format parameters to be tested for
+     * equality
+     * @param fmtps2 the second set of format parameters to be tested for
+     * equality
+     * @return <tt>true</tt> if the specified sets of format parameters are
+     * equal; <tt>false</tt>, otherwise
+     */
+    protected boolean formatParametersAreEqual(
+            Map<String, String> fmtps1,
+            Map<String, String> fmtps2)
+    {
+        return formatParametersAreEqual(getEncoding(), fmtps1, fmtps2);
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * The default implementation of <tt>MediaFormatImpl</tt> always returns
+     * <tt>true</tt> because format parameters in general do not cause the
+     * distinction of payload types.
+     * </p>
+     */
+    public boolean formatParametersMatch(Map<String, String> fmtps)
+    {
+        return true;
+    }
+
+    /**
+     * Returns additional codec settings.
+     *
+     * @return additional settings represented by a map.
+     */
+    public Map<String, String> getAdditionalCodecSettings()
+    {
+        return codecSettings;
+    }
+
+    /**
+     * Implements MediaFormat#getAdvancedAttributes(). Returns a copy of the
+     * attribute properties of this instance. Modifications to the returned Map
+     * do no affect the format properties of this instance.
+     *
+     * @return a copy of the attribute properties of this instance.
+     * Modifications to the returned Map do no affect the format properties of
+     * this instance.
+     */
+    public Map<String, String> getAdvancedAttributes()
+    {
+        return (advancedAttributes == EMPTY_FORMAT_PARAMETERS)
+                ? EMPTY_FORMAT_PARAMETERS
+                : new HashMap<String, String>(advancedAttributes);
+    }
+
+    /**
+     * Returns a <tt>String</tt> representation of the clock rate associated
+     * with this <tt>MediaFormat</tt> making sure that the value appears as
+     * an integer (i.e. its long-casted value is equal to its original one)
+     * unless it is actually a non integer.
+     *
+     * @return a <tt>String</tt> representation of the clock rate associated
+     * with this <tt>MediaFormat</tt>.
+     */
+    public String getClockRateString()
+    {
+        double clockRate = getClockRate();
+        long clockRateL = (long) clockRate;
+
+        if (clockRateL == clockRate)
+            return Long.toString(clockRateL);
+        else
+            return Double.toString(clockRate);
+    }
+
     /**
      * Implements MediaFormat#getEncoding() and returns the encoding of the JMF
      * <tt>Format</tt> that we are encapsulating here but it is the RFC-known
@@ -424,22 +464,6 @@ public Map<String, String> getFormatParameters()
                 : new HashMap<String, String>(formatParameters);
     }
 
-    /**
-     * Implements MediaFormat#getAdvancedParameters(). Returns a copy of the
-     * attribute properties of this instance. Modifications to the returned Map
-     * do no affect the format properties of this instance.
-     *
-     * @return a copy of the attribute properties of this instance.
-     * Modifications to the returned Map do no affect the format properties of
-     * this instance.
-     */
-    public Map<String, String> getAdvancedAttributes()
-    {
-        return (advancedParameters == EMPTY_FORMAT_PARAMETERS)
-                ? EMPTY_FORMAT_PARAMETERS
-                : new HashMap<String, String>(advancedParameters);
-    }
-
     /**
      * Gets the encoding of the JMF <tt>Format</tt> represented by this
      * instance as it is known to JMF (in contrast to its RFC name).
@@ -452,61 +476,6 @@ public String getJMFEncoding()
         return format.getEncoding();
     }
 
-    /**
-     * Gets the RTP payload type (number) of this <tt>MediaFormat</tt> as it is
-     * known in RFC 3551 "RTP Profile for Audio and Video Conferences with
-     * Minimal Control".
-     *
-     * @return the RTP payload type of this <tt>MediaFormat</tt> if it is known
-     * in RFC 3551 "RTP Profile for Audio and Video Conferences with Minimal
-     * Control"; otherwise, {@link #RTP_PAYLOAD_TYPE_UNKNOWN}
-     * @see MediaFormat#getRTPPayloadType()
-     */
-    public byte getRTPPayloadType()
-    {
-        return MediaUtils.getRTPPayloadType(getJMFEncoding(), getClockRate());
-    }
-
-    /**
-     * Overrides Object#hashCode() because Object#equals(Object) is overridden.
-     *
-     * @return a hash code value for this <tt>MediaFormat</tt>.
-     */
-    @Override
-    public int hashCode()
-    {
-        /*
-         * XXX We've experienced a case of JMF's VideoFormat#hashCode()
-         * returning different values for instances which are reported equal by
-         * VideoFormat#equals(Object) which is inconsistent with the protocol
-         * covering the two methods in question and causes problems,
-         * for example, with Map. While jmfEncoding is more generic than format,
-         * it still provides a relatively good distribution given that we do not
-         * have a lot of instances with one and the same jmfEncoding.
-         */
-        return getJMFEncoding().hashCode() | getFormatParameters().hashCode();
-    }
-
-    /**
-     * Returns a <tt>String</tt> representation of the clock rate associated
-     * with this <tt>MediaFormat</tt> making sure that the value appears as
-     * an integer (i.e. its long-casted value is equal to its original one)
-     * unless it is actually a non integer.
-     *
-     * @return a <tt>String</tt> representation of the clock rate associated
-     * with this <tt>MediaFormat</tt>.
-     */
-    public String getClockRateString()
-    {
-        double clockRate = getClockRate();
-        long clockRateL = (long) clockRate;
-
-        if (clockRateL == clockRate)
-            return Long.toString(clockRateL);
-        else
-            return Double.toString(clockRate);
-    }
-
     /**
      * Returns a <tt>String</tt> representation of the real used clock rate
      * associated with this <tt>MediaFormat</tt> making sure that the value
@@ -533,80 +502,38 @@ public String getRealUsedClockRateString()
     }
 
     /**
-     * Sets additional codec settings.
-     *
-     * @param settings additional settings represented by a map.
-     */
-    public void setAdditionalCodecSettings(Map<String, String> settings)
-    {
-        codecSettings = settings;
-    }
-
-    /**
-     * Returns additional codec settings.
+     * Gets the RTP payload type (number) of this <tt>MediaFormat</tt> as it is
+     * known in RFC 3551 "RTP Profile for Audio and Video Conferences with
+     * Minimal Control".
      *
-     * @return additional settings represented by a map.
+     * @return the RTP payload type of this <tt>MediaFormat</tt> if it is known
+     * in RFC 3551 "RTP Profile for Audio and Video Conferences with Minimal
+     * Control"; otherwise, {@link #RTP_PAYLOAD_TYPE_UNKNOWN}
+     * @see MediaFormat#getRTPPayloadType()
      */
-    public Map<String, String> getAdditionalCodecSettings()
+    public byte getRTPPayloadType()
     {
-        return codecSettings;
+        return MediaUtils.getRTPPayloadType(getJMFEncoding(), getClockRate());
     }
 
     /**
-     * Returns a <tt>String</tt> representation of this <tt>MediaFormat</tt>
-     * containing, among other things, its encoding and clockrate values.
+     * Overrides Object#hashCode() because Object#equals(Object) is overridden.
      *
-     * @return a <tt>String</tt> representation of this <tt>MediaFormat</tt>.
+     * @return a hash code value for this <tt>MediaFormat</tt>.
      */
     @Override
-    public String toString()
+    public int hashCode()
     {
-        StringBuffer str = new StringBuffer();
-
-        str.append("rtpmap:");
-        str.append(getRTPPayloadType());
-        str.append(' ');
-        str.append(getEncoding());
-        str.append('/');
-        str.append(getClockRateString());
-
         /*
-         * If the number of channels is 1, it does not have to be mentioned
-         * because it is the default.
+         * XXX We've experienced a case of JMF's VideoFormat#hashCode()
+         * returning different values for instances which are reported equal by
+         * VideoFormat#equals(Object) which is inconsistent with the protocol
+         * covering the two methods in question and causes problems,
+         * for example, with Map. While jmfEncoding is more generic than format,
+         * it still provides a relatively good distribution given that we do not
+         * have a lot of instances with one and the same jmfEncoding.
          */
-        if (MediaType.AUDIO.equals(getMediaType()))
-        {
-            int channels = ((AudioFormat) getFormat()).getChannels();
-
-            if (channels != 1)
-            {
-                str.append('/');
-                str.append(channels);
-            }
-        }
-
-        Map<String, String> formatParameters = getFormatParameters();
-
-        if (!formatParameters.isEmpty())
-        {
-            str.append(" fmtp:");
-
-            boolean prependSeparator = false;
-
-            for (Map.Entry<String, String> formatParameter
-                    : formatParameters.entrySet())
-            {
-                if (prependSeparator)
-                    str.append(';');
-                else
-                    prependSeparator = true;
-                str.append(formatParameter.getKey());
-                str.append('=');
-                str.append(formatParameter.getValue());
-            }
-        }
-
-        return str.toString();
+        return getJMFEncoding().hashCode() | getFormatParameters().hashCode();
     }
 
     /**
@@ -691,4 +618,74 @@ public boolean matches(MediaType mediaType,
         // formatParameters
         return formatParametersMatch(formatParameters);
     }
+
+    /**
+     * Sets additional codec settings.
+     *
+     * @param settings additional settings represented by a map.
+     */
+    public void setAdditionalCodecSettings(Map<String, String> settings)
+    {
+        codecSettings
+            = ((settings == null) || settings.isEmpty())
+                ? EMPTY_FORMAT_PARAMETERS
+                : settings;
+    }
+
+    /**
+     * Returns a <tt>String</tt> representation of this <tt>MediaFormat</tt>
+     * containing, among other things, its encoding and clockrate values.
+     *
+     * @return a <tt>String</tt> representation of this <tt>MediaFormat</tt>.
+     */
+    @Override
+    public String toString()
+    {
+        StringBuffer str = new StringBuffer();
+
+        str.append("rtpmap:");
+        str.append(getRTPPayloadType());
+        str.append(' ');
+        str.append(getEncoding());
+        str.append('/');
+        str.append(getClockRateString());
+
+        /*
+         * If the number of channels is 1, it does not have to be mentioned
+         * because it is the default.
+         */
+        if (MediaType.AUDIO.equals(getMediaType()))
+        {
+            int channels = ((AudioFormat) getFormat()).getChannels();
+
+            if (channels != 1)
+            {
+                str.append('/');
+                str.append(channels);
+            }
+        }
+
+        Map<String, String> formatParameters = getFormatParameters();
+
+        if (!formatParameters.isEmpty())
+        {
+            str.append(" fmtp:");
+
+            boolean prependSeparator = false;
+
+            for (Map.Entry<String, String> formatParameter
+                    : formatParameters.entrySet())
+            {
+                if (prependSeparator)
+                    str.append(';');
+                else
+                    prependSeparator = true;
+                str.append(formatParameter.getKey());
+                str.append('=');
+                str.append(formatParameter.getValue());
+            }
+        }
+
+        return str.toString();
+    }
 }
diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/renderer/video/JAWTRenderer.java b/src/org/jitsi/impl/neomedia/jmfext/media/renderer/video/JAWTRenderer.java
similarity index 88%
rename from src/net/java/sip/communicator/impl/neomedia/jmfext/media/renderer/video/JAWTRenderer.java
rename to src/org/jitsi/impl/neomedia/jmfext/media/renderer/video/JAWTRenderer.java
index f156866626e95a2e40049744b3333d67f004c382..fac7bf20ee294f9cf66cfc8a29c2425b61e0457b 100644
--- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/renderer/video/JAWTRenderer.java
+++ b/src/org/jitsi/impl/neomedia/jmfext/media/renderer/video/JAWTRenderer.java
@@ -4,7 +4,7 @@
  * Distributable under LGPL license.
  * See terms of license at gnu.org.
  */
-package net.java.sip.communicator.impl.neomedia.jmfext.media.renderer.video;
+package org.jitsi.impl.neomedia.jmfext.media.renderer.video;
 
 import java.awt.*;
 import java.lang.reflect.*;
@@ -15,8 +15,6 @@
 import javax.swing.*;
 
 import org.jitsi.impl.neomedia.jmfext.media.renderer.*;
-import org.jitsi.service.configuration.*;
-import org.jitsi.service.libjitsi.*;
 import org.jitsi.util.*;
 import org.jitsi.util.swing.*;
 
@@ -69,49 +67,9 @@ public class JAWTRenderer
                                 0x00FF0000, 0x0000FF00, 0x000000FF)
                 };
 
-    /**
-     * The indicator which determines whether <tt>CALayer</tt>-based painting is
-     * to be performed by <tt>JAWTRenderer</tt> on Mac OS X.
-     */
-    private static final boolean USE_MACOSX_CALAYERS;
-
     static
     {
         System.loadLibrary("jnawtrenderer");
-
-        /*
-         * XXX The native JAWTRenderer implementation on Mac OS X which paints
-         * in a CALayer-like fashion has been determined through testing to not
-         * work as expected on MacBookPro8. Unfortunately, the cause of the
-         * problem has not been determined. As a workaround, fall back to the
-         * alternative implementation (currently used on the other supported
-         * operating systems) on the problematic model. 
-         */
-        if (OSUtils.IS_MAC)
-        {
-            ConfigurationService cfg = LibJitsi.getConfigurationService();
-
-            if ((cfg == null)
-                    || cfg.getBoolean(
-                            JAWTRenderer.class.getName()
-                                + ".USE_MACOSX_CALAYERS",
-                            false))
-            {
-                String hwModel = sysctlbyname("hw.model");
-
-                USE_MACOSX_CALAYERS
-                    = (hwModel == null)
-                        || !(hwModel.startsWith("MacBookPro8")
-                                || hwModel.startsWith("MacBookAir4"));
-            }
-            else
-                USE_MACOSX_CALAYERS = false;
-        }
-        else
-        {
-            // CALayer-like painting is currently only supported on Mac OS X.
-            USE_MACOSX_CALAYERS = false;
-        }
     }
 
     /**
@@ -143,10 +101,6 @@ public JAWTRenderer()
     {
     }
 
-    public static native void addNotifyLightweightComponent(
-            long handle, Component component,
-            long parentHandle);
-
     /**
      * Closes this <tt>PlugIn</tt> and releases the resources it has retained
      * during its execution. No more data will be accepted by this
@@ -199,7 +153,7 @@ public synchronized void close()
      * platform-specific info of <tt>component</tt> is not guaranteed to be
      * valid.
      */
-    public static native void close(long handle, Component component);
+    private static native void close(long handle, Component component);
 
     /**
      * Gets the region in the component of this <tt>VideoRenderer</tt> where the
@@ -231,9 +185,7 @@ public synchronized Component getComponent()
                     "org.jitsi"
                         + ".impl.neomedia.jmfext.media.renderer.video"
                         + ".JAWTRenderer");
-            if (USE_MACOSX_CALAYERS && OSUtils.IS_MAC)
-                componentClassName.append("Swing");
-            else if (OSUtils.IS_ANDROID)
+            if (OSUtils.IS_ANDROID)
                 componentClassName.append("Android");
             componentClassName.append("VideoComponent");
 
@@ -395,7 +347,7 @@ public void run()
      * is to draw into the specified AWT <tt>Component</tt>
      * @throws ResourceUnavailableException if there is a problem during opening
      */
-    public static native long open(Component component)
+    private static native long open(Component component)
         throws ResourceUnavailableException;
 
     /**
@@ -413,6 +365,7 @@ public static native long open(Component component)
      * <tt>paint</tt>.
      * @param g the <tt>Graphics</tt> context into which the drawing is to be
      * performed
+     * @param zOrder
      * @return <tt>true</tt> if the native counterpart of a
      * <tt>JAWTRenderer</tt> wants to continue receiving the <tt>paint</tt>
      * calls on the AWT <tt>Component</tt>; otherwise, false. For example, after
@@ -423,11 +376,10 @@ public static native long open(Component component)
      * indicate with <tt>false</tt> that it does not need further <tt>paint</tt>
      * deliveries.
      */
-    public static native boolean paint(
-            long handle, Component component, Graphics g);
-
-    public static native boolean paintLightweightComponent(
-            long handle, Component component, Graphics g);
+    static native boolean paint(
+            long handle,
+            Component component, Graphics g,
+            int zOrder);
 
     /**
      * Processes the data provided in a specific <tt>Buffer</tt> and renders it
@@ -510,19 +462,12 @@ public synchronized int process(Buffer buffer)
      * @param height the height of the video frame in <tt>data</tt>
      * @return <tt>true</tt> if data has been successfully processed
      */
-    public static native boolean process(
+    static native boolean process(
             long handle,
             Component component,
             int[] data, int offset, int length,
             int width, int height);
 
-    public static native void processLightweightComponentEvent(
-            long handle,
-            int x, int y, int width, int height);
-
-    public static native void removeNotifyLightweightComponent(
-            long handle, Component component);
-
     /**
      * Sets the region in the component of this <tt>VideoRenderer</tt> where the
      * video is to be rendered.
diff --git a/src/org/jitsi/impl/neomedia/jmfext/media/renderer/video/JAWTRendererSwingVideoComponent.java b/src/org/jitsi/impl/neomedia/jmfext/media/renderer/video/JAWTRendererSwingVideoComponent.java
deleted file mode 100644
index 9071d1de2e9e969e53b22442f30598d35e3be43e..0000000000000000000000000000000000000000
--- a/src/org/jitsi/impl/neomedia/jmfext/media/renderer/video/JAWTRendererSwingVideoComponent.java
+++ /dev/null
@@ -1,910 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package org.jitsi.impl.neomedia.jmfext.media.renderer.video;
-
-import java.awt.*;
-import java.awt.event.*;
-import java.awt.image.*;
-import java.util.*;
-import java.util.List;
-
-import javax.media.*;
-import javax.swing.*;
-
-import net.java.sip.communicator.impl.neomedia.jmfext.media.renderer.video.*;
-
-import org.jitsi.util.*;
-import org.jitsi.util.swing.*;
-
-/**
- * Implements a Swing <tt>Component</tt> in which <tt>JAWTRenderer</tt> paints.
- *
- * @author Lyubomir Marinov
- */
-public class JAWTRendererSwingVideoComponent
-    extends JPanel
-{
-    /**
-     * Serial version UID.
-     */
-    private static final long serialVersionUID = 0L;
-
-    /**
-     * The <tt>Logger</tt> used by the <tt>JAWTRendererSwingVideoComponent</tt>
-     * class and its instances for logging output.
-     */
-    private static final Logger logger
-        = Logger.getLogger(JAWTRendererSwingVideoComponent.class);
-
-    /**
-     * The <tt>SwingVideoComponentCanvas</tt> in which this
-     * <tt>SwingVideoComponent</tt> is painted according to the last call to
-     * {@link #addNotify()}.
-     */
-    private SwingVideoComponentCanvas canvas;
-
-    /**
-     * The <tt>Container</tt> which is the last-known parent of this
-     * <tt>SwingVideoComponent</tt>.
-     */
-    private Container parent;
-
-    /**
-     * The <tt>ComponentListener</tt> which is to be or is listening to
-     * <tt>ComponentEvent</tt>s fired by {@link #parent}.
-     */
-    private final ComponentListener parentComponentListener
-        = new ComponentAdapter()
-        {
-            @Override
-            public void componentResized(ComponentEvent e)
-            {
-                /*
-                 * It is necessary to call
-                 * #procesLightweightComponentEvent() when the parent gets
-                 * resized only if the native counterpart of this
-                 * SwingVideoComponent expects bounds in a coordinate system
-                 * which changes with respect to the bounds of this
-                 * SwingVideoComponent when the parent gets resized.
-                 */
-                //processLightweightComponentEvent();
-            }
-        };
-
-    /**
-     * The <tt>JAWTRenderer</tt> which paints in this
-     * <tt>JAWTRendererSwingVideoComponent</tt>.
-     */
-    private final JAWTRenderer renderer;
-
-    /**
-     * The indicator which determines whether the native counterpart of this
-     * <tt>JAWTRenderer</tt> wants <tt>paint</tt> calls on its Swing
-     * <tt>Component</tt> to be delivered.
-     *
-     * @see JAWTRendererVideoComponent#wantsPaint
-     */
-    private boolean wantsPaint = true;
-
-    /**
-     * Constructor.
-     *
-     * @param renderer <tt>JAWTRenderer</tt> instance
-     */
-    public JAWTRendererSwingVideoComponent(JAWTRenderer renderer)
-    {
-        if (VideoContainer.DEFAULT_BACKGROUND_COLOR != null)
-            setBackground(VideoContainer.DEFAULT_BACKGROUND_COLOR);
-
-        this.renderer = renderer;
-    }
-
-    @Override
-    public void addNotify()
-    {
-        /*
-         * Since JAWTRenderer#open() may be performing the call, it may be
-         * wrong about this SwingVideoComponent having a parent.
-         */
-        Container parent = getParent();
-
-        if (parent == null)
-            return;
-
-        super.addNotify();
-
-        wantsPaint = true;
-
-        synchronized (renderer.getHandleLock())
-        {
-            long handle = renderer.getHandle();
-
-            if (handle != 0)
-            {
-                SwingVideoComponentCanvas canvas = findCanvas();
-
-                if (canvas == null)
-                {
-                    JAWTRenderer.addNotifyLightweightComponent(
-                            handle, this,
-                            0);
-                }
-                else
-                {
-                    long canvasHandle;
-
-                    synchronized (canvas.getHandleLock())
-                    {
-                        canvasHandle = canvas.getHandle();
-                        JAWTRenderer.addNotifyLightweightComponent(
-                                handle, this,
-                                canvasHandle);
-                    }
-                    if ((canvasHandle != 0) && (this.canvas != canvas))
-                    {
-                        this.canvas = canvas;
-                    }
-                }
-
-                /*
-                 * Emulate a ComponentEvent so that, for example, the native
-                 * counterpart of this Component gets its bounds up to date.
-                 */
-                processLightweightComponentEvent();
-            }
-        }
-
-        if (this.parent != parent)
-        {
-            this.parent = parent;
-            this.parent.addComponentListener(parentComponentListener);
-        }
-    }
-
-    /**
-     * Creates a new AWT <tt>Component</tt> in which
-     * <tt>SwingVideoComponent</tt>s can be rendered.
-     * @return new AWT <tt>Component</tt> in which <tt>SwingVideoComponent</tt>s
-     * can be rendered
-     */
-    public Component createCanvas()
-    {
-        return new SwingVideoComponentCanvas(renderer);
-    }
-
-    /**
-     * Finds a <tt>SwingVideoComponentCanvas</tt> in which this
-     * <tt>SwingVideoComponent</tt> can be painted.
-     *
-     * @return a <tt>SwingVideoComponentCanvas</tt> in which this
-     * <tt>SwingVideoComponent</tt> can be painted if any; otherwise,
-     * <tt>null</tt>
-     */
-    private SwingVideoComponentCanvas findCanvas()
-    {
-        Container parent = getParent();
-
-        if (parent != null)
-            for (Component component : parent.getComponents())
-                if (component instanceof SwingVideoComponentCanvas)
-                    return (SwingVideoComponentCanvas) component;
-        return null;
-    }
-
-    /**
-     * Gets the <tt>SwingVideoComponentCanvas</tt> in which this
-     * <tt>SwingVideoComponent</tt> is being painted.
-     *
-     * @return the <tt>SwingVideoComponentCanvas</tt> in which this
-     * <tt>SwingVideoComponent</tt> is being painted if any; otherwise,
-     * <tt>null</tt>
-     */
-    SwingVideoComponentCanvas getCanvas()
-    {
-        return canvas;
-    }
-
-    @Override
-    public void paint(Graphics g)
-    {
-        synchronized (renderer.getHandleLock())
-        {
-            long handle = renderer.getHandle();
-
-            if (wantsPaint && (handle != 0))
-            {
-                wantsPaint
-                    = JAWTRenderer.paintLightweightComponent(
-                            handle,
-                            this,
-                            g);
-            }
-        }
-    }
-
-    @Override
-    protected void processComponentEvent(ComponentEvent e)
-    {
-        super.processComponentEvent(e);
-
-        if (equals(e.getComponent()))
-        {
-            switch(e.getID())
-            {
-            case ComponentEvent.COMPONENT_MOVED:
-            case ComponentEvent.COMPONENT_RESIZED:
-                processLightweightComponentEvent();
-                break;
-            }
-        }
-    }
-
-    /**
-     * Notifies this <tt>SwingVideoComponent</tt> that a
-     * <tt>ComponentEvent</tt> related to it has occurred.
-     */
-    private void processLightweightComponentEvent()
-    {
-        Rectangle bounds = getBounds();
-
-        if (bounds != null)
-        {
-            synchronized (renderer.getHandleLock())
-            {
-                long handle = renderer.getHandle();
-
-                if (handle != 0)
-                {
-                    JAWTRenderer.processLightweightComponentEvent(
-                            handle,
-                            bounds.x,
-                            bounds.y,
-                            bounds.width,
-                            bounds.height);
-                }
-            }
-        }
-    }
-
-    @Override
-    public void removeNotify()
-    {
-        if (parent != null)
-        {
-            parent.removeComponentListener(parentComponentListener);
-            parent = null;
-        }
-
-        synchronized (renderer.getHandleLock())
-        {
-            long handle = renderer.getHandle();
-
-            if (handle != 0)
-            {
-                if (canvas != null)
-                {
-                    synchronized (canvas.getHandleLock())
-                    {
-                        JAWTRenderer.removeNotifyLightweightComponent(
-                                handle, this);
-                    }
-                    canvas = null;
-                }
-                else
-                {
-                    JAWTRenderer.removeNotifyLightweightComponent(
-                            handle, this);
-                }
-            }
-        }
-
-        /*
-         * In case the associated JAWTRenderer has said that it does not
-         * want paint events/notifications, ask it again next time because
-         * the native handle of this Canvas may be recreated.
-         */
-        wantsPaint = true;
-
-        super.removeNotify();
-    }
-
-    @Override
-    public void repaint()
-    {
-        super.repaint();
-
-        /*
-         * Since SwingVideoComponent is to be painted in a
-         * SwingVideoComponentCanvas, the latter should repaint when the
-         * former does.
-         */
-        Component canvas = getCanvas();
-
-        if (canvas != null)
-            canvas.repaint();
-    }
-
-    @Override
-    public void setBounds(int x, int y, int width, int height)
-    {
-        super.setBounds(x, y, width, height);
-
-        /*
-         * Calling #setBounds(int, int, int, int) does not seem to cause
-         * this SwingVideoComponent to process a ComponentEvent so force it
-         * because it is really necessary to deliver the up-to-date bounds
-         * to the native counterpart.
-         */
-        processLightweightComponentEvent();
-    }
-
-    @Override
-    public void setLocation(int x, int y)
-    {
-        super.setLocation(x, y);
-
-        processLightweightComponentEvent();
-    }
-
-    /**
-     * Represents a <tt>Component</tt> which is neither a
-     * <tt>AWTVideoComponent</tt> nor a <tt>SwingVideoComponent</tt> but which
-     * is to be painted by a <tt>SwingVideoComponentCanvas</tt> anyway.
-     */
-    private static class NonVideoComponent
-    {
-        /**
-         * The <tt>BufferedImage</tt> into which {@link #component} is to be
-         * painted so that it can be processed and then rendered by
-         * {@link #handle}.
-         */
-        private BufferedImage bufferedImage;
-
-        /**
-         * The <tt>Component</tt> represented by this <tt>NonVideoComponent</tt>
-         * instance.
-         */
-        public final Component component;
-
-        /**
-         * The handle of the native <tt>JAWTRenderer</tt> which paints this
-         * <tt>NonVideoComponent</tt>.
-         */
-        private long handle;
-
-        /**
-         * The height in pixels of {@link #bufferedImage} and {@link #rgb}.
-         */
-        private int height;
-
-        /**
-         * The pixels of {@link #bufferedImage} to be processed by
-         * {@link #handle}.
-         */
-        private int[] rgb;
-
-        /**
-         * The width in pixels of {@link #bufferedImage} and {@link #rgb}.
-         */
-        private int width;
-
-        /**
-         * Initializes a new <tt>NonVideoComponent</tt> instance which is to
-         * paint a specific <tt>Component</tt> in the context of a parent
-         * <tt>JAWTRenderer</tt>.
-         *
-         * @param component the <tt>Component</tt> to be painted
-         * @param parentHandle the handle of the native <tt>JAWTRenderer</tt> in
-         * the context of which <tt>component</tt> is to be painted
-         */
-        public NonVideoComponent(Component component, long parentHandle)
-        {
-            this.component = component;
-
-            try
-            {
-                handle = JAWTRenderer.open(this.component);
-                if (handle != 0)
-                {
-                    JAWTRenderer.addNotifyLightweightComponent(
-                            handle, this.component,
-                            parentHandle);
-                }
-            }
-            catch (ResourceUnavailableException rue)
-            {
-                logger.error(
-                        "Failed to JAWTRenderer.open for NonVideoComponent",
-                        rue);
-            }
-        }
-
-        /**
-         * Releases the resources of this <tt>NonVideoComponent</tt> and
-         * prepares it to be garbage collected.
-         */
-        public void dispose()
-        {
-            if (handle != 0)
-            {
-                JAWTRenderer.removeNotifyLightweightComponent(
-                        handle, component);
-                JAWTRenderer.close(handle, component);
-                handle = 0;
-            }
-        }
-
-        /**
-         * Paints the <tt>Component</tt> associated with this
-         * <tt>NonVideoComponent</tt> instance.
-         */
-        public void paint()
-        {
-            if (handle != 0)
-            {
-                /*
-                 * Make sure the location, the size and the visibility known to
-                 * the associated native JAWTRenderer are in sync with these of
-                 * the component.
-                 */
-                Rectangle bounds = component.getBounds();
-
-                if (!component.isVisible())
-                {
-                    bounds.height = 0;
-                    bounds.width = 0;
-                }
-                JAWTRenderer.processLightweightComponentEvent(
-                        handle,
-                        bounds.x, bounds.y, bounds.width, bounds.height);
-
-                /*
-                 * If the component is not visible, the native JAWTRenderer
-                 * already knows that it is not to be rendered.
-                 */
-                if ((bounds.height < 1) || (bounds.width < 1))
-                    return;
-
-                /*
-                 * Paint the component and tell the native JAWTRenderer about
-                 * the latest painting.
-                 */
-                if ((height != bounds.height) || (width != bounds.width))
-                {
-                    rgb = new int[bounds.width * bounds.height];
-                    bufferedImage
-                        = new BufferedImage(
-                                bounds.width, bounds.height,
-                                BufferedImage.TYPE_INT_ARGB);
-                    height = bounds.height;
-                    width = bounds.width;
-                }
-                if ((bufferedImage != null) && (rgb != null))
-                {
-                    Graphics g = bufferedImage.createGraphics();
-                    boolean process = false;
-
-                    try
-                    {
-                        component.paint(g);
-                        process = true;
-                    }
-                    finally
-                    {
-                        g.dispose();
-                    }
-                    if (process)
-                    {
-                        bufferedImage.getRGB(
-                                0, 0, width, height,
-                                rgb, 0, width);
-                        JAWTRenderer.process(
-                                handle, component,
-                                rgb, 0, rgb.length,
-                                width, height);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Implements an AWT <tt>Component</tt> in which
-     * <tt>SwingVideoComponent</tt>s can be rendered.
-     */
-    private static class SwingVideoComponentCanvas
-        extends JAWTRendererVideoComponent
-    {
-        /**
-         * Serial version UID.
-         */
-        private static final long serialVersionUID = 0L;
-
-        /**
-         * The handle to the native <tt>JAWTRenderer</tt> which does the actual
-         * painting of this <tt>SwingVideoComponentCanvas</tt>.
-         */
-        private long handle;
-
-        /**
-         * The <tt>Component</tt> to which this
-         * <tt>SwingVideoComponentCanvas</tt> has dispatched a
-         * {@link MouseEvent#MOUSE_PRESSED}.
-         */
-        private Component mousePressedComponent;
-
-        /**
-         * The <tt>NoVideoComponent</tt>s painted by this
-         * <tt>SwingVideoComponentCanvas</tt>.
-         */
-        private final List<NonVideoComponent> nonVideoComponents
-            = new LinkedList<NonVideoComponent>();
-
-        /**
-         * The <tt>Container</tt> which is the last-known parent of this
-         * <tt>SwingVideoComponentCanvas</tt>.
-         */
-        private Container parent;
-
-        /**
-         * The <tt>ContainerListener</tt> which listens to {@link #parent}.
-         */
-        private final ContainerListener parentContainerListener
-            = new ContainerListener()
-            {
-                public void componentAdded(ContainerEvent e)
-                {
-                    Component c = e.getChild();
-
-                    if (!(c instanceof JAWTRendererVideoComponent)
-                            && !(c instanceof JAWTRendererSwingVideoComponent))
-                    {
-                        nonVideoComponentAdded(c);
-                    }
-                }
-
-                public void componentRemoved(ContainerEvent e)
-                {
-                    Component c = e.getChild();
-
-                    if (mousePressedComponent == c)
-                        mousePressedComponent = null;
-
-                    if (!(c instanceof JAWTRendererVideoComponent)
-                            && !(c instanceof JAWTRendererSwingVideoComponent))
-                    {
-                        nonVideoComponentRemoved(c);
-                    }
-                    else if (SwingVideoComponentCanvas.this.equals(c))
-                        removeAllNonVideoComponents();
-                }
-            };
-
-        /**
-         * Initializes a new <tt>SwingVideoComponentCanvas</tt> instance.
-         *
-         * @param renderer
-         */
-        public SwingVideoComponentCanvas(JAWTRenderer renderer)
-        {
-            super(renderer);
-
-            enableEvents(
-                    AWTEvent.MOUSE_EVENT_MASK
-                        | AWTEvent.MOUSE_MOTION_EVENT_MASK);
-        }
-
-        @Override
-        public void addNotify()
-        {
-            super.addNotify();
-
-            synchronized (getHandleLock())
-            {
-                if (getHandle() == 0)
-                {
-                    try
-                    {
-                        this.handle = JAWTRenderer.open(this);
-                    }
-                    catch (ResourceUnavailableException rue)
-                    {
-                        throw new RuntimeException(rue);
-                    }
-                    if (getHandle() == 0)
-                    {
-                        throw new RuntimeException(
-                                "JAWTRenderer#open(Component)");
-                    }
-                }
-            }
-
-            Container parent = getParent();
-
-            if ((parent != null) && (this.parent != parent))
-            {
-                this.parent = parent;
-                this.parent.addContainerListener(parentContainerListener);
-            }
-        }
-
-        @Override
-        public boolean contains(int x, int y)
-        {
-            /*
-             * Act as a "glass pane" i.e. be transparent with respect to points
-             * and pretend they are in whatever is underneath.
-             */
-            return false;
-        }
-
-        /**
-         * Dispatches <tt>MouseEvent</tt>s to whatever is underneath this
-         * <tt>SwingVideoComponentCanvas</tt> because it only renders
-         * <tt>Component</tt>s i.e. it is like a "glass pane".
-         */
-        private boolean dispatchMouseEvent(MouseEvent e)
-        {
-            Component srcc = e.getComponent();
-
-            if (srcc != null)
-            {
-                int id = e.getID();
-                Component dstc = null;
-
-                /*
-                 * After a MOUSE_PRESSED, this SwingVideoComponentCanvas will
-                 * continue to receive, for example, MouseMotionEvents even
-                 * when the point has moved out of it. Emulate the same behavior
-                 * for the Components this SwingVideoComponentCanvas dispatches
-                 * events to since it is transparent in this respect.
-                 */
-                if (MouseEvent.MOUSE_PRESSED == id)
-                    mousePressedComponent = null;
-                else if (mousePressedComponent != null)
-                {
-                    dstc = mousePressedComponent;
-                    if ((MouseEvent.MOUSE_CLICKED == id)
-                            || (MouseEvent.MOUSE_RELEASED == id))
-                        mousePressedComponent = null;
-                }
-
-                if (dstc == null)
-                {
-                    Container parent = getParent();
-
-                    if (parent != null)
-                    {
-                        Point parentPoint
-                            = SwingUtilities.convertPoint(
-                                    srcc,
-                                    e.getPoint(),
-                                    parent);
-
-                        dstc = getComponentAt(parent, parentPoint);
-                    }
-                }
-
-                if (dstc != null)
-                {
-                    if (MouseEvent.MOUSE_PRESSED == id)
-                        mousePressedComponent = dstc;
-                    dstc.dispatchEvent(
-                            SwingUtilities.convertMouseEvent(
-                                    srcc,
-                                    e,
-                                    dstc));
-                    return true;
-                }
-            }
-            return false;
-        }
-
-        /**
-         * Determines the <tt>Component</tt> which is a child of a specific
-         * <tt>Container</tt> which contains a specific <tt>Point</tt>. Since
-         * <tt>SwingVideoComponentCanvas</tt> is like a "glass pane", it never
-         * contains the specified <tt>point</tt>.
-         *
-         * @param parent the <tt>Container</tt> which contains the
-         * <tt>Component</tt>s which may contain the specified <tt>point</tt>
-         * @param point the point in the coordinate system of <tt>parent</tt>
-         * which is to be determined which <tt>Component</tt> contains it
-         * @return the <tt>Component</tt> which is a child of the specified
-         * <tt>Container</tt> and contains the specified <tt>Point</tt> or
-         * <tt>null</tt> if there is no such <tt>Component</tt>
-         */
-        private Component getComponentAt(Container parent, Point point)
-        {
-            Component[] components = parent.getComponents();
-
-            for (int componentIndex = components.length - 1;
-                    componentIndex >= 0;
-                    componentIndex--)
-            {
-                Component component = components[componentIndex];
-
-                if (!equals(component)
-                        && component.isVisible()
-                        && component.contains(
-                                SwingUtilities.convertPoint(
-                                        parent,
-                                        point,
-                                        component)))
-                {
-                    return component;
-                }
-            }
-            return null;
-        }
-
-        /* Overrides JAWTRendererVideoComponent#getHandle(). */
-        @Override
-        protected long getHandle()
-        {
-            return handle;
-        }
-
-        /* Overrides JAWTRendererVideoComponent#getHandleLock(). */
-        @Override
-        protected Object getHandleLock()
-        {
-            return this;
-        }
-
-        /**
-         * Notifies this <tt>SwingVideoComponentCanvas</tt> that a
-         * <tt>Component</tt> which is neither an <tt>AWTVideoComponent</tt> nor
-         * a <tt>SwingVideoComponent</tt> has been added to {@link #parent}.
-         *
-         * @param c the component which has been added
-         */
-        private void nonVideoComponentAdded(Component c)
-        {
-            synchronized (getHandleLock())
-            {
-                synchronized (nonVideoComponents)
-                {
-                    for (NonVideoComponent nonVideoComponent
-                            : nonVideoComponents)
-                    {
-                        if (nonVideoComponent.component.equals(c))
-                            return;
-                    }
-
-                    nonVideoComponents.add(
-                            new NonVideoComponent(c, getHandle()));
-                }
-            }
-        }
-
-        /**
-         * Notifies this <tt>SwingVideoComponentCanvas</tt> that a
-         * <tt>Component</tt> which is neither an <tt>AWTVideoComponent</tt> nor
-         * a <tt>SwingVideoComponent</tt> has been removed from {@link #parent}.
-         *
-         * @param c the component which has been removed
-         */
-        private void nonVideoComponentRemoved(Component c)
-        {
-            synchronized (nonVideoComponents)
-            {
-                Iterator<NonVideoComponent> nonVideoComponentIter
-                    = nonVideoComponents.iterator();
-
-                while (nonVideoComponentIter.hasNext())
-                {
-                    NonVideoComponent nonVideoComponent
-                        = nonVideoComponentIter.next();
-
-                    if (nonVideoComponent.component.equals(c))
-                    {
-                        nonVideoComponentIter.remove();
-                        nonVideoComponent.dispose();
-                        break;
-                    }
-                }
-            }
-        }
-
-        @Override
-        public void paint(Graphics g)
-        {
-            try
-            {
-                synchronized (nonVideoComponents)
-                {
-                    for (NonVideoComponent nonVideoComponent
-                            : nonVideoComponents)
-                        nonVideoComponent.paint();
-                }
-            }
-            finally
-            {
-                super.paint(g);
-            }
-        }
-
-        @Override
-        protected void processMouseEvent(MouseEvent e)
-        {
-            /*
-             * Act as a "glass pane" i.e. be transparent with respect to
-             * MouseEvents and dispatch them to whatever is underneath.
-             */
-            if (!dispatchMouseEvent(e))
-                super.processMouseEvent(e);
-        }
-
-        @Override
-        protected void processMouseMotionEvent(MouseEvent e)
-        {
-            /*
-             * Act as a "glass pane" i.e. be transparent with respect to
-             * MouseEvents and dispatch them to whatever is underneath.
-             */
-            if (!dispatchMouseEvent(e))
-                super.processMouseMotionEvent(e);
-        }
-
-        /**
-         * Removes all <tt>NonVideoComponent</tt>s from this
-         * <tt>SwingVideoComponentCanvas</tt> so that their associated
-         * <tt>Component</tt>s are no longer painted by the represented native
-         * <tt>JAWTRenderer</tt>.
-         */
-        private void removeAllNonVideoComponents()
-        {
-            synchronized (nonVideoComponents)
-            {
-                Iterator<NonVideoComponent> nonVideoComponentIter
-                    = nonVideoComponents.iterator();
-
-                while (nonVideoComponentIter.hasNext())
-                {
-                    NonVideoComponent nonVideoComponent
-                        = nonVideoComponentIter.next();
-
-                    nonVideoComponentIter.remove();
-                    nonVideoComponent.dispose();
-                }
-            }
-        }
-
-        @Override
-        public void removeNotify()
-        {
-            mousePressedComponent = null;
-
-            if (parent != null)
-            {
-                parent.removeContainerListener(parentContainerListener);
-                removeAllNonVideoComponents();
-                parent = null;
-            }
-
-            synchronized (getHandleLock())
-            {
-                long handle = getHandle();
-
-                if (handle != 0)
-                {
-                    try
-                    {
-                        JAWTRenderer.close(handle, this);
-                    }
-                    finally
-                    {
-                        this.handle = 0;
-                    }
-                }
-            }
-
-            super.removeNotify();
-        }
-    }
-}
diff --git a/src/org/jitsi/impl/neomedia/jmfext/media/renderer/video/JAWTRendererVideoComponent.java b/src/org/jitsi/impl/neomedia/jmfext/media/renderer/video/JAWTRendererVideoComponent.java
index 26f05e62dbe3bb58fec8da240fd91c1ddfc4ddac..de8e03a8bc8e342bc3af208e0132ea0f0188397a 100644
--- a/src/org/jitsi/impl/neomedia/jmfext/media/renderer/video/JAWTRendererVideoComponent.java
+++ b/src/org/jitsi/impl/neomedia/jmfext/media/renderer/video/JAWTRendererVideoComponent.java
@@ -8,10 +8,6 @@
 
 import java.awt.*;
 
-import net.java.sip.communicator.impl.neomedia.jmfext.media.renderer.video.*;
-
-import org.jitsi.util.swing.*;
-
 /**
  * Implements an AWT <tt>Component</tt> in which <tt>JAWTRenderer</tt> paints.
  *
@@ -52,9 +48,6 @@ public class JAWTRendererVideoComponent
      */
     public JAWTRendererVideoComponent(JAWTRenderer renderer)
     {
-        if (VideoContainer.DEFAULT_BACKGROUND_COLOR != null)
-            setBackground(VideoContainer.DEFAULT_BACKGROUND_COLOR);
-
         this.renderer = renderer;
     }
 
@@ -110,7 +103,15 @@ public void paint(Graphics g)
                 long handle;
 
                 if ((handle = getHandle()) != 0)
-                    wantsPaint = JAWTRenderer.paint(handle, this, g);
+                {
+                    Container parent = getParent();
+                    int zOrder
+                        = (parent == null)
+                            ? -1
+                            : parent.getComponentZOrder(this);
+
+                    wantsPaint = JAWTRenderer.paint(handle, this, g, zOrder);
+                }
             }
         }
     }
diff --git a/src/org/jitsi/impl/neomedia/transform/csrc/CsrcTransformEngine.java b/src/org/jitsi/impl/neomedia/transform/csrc/CsrcTransformEngine.java
index 1d0122226e5324127dce3973df067b8a20ed0974..b310a8db84d1351e396cc41a8220552a36efcb06 100644
--- a/src/org/jitsi/impl/neomedia/transform/csrc/CsrcTransformEngine.java
+++ b/src/org/jitsi/impl/neomedia/transform/csrc/CsrcTransformEngine.java
@@ -280,40 +280,33 @@ public void run()
         {
             isRunning = true;
 
-            //no point in listening if our stream is not an audio one.
+            // Audio levels are received in RTP audio streams only. 
             if(!(mediaStream instanceof AudioMediaStreamImpl))
                 return;
 
-            long[] temp = null;
+            AudioMediaStreamImpl audioStream
+                = (AudioMediaStreamImpl) mediaStream;
 
             while(isRunning)
             {
+                long[] audioLevels;
+
                 synchronized(this)
                 {
                     if(lastReportedLevels == null)
                     {
-                        try
-                        {
-                            wait();
-                        }
-                        catch (InterruptedException ie) {}
+                        try { wait(); } catch (InterruptedException ie) {}
+                        continue;
                     }
-
-                    temp = lastReportedLevels;
-                    // make lastReportedLevels to null
-                    // so we will wait for the next level on next iteration
-                    lastReportedLevels = null;
-                }
-
-                if(temp != null)
-                {
-                    //now notify our listener
-                    if (mediaStream != null)
+                    else
                     {
-                        ((AudioMediaStreamImpl)mediaStream)
-                            .fireConferenceAudioLevelEvent(temp);
+                        audioLevels = lastReportedLevels;
+                        lastReportedLevels = null;
                     }
                 }
+
+                if(audioLevels != null)
+                    audioStream.audioLevelsReceived(audioLevels);
             }
         }
 
@@ -328,7 +321,6 @@ public void addLevels(long[] levels)
             synchronized(this)
             {
                 this.lastReportedLevels = levels;
-
                 notifyAll();
             }
         }
@@ -343,7 +335,6 @@ public void stop()
             {
                 this.lastReportedLevels = null;
                 isRunning = false;
-
                 notifyAll();
             }
         }
diff --git a/src/org/jitsi/util/swing/FitLayout.java b/src/org/jitsi/util/swing/FitLayout.java
index 6af174e3efc46fa18b3d1751936dd02af2afa644..e61c6cd2f6ebe648c2d7432443c0a641633ee245 100644
--- a/src/org/jitsi/util/swing/FitLayout.java
+++ b/src/org/jitsi/util/swing/FitLayout.java
@@ -62,12 +62,13 @@ protected void layoutComponent(
         /*
          * XXX The following is a quick and dirty hack for the purposes of video
          * conferencing which adds transparent JPanels to VideoContainer and
-         * does not want them fitted because they contains VideoContainers
+         * does not want them fitted because they contain VideoContainers
          * themselves and the videos get fitted in them.
          */
-        if ((component instanceof JPanel)
-                && !component.isOpaque()
-                && (((Container) component).getComponentCount() > 1))
+        if (((component instanceof JPanel)
+                    && !component.isOpaque()
+                    && (((Container) component).getComponentCount() > 1))
+                || (component instanceof VideoContainer))
         {
             componentSize = bounds.getSize();
         }
diff --git a/src/org/jitsi/util/swing/VideoContainer.java b/src/org/jitsi/util/swing/VideoContainer.java
index 7a1267926e37df1802a31c0fea4afc0f46153926..41194e97ec18a950adcdf87bf404d13816791cdb 100644
--- a/src/org/jitsi/util/swing/VideoContainer.java
+++ b/src/org/jitsi/util/swing/VideoContainer.java
@@ -8,7 +8,6 @@
 
 import java.awt.*;
 import java.awt.event.*;
-import java.lang.reflect.*;
 
 import org.jitsi.util.*;
 
@@ -29,34 +28,12 @@ public class VideoContainer
      */
     private static final long serialVersionUID = 0L;
 
-    /**
-     * The <tt>Logger</tt> used by the <tt>VideoContainer</tt> class and its
-     * instances for logging output.
-     */
-    private static final Logger logger = Logger.getLogger(VideoContainer.class);
-
     /**
      * The default background color.
      */
     public static final Color DEFAULT_BACKGROUND_COLOR
         = OSUtils.IS_MAC ? Color.BLACK : null;
 
-    /**
-     * The name of the instance method of <tt>Component</tt>s added to
-     * <tt>VideoContainer</tt> which creates a new <tt>Component</tt> acting as
-     * a canvas in which the other <tt>Component</tt>s contained in the
-     * <tt>VideoContainer</tt> are painted.
-     */
-    private static final String VIDEO_CANVAS_FACTORY_METHOD_NAME
-        = "createCanvas";
-
-    /**
-     * The <tt>Component</tt> which is the canvas, if any, in which the other
-     * <tt>Component</tt>s contained in this <tt>VideoContainer</tt> are
-     * painted.
-     */
-    private Component canvas;
-
     private int inAddOrRemove;
 
     /**
@@ -87,16 +64,6 @@ public VideoContainer(Component noVideoComponent, boolean conference)
 
         this.noVideoComponent = noVideoComponent;
 
-        /*
-         * JAWTRenderer on Mac OS X will by default occupy the whole video
-         * container and will, consequently, draw a black background. In certain
-         * problematic cases which it will try to provide a workaround, it will
-         * not occupy the whole video container. To make the experience
-         * relatively the same, always use a black background.
-         */
-        if (DEFAULT_BACKGROUND_COLOR != null)
-            setBackground(DEFAULT_BACKGROUND_COLOR);
-
         addContainerListener(
                 new ContainerListener()
                 {
@@ -165,94 +132,6 @@ public void add(Component comp, Object constraints, int index)
                 remove(noVideoComponent);
             }
 
-            if ((canvas == null) || (canvas.getParent() != this))
-            {
-                if (OSUtils.IS_MAC && (comp != canvas))
-                {
-                    /*
-                     * Unless the comp has a createCanvas() method, it makes no
-                     * sense to consider any exception a problem.
-                     */
-                    boolean ignoreException;
-                    Throwable exception;
-
-                    ignoreException = true;
-                    exception = null;
-                    canvas = null;
-
-                    try
-                    {
-                        Method m
-                            = comp.getClass().getMethod(
-                                    VIDEO_CANVAS_FACTORY_METHOD_NAME);
-
-                        if (m != null)
-                        {
-                            ignoreException = false;
-
-                            Object c = m.invoke(comp);
-
-                            if (c instanceof Component)
-                                canvas = (Component) c;
-                        }
-                    }
-                    catch (ClassCastException cce)
-                    {
-                        exception = cce;
-                    }
-                    catch (ExceptionInInitializerError eiie)
-                    {
-                        exception = eiie;
-                    }
-                    catch (IllegalAccessException illegalAccessException)
-                    {
-                        exception = illegalAccessException;
-                    }
-                    catch (IllegalArgumentException illegalArgumentException)
-                    {
-                        exception = illegalArgumentException;
-                    }
-                    catch (InvocationTargetException ita)
-                    {
-                        exception = ita;
-                    }
-                    catch (NoSuchMethodException nsme)
-                    {
-                        exception = nsme;
-                    }
-                    catch (NullPointerException npe)
-                    {
-                        exception = npe;
-                    }
-                    catch (SecurityException se)
-                    {
-                        exception = se;
-                    }
-                    if (canvas != null)
-                        add(canvas, VideoLayout.CANVAS, 0);
-                    else if ((exception != null) && !ignoreException)
-                        logger.error("Failed to create video canvas.", exception);
-                }
-            }
-            if ((canvas != null)
-                    && (canvas.getParent() == this)
-                    && OSUtils.IS_MAC
-                    && (comp != canvas))
-            {
-                /*
-                 * The canvas in which the other components are to be painted
-                 * should always be at index 0. And the order of adding is
-                 * important so no index should be specified.
-                 */
-                index = -1;
-            }
-
-            /*
-             * XXX Do not call #remove(Component) beyond this point and before
-             * #add(Component, Object, int) because #removeCanvasIfNecessary()
-             * will remove the canvas.
-             */
-
             super.add(comp, constraints, index);
         }
         finally
@@ -297,29 +176,10 @@ private void exitAddOrRemove()
 
     private void onContainerEvent(ContainerEvent ev)
     {
-        try
-        {
-            if (DEFAULT_BACKGROUND_COLOR != null)
-            {
-                int componentCount = getComponentCount();
-
-                if ((componentCount == 1)
-                        && (getComponent(0)
-                                == VideoContainer.this.noVideoComponent))
-                {
-                    componentCount = 0;
-                }
-
-                setOpaque(componentCount > 0);
-            }
-        }
-        finally
+        synchronized (syncRoot)
         {
-            synchronized (syncRoot)
-            {
-                if (inAddOrRemove != 0)
-                    validateAndRepaint = true;
-            }
+            if (inAddOrRemove != 0)
+                validateAndRepaint = true;
         }
     }
 
@@ -337,13 +197,6 @@ public void remove(Component comp)
         {
             super.remove(comp);
 
-            if ((comp == canvas)
-                    && (canvas != null)
-                    && (canvas.getParent() != this))
-            {
-                canvas = null;
-            }
-
             Component[] components = getComponents();
             VideoLayout videoLayout = (VideoLayout) getLayout();
             boolean hasComponentsAtCenterRemote = false;
@@ -365,8 +218,6 @@ public void remove(Component comp)
             {
                 add(noVideoComponent, VideoLayout.CENTER_REMOTE);
             }
-
-            removeCanvasIfNecessary();
         }
         finally
         {
@@ -391,9 +242,6 @@ public void removeAll()
         {
             super.removeAll();
 
-            if ((canvas != null) && (canvas.getParent() != this))
-                canvas = null;
-
             if (noVideoComponent != null)
                 add(noVideoComponent, VideoLayout.CENTER_REMOTE);
         }
@@ -402,38 +250,4 @@ public void removeAll()
             exitAddOrRemove();
         }
     }
-
-    /**
-     * Removes {@link #canvas} from this <tt>VideoContainer</tt> if no sibling
-     * <tt>Component</tt> needs it.
-     */
-    private void removeCanvasIfNecessary()
-    {
-        if ((canvas == null) || !OSUtils.IS_MAC)
-            return;
-
-        boolean removeCanvas = true;
-
-        for (Component component : getComponents())
-        {
-            if (component == canvas)
-                continue;
-            try
-            {
-                component.getClass().getMethod(
-                        VIDEO_CANVAS_FACTORY_METHOD_NAME);
-                removeCanvas = false;
-                break;
-            }
-            catch (NoSuchMethodException nsme)
-            {
-                /*
-                 * Ignore it because we already presume that component does not
-                 * need the canvas.
-                 */
-            }
-        }
-        if (removeCanvas)
-            remove(canvas);
-    }
 }
diff --git a/src/org/jitsi/util/swing/VideoLayout.java b/src/org/jitsi/util/swing/VideoLayout.java
index d3a94827df16f84cbc7e3db9433c9688dd7bb5c2..2e34da871666e048d13087b6181a0e2077b89485 100644
--- a/src/org/jitsi/util/swing/VideoLayout.java
+++ b/src/org/jitsi/util/swing/VideoLayout.java
@@ -301,6 +301,7 @@ else if (remoteCount > 0)
             int columns = calculateColumnCount(remotes);
             int columnsMinus1 = columns - 1;
             int rows = (remoteCount + columnsMinus1) / columns;
+            int rowsMinus1 = rows - 1;
             Rectangle bounds
                 = new Rectangle(
                         0,
@@ -314,31 +315,47 @@ else if (remoteCount > 0)
                          */
                         (parentSize.width - (columnsMinus1 * HGAP)) / columns,
                         parentSize.height / rows);
-            int i = 0;
 
-            for (Component remote : remotes)
+            for (int i = 0; i < remoteCount; i++)
             {
+                int column = i % columns;
+                int row = i / columns;
+
                 /*
-                 * We want the remote videos ordered from right to left so that
-                 * the local video does not cover a remote video when possible.
-                 */
-                /*
-                 * We account for the HGAP between the Components being laid out
-                 * by this VideoLayout.
+                 * On the x axis, the first column starts at zero and each
+                 * subsequent column starts relative to the end of its preceding
+                 * column.
                  */
-                bounds.x
-                    = (columnsMinus1 - (i % columns)) * (bounds.width + HGAP);
-                bounds.y = (i / columns) * bounds.height;
+                if (column == 0)
+                {
+                    bounds.x = 0;
+                    /*
+                     * Eventually, there may be empty cells in the last row.
+                     * Center the non-empty cells horizontally.
+                     */
+                    if (row == rowsMinus1)
+                    {
+                        int available = remoteCount - i;
+
+                        if (available < columns)
+                        {
+                            bounds.x
+                                = (parentSize.width
+                                        - available * bounds.width
+                                        - (available - 1) * HGAP)
+                                    / 2;
+                        }
+                    }
+                }
+                else
+                    bounds.x += (bounds.width + HGAP);
+                bounds.y = row * bounds.height;
 
                 super.layoutComponent(
-                        remote,
+                        remotes.get(i),
                         bounds,
                         Component.CENTER_ALIGNMENT,
                         Component.CENTER_ALIGNMENT);
-
-                i++;
-                if (i >= remoteCount)
-                    break;
             }
         }