diff --git a/engine/src/android/com/jme3/app/AndroidHarness.java b/engine/src/android/com/jme3/app/AndroidHarness.java
index 6631003..0ad2ba1 100644
--- a/engine/src/android/com/jme3/app/AndroidHarness.java
+++ b/engine/src/android/com/jme3/app/AndroidHarness.java
@@ -70,6 +70,10 @@
      */
     protected boolean mouseEventsInvertY = true;
     /**
+     * if true finish this activity when the jme app is stopped
+     */
+    protected boolean finishOnAppStop = true;
+    /**
      * Title of the exit dialog, default is "Do you want to exit?"
      */
     protected String exitDialogTitle = "Do you want to exit?";
@@ -131,7 +135,7 @@
         boolean bIsLogFormatSet = false;
         do {
             if (log.getHandlers().length == 0) {
-                log = logger.getParent();
+                log = log.getParent();
                 if (log != null) {
                     for (Handler h : log.getHandlers()) {
                         //h.setFormatter(new SimpleFormatter());
@@ -395,4 +399,10 @@
             }
         }
     }
+
+    public boolean isFinishOnAppStop() {
+        return finishOnAppStop;
+    }
+    
+    
 }
diff --git a/engine/src/android/com/jme3/asset/AndroidAssetManager.java b/engine/src/android/com/jme3/asset/AndroidAssetManager.java
index c6f0b17..b2140dd 100644
--- a/engine/src/android/com/jme3/asset/AndroidAssetManager.java
+++ b/engine/src/android/com/jme3/asset/AndroidAssetManager.java
@@ -37,6 +37,7 @@
 import com.jme3.texture.Texture;
 import com.jme3.texture.plugins.AndroidImageLoader;
 import java.net.URL;
+import java.util.logging.Level;
 import java.util.logging.Logger;
 
 /**
@@ -57,6 +58,14 @@
         //this(Thread.currentThread().getContextClassLoader().getResource("com/jme3/asset/Android.cfg"));
         this(null);
     }
+    
+    private void registerLoaderSafe(Class<? extends AssetLoader> loaderClass, String ... extensions) {
+        try {
+            registerLoader(loaderClass, extensions);
+        } catch (Exception e){
+            logger.log(Level.WARNING, "Failed to load AssetLoader", e);
+        }
+    }
 
     /**
      * AndroidAssetManager constructor
@@ -67,25 +76,29 @@
         System.setProperty("org.xml.sax.driver", "org.xmlpull.v1.sax2.Driver");
 
         // Set Default Android config        	       
-        this.registerLocator("", AndroidLocator.class);
-        this.registerLocator("", ClasspathLocator.class);
-        this.registerLoader(AndroidImageLoader.class, "jpg", "bmp", "gif", "png", "jpeg");
-        this.registerLoader(AndroidAudioLoader.class, "ogg", "mp3", "wav");
-        this.registerLoader(com.jme3.material.plugins.J3MLoader.class, "j3m");
-        this.registerLoader(com.jme3.material.plugins.J3MLoader.class, "j3md");
-        this.registerLoader(com.jme3.font.plugins.BitmapFontLoader.class, "fnt");
-        this.registerLoader(com.jme3.texture.plugins.DDSLoader.class, "dds");
-        this.registerLoader(com.jme3.texture.plugins.PFMLoader.class, "pfm");
-        this.registerLoader(com.jme3.texture.plugins.HDRLoader.class, "hdr");
-        this.registerLoader(com.jme3.texture.plugins.TGALoader.class, "tga");
-        this.registerLoader(com.jme3.export.binary.BinaryImporter.class, "j3o");
-        this.registerLoader(com.jme3.scene.plugins.OBJLoader.class, "obj");
-        this.registerLoader(com.jme3.scene.plugins.MTLLoader.class, "mtl");
-        this.registerLoader(com.jme3.scene.plugins.ogre.MeshLoader.class, "meshxml", "mesh.xml");
-        this.registerLoader(com.jme3.scene.plugins.ogre.SkeletonLoader.class, "skeletonxml", "skeleton.xml");
-        this.registerLoader(com.jme3.scene.plugins.ogre.MaterialLoader.class, "material");
-        this.registerLoader(com.jme3.scene.plugins.ogre.SceneLoader.class, "scene");
-        this.registerLoader(com.jme3.shader.plugins.GLSLLoader.class, "vert", "frag", "glsl", "glsllib");
+        registerLocator("", AndroidLocator.class);
+        registerLocator("", ClasspathLocator.class);
+        
+        registerLoader(AndroidImageLoader.class, "jpg", "bmp", "gif", "png", "jpeg");
+        registerLoader(AndroidAudioLoader.class, "ogg", "mp3", "wav");
+        registerLoader(com.jme3.material.plugins.J3MLoader.class, "j3m");
+        registerLoader(com.jme3.material.plugins.J3MLoader.class, "j3md");
+        registerLoader(com.jme3.shader.plugins.GLSLLoader.class, "vert", "frag", "glsl", "glsllib");
+        registerLoader(com.jme3.export.binary.BinaryImporter.class, "j3o");
+        registerLoader(com.jme3.font.plugins.BitmapFontLoader.class, "fnt");
+        
+        // Less common loaders (especially on Android)
+        registerLoaderSafe(com.jme3.texture.plugins.DDSLoader.class, "dds");
+        registerLoaderSafe(com.jme3.texture.plugins.PFMLoader.class, "pfm");
+        registerLoaderSafe(com.jme3.texture.plugins.HDRLoader.class, "hdr");
+        registerLoaderSafe(com.jme3.texture.plugins.TGALoader.class, "tga");
+        registerLoaderSafe(com.jme3.scene.plugins.OBJLoader.class, "obj");
+        registerLoaderSafe(com.jme3.scene.plugins.MTLLoader.class, "mtl");
+        registerLoaderSafe(com.jme3.scene.plugins.ogre.MeshLoader.class, "mesh.xml");
+        registerLoaderSafe(com.jme3.scene.plugins.ogre.SkeletonLoader.class, "skeleton.xml");
+        registerLoaderSafe(com.jme3.scene.plugins.ogre.MaterialLoader.class, "material");
+        registerLoaderSafe(com.jme3.scene.plugins.ogre.SceneLoader.class, "scene");
+        
 
         logger.info("AndroidAssetManager created.");
     }
diff --git a/engine/src/android/com/jme3/asset/plugins/AndroidLocator.java b/engine/src/android/com/jme3/asset/plugins/AndroidLocator.java
index 01b1cab..225faf3 100644
--- a/engine/src/android/com/jme3/asset/plugins/AndroidLocator.java
+++ b/engine/src/android/com/jme3/asset/plugins/AndroidLocator.java
@@ -4,9 +4,6 @@
 import com.jme3.system.android.JmeAndroidSystem;
 import java.io.IOException;
 import java.io.InputStream;
-import java.net.URL;
-import java.net.URLConnection;
-import java.util.logging.Level;
 import java.util.logging.Logger;
 
 public class AndroidLocator implements AssetLocator {
@@ -80,7 +77,7 @@
         assetPath = assetPath.replace("//", "/");
         try {
             return create(manager, key, assetPath);
-        }catch (IOException ex){
+        } catch (IOException ex) {
             // This is different handling than URL locator
             // since classpath locating would return null at the getResource() 
             // call, otherwise there's a more critical error...
diff --git a/engine/src/android/com/jme3/audio/plugins/AndroidAudioLoader.java b/engine/src/android/com/jme3/audio/plugins/AndroidAudioLoader.java
index fc9c03e..a11425b 100644
--- a/engine/src/android/com/jme3/audio/plugins/AndroidAudioLoader.java
+++ b/engine/src/android/com/jme3/audio/plugins/AndroidAudioLoader.java
@@ -5,15 +5,16 @@
 import com.jme3.audio.android.AndroidAudioData;
 import java.io.IOException;
 
-public class AndroidAudioLoader implements AssetLoader 
-{
+/**
+ * <code>AndroidAudioLoader</code> will create an 
+ * {@link AndroidAudioData} object with the specified asset key.
+ */
+public class AndroidAudioLoader implements AssetLoader {
 
     @Override
-    public Object load(AssetInfo assetInfo) throws IOException 
-    {
+    public Object load(AssetInfo assetInfo) throws IOException {
         AndroidAudioData result = new AndroidAudioData();
-        result.setAssetKey( assetInfo.getKey() );
+        result.setAssetKey(assetInfo.getKey());
         return result;
     }
-
 }
diff --git a/engine/src/android/com/jme3/input/android/AndroidInput.java b/engine/src/android/com/jme3/input/android/AndroidInput.java
index ca1141d..9bbbe4e 100644
--- a/engine/src/android/com/jme3/input/android/AndroidInput.java
+++ b/engine/src/android/com/jme3/input/android/AndroidInput.java
@@ -1,619 +1,620 @@
-package com.jme3.input.android;
-
-import android.content.Context;
-import android.opengl.GLSurfaceView;
-import android.util.AttributeSet;
-import android.view.GestureDetector;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.ScaleGestureDetector;
-import com.jme3.input.KeyInput;
-import com.jme3.input.RawInputListener;
-import com.jme3.input.TouchInput;
-import com.jme3.input.event.MouseButtonEvent;
-import com.jme3.input.event.MouseMotionEvent;
-import com.jme3.input.event.TouchEvent;
-import com.jme3.input.event.TouchEvent.Type;
-import com.jme3.math.Vector2f;
-import com.jme3.util.RingBuffer;
-import java.util.HashMap;
-import java.util.logging.Logger;
-
-/**
- * <code>AndroidInput</code> is one of the main components that connect jme with android. Is derived from GLSurfaceView and handles all Inputs
- * @author larynx
- *
- */
-public class AndroidInput extends GLSurfaceView implements TouchInput,
-        GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener, ScaleGestureDetector.OnScaleGestureListener {
-
-    final private static int MAX_EVENTS = 1024;
-    // Custom settings
-    public boolean mouseEventsEnabled = true;
-    public boolean mouseEventsInvertX = false;
-    public boolean mouseEventsInvertY = false;
-    public boolean keyboardEventsEnabled = false;
-    public boolean dontSendHistory = false;
-    // Used to transfer events from android thread to GLThread
-    final private RingBuffer<TouchEvent> eventQueue = new RingBuffer<TouchEvent>(MAX_EVENTS);
-    final private RingBuffer<TouchEvent> eventPoolUnConsumed = new RingBuffer<TouchEvent>(MAX_EVENTS);
-    final private RingBuffer<TouchEvent> eventPool = new RingBuffer<TouchEvent>(MAX_EVENTS);
-    final private HashMap<Integer, Vector2f> lastPositions = new HashMap<Integer, Vector2f>();
-    // Internal
-    private ScaleGestureDetector scaledetector;
-    private GestureDetector detector;
-    private int lastX;
-    private int lastY;
-    private final static Logger logger = Logger.getLogger(AndroidInput.class.getName());
-    private boolean isInitialized = false;
-    private RawInputListener listener = null;
-    private static final int[] ANDROID_TO_JME = {
-        0x0, // unknown
-        0x0, // key code soft left
-        0x0, // key code soft right
-        KeyInput.KEY_HOME,
-        KeyInput.KEY_ESCAPE, // key back
-        0x0, // key call
-        0x0, // key endcall
-        KeyInput.KEY_0,
-        KeyInput.KEY_1,
-        KeyInput.KEY_2,
-        KeyInput.KEY_3,
-        KeyInput.KEY_4,
-        KeyInput.KEY_5,
-        KeyInput.KEY_6,
-        KeyInput.KEY_7,
-        KeyInput.KEY_8,
-        KeyInput.KEY_9,
-        KeyInput.KEY_MULTIPLY,
-        0x0, // key pound
-        KeyInput.KEY_UP,
-        KeyInput.KEY_DOWN,
-        KeyInput.KEY_LEFT,
-        KeyInput.KEY_RIGHT,
-        KeyInput.KEY_RETURN, // dpad center
-        0x0, // volume up
-        0x0, // volume down
-        KeyInput.KEY_POWER, // power (?)
-        0x0, // camera
-        0x0, // clear
-        KeyInput.KEY_A,
-        KeyInput.KEY_B,
-        KeyInput.KEY_C,
-        KeyInput.KEY_D,
-        KeyInput.KEY_E,
-        KeyInput.KEY_F,
-        KeyInput.KEY_G,
-        KeyInput.KEY_H,
-        KeyInput.KEY_I,
-        KeyInput.KEY_J,
-        KeyInput.KEY_K,
-        KeyInput.KEY_L,
-        KeyInput.KEY_M,
-        KeyInput.KEY_N,
-        KeyInput.KEY_O,
-        KeyInput.KEY_P,
-        KeyInput.KEY_Q,
-        KeyInput.KEY_R,
-        KeyInput.KEY_S,
-        KeyInput.KEY_T,
-        KeyInput.KEY_U,
-        KeyInput.KEY_V,
-        KeyInput.KEY_W,
-        KeyInput.KEY_X,
-        KeyInput.KEY_Y,
-        KeyInput.KEY_Z,
-        KeyInput.KEY_COMMA,
-        KeyInput.KEY_PERIOD,
-        KeyInput.KEY_LMENU,
-        KeyInput.KEY_RMENU,
-        KeyInput.KEY_LSHIFT,
-        KeyInput.KEY_RSHIFT,
-        //        0x0, // fn
-        //        0x0, // cap (?)
-
-        KeyInput.KEY_TAB,
-        KeyInput.KEY_SPACE,
-        0x0, // sym (?) symbol
-        0x0, // explorer
-        0x0, // envelope
-        KeyInput.KEY_RETURN, // newline/enter
-        KeyInput.KEY_DELETE,
-        KeyInput.KEY_GRAVE,
-        KeyInput.KEY_MINUS,
-        KeyInput.KEY_EQUALS,
-        KeyInput.KEY_LBRACKET,
-        KeyInput.KEY_RBRACKET,
-        KeyInput.KEY_BACKSLASH,
-        KeyInput.KEY_SEMICOLON,
-        KeyInput.KEY_APOSTROPHE,
-        KeyInput.KEY_SLASH,
-        KeyInput.KEY_AT, // at (@)
-        KeyInput.KEY_NUMLOCK, //0x0, // num
-        0x0, //headset hook
-        0x0, //focus
-        KeyInput.KEY_ADD,
-        KeyInput.KEY_LMETA, //menu
-        0x0,//notification
-        0x0,//search
-        0x0,//media play/pause
-        0x0,//media stop
-        0x0,//media next
-        0x0,//media previous
-        0x0,//media rewind
-        0x0,//media fastforward
-        0x0,//mute
-    };
-
-    public AndroidInput(Context ctx, AttributeSet attribs) {
-        super(ctx, attribs);
-        detector = new GestureDetector(null, this, null, false);
-        scaledetector = new ScaleGestureDetector(ctx, this);
-
-    }
-
-    public AndroidInput(Context ctx) {
-        super(ctx);
-        detector = new GestureDetector(null, this, null, false);
-        scaledetector = new ScaleGestureDetector(ctx, this);
-    }
-
-    private TouchEvent getNextFreeTouchEvent() {
-        return getNextFreeTouchEvent(false);
-    }
-
-    /**
-     * Fetches a touch event from the reuse pool
-     * @param wait if true waits for a reusable event to get available/released by an other thread, if false returns a new one if needed
-     * @return a usable TouchEvent
-     */
-    private TouchEvent getNextFreeTouchEvent(boolean wait) {
-        TouchEvent evt = null;
-        synchronized (eventPoolUnConsumed) {
-            int size = eventPoolUnConsumed.size();
-            while (size > 0) {
-                evt = eventPoolUnConsumed.pop();
-                if (!evt.isConsumed()) {
-                    eventPoolUnConsumed.push(evt);
-                    evt = null;
-                } else {
-                    break;
-                }
-                size--;
-            }
-        }
-
-
-        if (evt == null) {
-            if (eventPool.isEmpty() && wait) {
-                logger.warning("eventPool buffer underrun");
-                boolean isEmpty;
-                do {
-                    synchronized (eventPool) {
-                        isEmpty = eventPool.isEmpty();
-                    }
-                    try {
-                        Thread.sleep(50);
-                    } catch (InterruptedException e) {
-                    }
-                } while (isEmpty);
-                synchronized (eventPool) {
-                    evt = eventPool.pop();
-                }
-            } else if (eventPool.isEmpty()) {
-                evt = new TouchEvent();
-                logger.warning("eventPool buffer underrun");
-            } else {
-                synchronized (eventPool) {
-                    evt = eventPool.pop();
-                }
-            }
-        }
-        return evt;
-    }
-
-    /**
-     * onTouchEvent gets called from android thread on touchpad events
-     */
-    @Override
-    public boolean onTouchEvent(MotionEvent event) {
-        boolean bWasHandled = false;
-        TouchEvent touch;
-        //    System.out.println("native : " + event.getAction());
-        int action = event.getAction() & MotionEvent.ACTION_MASK;
-        int pointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK)
-                >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
-        int pointerId = event.getPointerId(pointerIndex);
-
-        // final int historySize = event.getHistorySize();
-        //final int pointerCount = event.getPointerCount();
-
-
-        switch (action) {
-
-            case MotionEvent.ACTION_POINTER_DOWN:
-            case MotionEvent.ACTION_DOWN:
-
-
-                touch = getNextFreeTouchEvent();
-                touch.set(Type.DOWN, event.getX(pointerIndex), this.getHeight() - event.getY(pointerIndex), 0, 0);
-                touch.setPointerId(pointerId);
-                touch.setTime(event.getEventTime());
-                touch.setPressure(event.getPressure(pointerIndex));
-                processEvent(touch);
-
-                bWasHandled = true;
-                break;
-
-            case MotionEvent.ACTION_POINTER_UP:
-            case MotionEvent.ACTION_CANCEL:
-            case MotionEvent.ACTION_UP:
-
-                touch = getNextFreeTouchEvent();
-                touch.set(Type.UP, event.getX(pointerIndex), this.getHeight() - event.getY(pointerIndex), 0, 0);
-                touch.setPointerId(pointerId);
-                touch.setTime(event.getEventTime());
-                touch.setPressure(event.getPressure(pointerIndex));
-                processEvent(touch);
-
-
-                bWasHandled = true;
-                break;
-            case MotionEvent.ACTION_MOVE:
-
-
-                // Convert all pointers into events
-                for (int p = 0; p < event.getPointerCount(); p++) {
-                    Vector2f lastPos = lastPositions.get(pointerIndex);
-                    if (lastPos == null) {
-                        lastPos = new Vector2f(event.getX(pointerIndex), this.getHeight() - event.getY(pointerIndex));
-                        lastPositions.put(pointerId, lastPos);
-                    }
-                    touch = getNextFreeTouchEvent();
-                    touch.set(Type.MOVE, event.getX(pointerIndex), this.getHeight() - event.getY(pointerIndex), event.getX(pointerIndex) - lastPos.x, this.getHeight() - event.getY(pointerIndex) - lastPos.y);
-                    touch.setPointerId(pointerId);
-                    touch.setTime(event.getEventTime());
-                    touch.setPressure(event.getPressure(pointerIndex));
-                    processEvent(touch);
-                    lastPos.set(event.getX(pointerIndex), this.getHeight() - event.getY(pointerIndex));
-                }
-                bWasHandled = true;
-                break;
-
-
-            case MotionEvent.ACTION_OUTSIDE:
-                break;
-
-        }
-
-        // Try to detect gestures        
-        this.detector.onTouchEvent(event);
-        this.scaledetector.onTouchEvent(event);
-
-        return bWasHandled;
-    }
-
-    @Override
-    public boolean onKeyDown(int keyCode, KeyEvent event) {
-        TouchEvent evt;
-        evt = getNextFreeTouchEvent();
-        evt.set(TouchEvent.Type.KEY_DOWN);
-        evt.setKeyCode(keyCode);
-        evt.setCharacters(event.getCharacters());
-        evt.setTime(event.getEventTime());
-
-        // Send the event
-        processEvent(evt);
-
-        // Handle all keys ourself except Volume Up/Down
-        if ((keyCode == KeyEvent.KEYCODE_VOLUME_UP) || (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)) {
-            return false;
-        } else {
-            return true;
-        }
-
-    }
-
-    @Override
-    public boolean onKeyUp(int keyCode, KeyEvent event) {
-        TouchEvent evt;
-        evt = getNextFreeTouchEvent();
-        evt.set(TouchEvent.Type.KEY_UP);
-        evt.setKeyCode(keyCode);
-        evt.setCharacters(event.getCharacters());
-        evt.setTime(event.getEventTime());
-
-        // Send the event
-        processEvent(evt);
-
-        // Handle all keys ourself except Volume Up/Down
-        if ((keyCode == KeyEvent.KEYCODE_VOLUME_UP) || (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)) {
-            return false;
-        } else {
-            return true;
-        }
-    }
-
-    // -----------------------------------------
-    // JME3 Input interface
-    @Override
-    public void initialize() {
-        TouchEvent item;
-        for (int i = 0; i < MAX_EVENTS; i++) {
-            item = new TouchEvent();
-            eventPool.push(item);
-        }
-        isInitialized = true;
-    }
-
-    @Override
-    public void destroy() {
-        isInitialized = false;
-
-        // Clean up queues
-        while (!eventPool.isEmpty()) {
-            eventPool.pop();
-        }
-        while (!eventQueue.isEmpty()) {
-            eventQueue.pop();
-        }
-    }
-
-    @Override
-    public boolean isInitialized() {
-        return isInitialized;
-    }
-
-    @Override
-    public void setInputListener(RawInputListener listener) {
-        this.listener = listener;
-    }
-
-    @Override
-    public long getInputTimeNanos() {
-        return System.nanoTime();
-    }
-    // -----------------------------------------
-
-    private void processEvent(TouchEvent event) {
-        synchronized (eventQueue) {
-            eventQueue.push(event);
-        }
-    }
-
-    //  ---------------  INSIDE GLThread  --------------- 
-    @Override
-    public void update() {
-        generateEvents();
-    }
-
-    private void generateEvents() {
-        if (listener != null) {
-            TouchEvent event;
-            MouseButtonEvent btn;
-            int newX;
-            int newY;
-
-            while (!eventQueue.isEmpty()) {
-                synchronized (eventQueue) {
-                    event = eventQueue.pop();
-                }
-                if (event != null) {
-                    listener.onTouchEvent(event);
-
-                    if (mouseEventsEnabled) {
-                        if (mouseEventsInvertX) {
-                            newX = this.getWidth() - (int) event.getX();
-                        } else {
-                            newX = (int) event.getX();
-                        }
-
-                        if (mouseEventsInvertY) {
-                            newY = this.getHeight() - (int) event.getY();
-                        } else {
-                            newY = (int) event.getY();
-                        }
-
-                        switch (event.getType()) {
-                            case DOWN:
-                                // Handle mouse down event 
-                                btn = new MouseButtonEvent(0, true, newX, newY);
-                                btn.setTime(event.getTime());
-                                listener.onMouseButtonEvent(btn);
-                                // Store current pos
-                                lastX = -1;
-                                lastY = -1;
-                                break;
-
-                            case UP:
-                                // Handle mouse up event 
-                                btn = new MouseButtonEvent(0, false, newX, newY);
-                                btn.setTime(event.getTime());
-                                listener.onMouseButtonEvent(btn);
-                                // Store current pos
-                                lastX = -1;
-                                lastY = -1;
-                                break;
-
-                            case MOVE:
-                                int dx;
-                                int dy;
-                                if (lastX != -1) {
-                                    dx = newX - lastX;
-                                    dy = newY - lastY;
-                                } else {
-                                    dx = 0;
-                                    dy = 0;
-                                }
-                                MouseMotionEvent mot = new MouseMotionEvent(newX, newY, dx, dy, 0, 0);
-                                mot.setTime(event.getTime());
-                                listener.onMouseMotionEvent(mot);
-                                lastX = newX;
-                                lastY = newY;
-                                break;
-                        }
-
-
-                    }
-                }
-
-                if (event.isConsumed() == false) {
-                    synchronized (eventPoolUnConsumed) {
-                        eventPoolUnConsumed.push(event);
-                    }
-
-                } else {
-                    synchronized (eventPool) {
-                        eventPool.push(event);
-                    }
-                }
-            }
-
-        }
-    }
-    //  --------------- ENDOF INSIDE GLThread  --------------- 
-
-    // --------------- Gesture detected callback events  --------------- 
-    public boolean onDown(MotionEvent event) {
-        return false;
-    }
-
-    public void onLongPress(MotionEvent event) {
-        TouchEvent touch = getNextFreeTouchEvent();
-        touch.set(Type.LONGPRESSED, event.getX(), this.getHeight() - event.getY(), 0f, 0f);
-        touch.setPointerId(0);
-        touch.setTime(event.getEventTime());
-        processEvent(touch);
-    }
-
-    public boolean onFling(MotionEvent event, MotionEvent event2, float vx, float vy) {
-        TouchEvent touch = getNextFreeTouchEvent();
-        touch.set(Type.FLING, event.getX(), this.getHeight() - event.getY(), vx, vy);
-        touch.setPointerId(0);
-        touch.setTime(event.getEventTime());
-        processEvent(touch);
-
-        return true;
-    }
-
-    public boolean onSingleTapConfirmed(MotionEvent event) {
-        //Nothing to do here the tap has already been detected.
-        return false;
-    }
-
-    public boolean onDoubleTap(MotionEvent event) {
-        TouchEvent touch = getNextFreeTouchEvent();
-        touch.set(Type.DOUBLETAP, event.getX(), this.getHeight() - event.getY(), 0f, 0f);
-        touch.setPointerId(0);
-        touch.setTime(event.getEventTime());
-        processEvent(touch);
-        return true;
-    }
-
-    public boolean onDoubleTapEvent(MotionEvent event) {
-        return false;
-    }
-
-    public boolean onScaleBegin(ScaleGestureDetector scaleGestureDetector) {
-        TouchEvent touch = getNextFreeTouchEvent();
-        touch.set(Type.SCALE_START, scaleGestureDetector.getFocusX(), scaleGestureDetector.getFocusY(), 0f, 0f);
-        touch.setPointerId(0);
-        touch.setTime(scaleGestureDetector.getEventTime());
-        touch.setScaleSpan(scaleGestureDetector.getCurrentSpan());
-        touch.setScaleFactor(scaleGestureDetector.getScaleFactor());
-        processEvent(touch);
-        //    System.out.println("scaleBegin");
-
-        return true;
-    }
-
-    public boolean onScale(ScaleGestureDetector scaleGestureDetector) {
-        TouchEvent touch = getNextFreeTouchEvent();
-        touch.set(Type.SCALE_MOVE, scaleGestureDetector.getFocusX(), this.getHeight() - scaleGestureDetector.getFocusY(), 0f, 0f);
-        touch.setPointerId(0);
-        touch.setTime(scaleGestureDetector.getEventTime());
-        touch.setScaleSpan(scaleGestureDetector.getCurrentSpan());
-        touch.setScaleFactor(scaleGestureDetector.getScaleFactor());
-        processEvent(touch);
-        //   System.out.println("scale");
-
-        return false;
-    }
-
-    public void onScaleEnd(ScaleGestureDetector scaleGestureDetector) {
-        TouchEvent touch = getNextFreeTouchEvent();
-        touch.set(Type.SCALE_END, scaleGestureDetector.getFocusX(), this.getHeight() - scaleGestureDetector.getFocusY(), 0f, 0f);
-        touch.setPointerId(0);
-        touch.setTime(scaleGestureDetector.getEventTime());
-        touch.setScaleSpan(scaleGestureDetector.getCurrentSpan());
-        touch.setScaleFactor(scaleGestureDetector.getScaleFactor());
-        processEvent(touch);
-    }
-
-    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
-        TouchEvent touch = getNextFreeTouchEvent();
-        touch.set(Type.SCROLL, e1.getX(), this.getHeight() - e1.getY(), distanceX, distanceY * (-1));
-        touch.setPointerId(0);
-        touch.setTime(e1.getEventTime());
-        processEvent(touch);
-        //System.out.println("scroll " + e1.getPointerCount());
-        return false;
-    }
-
-    public void onShowPress(MotionEvent event) {
-        TouchEvent touch = getNextFreeTouchEvent();
-        touch.set(Type.SHOWPRESS, event.getX(), this.getHeight() - event.getY(), 0f, 0f);
-        touch.setPointerId(0);
-        touch.setTime(event.getEventTime());
-        processEvent(touch);
-    }
-
-    public boolean onSingleTapUp(MotionEvent event) {
-        TouchEvent touch = getNextFreeTouchEvent();
-        touch.set(Type.TAP, event.getX(), this.getHeight() - event.getY(), 0f, 0f);
-        touch.setPointerId(0);
-        touch.setTime(event.getEventTime());
-        processEvent(touch);
-        return true;
-    }
-
-    @Override
-    public void setSimulateMouse(boolean simulate) {
-        mouseEventsEnabled = simulate;
-    }
-
-    @Override
-    public void setSimulateKeyboard(boolean simulate) {
-        keyboardEventsEnabled = simulate;
-    }
-
-    @Override
-    public void setOmitHistoricEvents(boolean dontSendHistory) {
-        this.dontSendHistory = dontSendHistory;
-    }
-
-    // TODO: move to TouchInput
-    public boolean isMouseEventsEnabled() {
-        return mouseEventsEnabled;
-    }
-
-    public void setMouseEventsEnabled(boolean mouseEventsEnabled) {
-        this.mouseEventsEnabled = mouseEventsEnabled;
-    }
-
-    public boolean isMouseEventsInvertY() {
-        return mouseEventsInvertY;
-    }
-
-    public void setMouseEventsInvertY(boolean mouseEventsInvertY) {
-        this.mouseEventsInvertY = mouseEventsInvertY;
-    }
-
-    public boolean isMouseEventsInvertX() {
-        return mouseEventsInvertX;
-    }
-
-    public void setMouseEventsInvertX(boolean mouseEventsInvertX) {
-        this.mouseEventsInvertX = mouseEventsInvertX;
-    }
-}
+package com.jme3.input.android;
+
+import android.content.Context;
+import android.opengl.GLSurfaceView;
+import android.util.AttributeSet;
+import android.view.GestureDetector;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.ScaleGestureDetector;
+import com.jme3.input.KeyInput;
+import com.jme3.input.RawInputListener;
+import com.jme3.input.TouchInput;
+import com.jme3.input.event.MouseButtonEvent;
+import com.jme3.input.event.MouseMotionEvent;
+import com.jme3.input.event.TouchEvent;
+import com.jme3.input.event.TouchEvent.Type;
+import com.jme3.math.Vector2f;
+import com.jme3.util.RingBuffer;
+import java.util.HashMap;
+import java.util.logging.Logger;
+
+/**
+ * <code>AndroidInput</code> is one of the main components that connect jme with android. Is derived from GLSurfaceView and handles all Inputs
+ * @author larynx
+ *
+ */
+public class AndroidInput extends GLSurfaceView implements 
+        TouchInput,
+        GestureDetector.OnGestureListener, 
+        GestureDetector.OnDoubleTapListener, 
+        ScaleGestureDetector.OnScaleGestureListener {
+
+    final private static int MAX_EVENTS = 1024;
+    // Custom settings
+    public boolean mouseEventsEnabled = true;
+    public boolean mouseEventsInvertX = false;
+    public boolean mouseEventsInvertY = false;
+    public boolean keyboardEventsEnabled = false;
+    public boolean dontSendHistory = false;
+    // Used to transfer events from android thread to GLThread
+    final private RingBuffer<TouchEvent> eventQueue = new RingBuffer<TouchEvent>(MAX_EVENTS);
+    final private RingBuffer<TouchEvent> eventPoolUnConsumed = new RingBuffer<TouchEvent>(MAX_EVENTS);
+    final private RingBuffer<TouchEvent> eventPool = new RingBuffer<TouchEvent>(MAX_EVENTS);
+    final private HashMap<Integer, Vector2f> lastPositions = new HashMap<Integer, Vector2f>();
+    // Internal
+    private ScaleGestureDetector scaledetector;
+    private GestureDetector detector;
+    private int lastX;
+    private int lastY;
+    private final static Logger logger = Logger.getLogger(AndroidInput.class.getName());
+    private boolean isInitialized = false;
+    private RawInputListener listener = null;
+    private static final int[] ANDROID_TO_JME = {
+        0x0, // unknown
+        0x0, // key code soft left
+        0x0, // key code soft right
+        KeyInput.KEY_HOME,
+        KeyInput.KEY_ESCAPE, // key back
+        0x0, // key call
+        0x0, // key endcall
+        KeyInput.KEY_0,
+        KeyInput.KEY_1,
+        KeyInput.KEY_2,
+        KeyInput.KEY_3,
+        KeyInput.KEY_4,
+        KeyInput.KEY_5,
+        KeyInput.KEY_6,
+        KeyInput.KEY_7,
+        KeyInput.KEY_8,
+        KeyInput.KEY_9,
+        KeyInput.KEY_MULTIPLY,
+        0x0, // key pound
+        KeyInput.KEY_UP,
+        KeyInput.KEY_DOWN,
+        KeyInput.KEY_LEFT,
+        KeyInput.KEY_RIGHT,
+        KeyInput.KEY_RETURN, // dpad center
+        0x0, // volume up
+        0x0, // volume down
+        KeyInput.KEY_POWER, // power (?)
+        0x0, // camera
+        0x0, // clear
+        KeyInput.KEY_A,
+        KeyInput.KEY_B,
+        KeyInput.KEY_C,
+        KeyInput.KEY_D,
+        KeyInput.KEY_E,
+        KeyInput.KEY_F,
+        KeyInput.KEY_G,
+        KeyInput.KEY_H,
+        KeyInput.KEY_I,
+        KeyInput.KEY_J,
+        KeyInput.KEY_K,
+        KeyInput.KEY_L,
+        KeyInput.KEY_M,
+        KeyInput.KEY_N,
+        KeyInput.KEY_O,
+        KeyInput.KEY_P,
+        KeyInput.KEY_Q,
+        KeyInput.KEY_R,
+        KeyInput.KEY_S,
+        KeyInput.KEY_T,
+        KeyInput.KEY_U,
+        KeyInput.KEY_V,
+        KeyInput.KEY_W,
+        KeyInput.KEY_X,
+        KeyInput.KEY_Y,
+        KeyInput.KEY_Z,
+        KeyInput.KEY_COMMA,
+        KeyInput.KEY_PERIOD,
+        KeyInput.KEY_LMENU,
+        KeyInput.KEY_RMENU,
+        KeyInput.KEY_LSHIFT,
+        KeyInput.KEY_RSHIFT,
+        //        0x0, // fn
+        //        0x0, // cap (?)
+
+        KeyInput.KEY_TAB,
+        KeyInput.KEY_SPACE,
+        0x0, // sym (?) symbol
+        0x0, // explorer
+        0x0, // envelope
+        KeyInput.KEY_RETURN, // newline/enter
+        KeyInput.KEY_DELETE,
+        KeyInput.KEY_GRAVE,
+        KeyInput.KEY_MINUS,
+        KeyInput.KEY_EQUALS,
+        KeyInput.KEY_LBRACKET,
+        KeyInput.KEY_RBRACKET,
+        KeyInput.KEY_BACKSLASH,
+        KeyInput.KEY_SEMICOLON,
+        KeyInput.KEY_APOSTROPHE,
+        KeyInput.KEY_SLASH,
+        KeyInput.KEY_AT, // at (@)
+        KeyInput.KEY_NUMLOCK, //0x0, // num
+        0x0, //headset hook
+        0x0, //focus
+        KeyInput.KEY_ADD,
+        KeyInput.KEY_LMETA, //menu
+        0x0,//notification
+        0x0,//search
+        0x0,//media play/pause
+        0x0,//media stop
+        0x0,//media next
+        0x0,//media previous
+        0x0,//media rewind
+        0x0,//media fastforward
+        0x0,//mute
+    };
+
+    public AndroidInput(Context ctx, AttributeSet attribs) {
+        super(ctx, attribs);
+        detector = new GestureDetector(null, this, null, false);
+        scaledetector = new ScaleGestureDetector(ctx, this);
+
+    }
+
+    public AndroidInput(Context ctx) {
+        super(ctx);
+        detector = new GestureDetector(null, this, null, false);
+        scaledetector = new ScaleGestureDetector(ctx, this);
+    }
+
+    private TouchEvent getNextFreeTouchEvent() {
+        return getNextFreeTouchEvent(false);
+    }
+
+    /**
+     * Fetches a touch event from the reuse pool
+     * @param wait if true waits for a reusable event to get available/released 
+     * by an other thread, if false returns a new one if needed.
+     * 
+     * @return a usable TouchEvent
+     */
+    private TouchEvent getNextFreeTouchEvent(boolean wait) {
+        TouchEvent evt = null;
+        synchronized (eventPoolUnConsumed) {
+            int size = eventPoolUnConsumed.size();
+            while (size > 0) {
+                evt = eventPoolUnConsumed.pop();
+                if (!evt.isConsumed()) {
+                    eventPoolUnConsumed.push(evt);
+                    evt = null;
+                } else {
+                    break;
+                }
+                size--;
+            }
+        }
+
+        if (evt == null) {
+            if (eventPool.isEmpty() && wait) {
+                logger.warning("eventPool buffer underrun");
+                boolean isEmpty;
+                do {
+                    synchronized (eventPool) {
+                        isEmpty = eventPool.isEmpty();
+                    }
+                    try {
+                        Thread.sleep(50);
+                    } catch (InterruptedException e) {
+                    }
+                } while (isEmpty);
+                synchronized (eventPool) {
+                    evt = eventPool.pop();
+                }
+            } else if (eventPool.isEmpty()) {
+                evt = new TouchEvent();
+                logger.warning("eventPool buffer underrun");
+            } else {
+                synchronized (eventPool) {
+                    evt = eventPool.pop();
+                }
+            }
+        }
+        return evt;
+    }
+
+    /**
+     * onTouchEvent gets called from android thread on touchpad events
+     */
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        boolean bWasHandled = false;
+        TouchEvent touch;
+        //    System.out.println("native : " + event.getAction());
+        int action = event.getAction() & MotionEvent.ACTION_MASK;
+        int pointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK)
+                >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
+        int pointerId = event.getPointerId(pointerIndex);
+
+        // final int historySize = event.getHistorySize();
+        //final int pointerCount = event.getPointerCount();
+
+        switch (action) {
+            case MotionEvent.ACTION_POINTER_DOWN:
+            case MotionEvent.ACTION_DOWN:
+                touch = getNextFreeTouchEvent();
+                touch.set(Type.DOWN, event.getX(pointerIndex), this.getHeight() - event.getY(pointerIndex), 0, 0);
+                touch.setPointerId(pointerId);
+                touch.setTime(event.getEventTime());
+                touch.setPressure(event.getPressure(pointerIndex));
+                processEvent(touch);
+
+                bWasHandled = true;
+                break;
+
+            case MotionEvent.ACTION_POINTER_UP:
+            case MotionEvent.ACTION_CANCEL:
+            case MotionEvent.ACTION_UP:
+
+                touch = getNextFreeTouchEvent();
+                touch.set(Type.UP, event.getX(pointerIndex), this.getHeight() - event.getY(pointerIndex), 0, 0);
+                touch.setPointerId(pointerId);
+                touch.setTime(event.getEventTime());
+                touch.setPressure(event.getPressure(pointerIndex));
+                processEvent(touch);
+
+
+                bWasHandled = true;
+                break;
+            case MotionEvent.ACTION_MOVE:
+
+
+                // Convert all pointers into events
+                for (int p = 0; p < event.getPointerCount(); p++) {
+                    Vector2f lastPos = lastPositions.get(pointerIndex);
+                    if (lastPos == null) {
+                        lastPos = new Vector2f(event.getX(pointerIndex), this.getHeight() - event.getY(pointerIndex));
+                        lastPositions.put(pointerId, lastPos);
+                    }
+                    touch = getNextFreeTouchEvent();
+                    touch.set(Type.MOVE, event.getX(pointerIndex), this.getHeight() - event.getY(pointerIndex), event.getX(pointerIndex) - lastPos.x, this.getHeight() - event.getY(pointerIndex) - lastPos.y);
+                    touch.setPointerId(pointerId);
+                    touch.setTime(event.getEventTime());
+                    touch.setPressure(event.getPressure(pointerIndex));
+                    processEvent(touch);
+                    lastPos.set(event.getX(pointerIndex), this.getHeight() - event.getY(pointerIndex));
+                }
+                bWasHandled = true;
+                break;
+            case MotionEvent.ACTION_OUTSIDE:
+                break;
+
+        }
+
+        // Try to detect gestures        
+        this.detector.onTouchEvent(event);
+        this.scaledetector.onTouchEvent(event);
+
+        return bWasHandled;
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        TouchEvent evt;
+        evt = getNextFreeTouchEvent();
+        evt.set(TouchEvent.Type.KEY_DOWN);
+        evt.setKeyCode(keyCode);
+        evt.setCharacters(event.getCharacters());
+        evt.setTime(event.getEventTime());
+
+        // Send the event
+        processEvent(evt);
+
+        // Handle all keys ourself except Volume Up/Down
+        if ((keyCode == KeyEvent.KEYCODE_VOLUME_UP) || (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)) {
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    @Override
+    public boolean onKeyUp(int keyCode, KeyEvent event) {
+        TouchEvent evt;
+        evt = getNextFreeTouchEvent();
+        evt.set(TouchEvent.Type.KEY_UP);
+        evt.setKeyCode(keyCode);
+        evt.setCharacters(event.getCharacters());
+        evt.setTime(event.getEventTime());
+
+        // Send the event
+        processEvent(evt);
+
+        // Handle all keys ourself except Volume Up/Down
+        if ((keyCode == KeyEvent.KEYCODE_VOLUME_UP) || (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)) {
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    // -----------------------------------------
+    // JME3 Input interface
+    @Override
+    public void initialize() {
+        TouchEvent item;
+        for (int i = 0; i < MAX_EVENTS; i++) {
+            item = new TouchEvent();
+            eventPool.push(item);
+        }
+        isInitialized = true;
+    }
+
+    @Override
+    public void destroy() {
+        isInitialized = false;
+
+        // Clean up queues
+        while (!eventPool.isEmpty()) {
+            eventPool.pop();
+        }
+        while (!eventQueue.isEmpty()) {
+            eventQueue.pop();
+        }
+    }
+
+    @Override
+    public boolean isInitialized() {
+        return isInitialized;
+    }
+
+    @Override
+    public void setInputListener(RawInputListener listener) {
+        this.listener = listener;
+    }
+
+    @Override
+    public long getInputTimeNanos() {
+        return System.nanoTime();
+    }
+    // -----------------------------------------
+
+    private void processEvent(TouchEvent event) {
+        synchronized (eventQueue) {
+            eventQueue.push(event);
+        }
+    }
+
+    //  ---------------  INSIDE GLThread  --------------- 
+    @Override
+    public void update() {
+        generateEvents();
+    }
+
+    private void generateEvents() {
+        if (listener != null) {
+            TouchEvent event;
+            MouseButtonEvent btn;
+            int newX;
+            int newY;
+
+            while (!eventQueue.isEmpty()) {
+                synchronized (eventQueue) {
+                    event = eventQueue.pop();
+                }
+                if (event != null) {
+                    listener.onTouchEvent(event);
+
+                    if (mouseEventsEnabled) {
+                        if (mouseEventsInvertX) {
+                            newX = this.getWidth() - (int) event.getX();
+                        } else {
+                            newX = (int) event.getX();
+                        }
+
+                        if (mouseEventsInvertY) {
+                            newY = this.getHeight() - (int) event.getY();
+                        } else {
+                            newY = (int) event.getY();
+                        }
+
+                        switch (event.getType()) {
+                            case DOWN:
+                                // Handle mouse down event 
+                                btn = new MouseButtonEvent(0, true, newX, newY);
+                                btn.setTime(event.getTime());
+                                listener.onMouseButtonEvent(btn);
+                                // Store current pos
+                                lastX = -1;
+                                lastY = -1;
+                                break;
+
+                            case UP:
+                                // Handle mouse up event 
+                                btn = new MouseButtonEvent(0, false, newX, newY);
+                                btn.setTime(event.getTime());
+                                listener.onMouseButtonEvent(btn);
+                                // Store current pos
+                                lastX = -1;
+                                lastY = -1;
+                                break;
+
+                            case MOVE:
+                                int dx;
+                                int dy;
+                                if (lastX != -1) {
+                                    dx = newX - lastX;
+                                    dy = newY - lastY;
+                                } else {
+                                    dx = 0;
+                                    dy = 0;
+                                }
+                                MouseMotionEvent mot = new MouseMotionEvent(newX, newY, dx, dy, 0, 0);
+                                mot.setTime(event.getTime());
+                                listener.onMouseMotionEvent(mot);
+                                lastX = newX;
+                                lastY = newY;
+                                break;
+                        }
+
+
+                    }
+                }
+
+                if (event.isConsumed() == false) {
+                    synchronized (eventPoolUnConsumed) {
+                        eventPoolUnConsumed.push(event);
+                    }
+
+                } else {
+                    synchronized (eventPool) {
+                        eventPool.push(event);
+                    }
+                }
+            }
+
+        }
+    }
+    //  --------------- ENDOF INSIDE GLThread  --------------- 
+
+    // --------------- Gesture detected callback events  --------------- 
+    public boolean onDown(MotionEvent event) {
+        return false;
+    }
+
+    public void onLongPress(MotionEvent event) {
+        TouchEvent touch = getNextFreeTouchEvent();
+        touch.set(Type.LONGPRESSED, event.getX(), this.getHeight() - event.getY(), 0f, 0f);
+        touch.setPointerId(0);
+        touch.setTime(event.getEventTime());
+        processEvent(touch);
+    }
+
+    public boolean onFling(MotionEvent event, MotionEvent event2, float vx, float vy) {
+        TouchEvent touch = getNextFreeTouchEvent();
+        touch.set(Type.FLING, event.getX(), this.getHeight() - event.getY(), vx, vy);
+        touch.setPointerId(0);
+        touch.setTime(event.getEventTime());
+        processEvent(touch);
+
+        return true;
+    }
+
+    public boolean onSingleTapConfirmed(MotionEvent event) {
+        //Nothing to do here the tap has already been detected.
+        return false;
+    }
+
+    public boolean onDoubleTap(MotionEvent event) {
+        TouchEvent touch = getNextFreeTouchEvent();
+        touch.set(Type.DOUBLETAP, event.getX(), this.getHeight() - event.getY(), 0f, 0f);
+        touch.setPointerId(0);
+        touch.setTime(event.getEventTime());
+        processEvent(touch);
+        return true;
+    }
+
+    public boolean onDoubleTapEvent(MotionEvent event) {
+        return false;
+    }
+
+    public boolean onScaleBegin(ScaleGestureDetector scaleGestureDetector) {
+        TouchEvent touch = getNextFreeTouchEvent();
+        touch.set(Type.SCALE_START, scaleGestureDetector.getFocusX(), scaleGestureDetector.getFocusY(), 0f, 0f);
+        touch.setPointerId(0);
+        touch.setTime(scaleGestureDetector.getEventTime());
+        touch.setScaleSpan(scaleGestureDetector.getCurrentSpan());
+        touch.setScaleFactor(scaleGestureDetector.getScaleFactor());
+        processEvent(touch);
+        //    System.out.println("scaleBegin");
+
+        return true;
+    }
+
+    public boolean onScale(ScaleGestureDetector scaleGestureDetector) {
+        TouchEvent touch = getNextFreeTouchEvent();
+        touch.set(Type.SCALE_MOVE, scaleGestureDetector.getFocusX(), this.getHeight() - scaleGestureDetector.getFocusY(), 0f, 0f);
+        touch.setPointerId(0);
+        touch.setTime(scaleGestureDetector.getEventTime());
+        touch.setScaleSpan(scaleGestureDetector.getCurrentSpan());
+        touch.setScaleFactor(scaleGestureDetector.getScaleFactor());
+        processEvent(touch);
+        //   System.out.println("scale");
+
+        return false;
+    }
+
+    public void onScaleEnd(ScaleGestureDetector scaleGestureDetector) {
+        TouchEvent touch = getNextFreeTouchEvent();
+        touch.set(Type.SCALE_END, scaleGestureDetector.getFocusX(), this.getHeight() - scaleGestureDetector.getFocusY(), 0f, 0f);
+        touch.setPointerId(0);
+        touch.setTime(scaleGestureDetector.getEventTime());
+        touch.setScaleSpan(scaleGestureDetector.getCurrentSpan());
+        touch.setScaleFactor(scaleGestureDetector.getScaleFactor());
+        processEvent(touch);
+    }
+
+    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
+        TouchEvent touch = getNextFreeTouchEvent();
+        touch.set(Type.SCROLL, e1.getX(), this.getHeight() - e1.getY(), distanceX, distanceY * (-1));
+        touch.setPointerId(0);
+        touch.setTime(e1.getEventTime());
+        processEvent(touch);
+        //System.out.println("scroll " + e1.getPointerCount());
+        return false;
+    }
+
+    public void onShowPress(MotionEvent event) {
+        TouchEvent touch = getNextFreeTouchEvent();
+        touch.set(Type.SHOWPRESS, event.getX(), this.getHeight() - event.getY(), 0f, 0f);
+        touch.setPointerId(0);
+        touch.setTime(event.getEventTime());
+        processEvent(touch);
+    }
+
+    public boolean onSingleTapUp(MotionEvent event) {
+        TouchEvent touch = getNextFreeTouchEvent();
+        touch.set(Type.TAP, event.getX(), this.getHeight() - event.getY(), 0f, 0f);
+        touch.setPointerId(0);
+        touch.setTime(event.getEventTime());
+        processEvent(touch);
+        return true;
+    }
+
+    @Override
+    public void setSimulateMouse(boolean simulate) {
+        mouseEventsEnabled = simulate;
+    }
+    @Override
+    public boolean getSimulateMouse() {
+        return mouseEventsEnabled;
+    }
+
+    @Override
+    public void setSimulateKeyboard(boolean simulate) {
+        keyboardEventsEnabled = simulate;
+    }
+
+    @Override
+    public void setOmitHistoricEvents(boolean dontSendHistory) {
+        this.dontSendHistory = dontSendHistory;
+    }
+
+    // TODO: move to TouchInput
+    public boolean isMouseEventsEnabled() {
+        return mouseEventsEnabled;
+    }
+
+    public void setMouseEventsEnabled(boolean mouseEventsEnabled) {
+        this.mouseEventsEnabled = mouseEventsEnabled;
+    }
+
+    public boolean isMouseEventsInvertY() {
+        return mouseEventsInvertY;
+    }
+
+    public void setMouseEventsInvertY(boolean mouseEventsInvertY) {
+        this.mouseEventsInvertY = mouseEventsInvertY;
+    }
+
+    public boolean isMouseEventsInvertX() {
+        return mouseEventsInvertX;
+    }
+
+    public void setMouseEventsInvertX(boolean mouseEventsInvertX) {
+        this.mouseEventsInvertX = mouseEventsInvertX;
+    }
+}
diff --git a/engine/src/android/com/jme3/input/android/AndroidTouchInputListener.java b/engine/src/android/com/jme3/input/android/AndroidTouchInputListener.java
index 34e4592..c8b2228 100644
--- a/engine/src/android/com/jme3/input/android/AndroidTouchInputListener.java
+++ b/engine/src/android/com/jme3/input/android/AndroidTouchInputListener.java
@@ -6,14 +6,17 @@
 import com.jme3.input.event.TouchEvent;
 
 /**
- * AndroidTouchInputListener is an inputlistener interface which defines callbacks/events for android touch screens
- * For use with class AndroidInput
+ * AndroidTouchInputListener is an inputlistener interface which defines
+ * callbacks/events for android touch screens For use with class AndroidInput
+ *
  * @author larynx
  *
  */
-public interface AndroidTouchInputListener extends RawInputListener
-{
+public interface AndroidTouchInputListener extends RawInputListener {
+
     public void onTouchEvent(TouchEvent evt);
+
     public void onMotionEvent(MotionEvent evt);
+
     public void onAndroidKeyEvent(KeyEvent evt);
 }
diff --git a/engine/src/android/com/jme3/renderer/android/OGLESShaderRenderer.java b/engine/src/android/com/jme3/renderer/android/OGLESShaderRenderer.java
index b5a8c14..7e7af29 100644
--- a/engine/src/android/com/jme3/renderer/android/OGLESShaderRenderer.java
+++ b/engine/src/android/com/jme3/renderer/android/OGLESShaderRenderer.java
@@ -31,9 +31,7 @@
  */
 package com.jme3.renderer.android;
 
-import android.graphics.Bitmap;
 import android.opengl.GLES10;
-import android.opengl.GLES11;
 import android.opengl.GLES20;
 import android.os.Build;
 import com.jme3.asset.AndroidImageInfo;
@@ -60,14 +58,11 @@
 import com.jme3.util.BufferUtils;
 import com.jme3.util.ListMap;
 import com.jme3.util.NativeObjectManager;
-import com.jme3.util.SafeArrayList;
 import java.nio.*;
-import java.util.ArrayList;
 import java.util.EnumSet;
 import java.util.List;
 import java.util.logging.Level;
 import java.util.logging.Logger;
-import javax.microedition.khronos.opengles.GL10;
 
 public class OGLESShaderRenderer implements Renderer {
 
@@ -360,25 +355,10 @@
         }
 
         applyRenderState(RenderState.DEFAULT);
-//        GLES20.glClearDepthf(1.0f);
-
-        if (verboseLogging) {
-            logger.info("GLES20.glDisable(GL10.GL_DITHER)");
-        }
-
-        GLES20.glDisable(GL10.GL_DITHER);
+        GLES20.glDisable(GLES20.GL_DITHER);
 
         checkGLError();
 
-        if (verboseLogging) {
-            logger.info("GLES20.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST)");
-        }
-         
-        //It seems that GL10.GL_PERSPECTIVE_CORRECTION_HINT gives invalid_enum error on android.        
-//        GLES20.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
-
-//	checkGLError();
-
         useVBO = false;
         
         // NOTE: SDK_INT is only available since 1.6, 
@@ -1779,10 +1759,8 @@
 
     private int convertWrapMode(Texture.WrapMode mode) {
         switch (mode) {
-//            case BorderClamp:
-//                return GLES20.GL_CLAMP_TO_BORDER;
-//            case Clamp:
-//                return GLES20.GL_CLAMP;
+            case BorderClamp:
+            case Clamp:
             case EdgeClamp:
                 return GLES20.GL_CLAMP_TO_EDGE;
             case Repeat:
@@ -2557,7 +2535,7 @@
                     logger.log(Level.INFO, "glDrawElements(), indexBuf.capacity ({0}), vertCount ({1})", new Object[]{indexBuf.getData().capacity(), vertCount});
                 }
 
-                GLES11.glDrawElements(
+                GLES20.glDrawElements(
                         convertElementMode(mesh.getMode()),
                         indexBuf.getData().capacity(),
                         convertFormat(indexBuf.getFormat()),
diff --git a/engine/src/android/com/jme3/renderer/android/TextureUtil.java b/engine/src/android/com/jme3/renderer/android/TextureUtil.java
index 53b96b4..4a60d6b 100644
--- a/engine/src/android/com/jme3/renderer/android/TextureUtil.java
+++ b/engine/src/android/com/jme3/renderer/android/TextureUtil.java
@@ -70,7 +70,7 @@
             width /= 2;
             Bitmap bitmap2 = Bitmap.createScaledBitmap(bitmap, width, height, true);
 
-            bitmap.recycle();
+            //bitmap.recycle();
             bitmap = bitmap2;
         }
     }
@@ -94,7 +94,7 @@
                 width = FastMath.nearestPowerOfTwo(width);
                 height = FastMath.nearestPowerOfTwo(height);
                 Bitmap bitmap2 = Bitmap.createScaledBitmap(bitmap, width, height, true);
-                bitmap.recycle();
+                //bitmap.recycle();
                 bitmap = bitmap2;
             }
         }
diff --git a/engine/src/android/com/jme3/system/android/AndroidConfigChooser.java b/engine/src/android/com/jme3/system/android/AndroidConfigChooser.java
index e55fa55..56ed415 100644
--- a/engine/src/android/com/jme3/system/android/AndroidConfigChooser.java
+++ b/engine/src/android/com/jme3/system/android/AndroidConfigChooser.java
@@ -2,6 +2,7 @@
 
 import android.graphics.PixelFormat;
 import android.opengl.GLSurfaceView.EGLConfigChooser;
+import java.util.logging.Level;
 import java.util.logging.Logger;
 import javax.microedition.khronos.egl.EGL10;
 import javax.microedition.khronos.egl.EGLConfig;
@@ -9,26 +10,23 @@
 
 /**
  * AndroidConfigChooser is used to determine the best suited EGL Config
- * @author larynx
  *
+ * @author larynx
  */
-public class AndroidConfigChooser implements EGLConfigChooser 
-{
+public class AndroidConfigChooser implements EGLConfigChooser {
+
     private static final Logger logger = Logger.getLogger(AndroidConfigChooser.class.getName());
-    
     protected int clientOpenGLESVersion = 0;
     protected EGLConfig bestConfig = null;
     protected EGLConfig fastestConfig = null;
     protected EGLConfig choosenConfig = null;
     protected ConfigType type;
     protected int pixelFormat;
-    
     protected boolean verbose = false;
-    
     private final static int EGL_OPENGL_ES2_BIT = 4;
 
-    public enum ConfigType 
-    {
+    public enum ConfigType {
+
         /**
          * RGB565, 0 alpha, 16 depth, 0 stencil
          */
@@ -39,94 +37,79 @@
         BEST,
         /**
          * Turn off config chooser and use hardcoded
-         * setEGLContextClientVersion(2);
-         * setEGLConfigChooser(5, 6, 5, 0, 16, 0);
+         * setEGLContextClientVersion(2); setEGLConfigChooser(5, 6, 5, 0, 16,
+         * 0);
          */
         LEGACY
     }
-    
-    public AndroidConfigChooser(ConfigType type, boolean verbose)
-    {
+
+    public AndroidConfigChooser(ConfigType type) {
         this.type = type;
-        this.verbose = verbose;
     }
-        
+
     /**
      * Gets called by the GLSurfaceView class to return the best config
-     */    
+     */
     @Override
-    public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display)
-    {
+    public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
         logger.info("GLSurfaceView asks for egl config, returning: ");
         logEGLConfig(choosenConfig, display, egl);
         return choosenConfig;
     }
-    
+
     /**
      * findConfig is used to locate the best config and init the chooser with
+     *
      * @param egl
      * @param display
      * @return true if successfull, false if no config was found
      */
-    public boolean findConfig(EGL10 egl, EGLDisplay display)
-    {           
-        
-        if (type == ConfigType.BEST)
-        {        	
-        	ComponentSizeChooser compChooser = new ComponentSizeChooser(8, 8, 8, 8, 32, 0);
-        	choosenConfig = compChooser.chooseConfig(egl, display);
+    public boolean findConfig(EGL10 egl, EGLDisplay display) {
 
-        	if (choosenConfig == null)
-        	{
+        if (type == ConfigType.BEST) {
+            ComponentSizeChooser compChooser = new ComponentSizeChooser(8, 8, 8, 8, 32, 0);
+            choosenConfig = compChooser.chooseConfig(egl, display);
+
+            if (choosenConfig == null) {
                 compChooser = new ComponentSizeChooser(8, 8, 8, 0, 32, 0);
                 choosenConfig = compChooser.chooseConfig(egl, display);
-                if (choosenConfig == null)
-                {
+                if (choosenConfig == null) {
                     compChooser = new ComponentSizeChooser(8, 8, 8, 8, 16, 0);
                     choosenConfig = compChooser.chooseConfig(egl, display);
-                    if (choosenConfig == null)
-                    {
+                    if (choosenConfig == null) {
                         compChooser = new ComponentSizeChooser(8, 8, 8, 0, 16, 0);
                         choosenConfig = compChooser.chooseConfig(egl, display);
                     }
                 }
-        	}
-        	
+            }
+
             logger.info("JME3 using best EGL configuration available here: ");
-        }
-        else
-        {
-        	ComponentSizeChooser compChooser = new ComponentSizeChooser(5, 6, 5, 0, 16, 0);
-        	choosenConfig = compChooser.chooseConfig(egl, display);
+        } else {
+            ComponentSizeChooser compChooser = new ComponentSizeChooser(5, 6, 5, 0, 16, 0);
+            choosenConfig = compChooser.chooseConfig(egl, display);
             logger.info("JME3 using fastest EGL configuration available here: ");
         }
-        
-        if (choosenConfig != null)
-        {
-            logger.info("JME3 using choosen config: "); 
-            logEGLConfig(choosenConfig, display, egl);               
+
+        if (choosenConfig != null) {
+            logger.info("JME3 using choosen config: ");
+            logEGLConfig(choosenConfig, display, egl);
             pixelFormat = getPixelFormat(choosenConfig, display, egl);
             clientOpenGLESVersion = getOpenGLVersion(choosenConfig, display, egl);
             return true;
-        }
-        else
-        {
+        } else {
             logger.severe("###ERROR### Unable to get a valid OpenGL ES 2.0 config, nether Fastest nor Best found! Bug. Please report this.");
             clientOpenGLESVersion = 1;
             pixelFormat = PixelFormat.UNKNOWN;
             return false;
-        }        
+        }
     }
-    
-    
-    private int getPixelFormat(EGLConfig conf, EGLDisplay display, EGL10 egl)
-    {
+
+    private int getPixelFormat(EGLConfig conf, EGLDisplay display, EGL10 egl) {
         int[] value = new int[1];
-        int result = PixelFormat.RGB_565;                
+        int result = PixelFormat.RGB_565;
 
         egl.eglGetConfigAttrib(display, conf, EGL10.EGL_RED_SIZE, value);
-        if (value[0] == 8)
-        {
+        if (value[0] == 8) {
             result = PixelFormat.RGBA_8888;
             /*
             egl.eglGetConfigAttrib(display, conf, EGL10.EGL_ALPHA_SIZE, value);
@@ -139,165 +122,163 @@
                 result = PixelFormat.RGB_888;
             }*/
         }
-        
-        if (verbose)
-        {
-            logger.info("Using PixelFormat " + result);                            
+
+        if (verbose) {
+            logger.log(Level.INFO, "Using PixelFormat {0}", result);
         }
-    
+
         //return result; TODO Test pixelformat
         return PixelFormat.TRANSPARENT;
     }
-    
-    private int getOpenGLVersion(EGLConfig conf, EGLDisplay display, EGL10 egl)
-    {
+
+    private int getOpenGLVersion(EGLConfig conf, EGLDisplay display, EGL10 egl) {
         int[] value = new int[1];
         int result = 1;
-                        
+
         egl.eglGetConfigAttrib(display, conf, EGL10.EGL_RENDERABLE_TYPE, value);
         // Check if conf is OpenGL ES 2.0
-        if ((value[0] & EGL_OPENGL_ES2_BIT) != 0)
-        {
+        if ((value[0] & EGL_OPENGL_ES2_BIT) != 0) {
             result = 2;
         }
 
-        return result;                    
+        return result;
     }
-    
+
     /**
      * log output with egl config details
+     *
      * @param conf
      * @param display
      * @param egl
      */
-    public void logEGLConfig(EGLConfig conf, EGLDisplay display, EGL10 egl)
-    {
+    public void logEGLConfig(EGLConfig conf, EGLDisplay display, EGL10 egl) {
         int[] value = new int[1];
 
         egl.eglGetConfigAttrib(display, conf, EGL10.EGL_RED_SIZE, value);
-        logger.info(String.format("EGL_RED_SIZE  = %d", value[0] ) );
-        
+        logger.info(String.format("EGL_RED_SIZE  = %d", value[0]));
+
         egl.eglGetConfigAttrib(display, conf, EGL10.EGL_GREEN_SIZE, value);
-        logger.info(String.format("EGL_GREEN_SIZE  = %d", value[0] ) );
-        
+        logger.info(String.format("EGL_GREEN_SIZE  = %d", value[0]));
+
         egl.eglGetConfigAttrib(display, conf, EGL10.EGL_BLUE_SIZE, value);
-        logger.info(String.format("EGL_BLUE_SIZE  = %d", value[0] ) );
-        
+        logger.info(String.format("EGL_BLUE_SIZE  = %d", value[0]));
+
         egl.eglGetConfigAttrib(display, conf, EGL10.EGL_ALPHA_SIZE, value);
-        logger.info(String.format("EGL_ALPHA_SIZE  = %d", value[0] ) );
-        
+        logger.info(String.format("EGL_ALPHA_SIZE  = %d", value[0]));
+
         egl.eglGetConfigAttrib(display, conf, EGL10.EGL_DEPTH_SIZE, value);
-        logger.info(String.format("EGL_DEPTH_SIZE  = %d", value[0] ) );
-                
+        logger.info(String.format("EGL_DEPTH_SIZE  = %d", value[0]));
+
         egl.eglGetConfigAttrib(display, conf, EGL10.EGL_STENCIL_SIZE, value);
-        logger.info(String.format("EGL_STENCIL_SIZE  = %d", value[0] ) );
+        logger.info(String.format("EGL_STENCIL_SIZE  = %d", value[0]));
 
         egl.eglGetConfigAttrib(display, conf, EGL10.EGL_RENDERABLE_TYPE, value);
-        logger.info(String.format("EGL_RENDERABLE_TYPE  = %d", value[0] ) );
-        
+        logger.info(String.format("EGL_RENDERABLE_TYPE  = %d", value[0]));
+
         egl.eglGetConfigAttrib(display, conf, EGL10.EGL_SURFACE_TYPE, value);
-        logger.info(String.format("EGL_SURFACE_TYPE  = %d", value[0] ) );               
+        logger.info(String.format("EGL_SURFACE_TYPE  = %d", value[0]));
     }
-        
-    public int getClientOpenGLESVersion() 
-    {
+
+    public int getClientOpenGLESVersion() {
         return clientOpenGLESVersion;
     }
 
-    public void setClientOpenGLESVersion(int clientOpenGLESVersion) 
-    {
+    public void setClientOpenGLESVersion(int clientOpenGLESVersion) {
         this.clientOpenGLESVersion = clientOpenGLESVersion;
     }
-    
-    public int getPixelFormat() 
-    {
+
+    public int getPixelFormat() {
         return pixelFormat;
     }
-    
-    
-    
-    private abstract class BaseConfigChooser implements EGLConfigChooser 
-    {
+
+    private abstract class BaseConfigChooser implements EGLConfigChooser {
+
         private boolean bClientOpenGLESVersionSet;
-        
-		public BaseConfigChooser(int[] configSpec) 
-		{
-		    bClientOpenGLESVersionSet = false;
-		    mConfigSpec = filterConfigSpec(configSpec);
-		}
-		
-		public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) 
-		{
-		    int[] num_config = new int[1];
-		    if (!egl.eglChooseConfig(display, mConfigSpec, null, 0,
-		            num_config)) {
-		        throw new IllegalArgumentException("eglChooseConfig failed");
-		    }
-		
-		    int numConfigs = num_config[0];
-		
-		    if (numConfigs <= 0) 
-		    {
-		        //throw new IllegalArgumentException("No configs match configSpec");
-		        
-		        return null;
-		    }
-		
-		    EGLConfig[] configs = new EGLConfig[numConfigs];
-		    if (!egl.eglChooseConfig(display, mConfigSpec, configs, numConfigs,
-		            num_config)) {
-		        throw new IllegalArgumentException("eglChooseConfig#2 failed");
-		    }
-		    EGLConfig config = chooseConfig(egl, display, configs);
-		    //if (config == null) {
-		    //    throw new IllegalArgumentException("No config chosen");
-		    //}
-		    return config;
-		}
-		
-		abstract EGLConfig chooseConfig(EGL10 egl, EGLDisplay display,
-		        EGLConfig[] configs);
-		
-		protected int[] mConfigSpec;
-		
-		private int[] filterConfigSpec(int[] configSpec) 
-		{
-		    if (bClientOpenGLESVersionSet == true) {
-		        return configSpec;
-		    }
-		    /* We know none of the subclasses define EGL_RENDERABLE_TYPE.
-		     * And we know the configSpec is well formed.
-		     */
-		    int len = configSpec.length;
-		    int[] newConfigSpec = new int[len + 2];
-		    System.arraycopy(configSpec, 0, newConfigSpec, 0, len-1);
-		    newConfigSpec[len-1] = EGL10.EGL_RENDERABLE_TYPE;
-		    newConfigSpec[len] = 4; /* EGL_OPENGL_ES2_BIT */
-		    newConfigSpec[len+1] = EGL10.EGL_NONE;
-		    
-		    bClientOpenGLESVersionSet = true;
-		    
-		    return newConfigSpec;
-		}
+
+        public BaseConfigChooser(int[] configSpec) {
+            bClientOpenGLESVersionSet = false;
+            mConfigSpec = filterConfigSpec(configSpec);
+        }
+
+        public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
+            int[] num_config = new int[1];
+            if (!egl.eglChooseConfig(display, mConfigSpec, null, 0,
+                    num_config)) {
+                throw new IllegalArgumentException("eglChooseConfig failed");
+            }
+
+            int numConfigs = num_config[0];
+
+            if (numConfigs <= 0) {
+                //throw new IllegalArgumentException("No configs match configSpec");
+
+                return null;
+            }
+
+            EGLConfig[] configs = new EGLConfig[numConfigs];
+            if (!egl.eglChooseConfig(display, mConfigSpec, configs, numConfigs,
+                    num_config)) {
+                throw new IllegalArgumentException("eglChooseConfig#2 failed");
+            }
+            EGLConfig config = chooseConfig(egl, display, configs);
+            //if (config == null) {
+            //    throw new IllegalArgumentException("No config chosen");
+            //}
+            return config;
+        }
+
+        abstract EGLConfig chooseConfig(EGL10 egl, EGLDisplay display,
+                EGLConfig[] configs);
+        protected int[] mConfigSpec;
+
+        private int[] filterConfigSpec(int[] configSpec) {
+            if (bClientOpenGLESVersionSet == true) {
+                return configSpec;
+            }
+            /*
+             * We know none of the subclasses define EGL_RENDERABLE_TYPE. And we
+             * know the configSpec is well formed.
+             */
+            int len = configSpec.length;
+            int[] newConfigSpec = new int[len + 2];
+            System.arraycopy(configSpec, 0, newConfigSpec, 0, len - 1);
+            newConfigSpec[len - 1] = EGL10.EGL_RENDERABLE_TYPE;
+            newConfigSpec[len] = 4; /*
+             * EGL_OPENGL_ES2_BIT
+             */
+            newConfigSpec[len + 1] = EGL10.EGL_NONE;
+
+            bClientOpenGLESVersionSet = true;
+
+            return newConfigSpec;
+        }
     }
-    
+
     /**
-     * Choose a configuration with exactly the specified r,g,b,a sizes,
-     * and at least the specified depth and stencil sizes.
+     * Choose a configuration with exactly the specified r,g,b,a sizes, and at
+     * least the specified depth and stencil sizes.
      */
-    private class ComponentSizeChooser extends BaseConfigChooser 
-    {
+    private class ComponentSizeChooser extends BaseConfigChooser {
+
+        private int[] mValue;
+        // Subclasses can adjust these values:
+        protected int mRedSize;
+        protected int mGreenSize;
+        protected int mBlueSize;
+        protected int mAlphaSize;
+        protected int mDepthSize;
+        protected int mStencilSize;
+        
         public ComponentSizeChooser(int redSize, int greenSize, int blueSize,
-                int alphaSize, int depthSize, int stencilSize) 
-        {
-            super(new int[] {
-                    EGL10.EGL_RED_SIZE, redSize,
-                    EGL10.EGL_GREEN_SIZE, greenSize,
-                    EGL10.EGL_BLUE_SIZE, blueSize,
-                    EGL10.EGL_ALPHA_SIZE, alphaSize,
-                    EGL10.EGL_DEPTH_SIZE, depthSize,
-                    EGL10.EGL_STENCIL_SIZE, stencilSize,
-                    EGL10.EGL_NONE});
+                int alphaSize, int depthSize, int stencilSize) {
+            super(new int[]{
+                        EGL10.EGL_RED_SIZE, redSize,
+                        EGL10.EGL_GREEN_SIZE, greenSize,
+                        EGL10.EGL_BLUE_SIZE, blueSize,
+                        EGL10.EGL_ALPHA_SIZE, alphaSize,
+                        EGL10.EGL_DEPTH_SIZE, depthSize,
+                        EGL10.EGL_STENCIL_SIZE, stencilSize,
+                        EGL10.EGL_NONE});
             mValue = new int[1];
             mRedSize = redSize;
             mGreenSize = greenSize;
@@ -305,25 +286,22 @@
             mAlphaSize = alphaSize;
             mDepthSize = depthSize;
             mStencilSize = stencilSize;
-       }
+        }
 
         @Override
-        public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display, EGLConfig[] configs) 
-        {
-            for (EGLConfig config : configs) 
-            {
+        public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display, EGLConfig[] configs) {
+            for (EGLConfig config : configs) {
                 int d = findConfigAttrib(egl, display, config,
                         EGL10.EGL_DEPTH_SIZE, 0);
                 int s = findConfigAttrib(egl, display, config,
                         EGL10.EGL_STENCIL_SIZE, 0);
-                if ((d >= mDepthSize) && (s >= mStencilSize)) 
-                {
+                if ((d >= mDepthSize) && (s >= mStencilSize)) {
                     int r = findConfigAttrib(egl, display, config,
                             EGL10.EGL_RED_SIZE, 0);
                     int g = findConfigAttrib(egl, display, config,
-                             EGL10.EGL_GREEN_SIZE, 0);
+                            EGL10.EGL_GREEN_SIZE, 0);
                     int b = findConfigAttrib(egl, display, config,
-                              EGL10.EGL_BLUE_SIZE, 0);
+                            EGL10.EGL_BLUE_SIZE, 0);
                     int a = findConfigAttrib(egl, display, config,
                             EGL10.EGL_ALPHA_SIZE, 0);
                     if ((r == mRedSize) && (g == mGreenSize)
@@ -336,27 +314,12 @@
         }
 
         private int findConfigAttrib(EGL10 egl, EGLDisplay display,
-                EGLConfig config, int attribute, int defaultValue) 
-        {
+                EGLConfig config, int attribute, int defaultValue) {
 
-            if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) 
-            {
+            if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) {
                 return mValue[0];
             }
             return defaultValue;
         }
-
-        private int[] mValue;
-        // Subclasses can adjust these values:
-        protected int mRedSize;
-        protected int mGreenSize;
-        protected int mBlueSize;
-        protected int mAlphaSize;
-        protected int mDepthSize;
-        protected int mStencilSize;
     }
-    
-    
-    
-    
 }
diff --git a/engine/src/android/com/jme3/system/android/OGLESContext.java b/engine/src/android/com/jme3/system/android/OGLESContext.java
index 668b68d..1ecf2e1 100644
--- a/engine/src/android/com/jme3/system/android/OGLESContext.java
+++ b/engine/src/android/com/jme3/system/android/OGLESContext.java
@@ -32,26 +32,37 @@
 package com.jme3.system.android;
 
 import android.app.Activity;
+import android.app.AlertDialog;
 import android.content.Context;
+import android.content.DialogInterface;
 import android.opengl.GLSurfaceView;
+import android.text.InputType;
+import android.view.Gravity;
 import android.view.SurfaceHolder;
+import android.view.ViewGroup.LayoutParams;
+import android.widget.EditText;
+import android.widget.FrameLayout;
 import com.jme3.app.AndroidHarness;
 import com.jme3.app.Application;
 import com.jme3.input.JoyInput;
 import com.jme3.input.KeyInput;
 import com.jme3.input.MouseInput;
+import com.jme3.input.SoftTextDialogInput;
 import com.jme3.input.TouchInput;
 import com.jme3.input.android.AndroidInput;
+import com.jme3.input.controls.SoftTextDialogInputListener;
 import com.jme3.input.controls.TouchTrigger;
 import com.jme3.input.dummy.DummyKeyInput;
 import com.jme3.input.dummy.DummyMouseInput;
 import com.jme3.renderer.android.OGLESShaderRenderer;
 import com.jme3.system.AppSettings;
 import com.jme3.system.JmeContext;
+import com.jme3.system.JmeSystem;
 import com.jme3.system.SystemListener;
 import com.jme3.system.Timer;
 import com.jme3.system.android.AndroidConfigChooser.ConfigType;
 import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.logging.Level;
 import java.util.logging.Logger;
 import javax.microedition.khronos.egl.EGL10;
 import javax.microedition.khronos.egl.EGLConfig;
@@ -59,7 +70,7 @@
 import javax.microedition.khronos.egl.EGLDisplay;
 import javax.microedition.khronos.opengles.GL10;
 
-public class OGLESContext implements JmeContext, GLSurfaceView.Renderer {
+public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTextDialogInput {
 
     private static final Logger logger = Logger.getLogger(OGLESContext.class.getName());
     protected final AtomicBoolean created = new AtomicBoolean(false);
@@ -76,7 +87,6 @@
     protected boolean autoFlush = true;
     protected AndroidInput view;
     private boolean firstDrawFrame = true;
-
     //protected int minFrameDuration = 1000 / frameRate;  // Set a max FPS of 33
     protected int minFrameDuration = 0;                   // No FPS cap
     /**
@@ -145,12 +155,12 @@
 
             int[] version = new int[2];
             if (egl.eglInitialize(display, version) == true) {
-                logger.info("Display EGL Version: " + version[0] + "." + version[1]);
+                logger.log(Level.INFO, "Display EGL Version: {0}.{1}", new Object[]{version[0], version[1]});
             }
 
             try {
                 // Create a config chooser
-                AndroidConfigChooser configChooser = new AndroidConfigChooser(configType, eglConfigVerboseLogging);
+                AndroidConfigChooser configChooser = new AndroidConfigChooser(configType);
                 // Init chooser
                 if (!configChooser.findConfig(egl, display)) {
                     listener.handleError("Unable to find suitable EGL config", null);
@@ -162,7 +172,7 @@
                     listener.handleError("OpenGL ES 2.0 is not supported on this device", null);
                     return null;
                 }
-                
+
                 // Requesting client version from GLSurfaceView which is extended by
                 // AndroidInput.
                 view.setEGLContextClientVersion(clientOpenGLESVersion);
@@ -210,12 +220,14 @@
         // Setup unhandled Exception Handler
         if (ctx instanceof AndroidHarness) {
             Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
+
                 public void uncaughtException(Thread thread, Throwable thrown) {
                     ((AndroidHarness) ctx).handleError("Exception thrown in " + thread.toString(), thrown);
                 }
             });
         } else {
             Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
+
                 public void uncaughtException(Thread thread, Throwable thrown) {
                     listener.handleError("Exception thrown in " + thread.toString(), thrown);
                 }
@@ -244,6 +256,8 @@
             }
         }
 
+        JmeSystem.setSoftTextDialogInput(this);
+
         needClose.set(false);
         renderable.set(true);
     }
@@ -268,6 +282,13 @@
             logger.info("Display destroyed.");
 
             renderable.set(false);
+            final Context ctx = this.view.getContext();
+            if (ctx instanceof AndroidHarness) {
+                AndroidHarness harness = (AndroidHarness) ctx;
+                if (harness.isFinishOnAppStop()) {
+                    harness.finish();
+                }
+            }
         }
     }
 
@@ -442,4 +463,67 @@
     public int getClientOpenGLESVersion() {
         return clientOpenGLESVersion;
     }
+
+    public void requestDialog(final int id, final String title, final String initialValue, final SoftTextDialogInputListener listener) {
+        logger.log(Level.INFO, "requestDialog: title: {0}, initialValue: {1}",
+                new Object[]{title, initialValue});
+
+        JmeAndroidSystem.getActivity().runOnUiThread(new Runnable() {
+
+            @Override
+            public void run() {
+
+                final FrameLayout layoutTextDialogInput = new FrameLayout(JmeAndroidSystem.getActivity());
+                final EditText editTextDialogInput = new EditText(JmeAndroidSystem.getActivity());
+                editTextDialogInput.setWidth(LayoutParams.FILL_PARENT);
+                editTextDialogInput.setHeight(LayoutParams.FILL_PARENT);
+                editTextDialogInput.setPadding(20, 20, 20, 20);
+                editTextDialogInput.setGravity(Gravity.FILL_HORIZONTAL);
+
+                editTextDialogInput.setText(initialValue);
+
+                switch (id) {
+                    case SoftTextDialogInput.TEXT_ENTRY_DIALOG:
+
+                        editTextDialogInput.setInputType(InputType.TYPE_CLASS_TEXT);
+                        break;
+
+                    case SoftTextDialogInput.NUMERIC_ENTRY_DIALOG:
+
+                        editTextDialogInput.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL | InputType.TYPE_NUMBER_FLAG_SIGNED);
+                        break;
+
+                    case SoftTextDialogInput.NUMERIC_KEYPAD_DIALOG:
+
+                        editTextDialogInput.setInputType(InputType.TYPE_CLASS_PHONE);
+                        break;
+
+                    default:
+                        break;
+                }
+
+                layoutTextDialogInput.addView(editTextDialogInput);
+
+                AlertDialog dialogTextInput = new AlertDialog.Builder(JmeAndroidSystem.getActivity()).setTitle(title).setView(layoutTextDialogInput).setPositiveButton("OK",
+                        new DialogInterface.OnClickListener() {
+
+                            public void onClick(DialogInterface dialog, int whichButton) {
+                                /* User clicked OK, send COMPLETE action
+                                 * and text */
+                                listener.onSoftText(SoftTextDialogInputListener.COMPLETE, editTextDialogInput.getText().toString());
+                            }
+                        }).setNegativeButton("Cancel",
+                        new DialogInterface.OnClickListener() {
+
+                            public void onClick(DialogInterface dialog, int whichButton) {
+                                /* User clicked CANCEL, send CANCEL action
+                                 * and text */
+                                listener.onSoftText(SoftTextDialogInputListener.CANCEL, editTextDialogInput.getText().toString());
+                            }
+                        }).create();
+
+                dialogTextInput.show();
+            }
+        });
+    }
 }
diff --git a/engine/src/android/com/jme3/util/AndroidLogHandler.java b/engine/src/android/com/jme3/util/AndroidLogHandler.java
index 8fb21c2..1da1299 100644
--- a/engine/src/android/com/jme3/util/AndroidLogHandler.java
+++ b/engine/src/android/com/jme3/util/AndroidLogHandler.java
@@ -4,7 +4,12 @@
 import java.util.logging.Handler;
 import java.util.logging.Level;
 import java.util.logging.LogRecord;
+import java.util.logging.Logger;
 
+/**
+ * Converts from Java based logging ({@link Logger} to Android based
+ * logging {@link Log}.
+ */
 public class AndroidLogHandler extends Handler {
 
     @Override
@@ -21,17 +26,16 @@
         String clsName = record.getSourceClassName();
         String msg = record.getMessage();
         Throwable t = record.getThrown();
-        if (level == Level.INFO){
+        if (level == Level.INFO) {
             Log.i(clsName, msg, t);
-        }else if (level == Level.SEVERE){
+        } else if (level == Level.SEVERE) {
             Log.e(clsName, msg, t);
-        }else if (level == Level.WARNING){
+        } else if (level == Level.WARNING) {
             Log.w(clsName, msg, t);
-        }else if (level == Level.CONFIG){
+        } else if (level == Level.CONFIG) {
             Log.d(clsName, msg, t);
-        }else if (level == Level.FINE || level == Level.FINER || level == Level.FINEST){
+        } else if (level == Level.FINE || level == Level.FINER || level == Level.FINEST) {
             Log.v(clsName, msg, t);
         }
     }
-
 }
diff --git a/engine/src/android/com/jme3/util/RingBuffer.java b/engine/src/android/com/jme3/util/RingBuffer.java
index 786417b..1d3c22d 100644
--- a/engine/src/android/com/jme3/util/RingBuffer.java
+++ b/engine/src/android/com/jme3/util/RingBuffer.java
@@ -4,20 +4,21 @@
 import java.util.NoSuchElementException;
 
 /**
- * Ring buffer (fixed size queue) implementation using a circular array (array with wrap-around).
+ * Ring buffer (fixed size queue) implementation using a circular array (array
+ * with wrap-around).
  */
 // suppress unchecked warnings in Java 1.5.0_6 and later
 @SuppressWarnings("unchecked")
-public class RingBuffer<Item> implements Iterable<Item> {
+public class RingBuffer<T> implements Iterable<T> {
 
-    private Item[] buffer;          // queue elements
+    private T[] buffer;          // queue elements
     private int count = 0;          // number of elements on queue
     private int indexOut = 0;       // index of first element of queue
     private int indexIn = 0;       // index of next available slot
 
     // cast needed since no generic array creation in Java
     public RingBuffer(int capacity) {
-        buffer = (Item[]) new Object[capacity];
+        buffer = (T[]) new Object[capacity];
     }
 
     public boolean isEmpty() {
@@ -28,7 +29,7 @@
         return count;
     }
 
-    public void push(Item item) {
+    public void push(T item) {
         if (count == buffer.length) {
             throw new RuntimeException("Ring buffer overflow");
         }
@@ -37,23 +38,23 @@
         count++;
     }
 
-    public Item pop() {
+    public T pop() {
         if (isEmpty()) {
             throw new RuntimeException("Ring buffer underflow");
         }
-        Item item = buffer[indexOut];
+        T item = buffer[indexOut];
         buffer[indexOut] = null;                  // to help with garbage collection
         count--;
         indexOut = (indexOut + 1) % buffer.length; // wrap-around
         return item;
     }
 
-    public Iterator<Item> iterator() {
+    public Iterator<T> iterator() {
         return new RingBufferIterator();
     }
 
     // an iterator, doesn't implement remove() since it's optional
-    private class RingBufferIterator implements Iterator<Item> {
+    private class RingBufferIterator implements Iterator<T> {
 
         private int i = 0;
 
@@ -65,7 +66,7 @@
             throw new UnsupportedOperationException();
         }
 
-        public Item next() {
+        public T next() {
             if (!hasNext()) {
                 throw new NoSuchElementException();
             }
diff --git a/engine/src/android/res/layout/about.xml b/engine/src/android/res/layout/about.xml
index 1d8c2b0..ca249e7 100644
--- a/engine/src/android/res/layout/about.xml
+++ b/engine/src/android/res/layout/about.xml
@@ -1,29 +1,29 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <LinearLayout
-	xmlns:android="http://schemas.android.com/apk/res/android"
-	android:orientation="vertical"
-	android:layout_width="fill_parent"
-	android:layout_height="fill_parent"
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
 >
 
     <LinearLayout
-		android:id="@+id/buttonsContainer"
-		xmlns:android="http://schemas.android.com/apk/res/android"
-		android:orientation="vertical"
-		android:layout_width="fill_parent"
-		android:layout_height="fill_parent"
-	>
+        android:id="@+id/buttonsContainer"
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="vertical"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
+    >
         <TextView  
-			android:layout_width="fill_parent" 
-			android:layout_height="wrap_content" 
-			android:text="copyright (c) 2009-2010 JMonkeyEngine"
+            android:layout_width="fill_parent" 
+            android:layout_height="wrap_content" 
+            android:text="copyright (c) 2009-2010 JMonkeyEngine"
 		/>
 
         <TextView  
-			android:layout_width="fill_parent" 
-			android:layout_height="wrap_content" 
-			android:text="http://www.jmonkeyengine.org"
+            android:layout_width="fill_parent" 
+            android:layout_height="wrap_content" 
+            android:text="http://www.jmonkeyengine.org"
 		/>
 
     </LinearLayout>
diff --git a/engine/src/android/res/layout/tests.xml b/engine/src/android/res/layout/tests.xml
index 70bd5ec..f38e233 100644
--- a/engine/src/android/res/layout/tests.xml
+++ b/engine/src/android/res/layout/tests.xml
@@ -1,17 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <LinearLayout
-	xmlns:android="http://schemas.android.com/apk/res/android"
-	android:orientation="vertical"
-	android:layout_width="fill_parent"
-	android:layout_height="fill_parent"
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
 >
     <LinearLayout
-		android:id="@+id/buttonsContainer"
-		xmlns:android="http://schemas.android.com/apk/res/android"
-		android:orientation="vertical"
-		android:layout_width="fill_parent"
-		android:layout_height="fill_parent">
+        android:id="@+id/buttonsContainer"
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="vertical"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent">
 <!--
 		<Button
 			android:id="@+id/SimpleTextured"
diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/meshes/MeshHelper.java b/engine/src/blender/com/jme3/scene/plugins/blender/meshes/MeshHelper.java
index 484e942..7f9e8ac 100644
--- a/engine/src/blender/com/jme3/scene/plugins/blender/meshes/MeshHelper.java
+++ b/engine/src/blender/com/jme3/scene/plugins/blender/meshes/MeshHelper.java
@@ -31,6 +31,14 @@
  */
 package com.jme3.scene.plugins.blender.meshes;
 
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
 import com.jme3.asset.BlenderKey.FeaturesToLoad;
 import com.jme3.material.Material;
 import com.jme3.math.FastMath;
@@ -57,10 +65,6 @@
 import com.jme3.scene.plugins.blender.textures.UVCoordinatesGenerator;
 import com.jme3.texture.Texture;
 import com.jme3.util.BufferUtils;
-import java.nio.ByteBuffer;
-import java.nio.FloatBuffer;
-import java.util.*;
-import java.util.Map.Entry;
 
 /**
  * A class that is used in mesh calculations.
@@ -300,12 +304,13 @@
         // generating meshes
         //FloatBuffer verticesColorsBuffer = this.createFloatBuffer(verticesColors);
         ByteBuffer verticesColorsBuffer = createByteBuffer(verticesColors);
+        verticesAmount = vertexList.size();
         for (Entry<Integer, List<Integer>> meshEntry : meshesMap.entrySet()) {
             Mesh mesh = new Mesh();
 
             // creating vertices indices for this mesh
             List<Integer> indexList = meshEntry.getValue();
-            if(verticesAmount < Short.MAX_VALUE * 2) {
+            if(verticesAmount <= Short.MAX_VALUE) {
             	short[] indices = new short[indexList.size()];
                 for (int i = 0; i < indexList.size(); ++i) {
                     indices[i] = indexList.get(i).shortValue();
diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/textures/blending/TextureBlenderAWT.java b/engine/src/blender/com/jme3/scene/plugins/blender/textures/blending/TextureBlenderAWT.java
index 75fc0c5..918072e 100644
--- a/engine/src/blender/com/jme3/scene/plugins/blender/textures/blending/TextureBlenderAWT.java
+++ b/engine/src/blender/com/jme3/scene/plugins/blender/textures/blending/TextureBlenderAWT.java
@@ -56,8 +56,8 @@
 		float[] resultPixel = new float[4];
 		int dataIndex = 0;
 		while (data.hasRemaining()) {
-			float tin = this.setupMaterialColor(data, format, neg, pixelColor);
-			this.blendPixel(resultPixel, materialColor, color, tin, blendType, blenderContext);
+			this.setupMaterialColor(data, format, neg, pixelColor);
+			this.blendPixel(resultPixel, materialColor, pixelColor, affectFactor, blendType, blenderContext);
 			newData.put(dataIndex++, (byte) (resultPixel[0] * 255.0f));
 			newData.put(dataIndex++, (byte) (resultPixel[1] * 255.0f));
 			newData.put(dataIndex++, (byte) (resultPixel[2] * 255.0f));
diff --git a/engine/src/core-data/Common/MatDefs/Light/Lighting.frag b/engine/src/core-data/Common/MatDefs/Light/Lighting.frag
index 76f0e15..eb1c3fd 100644
--- a/engine/src/core-data/Common/MatDefs/Light/Lighting.frag
+++ b/engine/src/core-data/Common/MatDefs/Light/Lighting.frag
@@ -126,6 +126,10 @@
     float att = vLightDir.w;
    #endif
 
+   if (m_Shininess <= 1.0) {
+       specularFactor = 0.0; // should be one instruction on most cards ..
+   }
+
    specularFactor *= diffuseFactor;
 
    return vec2(diffuseFactor, specularFactor) * vec2(att);
diff --git a/engine/src/core-data/Common/MatDefs/Misc/Particle.j3md b/engine/src/core-data/Common/MatDefs/Misc/Particle.j3md
index e28d41a..73674f9 100644
--- a/engine/src/core-data/Common/MatDefs/Misc/Particle.j3md
+++ b/engine/src/core-data/Common/MatDefs/Misc/Particle.j3md
@@ -4,6 +4,10 @@
         Texture2D Texture
         Float Quadratic
         Boolean PointSprite
+        
+        //only used for soft particles
+        Texture2D DepthTexture
+        Float Softness
 
         // Texture of the glowing parts of the material
         Texture2D GlowMap
@@ -58,6 +62,28 @@
         }
     }
 
+    Technique SoftParticles{
+
+        VertexShader   GLSL100 : Common/MatDefs/Misc/SoftParticle.vert
+        FragmentShader GLSL100 : Common/MatDefs/Misc/SoftParticle.frag
+
+        WorldParameters {
+            WorldViewProjectionMatrix
+            WorldViewMatrix
+            WorldMatrix
+            CameraPosition
+        }
+
+        RenderState {
+            Blend AlphaAdditive
+            DepthWrite Off
+        }
+
+        Defines {
+            USE_TEXTURE : Texture
+        }
+    }
+
     Technique FixedFunc {
         RenderState {
             Blend AlphaAdditive
diff --git a/engine/src/core-data/Common/MatDefs/Misc/SoftParticle.frag b/engine/src/core-data/Common/MatDefs/Misc/SoftParticle.frag
new file mode 100644
index 0000000..d3108b5
--- /dev/null
+++ b/engine/src/core-data/Common/MatDefs/Misc/SoftParticle.frag
@@ -0,0 +1,50 @@
+uniform sampler2D m_DepthTexture;
+uniform float m_Softness; // Power used in the contrast function
+varying vec2 vPos; // Position of the pixel
+varying vec2 projPos;// z and w valus in projection space
+
+#ifdef USE_TEXTURE
+uniform sampler2D m_Texture;
+varying vec4 texCoord;
+#endif
+
+varying vec4 color;
+
+float Contrast(float d){
+    float val = clamp( 2.0*( (d > 0.5) ? 1.0-d : d ), 0.0, 1.0);
+    float a = 0.5 * pow(val, m_Softness);
+    return (d > 0.5) ? 1.0 - a : a;
+}
+
+float stdDiff(float d){   
+    return clamp((d)*m_Softness,0.0,1.0);
+}
+
+
+void main(){
+    if (color.a <= 0.01)
+        discard;
+
+    vec4 c = vec4(1.0,1.0,1.0,1.0);//color;
+    #ifdef USE_TEXTURE
+        #ifdef POINT_SPRITE
+            vec2 uv = mix(texCoord.xy, texCoord.zw, gl_PointCoord.xy);
+        #else
+            vec2 uv = texCoord.xy;
+        #endif
+        c = texture2D(m_Texture, uv) * color;
+    #endif
+
+
+    float depthv = texture2D(m_DepthTexture, vPos).x*2.0-1.0; // Scene depth
+    depthv*=projPos.y;   
+    float particleDepth = projPos.x;
+	
+    float zdiff =depthv-particleDepth;
+    if(zdiff<=0.0){
+        discard;
+    }
+    // Computes alpha based on the particles distance to the rest of the scene
+    c.a = c.a * stdDiff(zdiff);// Contrast(zdiff);
+    gl_FragColor =c;
+}
\ No newline at end of file
diff --git a/engine/src/core-data/Common/MatDefs/Misc/SoftParticle.vert b/engine/src/core-data/Common/MatDefs/Misc/SoftParticle.vert
new file mode 100644
index 0000000..4f0dfd5
--- /dev/null
+++ b/engine/src/core-data/Common/MatDefs/Misc/SoftParticle.vert
@@ -0,0 +1,53 @@
+uniform mat4 g_WorldViewProjectionMatrix;
+
+attribute vec3 inPosition;
+attribute vec4 inColor;
+attribute vec4 inTexCoord;
+
+varying vec4 color;
+// z and w values in projection space
+varying vec2 projPos;
+varying vec2 vPos; // Position of the pixel in clip space
+
+
+
+#ifdef USE_TEXTURE
+varying vec4 texCoord;
+#endif
+
+#ifdef POINT_SPRITE
+uniform mat4 g_WorldViewMatrix;
+uniform mat4 g_WorldMatrix;
+uniform vec3 g_CameraPosition;
+uniform float m_Quadratic;
+const float SIZE_MULTIPLIER = 4.0;
+attribute float inSize;
+#endif
+
+void main(){
+    vec4 pos = vec4(inPosition, 1.0);
+
+    gl_Position = g_WorldViewProjectionMatrix * pos;
+    color = inColor;
+
+    projPos = gl_Position.zw;
+   // projPos.x = 0.5 * (projPos.x) + 0.5;
+
+    // Transforms the vPosition data to the range [0,1]
+    vPos = (gl_Position.xy / gl_Position.w + 1.0) / 2.0;
+
+    #ifdef USE_TEXTURE
+        texCoord = inTexCoord;
+    #endif
+
+    #ifdef POINT_SPRITE
+        vec4 worldPos = g_WorldMatrix * pos;
+        float d = distance(g_CameraPosition.xyz, worldPos.xyz);
+        gl_PointSize = max(1.0, (inSize * SIZE_MULTIPLIER * m_Quadratic) / d);
+
+        //vec4 worldViewPos = g_WorldViewMatrix * pos;
+        //gl_PointSize = (inSize * SIZE_MULTIPLIER * m_Quadratic)*100.0 / worldViewPos.z;
+
+        color.a *= min(gl_PointSize, 1.0);
+    #endif
+}
\ No newline at end of file
diff --git a/engine/src/core-effects/com/jme3/post/filters/TranslucentBucketFilter.java b/engine/src/core-effects/com/jme3/post/filters/TranslucentBucketFilter.java
index 47be413..c377a58 100644
--- a/engine/src/core-effects/com/jme3/post/filters/TranslucentBucketFilter.java
+++ b/engine/src/core-effects/com/jme3/post/filters/TranslucentBucketFilter.java
@@ -5,6 +5,7 @@
 package com.jme3.post.filters;
 
 import com.jme3.asset.AssetManager;
+import com.jme3.effect.ParticleEmitter;
 import com.jme3.material.Material;
 import com.jme3.math.ColorRGBA;
 import com.jme3.post.Filter;
@@ -12,8 +13,14 @@
 import com.jme3.renderer.Renderer;
 import com.jme3.renderer.ViewPort;
 import com.jme3.renderer.queue.RenderQueue;
+import com.jme3.scene.Node;
+
+import com.jme3.scene.Spatial;
 import com.jme3.texture.FrameBuffer;
+import com.jme3.texture.Texture;
 import com.jme3.texture.Texture2D;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 /**
  * A filter to handle translucent objects when rendering a scene with filters that uses depth like WaterFilter and SSAOFilter
@@ -22,11 +29,25 @@
  */
 public final class TranslucentBucketFilter extends Filter {
 
+    private final static Logger logger = Logger.getLogger(TranslucentBucketFilter.class.getName());
     private RenderManager renderManager;
+    private boolean enabledSoftParticles = false;
+    private Texture depthTexture;
+    private ViewPort viewPort;
+
+    public TranslucentBucketFilter() {
+        super("TranslucentBucketFilter");
+    }
+
+    public TranslucentBucketFilter(boolean enabledSoftParticles) {
+        this();
+        this.enabledSoftParticles = enabledSoftParticles;
+    }
 
     @Override
     protected void initFilter(AssetManager manager, RenderManager rm, ViewPort vp, int w, int h) {
         this.renderManager = rm;
+        this.viewPort = vp;
         material = new Material(manager, "Common/MatDefs/Post/Overlay.j3md");
         material.setColor("Color", ColorRGBA.White);
         Texture2D tex = processor.getFilterTexture();
@@ -37,6 +58,26 @@
             material.clearParam("NumSamples");
         }
         renderManager.setHandleTranslucentBucket(false);
+        if (enabledSoftParticles && depthTexture != null) {
+            initSoftParticles(vp, true);
+        }
+    }
+
+    private void initSoftParticles(ViewPort vp, boolean enabledSP) {
+        if (depthTexture != null) {
+            for (Spatial scene : vp.getScenes()) {
+                makeSoftParticleEmitter(scene, enabledSP && enabled);
+            }
+        }
+
+    }
+
+    @Override
+    protected void setDepthTexture(Texture depthTexture) {
+        this.depthTexture = depthTexture;
+        if (enabledSoftParticles && depthTexture != null) {
+            initSoftParticles(viewPort, true);
+        }
     }
 
     /**
@@ -49,6 +90,11 @@
     }
 
     @Override
+    protected boolean isRequiresDepthTexture() {
+        return enabledSoftParticles;
+    }
+
+    @Override
     protected void postFrame(RenderManager renderManager, ViewPort viewPort, FrameBuffer prevFilterBuffer, FrameBuffer sceneBuffer) {
         renderManager.setCamera(viewPort.getCamera(), false);
         if (prevFilterBuffer != sceneBuffer) {
@@ -63,6 +109,8 @@
         if (renderManager != null) {
             renderManager.setHandleTranslucentBucket(true);
         }
+
+        initSoftParticles(viewPort, false);
     }
 
     @Override
@@ -76,5 +124,32 @@
         if (renderManager != null) {
             renderManager.setHandleTranslucentBucket(!enabled);
         }
+        initSoftParticles(viewPort, enabledSoftParticles);
+    }
+
+    private void makeSoftParticleEmitter(Spatial scene, boolean enabled) {
+        if (scene instanceof Node) {
+            Node n = (Node) scene;
+            for (Spatial child : n.getChildren()) {
+                makeSoftParticleEmitter(child, enabled);
+            }
+        }
+        if (scene instanceof ParticleEmitter) {
+            ParticleEmitter emitter = (ParticleEmitter) scene;
+            if (enabled) {
+                enabledSoftParticles = enabled;
+
+                emitter.getMaterial().selectTechnique("SoftParticles", renderManager);
+                emitter.getMaterial().setTexture("DepthTexture", processor.getDepthTexture());
+                emitter.setQueueBucket(RenderQueue.Bucket.Translucent);
+
+                logger.log(Level.INFO, "Made particle Emitter {0} soft.", emitter.getName());
+            } else {
+                emitter.getMaterial().clearParam("DepthTexture");
+                emitter.getMaterial().selectTechnique("Default", renderManager);
+               // emitter.setQueueBucket(RenderQueue.Bucket.Transparent);
+                logger.log(Level.INFO, "Particle Emitter {0} is not soft anymore.", emitter.getName());
+            }
+        }
     }
 }
diff --git a/engine/src/core-plugins/com/jme3/asset/plugins/HttpZipLocator.java~ b/engine/src/core-plugins/com/jme3/asset/plugins/HttpZipLocator.java~
deleted file mode 100644
index f5fbfd1..0000000
--- a/engine/src/core-plugins/com/jme3/asset/plugins/HttpZipLocator.java~
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- *   may be used to endorse or promote products derived from this software
- *   without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.jme3.asset.plugins;
-
-import com.jme3.asset.AssetInfo;
-import com.jme3.asset.AssetKey;
-import com.jme3.asset.AssetLocator;
-import com.jme3.asset.AssetManager;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.charset.CharacterCodingException;
-import java.nio.charset.Charset;
-import java.nio.charset.CharsetDecoder;
-import java.nio.charset.CoderResult;
-import java.util.HashMap;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import java.util.zip.Inflater;
-import java.util.zip.InflaterInputStream;
-import java.util.zip.ZipEntry;
-
-public class HttpZipLocator implements AssetLocator {
-
-    private static final Logger logger = Logger.getLogger(HttpZipLocator.class.getName());
-
-    private URL zipUrl;
-    private String rootPath = "";
-    private int numEntries;
-    private int tableOffset;
-    private int tableLength;
-    private HashMap<String, ZipEntry2> entries;
-    
-    private static final ByteBuffer byteBuf = ByteBuffer.allocate(250);
-    private static final CharBuffer charBuf = CharBuffer.allocate(250);
-    private static final CharsetDecoder utf8Decoder;
-    
-    static {
-        Charset utf8 = Charset.forName("UTF-8");
-        utf8Decoder = utf8.newDecoder();
-    }
-
-    private static class ZipEntry2 {
-        String name;
-        int length;
-        int offset;
-        int compSize;
-        long crc;
-        boolean deflate;
-
-        @Override
-        public String toString(){
-            return "ZipEntry[name=" + name +
-                         ",  length=" + length +
-                         ",  compSize=" + compSize +
-                         ",  offset=" + offset + "]";
-        }
-    }
-
-    private static int get16(byte[] b, int off) {
-	return  (b[off++] & 0xff) |
-               ((b[off]   & 0xff) << 8);
-    }
-
-    private static int get32(byte[] b, int off) {
-	return  (b[off++] & 0xff) |
-               ((b[off++] & 0xff) << 8) |
-               ((b[off++] & 0xff) << 16) |
-               ((b[off] & 0xff) << 24);
-    }
-
-    private static long getu32(byte[] b, int off) throws IOException{
-        return (b[off++]&0xff) |
-              ((b[off++]&0xff) << 8) |
-              ((b[off++]&0xff) << 16) |
-             (((long)(b[off]&0xff)) << 24);
-    }
-
-    private static String getUTF8String(byte[] b, int off, int len) throws CharacterCodingException {
-        StringBuilder sb = new StringBuilder();
-        
-        int read = 0;
-        while (read < len){
-            // Either read n remaining bytes in b or 250 if n is higher.
-            int toRead = Math.min(len - read, byteBuf.capacity());
-            
-            boolean endOfInput = toRead < byteBuf.capacity();
-            
-            // read 'toRead' bytes into byteBuf
-            byteBuf.put(b, off + read, toRead);
-            
-            // set limit to position and set position to 0
-            // so data can be decoded
-            byteBuf.flip();
-            
-            // decode data in byteBuf
-            CoderResult result = utf8Decoder.decode(byteBuf, charBuf, endOfInput); 
-            
-            // if the result is not an underflow its an error
-            // that cannot be handled.
-            // if the error is an underflow and its the end of input
-            // then the decoder expects more bytes but there are no more => error
-            if (!result.isUnderflow() || !endOfInput){
-                result.throwException();
-            }
-            
-            // flip the char buf to get the string just decoded
-            charBuf.flip();
-            
-            // append the decoded data into the StringBuilder
-            sb.append(charBuf.toString());
-            
-            // clear buffers for next use
-            byteBuf.clear();
-            charBuf.clear();
-            
-            read += toRead;
-        }
-        
-        return sb.toString();
-    }
-
-    private InputStream readData(int offset, int length) throws IOException{
-        HttpURLConnection conn = (HttpURLConnection) zipUrl.openConnection();
-        conn.setDoOutput(false);
-        conn.setUseCaches(false);
-        conn.setInstanceFollowRedirects(false);
-        String range = "-";
-        if (offset != Integer.MAX_VALUE){
-            range = offset + range;
-        }
-        if (length != Integer.MAX_VALUE){
-            if (offset != Integer.MAX_VALUE){
-                range = range + (offset + length - 1);
-            }else{
-                range = range + length;
-            }
-        }
-
-        conn.setRequestProperty("Range", "bytes=" + range);
-        conn.connect();
-        if (conn.getResponseCode() == HttpURLConnection.HTTP_PARTIAL){
-            return conn.getInputStream();
-        }else if (conn.getResponseCode() == HttpURLConnection.HTTP_OK){
-            throw new IOException("Your server does not support HTTP feature Content-Range. Please contact your server administrator.");
-        }else{
-            throw new IOException(conn.getResponseCode() + " " + conn.getResponseMessage());
-        }
-    }
-
-    private int readTableEntry(byte[] table, int offset) throws IOException{
-        if (get32(table, offset) != ZipEntry.CENSIG){
-            throw new IOException("Central directory error, expected 'PK12'");
-        }
-
-        int nameLen = get16(table, offset + ZipEntry.CENNAM);
-        int extraLen = get16(table, offset + ZipEntry.CENEXT);
-        int commentLen = get16(table, offset + ZipEntry.CENCOM);
-        int newOffset = offset + ZipEntry.CENHDR + nameLen + extraLen + commentLen;
-
-        int flags = get16(table, offset + ZipEntry.CENFLG);
-        if ((flags & 1) == 1){
-            // ignore this entry, it uses encryption
-            return newOffset;
-        }
-            
-        int method = get16(table, offset + ZipEntry.CENHOW);
-        if (method != ZipEntry.DEFLATED && method != ZipEntry.STORED){
-            // ignore this entry, it uses unknown compression method
-            return newOffset;
-        }
-
-        String name = getUTF8String(table, offset + ZipEntry.CENHDR, nameLen);
-        if (name.charAt(name.length()-1) == '/'){
-            // ignore this entry, it is directory node
-            // or it has no name (?)
-            return newOffset;
-        }
-
-        ZipEntry2 entry = new ZipEntry2();
-        entry.name     = name;
-        entry.deflate  = (method == ZipEntry.DEFLATED);
-        entry.crc      = getu32(table, offset + ZipEntry.CENCRC);
-        entry.length   = get32(table, offset + ZipEntry.CENLEN);
-        entry.compSize = get32(table, offset + ZipEntry.CENSIZ);
-        entry.offset   = get32(table, offset + ZipEntry.CENOFF);
-
-        // we want offset directly into file data ..
-        // move the offset forward to skip the LOC header
-        entry.offset += ZipEntry.LOCHDR + nameLen + extraLen;
-
-        entries.put(entry.name, entry);
-        
-        return newOffset;
-    }
-
-    private void fillByteArray(byte[] array, InputStream source) throws IOException{
-        int total = 0;
-        int length = array.length;
-	while (total < length) {
-	    int read = source.read(array, total, length - total);
-            if (read < 0)
-                throw new IOException("Failed to read entire array");
-
-	    total += read;
-	}
-    }
-
-    private void readCentralDirectory() throws IOException{
-        InputStream in = readData(tableOffset, tableLength);
-        byte[] header = new byte[tableLength];
-
-        // Fix for "PK12 bug in town.zip": sometimes
-        // not entire byte array will be read with InputStream.read()
-        // (especially for big headers)
-        fillByteArray(header, in);
-
-//        in.read(header);
-        in.close();
-
-        entries = new HashMap<String, ZipEntry2>(numEntries);
-        int offset = 0;
-        for (int i = 0; i < numEntries; i++){
-            offset = readTableEntry(header, offset);
-        }
-    }
-
-    private void readEndHeader() throws IOException{
-
-//        InputStream in = readData(Integer.MAX_VALUE, ZipEntry.ENDHDR);
-//        byte[] header = new byte[ZipEntry.ENDHDR];
-//        fillByteArray(header, in);
-//        in.close();
-//
-//        if (get32(header, 0) != ZipEntry.ENDSIG){
-//            throw new IOException("End header error, expected 'PK56'");
-//        }
-
-        // Fix for "PK56 bug in town.zip":
-        // If there's a zip comment inside the end header,
-        // PK56 won't appear in the -22 position relative to the end of the
-        // file!
-        // In that case, we have to search for it.
-        // Increase search space to 200 bytes
-
-        InputStream in = readData(Integer.MAX_VALUE, 200);
-        byte[] header = new byte[200];
-        fillByteArray(header, in);
-        in.close();
-
-        int offset = -1;
-        for (int i = 200 - 22; i >= 0; i--){
-            if (header[i] == (byte) (ZipEntry.ENDSIG & 0xff)
-              && get32(header, i) == ZipEntry.ENDSIG){
-                // found location
-                offset = i;
-                break;
-            }
-        }
-        if (offset == -1)
-            throw new IOException("Cannot find Zip End Header in file!");
-
-        numEntries  = get16(header, offset + ZipEntry.ENDTOT);
-        tableLength = get32(header, offset + ZipEntry.ENDSIZ);
-        tableOffset = get32(header, offset + ZipEntry.ENDOFF);
-    }
-
-    public void load(URL url) throws IOException {
-        if (!url.getProtocol().equals("http"))
-            throw new UnsupportedOperationException();
-
-        zipUrl = url;
-        readEndHeader();
-        readCentralDirectory();
-    }
-
-    private InputStream openStream(ZipEntry2 entry) throws IOException{
-        InputStream in = readData(entry.offset, entry.compSize);
-        if (entry.deflate){
-            return new InflaterInputStream(in, new Inflater(true));
-        }
-        return in;
-    }
-
-    public InputStream openStream(String name) throws IOException{
-        ZipEntry2 entry = entries.get(name);
-        if (entry == null)
-            throw new RuntimeException("Entry not found: "+name);
-
-        return openStream(entry);
-    }
-
-    public void setRootPath(String path){
-        if (!rootPath.equals(path)){
-            rootPath = path;
-            try {
-                load(new URL(path));
-            } catch (IOException ex) {
-                logger.log(Level.WARNING, "Failed to set root path "+path, ex);
-            }
-        }
-    }
-
-    public AssetInfo locate(AssetManager manager, AssetKey key){
-        final ZipEntry2 entry = entries.get(key.getName());
-        if (entry == null)
-            return null;
-
-        return new AssetInfo(manager, key){
-            @Override
-            public InputStream openStream() {
-                try {
-                    return HttpZipLocator.this.openStream(entry);
-                } catch (IOException ex) {
-                    logger.log(Level.WARNING, "Error retrieving "+entry.name, ex);
-                    return null;
-                }
-            }
-        };
-    }
-
-}
diff --git a/engine/src/core-plugins/com/jme3/scene/plugins/OBJLoader.java b/engine/src/core-plugins/com/jme3/scene/plugins/OBJLoader.java
index 3ce7f52..47165f6 100644
--- a/engine/src/core-plugins/com/jme3/scene/plugins/OBJLoader.java
+++ b/engine/src/core-plugins/com/jme3/scene/plugins/OBJLoader.java
@@ -454,9 +454,11 @@
 
         if (hasNormals){
             normBuf = BufferUtils.createFloatBuffer(vertIndexMap.size() * 3);
+            m.setBuffer(VertexBuffer.Type.Normal, 3, normBuf);
         }
         if (hasTexCoord){
             tcBuf = BufferUtils.createFloatBuffer(vertIndexMap.size() * 2);
+            m.setBuffer(VertexBuffer.Type.TexCoord, 2, tcBuf);
         }
 
         IndexBuffer indexBuf = null;
@@ -517,9 +519,7 @@
         }
 
         m.setBuffer(VertexBuffer.Type.Position, 3, posBuf);
-        m.setBuffer(VertexBuffer.Type.Normal,   3, normBuf);
-        m.setBuffer(VertexBuffer.Type.TexCoord, 2, tcBuf);
-        // index buffer was set on creation
+        // index buffer and others were set on creation
 
         m.setStatic();
         m.updateBound();
diff --git a/engine/src/core/com/jme3/app/Application.java b/engine/src/core/com/jme3/app/Application.java
index 517ec61..5100725 100644
--- a/engine/src/core/com/jme3/app/Application.java
+++ b/engine/src/core/com/jme3/app/Application.java
@@ -290,6 +290,10 @@
 
     private void initStateManager(){
         stateManager = new AppStateManager(this);
+        
+        // Always register a ResetStatsState to make sure
+        // that the stats are cleared every frame
+        stateManager.attach(new ResetStatsState());
     }
 
     /**
@@ -580,6 +584,17 @@
             }
             task.invoke();
         } while (((task = taskQueue.poll()) != null));
+        
+        /* I think the above is really just doing this:
+        AppTask<?> task;
+        while( (task = taskQueue.poll()) != null ) {
+            if (!task.isCancelled()) {
+                task.invoke();
+            }
+        }
+        //...but it's hard to say for sure.  It's so twisted
+        //up that I don't trust my eyes.  -pspeed
+        */ 
     
         if (speed == 0 || paused)
             return;
diff --git a/engine/src/core/com/jme3/app/ResetStatsState.java b/engine/src/core/com/jme3/app/ResetStatsState.java
new file mode 100644
index 0000000..03f3013
--- /dev/null
+++ b/engine/src/core/com/jme3/app/ResetStatsState.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2009-2012 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.app;
+
+import com.jme3.app.state.AbstractAppState;
+import com.jme3.renderer.RenderManager;
+
+
+/**
+ *  Resets (clearFrame()) the render's stats object every frame
+ *  during AppState.render().  This state is registered once
+ *  with Application to ensure that the stats are cleared once
+ *  a frame.  Using this makes sure that any Appliction based
+ *  application that properly runs its state manager will have
+ *  stats reset no matter how many views it has or if it even
+ *  has views.
+ *
+ *  @author    Paul Speed
+ */
+public class ResetStatsState extends AbstractAppState {
+
+    public ResetStatsState() {
+    }    
+
+    @Override
+    public void render(RenderManager rm) {
+        super.render(rm);
+        rm.getRenderer().getStatistics().clearFrame();        
+    } 
+
+}
diff --git a/engine/src/core/com/jme3/app/SimpleApplication.java b/engine/src/core/com/jme3/app/SimpleApplication.java
index c79ce83..aa8e749 100644
--- a/engine/src/core/com/jme3/app/SimpleApplication.java
+++ b/engine/src/core/com/jme3/app/SimpleApplication.java
@@ -241,13 +241,6 @@
         rootNode.updateGeometricState();
         guiNode.updateGeometricState();
 
-        // Moving this here to make sure it is always done.
-        // Now the sets are cleared every frame (guaranteed)
-        // and more than one viewer can access the data.  This
-        // used to be cleared by StatsView but then only StatsView
-        // could get accurate counts.
-        renderer.getStatistics().clearFrame();        
-                
         // render states
         stateManager.render(renderManager);
         renderManager.render(tpf, context.isRenderable());
diff --git a/engine/src/core/com/jme3/app/StatsView.java b/engine/src/core/com/jme3/app/StatsView.java
index 49eeb13..f2b2ba5 100644
--- a/engine/src/core/com/jme3/app/StatsView.java
+++ b/engine/src/core/com/jme3/app/StatsView.java
@@ -105,7 +105,7 @@
             labels[i].setText(stringBuilder);
         }
         
-        // Moved to SimpleApplication to make sure it is
+        // Moved to ResetStatsState to make sure it is
         // done even if there is no StatsView or the StatsView
         // is disable.
         //statistics.clearFrame();
diff --git a/engine/src/core/com/jme3/app/state/AppStateManager.java b/engine/src/core/com/jme3/app/state/AppStateManager.java
index 81228af..92a00f5 100644
--- a/engine/src/core/com/jme3/app/state/AppStateManager.java
+++ b/engine/src/core/com/jme3/app/state/AppStateManager.java
@@ -202,6 +202,9 @@
 
     protected void initializePending(){
         AppState[] array = getInitializing();
+        if (array.length == 0)
+            return;
+            
         synchronized( states ) {
             // Move the states that will be initialized
             // into the active array.  In all but one case the
@@ -219,6 +222,9 @@
     
     protected void terminatePending(){
         AppState[] array = getTerminating();
+        if (array.length == 0)
+            return;
+            
         for (AppState state : array) {
             state.cleanup();
         }        
diff --git a/engine/src/core/com/jme3/input/InputManager.java b/engine/src/core/com/jme3/input/InputManager.java
index 23f2988..a0c8788 100644
--- a/engine/src/core/com/jme3/input/InputManager.java
+++ b/engine/src/core/com/jme3/input/InputManager.java
@@ -1,881 +1,892 @@
-/*
- * Copyright (c) 2009-2012 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- *   may be used to endorse or promote products derived from this software
- *   without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package com.jme3.input;
-
-import com.jme3.app.Application;
-import com.jme3.input.controls.*;
-import com.jme3.input.event.*;
-import com.jme3.math.FastMath;
-import com.jme3.math.Vector2f;
-import com.jme3.util.IntMap;
-import com.jme3.util.IntMap.Entry;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * The <code>InputManager</code> is responsible for converting input events
- * received from the Key, Mouse and Joy Input implementations into an
- * abstract, input device independent representation that user code can use.
- * <p>
- * By default an <code>InputManager</code> is included with every Application instance for use
- * in user code to query input, unless the Application is created as headless
- * or with input explicitly disabled.
- * <p>
- * The input manager has two concepts, a {@link Trigger} and a mapping.
- * A trigger represents a specific input trigger, such as a key button, 
- * or a mouse axis. A mapping represents a link onto one or several triggers, 
- * when the appropriate trigger is activated (e.g. a key is pressed), the 
- * mapping will be invoked. Any listeners registered to receive an event
- * from the mapping will have an event raised.
- * <p>
- * There are two types of events that {@link InputListener input listeners}
- * can receive, one is {@link ActionListener#onAction(java.lang.String, boolean, float) action}
- * events and another is {@link AnalogListener#onAnalog(java.lang.String, float, float) analog}
- * events. 
- * <p>
- * <code>onAction</code> events are raised when the specific input
- * activates or deactivates. For a digital input such as key press, the <code>onAction()</code>
- * event will be raised with the <code>isPressed</code> argument equal to true,
- * when the key is released, <code>onAction</code> is called again but this time
- * with the <code>isPressed</code> argument set to false.
- * For analog inputs, the <code>onAction</code> method will be called any time
- * the input is non-zero, however an exception to this is for joystick axis inputs,
- * which are only called when the input is above the {@link InputManager#setAxisDeadZone(float) dead zone}.
- * <p>
- * <code>onAnalog</code> events are raised every frame while the input is activated.
- * For digital inputs, every frame that the input is active will cause the
- * <code>onAnalog</code> method to be called, the argument <code>value</code>
- * argument will equal to the frame's time per frame (TPF) value but only
- * for digital inputs. For analog inputs however, the <code>value</code> argument
- * will equal the actual analog value.
- */
-public class InputManager implements RawInputListener {
-
-    private static final Logger logger = Logger.getLogger(InputManager.class.getName());
-    private final KeyInput keys;
-    private final MouseInput mouse;
-    private final JoyInput joystick;
-    private final TouchInput touch;
-    private float frameTPF;
-    private long lastLastUpdateTime = 0;
-    private long lastUpdateTime = 0;
-    private long frameDelta = 0;
-    private long firstTime = 0;
-    private boolean eventsPermitted = false;
-    private boolean mouseVisible = true;
-    private boolean safeMode = false;
-    private float axisDeadZone = 0.05f;
-    private Vector2f cursorPos = new Vector2f();
-    private Joystick[] joysticks;
-    private final IntMap<ArrayList<Mapping>> bindings = new IntMap<ArrayList<Mapping>>();
-    private final HashMap<String, Mapping> mappings = new HashMap<String, Mapping>();
-    private final IntMap<Long> pressedButtons = new IntMap<Long>();
-    private final IntMap<Float> axisValues = new IntMap<Float>();
-    private ArrayList<RawInputListener> rawListeners = new ArrayList<RawInputListener>();
-    private RawInputListener[] rawListenerArray = null;
-    private ArrayList<InputEvent> inputQueue = new ArrayList<InputEvent>();
-
-    private static class Mapping {
-
-        private final String name;
-        private final ArrayList<Integer> triggers = new ArrayList<Integer>();
-        private final ArrayList<InputListener> listeners = new ArrayList<InputListener>();
-
-        public Mapping(String name) {
-            this.name = name;
-        }
-    }
-
-    /**
-     * Initializes the InputManager.
-     * 
-     * <p>This should only be called internally in {@link Application}.
-     *
-     * @param mouse
-     * @param keys
-     * @param joystick
-     * @param touch
-     * @throws IllegalArgumentException If either mouseInput or keyInput are null.
-     */
-    public InputManager(MouseInput mouse, KeyInput keys, JoyInput joystick, TouchInput touch) {
-        if (keys == null || mouse == null) {
-            throw new NullPointerException("Mouse or keyboard cannot be null");
-        }
-
-        this.keys = keys;
-        this.mouse = mouse;
-        this.joystick = joystick;
-        this.touch = touch;
-
-        keys.setInputListener(this);
-        mouse.setInputListener(this);
-        if (joystick != null) {
-            joystick.setInputListener(this);
-            joysticks = joystick.loadJoysticks(this);
-        }
-        if (touch != null) {
-            touch.setInputListener(this);
-        }
-
-        firstTime = keys.getInputTimeNanos();
-    }
-
-    private void invokeActions(int hash, boolean pressed) {
-        ArrayList<Mapping> maps = bindings.get(hash);
-        if (maps == null) {
-            return;
-        }
-
-        int size = maps.size();
-        for (int i = size - 1; i >= 0; i--) {
-            Mapping mapping = maps.get(i);
-            ArrayList<InputListener> listeners = mapping.listeners;
-            int listenerSize = listeners.size();
-            for (int j = listenerSize - 1; j >= 0; j--) {
-                InputListener listener = listeners.get(j);
-                if (listener instanceof ActionListener) {
-                    ((ActionListener) listener).onAction(mapping.name, pressed, frameTPF);
-                }
-            }
-        }
-    }
-
-    private float computeAnalogValue(long timeDelta) {
-        if (safeMode || frameDelta == 0) {
-            return 1f;
-        } else {
-            return FastMath.clamp((float) timeDelta / (float) frameDelta, 0, 1);
-        }
-    }
-
-    private void invokeTimedActions(int hash, long time, boolean pressed) {
-        if (!bindings.containsKey(hash)) {
-            return;
-        }
-
-        if (pressed) {
-            pressedButtons.put(hash, time);
-        } else {
-            Long pressTimeObj = pressedButtons.remove(hash);
-            if (pressTimeObj == null) {
-                return; // under certain circumstances it can be null, ignore
-            }                        // the event then.
-
-            long pressTime = pressTimeObj;
-            long lastUpdate = lastLastUpdateTime;
-            long releaseTime = time;
-            long timeDelta = releaseTime - Math.max(pressTime, lastUpdate);
-
-            if (timeDelta > 0) {
-                invokeAnalogs(hash, computeAnalogValue(timeDelta), false);
-            }
-        }
-    }
-
-    private void invokeUpdateActions() {
-        for (Entry<Long> pressedButton : pressedButtons) {
-            int hash = pressedButton.getKey();
-
-            long pressTime = pressedButton.getValue();
-            long timeDelta = lastUpdateTime - Math.max(lastLastUpdateTime, pressTime);
-
-            if (timeDelta > 0) {
-                invokeAnalogs(hash, computeAnalogValue(timeDelta), false);
-            }
-        }
-
-        for (Entry<Float> axisValue : axisValues) {
-            int hash = axisValue.getKey();
-            float value = axisValue.getValue();
-            invokeAnalogs(hash, value * frameTPF, true);
-        }
-    }
-
-    private void invokeAnalogs(int hash, float value, boolean isAxis) {
-        ArrayList<Mapping> maps = bindings.get(hash);
-        if (maps == null) {
-            return;
-        }
-
-        if (!isAxis) {
-            value *= frameTPF;
-        }
-
-        int size = maps.size();
-        for (int i = size - 1; i >= 0; i--) {
-            Mapping mapping = maps.get(i);
-            ArrayList<InputListener> listeners = mapping.listeners;
-            int listenerSize = listeners.size();
-            for (int j = listenerSize - 1; j >= 0; j--) {
-                InputListener listener = listeners.get(j);
-                if (listener instanceof AnalogListener) {
-                    // NOTE: multiply by TPF for any button bindings
-                    ((AnalogListener) listener).onAnalog(mapping.name, value, frameTPF);
-                }
-            }
-        }
-    }
-
-    private void invokeAnalogsAndActions(int hash, float value, boolean applyTpf) {
-        if (value < axisDeadZone) {
-            invokeAnalogs(hash, value, !applyTpf);
-            return;
-        }
-
-        ArrayList<Mapping> maps = bindings.get(hash);
-        if (maps == null) {
-            return;
-        }
-
-        boolean valueChanged = !axisValues.containsKey(hash);
-        if (applyTpf) {
-            value *= frameTPF;
-        }
-
-        int size = maps.size();
-        for (int i = size - 1; i >= 0; i--) {
-            Mapping mapping = maps.get(i);
-            ArrayList<InputListener> listeners = mapping.listeners;
-            int listenerSize = listeners.size();
-            for (int j = listenerSize - 1; j >= 0; j--) {
-                InputListener listener = listeners.get(j);
-
-                if (listener instanceof ActionListener && valueChanged) {
-                    ((ActionListener) listener).onAction(mapping.name, true, frameTPF);
-                }
-
-                if (listener instanceof AnalogListener) {
-                    ((AnalogListener) listener).onAnalog(mapping.name, value, frameTPF);
-                }
-
-            }
-        }
-    }
-
-    /**
-     * Callback from RawInputListener. Do not use.
-     */
-    public void beginInput() {
-    }
-
-    /**
-     * Callback from RawInputListener. Do not use.
-     */
-    public void endInput() {
-    }
-
-    private void onJoyAxisEventQueued(JoyAxisEvent evt) {
-//        for (int i = 0; i < rawListeners.size(); i++){
-//            rawListeners.get(i).onJoyAxisEvent(evt);
-//        }
-
-        int joyId = evt.getJoyIndex();
-        int axis = evt.getAxisIndex();
-        float value = evt.getValue();
-        if (value < axisDeadZone && value > -axisDeadZone) {
-            int hash1 = JoyAxisTrigger.joyAxisHash(joyId, axis, true);
-            int hash2 = JoyAxisTrigger.joyAxisHash(joyId, axis, false);
-
-            Float val1 = axisValues.get(hash1);
-            Float val2 = axisValues.get(hash2);
-
-            if (val1 != null && val1.floatValue() > axisDeadZone) {
-                invokeActions(hash1, false);
-            }
-            if (val2 != null && val2.floatValue() > axisDeadZone) {
-                invokeActions(hash2, false);
-            }
-
-            axisValues.remove(hash1);
-            axisValues.remove(hash2);
-
-        } else if (value < 0) {
-            int hash = JoyAxisTrigger.joyAxisHash(joyId, axis, true);
-            int otherHash = JoyAxisTrigger.joyAxisHash(joyId, axis, false);
-            invokeAnalogsAndActions(hash, -value, true);
-            axisValues.put(hash, -value);
-            axisValues.remove(otherHash);
-        } else {
-            int hash = JoyAxisTrigger.joyAxisHash(joyId, axis, false);
-            int otherHash = JoyAxisTrigger.joyAxisHash(joyId, axis, true);
-            invokeAnalogsAndActions(hash, value, true);
-            axisValues.put(hash, value);
-            axisValues.remove(otherHash);
-        }
-    }
-
-    /**
-     * Callback from RawInputListener. Do not use.
-     */
-    public void onJoyAxisEvent(JoyAxisEvent evt) {
-        if (!eventsPermitted) {
-            throw new UnsupportedOperationException("JoyInput has raised an event at an illegal time.");
-        }
-
-        inputQueue.add(evt);
-    }
-
-    private void onJoyButtonEventQueued(JoyButtonEvent evt) {
-//        for (int i = 0; i < rawListeners.size(); i++){
-//            rawListeners.get(i).onJoyButtonEvent(evt);
-//        }
-
-        int hash = JoyButtonTrigger.joyButtonHash(evt.getJoyIndex(), evt.getButtonIndex());
-        invokeActions(hash, evt.isPressed());
-        invokeTimedActions(hash, evt.getTime(), evt.isPressed());
-    }
-
-    /**
-     * Callback from RawInputListener. Do not use.
-     */
-    public void onJoyButtonEvent(JoyButtonEvent evt) {
-        if (!eventsPermitted) {
-            throw new UnsupportedOperationException("JoyInput has raised an event at an illegal time.");
-        }
-
-        inputQueue.add(evt);
-    }
-
-    private void onMouseMotionEventQueued(MouseMotionEvent evt) {
-//        for (int i = 0; i < rawListeners.size(); i++){
-//            rawListeners.get(i).onMouseMotionEvent(evt);
-//        }
-
-        if (evt.getDX() != 0) {
-            float val = Math.abs(evt.getDX()) / 1024f;
-            invokeAnalogsAndActions(MouseAxisTrigger.mouseAxisHash(MouseInput.AXIS_X, evt.getDX() < 0), val, false);
-        }
-        if (evt.getDY() != 0) {
-            float val = Math.abs(evt.getDY()) / 1024f;
-            invokeAnalogsAndActions(MouseAxisTrigger.mouseAxisHash(MouseInput.AXIS_Y, evt.getDY() < 0), val, false);
-        }
-        if (evt.getDeltaWheel() != 0) {
-            float val = Math.abs(evt.getDeltaWheel()) / 100f;
-            invokeAnalogsAndActions(MouseAxisTrigger.mouseAxisHash(MouseInput.AXIS_WHEEL, evt.getDeltaWheel() < 0), val, false);
-        }
-    }
-
-    /**
-     * Callback from RawInputListener. Do not use.
-     */
-    public void onMouseMotionEvent(MouseMotionEvent evt) {
-        if (!eventsPermitted) {
-            throw new UnsupportedOperationException("MouseInput has raised an event at an illegal time.");
-        }
-
-        cursorPos.set(evt.getX(), evt.getY());
-        inputQueue.add(evt);
-    }
-
-    private void onMouseButtonEventQueued(MouseButtonEvent evt) {
-        int hash = MouseButtonTrigger.mouseButtonHash(evt.getButtonIndex());
-        invokeActions(hash, evt.isPressed());
-        invokeTimedActions(hash, evt.getTime(), evt.isPressed());
-    }
-
-    /**
-     * Callback from RawInputListener. Do not use.
-     */
-    public void onMouseButtonEvent(MouseButtonEvent evt) {
-        if (!eventsPermitted) {
-            throw new UnsupportedOperationException("MouseInput has raised an event at an illegal time.");
-        }
-        //updating cursor pos on click, so that non android touch events can properly update cursor position.
-        cursorPos.set(evt.getX(), evt.getY());
-        inputQueue.add(evt);
-    }
-
-    private void onKeyEventQueued(KeyInputEvent evt) {
-        if (evt.isRepeating()) {
-            return; // repeat events not used for bindings
-        }
-        
-        int hash = KeyTrigger.keyHash(evt.getKeyCode());
-        invokeActions(hash, evt.isPressed());
-        invokeTimedActions(hash, evt.getTime(), evt.isPressed());
-    }
-
-    /**
-     * Callback from RawInputListener. Do not use.
-     */
-    public void onKeyEvent(KeyInputEvent evt) {
-        if (!eventsPermitted) {
-            throw new UnsupportedOperationException("KeyInput has raised an event at an illegal time.");
-        }
-
-        inputQueue.add(evt);
-    }
-
-    /**
-     * Set the deadzone for joystick axes.
-     * 
-     * <p>{@link ActionListener#onAction(java.lang.String, boolean, float) }
-     * events will only be raised if the joystick axis value is greater than
-     * the <code>deadZone</code>.
-     * 
-     * @param deadZone the deadzone for joystick axes. 
-     */
-    public void setAxisDeadZone(float deadZone) {
-        this.axisDeadZone = deadZone;
-    }
-
-    /**
-     * Returns the deadzone for joystick axes.
-     * 
-     * @return the deadzone for joystick axes.
-     */
-    public float getAxisDeadZone() {
-        return axisDeadZone;
-    }
-    
-    /**
-     * Adds a new listener to receive events on the given mappings.
-     * 
-     * <p>The given InputListener will be registered to receive events
-     * on the specified mapping names. When a mapping raises an event, the
-     * listener will have its appropriate method invoked, either
-     * {@link ActionListener#onAction(java.lang.String, boolean, float) }
-     * or {@link AnalogListener#onAnalog(java.lang.String, float, float) }
-     * depending on which interface the <code>listener</code> implements. 
-     * If the listener implements both interfaces, then it will receive the
-     * appropriate event for each method.
-     * 
-     * @param listener The listener to register to receive input events.
-     * @param mappingNames The mapping names which the listener will receive
-     * events from.
-     * 
-     * @see InputManager#removeListener(com.jme3.input.controls.InputListener) 
-     */
-    public void addListener(InputListener listener, String... mappingNames) {
-        for (String mappingName : mappingNames) {
-            Mapping mapping = mappings.get(mappingName);
-            if (mapping == null) {
-                mapping = new Mapping(mappingName);
-                mappings.put(mappingName, mapping);
-            }
-            if (!mapping.listeners.contains(listener)) {
-                mapping.listeners.add(listener);
-            }
-        }
-    }
-
-    /**
-     * Removes a listener from receiving events.
-     * 
-     * <p>This will unregister the listener from any mappings that it
-     * was previously registered with via 
-     * {@link InputManager#addListener(com.jme3.input.controls.InputListener, java.lang.String[]) }.
-     * 
-     * @param listener The listener to unregister.
-     * 
-     * @see InputManager#addListener(com.jme3.input.controls.InputListener, java.lang.String[]) 
-     */
-    public void removeListener(InputListener listener) {
-        for (Mapping mapping : mappings.values()) {
-            mapping.listeners.remove(listener);
-        }
-    }
-
-    /**
-     * Create a new mapping to the given triggers.
-     * 
-     * <p>
-     * The given mapping will be assigned to the given triggers, when
-     * any of the triggers given raise an event, the listeners
-     * registered to the mappings will receive appropriate events.
-     * 
-     * @param mappingName The mapping name to assign.
-     * @param triggers The triggers to which the mapping is to be registered.
-     * 
-     * @see InputManager#deleteMapping(java.lang.String) 
-     */
-    public void addMapping(String mappingName, Trigger... triggers) {
-        Mapping mapping = mappings.get(mappingName);
-        if (mapping == null) {
-            mapping = new Mapping(mappingName);
-            mappings.put(mappingName, mapping);
-        }
-
-        for (Trigger trigger : triggers) {
-            int hash = trigger.triggerHashCode();
-            ArrayList<Mapping> names = bindings.get(hash);
-            if (names == null) {
-                names = new ArrayList<Mapping>();
-                bindings.put(hash, names);
-            }
-            if (!names.contains(mapping)) {
-                names.add(mapping);
-                mapping.triggers.add(hash);
-            } else {
-                logger.log(Level.WARNING, "Attempted to add mapping \"{0}\" twice to trigger.", mappingName);
-            }
-        }
-    }
-
-    /**
-     * Returns true if this InputManager has a mapping registered
-     * for the given mappingName.
-     *
-     * @param mappingName The mapping name to check.
-     *
-     * @see InputManager#addMapping(java.lang.String, com.jme3.input.controls.Trigger[]) 
-     * @see InputManager#deleteMapping(java.lang.String) 
-     */ 
-    public boolean hasMapping(String mappingName) {
-        return mappings.containsKey(mappingName);
-    }
-    
-    /**
-     * Deletes a mapping from receiving trigger events.
-     * 
-     * <p>
-     * The given mapping will no longer be assigned to receive trigger
-     * events.
-     * 
-     * @param mappingName The mapping name to unregister.
-     * 
-     * @see InputManager#addMapping(java.lang.String, com.jme3.input.controls.Trigger[]) 
-     */
-    public void deleteMapping(String mappingName) {
-        Mapping mapping = mappings.remove(mappingName);
-        if (mapping == null) {
-            throw new IllegalArgumentException("Cannot find mapping: " + mappingName);
-        }
-
-        ArrayList<Integer> triggers = mapping.triggers;
-        for (int i = triggers.size() - 1; i >= 0; i--) {
-            int hash = triggers.get(i);
-            ArrayList<Mapping> maps = bindings.get(hash);
-            maps.remove(mapping);
-        }
-    }
-
-    /**
-     * Deletes a specific trigger registered to a mapping.
-     * 
-     * <p>
-     * The given mapping will no longer receive events raised by the 
-     * trigger.
-     * 
-     * @param mappingName The mapping name to cease receiving events from the 
-     * trigger.
-     * @param trigger The trigger to no longer invoke events on the mapping.
-     */
-    public void deleteTrigger(String mappingName, Trigger trigger) {
-        Mapping mapping = mappings.get(mappingName);
-        if (mapping == null) {
-            throw new IllegalArgumentException("Cannot find mapping: " + mappingName);
-        }
-
-        ArrayList<Mapping> maps = bindings.get(trigger.triggerHashCode());
-        maps.remove(mapping);
-
-    }
-
-    /**
-     * Clears all the input mappings from this InputManager. 
-     * Consequently, also clears all of the
-     * InputListeners as well.
-     */
-    public void clearMappings() {
-        mappings.clear();
-        bindings.clear();
-        reset();
-    }
-
-    /**
-     * Do not use.
-     * Called to reset pressed keys or buttons when focus is restored.
-     */
-    public void reset() {
-        pressedButtons.clear();
-        axisValues.clear();
-    }
-
-    /**
-     * Returns whether the mouse cursor is visible or not.
-     * 
-     * <p>By default the cursor is visible.
-     * 
-     * @return whether the mouse cursor is visible or not.
-     * 
-     * @see InputManager#setCursorVisible(boolean) 
-     */
-    public boolean isCursorVisible() {
-        return mouseVisible;
-    }
-
-    /**
-     * Set whether the mouse cursor should be visible or not.
-     * 
-     * @param visible whether the mouse cursor should be visible or not.
-     */
-    public void setCursorVisible(boolean visible) {
-        if (mouseVisible != visible) {
-            mouseVisible = visible;
-            mouse.setCursorVisible(mouseVisible);
-        }
-    }
-
-    /**
-     * Returns the current cursor position. The position is relative to the
-     * bottom-left of the screen and is in pixels.
-     * 
-     * @return the current cursor position
-     */
-    public Vector2f getCursorPosition() {
-        return cursorPos;
-    }
-
-    /**
-     * Returns an array of all joysticks installed on the system.
-     * 
-     * @return an array of all joysticks installed on the system.
-     */
-    public Joystick[] getJoysticks() {
-        return joysticks;
-    }
-
-    /**
-     * Adds a {@link RawInputListener} to receive raw input events.
-     * 
-     * <p>
-     * Any raw input listeners registered to this <code>InputManager</code>
-     * will receive raw input events first, before they get handled
-     * by the <code>InputManager</code> itself. The listeners are 
-     * each processed in the order they were added, e.g. FIFO.
-     * <p>
-     * If a raw input listener has handled the event and does not wish
-     * other listeners down the list to process the event, it may set the
-     * {@link InputEvent#setConsumed() consumed flag} to indicate the 
-     * event was consumed and shouldn't be processed any further.
-     * The listener may do this either at each of the event callbacks 
-     * or at the {@link RawInputListener#endInput() } method.
-     * 
-     * @param listener A listener to receive raw input events.
-     * 
-     * @see RawInputListener
-     */
-    public void addRawInputListener(RawInputListener listener) {
-        rawListeners.add(listener);
-        rawListenerArray = null;
-    }
-
-    /**
-     * Removes a {@link RawInputListener} so that it no longer
-     * receives raw input events.
-     * 
-     * @param listener The listener to cease receiving raw input events.
-     * 
-     * @see InputManager#addRawInputListener(com.jme3.input.RawInputListener) 
-     */
-    public void removeRawInputListener(RawInputListener listener) {
-        rawListeners.remove(listener);
-        rawListenerArray = null;
-    }
-
-    /**
-     * Clears all {@link RawInputListener}s.
-     * 
-     * @see InputManager#addRawInputListener(com.jme3.input.RawInputListener) 
-     */
-    public void clearRawInputListeners() {
-        rawListeners.clear();
-        rawListenerArray = null;
-    }
-
-    private RawInputListener[] getRawListenerArray() {
-        if (rawListenerArray == null) 
-            rawListenerArray = rawListeners.toArray(new RawInputListener[rawListeners.size()]);
-        return rawListenerArray;
-    }
-    
-    /**
-     * Enable simulation of mouse events. Used for touchscreen input only.
-     * 
-     * @param value True to enable simulation of mouse events
-     */
-    public void setSimulateMouse(boolean value) {
-        if (touch != null) {
-            touch.setSimulateMouse(value);
-        }
-    }
-    
-    /**
-     * Enable simulation of keyboard events. Used for touchscreen input only.
-     * 
-     * @param value True to enable simulation of keyboard events
-     */
-    public void setSimulateKeyboard(boolean value) {
-        if (touch != null) {
-            touch.setSimulateKeyboard(value);
-        }
-    }
-
-    private void processQueue() {
-        int queueSize = inputQueue.size();
-        RawInputListener[] array = getRawListenerArray();
- 
-        for (RawInputListener listener : array) {
-            listener.beginInput();
-
-            for (int j = 0; j < queueSize; j++) {
-                InputEvent event = inputQueue.get(j);
-                if (event.isConsumed()) {
-                    continue;
-                }
-
-                if (event instanceof MouseMotionEvent) {
-                    listener.onMouseMotionEvent((MouseMotionEvent) event);
-                } else if (event instanceof KeyInputEvent) {
-                    listener.onKeyEvent((KeyInputEvent) event);
-                } else if (event instanceof MouseButtonEvent) {
-                    listener.onMouseButtonEvent((MouseButtonEvent) event);
-                } else if (event instanceof JoyAxisEvent) {
-                    listener.onJoyAxisEvent((JoyAxisEvent) event);
-                } else if (event instanceof JoyButtonEvent) {
-                    listener.onJoyButtonEvent((JoyButtonEvent) event);
-                } else if (event instanceof TouchEvent) {
-                    listener.onTouchEvent((TouchEvent) event);
-                } else {
-                    assert false;
-                }
-            }
-
-            listener.endInput();
-        }
-
-        for (int i = 0; i < queueSize; i++) {
-            InputEvent event = inputQueue.get(i);
-            if (event.isConsumed()) {
-                continue;
-            }
-
-            if (event instanceof MouseMotionEvent) {
-                onMouseMotionEventQueued((MouseMotionEvent) event);
-            } else if (event instanceof KeyInputEvent) {
-                onKeyEventQueued((KeyInputEvent) event);
-            } else if (event instanceof MouseButtonEvent) {
-                onMouseButtonEventQueued((MouseButtonEvent) event);
-            } else if (event instanceof JoyAxisEvent) {
-                onJoyAxisEventQueued((JoyAxisEvent) event);
-            } else if (event instanceof JoyButtonEvent) {
-                onJoyButtonEventQueued((JoyButtonEvent) event);
-            } else if (event instanceof TouchEvent) {
-                onTouchEventQueued((TouchEvent) event);
-            } else {
-                assert false;
-            }
-            // larynx, 2011.06.10 - flag event as reusable because
-            // the android input uses a non-allocating ringbuffer which
-            // needs to know when the event is not anymore in inputQueue
-            // and therefor can be reused.
-            event.setConsumed();
-        }
-
-        inputQueue.clear();
-    }
-
-    /**
-     * Updates the <code>InputManager</code>. 
-     * This will query current input devices and send
-     * appropriate events to registered listeners.
-     *
-     * @param tpf Time per frame value.
-     */
-    public void update(float tpf) {
-        frameTPF = tpf;
-        
-        // Activate safemode if the TPF value is so small
-        // that rounding errors are inevitable
-        safeMode = tpf < 0.015f;
-        
-        long currentTime = keys.getInputTimeNanos();
-        frameDelta = currentTime - lastUpdateTime;
-
-        eventsPermitted = true;
-
-        keys.update();
-        mouse.update();
-        if (joystick != null) {
-            joystick.update();
-        }
-        if (touch != null) {
-            touch.update();
-        }
-
-        eventsPermitted = false;
-
-        processQueue();
-        invokeUpdateActions();
-
-        lastLastUpdateTime = lastUpdateTime;
-        lastUpdateTime = currentTime;
-    }
-
-    /**
-     * Dispatches touch events to touch listeners
-     * @param evt The touch event to be dispatched to all onTouch listeners
-     */
-    public void onTouchEventQueued(TouchEvent evt) { 
-        ArrayList<Mapping> maps = bindings.get(TouchTrigger.touchHash(evt.getKeyCode()));
-        if (maps == null) {
-            return;
-        }
-
-        int size = maps.size();
-        for (int i = size - 1; i >= 0; i--) {
-            Mapping mapping = maps.get(i);
-            ArrayList<InputListener> listeners = mapping.listeners;
-            int listenerSize = listeners.size();
-            for (int j = listenerSize - 1; j >= 0; j--) {
-                InputListener listener = listeners.get(j);
-                if (listener instanceof TouchListener) {
-                    ((TouchListener) listener).onTouch(mapping.name, evt, frameTPF); 
-                }
-            }
-        }               
-    }
-    
-    /**
-     * Callback from RawInputListener. Do not use.
-     */
-    @Override
-    public void onTouchEvent(TouchEvent evt) {
-        if (!eventsPermitted) {
-            throw new UnsupportedOperationException("TouchInput has raised an event at an illegal time.");
-        }
-        inputQueue.add(evt);         
-    }
-}
+/*
+ * Copyright (c) 2009-2012 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.input;
+
+import com.jme3.app.Application;
+import com.jme3.input.controls.*;
+import com.jme3.input.event.*;
+import com.jme3.math.FastMath;
+import com.jme3.math.Vector2f;
+import com.jme3.util.IntMap;
+import com.jme3.util.IntMap.Entry;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * The <code>InputManager</code> is responsible for converting input events
+ * received from the Key, Mouse and Joy Input implementations into an
+ * abstract, input device independent representation that user code can use.
+ * <p>
+ * By default an <code>InputManager</code> is included with every Application instance for use
+ * in user code to query input, unless the Application is created as headless
+ * or with input explicitly disabled.
+ * <p>
+ * The input manager has two concepts, a {@link Trigger} and a mapping.
+ * A trigger represents a specific input trigger, such as a key button, 
+ * or a mouse axis. A mapping represents a link onto one or several triggers, 
+ * when the appropriate trigger is activated (e.g. a key is pressed), the 
+ * mapping will be invoked. Any listeners registered to receive an event
+ * from the mapping will have an event raised.
+ * <p>
+ * There are two types of events that {@link InputListener input listeners}
+ * can receive, one is {@link ActionListener#onAction(java.lang.String, boolean, float) action}
+ * events and another is {@link AnalogListener#onAnalog(java.lang.String, float, float) analog}
+ * events. 
+ * <p>
+ * <code>onAction</code> events are raised when the specific input
+ * activates or deactivates. For a digital input such as key press, the <code>onAction()</code>
+ * event will be raised with the <code>isPressed</code> argument equal to true,
+ * when the key is released, <code>onAction</code> is called again but this time
+ * with the <code>isPressed</code> argument set to false.
+ * For analog inputs, the <code>onAction</code> method will be called any time
+ * the input is non-zero, however an exception to this is for joystick axis inputs,
+ * which are only called when the input is above the {@link InputManager#setAxisDeadZone(float) dead zone}.
+ * <p>
+ * <code>onAnalog</code> events are raised every frame while the input is activated.
+ * For digital inputs, every frame that the input is active will cause the
+ * <code>onAnalog</code> method to be called, the argument <code>value</code>
+ * argument will equal to the frame's time per frame (TPF) value but only
+ * for digital inputs. For analog inputs however, the <code>value</code> argument
+ * will equal the actual analog value.
+ */
+public class InputManager implements RawInputListener {
+
+    private static final Logger logger = Logger.getLogger(InputManager.class.getName());
+    private final KeyInput keys;
+    private final MouseInput mouse;
+    private final JoyInput joystick;
+    private final TouchInput touch;
+    private float frameTPF;
+    private long lastLastUpdateTime = 0;
+    private long lastUpdateTime = 0;
+    private long frameDelta = 0;
+    private long firstTime = 0;
+    private boolean eventsPermitted = false;
+    private boolean mouseVisible = true;
+    private boolean safeMode = false;
+    private float axisDeadZone = 0.05f;
+    private Vector2f cursorPos = new Vector2f();
+    private Joystick[] joysticks;
+    private final IntMap<ArrayList<Mapping>> bindings = new IntMap<ArrayList<Mapping>>();
+    private final HashMap<String, Mapping> mappings = new HashMap<String, Mapping>();
+    private final IntMap<Long> pressedButtons = new IntMap<Long>();
+    private final IntMap<Float> axisValues = new IntMap<Float>();
+    private ArrayList<RawInputListener> rawListeners = new ArrayList<RawInputListener>();
+    private RawInputListener[] rawListenerArray = null;
+    private ArrayList<InputEvent> inputQueue = new ArrayList<InputEvent>();
+
+    private static class Mapping {
+
+        private final String name;
+        private final ArrayList<Integer> triggers = new ArrayList<Integer>();
+        private final ArrayList<InputListener> listeners = new ArrayList<InputListener>();
+
+        public Mapping(String name) {
+            this.name = name;
+        }
+    }
+
+    /**
+     * Initializes the InputManager.
+     * 
+     * <p>This should only be called internally in {@link Application}.
+     *
+     * @param mouse
+     * @param keys
+     * @param joystick
+     * @param touch
+     * @throws IllegalArgumentException If either mouseInput or keyInput are null.
+     */
+    public InputManager(MouseInput mouse, KeyInput keys, JoyInput joystick, TouchInput touch) {
+        if (keys == null || mouse == null) {
+            throw new NullPointerException("Mouse or keyboard cannot be null");
+        }
+
+        this.keys = keys;
+        this.mouse = mouse;
+        this.joystick = joystick;
+        this.touch = touch;
+
+        keys.setInputListener(this);
+        mouse.setInputListener(this);
+        if (joystick != null) {
+            joystick.setInputListener(this);
+            joysticks = joystick.loadJoysticks(this);
+        }
+        if (touch != null) {
+            touch.setInputListener(this);
+        }
+
+        firstTime = keys.getInputTimeNanos();
+    }
+
+    private void invokeActions(int hash, boolean pressed) {
+        ArrayList<Mapping> maps = bindings.get(hash);
+        if (maps == null) {
+            return;
+        }
+
+        int size = maps.size();
+        for (int i = size - 1; i >= 0; i--) {
+            Mapping mapping = maps.get(i);
+            ArrayList<InputListener> listeners = mapping.listeners;
+            int listenerSize = listeners.size();
+            for (int j = listenerSize - 1; j >= 0; j--) {
+                InputListener listener = listeners.get(j);
+                if (listener instanceof ActionListener) {
+                    ((ActionListener) listener).onAction(mapping.name, pressed, frameTPF);
+                }
+            }
+        }
+    }
+
+    private float computeAnalogValue(long timeDelta) {
+        if (safeMode || frameDelta == 0) {
+            return 1f;
+        } else {
+            return FastMath.clamp((float) timeDelta / (float) frameDelta, 0, 1);
+        }
+    }
+
+    private void invokeTimedActions(int hash, long time, boolean pressed) {
+        if (!bindings.containsKey(hash)) {
+            return;
+        }
+
+        if (pressed) {
+            pressedButtons.put(hash, time);
+        } else {
+            Long pressTimeObj = pressedButtons.remove(hash);
+            if (pressTimeObj == null) {
+                return; // under certain circumstances it can be null, ignore
+            }                        // the event then.
+
+            long pressTime = pressTimeObj;
+            long lastUpdate = lastLastUpdateTime;
+            long releaseTime = time;
+            long timeDelta = releaseTime - Math.max(pressTime, lastUpdate);
+
+            if (timeDelta > 0) {
+                invokeAnalogs(hash, computeAnalogValue(timeDelta), false);
+            }
+        }
+    }
+
+    private void invokeUpdateActions() {
+      if (pressedButtons.size() > 0) for (Entry<Long> pressedButton : pressedButtons) {
+            int hash = pressedButton.getKey();
+
+            long pressTime = pressedButton.getValue();
+            long timeDelta = lastUpdateTime - Math.max(lastLastUpdateTime, pressTime);
+
+            if (timeDelta > 0) {
+                invokeAnalogs(hash, computeAnalogValue(timeDelta), false);
+            }
+        }
+
+      if (axisValues.size() > 0) for (Entry<Float> axisValue : axisValues) {
+            int hash = axisValue.getKey();
+            float value = axisValue.getValue();
+            invokeAnalogs(hash, value * frameTPF, true);
+        }
+    }
+
+    private void invokeAnalogs(int hash, float value, boolean isAxis) {
+        ArrayList<Mapping> maps = bindings.get(hash);
+        if (maps == null) {
+            return;
+        }
+
+        if (!isAxis) {
+            value *= frameTPF;
+        }
+
+        int size = maps.size();
+        for (int i = size - 1; i >= 0; i--) {
+            Mapping mapping = maps.get(i);
+            ArrayList<InputListener> listeners = mapping.listeners;
+            int listenerSize = listeners.size();
+            for (int j = listenerSize - 1; j >= 0; j--) {
+                InputListener listener = listeners.get(j);
+                if (listener instanceof AnalogListener) {
+                    // NOTE: multiply by TPF for any button bindings
+                    ((AnalogListener) listener).onAnalog(mapping.name, value, frameTPF);
+                }
+            }
+        }
+    }
+
+    private void invokeAnalogsAndActions(int hash, float value, boolean applyTpf) {
+        if (value < axisDeadZone) {
+            invokeAnalogs(hash, value, !applyTpf);
+            return;
+        }
+
+        ArrayList<Mapping> maps = bindings.get(hash);
+        if (maps == null) {
+            return;
+        }
+
+        boolean valueChanged = !axisValues.containsKey(hash);
+        if (applyTpf) {
+            value *= frameTPF;
+        }
+
+        int size = maps.size();
+        for (int i = size - 1; i >= 0; i--) {
+            Mapping mapping = maps.get(i);
+            ArrayList<InputListener> listeners = mapping.listeners;
+            int listenerSize = listeners.size();
+            for (int j = listenerSize - 1; j >= 0; j--) {
+                InputListener listener = listeners.get(j);
+
+                if (listener instanceof ActionListener && valueChanged) {
+                    ((ActionListener) listener).onAction(mapping.name, true, frameTPF);
+                }
+
+                if (listener instanceof AnalogListener) {
+                    ((AnalogListener) listener).onAnalog(mapping.name, value, frameTPF);
+                }
+
+            }
+        }
+    }
+
+    /**
+     * Callback from RawInputListener. Do not use.
+     */
+    public void beginInput() {
+    }
+
+    /**
+     * Callback from RawInputListener. Do not use.
+     */
+    public void endInput() {
+    }
+
+    private void onJoyAxisEventQueued(JoyAxisEvent evt) {
+//        for (int i = 0; i < rawListeners.size(); i++){
+//            rawListeners.get(i).onJoyAxisEvent(evt);
+//        }
+
+        int joyId = evt.getJoyIndex();
+        int axis = evt.getAxisIndex();
+        float value = evt.getValue();
+        if (value < axisDeadZone && value > -axisDeadZone) {
+            int hash1 = JoyAxisTrigger.joyAxisHash(joyId, axis, true);
+            int hash2 = JoyAxisTrigger.joyAxisHash(joyId, axis, false);
+
+            Float val1 = axisValues.get(hash1);
+            Float val2 = axisValues.get(hash2);
+
+            if (val1 != null && val1.floatValue() > axisDeadZone) {
+                invokeActions(hash1, false);
+            }
+            if (val2 != null && val2.floatValue() > axisDeadZone) {
+                invokeActions(hash2, false);
+            }
+
+            axisValues.remove(hash1);
+            axisValues.remove(hash2);
+
+        } else if (value < 0) {
+            int hash = JoyAxisTrigger.joyAxisHash(joyId, axis, true);
+            int otherHash = JoyAxisTrigger.joyAxisHash(joyId, axis, false);
+            invokeAnalogsAndActions(hash, -value, true);
+            axisValues.put(hash, -value);
+            axisValues.remove(otherHash);
+        } else {
+            int hash = JoyAxisTrigger.joyAxisHash(joyId, axis, false);
+            int otherHash = JoyAxisTrigger.joyAxisHash(joyId, axis, true);
+            invokeAnalogsAndActions(hash, value, true);
+            axisValues.put(hash, value);
+            axisValues.remove(otherHash);
+        }
+    }
+
+    /**
+     * Callback from RawInputListener. Do not use.
+     */
+    public void onJoyAxisEvent(JoyAxisEvent evt) {
+        if (!eventsPermitted) {
+            throw new UnsupportedOperationException("JoyInput has raised an event at an illegal time.");
+        }
+
+        inputQueue.add(evt);
+    }
+
+    private void onJoyButtonEventQueued(JoyButtonEvent evt) {
+//        for (int i = 0; i < rawListeners.size(); i++){
+//            rawListeners.get(i).onJoyButtonEvent(evt);
+//        }
+
+        int hash = JoyButtonTrigger.joyButtonHash(evt.getJoyIndex(), evt.getButtonIndex());
+        invokeActions(hash, evt.isPressed());
+        invokeTimedActions(hash, evt.getTime(), evt.isPressed());
+    }
+
+    /**
+     * Callback from RawInputListener. Do not use.
+     */
+    public void onJoyButtonEvent(JoyButtonEvent evt) {
+        if (!eventsPermitted) {
+            throw new UnsupportedOperationException("JoyInput has raised an event at an illegal time.");
+        }
+
+        inputQueue.add(evt);
+    }
+
+    private void onMouseMotionEventQueued(MouseMotionEvent evt) {
+//        for (int i = 0; i < rawListeners.size(); i++){
+//            rawListeners.get(i).onMouseMotionEvent(evt);
+//        }
+
+        if (evt.getDX() != 0) {
+            float val = Math.abs(evt.getDX()) / 1024f;
+            invokeAnalogsAndActions(MouseAxisTrigger.mouseAxisHash(MouseInput.AXIS_X, evt.getDX() < 0), val, false);
+        }
+        if (evt.getDY() != 0) {
+            float val = Math.abs(evt.getDY()) / 1024f;
+            invokeAnalogsAndActions(MouseAxisTrigger.mouseAxisHash(MouseInput.AXIS_Y, evt.getDY() < 0), val, false);
+        }
+        if (evt.getDeltaWheel() != 0) {
+            float val = Math.abs(evt.getDeltaWheel()) / 100f;
+            invokeAnalogsAndActions(MouseAxisTrigger.mouseAxisHash(MouseInput.AXIS_WHEEL, evt.getDeltaWheel() < 0), val, false);
+        }
+    }
+
+    /**
+     * Callback from RawInputListener. Do not use.
+     */
+    public void onMouseMotionEvent(MouseMotionEvent evt) {
+        if (!eventsPermitted) {
+            throw new UnsupportedOperationException("MouseInput has raised an event at an illegal time.");
+        }
+
+        cursorPos.set(evt.getX(), evt.getY());
+        inputQueue.add(evt);
+    }
+
+    private void onMouseButtonEventQueued(MouseButtonEvent evt) {
+        int hash = MouseButtonTrigger.mouseButtonHash(evt.getButtonIndex());
+        invokeActions(hash, evt.isPressed());
+        invokeTimedActions(hash, evt.getTime(), evt.isPressed());
+    }
+
+    /**
+     * Callback from RawInputListener. Do not use.
+     */
+    public void onMouseButtonEvent(MouseButtonEvent evt) {
+        if (!eventsPermitted) {
+            throw new UnsupportedOperationException("MouseInput has raised an event at an illegal time.");
+        }
+        //updating cursor pos on click, so that non android touch events can properly update cursor position.
+        cursorPos.set(evt.getX(), evt.getY());
+        inputQueue.add(evt);
+    }
+
+    private void onKeyEventQueued(KeyInputEvent evt) {
+        if (evt.isRepeating()) {
+            return; // repeat events not used for bindings
+        }
+        
+        int hash = KeyTrigger.keyHash(evt.getKeyCode());
+        invokeActions(hash, evt.isPressed());
+        invokeTimedActions(hash, evt.getTime(), evt.isPressed());
+    }
+
+    /**
+     * Callback from RawInputListener. Do not use.
+     */
+    public void onKeyEvent(KeyInputEvent evt) {
+        if (!eventsPermitted) {
+            throw new UnsupportedOperationException("KeyInput has raised an event at an illegal time.");
+        }
+
+        inputQueue.add(evt);
+    }
+
+    /**
+     * Set the deadzone for joystick axes.
+     * 
+     * <p>{@link ActionListener#onAction(java.lang.String, boolean, float) }
+     * events will only be raised if the joystick axis value is greater than
+     * the <code>deadZone</code>.
+     * 
+     * @param deadZone the deadzone for joystick axes. 
+     */
+    public void setAxisDeadZone(float deadZone) {
+        this.axisDeadZone = deadZone;
+    }
+
+    /**
+     * Returns the deadzone for joystick axes.
+     * 
+     * @return the deadzone for joystick axes.
+     */
+    public float getAxisDeadZone() {
+        return axisDeadZone;
+    }
+    
+    /**
+     * Adds a new listener to receive events on the given mappings.
+     * 
+     * <p>The given InputListener will be registered to receive events
+     * on the specified mapping names. When a mapping raises an event, the
+     * listener will have its appropriate method invoked, either
+     * {@link ActionListener#onAction(java.lang.String, boolean, float) }
+     * or {@link AnalogListener#onAnalog(java.lang.String, float, float) }
+     * depending on which interface the <code>listener</code> implements. 
+     * If the listener implements both interfaces, then it will receive the
+     * appropriate event for each method.
+     * 
+     * @param listener The listener to register to receive input events.
+     * @param mappingNames The mapping names which the listener will receive
+     * events from.
+     * 
+     * @see InputManager#removeListener(com.jme3.input.controls.InputListener) 
+     */
+    public void addListener(InputListener listener, String... mappingNames) {
+        for (String mappingName : mappingNames) {
+            Mapping mapping = mappings.get(mappingName);
+            if (mapping == null) {
+                mapping = new Mapping(mappingName);
+                mappings.put(mappingName, mapping);
+            }
+            if (!mapping.listeners.contains(listener)) {
+                mapping.listeners.add(listener);
+            }
+        }
+    }
+
+    /**
+     * Removes a listener from receiving events.
+     * 
+     * <p>This will unregister the listener from any mappings that it
+     * was previously registered with via 
+     * {@link InputManager#addListener(com.jme3.input.controls.InputListener, java.lang.String[]) }.
+     * 
+     * @param listener The listener to unregister.
+     * 
+     * @see InputManager#addListener(com.jme3.input.controls.InputListener, java.lang.String[]) 
+     */
+    public void removeListener(InputListener listener) {
+        for (Mapping mapping : mappings.values()) {
+            mapping.listeners.remove(listener);
+        }
+    }
+
+    /**
+     * Create a new mapping to the given triggers.
+     * 
+     * <p>
+     * The given mapping will be assigned to the given triggers, when
+     * any of the triggers given raise an event, the listeners
+     * registered to the mappings will receive appropriate events.
+     * 
+     * @param mappingName The mapping name to assign.
+     * @param triggers The triggers to which the mapping is to be registered.
+     * 
+     * @see InputManager#deleteMapping(java.lang.String) 
+     */
+    public void addMapping(String mappingName, Trigger... triggers) {
+        Mapping mapping = mappings.get(mappingName);
+        if (mapping == null) {
+            mapping = new Mapping(mappingName);
+            mappings.put(mappingName, mapping);
+        }
+
+        for (Trigger trigger : triggers) {
+            int hash = trigger.triggerHashCode();
+            ArrayList<Mapping> names = bindings.get(hash);
+            if (names == null) {
+                names = new ArrayList<Mapping>();
+                bindings.put(hash, names);
+            }
+            if (!names.contains(mapping)) {
+                names.add(mapping);
+                mapping.triggers.add(hash);
+            } else {
+                logger.log(Level.WARNING, "Attempted to add mapping \"{0}\" twice to trigger.", mappingName);
+            }
+        }
+    }
+
+    /**
+     * Returns true if this InputManager has a mapping registered
+     * for the given mappingName.
+     *
+     * @param mappingName The mapping name to check.
+     *
+     * @see InputManager#addMapping(java.lang.String, com.jme3.input.controls.Trigger[]) 
+     * @see InputManager#deleteMapping(java.lang.String) 
+     */ 
+    public boolean hasMapping(String mappingName) {
+        return mappings.containsKey(mappingName);
+    }
+    
+    /**
+     * Deletes a mapping from receiving trigger events.
+     * 
+     * <p>
+     * The given mapping will no longer be assigned to receive trigger
+     * events.
+     * 
+     * @param mappingName The mapping name to unregister.
+     * 
+     * @see InputManager#addMapping(java.lang.String, com.jme3.input.controls.Trigger[]) 
+     */
+    public void deleteMapping(String mappingName) {
+        Mapping mapping = mappings.remove(mappingName);
+        if (mapping == null) {
+            throw new IllegalArgumentException("Cannot find mapping: " + mappingName);
+        }
+
+        ArrayList<Integer> triggers = mapping.triggers;
+        for (int i = triggers.size() - 1; i >= 0; i--) {
+            int hash = triggers.get(i);
+            ArrayList<Mapping> maps = bindings.get(hash);
+            maps.remove(mapping);
+        }
+    }
+
+    /**
+     * Deletes a specific trigger registered to a mapping.
+     * 
+     * <p>
+     * The given mapping will no longer receive events raised by the 
+     * trigger.
+     * 
+     * @param mappingName The mapping name to cease receiving events from the 
+     * trigger.
+     * @param trigger The trigger to no longer invoke events on the mapping.
+     */
+    public void deleteTrigger(String mappingName, Trigger trigger) {
+        Mapping mapping = mappings.get(mappingName);
+        if (mapping == null) {
+            throw new IllegalArgumentException("Cannot find mapping: " + mappingName);
+        }
+
+        ArrayList<Mapping> maps = bindings.get(trigger.triggerHashCode());
+        maps.remove(mapping);
+
+    }
+
+    /**
+     * Clears all the input mappings from this InputManager. 
+     * Consequently, also clears all of the
+     * InputListeners as well.
+     */
+    public void clearMappings() {
+        mappings.clear();
+        bindings.clear();
+        reset();
+    }
+
+    /**
+     * Do not use.
+     * Called to reset pressed keys or buttons when focus is restored.
+     */
+    public void reset() {
+        pressedButtons.clear();
+        axisValues.clear();
+    }
+
+    /**
+     * Returns whether the mouse cursor is visible or not.
+     * 
+     * <p>By default the cursor is visible.
+     * 
+     * @return whether the mouse cursor is visible or not.
+     * 
+     * @see InputManager#setCursorVisible(boolean) 
+     */
+    public boolean isCursorVisible() {
+        return mouseVisible;
+    }
+
+    /**
+     * Set whether the mouse cursor should be visible or not.
+     * 
+     * @param visible whether the mouse cursor should be visible or not.
+     */
+    public void setCursorVisible(boolean visible) {
+        if (mouseVisible != visible) {
+            mouseVisible = visible;
+            mouse.setCursorVisible(mouseVisible);
+        }
+    }
+
+    /**
+     * Returns the current cursor position. The position is relative to the
+     * bottom-left of the screen and is in pixels.
+     * 
+     * @return the current cursor position
+     */
+    public Vector2f getCursorPosition() {
+        return cursorPos;
+    }
+
+    /**
+     * Returns an array of all joysticks installed on the system.
+     * 
+     * @return an array of all joysticks installed on the system.
+     */
+    public Joystick[] getJoysticks() {
+        return joysticks;
+    }
+
+    /**
+     * Adds a {@link RawInputListener} to receive raw input events.
+     * 
+     * <p>
+     * Any raw input listeners registered to this <code>InputManager</code>
+     * will receive raw input events first, before they get handled
+     * by the <code>InputManager</code> itself. The listeners are 
+     * each processed in the order they were added, e.g. FIFO.
+     * <p>
+     * If a raw input listener has handled the event and does not wish
+     * other listeners down the list to process the event, it may set the
+     * {@link InputEvent#setConsumed() consumed flag} to indicate the 
+     * event was consumed and shouldn't be processed any further.
+     * The listener may do this either at each of the event callbacks 
+     * or at the {@link RawInputListener#endInput() } method.
+     * 
+     * @param listener A listener to receive raw input events.
+     * 
+     * @see RawInputListener
+     */
+    public void addRawInputListener(RawInputListener listener) {
+        rawListeners.add(listener);
+        rawListenerArray = null;
+    }
+
+    /**
+     * Removes a {@link RawInputListener} so that it no longer
+     * receives raw input events.
+     * 
+     * @param listener The listener to cease receiving raw input events.
+     * 
+     * @see InputManager#addRawInputListener(com.jme3.input.RawInputListener) 
+     */
+    public void removeRawInputListener(RawInputListener listener) {
+        rawListeners.remove(listener);
+        rawListenerArray = null;
+    }
+
+    /**
+     * Clears all {@link RawInputListener}s.
+     * 
+     * @see InputManager#addRawInputListener(com.jme3.input.RawInputListener) 
+     */
+    public void clearRawInputListeners() {
+        rawListeners.clear();
+        rawListenerArray = null;
+    }
+
+    private RawInputListener[] getRawListenerArray() {
+        if (rawListenerArray == null) 
+            rawListenerArray = rawListeners.toArray(new RawInputListener[rawListeners.size()]);
+        return rawListenerArray;
+    }
+    
+    /**
+     * Enable simulation of mouse events. Used for touchscreen input only.
+     * 
+     * @param value True to enable simulation of mouse events
+     */
+    public void setSimulateMouse(boolean value) {
+        if (touch != null) {
+            touch.setSimulateMouse(value);
+        }
+    }
+    /**
+     * Returns state of simulation of mouse events. Used for touchscreen input only.
+     *
+     */
+    public boolean getSimulateMouse() {
+        if (touch != null) {           
+            return touch.getSimulateMouse();
+        } else {
+            return false;
+        }
+    }
+    
+    /**
+     * Enable simulation of keyboard events. Used for touchscreen input only.
+     * 
+     * @param value True to enable simulation of keyboard events
+     */
+    public void setSimulateKeyboard(boolean value) {
+        if (touch != null) {
+            touch.setSimulateKeyboard(value);
+        }
+    }
+
+    private void processQueue() {
+        int queueSize = inputQueue.size();
+        RawInputListener[] array = getRawListenerArray();
+ 
+        for (RawInputListener listener : array) {
+            listener.beginInput();
+
+            for (int j = 0; j < queueSize; j++) {
+                InputEvent event = inputQueue.get(j);
+                if (event.isConsumed()) {
+                    continue;
+                }
+
+                if (event instanceof MouseMotionEvent) {
+                    listener.onMouseMotionEvent((MouseMotionEvent) event);
+                } else if (event instanceof KeyInputEvent) {
+                    listener.onKeyEvent((KeyInputEvent) event);
+                } else if (event instanceof MouseButtonEvent) {
+                    listener.onMouseButtonEvent((MouseButtonEvent) event);
+                } else if (event instanceof JoyAxisEvent) {
+                    listener.onJoyAxisEvent((JoyAxisEvent) event);
+                } else if (event instanceof JoyButtonEvent) {
+                    listener.onJoyButtonEvent((JoyButtonEvent) event);
+                } else if (event instanceof TouchEvent) {
+                    listener.onTouchEvent((TouchEvent) event);
+                } else {
+                    assert false;
+                }
+            }
+
+            listener.endInput();
+        }
+
+        for (int i = 0; i < queueSize; i++) {
+            InputEvent event = inputQueue.get(i);
+            if (event.isConsumed()) {
+                continue;
+            }
+
+            if (event instanceof MouseMotionEvent) {
+                onMouseMotionEventQueued((MouseMotionEvent) event);
+            } else if (event instanceof KeyInputEvent) {
+                onKeyEventQueued((KeyInputEvent) event);
+            } else if (event instanceof MouseButtonEvent) {
+                onMouseButtonEventQueued((MouseButtonEvent) event);
+            } else if (event instanceof JoyAxisEvent) {
+                onJoyAxisEventQueued((JoyAxisEvent) event);
+            } else if (event instanceof JoyButtonEvent) {
+                onJoyButtonEventQueued((JoyButtonEvent) event);
+            } else if (event instanceof TouchEvent) {
+                onTouchEventQueued((TouchEvent) event);
+            } else {
+                assert false;
+            }
+            // larynx, 2011.06.10 - flag event as reusable because
+            // the android input uses a non-allocating ringbuffer which
+            // needs to know when the event is not anymore in inputQueue
+            // and therefor can be reused.
+            event.setConsumed();
+        }
+
+        inputQueue.clear();
+    }
+
+    /**
+     * Updates the <code>InputManager</code>. 
+     * This will query current input devices and send
+     * appropriate events to registered listeners.
+     *
+     * @param tpf Time per frame value.
+     */
+    public void update(float tpf) {
+        frameTPF = tpf;
+        
+        // Activate safemode if the TPF value is so small
+        // that rounding errors are inevitable
+        safeMode = tpf < 0.015f;
+        
+        long currentTime = keys.getInputTimeNanos();
+        frameDelta = currentTime - lastUpdateTime;
+
+        eventsPermitted = true;
+
+        keys.update();
+        mouse.update();
+        if (joystick != null) {
+            joystick.update();
+        }
+        if (touch != null) {
+            touch.update();
+        }
+
+        eventsPermitted = false;
+
+        processQueue();
+        invokeUpdateActions();
+
+        lastLastUpdateTime = lastUpdateTime;
+        lastUpdateTime = currentTime;
+    }
+
+    /**
+     * Dispatches touch events to touch listeners
+     * @param evt The touch event to be dispatched to all onTouch listeners
+     */
+    public void onTouchEventQueued(TouchEvent evt) { 
+        ArrayList<Mapping> maps = bindings.get(TouchTrigger.touchHash(evt.getKeyCode()));
+        if (maps == null) {
+            return;
+        }
+
+        int size = maps.size();
+        for (int i = size - 1; i >= 0; i--) {
+            Mapping mapping = maps.get(i);
+            ArrayList<InputListener> listeners = mapping.listeners;
+            int listenerSize = listeners.size();
+            for (int j = listenerSize - 1; j >= 0; j--) {
+                InputListener listener = listeners.get(j);
+                if (listener instanceof TouchListener) {
+                    ((TouchListener) listener).onTouch(mapping.name, evt, frameTPF); 
+                }
+            }
+        }               
+    }
+    
+    /**
+     * Callback from RawInputListener. Do not use.
+     */
+    @Override
+    public void onTouchEvent(TouchEvent evt) {
+        if (!eventsPermitted) {
+            throw new UnsupportedOperationException("TouchInput has raised an event at an illegal time.");
+        }
+        inputQueue.add(evt);         
+    }
+}
diff --git a/engine/src/core/com/jme3/input/SoftTextDialogInput.java b/engine/src/core/com/jme3/input/SoftTextDialogInput.java
new file mode 100644
index 0000000..d166b97
--- /dev/null
+++ b/engine/src/core/com/jme3/input/SoftTextDialogInput.java
@@ -0,0 +1,13 @@
+package com.jme3.input;
+
+import com.jme3.input.controls.SoftTextDialogInputListener;
+
+public interface SoftTextDialogInput {
+
+    public static int TEXT_ENTRY_DIALOG = 0;
+    public static int NUMERIC_ENTRY_DIALOG = 1;
+    public static int NUMERIC_KEYPAD_DIALOG = 2;
+
+    public void requestDialog(int id, String title, String initialValue, SoftTextDialogInputListener listener);
+
+}
diff --git a/engine/src/core/com/jme3/input/TouchInput.java b/engine/src/core/com/jme3/input/TouchInput.java
index 2f45b44..e69c4b3 100644
--- a/engine/src/core/com/jme3/input/TouchInput.java
+++ b/engine/src/core/com/jme3/input/TouchInput.java
@@ -73,6 +73,12 @@
      * @param simulate if mouse events should be generated
      */
     public void setSimulateMouse(boolean simulate);
+    
+    /**
+     * Get if mouse events are generated
+     *
+     */
+    public boolean getSimulateMouse();
 
     /**
      * Set if keyboard events should be generated
diff --git a/engine/src/core/com/jme3/input/controls/SoftTextDialogInputListener.java b/engine/src/core/com/jme3/input/controls/SoftTextDialogInputListener.java
new file mode 100644
index 0000000..d33844d
--- /dev/null
+++ b/engine/src/core/com/jme3/input/controls/SoftTextDialogInputListener.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.input.controls;
+
+/**
+ *
+ * @author potterec (aka iwgeric)
+ */
+public interface SoftTextDialogInputListener {
+
+    public static int COMPLETE = 0;
+    public static int CANCEL = 1;
+
+    public void onSoftText(int action, String text);
+}
diff --git a/engine/src/core/com/jme3/math/Transform.java b/engine/src/core/com/jme3/math/Transform.java
index 7ccd847..3573d8c 100644
--- a/engine/src/core/com/jme3/math/Transform.java
+++ b/engine/src/core/com/jme3/math/Transform.java
@@ -1,318 +1,318 @@
-/*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- *   may be used to endorse or promote products derived from this software
- *   without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.jme3.math;
-
-import com.jme3.export.*;
-import java.io.IOException;
-
-/**
- * Started Date: Jul 16, 2004<br><br>
- * Represents a translation, rotation and scale in one object.
- * 
- * @author Jack Lindamood
- * @author Joshua Slack
- */
-public final class Transform implements Savable, Cloneable, java.io.Serializable {
-
-    static final long serialVersionUID = 1;
-
-    public static final Transform IDENTITY = new Transform();
-
-    private Quaternion rot = new Quaternion();
-    private Vector3f translation = new Vector3f();
-    private Vector3f scale = new Vector3f(1,1,1);
-
-    public Transform(Vector3f translation, Quaternion rot){
-        this.translation.set(translation);
-        this.rot.set(rot);
-    }
-    
-    public Transform(Vector3f translation, Quaternion rot, Vector3f scale){
-        this(translation, rot);
-        this.scale.set(scale);
-    }
-
-    public Transform(Vector3f translation){
-        this(translation, Quaternion.IDENTITY);
-    }
-
-    public Transform(Quaternion rot){
-        this(Vector3f.ZERO, rot);
-    }
-
-    public Transform(){
-        this(Vector3f.ZERO, Quaternion.IDENTITY);
-    }
-
-    /**
-     * Sets this rotation to the given Quaternion value.
-     * @param rot The new rotation for this matrix.
-     * @return this
-     */
-    public Transform setRotation(Quaternion rot) {
-        this.rot.set(rot);
-        return this;
-    }
-
-    /**
-     * Sets this translation to the given value.
-     * @param trans The new translation for this matrix.
-     * @return this
-     */
-    public Transform setTranslation(Vector3f trans) {
-        this.translation.set(trans);
-        return this;
-    }
-
-    /**
-     * Return the translation vector in this matrix.
-     * @return translation vector.
-     */
-    public Vector3f getTranslation() {
-        return translation;
-    }
-
-    /**
-     * Sets this scale to the given value.
-     * @param scale The new scale for this matrix.
-     * @return this
-     */
-    public Transform setScale(Vector3f scale) {
-        this.scale.set(scale);
-        return this;
-    }
-
-    /**
-     * Sets this scale to the given value.
-     * @param scale The new scale for this matrix.
-     * @return this
-     */
-    public Transform setScale(float scale) {
-        this.scale.set(scale, scale, scale);
-        return this;
-    }
-
-    /**
-     * Return the scale vector in this matrix.
-     * @return scale vector.
-     */
-    public Vector3f getScale() {
-        return scale;
-    }
-
-    /**
-     * Stores this translation value into the given vector3f.  If trans is null, a new vector3f is created to
-     * hold the value.  The value, once stored, is returned.
-     * @param trans The store location for this matrix's translation.
-     * @return The value of this matrix's translation.
-     */
-    public Vector3f getTranslation(Vector3f trans) {
-        if (trans==null) trans=new Vector3f();
-        trans.set(this.translation);
-        return trans;
-    }
-
-    /**
-     * Stores this rotation value into the given Quaternion.  If quat is null, a new Quaternion is created to
-     * hold the value.  The value, once stored, is returned.
-     * @param quat The store location for this matrix's rotation.
-     * @return The value of this matrix's rotation.
-     */
-    public Quaternion getRotation(Quaternion quat) {
-        if (quat==null) quat=new Quaternion();
-        quat.set(rot);
-        return quat;
-    }
-    
-    /**
-     * Return the rotation quaternion in this matrix.
-     * @return rotation quaternion.
-     */
-    public Quaternion getRotation() {
-        return rot;
-    } 
-    
-    /**
-     * Stores this scale value into the given vector3f.  If scale is null, a new vector3f is created to
-     * hold the value.  The value, once stored, is returned.
-     * @param scale The store location for this matrix's scale.
-     * @return The value of this matrix's scale.
-     */
-    public Vector3f getScale(Vector3f scale) {
-        if (scale==null) scale=new Vector3f();
-        scale.set(this.scale);
-        return scale;
-    }
-
-    /**
-     * Sets this matrix to the interpolation between the first matrix and the second by delta amount.
-     * @param t1 The begining transform.
-     * @param t2 The ending transform.
-     * @param delta An amount between 0 and 1 representing how far to interpolate from t1 to t2.
-     */
-    public void interpolateTransforms(Transform t1, Transform t2, float delta) {
-        this.rot.slerp(t1.rot,t2.rot,delta);
-        this.translation.interpolate(t1.translation,t2.translation,delta);
-        this.scale.interpolate(t1.scale,t2.scale,delta);
-    }
-
-    /**
-     * Changes the values of this matrix acording to it's parent.  Very similar to the concept of Node/Spatial transforms.
-     * @param parent The parent matrix.
-     * @return This matrix, after combining.
-     */
-    public Transform combineWithParent(Transform parent) {
-        scale.multLocal(parent.scale);
-//        rot.multLocal(parent.rot);
-        parent.rot.mult(rot, rot);
-
-        // This here, is evil code
-//        parent
-//            .rot
-//            .multLocal(translation)
-//            .multLocal(parent.scale)
-//            .addLocal(parent.translation);
-
-        translation.multLocal(parent.scale);
-        parent
-            .rot
-            .multLocal(translation)
-            .addLocal(parent.translation);
-        return this;
-    }
-
-    /**
-     * Sets this matrix's translation to the given x,y,z values.
-     * @param x This matrix's new x translation.
-     * @param y This matrix's new y translation.
-     * @param z This matrix's new z translation.
-     * @return this
-     */
-    public Transform setTranslation(float x,float y, float z) {
-        translation.set(x,y,z);
-        return this;
-    }
-
-    /**
-     * Sets this matrix's scale to the given x,y,z values.
-     * @param x This matrix's new x scale.
-     * @param y This matrix's new y scale.
-     * @param z This matrix's new z scale.
-     * @return this
-     */
-    public Transform setScale(float x, float y, float z) {
-        scale.set(x,y,z);
-        return this;
-    }
-
-    public Vector3f transformVector(final Vector3f in, Vector3f store){
-        if (store == null)
-            store = new Vector3f();
-
-        // multiply with scale first, then rotate, finally translate (cf.
-        // Eberly)
-        return rot.mult(store.set(in).multLocal(scale), store).addLocal(translation);
-    }
-
-    public Vector3f transformInverseVector(final Vector3f in, Vector3f store){
-        if (store == null)
-            store = new Vector3f();
-
-        // The author of this code should look above and take the inverse of that
-        // But for some reason, they didnt ..
-//        in.subtract(translation, store).divideLocal(scale);
-//        rot.inverse().mult(store, store);
-
-        in.subtract(translation, store);
-        rot.inverse().mult(store, store);
-        store.divideLocal(scale);
-
-        return store;
-    }
-
-    /**
-     * Loads the identity.  Equal to translation=1,1,1 scale=0,0,0 rot=0,0,0,1.
-     */
-    public void loadIdentity() {
-        translation.set(0,0,0);
-        scale.set(1,1,1);
-        rot.set(0,0,0,1);
-    }
-
-    @Override
-    public String toString(){
-        return getClass().getSimpleName() + "[ " + translation.x + ", " + translation.y + ", " + translation.z + "]\n"
-                                          + "[ " + rot.x + ", " + rot.y + ", " + rot.z + ", " + rot.w + "]\n"
-                                          + "[ " + scale.x + " , " + scale.y + ", " + scale.z + "]";
-    }
-
-    /**
-     * Sets this matrix to be equal to the given matrix.
-     * @param matrixQuat The matrix to be equal to.
-     * @return this
-     */
-    public Transform set(Transform matrixQuat) {
-        this.translation.set(matrixQuat.translation);
-        this.rot.set(matrixQuat.rot);
-        this.scale.set(matrixQuat.scale);
-        return this;
-    }
-
-    public void write(JmeExporter e) throws IOException {
-        OutputCapsule capsule = e.getCapsule(this);
-        capsule.write(rot, "rot", new Quaternion());
-        capsule.write(translation, "translation", Vector3f.ZERO);
-        capsule.write(scale, "scale", Vector3f.UNIT_XYZ);
-    }
-
-    public void read(JmeImporter e) throws IOException {
-        InputCapsule capsule = e.getCapsule(this);
-        
-        rot = (Quaternion)capsule.readSavable("rot", new Quaternion());
-        translation = (Vector3f)capsule.readSavable("translation", Vector3f.ZERO);
-        scale = (Vector3f)capsule.readSavable("scale", Vector3f.UNIT_XYZ);
-    }
-    
-    @Override
-    public Transform clone() {
-        try {
-            Transform tq = (Transform) super.clone();
-            tq.rot = rot.clone();
-            tq.scale = scale.clone();
-            tq.translation = translation.clone();
-            return tq;
-        } catch (CloneNotSupportedException e) {
-            throw new AssertionError();
-        }
-    }
-}
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.jme3.math;
+
+import com.jme3.export.*;
+import java.io.IOException;
+
+/**
+ * Started Date: Jul 16, 2004<br><br>
+ * Represents a translation, rotation and scale in one object.
+ * 
+ * @author Jack Lindamood
+ * @author Joshua Slack
+ */
+public final class Transform implements Savable, Cloneable, java.io.Serializable {
+
+    static final long serialVersionUID = 1;
+
+    public static final Transform IDENTITY = new Transform();
+
+    private Quaternion rot = new Quaternion();
+    private Vector3f translation = new Vector3f();
+    private Vector3f scale = new Vector3f(1,1,1);
+
+    public Transform(Vector3f translation, Quaternion rot){
+        this.translation.set(translation);
+        this.rot.set(rot);
+    }
+    
+    public Transform(Vector3f translation, Quaternion rot, Vector3f scale){
+        this(translation, rot);
+        this.scale.set(scale);
+    }
+
+    public Transform(Vector3f translation){
+        this(translation, Quaternion.IDENTITY);
+    }
+
+    public Transform(Quaternion rot){
+        this(Vector3f.ZERO, rot);
+    }
+
+    public Transform(){
+        this(Vector3f.ZERO, Quaternion.IDENTITY);
+    }
+
+    /**
+     * Sets this rotation to the given Quaternion value.
+     * @param rot The new rotation for this matrix.
+     * @return this
+     */
+    public Transform setRotation(Quaternion rot) {
+        this.rot.set(rot);
+        return this;
+    }
+
+    /**
+     * Sets this translation to the given value.
+     * @param trans The new translation for this matrix.
+     * @return this
+     */
+    public Transform setTranslation(Vector3f trans) {
+        this.translation.set(trans);
+        return this;
+    }
+
+    /**
+     * Return the translation vector in this matrix.
+     * @return translation vector.
+     */
+    public Vector3f getTranslation() {
+        return translation;
+    }
+
+    /**
+     * Sets this scale to the given value.
+     * @param scale The new scale for this matrix.
+     * @return this
+     */
+    public Transform setScale(Vector3f scale) {
+        this.scale.set(scale);
+        return this;
+    }
+
+    /**
+     * Sets this scale to the given value.
+     * @param scale The new scale for this matrix.
+     * @return this
+     */
+    public Transform setScale(float scale) {
+        this.scale.set(scale, scale, scale);
+        return this;
+    }
+
+    /**
+     * Return the scale vector in this matrix.
+     * @return scale vector.
+     */
+    public Vector3f getScale() {
+        return scale;
+    }
+
+    /**
+     * Stores this translation value into the given vector3f.  If trans is null, a new vector3f is created to
+     * hold the value.  The value, once stored, is returned.
+     * @param trans The store location for this matrix's translation.
+     * @return The value of this matrix's translation.
+     */
+    public Vector3f getTranslation(Vector3f trans) {
+        if (trans==null) trans=new Vector3f();
+        trans.set(this.translation);
+        return trans;
+    }
+
+    /**
+     * Stores this rotation value into the given Quaternion.  If quat is null, a new Quaternion is created to
+     * hold the value.  The value, once stored, is returned.
+     * @param quat The store location for this matrix's rotation.
+     * @return The value of this matrix's rotation.
+     */
+    public Quaternion getRotation(Quaternion quat) {
+        if (quat==null) quat=new Quaternion();
+        quat.set(rot);
+        return quat;
+    }
+    
+    /**
+     * Return the rotation quaternion in this matrix.
+     * @return rotation quaternion.
+     */
+    public Quaternion getRotation() {
+        return rot;
+    } 
+    
+    /**
+     * Stores this scale value into the given vector3f.  If scale is null, a new vector3f is created to
+     * hold the value.  The value, once stored, is returned.
+     * @param scale The store location for this matrix's scale.
+     * @return The value of this matrix's scale.
+     */
+    public Vector3f getScale(Vector3f scale) {
+        if (scale==null) scale=new Vector3f();
+        scale.set(this.scale);
+        return scale;
+    }
+
+    /**
+     * Sets this matrix to the interpolation between the first matrix and the second by delta amount.
+     * @param t1 The begining transform.
+     * @param t2 The ending transform.
+     * @param delta An amount between 0 and 1 representing how far to interpolate from t1 to t2.
+     */
+    public void interpolateTransforms(Transform t1, Transform t2, float delta) {
+        this.rot.slerp(t1.rot,t2.rot,delta);
+        this.translation.interpolate(t1.translation,t2.translation,delta);
+        this.scale.interpolate(t1.scale,t2.scale,delta);
+    }
+
+    /**
+     * Changes the values of this matrix acording to it's parent.  Very similar to the concept of Node/Spatial transforms.
+     * @param parent The parent matrix.
+     * @return This matrix, after combining.
+     */
+    public Transform combineWithParent(Transform parent) {
+        scale.multLocal(parent.scale);
+//        rot.multLocal(parent.rot);
+        parent.rot.mult(rot, rot);
+
+        // This here, is evil code
+//        parent
+//            .rot
+//            .multLocal(translation)
+//            .multLocal(parent.scale)
+//            .addLocal(parent.translation);
+
+        translation.multLocal(parent.scale);
+        parent
+            .rot
+            .multLocal(translation)
+            .addLocal(parent.translation);
+        return this;
+    }
+
+    /**
+     * Sets this matrix's translation to the given x,y,z values.
+     * @param x This matrix's new x translation.
+     * @param y This matrix's new y translation.
+     * @param z This matrix's new z translation.
+     * @return this
+     */
+    public Transform setTranslation(float x,float y, float z) {
+        translation.set(x,y,z);
+        return this;
+    }
+
+    /**
+     * Sets this matrix's scale to the given x,y,z values.
+     * @param x This matrix's new x scale.
+     * @param y This matrix's new y scale.
+     * @param z This matrix's new z scale.
+     * @return this
+     */
+    public Transform setScale(float x, float y, float z) {
+        scale.set(x,y,z);
+        return this;
+    }
+
+    public Vector3f transformVector(final Vector3f in, Vector3f store){
+        if (store == null)
+            store = new Vector3f();
+
+        // multiply with scale first, then rotate, finally translate (cf.
+        // Eberly)
+        return rot.mult(store.set(in).multLocal(scale), store).addLocal(translation);
+    }
+
+    public Vector3f transformInverseVector(final Vector3f in, Vector3f store){
+        if (store == null)
+            store = new Vector3f();
+
+        // The author of this code should look above and take the inverse of that
+        // But for some reason, they didnt ..
+//        in.subtract(translation, store).divideLocal(scale);
+//        rot.inverse().mult(store, store);
+
+        in.subtract(translation, store);
+        rot.inverse().mult(store, store);
+        store.divideLocal(scale);
+
+        return store;
+    }
+
+    /**
+     * Loads the identity.  Equal to translation=0,0,0 scale=1,1,1 rot=0,0,0,1.
+     */
+    public void loadIdentity() {
+        translation.set(0,0,0);
+        scale.set(1,1,1);
+        rot.set(0,0,0,1);
+    }
+
+    @Override
+    public String toString(){
+        return getClass().getSimpleName() + "[ " + translation.x + ", " + translation.y + ", " + translation.z + "]\n"
+                                          + "[ " + rot.x + ", " + rot.y + ", " + rot.z + ", " + rot.w + "]\n"
+                                          + "[ " + scale.x + " , " + scale.y + ", " + scale.z + "]";
+    }
+
+    /**
+     * Sets this matrix to be equal to the given matrix.
+     * @param matrixQuat The matrix to be equal to.
+     * @return this
+     */
+    public Transform set(Transform matrixQuat) {
+        this.translation.set(matrixQuat.translation);
+        this.rot.set(matrixQuat.rot);
+        this.scale.set(matrixQuat.scale);
+        return this;
+    }
+
+    public void write(JmeExporter e) throws IOException {
+        OutputCapsule capsule = e.getCapsule(this);
+        capsule.write(rot, "rot", new Quaternion());
+        capsule.write(translation, "translation", Vector3f.ZERO);
+        capsule.write(scale, "scale", Vector3f.UNIT_XYZ);
+    }
+
+    public void read(JmeImporter e) throws IOException {
+        InputCapsule capsule = e.getCapsule(this);
+        
+        rot = (Quaternion)capsule.readSavable("rot", new Quaternion());
+        translation = (Vector3f)capsule.readSavable("translation", Vector3f.ZERO);
+        scale = (Vector3f)capsule.readSavable("scale", Vector3f.UNIT_XYZ);
+    }
+    
+    @Override
+    public Transform clone() {
+        try {
+            Transform tq = (Transform) super.clone();
+            tq.rot = rot.clone();
+            tq.scale = scale.clone();
+            tq.translation = translation.clone();
+            return tq;
+        } catch (CloneNotSupportedException e) {
+            throw new AssertionError();
+        }
+    }
+}
diff --git a/engine/src/core/com/jme3/post/Filter.java b/engine/src/core/com/jme3/post/Filter.java
index ef9a6ff..12babf5 100644
--- a/engine/src/core/com/jme3/post/Filter.java
+++ b/engine/src/core/com/jme3/post/Filter.java
@@ -40,6 +40,7 @@
 import com.jme3.renderer.ViewPort;
 import com.jme3.texture.FrameBuffer;
 import com.jme3.texture.Image.Format;
+import com.jme3.texture.Texture;
 import com.jme3.texture.Texture2D;
 import java.io.IOException;
 import java.util.Collection;
@@ -236,7 +237,7 @@
      * cleanup this filter
      * @param r
      */
-    protected final void cleanup(Renderer r) {
+    protected final void cleanup(Renderer r) {   
         processor = null;
         if (defaultPass != null) {
             defaultPass.cleanup(r);
@@ -269,8 +270,6 @@
     protected void cleanUpFilter(Renderer r) {
     }
 
-    ;
-
     /**
      * Must return the material used for this filter.
      * this method is called every frame.
@@ -278,6 +277,14 @@
      * @return the material used for this filter.
      */
     protected abstract Material getMaterial();
+    
+    /**
+     * Override if you want to do something special with the depth texture;
+     * @param depthTexture 
+     */
+    protected void setDepthTexture(Texture depthTexture){
+        getMaterial().setTexture("DepthTexture", depthTexture);
+    }
 
     /**
      * Override this method if you want to make a pre pass, before the actual rendering of the frame
diff --git a/engine/src/core/com/jme3/post/FilterPostProcessor.java b/engine/src/core/com/jme3/post/FilterPostProcessor.java
index 2e48f0f..d97e8e9 100644
--- a/engine/src/core/com/jme3/post/FilterPostProcessor.java
+++ b/engine/src/core/com/jme3/post/FilterPostProcessor.java
@@ -77,7 +77,7 @@
     private int originalHeight;
     private int lastFilterIndex = -1;
     private boolean cameraInit = false;
-
+    
     /**
      * Create a FilterProcessor 
      * @param assetManager the assetManager
@@ -98,8 +98,7 @@
      * @param filter the filter to add
      */
     public void addFilter(Filter filter) {
-        filters.add(filter);
-        filter.setProcessor(this);
+        filters.add(filter);        
 
         if (isInitialized()) {
             initFilter(filter, viewPort);
@@ -148,14 +147,17 @@
      * @param vp 
      */
     private void initFilter(Filter filter, ViewPort vp) {
-        filter.init(assetManager, renderManager, vp, width, height);
+        filter.setProcessor(this);
         if (filter.isRequiresDepthTexture()) {
-            if (!computeDepth && renderFrameBuffer != null) {
+            if (!computeDepth && renderFrameBuffer != null) {                
                 depthTexture = new Texture2D(width, height, Format.Depth24);
                 renderFrameBuffer.setDepthTexture(depthTexture);
             }
             computeDepth = true;
-            filter.getMaterial().setTexture("DepthTexture", depthTexture);
+            filter.init(assetManager, renderManager, vp, width, height);
+            filter.setDepthTexture(depthTexture);
+        } else {
+            filter.init(assetManager, renderManager, vp, width, height);
         }
     }
 
@@ -281,9 +283,9 @@
         } else if (renderFrameBufferMS != null) {
             sceneBuffer = renderFrameBufferMS;
         }
-        renderFilterChain(renderer, sceneBuffer);        
+        renderFilterChain(renderer, sceneBuffer);
         renderer.setFrameBuffer(outputBuffer);
-        
+
         //viewport can be null if no filters are enabled
         if (viewPort != null) {
             renderManager.setCamera(viewPort.getCamera(), false);
@@ -356,8 +358,11 @@
             //reseting the viewport camera viewport to its initial value
             viewPort.getCamera().resize(originalWidth, originalHeight, true);
             viewPort.getCamera().setViewPort(left, right, bottom, top);
-            viewPort.setOutputFrameBuffer(outputBuffer);          
+            viewPort.setOutputFrameBuffer(outputBuffer);            
             viewPort = null;
+            for (Filter filter : filters) {
+                filter.cleanup(renderer);
+            }
         }
 
     }
@@ -484,7 +489,7 @@
      * For internal use only<br>
      * returns the depth texture of the scene
      * @return 
-     */
+     */    
     public Texture2D getDepthTexture() {
         return depthTexture;
     }
diff --git a/engine/src/core/com/jme3/renderer/RenderManager.java b/engine/src/core/com/jme3/renderer/RenderManager.java
index 1d58d22..a0f5fdf 100644
--- a/engine/src/core/com/jme3/renderer/RenderManager.java
+++ b/engine/src/core/com/jme3/renderer/RenderManager.java
@@ -1,1170 +1,1178 @@
-/*
- * Copyright (c) 2009-2012 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- *   may be used to endorse or promote products derived from this software
- *   without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package com.jme3.renderer;
-
-import com.jme3.material.Material;
-import com.jme3.material.MaterialDef;
-import com.jme3.material.RenderState;
-import com.jme3.material.Technique;
-import com.jme3.math.*;
-import com.jme3.post.SceneProcessor;
-import com.jme3.renderer.queue.GeometryList;
-import com.jme3.renderer.queue.RenderQueue;
-import com.jme3.renderer.queue.RenderQueue.Bucket;
-import com.jme3.renderer.queue.RenderQueue.ShadowMode;
-import com.jme3.scene.*;
-import com.jme3.shader.Uniform;
-import com.jme3.shader.UniformBinding;
-import com.jme3.shader.VarType;
-import com.jme3.system.NullRenderer;
-import com.jme3.system.Timer;
-import com.jme3.util.IntMap.Entry;
-import com.jme3.util.TempVars;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.logging.Logger;
-
-/**
- * <code>RenderManager</code> is a high-level rendering interface that is
- * above the Renderer implementation. RenderManager takes care
- * of rendering the scene graphs attached to each viewport and
- * handling SceneProcessors.
- *
- * @see SceneProcessor
- * @see ViewPort
- * @see Spatial
- */
-public class RenderManager {
-
-    private static final Logger logger = Logger.getLogger(RenderManager.class.getName());
-    
-    private Renderer renderer;
-    private Timer timer;
-    private ArrayList<ViewPort> preViewPorts = new ArrayList<ViewPort>();
-    private ArrayList<ViewPort> viewPorts = new ArrayList<ViewPort>();
-    private ArrayList<ViewPort> postViewPorts = new ArrayList<ViewPort>();
-    private Camera prevCam = null;
-    private Material forcedMaterial = null;
-    private String forcedTechnique = null;
-    private RenderState forcedRenderState = null;
-    private boolean shader;
-    private int viewX, viewY, viewWidth, viewHeight;
-    private float near, far;
-    private Matrix4f orthoMatrix = new Matrix4f();
-    private Matrix4f viewMatrix = new Matrix4f();
-    private Matrix4f projMatrix = new Matrix4f();
-    private Matrix4f viewProjMatrix = new Matrix4f();
-    private Matrix4f worldMatrix = new Matrix4f();
-    private Vector3f camUp = new Vector3f(),
-            camLeft = new Vector3f(),
-            camDir = new Vector3f(),
-            camLoc = new Vector3f();
-    //temp technique
-    private String tmpTech;
-    private boolean handleTranlucentBucket = true;
-
-    /**
-     * Create a high-level rendering interface over the
-     * low-level rendering interface.
-     * @param renderer
-     */
-    public RenderManager(Renderer renderer) {
-        this.renderer = renderer;
-        //this.shader = renderer.getCaps().contains(Caps.GLSL100);
-    }
-
-    /**
-     * Returns the pre ViewPort with the given name.
-     * 
-     * @param viewName The name of the pre ViewPort to look up
-     * @return The ViewPort, or null if not found.
-     * 
-     * @see #createPreView(java.lang.String, com.jme3.renderer.Camera) 
-     */
-    public ViewPort getPreView(String viewName) {
-        for (int i = 0; i < preViewPorts.size(); i++) {
-            if (preViewPorts.get(i).getName().equals(viewName)) {
-                return preViewPorts.get(i);
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Removes the specified pre ViewPort.
-     * 
-     * @param view The pre ViewPort to remove
-     * @return True if the ViewPort was removed successfully.
-     * 
-     * @see #createPreView(java.lang.String, com.jme3.renderer.Camera) 
-     */
-    public boolean removePreView(ViewPort view) {
-        return preViewPorts.remove(view);
-    }
-
-    /**
-     * Returns the main ViewPort with the given name.
-     * 
-     * @param viewName The name of the main ViewPort to look up
-     * @return The ViewPort, or null if not found.
-     * 
-     * @see #createMainView(java.lang.String, com.jme3.renderer.Camera) 
-     */
-    public ViewPort getMainView(String viewName) {
-        for (int i = 0; i < viewPorts.size(); i++) {
-            if (viewPorts.get(i).getName().equals(viewName)) {
-                return viewPorts.get(i);
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Removes the main ViewPort with the specified name.
-     * 
-     * @param viewName The main ViewPort name to remove
-     * @return True if the ViewPort was removed successfully.
-     * 
-     * @see #createMainView(java.lang.String, com.jme3.renderer.Camera) 
-     */
-    public boolean removeMainView(String viewName) {
-        for (int i = 0; i < viewPorts.size(); i++) {
-            if (viewPorts.get(i).getName().equals(viewName)) {
-                viewPorts.remove(i);
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Removes the specified main ViewPort.
-     * 
-     * @param view The main ViewPort to remove
-     * @return True if the ViewPort was removed successfully.
-     * 
-     * @see #createMainView(java.lang.String, com.jme3.renderer.Camera) 
-     */
-    public boolean removeMainView(ViewPort view) {
-        return viewPorts.remove(view);
-    }
-
-    /**
-     * Returns the post ViewPort with the given name.
-     * 
-     * @param viewName The name of the post ViewPort to look up
-     * @return The ViewPort, or null if not found.
-     * 
-     * @see #createPostView(java.lang.String, com.jme3.renderer.Camera) 
-     */
-    public ViewPort getPostView(String viewName) {
-        for (int i = 0; i < postViewPorts.size(); i++) {
-            if (postViewPorts.get(i).getName().equals(viewName)) {
-                return postViewPorts.get(i);
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Removes the post ViewPort with the specified name.
-     * 
-     * @param viewName The post ViewPort name to remove
-     * @return True if the ViewPort was removed successfully.
-     * 
-     * @see #createPostView(java.lang.String, com.jme3.renderer.Camera) 
-     */
-    public boolean removePostView(String viewName) {
-        for (int i = 0; i < postViewPorts.size(); i++) {
-            if (postViewPorts.get(i).getName().equals(viewName)) {
-                postViewPorts.remove(i);
-
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Removes the specified post ViewPort.
-     * 
-     * @param view The post ViewPort to remove
-     * @return True if the ViewPort was removed successfully.
-     * 
-     * @see #createPostView(java.lang.String, com.jme3.renderer.Camera) 
-     */
-    public boolean removePostView(ViewPort view) {
-        return postViewPorts.remove(view);
-    }
-
-    /**
-     * Returns a read-only list of all pre ViewPorts
-     * @return a read-only list of all pre ViewPorts
-     * @see #createPreView(java.lang.String, com.jme3.renderer.Camera) 
-     */
-    public List<ViewPort> getPreViews() {
-        return Collections.unmodifiableList(preViewPorts);
-    }
-
-    /**
-     * Returns a read-only list of all main ViewPorts
-     * @return a read-only list of all main ViewPorts
-     * @see #createMainView(java.lang.String, com.jme3.renderer.Camera) 
-     */
-    public List<ViewPort> getMainViews() {
-        return Collections.unmodifiableList(viewPorts);
-    }
-
-    /**
-     * Returns a read-only list of all post ViewPorts
-     * @return a read-only list of all post ViewPorts
-     * @see #createPostView(java.lang.String, com.jme3.renderer.Camera) 
-     */
-    public List<ViewPort> getPostViews() {
-        return Collections.unmodifiableList(postViewPorts);
-    }
-
-    /**
-     * Creates a new pre ViewPort, to display the given camera's content.
-     * <p>
-     * The view will be processed before the main and post viewports.
-     */
-    public ViewPort createPreView(String viewName, Camera cam) {
-        ViewPort vp = new ViewPort(viewName, cam);
-        preViewPorts.add(vp);
-        return vp;
-    }
-
-    /**
-     * Creates a new main ViewPort, to display the given camera's content.
-     * <p>
-     * The view will be processed before the post viewports but after
-     * the pre viewports.
-     */
-    public ViewPort createMainView(String viewName, Camera cam) {
-        ViewPort vp = new ViewPort(viewName, cam);
-        viewPorts.add(vp);
-        return vp;
-    }
-
-    /**
-     * Creates a new post ViewPort, to display the given camera's content.
-     * <p>
-     * The view will be processed after the pre and main viewports.
-     */
-    public ViewPort createPostView(String viewName, Camera cam) {
-        ViewPort vp = new ViewPort(viewName, cam);
-        postViewPorts.add(vp);
-        return vp;
-    }
-
-    private void notifyReshape(ViewPort vp, int w, int h) {
-        List<SceneProcessor> processors = vp.getProcessors();
-        for (SceneProcessor proc : processors) {
-            if (!proc.isInitialized()) {
-                proc.initialize(this, vp);
-            } else {
-                proc.reshape(vp, w, h);
-            }
-        }
-    }
-
-    /**
-     * Internal use only.
-     * Updates the resolution of all on-screen cameras to match
-     * the given width and height.
-     */
-    public void notifyReshape(int w, int h) {
-        for (ViewPort vp : preViewPorts) {
-            if (vp.getOutputFrameBuffer() == null) {
-                Camera cam = vp.getCamera();
-                cam.resize(w, h, true);
-            }
-            notifyReshape(vp, w, h);
-        }
-        for (ViewPort vp : viewPorts) {
-            if (vp.getOutputFrameBuffer() == null) {
-                Camera cam = vp.getCamera();
-                cam.resize(w, h, true);
-            }
-            notifyReshape(vp, w, h);
-        }
-        for (ViewPort vp : postViewPorts) {
-            if (vp.getOutputFrameBuffer() == null) {
-                Camera cam = vp.getCamera();
-                cam.resize(w, h, true);
-            }
-            notifyReshape(vp, w, h);
-        }
-    }
-
-    /**
-     * Internal use only.
-     * Updates the given list of uniforms with {@link UniformBinding uniform bindings}
-     * based on the current world state.
-     */
-    public void updateUniformBindings(List<Uniform> params) {
-        // assums worldMatrix is properly set.
-        TempVars vars = TempVars.get();
-
-        Matrix4f tempMat4 = vars.tempMat4;
-        Matrix3f tempMat3 = vars.tempMat3;
-        Vector2f tempVec2 = vars.vect2d;
-        Quaternion tempVec4 = vars.quat1;
-
-        for (int i = 0; i < params.size(); i++) {
-            Uniform u = params.get(i);
-            switch (u.getBinding()) {
-                case WorldMatrix:
-                    u.setValue(VarType.Matrix4, worldMatrix);
-                    break;
-                case ViewMatrix:
-                    u.setValue(VarType.Matrix4, viewMatrix);
-                    break;
-                case ProjectionMatrix:
-                    u.setValue(VarType.Matrix4, projMatrix);
-                    break;
-                case ViewProjectionMatrix:
-                    u.setValue(VarType.Matrix4, viewProjMatrix);
-                    break;
-                case WorldViewMatrix:
-                    tempMat4.set(viewMatrix);
-                    tempMat4.multLocal(worldMatrix);
-                    u.setValue(VarType.Matrix4, tempMat4);
-                    break;
-                case NormalMatrix:
-                    tempMat4.set(viewMatrix);
-                    tempMat4.multLocal(worldMatrix);
-                    tempMat4.toRotationMatrix(tempMat3);
-                    tempMat3.invertLocal();
-                    tempMat3.transposeLocal();
-                    u.setValue(VarType.Matrix3, tempMat3);
-                    break;
-                case WorldViewProjectionMatrix:
-                    tempMat4.set(viewProjMatrix);
-                    tempMat4.multLocal(worldMatrix);
-                    u.setValue(VarType.Matrix4, tempMat4);
-                    break;
-                case WorldMatrixInverse:
-                    tempMat4.multLocal(worldMatrix);
-                    tempMat4.invertLocal();
-                    u.setValue(VarType.Matrix4, tempMat4);
-                    break;
-                case ViewMatrixInverse:
-                    tempMat4.set(viewMatrix);
-                    tempMat4.invertLocal();
-                    u.setValue(VarType.Matrix4, tempMat4);
-                    break;
-                case ProjectionMatrixInverse:
-                    tempMat4.set(projMatrix);
-                    tempMat4.invertLocal();
-                    u.setValue(VarType.Matrix4, tempMat4);
-                    break;
-                case ViewProjectionMatrixInverse:
-                    tempMat4.set(viewProjMatrix);
-                    tempMat4.invertLocal();
-                    u.setValue(VarType.Matrix4, tempMat4);
-                    break;
-                case WorldViewMatrixInverse:
-                    tempMat4.set(viewMatrix);
-                    tempMat4.multLocal(worldMatrix);
-                    tempMat4.invertLocal();
-                    u.setValue(VarType.Matrix4, tempMat4);
-                    break;
-                case NormalMatrixInverse:
-                    tempMat4.set(viewMatrix);
-                    tempMat4.multLocal(worldMatrix);
-                    tempMat4.toRotationMatrix(tempMat3);
-                    tempMat3.invertLocal();
-                    tempMat3.transposeLocal();
-                    tempMat3.invertLocal();
-                    u.setValue(VarType.Matrix3, tempMat3);
-                    break;
-                case WorldViewProjectionMatrixInverse:
-                    tempMat4.set(viewProjMatrix);
-                    tempMat4.multLocal(worldMatrix);
-                    tempMat4.invertLocal();
-                    u.setValue(VarType.Matrix4, tempMat4);
-                    break;
-                case ViewPort:
-                    tempVec4.set(viewX, viewY, viewWidth, viewHeight);
-                    u.setValue(VarType.Vector4, tempVec4);
-                    break;
-                case Resolution:
-                    tempVec2.set(viewWidth, viewHeight);
-                    u.setValue(VarType.Vector2, tempVec2);
-                    break;
-                case Aspect:
-                    float aspect = ((float) viewWidth) / viewHeight;
-                    u.setValue(VarType.Float, aspect);
-                    break;
-                case FrustumNearFar:
-                    tempVec2.set(near, far);
-                    u.setValue(VarType.Vector2, tempVec2);
-                    break;
-                case CameraPosition:
-                    u.setValue(VarType.Vector3, camLoc);
-                    break;
-                case CameraDirection:
-                    u.setValue(VarType.Vector3, camDir);
-                    break;
-                case CameraLeft:
-                    u.setValue(VarType.Vector3, camLeft);
-                    break;
-                case CameraUp:
-                    u.setValue(VarType.Vector3, camUp);
-                    break;
-                case Time:
-                    u.setValue(VarType.Float, timer.getTimeInSeconds());
-                    break;
-                case Tpf:
-                    u.setValue(VarType.Float, timer.getTimePerFrame());
-                    break;
-                case FrameRate:
-                    u.setValue(VarType.Float, timer.getFrameRate());
-                    break;
-            }
-        }
-
-        vars.release();
-    }
-
-    /**
-     * Set the material to use to render all future objects.
-     * This overrides the material set on the geometry and renders
-     * with the provided material instead.
-     * Use null to clear the material and return renderer to normal
-     * functionality.
-     * @param mat The forced material to set, or null to return to normal
-     */
-    public void setForcedMaterial(Material mat) {
-        forcedMaterial = mat;
-    }
-
-    /**
-     * Returns the forced render state previously set with 
-     * {@link #setForcedRenderState(com.jme3.material.RenderState) }.
-     * @return the forced render state
-     */
-    public RenderState getForcedRenderState() {
-        return forcedRenderState;
-    }
-
-    /**
-     * Set the render state to use for all future objects.
-     * This overrides the render state set on the material and instead
-     * forces this render state to be applied for all future materials
-     * rendered. Set to null to return to normal functionality.
-     * 
-     * @param forcedRenderState The forced render state to set, or null
-     * to return to normal
-     */
-    public void setForcedRenderState(RenderState forcedRenderState) {
-        this.forcedRenderState = forcedRenderState;
-    }
-
-    /**
-     * Set the timer that should be used to query the time based
-     * {@link UniformBinding}s for material world parameters.
-     * 
-     * @param timer The timer to query time world parameters
-     */
-    public void setTimer(Timer timer) {
-        this.timer = timer;
-    }
-
-    /**
-     * Returns the forced technique name set.
-     * 
-     * @return the forced technique name set.
-     * 
-     * @see #setForcedTechnique(java.lang.String) 
-     */
-    public String getForcedTechnique() {
-        return forcedTechnique;
-    }
-
-    /**
-     * Sets the forced technique to use when rendering geometries.
-     * <p>
-     * If the specified technique name is available on the geometry's
-     * material, then it is used, otherwise, the 
-     * {@link #setForcedMaterial(com.jme3.material.Material) forced material} is used.
-     * If a forced material is not set and the forced technique name cannot
-     * be found on the material, the geometry will <em>not</em> be rendered.
-     * 
-     * @param forcedTechnique The forced technique name to use, set to null
-     * to return to normal functionality.
-     * 
-     * @see #renderGeometry(com.jme3.scene.Geometry) 
-     */
-    public void setForcedTechnique(String forcedTechnique) {
-        this.forcedTechnique = forcedTechnique;
-    }
-
-    /**
-     * Enable or disable alpha-to-coverage. 
-     * <p>
-     * When alpha to coverage is enabled and the renderer implementation
-     * supports it, then alpha blending will be replaced with alpha dissolve
-     * if multi-sampling is also set on the renderer.
-     * This feature allows avoiding of alpha blending artifacts due to
-     * lack of triangle-level back-to-front sorting.
-     * 
-     * @param value True to enable alpha-to-coverage, false otherwise.
-     */
-    public void setAlphaToCoverage(boolean value) {
-        renderer.setAlphaToCoverage(value);
-    }
-
-    /**
-     * True if the translucent bucket should automatically be rendered
-     * by the RenderManager.
-     * 
-     * @return Whether or not the translucent bucket is rendered.
-     * 
-     * @see #setHandleTranslucentBucket(boolean) 
-     */
-    public boolean isHandleTranslucentBucket() {
-        return handleTranlucentBucket;
-    }
-
-    /**
-     * Enable or disable rendering of the 
-     * {@link Bucket#Translucent translucent bucket}
-     * by the RenderManager. The default is enabled.
-     * 
-     * @param handleTranslucentBucket Whether or not the translucent bucket should
-     * be rendered.
-     */
-    public void setHandleTranslucentBucket(boolean handleTranslucentBucket) {
-        this.handleTranlucentBucket = handleTranslucentBucket;
-    }
-
-    /**
-     * Internal use only. Sets the world matrix to use for future
-     * rendering. This has no effect unless objects are rendered manually
-     * using {@link Material#render(com.jme3.scene.Geometry, com.jme3.renderer.RenderManager) }.
-     * Using {@link #renderGeometry(com.jme3.scene.Geometry) } will 
-     * override this value.
-     * 
-     * @param mat The world matrix to set
-     */
-    public void setWorldMatrix(Matrix4f mat) {
-        if (shader) {
-            worldMatrix.set(mat);
-        } else {
-            renderer.setWorldMatrix(mat);
-        }
-    }
-
-    /**
-     * Renders the given geometry.
-     * <p>
-     * First the proper world matrix is set, if 
-     * the geometry's {@link Geometry#setIgnoreTransform(boolean) ignore transform}
-     * feature is enabled, the identity world matrix is used, otherwise, the 
-     * geometry's {@link Geometry#getWorldMatrix() world transform matrix} is used. 
-     * <p>
-     * Once the world matrix is applied, the proper material is chosen for rendering.
-     * If a {@link #setForcedMaterial(com.jme3.material.Material) forced material} is
-     * set on this RenderManager, then it is used for rendering the geometry,
-     * otherwise, the {@link Geometry#getMaterial() geometry's material} is used.
-     * <p>
-     * If a {@link #setForcedTechnique(java.lang.String) forced technique} is
-     * set on this RenderManager, then it is selected automatically
-     * on the geometry's material and is used for rendering. Otherwise, one
-     * of the {@link MaterialDef#getDefaultTechniques() default techniques} is
-     * used.
-     * <p>
-     * If a {@link #setForcedRenderState(com.jme3.material.RenderState) forced
-     * render state} is set on this RenderManager, then it is used
-     * for rendering the material, and the material's own render state is ignored.
-     * Otherwise, the material's render state is used as intended.
-     * 
-     * @param g The geometry to render
-     * 
-     * @see Technique
-     * @see RenderState
-     * @see Material#selectTechnique(java.lang.String, com.jme3.renderer.RenderManager) 
-     * @see Material#render(com.jme3.scene.Geometry, com.jme3.renderer.RenderManager) 
-     */
-    public void renderGeometry(Geometry g) {
-        if (g.isIgnoreTransform()) {
-            setWorldMatrix(Matrix4f.IDENTITY);
-        } else {
-            setWorldMatrix(g.getWorldMatrix());
-        }
-
-        //if forcedTechnique we try to force it for render,
-        //if it does not exists in the mat def, we check for forcedMaterial and render the geom if not null
-        //else the geom is not rendered
-        if (forcedTechnique != null) {
-            if (g.getMaterial().getMaterialDef().getTechniqueDef(forcedTechnique) != null) {
-                tmpTech = g.getMaterial().getActiveTechnique() != null ? g.getMaterial().getActiveTechnique().getDef().getName() : "Default";
-                g.getMaterial().selectTechnique(forcedTechnique, this);
-                // use geometry's material
-                g.getMaterial().render(g, this);
-                g.getMaterial().selectTechnique(tmpTech, this);
-                //Reverted this part from revision 6197
-                //If forcedTechnique does not exists, and frocedMaterial is not set, the geom MUST NOT be rendered
-            } else if (forcedMaterial != null) {
-                // use forced material
-                forcedMaterial.render(g, this);
-            }
-        } else if (forcedMaterial != null) {
-            // use forced material
-            forcedMaterial.render(g, this);
-        } else {
-            g.getMaterial().render(g, this);
-        }
-    }
-
-    /**
-     * Renders the given GeometryList.
-     * <p>
-     * For every geometry in the list, the 
-     * {@link #renderGeometry(com.jme3.scene.Geometry) } method is called.
-     * 
-     * @param gl The geometry list to render.
-     * 
-     * @see GeometryList
-     * @see #renderGeometry(com.jme3.scene.Geometry) 
-     */
-    public void renderGeometryList(GeometryList gl) {
-        for (int i = 0; i < gl.size(); i++) {
-            renderGeometry(gl.get(i));
-        }
-    }
-
-    /**
-     * If a spatial is not inside the eye frustum, it
-     * is still rendered in the shadow frustum (shadow casting queue)
-     * through this recursive method.
-     */
-    private void renderShadow(Spatial s, RenderQueue rq) {
-        if (s instanceof Node) {
-            Node n = (Node) s;
-            List<Spatial> children = n.getChildren();
-            for (int i = 0; i < children.size(); i++) {
-                renderShadow(children.get(i), rq);
-            }
-        } else if (s instanceof Geometry) {
-            Geometry gm = (Geometry) s;
-
-            RenderQueue.ShadowMode shadowMode = s.getShadowMode();
-            if (shadowMode != RenderQueue.ShadowMode.Off && shadowMode != RenderQueue.ShadowMode.Receive) {
-                //forcing adding to shadow cast mode, culled objects doesn't have to be in the receiver queue
-                rq.addToShadowQueue(gm, RenderQueue.ShadowMode.Cast);
-            }
-        }
-    }
-
-    /**
-     * Preloads a scene for rendering.
-     * <p>
-     * After invocation of this method, the underlying
-     * renderer would have uploaded any textures, shaders and meshes
-     * used by the given scene to the video driver. 
-     * Using this method is useful when wishing to avoid the initial pause
-     * when rendering a scene for the first time. Note that it is not 
-     * guaranteed that the underlying renderer will actually choose to upload
-     * the data to the GPU so some pause is still to be expected.
-     * 
-     * @param scene The scene to preload
-     */
-    public void preloadScene(Spatial scene) {
-        if (scene instanceof Node) {
-            // recurse for all children
-            Node n = (Node) scene;
-            List<Spatial> children = n.getChildren();
-            for (int i = 0; i < children.size(); i++) {
-                preloadScene(children.get(i));
-            }
-        } else if (scene instanceof Geometry) {
-            // add to the render queue
-            Geometry gm = (Geometry) scene;
-            if (gm.getMaterial() == null) {
-                throw new IllegalStateException("No material is set for Geometry: " + gm.getName());
-            }
-
-            gm.getMaterial().preload(this);
-            Mesh mesh = gm.getMesh();
-            if (mesh != null) {
-                for (Entry<VertexBuffer> entry : mesh.getBuffers()) {
-                    VertexBuffer buf = entry.getValue();
-                    if (buf.getData() != null) {
-                        renderer.updateBufferData(buf);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Flattens the given scene graph into the ViewPort's RenderQueue,
-     * checking for culling as the call goes down the graph recursively.
-     * <p>
-     * First, the scene is checked for culling based on the <code>Spatial</code>s
-     * {@link Spatial#setCullHint(com.jme3.scene.Spatial.CullHint) cull hint},
-     * if the camera frustum contains the scene, then this method is recursively
-     * called on its children.
-     * <p>
-     * When the scene's leaves or {@link Geometry geometries} are reached,
-     * they are each enqueued into the 
-     * {@link ViewPort#getQueue() ViewPort's render queue}.
-     * <p>
-     * In addition to enqueuing the visible geometries, this method
-     * also scenes which cast or receive shadows, by putting them into the
-     * RenderQueue's 
-     * {@link RenderQueue#addToShadowQueue(com.jme3.scene.Geometry, com.jme3.renderer.queue.RenderQueue.ShadowMode) 
-     * shadow queue}. Each Spatial which has its 
-     * {@link Spatial#setShadowMode(com.jme3.renderer.queue.RenderQueue.ShadowMode) shadow mode}
-     * set to not off, will be put into the appropriate shadow queue, note that
-     * this process does not check for frustum culling on any 
-     * {@link ShadowMode#Cast shadow casters}, as they don't have to be
-     * in the eye camera frustum to cast shadows on objects that are inside it.
-     * 
-     * @param scene The scene to flatten into the queue
-     * @param vp The ViewPort provides the {@link ViewPort#getCamera() camera}
-     * used for culling and the {@link ViewPort#getQueue() queue} used to 
-     * contain the flattened scene graph.
-     */
-    public void renderScene(Spatial scene, ViewPort vp) {
-        if (scene.getParent() == null) {
-            vp.getCamera().setPlaneState(0);
-        }
-        // check culling first.
-        if (!scene.checkCulling(vp.getCamera())) {
-            // move on to shadow-only render
-            if ((scene.getShadowMode() != RenderQueue.ShadowMode.Off || scene instanceof Node) && scene.getCullHint()!=Spatial.CullHint.Always) {
-                renderShadow(scene, vp.getQueue());
-            }
-            return;
-        }
-
-        scene.runControlRender(this, vp);
-        if (scene instanceof Node) {
-            // recurse for all children
-            Node n = (Node) scene;
-            List<Spatial> children = n.getChildren();
-            //saving cam state for culling
-            int camState = vp.getCamera().getPlaneState();
-            for (int i = 0; i < children.size(); i++) {
-                //restoring cam state before proceeding children recusively
-                vp.getCamera().setPlaneState(camState);
-                renderScene(children.get(i), vp);
-
-            }
-        } else if (scene instanceof Geometry) {
-
-            // add to the render queue
-            Geometry gm = (Geometry) scene;
-            if (gm.getMaterial() == null) {
-                throw new IllegalStateException("No material is set for Geometry: " + gm.getName());
-            }
-
-            vp.getQueue().addToQueue(gm, scene.getQueueBucket());
-
-            // add to shadow queue if needed
-            RenderQueue.ShadowMode shadowMode = scene.getShadowMode();
-            if (shadowMode != RenderQueue.ShadowMode.Off) {
-                vp.getQueue().addToShadowQueue(gm, shadowMode);
-            }
-        }
-    }
-
-    /**
-     * Returns the camera currently used for rendering.
-     * <p>
-     * The camera can be set with {@link #setCamera(com.jme3.renderer.Camera, boolean) }.
-     * 
-     * @return the camera currently used for rendering.
-     */
-    public Camera getCurrentCamera() {
-        return prevCam;
-    }
-
-    /**
-     * The renderer implementation used for rendering operations.
-     * 
-     * @return The renderer implementation
-     * 
-     * @see #RenderManager(com.jme3.renderer.Renderer) 
-     * @see Renderer
-     */
-    public Renderer getRenderer() {
-        return renderer;
-    }
-
-    /**
-     * Flushes the ViewPort's {@link ViewPort#getQueue() render queue}
-     * by rendering each of its visible buckets.
-     * By default the queues will automatically be cleared after rendering,
-     * so there's no need to clear them manually.
-     * 
-     * @param vp The ViewPort of which the queue will be flushed
-     * 
-     * @see RenderQueue#renderQueue(com.jme3.renderer.queue.RenderQueue.Bucket, com.jme3.renderer.RenderManager, com.jme3.renderer.Camera) 
-     * @see #renderGeometryList(com.jme3.renderer.queue.GeometryList) 
-     */
-    public void flushQueue(ViewPort vp) {
-        renderViewPortQueues(vp, true);
-    }
-
-    /**
-     * Clears the queue of the given ViewPort.
-     * Simply calls {@link RenderQueue#clear() } on the ViewPort's 
-     * {@link ViewPort#getQueue() render queue}.
-     * 
-     * @param vp The ViewPort of which the queue will be cleared.
-     * 
-     * @see RenderQueue#clear()
-     * @see ViewPort#getQueue()
-     */
-    public void clearQueue(ViewPort vp) {
-        vp.getQueue().clear();
-    }
-
-    /**
-     * Render the given viewport queues.
-     * <p>
-     * Changes the {@link Renderer#setDepthRange(float, float) depth range}
-     * appropriately as expected by each queue and then calls 
-     * {@link RenderQueue#renderQueue(com.jme3.renderer.queue.RenderQueue.Bucket, com.jme3.renderer.RenderManager, com.jme3.renderer.Camera, boolean) }
-     * on the queue. Makes sure to restore the depth range to [0, 1] 
-     * at the end of the call.
-     * Note that the {@link Bucket#Translucent translucent bucket} is NOT
-     * rendered by this method. Instead the user should call 
-     * {@link #renderTranslucentQueue(com.jme3.renderer.ViewPort) }
-     * after this call.
-     * 
-     * @param vp the viewport of which queue should be rendered
-     * @param flush If true, the queues will be cleared after
-     * rendering.
-     * 
-     * @see RenderQueue
-     * @see #renderTranslucentQueue(com.jme3.renderer.ViewPort) 
-     */
-    public void renderViewPortQueues(ViewPort vp, boolean flush) {
-        RenderQueue rq = vp.getQueue();
-        Camera cam = vp.getCamera();
-        boolean depthRangeChanged = false;
-
-        // render opaque objects with default depth range
-        // opaque objects are sorted front-to-back, reducing overdraw
-        rq.renderQueue(Bucket.Opaque, this, cam, flush);
-
-        // render the sky, with depth range set to the farthest
-        if (!rq.isQueueEmpty(Bucket.Sky)) {
-            renderer.setDepthRange(1, 1);
-            rq.renderQueue(Bucket.Sky, this, cam, flush);
-            depthRangeChanged = true;
-        }
-
-
-        // transparent objects are last because they require blending with the
-        // rest of the scene's objects. Consequently, they are sorted
-        // back-to-front.
-        if (!rq.isQueueEmpty(Bucket.Transparent)) {
-            if (depthRangeChanged) {
-                renderer.setDepthRange(0, 1);
-                depthRangeChanged = false;
-            }
-
-            rq.renderQueue(Bucket.Transparent, this, cam, flush);
-        }
-
-        if (!rq.isQueueEmpty(Bucket.Gui)) {
-            renderer.setDepthRange(0, 0);
-            setCamera(cam, true);
-            rq.renderQueue(Bucket.Gui, this, cam, flush);
-            setCamera(cam, false);
-            depthRangeChanged = true;
-        }
-
-        // restore range to default
-        if (depthRangeChanged) {
-            renderer.setDepthRange(0, 1);
-        }
-    }
-
-    /**
-     * Renders the {@link Bucket#Translucent translucent queue} on the viewPort.
-     * <p>
-     * This call does nothing unless {@link #setHandleTranslucentBucket(boolean) }
-     * is set to true. This method clears the translucent queue after rendering
-     * it.
-     * 
-     * @param vp The viewport of which the translucent queue should be rendered.
-     * 
-     * @see #renderViewPortQueues(com.jme3.renderer.ViewPort, boolean) 
-     * @see #setHandleTranslucentBucket(boolean) 
-     */
-    public void renderTranslucentQueue(ViewPort vp) {
-        RenderQueue rq = vp.getQueue();
-        if (!rq.isQueueEmpty(Bucket.Translucent) && handleTranlucentBucket) {
-            rq.renderQueue(Bucket.Translucent, this, vp.getCamera(), true);
-        }
-    }
-
-    private void setViewPort(Camera cam) {
-        // this will make sure to update viewport only if needed
-        if (cam != prevCam || cam.isViewportChanged()) {
-            viewX = (int) (cam.getViewPortLeft() * cam.getWidth());
-            viewY = (int) (cam.getViewPortBottom() * cam.getHeight());
-            viewWidth = (int) ((cam.getViewPortRight() - cam.getViewPortLeft()) * cam.getWidth());
-            viewHeight = (int) ((cam.getViewPortTop() - cam.getViewPortBottom()) * cam.getHeight());
-            renderer.setViewPort(viewX, viewY, viewWidth, viewHeight);
-            renderer.setClipRect(viewX, viewY, viewWidth, viewHeight);
-            cam.clearViewportChanged();
-            prevCam = cam;
-
-//            float translateX = viewWidth == viewX ? 0 : -(viewWidth + viewX) / (viewWidth - viewX);
-//            float translateY = viewHeight == viewY ? 0 : -(viewHeight + viewY) / (viewHeight - viewY);
-//            float scaleX = viewWidth == viewX ? 1f : 2f / (viewWidth - viewX);
-//            float scaleY = viewHeight == viewY ? 1f : 2f / (viewHeight - viewY);
-//            
-//            orthoMatrix.loadIdentity();
-//            orthoMatrix.setTranslation(translateX, translateY, 0);
-//            orthoMatrix.setScale(scaleX, scaleY, 0); 
-
-            orthoMatrix.loadIdentity();
-            orthoMatrix.setTranslation(-1f, -1f, 0f);
-            orthoMatrix.setScale(2f / cam.getWidth(), 2f / cam.getHeight(), 0f);
-        }
-    }
-
-    private void setViewProjection(Camera cam, boolean ortho) {
-        if (shader) {
-            if (ortho) {
-                viewMatrix.set(Matrix4f.IDENTITY);
-                projMatrix.set(orthoMatrix);
-                viewProjMatrix.set(orthoMatrix);
-            } else {
-                viewMatrix.set(cam.getViewMatrix());
-                projMatrix.set(cam.getProjectionMatrix());
-                viewProjMatrix.set(cam.getViewProjectionMatrix());
-            }
-
-            camLoc.set(cam.getLocation());
-            cam.getLeft(camLeft);
-            cam.getUp(camUp);
-            cam.getDirection(camDir);
-
-            near = cam.getFrustumNear();
-            far = cam.getFrustumFar();
-        } else {
-            if (ortho) {
-                renderer.setViewProjectionMatrices(Matrix4f.IDENTITY, orthoMatrix);
-            } else {
-                renderer.setViewProjectionMatrices(cam.getViewMatrix(),
-                        cam.getProjectionMatrix());
-            }
-
-        }
-    }
-
-    /**
-     * Set the camera to use for rendering.
-     * <p>
-     * First, the camera's 
-     * {@link Camera#setViewPort(float, float, float, float) view port parameters}
-     * are applied. Then, the camera's {@link Camera#getViewMatrix() view} and 
-     * {@link Camera#getProjectionMatrix() projection} matrices are set
-     * on the renderer. If <code>ortho</code> is <code>true</code>, then
-     * instead of using the camera's view and projection matrices, an ortho
-     * matrix is computed and used instead of the view projection matrix. 
-     * The ortho matrix converts from the range (0 ~ Width, 0 ~ Height, -1 ~ +1)
-     * to the clip range (-1 ~ +1, -1 ~ +1, -1 ~ +1).
-     * 
-     * @param cam The camera to set
-     * @param ortho True if to use orthographic projection (for GUI rendering),
-     * false if to use the camera's view and projection matrices.
-     */
-    public void setCamera(Camera cam, boolean ortho) {
-        setViewPort(cam);
-        setViewProjection(cam, ortho);
-    }
-
-    /**
-     * Draws the viewport but without notifying {@link SceneProcessor scene
-     * processors} of any rendering events.
-     * 
-     * @param vp The ViewPort to render
-     * 
-     * @see #renderViewPort(com.jme3.renderer.ViewPort, float) 
-     */
-    public void renderViewPortRaw(ViewPort vp) {
-        setCamera(vp.getCamera(), false);
-        List<Spatial> scenes = vp.getScenes();
-        for (int i = scenes.size() - 1; i >= 0; i--) {
-            renderScene(scenes.get(i), vp);
-        }
-        flushQueue(vp);
-    }
-
-    /**
-     * Renders the {@link ViewPort}.
-     * <p>
-     * If the ViewPort is {@link ViewPort#isEnabled() disabled}, this method
-     * returns immediately. Otherwise, the ViewPort is rendered by 
-     * the following process:<br>
-     * <ul>
-     * <li>All {@link SceneProcessor scene processors} that are attached
-     * to the ViewPort are {@link SceneProcessor#initialize(com.jme3.renderer.RenderManager, com.jme3.renderer.ViewPort) initialized}.
-     * </li>
-     * <li>The SceneProcessors' {@link SceneProcessor#preFrame(float) } method 
-     * is called.</li>
-     * <li>The ViewPort's {@link ViewPort#getOutputFrameBuffer() output framebuffer}
-     * is set on the Renderer</li>
-     * <li>The camera is set on the renderer, including its view port parameters.
-     * (see {@link #setCamera(com.jme3.renderer.Camera, boolean) })</li>
-     * <li>Any buffers that the ViewPort requests to be cleared are cleared
-     * and the {@link ViewPort#getBackgroundColor() background color} is set</li>
-     * <li>Every scene that is attached to the ViewPort is flattened into 
-     * the ViewPort's render queue 
-     * (see {@link #renderViewPortQueues(com.jme3.renderer.ViewPort, boolean) })
-     * </li>
-     * <li>The SceneProcessors' {@link SceneProcessor#postQueue(com.jme3.renderer.queue.RenderQueue) }
-     * method is called.</li>
-     * <li>The render queue is sorted and then flushed, sending
-     * rendering commands to the underlying Renderer implementation. 
-     * (see {@link #flushQueue(com.jme3.renderer.ViewPort) })</li>
-     * <li>The SceneProcessors' {@link SceneProcessor#postFrame(com.jme3.texture.FrameBuffer) }
-     * method is called.</li>
-     * <li>The translucent queue of the ViewPort is sorted and then flushed
-     * (see {@link #renderTranslucentQueue(com.jme3.renderer.ViewPort) })</li>
-     * <li>If any objects remained in the render queue, they are removed
-     * from the queue. This is generally objects added to the 
-     * {@link RenderQueue#renderShadowQueue(com.jme3.renderer.queue.RenderQueue.ShadowMode, com.jme3.renderer.RenderManager, com.jme3.renderer.Camera, boolean) 
-     * shadow queue}
-     * which were not rendered because of a missing shadow renderer.</li>
-     * </ul>
-     * 
-     * @param vp
-     * @param tpf 
-     */
-    public void renderViewPort(ViewPort vp, float tpf) {
-        if (!vp.isEnabled()) {
-            return;
-        }
-        List<SceneProcessor> processors = vp.getProcessors();
-        if (processors.isEmpty()) {
-            processors = null;
-        }
-
-        if (processors != null) {
-            for (SceneProcessor proc : processors) {
-                if (!proc.isInitialized()) {
-                    proc.initialize(this, vp);
-                }
-                proc.preFrame(tpf);
-            }
-        }
-
-        renderer.setFrameBuffer(vp.getOutputFrameBuffer());
-        setCamera(vp.getCamera(), false);
-        if (vp.isClearDepth() || vp.isClearColor() || vp.isClearStencil()) {
-            if (vp.isClearColor()) {
-                renderer.setBackgroundColor(vp.getBackgroundColor());
-            }
-            renderer.clearBuffers(vp.isClearColor(),
-                    vp.isClearDepth(),
-                    vp.isClearStencil());
-        }
-
-        List<Spatial> scenes = vp.getScenes();
-        for (int i = scenes.size() - 1; i >= 0; i--) {
-            renderScene(scenes.get(i), vp);
-        }
-
-        if (processors != null) {
-            for (SceneProcessor proc : processors) {
-                proc.postQueue(vp.getQueue());
-            }
-        }
-
-        flushQueue(vp);
-
-        if (processors != null) {
-            for (SceneProcessor proc : processors) {
-                proc.postFrame(vp.getOutputFrameBuffer());
-            }
-        }
-        //renders the translucent objects queue after processors have been rendered
-        renderTranslucentQueue(vp);
-        // clear any remaining spatials that were not rendered.
-        clearQueue(vp);
-    }
-
-    /**
-     * Called by the application to render any ViewPorts
-     * added to this RenderManager.
-     * <p>
-     * Renders any viewports that were added using the following methods:
-     * <ul>
-     * <li>{@link #createPreView(java.lang.String, com.jme3.renderer.Camera) }</li>
-     * <li>{@link #createMainView(java.lang.String, com.jme3.renderer.Camera) }</li>
-     * <li>{@link #createPostView(java.lang.String, com.jme3.renderer.Camera) }</li>
-     * </ul>
-     * 
-     * @param tpf Time per frame value
-     */
-    public void render(float tpf, boolean mainFrameBufferActive) {
-        if (renderer instanceof NullRenderer) {
-            return;
-        }
-
-        this.shader = renderer.getCaps().contains(Caps.GLSL100);
-
-        for (int i = 0; i < preViewPorts.size(); i++) {
-            ViewPort vp = preViewPorts.get(i);
-            if (vp.getOutputFrameBuffer() != null || mainFrameBufferActive){
-                renderViewPort(vp, tpf);
-            }
-        }
-        for (int i = 0; i < viewPorts.size(); i++) {
-            ViewPort vp = viewPorts.get(i);
-            if (vp.getOutputFrameBuffer() != null || mainFrameBufferActive){
-                renderViewPort(vp, tpf);
-            }
-        }
-        for (int i = 0; i < postViewPorts.size(); i++) {
-            ViewPort vp = postViewPorts.get(i);
-            if (vp.getOutputFrameBuffer() != null || mainFrameBufferActive){
-                renderViewPort(vp, tpf);
-            }
-        }
-    }
-}
+/*
+ * Copyright (c) 2009-2012 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.renderer;
+
+import com.jme3.material.Material;
+import com.jme3.material.MaterialDef;
+import com.jme3.material.RenderState;
+import com.jme3.material.Technique;
+import com.jme3.math.*;
+import com.jme3.post.SceneProcessor;
+import com.jme3.renderer.queue.GeometryList;
+import com.jme3.renderer.queue.RenderQueue;
+import com.jme3.renderer.queue.RenderQueue.Bucket;
+import com.jme3.renderer.queue.RenderQueue.ShadowMode;
+import com.jme3.scene.*;
+import com.jme3.shader.Uniform;
+import com.jme3.shader.UniformBinding;
+import com.jme3.shader.VarType;
+import com.jme3.system.NullRenderer;
+import com.jme3.system.Timer;
+import com.jme3.util.IntMap.Entry;
+import com.jme3.util.TempVars;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.logging.Logger;
+
+/**
+ * <code>RenderManager</code> is a high-level rendering interface that is
+ * above the Renderer implementation. RenderManager takes care
+ * of rendering the scene graphs attached to each viewport and
+ * handling SceneProcessors.
+ *
+ * @see SceneProcessor
+ * @see ViewPort
+ * @see Spatial
+ */
+public class RenderManager {
+
+    private static final Logger logger = Logger.getLogger(RenderManager.class.getName());
+    
+    private Renderer renderer;
+    private Timer timer;
+    private ArrayList<ViewPort> preViewPorts = new ArrayList<ViewPort>();
+    private ArrayList<ViewPort> viewPorts = new ArrayList<ViewPort>();
+    private ArrayList<ViewPort> postViewPorts = new ArrayList<ViewPort>();
+    private Camera prevCam = null;
+    private Material forcedMaterial = null;
+    private String forcedTechnique = null;
+    private RenderState forcedRenderState = null;
+    private boolean shader;
+    private int viewX, viewY, viewWidth, viewHeight;
+    private float near, far;
+    private Matrix4f orthoMatrix = new Matrix4f();
+    private Matrix4f viewMatrix = new Matrix4f();
+    private Matrix4f projMatrix = new Matrix4f();
+    private Matrix4f viewProjMatrix = new Matrix4f();
+    private Matrix4f worldMatrix = new Matrix4f();
+    private Vector3f camUp = new Vector3f(),
+            camLeft = new Vector3f(),
+            camDir = new Vector3f(),
+            camLoc = new Vector3f();
+    //temp technique
+    private String tmpTech;
+    private boolean handleTranlucentBucket = true;
+
+    /**
+     * Create a high-level rendering interface over the
+     * low-level rendering interface.
+     * @param renderer
+     */
+    public RenderManager(Renderer renderer) {
+        this.renderer = renderer;
+        //this.shader = renderer.getCaps().contains(Caps.GLSL100);
+    }
+
+    /**
+     * Returns the pre ViewPort with the given name.
+     * 
+     * @param viewName The name of the pre ViewPort to look up
+     * @return The ViewPort, or null if not found.
+     * 
+     * @see #createPreView(java.lang.String, com.jme3.renderer.Camera) 
+     */
+    public ViewPort getPreView(String viewName) {
+        for (int i = 0; i < preViewPorts.size(); i++) {
+            if (preViewPorts.get(i).getName().equals(viewName)) {
+                return preViewPorts.get(i);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Removes the specified pre ViewPort.
+     * 
+     * @param view The pre ViewPort to remove
+     * @return True if the ViewPort was removed successfully.
+     * 
+     * @see #createPreView(java.lang.String, com.jme3.renderer.Camera) 
+     */
+    public boolean removePreView(ViewPort view) {
+        return preViewPorts.remove(view);
+    }
+
+    /**
+     * Returns the main ViewPort with the given name.
+     * 
+     * @param viewName The name of the main ViewPort to look up
+     * @return The ViewPort, or null if not found.
+     * 
+     * @see #createMainView(java.lang.String, com.jme3.renderer.Camera) 
+     */
+    public ViewPort getMainView(String viewName) {
+        for (int i = 0; i < viewPorts.size(); i++) {
+            if (viewPorts.get(i).getName().equals(viewName)) {
+                return viewPorts.get(i);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Removes the main ViewPort with the specified name.
+     * 
+     * @param viewName The main ViewPort name to remove
+     * @return True if the ViewPort was removed successfully.
+     * 
+     * @see #createMainView(java.lang.String, com.jme3.renderer.Camera) 
+     */
+    public boolean removeMainView(String viewName) {
+        for (int i = 0; i < viewPorts.size(); i++) {
+            if (viewPorts.get(i).getName().equals(viewName)) {
+                viewPorts.remove(i);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Removes the specified main ViewPort.
+     * 
+     * @param view The main ViewPort to remove
+     * @return True if the ViewPort was removed successfully.
+     * 
+     * @see #createMainView(java.lang.String, com.jme3.renderer.Camera) 
+     */
+    public boolean removeMainView(ViewPort view) {
+        return viewPorts.remove(view);
+    }
+
+    /**
+     * Returns the post ViewPort with the given name.
+     * 
+     * @param viewName The name of the post ViewPort to look up
+     * @return The ViewPort, or null if not found.
+     * 
+     * @see #createPostView(java.lang.String, com.jme3.renderer.Camera) 
+     */
+    public ViewPort getPostView(String viewName) {
+        for (int i = 0; i < postViewPorts.size(); i++) {
+            if (postViewPorts.get(i).getName().equals(viewName)) {
+                return postViewPorts.get(i);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Removes the post ViewPort with the specified name.
+     * 
+     * @param viewName The post ViewPort name to remove
+     * @return True if the ViewPort was removed successfully.
+     * 
+     * @see #createPostView(java.lang.String, com.jme3.renderer.Camera) 
+     */
+    public boolean removePostView(String viewName) {
+        for (int i = 0; i < postViewPorts.size(); i++) {
+            if (postViewPorts.get(i).getName().equals(viewName)) {
+                postViewPorts.remove(i);
+
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Removes the specified post ViewPort.
+     * 
+     * @param view The post ViewPort to remove
+     * @return True if the ViewPort was removed successfully.
+     * 
+     * @see #createPostView(java.lang.String, com.jme3.renderer.Camera) 
+     */
+    public boolean removePostView(ViewPort view) {
+        return postViewPorts.remove(view);
+    }
+
+    /**
+     * Returns a read-only list of all pre ViewPorts
+     * @return a read-only list of all pre ViewPorts
+     * @see #createPreView(java.lang.String, com.jme3.renderer.Camera) 
+     */
+    public List<ViewPort> getPreViews() {
+        return Collections.unmodifiableList(preViewPorts);
+    }
+
+    /**
+     * Returns a read-only list of all main ViewPorts
+     * @return a read-only list of all main ViewPorts
+     * @see #createMainView(java.lang.String, com.jme3.renderer.Camera) 
+     */
+    public List<ViewPort> getMainViews() {
+        return Collections.unmodifiableList(viewPorts);
+    }
+
+    /**
+     * Returns a read-only list of all post ViewPorts
+     * @return a read-only list of all post ViewPorts
+     * @see #createPostView(java.lang.String, com.jme3.renderer.Camera) 
+     */
+    public List<ViewPort> getPostViews() {
+        return Collections.unmodifiableList(postViewPorts);
+    }
+
+    /**
+     * Creates a new pre ViewPort, to display the given camera's content.
+     * <p>
+     * The view will be processed before the main and post viewports.
+     */
+    public ViewPort createPreView(String viewName, Camera cam) {
+        ViewPort vp = new ViewPort(viewName, cam);
+        preViewPorts.add(vp);
+        return vp;
+    }
+
+    /**
+     * Creates a new main ViewPort, to display the given camera's content.
+     * <p>
+     * The view will be processed before the post viewports but after
+     * the pre viewports.
+     */
+    public ViewPort createMainView(String viewName, Camera cam) {
+        ViewPort vp = new ViewPort(viewName, cam);
+        viewPorts.add(vp);
+        return vp;
+    }
+
+    /**
+     * Creates a new post ViewPort, to display the given camera's content.
+     * <p>
+     * The view will be processed after the pre and main viewports.
+     */
+    public ViewPort createPostView(String viewName, Camera cam) {
+        ViewPort vp = new ViewPort(viewName, cam);
+        postViewPorts.add(vp);
+        return vp;
+    }
+
+    private void notifyReshape(ViewPort vp, int w, int h) {
+        List<SceneProcessor> processors = vp.getProcessors();
+        for (SceneProcessor proc : processors) {
+            if (!proc.isInitialized()) {
+                proc.initialize(this, vp);
+            } else {
+                proc.reshape(vp, w, h);
+            }
+        }
+    }
+
+    /**
+     * Internal use only.
+     * Updates the resolution of all on-screen cameras to match
+     * the given width and height.
+     */
+    public void notifyReshape(int w, int h) {
+        for (ViewPort vp : preViewPorts) {
+            if (vp.getOutputFrameBuffer() == null) {
+                Camera cam = vp.getCamera();
+                cam.resize(w, h, true);
+            }
+            notifyReshape(vp, w, h);
+        }
+        for (ViewPort vp : viewPorts) {
+            if (vp.getOutputFrameBuffer() == null) {
+                Camera cam = vp.getCamera();
+                cam.resize(w, h, true);
+            }
+            notifyReshape(vp, w, h);
+        }
+        for (ViewPort vp : postViewPorts) {
+            if (vp.getOutputFrameBuffer() == null) {
+                Camera cam = vp.getCamera();
+                cam.resize(w, h, true);
+            }
+            notifyReshape(vp, w, h);
+        }
+    }
+
+    /**
+     * Internal use only.
+     * Updates the given list of uniforms with {@link UniformBinding uniform bindings}
+     * based on the current world state.
+     */
+    public void updateUniformBindings(List<Uniform> params) {
+        // assums worldMatrix is properly set.
+        TempVars vars = TempVars.get();
+
+        Matrix4f tempMat4 = vars.tempMat4;
+        Matrix3f tempMat3 = vars.tempMat3;
+        Vector2f tempVec2 = vars.vect2d;
+        Quaternion tempVec4 = vars.quat1;
+
+        for (int i = 0; i < params.size(); i++) {
+            Uniform u = params.get(i);
+            switch (u.getBinding()) {
+                case WorldMatrix:
+                    u.setValue(VarType.Matrix4, worldMatrix);
+                    break;
+                case ViewMatrix:
+                    u.setValue(VarType.Matrix4, viewMatrix);
+                    break;
+                case ProjectionMatrix:
+                    u.setValue(VarType.Matrix4, projMatrix);
+                    break;
+                case ViewProjectionMatrix:
+                    u.setValue(VarType.Matrix4, viewProjMatrix);
+                    break;
+                case WorldViewMatrix:
+                    tempMat4.set(viewMatrix);
+                    tempMat4.multLocal(worldMatrix);
+                    u.setValue(VarType.Matrix4, tempMat4);
+                    break;
+                case NormalMatrix:
+                    tempMat4.set(viewMatrix);
+                    tempMat4.multLocal(worldMatrix);
+                    tempMat4.toRotationMatrix(tempMat3);
+                    tempMat3.invertLocal();
+                    tempMat3.transposeLocal();
+                    u.setValue(VarType.Matrix3, tempMat3);
+                    break;
+                case WorldViewProjectionMatrix:
+                    tempMat4.set(viewProjMatrix);
+                    tempMat4.multLocal(worldMatrix);
+                    u.setValue(VarType.Matrix4, tempMat4);
+                    break;
+                case WorldMatrixInverse:
+                    tempMat4.set(worldMatrix);
+                    tempMat4.invertLocal();
+                    u.setValue(VarType.Matrix4, tempMat4);
+                    break;
+                case WorldMatrixInverseTranspose:
+                    worldMatrix.toRotationMatrix(tempMat3);
+                    tempMat3.invertLocal().transposeLocal();
+                    u.setValue(VarType.Matrix3, tempMat3);
+                    break;
+                case ViewMatrixInverse:
+                    tempMat4.set(viewMatrix);
+                    tempMat4.invertLocal();
+                    u.setValue(VarType.Matrix4, tempMat4);
+                    break;
+                case ProjectionMatrixInverse:
+                    tempMat4.set(projMatrix);
+                    tempMat4.invertLocal();
+                    u.setValue(VarType.Matrix4, tempMat4);
+                    break;
+                case ViewProjectionMatrixInverse:
+                    tempMat4.set(viewProjMatrix);
+                    tempMat4.invertLocal();
+                    u.setValue(VarType.Matrix4, tempMat4);
+                    break;
+                case WorldViewMatrixInverse:
+                    tempMat4.set(viewMatrix);
+                    tempMat4.multLocal(worldMatrix);
+                    tempMat4.invertLocal();
+                    u.setValue(VarType.Matrix4, tempMat4);
+                    break;
+                case NormalMatrixInverse:
+                    tempMat4.set(viewMatrix);
+                    tempMat4.multLocal(worldMatrix);
+                    tempMat4.toRotationMatrix(tempMat3);
+                    tempMat3.invertLocal();
+                    tempMat3.transposeLocal();
+                    tempMat3.invertLocal();
+                    u.setValue(VarType.Matrix3, tempMat3);
+                    break;
+                case WorldViewProjectionMatrixInverse:
+                    tempMat4.set(viewProjMatrix);
+                    tempMat4.multLocal(worldMatrix);
+                    tempMat4.invertLocal();
+                    u.setValue(VarType.Matrix4, tempMat4);
+                    break;
+                case ViewPort:
+                    tempVec4.set(viewX, viewY, viewWidth, viewHeight);
+                    u.setValue(VarType.Vector4, tempVec4);
+                    break;
+                case Resolution:
+                    tempVec2.set(viewWidth, viewHeight);
+                    u.setValue(VarType.Vector2, tempVec2);
+                    break;
+                case ResolutionInverse:
+                    tempVec2.set(1f / viewWidth, 1f / viewHeight);
+                    u.setValue(VarType.Vector2, tempVec2);
+                    break;
+                case Aspect:
+                    float aspect = ((float) viewWidth) / viewHeight;
+                    u.setValue(VarType.Float, aspect);
+                    break;
+                case FrustumNearFar:
+                    tempVec2.set(near, far);
+                    u.setValue(VarType.Vector2, tempVec2);
+                    break;
+                case CameraPosition:
+                    u.setValue(VarType.Vector3, camLoc);
+                    break;
+                case CameraDirection:
+                    u.setValue(VarType.Vector3, camDir);
+                    break;
+                case CameraLeft:
+                    u.setValue(VarType.Vector3, camLeft);
+                    break;
+                case CameraUp:
+                    u.setValue(VarType.Vector3, camUp);
+                    break;
+                case Time:
+                    u.setValue(VarType.Float, timer.getTimeInSeconds());
+                    break;
+                case Tpf:
+                    u.setValue(VarType.Float, timer.getTimePerFrame());
+                    break;
+                case FrameRate:
+                    u.setValue(VarType.Float, timer.getFrameRate());
+                    break;
+            }
+        }
+
+        vars.release();
+    }
+
+    /**
+     * Set the material to use to render all future objects.
+     * This overrides the material set on the geometry and renders
+     * with the provided material instead.
+     * Use null to clear the material and return renderer to normal
+     * functionality.
+     * @param mat The forced material to set, or null to return to normal
+     */
+    public void setForcedMaterial(Material mat) {
+        forcedMaterial = mat;
+    }
+
+    /**
+     * Returns the forced render state previously set with 
+     * {@link #setForcedRenderState(com.jme3.material.RenderState) }.
+     * @return the forced render state
+     */
+    public RenderState getForcedRenderState() {
+        return forcedRenderState;
+    }
+
+    /**
+     * Set the render state to use for all future objects.
+     * This overrides the render state set on the material and instead
+     * forces this render state to be applied for all future materials
+     * rendered. Set to null to return to normal functionality.
+     * 
+     * @param forcedRenderState The forced render state to set, or null
+     * to return to normal
+     */
+    public void setForcedRenderState(RenderState forcedRenderState) {
+        this.forcedRenderState = forcedRenderState;
+    }
+
+    /**
+     * Set the timer that should be used to query the time based
+     * {@link UniformBinding}s for material world parameters.
+     * 
+     * @param timer The timer to query time world parameters
+     */
+    public void setTimer(Timer timer) {
+        this.timer = timer;
+    }
+
+    /**
+     * Returns the forced technique name set.
+     * 
+     * @return the forced technique name set.
+     * 
+     * @see #setForcedTechnique(java.lang.String) 
+     */
+    public String getForcedTechnique() {
+        return forcedTechnique;
+    }
+
+    /**
+     * Sets the forced technique to use when rendering geometries.
+     * <p>
+     * If the specified technique name is available on the geometry's
+     * material, then it is used, otherwise, the 
+     * {@link #setForcedMaterial(com.jme3.material.Material) forced material} is used.
+     * If a forced material is not set and the forced technique name cannot
+     * be found on the material, the geometry will <em>not</em> be rendered.
+     * 
+     * @param forcedTechnique The forced technique name to use, set to null
+     * to return to normal functionality.
+     * 
+     * @see #renderGeometry(com.jme3.scene.Geometry) 
+     */
+    public void setForcedTechnique(String forcedTechnique) {
+        this.forcedTechnique = forcedTechnique;
+    }
+
+    /**
+     * Enable or disable alpha-to-coverage. 
+     * <p>
+     * When alpha to coverage is enabled and the renderer implementation
+     * supports it, then alpha blending will be replaced with alpha dissolve
+     * if multi-sampling is also set on the renderer.
+     * This feature allows avoiding of alpha blending artifacts due to
+     * lack of triangle-level back-to-front sorting.
+     * 
+     * @param value True to enable alpha-to-coverage, false otherwise.
+     */
+    public void setAlphaToCoverage(boolean value) {
+        renderer.setAlphaToCoverage(value);
+    }
+
+    /**
+     * True if the translucent bucket should automatically be rendered
+     * by the RenderManager.
+     * 
+     * @return Whether or not the translucent bucket is rendered.
+     * 
+     * @see #setHandleTranslucentBucket(boolean) 
+     */
+    public boolean isHandleTranslucentBucket() {
+        return handleTranlucentBucket;
+    }
+
+    /**
+     * Enable or disable rendering of the 
+     * {@link Bucket#Translucent translucent bucket}
+     * by the RenderManager. The default is enabled.
+     * 
+     * @param handleTranslucentBucket Whether or not the translucent bucket should
+     * be rendered.
+     */
+    public void setHandleTranslucentBucket(boolean handleTranslucentBucket) {
+        this.handleTranlucentBucket = handleTranslucentBucket;
+    }
+
+    /**
+     * Internal use only. Sets the world matrix to use for future
+     * rendering. This has no effect unless objects are rendered manually
+     * using {@link Material#render(com.jme3.scene.Geometry, com.jme3.renderer.RenderManager) }.
+     * Using {@link #renderGeometry(com.jme3.scene.Geometry) } will 
+     * override this value.
+     * 
+     * @param mat The world matrix to set
+     */
+    public void setWorldMatrix(Matrix4f mat) {
+        if (shader) {
+            worldMatrix.set(mat);
+        } else {
+            renderer.setWorldMatrix(mat);
+        }
+    }
+
+    /**
+     * Renders the given geometry.
+     * <p>
+     * First the proper world matrix is set, if 
+     * the geometry's {@link Geometry#setIgnoreTransform(boolean) ignore transform}
+     * feature is enabled, the identity world matrix is used, otherwise, the 
+     * geometry's {@link Geometry#getWorldMatrix() world transform matrix} is used. 
+     * <p>
+     * Once the world matrix is applied, the proper material is chosen for rendering.
+     * If a {@link #setForcedMaterial(com.jme3.material.Material) forced material} is
+     * set on this RenderManager, then it is used for rendering the geometry,
+     * otherwise, the {@link Geometry#getMaterial() geometry's material} is used.
+     * <p>
+     * If a {@link #setForcedTechnique(java.lang.String) forced technique} is
+     * set on this RenderManager, then it is selected automatically
+     * on the geometry's material and is used for rendering. Otherwise, one
+     * of the {@link MaterialDef#getDefaultTechniques() default techniques} is
+     * used.
+     * <p>
+     * If a {@link #setForcedRenderState(com.jme3.material.RenderState) forced
+     * render state} is set on this RenderManager, then it is used
+     * for rendering the material, and the material's own render state is ignored.
+     * Otherwise, the material's render state is used as intended.
+     * 
+     * @param g The geometry to render
+     * 
+     * @see Technique
+     * @see RenderState
+     * @see Material#selectTechnique(java.lang.String, com.jme3.renderer.RenderManager) 
+     * @see Material#render(com.jme3.scene.Geometry, com.jme3.renderer.RenderManager) 
+     */
+    public void renderGeometry(Geometry g) {
+        if (g.isIgnoreTransform()) {
+            setWorldMatrix(Matrix4f.IDENTITY);
+        } else {
+            setWorldMatrix(g.getWorldMatrix());
+        }
+
+        //if forcedTechnique we try to force it for render,
+        //if it does not exists in the mat def, we check for forcedMaterial and render the geom if not null
+        //else the geom is not rendered
+        if (forcedTechnique != null) {
+            if (g.getMaterial().getMaterialDef().getTechniqueDef(forcedTechnique) != null) {
+                tmpTech = g.getMaterial().getActiveTechnique() != null ? g.getMaterial().getActiveTechnique().getDef().getName() : "Default";
+                g.getMaterial().selectTechnique(forcedTechnique, this);
+                // use geometry's material
+                g.getMaterial().render(g, this);
+                g.getMaterial().selectTechnique(tmpTech, this);
+                //Reverted this part from revision 6197
+                //If forcedTechnique does not exists, and frocedMaterial is not set, the geom MUST NOT be rendered
+            } else if (forcedMaterial != null) {
+                // use forced material
+                forcedMaterial.render(g, this);
+            }
+        } else if (forcedMaterial != null) {
+            // use forced material
+            forcedMaterial.render(g, this);
+        } else {
+            g.getMaterial().render(g, this);
+        }
+    }
+
+    /**
+     * Renders the given GeometryList.
+     * <p>
+     * For every geometry in the list, the 
+     * {@link #renderGeometry(com.jme3.scene.Geometry) } method is called.
+     * 
+     * @param gl The geometry list to render.
+     * 
+     * @see GeometryList
+     * @see #renderGeometry(com.jme3.scene.Geometry) 
+     */
+    public void renderGeometryList(GeometryList gl) {
+        for (int i = 0; i < gl.size(); i++) {
+            renderGeometry(gl.get(i));
+        }
+    }
+
+    /**
+     * If a spatial is not inside the eye frustum, it
+     * is still rendered in the shadow frustum (shadow casting queue)
+     * through this recursive method.
+     */
+    private void renderShadow(Spatial s, RenderQueue rq) {
+        if (s instanceof Node) {
+            Node n = (Node) s;
+            List<Spatial> children = n.getChildren();
+            for (int i = 0; i < children.size(); i++) {
+                renderShadow(children.get(i), rq);
+            }
+        } else if (s instanceof Geometry) {
+            Geometry gm = (Geometry) s;
+
+            RenderQueue.ShadowMode shadowMode = s.getShadowMode();
+            if (shadowMode != RenderQueue.ShadowMode.Off && shadowMode != RenderQueue.ShadowMode.Receive) {
+                //forcing adding to shadow cast mode, culled objects doesn't have to be in the receiver queue
+                rq.addToShadowQueue(gm, RenderQueue.ShadowMode.Cast);
+            }
+        }
+    }
+
+    /**
+     * Preloads a scene for rendering.
+     * <p>
+     * After invocation of this method, the underlying
+     * renderer would have uploaded any textures, shaders and meshes
+     * used by the given scene to the video driver. 
+     * Using this method is useful when wishing to avoid the initial pause
+     * when rendering a scene for the first time. Note that it is not 
+     * guaranteed that the underlying renderer will actually choose to upload
+     * the data to the GPU so some pause is still to be expected.
+     * 
+     * @param scene The scene to preload
+     */
+    public void preloadScene(Spatial scene) {
+        if (scene instanceof Node) {
+            // recurse for all children
+            Node n = (Node) scene;
+            List<Spatial> children = n.getChildren();
+            for (int i = 0; i < children.size(); i++) {
+                preloadScene(children.get(i));
+            }
+        } else if (scene instanceof Geometry) {
+            // add to the render queue
+            Geometry gm = (Geometry) scene;
+            if (gm.getMaterial() == null) {
+                throw new IllegalStateException("No material is set for Geometry: " + gm.getName());
+            }
+
+            gm.getMaterial().preload(this);
+            Mesh mesh = gm.getMesh();
+            if (mesh != null) {
+                for (VertexBuffer vb : mesh.getBufferList().getArray()) {
+                    if (vb.getData() != null) {
+                        renderer.updateBufferData(vb);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Flattens the given scene graph into the ViewPort's RenderQueue,
+     * checking for culling as the call goes down the graph recursively.
+     * <p>
+     * First, the scene is checked for culling based on the <code>Spatial</code>s
+     * {@link Spatial#setCullHint(com.jme3.scene.Spatial.CullHint) cull hint},
+     * if the camera frustum contains the scene, then this method is recursively
+     * called on its children.
+     * <p>
+     * When the scene's leaves or {@link Geometry geometries} are reached,
+     * they are each enqueued into the 
+     * {@link ViewPort#getQueue() ViewPort's render queue}.
+     * <p>
+     * In addition to enqueuing the visible geometries, this method
+     * also scenes which cast or receive shadows, by putting them into the
+     * RenderQueue's 
+     * {@link RenderQueue#addToShadowQueue(com.jme3.scene.Geometry, com.jme3.renderer.queue.RenderQueue.ShadowMode) 
+     * shadow queue}. Each Spatial which has its 
+     * {@link Spatial#setShadowMode(com.jme3.renderer.queue.RenderQueue.ShadowMode) shadow mode}
+     * set to not off, will be put into the appropriate shadow queue, note that
+     * this process does not check for frustum culling on any 
+     * {@link ShadowMode#Cast shadow casters}, as they don't have to be
+     * in the eye camera frustum to cast shadows on objects that are inside it.
+     * 
+     * @param scene The scene to flatten into the queue
+     * @param vp The ViewPort provides the {@link ViewPort#getCamera() camera}
+     * used for culling and the {@link ViewPort#getQueue() queue} used to 
+     * contain the flattened scene graph.
+     */
+    public void renderScene(Spatial scene, ViewPort vp) {
+        if (scene.getParent() == null) {
+            vp.getCamera().setPlaneState(0);
+        }
+        // check culling first.
+        if (!scene.checkCulling(vp.getCamera())) {
+            // move on to shadow-only render
+            if ((scene.getShadowMode() != RenderQueue.ShadowMode.Off || scene instanceof Node) && scene.getCullHint()!=Spatial.CullHint.Always) {
+                renderShadow(scene, vp.getQueue());
+            }
+            return;
+        }
+
+        scene.runControlRender(this, vp);
+        if (scene instanceof Node) {
+            // recurse for all children
+            Node n = (Node) scene;
+            List<Spatial> children = n.getChildren();
+            //saving cam state for culling
+            int camState = vp.getCamera().getPlaneState();
+            for (int i = 0; i < children.size(); i++) {
+                //restoring cam state before proceeding children recusively
+                vp.getCamera().setPlaneState(camState);
+                renderScene(children.get(i), vp);
+
+            }
+        } else if (scene instanceof Geometry) {
+
+            // add to the render queue
+            Geometry gm = (Geometry) scene;
+            if (gm.getMaterial() == null) {
+                throw new IllegalStateException("No material is set for Geometry: " + gm.getName());
+            }
+
+            vp.getQueue().addToQueue(gm, scene.getQueueBucket());
+
+            // add to shadow queue if needed
+            RenderQueue.ShadowMode shadowMode = scene.getShadowMode();
+            if (shadowMode != RenderQueue.ShadowMode.Off) {
+                vp.getQueue().addToShadowQueue(gm, shadowMode);
+            }
+        }
+    }
+
+    /**
+     * Returns the camera currently used for rendering.
+     * <p>
+     * The camera can be set with {@link #setCamera(com.jme3.renderer.Camera, boolean) }.
+     * 
+     * @return the camera currently used for rendering.
+     */
+    public Camera getCurrentCamera() {
+        return prevCam;
+    }
+
+    /**
+     * The renderer implementation used for rendering operations.
+     * 
+     * @return The renderer implementation
+     * 
+     * @see #RenderManager(com.jme3.renderer.Renderer) 
+     * @see Renderer
+     */
+    public Renderer getRenderer() {
+        return renderer;
+    }
+
+    /**
+     * Flushes the ViewPort's {@link ViewPort#getQueue() render queue}
+     * by rendering each of its visible buckets.
+     * By default the queues will automatically be cleared after rendering,
+     * so there's no need to clear them manually.
+     * 
+     * @param vp The ViewPort of which the queue will be flushed
+     * 
+     * @see RenderQueue#renderQueue(com.jme3.renderer.queue.RenderQueue.Bucket, com.jme3.renderer.RenderManager, com.jme3.renderer.Camera) 
+     * @see #renderGeometryList(com.jme3.renderer.queue.GeometryList) 
+     */
+    public void flushQueue(ViewPort vp) {
+        renderViewPortQueues(vp, true);
+    }
+
+    /**
+     * Clears the queue of the given ViewPort.
+     * Simply calls {@link RenderQueue#clear() } on the ViewPort's 
+     * {@link ViewPort#getQueue() render queue}.
+     * 
+     * @param vp The ViewPort of which the queue will be cleared.
+     * 
+     * @see RenderQueue#clear()
+     * @see ViewPort#getQueue()
+     */
+    public void clearQueue(ViewPort vp) {
+        vp.getQueue().clear();
+    }
+
+    /**
+     * Render the given viewport queues.
+     * <p>
+     * Changes the {@link Renderer#setDepthRange(float, float) depth range}
+     * appropriately as expected by each queue and then calls 
+     * {@link RenderQueue#renderQueue(com.jme3.renderer.queue.RenderQueue.Bucket, com.jme3.renderer.RenderManager, com.jme3.renderer.Camera, boolean) }
+     * on the queue. Makes sure to restore the depth range to [0, 1] 
+     * at the end of the call.
+     * Note that the {@link Bucket#Translucent translucent bucket} is NOT
+     * rendered by this method. Instead the user should call 
+     * {@link #renderTranslucentQueue(com.jme3.renderer.ViewPort) }
+     * after this call.
+     * 
+     * @param vp the viewport of which queue should be rendered
+     * @param flush If true, the queues will be cleared after
+     * rendering.
+     * 
+     * @see RenderQueue
+     * @see #renderTranslucentQueue(com.jme3.renderer.ViewPort) 
+     */
+    public void renderViewPortQueues(ViewPort vp, boolean flush) {
+        RenderQueue rq = vp.getQueue();
+        Camera cam = vp.getCamera();
+        boolean depthRangeChanged = false;
+
+        // render opaque objects with default depth range
+        // opaque objects are sorted front-to-back, reducing overdraw
+        rq.renderQueue(Bucket.Opaque, this, cam, flush);
+
+        // render the sky, with depth range set to the farthest
+        if (!rq.isQueueEmpty(Bucket.Sky)) {
+            renderer.setDepthRange(1, 1);
+            rq.renderQueue(Bucket.Sky, this, cam, flush);
+            depthRangeChanged = true;
+        }
+
+
+        // transparent objects are last because they require blending with the
+        // rest of the scene's objects. Consequently, they are sorted
+        // back-to-front.
+        if (!rq.isQueueEmpty(Bucket.Transparent)) {
+            if (depthRangeChanged) {
+                renderer.setDepthRange(0, 1);
+                depthRangeChanged = false;
+            }
+
+            rq.renderQueue(Bucket.Transparent, this, cam, flush);
+        }
+
+        if (!rq.isQueueEmpty(Bucket.Gui)) {
+            renderer.setDepthRange(0, 0);
+            setCamera(cam, true);
+            rq.renderQueue(Bucket.Gui, this, cam, flush);
+            setCamera(cam, false);
+            depthRangeChanged = true;
+        }
+
+        // restore range to default
+        if (depthRangeChanged) {
+            renderer.setDepthRange(0, 1);
+        }
+    }
+
+    /**
+     * Renders the {@link Bucket#Translucent translucent queue} on the viewPort.
+     * <p>
+     * This call does nothing unless {@link #setHandleTranslucentBucket(boolean) }
+     * is set to true. This method clears the translucent queue after rendering
+     * it.
+     * 
+     * @param vp The viewport of which the translucent queue should be rendered.
+     * 
+     * @see #renderViewPortQueues(com.jme3.renderer.ViewPort, boolean) 
+     * @see #setHandleTranslucentBucket(boolean) 
+     */
+    public void renderTranslucentQueue(ViewPort vp) {
+        RenderQueue rq = vp.getQueue();
+        if (!rq.isQueueEmpty(Bucket.Translucent) && handleTranlucentBucket) {
+            rq.renderQueue(Bucket.Translucent, this, vp.getCamera(), true);
+        }
+    }
+
+    private void setViewPort(Camera cam) {
+        // this will make sure to update viewport only if needed
+        if (cam != prevCam || cam.isViewportChanged()) {
+            viewX = (int) (cam.getViewPortLeft() * cam.getWidth());
+            viewY = (int) (cam.getViewPortBottom() * cam.getHeight());
+            viewWidth = (int) ((cam.getViewPortRight() - cam.getViewPortLeft()) * cam.getWidth());
+            viewHeight = (int) ((cam.getViewPortTop() - cam.getViewPortBottom()) * cam.getHeight());
+            renderer.setViewPort(viewX, viewY, viewWidth, viewHeight);
+            renderer.setClipRect(viewX, viewY, viewWidth, viewHeight);
+            cam.clearViewportChanged();
+            prevCam = cam;
+
+//            float translateX = viewWidth == viewX ? 0 : -(viewWidth + viewX) / (viewWidth - viewX);
+//            float translateY = viewHeight == viewY ? 0 : -(viewHeight + viewY) / (viewHeight - viewY);
+//            float scaleX = viewWidth == viewX ? 1f : 2f / (viewWidth - viewX);
+//            float scaleY = viewHeight == viewY ? 1f : 2f / (viewHeight - viewY);
+//            
+//            orthoMatrix.loadIdentity();
+//            orthoMatrix.setTranslation(translateX, translateY, 0);
+//            orthoMatrix.setScale(scaleX, scaleY, 0); 
+
+            orthoMatrix.loadIdentity();
+            orthoMatrix.setTranslation(-1f, -1f, 0f);
+            orthoMatrix.setScale(2f / cam.getWidth(), 2f / cam.getHeight(), 0f);
+        }
+    }
+
+    private void setViewProjection(Camera cam, boolean ortho) {
+        if (shader) {
+            if (ortho) {
+                viewMatrix.set(Matrix4f.IDENTITY);
+                projMatrix.set(orthoMatrix);
+                viewProjMatrix.set(orthoMatrix);
+            } else {
+                viewMatrix.set(cam.getViewMatrix());
+                projMatrix.set(cam.getProjectionMatrix());
+                viewProjMatrix.set(cam.getViewProjectionMatrix());
+            }
+
+            camLoc.set(cam.getLocation());
+            cam.getLeft(camLeft);
+            cam.getUp(camUp);
+            cam.getDirection(camDir);
+
+            near = cam.getFrustumNear();
+            far = cam.getFrustumFar();
+        } else {
+            if (ortho) {
+                renderer.setViewProjectionMatrices(Matrix4f.IDENTITY, orthoMatrix);
+            } else {
+                renderer.setViewProjectionMatrices(cam.getViewMatrix(),
+                        cam.getProjectionMatrix());
+            }
+
+        }
+    }
+
+    /**
+     * Set the camera to use for rendering.
+     * <p>
+     * First, the camera's 
+     * {@link Camera#setViewPort(float, float, float, float) view port parameters}
+     * are applied. Then, the camera's {@link Camera#getViewMatrix() view} and 
+     * {@link Camera#getProjectionMatrix() projection} matrices are set
+     * on the renderer. If <code>ortho</code> is <code>true</code>, then
+     * instead of using the camera's view and projection matrices, an ortho
+     * matrix is computed and used instead of the view projection matrix. 
+     * The ortho matrix converts from the range (0 ~ Width, 0 ~ Height, -1 ~ +1)
+     * to the clip range (-1 ~ +1, -1 ~ +1, -1 ~ +1).
+     * 
+     * @param cam The camera to set
+     * @param ortho True if to use orthographic projection (for GUI rendering),
+     * false if to use the camera's view and projection matrices.
+     */
+    public void setCamera(Camera cam, boolean ortho) {
+        setViewPort(cam);
+        setViewProjection(cam, ortho);
+    }
+
+    /**
+     * Draws the viewport but without notifying {@link SceneProcessor scene
+     * processors} of any rendering events.
+     * 
+     * @param vp The ViewPort to render
+     * 
+     * @see #renderViewPort(com.jme3.renderer.ViewPort, float) 
+     */
+    public void renderViewPortRaw(ViewPort vp) {
+        setCamera(vp.getCamera(), false);
+        List<Spatial> scenes = vp.getScenes();
+        for (int i = scenes.size() - 1; i >= 0; i--) {
+            renderScene(scenes.get(i), vp);
+        }
+        flushQueue(vp);
+    }
+
+    /**
+     * Renders the {@link ViewPort}.
+     * <p>
+     * If the ViewPort is {@link ViewPort#isEnabled() disabled}, this method
+     * returns immediately. Otherwise, the ViewPort is rendered by 
+     * the following process:<br>
+     * <ul>
+     * <li>All {@link SceneProcessor scene processors} that are attached
+     * to the ViewPort are {@link SceneProcessor#initialize(com.jme3.renderer.RenderManager, com.jme3.renderer.ViewPort) initialized}.
+     * </li>
+     * <li>The SceneProcessors' {@link SceneProcessor#preFrame(float) } method 
+     * is called.</li>
+     * <li>The ViewPort's {@link ViewPort#getOutputFrameBuffer() output framebuffer}
+     * is set on the Renderer</li>
+     * <li>The camera is set on the renderer, including its view port parameters.
+     * (see {@link #setCamera(com.jme3.renderer.Camera, boolean) })</li>
+     * <li>Any buffers that the ViewPort requests to be cleared are cleared
+     * and the {@link ViewPort#getBackgroundColor() background color} is set</li>
+     * <li>Every scene that is attached to the ViewPort is flattened into 
+     * the ViewPort's render queue 
+     * (see {@link #renderViewPortQueues(com.jme3.renderer.ViewPort, boolean) })
+     * </li>
+     * <li>The SceneProcessors' {@link SceneProcessor#postQueue(com.jme3.renderer.queue.RenderQueue) }
+     * method is called.</li>
+     * <li>The render queue is sorted and then flushed, sending
+     * rendering commands to the underlying Renderer implementation. 
+     * (see {@link #flushQueue(com.jme3.renderer.ViewPort) })</li>
+     * <li>The SceneProcessors' {@link SceneProcessor#postFrame(com.jme3.texture.FrameBuffer) }
+     * method is called.</li>
+     * <li>The translucent queue of the ViewPort is sorted and then flushed
+     * (see {@link #renderTranslucentQueue(com.jme3.renderer.ViewPort) })</li>
+     * <li>If any objects remained in the render queue, they are removed
+     * from the queue. This is generally objects added to the 
+     * {@link RenderQueue#renderShadowQueue(com.jme3.renderer.queue.RenderQueue.ShadowMode, com.jme3.renderer.RenderManager, com.jme3.renderer.Camera, boolean) 
+     * shadow queue}
+     * which were not rendered because of a missing shadow renderer.</li>
+     * </ul>
+     * 
+     * @param vp
+     * @param tpf 
+     */
+    public void renderViewPort(ViewPort vp, float tpf) {
+        if (!vp.isEnabled()) {
+            return;
+        }
+        List<SceneProcessor> processors = vp.getProcessors();
+        if (processors.isEmpty()) {
+            processors = null;
+        }
+
+        if (processors != null) {
+            for (SceneProcessor proc : processors) {
+                if (!proc.isInitialized()) {
+                    proc.initialize(this, vp);
+                }
+                proc.preFrame(tpf);
+            }
+        }
+
+        renderer.setFrameBuffer(vp.getOutputFrameBuffer());
+        setCamera(vp.getCamera(), false);
+        if (vp.isClearDepth() || vp.isClearColor() || vp.isClearStencil()) {
+            if (vp.isClearColor()) {
+                renderer.setBackgroundColor(vp.getBackgroundColor());
+            }
+            renderer.clearBuffers(vp.isClearColor(),
+                    vp.isClearDepth(),
+                    vp.isClearStencil());
+        }
+
+        List<Spatial> scenes = vp.getScenes();
+        for (int i = scenes.size() - 1; i >= 0; i--) {
+            renderScene(scenes.get(i), vp);
+        }
+
+        if (processors != null) {
+            for (SceneProcessor proc : processors) {
+                proc.postQueue(vp.getQueue());
+            }
+        }
+
+        flushQueue(vp);
+
+        if (processors != null) {
+            for (SceneProcessor proc : processors) {
+                proc.postFrame(vp.getOutputFrameBuffer());
+            }
+        }
+        //renders the translucent objects queue after processors have been rendered
+        renderTranslucentQueue(vp);
+        // clear any remaining spatials that were not rendered.
+        clearQueue(vp);
+    }
+
+    /**
+     * Called by the application to render any ViewPorts
+     * added to this RenderManager.
+     * <p>
+     * Renders any viewports that were added using the following methods:
+     * <ul>
+     * <li>{@link #createPreView(java.lang.String, com.jme3.renderer.Camera) }</li>
+     * <li>{@link #createMainView(java.lang.String, com.jme3.renderer.Camera) }</li>
+     * <li>{@link #createPostView(java.lang.String, com.jme3.renderer.Camera) }</li>
+     * </ul>
+     * 
+     * @param tpf Time per frame value
+     */
+    public void render(float tpf, boolean mainFrameBufferActive) {
+        if (renderer instanceof NullRenderer) {
+            return;
+        }
+
+        this.shader = renderer.getCaps().contains(Caps.GLSL100);
+
+        for (int i = 0; i < preViewPorts.size(); i++) {
+            ViewPort vp = preViewPorts.get(i);
+            if (vp.getOutputFrameBuffer() != null || mainFrameBufferActive){
+                renderViewPort(vp, tpf);
+            }
+        }
+        for (int i = 0; i < viewPorts.size(); i++) {
+            ViewPort vp = viewPorts.get(i);
+            if (vp.getOutputFrameBuffer() != null || mainFrameBufferActive){
+                renderViewPort(vp, tpf);
+            }
+        }
+        for (int i = 0; i < postViewPorts.size(); i++) {
+            ViewPort vp = postViewPorts.get(i);
+            if (vp.getOutputFrameBuffer() != null || mainFrameBufferActive){
+                renderViewPort(vp, tpf);
+            }
+        }
+    }
+}
diff --git a/engine/src/core/com/jme3/scene/BatchNode.java b/engine/src/core/com/jme3/scene/BatchNode.java
index bc1b2cb..303de7a 100644
--- a/engine/src/core/com/jme3/scene/BatchNode.java
+++ b/engine/src/core/com/jme3/scene/BatchNode.java
@@ -46,6 +46,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -190,10 +191,10 @@
             }
             batches.clear();
         }
-        
-        for (Material material : matMap.keySet()) {
+        for (Map.Entry<Material, List<Geometry>> entry : matMap.entrySet()) {
             Mesh m = new Mesh();
-            List<Geometry> list = matMap.get(material);
+            Material material = entry.getKey();
+            List<Geometry> list = entry.getValue();
             nbGeoms += list.size();
             if (!needsFullRebatch) {
                 list.add(batches.get(material).geometry);
@@ -408,9 +409,9 @@
                     throw new UnsupportedOperationException();
             }
 
-            for (Entry<VertexBuffer> entry : geom.getMesh().getBuffers()) {
-                compsForBuf[entry.getKey()] = entry.getValue().getNumComponents();
-                formatForBuf[entry.getKey()] = entry.getValue().getFormat();
+            for (VertexBuffer vb : geom.getMesh().getBufferList().getArray()) {
+                compsForBuf[vb.getBufferType().ordinal()] = vb.getNumComponents();
+                formatForBuf[vb.getBufferType().ordinal()] = vb.getFormat();
             }
 
             if (mode != null && mode != listMode) {
diff --git a/engine/src/core/com/jme3/scene/Mesh.java b/engine/src/core/com/jme3/scene/Mesh.java
index 6c587f2..036e525 100644
--- a/engine/src/core/com/jme3/scene/Mesh.java
+++ b/engine/src/core/com/jme3/scene/Mesh.java
@@ -43,7 +43,6 @@
 import com.jme3.math.Triangle;
 import com.jme3.math.Vector2f;
 import com.jme3.math.Vector3f;
-import com.jme3.scene.VertexBuffer;
 import com.jme3.scene.VertexBuffer.Format;
 import com.jme3.scene.VertexBuffer.Type;
 import com.jme3.scene.VertexBuffer.Usage;
@@ -55,8 +54,6 @@
 import java.io.IOException;
 import java.nio.*;
 import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Set;
 
 /**
  * <code>Mesh</code> is used to store rendering data.
@@ -237,9 +234,9 @@
 
             clone.buffers = new IntMap<VertexBuffer>();
             clone.buffersList = new SafeArrayList<VertexBuffer>(VertexBuffer.class);
-            for (Entry<VertexBuffer> ent : buffers){
-                VertexBuffer bufClone = ent.getValue().clone();
-                clone.buffers.put(ent.getKey(), bufClone);
+            for (VertexBuffer vb : buffersList.getArray()){
+                VertexBuffer bufClone = vb.clone();
+                clone.buffers.put(vb.getBufferType().ordinal(), bufClone);
                 clone.buffersList.add(bufClone);
             }
             
@@ -540,8 +537,8 @@
      * for all {@link VertexBuffer vertex buffers} on this Mesh.
      */
     public void setStatic() {
-        for (Entry<VertexBuffer> entry : buffers){
-            entry.getValue().setUsage(Usage.Static);
+        for (VertexBuffer vb : buffersList.getArray()){
+            vb.setUsage(Usage.Static);
         }
     }
 
@@ -551,8 +548,8 @@
      * for all {@link VertexBuffer vertex buffers} on this Mesh.
      */
     public void setDynamic() {
-        for (Entry<VertexBuffer> entry : buffers){
-            entry.getValue().setUsage(Usage.Dynamic);
+        for (VertexBuffer vb : buffersList.getArray()){
+            vb.setUsage(Usage.Dynamic);
         }
     }
 
@@ -562,8 +559,8 @@
      * for all {@link VertexBuffer vertex buffers} on this Mesh.
      */
     public void setStreamed(){
-        for (Entry<VertexBuffer> entry : buffers){
-            entry.getValue().setUsage(Usage.Stream);
+        for (VertexBuffer vb : buffersList.getArray()){
+            vb.setUsage(Usage.Stream);
         }
     }
 
@@ -572,11 +569,11 @@
      * Some GPUs may prefer the data in this format, however it is a good idea
      * to <em>avoid</em> using this method as it disables some engine features.
      */
+    @Deprecated
     public void setInterleaved(){
         ArrayList<VertexBuffer> vbs = new ArrayList<VertexBuffer>();
-        for (Entry<VertexBuffer> entry : buffers){
-            vbs.add(entry.getValue());
-        }
+        vbs.addAll(buffersList);
+        
 //        ArrayList<VertexBuffer> vbs = new ArrayList<VertexBuffer>(buffers.values());
         // index buffer not included when interleaving
         vbs.remove(getBuffer(Type.Index));
@@ -860,6 +857,65 @@
     }
 
     /**
+     * Sets the {@link VertexBuffer} on the mesh.
+     * This will update the vertex/triangle counts if needed.
+     * 
+     * @param vb The buffer to set
+     * @throws IllegalArgumentException If the buffer type is already set
+     */
+    public void setBuffer(VertexBuffer vb){
+        if (buffers.containsKey(vb.getBufferType().ordinal()))
+            throw new IllegalArgumentException("Buffer type already set: "+vb.getBufferType());
+
+        buffers.put(vb.getBufferType().ordinal(), vb);
+        buffersList.add(vb);
+        updateCounts();
+    }
+    
+    /**
+     * Unsets the {@link VertexBuffer} set on this mesh
+     * with the given type. Does nothing if the vertex buffer type is not set 
+     * initially.
+     * 
+     * @param type The buffer type to remove
+     */
+    public void clearBuffer(VertexBuffer.Type type){
+        VertexBuffer vb = buffers.remove(type.ordinal());
+        if (vb != null){
+            buffersList.remove(vb);
+            updateCounts();
+        }
+    }
+    
+    /**
+     * Creates a {@link VertexBuffer} for the mesh or modifies
+     * the existing one per the parameters given.
+     * 
+     * @param type The type of the buffer
+     * @param components Number of components
+     * @param format Data format
+     * @param buf The buffer data
+     * 
+     * @throws UnsupportedOperationException If the buffer already set is 
+     * incompatible with the parameters given.
+     */
+    public void setBuffer(Type type, int components, Format format, Buffer buf){
+        VertexBuffer vb = buffers.get(type.ordinal());
+        if (vb == null){
+            vb = new VertexBuffer(type);
+            vb.setupData(Usage.Dynamic, components, format, buf);
+            setBuffer(vb);
+        }else{
+            if (vb.getNumComponents() != components || vb.getFormat() != format){
+                throw new UnsupportedOperationException("The buffer already set "
+                        + "is incompatible with the given parameters");
+            }
+            vb.updateData(buf);
+            updateCounts();
+        }
+    }
+    
+    /**
      * Set a floating point {@link VertexBuffer} on the mesh. 
      * 
      * @param type The type of {@link VertexBuffer}, 
@@ -871,21 +927,7 @@
      * @param buf The floating point data to contain
      */
     public void setBuffer(Type type, int components, FloatBuffer buf) {
-//        VertexBuffer vb = buffers.get(type);
-        VertexBuffer vb = buffers.get(type.ordinal());
-        if (vb == null){
-            if (buf == null)
-                return;
-
-            vb = new VertexBuffer(type);
-            vb.setupData(Usage.Dynamic, components, Format.Float, buf);
-//            buffers.put(type, vb);
-            buffers.put(type.ordinal(), vb);
-            buffersList.add(vb);
-        }else{
-            vb.setupData(Usage.Dynamic, components, Format.Float, buf);
-        }
-        updateCounts();
+        setBuffer(type, components, Format.Float, buf);
     }
 
     public void setBuffer(Type type, int components, float[] buf){
@@ -893,14 +935,7 @@
     }
 
     public void setBuffer(Type type, int components, IntBuffer buf) {
-        VertexBuffer vb = buffers.get(type.ordinal());
-        if (vb == null){
-            vb = new VertexBuffer(type);
-            vb.setupData(Usage.Dynamic, components, Format.UnsignedInt, buf);
-            buffers.put(type.ordinal(), vb);
-            buffersList.add(vb);
-            updateCounts();
-        }
+        setBuffer(type, components, Format.UnsignedInt, buf);
     }
 
     public void setBuffer(Type type, int components, int[] buf){
@@ -908,14 +943,7 @@
     }
 
     public void setBuffer(Type type, int components, ShortBuffer buf) {
-        VertexBuffer vb = buffers.get(type.ordinal());
-        if (vb == null){
-            vb = new VertexBuffer(type);
-            vb.setupData(Usage.Dynamic, components, Format.UnsignedShort, buf);
-            buffers.put(type.ordinal(), vb);
-            buffersList.add(vb);
-            updateCounts();
-        }
+        setBuffer(type, components, Format.UnsignedShort, buf);
     }
 
     public void setBuffer(Type type, int components, byte[] buf){
@@ -923,38 +951,7 @@
     }
 
     public void setBuffer(Type type, int components, ByteBuffer buf) {
-        VertexBuffer vb = buffers.get(type.ordinal());
-        if (vb == null){
-            vb = new VertexBuffer(type);
-            vb.setupData(Usage.Dynamic, components, Format.UnsignedByte, buf);
-            buffers.put(type.ordinal(), vb);
-            buffersList.add(vb);
-            updateCounts();
-        }
-    }
-
-    public void setBuffer(VertexBuffer vb){
-        if (buffers.containsKey(vb.getBufferType().ordinal()))
-            throw new IllegalArgumentException("Buffer type already set: "+vb.getBufferType());
-
-        buffers.put(vb.getBufferType().ordinal(), vb);
-        buffersList.add(vb);
-        updateCounts();
-    }
-
-    /**
-     * Clears or unsets the {@link VertexBuffer} set on this mesh
-     * with the given type.
-     * Does nothing if the vertex buffer type is not set initially
-     * 
-     * @param type The type to remove
-     */
-    public void clearBuffer(VertexBuffer.Type type){
-        VertexBuffer vb = buffers.remove(type.ordinal());
-        if (vb != null){
-            buffersList.remove(vb);
-            updateCounts();
-        }
+        setBuffer(type, components, Format.UnsignedByte, buf);
     }
 
     public void setBuffer(Type type, int components, short[] buf){
diff --git a/engine/src/core/com/jme3/shader/UniformBinding.java b/engine/src/core/com/jme3/shader/UniformBinding.java
index bdca35b..6bd4ca9 100644
--- a/engine/src/core/com/jme3/shader/UniformBinding.java
+++ b/engine/src/core/com/jme3/shader/UniformBinding.java
@@ -1,162 +1,176 @@
-/*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- *   may be used to endorse or promote products derived from this software
- *   without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.jme3.shader;
-
-public enum UniformBinding {
-
-    /**
-     * The world matrix. Converts Model space to World space.
-     * Type: mat4
-     */
-    WorldMatrix,
-
-    /**
-     * The view matrix. Converts World space to View space.
-     * Type: mat4
-     */
-    ViewMatrix,
-
-    /**
-     * The projection matrix. Converts View space to Clip/Projection space.
-     * Type: mat4
-     */
-    ProjectionMatrix,
-
-    /**
-     * The world view matrix. Converts Model space to View space.
-     * Type: mat4
-     */
-    WorldViewMatrix,
-
-    /**
-     * The normal matrix. The inverse transpose of the worldview matrix.
-     * Converts normals from model space to view space.
-     * Type: mat3
-     */
-    NormalMatrix,
-
-    /**
-     * The world view projection matrix. Converts Model space to Clip/Projection
-     * space.
-     * Type: mat4
-     */
-    WorldViewProjectionMatrix,
-
-    /**
-     * The view projection matrix. Converts Model space to Clip/Projection
-     * space.
-     * Type: mat4
-     */
-    ViewProjectionMatrix,
-
-
-    WorldMatrixInverse,
-    ViewMatrixInverse,
-    ProjectionMatrixInverse,
-    ViewProjectionMatrixInverse,
-    WorldViewMatrixInverse,
-    NormalMatrixInverse,
-    WorldViewProjectionMatrixInverse,
-
-    /**
-     * Contains the four viewport parameters in this order:
-     * X = Left,
-     * Y = Top,
-     * Z = Right,
-     * W = Bottom.
-     * Type: vec4
-     */
-    ViewPort,
-
-    /**
-     * The near and far values for the camera frustum.
-     * X = Near
-     * Y = Far.
-     * Type: vec2
-     */
-    FrustumNearFar,
-    
-    /**
-     * The width and height of the camera.
-     * Type: vec2
-     */
-    Resolution,
-
-    /**
-     * Aspect ratio of the resolution currently set. Width/Height.
-     * Type: float
-     */
-    Aspect,
-
-    /**
-     * Camera position in world space.
-     * Type: vec3
-     */
-    CameraPosition,
-
-    /**
-     * Direction of the camera.
-     * Type: vec3
-     */
-    CameraDirection,
-
-    /**
-     * Left vector of the camera.
-     * Type: vec3
-     */
-    CameraLeft,
-
-    /**
-     * Up vector of the camera.
-     * Type: vec3
-     */
-    CameraUp,
-
-    /**
-     * Time in seconds since the application was started.
-     * Type: float
-     */
-    Time,
-
-    /**
-     * Time in seconds that the last frame took.
-     * Type: float
-     */
-    Tpf,
-
-    /**
-     * Frames per second.
-     * Type: float
-     */
-    FrameRate,
-}
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.jme3.shader;
+
+public enum UniformBinding {
+
+    /**
+     * The world matrix. Converts Model space to World space.
+     * Type: mat4
+     */
+    WorldMatrix,
+
+    /**
+     * The view matrix. Converts World space to View space.
+     * Type: mat4
+     */
+    ViewMatrix,
+
+    /**
+     * The projection matrix. Converts View space to Clip/Projection space.
+     * Type: mat4
+     */
+    ProjectionMatrix,
+
+    /**
+     * The world view matrix. Converts Model space to View space.
+     * Type: mat4
+     */
+    WorldViewMatrix,
+
+    /**
+     * The normal matrix. The inverse transpose of the worldview matrix.
+     * Converts normals from model space to view space.
+     * Type: mat3
+     */
+    NormalMatrix,
+
+    /**
+     * The world view projection matrix. Converts Model space to Clip/Projection
+     * space.
+     * Type: mat4
+     */
+    WorldViewProjectionMatrix,
+
+    /**
+     * The view projection matrix. Converts World space to Clip/Projection
+     * space.
+     * Type: mat4
+     */
+    ViewProjectionMatrix,
+
+    /**
+     * The world matrix inverse transpose. Converts a normals from Model space
+     * to world space.
+     * Type: mat3
+     */
+    WorldMatrixInverseTranspose,      
+
+
+
+    WorldMatrixInverse,
+    ViewMatrixInverse,
+    ProjectionMatrixInverse,
+    ViewProjectionMatrixInverse,
+    WorldViewMatrixInverse,
+    NormalMatrixInverse,
+    WorldViewProjectionMatrixInverse,
+
+    /**
+     * Contains the four viewport parameters in this order:
+     * X = Left,
+     * Y = Top,
+     * Z = Right,
+     * W = Bottom.
+     * Type: vec4
+     */
+    ViewPort,
+
+    /**
+     * The near and far values for the camera frustum.
+     * X = Near
+     * Y = Far.
+     * Type: vec2
+     */
+    FrustumNearFar,
+    
+    /**
+     * The width and height of the camera.
+     * Type: vec2
+     */
+    Resolution,
+    
+    /**
+     * The inverse of the resolution, 1/width and 1/height. 
+     * Type: vec2
+     */
+    ResolutionInverse,
+
+    /**
+     * Aspect ratio of the resolution currently set. Width/Height.
+     * Type: float
+     */
+    Aspect,
+
+    /**
+     * Camera position in world space.
+     * Type: vec3
+     */
+    CameraPosition,
+
+    /**
+     * Direction of the camera.
+     * Type: vec3
+     */
+    CameraDirection,
+
+    /**
+     * Left vector of the camera.
+     * Type: vec3
+     */
+    CameraLeft,
+
+    /**
+     * Up vector of the camera.
+     * Type: vec3
+     */
+    CameraUp,
+
+    /**
+     * Time in seconds since the application was started.
+     * Type: float
+     */
+    Time,
+
+    /**
+     * Time in seconds that the last frame took.
+     * Type: float
+     */
+    Tpf,
+
+    /**
+     * Frames per second.
+     * Type: float
+     */
+    FrameRate,
+}
diff --git a/engine/src/core/com/jme3/system/JmeSystem.java b/engine/src/core/com/jme3/system/JmeSystem.java
index 1a13a42..2e2d79a 100644
--- a/engine/src/core/com/jme3/system/JmeSystem.java
+++ b/engine/src/core/com/jme3/system/JmeSystem.java
@@ -1,136 +1,147 @@
-/*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- *   may be used to endorse or promote products derived from this software
- *   without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package com.jme3.system;
-
-import com.jme3.asset.AssetManager;
-import com.jme3.audio.AudioRenderer;
-import java.io.File;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-public class JmeSystem {
-
-    private static JmeSystemDelegate systemDelegate;
-
-    public static void setSystemDelegate(JmeSystemDelegate systemDelegate) {
-        JmeSystem.systemDelegate = systemDelegate;
-    }
-    
-    public static synchronized File getStorageFolder() {
-        checkDelegate();
-        return systemDelegate.getStorageFolder();
-    }
-
-    public static String getFullName() {
-        checkDelegate();
-        return systemDelegate.getFullName();
-    }
-
-    public static InputStream getResourceAsStream(String name) {
-        checkDelegate();
-        return systemDelegate.getResourceAsStream(name);
-    }
-
-    public static URL getResource(String name) {
-        checkDelegate();
-        return systemDelegate.getResource(name);
-    }
-
-    public static boolean trackDirectMemory() {
-        checkDelegate();
-        return systemDelegate.trackDirectMemory();
-    }
-
-    public static void setLowPermissions(boolean lowPerm) {
-        checkDelegate();
-        systemDelegate.setLowPermissions(lowPerm);
-    }
-
-    public static boolean isLowPermissions() {
-        checkDelegate();
-        return systemDelegate.isLowPermissions();
-    }
-
-    public static AssetManager newAssetManager(URL configFile) {
-        checkDelegate();
-        return systemDelegate.newAssetManager(configFile);
-    }
-
-    public static AssetManager newAssetManager() {
-        checkDelegate();
-        return systemDelegate.newAssetManager();
-    }
-
-    public static boolean showSettingsDialog(AppSettings sourceSettings, final boolean loadFromRegistry) {
-        checkDelegate();
-        return systemDelegate.showSettingsDialog(sourceSettings, loadFromRegistry);
-    }
-
-    public static Platform getPlatform() {
-        checkDelegate();
-        return systemDelegate.getPlatform();
-    }
-
-    public static JmeContext newContext(AppSettings settings, JmeContext.Type contextType) {
-        checkDelegate();
-        return systemDelegate.newContext(settings, contextType);
-    }
-
-    public static AudioRenderer newAudioRenderer(AppSettings settings) {
-        checkDelegate();
-        return systemDelegate.newAudioRenderer(settings);
-    }
-
-    public static void initialize(AppSettings settings) {
-        checkDelegate();
-        systemDelegate.initialize(settings);
-    }
-
-    @SuppressWarnings("unchecked")
-    private static void checkDelegate() {
-        if (systemDelegate == null) {
-            Class<JmeSystemDelegate> systemDelegateClass;
-            try {
-                systemDelegateClass = (Class<JmeSystemDelegate>) Class.forName("com.jme3.system.JmeDesktopSystem");
-                systemDelegate = systemDelegateClass.newInstance();
-            } catch (InstantiationException ex) {
-                Logger.getLogger(JmeSystem.class.getName()).log(Level.SEVERE, "No JmeSystemDelegate specified, cannot instantiate default JmeDesktopSystem:\n{0}", ex);
-            } catch (IllegalAccessException ex) {
-                Logger.getLogger(JmeSystem.class.getName()).log(Level.SEVERE, "No JmeSystemDelegate specified, cannot instantiate default JmeDesktopSystem:\n{0}", ex);
-            } catch (ClassNotFoundException ex) {
-                Logger.getLogger(JmeSystem.class.getName()).log(Level.SEVERE, "No JmeSystemDelegate specified, cannot instantiate default JmeDesktopSystem:\n{0}", ex);
-            }
-        }
-    }
-}
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.system;
+
+import com.jme3.asset.AssetManager;
+import com.jme3.audio.AudioRenderer;
+import com.jme3.input.SoftTextDialogInput;
+import java.io.File;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public class JmeSystem {
+
+    private static JmeSystemDelegate systemDelegate;
+
+    public static void setSystemDelegate(JmeSystemDelegate systemDelegate) {
+        JmeSystem.systemDelegate = systemDelegate;
+    }
+    
+    public static synchronized File getStorageFolder() {
+        checkDelegate();
+        return systemDelegate.getStorageFolder();
+    }
+
+    public static String getFullName() {
+        checkDelegate();
+        return systemDelegate.getFullName();
+    }
+
+    public static InputStream getResourceAsStream(String name) {
+        checkDelegate();
+        return systemDelegate.getResourceAsStream(name);
+    }
+
+    public static URL getResource(String name) {
+        checkDelegate();
+        return systemDelegate.getResource(name);
+    }
+
+    public static boolean trackDirectMemory() {
+        checkDelegate();
+        return systemDelegate.trackDirectMemory();
+    }
+
+    public static void setLowPermissions(boolean lowPerm) {
+        checkDelegate();
+        systemDelegate.setLowPermissions(lowPerm);
+    }
+
+    public static boolean isLowPermissions() {
+        checkDelegate();
+        return systemDelegate.isLowPermissions();
+    }
+
+    public static void setSoftTextDialogInput(SoftTextDialogInput input) {
+        checkDelegate();
+        systemDelegate.setSoftTextDialogInput(input);
+    }
+
+    public static SoftTextDialogInput getSoftTextDialogInput() {
+        checkDelegate();
+        return systemDelegate.getSoftTextDialogInput();
+    }
+
+    public static AssetManager newAssetManager(URL configFile) {
+        checkDelegate();
+        return systemDelegate.newAssetManager(configFile);
+    }
+
+    public static AssetManager newAssetManager() {
+        checkDelegate();
+        return systemDelegate.newAssetManager();
+    }
+
+    public static boolean showSettingsDialog(AppSettings sourceSettings, final boolean loadFromRegistry) {
+        checkDelegate();
+        return systemDelegate.showSettingsDialog(sourceSettings, loadFromRegistry);
+    }
+
+    public static Platform getPlatform() {
+        checkDelegate();
+        return systemDelegate.getPlatform();
+    }
+
+    public static JmeContext newContext(AppSettings settings, JmeContext.Type contextType) {
+        checkDelegate();
+        return systemDelegate.newContext(settings, contextType);
+    }
+
+    public static AudioRenderer newAudioRenderer(AppSettings settings) {
+        checkDelegate();
+        return systemDelegate.newAudioRenderer(settings);
+    }
+
+    public static void initialize(AppSettings settings) {
+        checkDelegate();
+        systemDelegate.initialize(settings);
+    }
+
+    @SuppressWarnings("unchecked")
+    private static void checkDelegate() {
+        if (systemDelegate == null) {
+            Class<JmeSystemDelegate> systemDelegateClass;
+            try {
+                systemDelegateClass = (Class<JmeSystemDelegate>) Class.forName("com.jme3.system.JmeDesktopSystem");
+                systemDelegate = systemDelegateClass.newInstance();
+            } catch (InstantiationException ex) {
+                Logger.getLogger(JmeSystem.class.getName()).log(Level.SEVERE, "No JmeSystemDelegate specified, cannot instantiate default JmeDesktopSystem:\n{0}", ex);
+            } catch (IllegalAccessException ex) {
+                Logger.getLogger(JmeSystem.class.getName()).log(Level.SEVERE, "No JmeSystemDelegate specified, cannot instantiate default JmeDesktopSystem:\n{0}", ex);
+            } catch (ClassNotFoundException ex) {
+                Logger.getLogger(JmeSystem.class.getName()).log(Level.SEVERE, "No JmeSystemDelegate specified, cannot instantiate default JmeDesktopSystem:\n{0}", ex);
+            }
+        }
+    }
+}
diff --git a/engine/src/core/com/jme3/system/JmeSystemDelegate.java b/engine/src/core/com/jme3/system/JmeSystemDelegate.java
index 60265ae..e0f6fa5 100644
--- a/engine/src/core/com/jme3/system/JmeSystemDelegate.java
+++ b/engine/src/core/com/jme3/system/JmeSystemDelegate.java
@@ -1,140 +1,149 @@
-/*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- *   may be used to endorse or promote products derived from this software
- *   without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package com.jme3.system;
-
-import com.jme3.asset.AssetManager;
-import com.jme3.audio.AudioRenderer;
-import java.io.File;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.logging.Logger;
-
-/**
- *
- * @author Kirill Vainer, normenhansen
- */
-public abstract class JmeSystemDelegate {
-
-    protected final Logger logger = Logger.getLogger(JmeSystem.class.getName());
-    protected boolean initialized = false;
-    protected boolean lowPermissions = false;
-    protected File storageFolder = null;
-
-    public synchronized File getStorageFolder() {
-        if (lowPermissions) {
-            throw new UnsupportedOperationException("File system access restricted");
-        }
-        if (storageFolder == null) {
-            // Initialize storage folder
-            storageFolder = new File(System.getProperty("user.home"), ".jme3");
-            if (!storageFolder.exists()) {
-                storageFolder.mkdir();
-            }
-        }
-        return storageFolder;
-    }
-    
-    public String getFullName() {
-        return JmeVersion.FULL_NAME;
-    }
-
-    public InputStream getResourceAsStream(String name) {
-        return this.getClass().getResourceAsStream(name);
-    }
-
-    public URL getResource(String name) {
-        return this.getClass().getResource(name);
-    }
-
-    public boolean trackDirectMemory() {
-        return false;
-    }
-
-    public void setLowPermissions(boolean lowPerm) {
-        lowPermissions = lowPerm;
-    }
-
-    public boolean isLowPermissions() {
-        return lowPermissions;
-    }
-
-    public abstract AssetManager newAssetManager(URL configFile);
-
-    public abstract AssetManager newAssetManager();
-
-    public abstract boolean showSettingsDialog(AppSettings sourceSettings, boolean loadFromRegistry);
-
-    private boolean is64Bit(String arch) {
-        if (arch.equals("x86")) {
-            return false;
-        } else if (arch.equals("amd64")) {
-            return true;
-        } else if (arch.equals("x86_64")) {
-            return true;
-        } else if (arch.equals("ppc") || arch.equals("PowerPC")) {
-            return false;
-        } else if (arch.equals("ppc64")) {
-            return true;
-        } else if (arch.equals("i386") || arch.equals("i686")) {
-            return false;
-        } else if (arch.equals("universal")) {
-            return false;
-        } else {
-            throw new UnsupportedOperationException("Unsupported architecture: " + arch);
-        }
-    }
-
-    public Platform getPlatform() {
-        String os = System.getProperty("os.name").toLowerCase();
-        String arch = System.getProperty("os.arch").toLowerCase();
-        boolean is64 = is64Bit(arch);
-        if (os.contains("windows")) {
-            return is64 ? Platform.Windows64 : Platform.Windows32;
-        } else if (os.contains("linux") || os.contains("freebsd") || os.contains("sunos")) {
-            return is64 ? Platform.Linux64 : Platform.Linux32;
-        } else if (os.contains("mac os x") || os.contains("darwin")) {
-            if (arch.startsWith("ppc")) {
-                return is64 ? Platform.MacOSX_PPC64 : Platform.MacOSX_PPC32;
-            } else {
-                return is64 ? Platform.MacOSX64 : Platform.MacOSX32;
-            }
-        } else {
-            throw new UnsupportedOperationException("The specified platform: " + os + " is not supported.");
-        }
-    }
-
-    public abstract JmeContext newContext(AppSettings settings, JmeContext.Type contextType);
-
-    public abstract AudioRenderer newAudioRenderer(AppSettings settings);
-
-    public abstract void initialize(AppSettings settings);
-}
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.system;
+
+import com.jme3.asset.AssetManager;
+import com.jme3.audio.AudioRenderer;
+import com.jme3.input.SoftTextDialogInput;
+import java.io.File;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.logging.Logger;
+
+/**
+ *
+ * @author Kirill Vainer, normenhansen
+ */
+public abstract class JmeSystemDelegate {
+
+    protected final Logger logger = Logger.getLogger(JmeSystem.class.getName());
+    protected boolean initialized = false;
+    protected boolean lowPermissions = false;
+    protected File storageFolder = null;
+    protected SoftTextDialogInput softTextDialogInput = null;
+
+    public synchronized File getStorageFolder() {
+        if (lowPermissions) {
+            throw new UnsupportedOperationException("File system access restricted");
+        }
+        if (storageFolder == null) {
+            // Initialize storage folder
+            storageFolder = new File(System.getProperty("user.home"), ".jme3");
+            if (!storageFolder.exists()) {
+                storageFolder.mkdir();
+            }
+        }
+        return storageFolder;
+    }
+    
+    public String getFullName() {
+        return JmeVersion.FULL_NAME;
+    }
+
+    public InputStream getResourceAsStream(String name) {
+        return this.getClass().getResourceAsStream(name);
+    }
+
+    public URL getResource(String name) {
+        return this.getClass().getResource(name);
+    }
+
+    public boolean trackDirectMemory() {
+        return false;
+    }
+
+    public void setLowPermissions(boolean lowPerm) {
+        lowPermissions = lowPerm;
+    }
+
+    public boolean isLowPermissions() {
+        return lowPermissions;
+    }
+
+    public void setSoftTextDialogInput(SoftTextDialogInput input) {
+        softTextDialogInput = input;
+    }
+    public SoftTextDialogInput getSoftTextDialogInput() {
+        return softTextDialogInput;
+    }
+
+    public abstract AssetManager newAssetManager(URL configFile);
+
+    public abstract AssetManager newAssetManager();
+
+    public abstract boolean showSettingsDialog(AppSettings sourceSettings, boolean loadFromRegistry);
+
+    private boolean is64Bit(String arch) {
+        if (arch.equals("x86")) {
+            return false;
+        } else if (arch.equals("amd64")) {
+            return true;
+        } else if (arch.equals("x86_64")) {
+            return true;
+        } else if (arch.equals("ppc") || arch.equals("PowerPC")) {
+            return false;
+        } else if (arch.equals("ppc64")) {
+            return true;
+        } else if (arch.equals("i386") || arch.equals("i686")) {
+            return false;
+        } else if (arch.equals("universal")) {
+            return false;
+        } else {
+            throw new UnsupportedOperationException("Unsupported architecture: " + arch);
+        }
+    }
+
+    public Platform getPlatform() {
+        String os = System.getProperty("os.name").toLowerCase();
+        String arch = System.getProperty("os.arch").toLowerCase();
+        boolean is64 = is64Bit(arch);
+        if (os.contains("windows")) {
+            return is64 ? Platform.Windows64 : Platform.Windows32;
+        } else if (os.contains("linux") || os.contains("freebsd") || os.contains("sunos")) {
+            return is64 ? Platform.Linux64 : Platform.Linux32;
+        } else if (os.contains("mac os x") || os.contains("darwin")) {
+            if (arch.startsWith("ppc")) {
+                return is64 ? Platform.MacOSX_PPC64 : Platform.MacOSX_PPC32;
+            } else {
+                return is64 ? Platform.MacOSX64 : Platform.MacOSX32;
+            }
+        } else {
+            throw new UnsupportedOperationException("The specified platform: " + os + " is not supported.");
+        }
+    }
+
+    public abstract JmeContext newContext(AppSettings settings, JmeContext.Type contextType);
+
+    public abstract AudioRenderer newAudioRenderer(AppSettings settings);
+
+    public abstract void initialize(AppSettings settings);
+}
diff --git a/engine/src/core/com/jme3/util/BufferUtils.java b/engine/src/core/com/jme3/util/BufferUtils.java
index f0cc698..2e59e97 100644
--- a/engine/src/core/com/jme3/util/BufferUtils.java
+++ b/engine/src/core/com/jme3/util/BufferUtils.java
@@ -42,6 +42,7 @@
 import java.util.Collections;
 import java.util.Map;
 import java.util.WeakHashMap;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -1144,6 +1145,47 @@
         }
     }
     
+    private static final AtomicBoolean loadedMethods = new AtomicBoolean(false);
+    private static Method cleanerMethod = null;
+    private static Method cleanMethod = null;
+    private static Method viewedBufferMethod = null;
+    private static Method freeMethod = null;
+    
+    private static Method loadMethod(String className, String methodName){
+        try {
+            Method method = Class.forName(className).getMethod(methodName);
+            method.setAccessible(true);
+            return method;
+        } catch (NoSuchMethodException ex) {
+            return null; // the method was not found
+        } catch (SecurityException ex) {
+            return null; // setAccessible not allowed by security policy
+        } catch (ClassNotFoundException ex) {
+            return null; // the direct buffer implementation was not found
+        }
+    }
+    
+    private static void loadCleanerMethods() {
+        // If its already true, exit, if not, set it to true.
+        if (loadedMethods.getAndSet(true)) {
+            return;
+        }
+        // This could potentially be called many times if used from multiple
+        // threads
+        synchronized (loadedMethods) {
+            // Oracle JRE / OpenJDK
+            cleanerMethod = loadMethod("sun.nio.ch.DirectBuffer", "cleaner");
+            cleanMethod = loadMethod("sun.misc.Cleaner", "clean");
+            viewedBufferMethod = loadMethod("sun.nio.ch.DirectBuffer", "viewedBuffer");
+            
+            // Apache Harmony
+            freeMethod = loadMethod("org.apache.harmony.nio.internal.DirectBuffer", "free");
+            
+            // GUN Classpath (not likely)
+            //finalizeMethod = loadMethod("java.nio.DirectByteBufferImpl", "finalize");
+        }
+    }
+    
     /**
     * Direct buffers are garbage collected by using a phantom reference and a
     * reference queue. Every once a while, the JVM checks the reference queue and
@@ -1157,27 +1199,27 @@
     *          
     */
     public static void destroyDirectBuffer(Buffer toBeDestroyed) {
-    
         if (!toBeDestroyed.isDirect()) {
             return;
         }
+        
+        loadCleanerMethods();
+        
         try {
-            Method cleanerMethod = toBeDestroyed.getClass().getMethod("cleaner");
-            cleanerMethod.setAccessible(true);
-            Object cleaner = cleanerMethod.invoke(toBeDestroyed);
-            if (cleaner != null) {
-                Method cleanMethod = cleaner.getClass().getMethod("clean");
-                cleanMethod.setAccessible(true);
-                cleanMethod.invoke(cleaner);
+            if (freeMethod != null) {
+                freeMethod.invoke(toBeDestroyed);
             } else {
-                // Try the alternate approach of getting the viewed buffer
-                Method viewedBufferMethod = toBeDestroyed.getClass().getMethod("viewedBuffer");
-                viewedBufferMethod.setAccessible(true);
-                Object viewedBuffer = viewedBufferMethod.invoke(toBeDestroyed);
-                if (viewedBuffer != null) {
-                    destroyDirectBuffer( (Buffer)viewedBuffer );
+                Object cleaner = cleanerMethod.invoke(toBeDestroyed);
+                if (cleaner != null) {
+                    cleanMethod.invoke(cleaner);
                 } else {
-                    Logger.getLogger(BufferUtils.class.getName()).log(Level.SEVERE, "Buffer cannot be destroyed: {0}", toBeDestroyed);
+                    // Try the alternate approach of getting the viewed buffer first
+                    Object viewedBuffer = viewedBufferMethod.invoke(toBeDestroyed);
+                    if (viewedBuffer != null) {
+                        destroyDirectBuffer((Buffer) viewedBuffer);
+                    } else {
+                        Logger.getLogger(BufferUtils.class.getName()).log(Level.SEVERE, "Buffer cannot be destroyed: {0}", toBeDestroyed);
+                    }
                 }
             }
         } catch (IllegalAccessException ex) {
@@ -1186,11 +1228,8 @@
             Logger.getLogger(BufferUtils.class.getName()).log(Level.SEVERE, "{0}", ex);
         } catch (InvocationTargetException ex) {
             Logger.getLogger(BufferUtils.class.getName()).log(Level.SEVERE, "{0}", ex);
-        } catch (NoSuchMethodException ex) {
-            Logger.getLogger(BufferUtils.class.getName()).log(Level.SEVERE, "{0}", ex);
         } catch (SecurityException ex) {
             Logger.getLogger(BufferUtils.class.getName()).log(Level.SEVERE, "{0}", ex);
         }
     }
-
 }
diff --git a/engine/src/core/com/jme3/util/IntMap.java b/engine/src/core/com/jme3/util/IntMap.java
index edf659b..1b91119 100644
--- a/engine/src/core/com/jme3/util/IntMap.java
+++ b/engine/src/core/com/jme3/util/IntMap.java
@@ -44,8 +44,6 @@
  * @author Nate 
  */
 public final class IntMap<T> implements Iterable<Entry<T>>, Cloneable {
-
-    private final IntMapIterator iterator = new IntMapIterator();
             
     private Entry[] table;
     private final float loadFactor;
@@ -200,8 +198,9 @@
     }
 
     public Iterator<Entry<T>> iterator() {
-        iterator.beginUse();
-        return iterator;
+        IntMapIterator it = new IntMapIterator();
+        it.beginUse();
+        return it;
     }
 
     final class IntMapIterator implements Iterator<Entry<T>> {
diff --git a/engine/src/core/com/jme3/util/TangentBinormalGenerator.java b/engine/src/core/com/jme3/util/TangentBinormalGenerator.java
index 88f6822..8816b91 100644
--- a/engine/src/core/com/jme3/util/TangentBinormalGenerator.java
+++ b/engine/src/core/com/jme3/util/TangentBinormalGenerator.java
@@ -117,7 +117,13 @@
             }
         } else {
             Geometry geom = (Geometry) scene;
-            generate(geom.getMesh());
+            Mesh mesh = geom.getMesh();
+            
+            // Check to ensure mesh has texcoords and normals before generating
+            if (mesh.getBuffer(Type.TexCoord) != null 
+             && mesh.getBuffer(Type.Normal) != null){
+                generate(geom.getMesh());
+            }
         }
     }
     
@@ -640,7 +646,7 @@
         lineMesh.setBuffer(Type.Color, 4, lineColor);
         
         lineMesh.setStatic();
-        lineMesh.setInterleaved();
+        //lineMesh.setInterleaved();
         return lineMesh;
     }
     
@@ -733,7 +739,7 @@
         lineMesh.setBuffer(Type.Color, 4, lineColor);
         
         lineMesh.setStatic();
-        lineMesh.setInterleaved();
+        //lineMesh.setInterleaved();
         return lineMesh;
     }
 }
diff --git a/engine/src/desktop/com/jme3/texture/plugins/AWTLoader.java b/engine/src/desktop/com/jme3/texture/plugins/AWTLoader.java
index 3f471f7..9513bcf 100644
--- a/engine/src/desktop/com/jme3/texture/plugins/AWTLoader.java
+++ b/engine/src/desktop/com/jme3/texture/plugins/AWTLoader.java
@@ -33,6 +33,7 @@
 package com.jme3.texture.plugins;
 
 import com.jme3.asset.AssetInfo;
+import com.jme3.asset.AssetLoadException;
 import com.jme3.asset.AssetLoader;
 import com.jme3.asset.TextureKey;
 import com.jme3.texture.Image;
@@ -185,27 +186,30 @@
     public Image load(InputStream in, boolean flipY) throws IOException{
         ImageIO.setUseCache(false);
         BufferedImage img = ImageIO.read(in);
-        if (img == null)
+        if (img == null){
             return null;
-
+        }
         return load(img, flipY);
     }
 
     public Object load(AssetInfo info) throws IOException {
-        if (ImageIO.getImageWritersBySuffix(info.getKey().getExtension()) != null){
-            
+        if (ImageIO.getImageReadersBySuffix(info.getKey().getExtension()) != null){
             boolean flip = ((TextureKey) info.getKey()).isFlipY();
             InputStream in = null;
             try {
                 in = info.openStream();
                 Image img = load(in, flip);
+                if (img == null){
+                    throw new AssetLoadException("The given image cannot be loaded " + info.getKey());
+                }
                 return img;
             } finally {
                 if (in != null){
                     in.close();
                 }
             }
+        }else{
+            throw new AssetLoadException("The extension " + info.getKey().getExtension() + " is not supported");
         }
-        return null;
     }
 }
diff --git a/engine/src/niftygui/Common/MatDefs/Nifty/Nifty.frag b/engine/src/niftygui/Common/MatDefs/Nifty/Nifty.frag
deleted file mode 100644
index 5e77548..0000000
--- a/engine/src/niftygui/Common/MatDefs/Nifty/Nifty.frag
+++ /dev/null
@@ -1,13 +0,0 @@
-uniform bool m_UseTex;
-uniform sampler2D m_Texture;
-uniform vec4 m_Color;
-
-varying vec2 texCoord;
-varying vec4 color;
-
-void main() {
-    vec4 texVal = texture2D(m_Texture, texCoord);
-    texVal = m_UseTex ? texVal : vec4(1.0);
-    gl_FragColor = texVal * color * m_Color;
-}
-
diff --git a/engine/src/niftygui/Common/MatDefs/Nifty/NiftyQuad.frag b/engine/src/niftygui/Common/MatDefs/Nifty/NiftyQuad.frag
new file mode 100644
index 0000000..31f49d6
--- /dev/null
+++ b/engine/src/niftygui/Common/MatDefs/Nifty/NiftyQuad.frag
@@ -0,0 +1,6 @@
+uniform vec4 m_Color;
+
+void main() { 
+    gl_FragColor = m_Color;
+}
+
diff --git a/engine/src/niftygui/Common/MatDefs/Nifty/NiftyQuad.j3md b/engine/src/niftygui/Common/MatDefs/Nifty/NiftyQuad.j3md
new file mode 100644
index 0000000..d0213e9
--- /dev/null
+++ b/engine/src/niftygui/Common/MatDefs/Nifty/NiftyQuad.j3md
@@ -0,0 +1,19 @@
+MaterialDef Default GUI {
+
+    MaterialParameters {      
+        Vector4 Color (Color)
+    }
+
+    Technique {
+        VertexShader GLSL100:   Common/MatDefs/Nifty/NiftyQuad.vert
+        FragmentShader GLSL100: Common/MatDefs/Nifty/NiftyQuad.frag
+
+        WorldParameters {
+            WorldViewProjectionMatrix
+        }   
+    }
+
+    Technique FixedFunc {
+    }
+
+}
\ No newline at end of file
diff --git a/engine/src/niftygui/Common/MatDefs/Nifty/NiftyQuad.vert b/engine/src/niftygui/Common/MatDefs/Nifty/NiftyQuad.vert
new file mode 100644
index 0000000..1eb1616
--- /dev/null
+++ b/engine/src/niftygui/Common/MatDefs/Nifty/NiftyQuad.vert
@@ -0,0 +1,9 @@
+uniform mat4 g_WorldViewProjectionMatrix;
+
+attribute vec4 inPosition;
+
+
+void main() {
+    vec2 pos = (g_WorldViewProjectionMatrix * inPosition).xy;
+    gl_Position = vec4(pos, 0.0, 1.0);
+}
\ No newline at end of file
diff --git a/engine/src/niftygui/Common/MatDefs/Nifty/NiftyQuadGrad.frag b/engine/src/niftygui/Common/MatDefs/Nifty/NiftyQuadGrad.frag
new file mode 100644
index 0000000..1f0a645
--- /dev/null
+++ b/engine/src/niftygui/Common/MatDefs/Nifty/NiftyQuadGrad.frag
@@ -0,0 +1,6 @@
+varying vec4 color;
+
+void main() { 
+    gl_FragColor = color;
+}
+
diff --git a/engine/src/niftygui/Common/MatDefs/Nifty/NiftyQuadGrad.j3md b/engine/src/niftygui/Common/MatDefs/Nifty/NiftyQuadGrad.j3md
new file mode 100644
index 0000000..4b3b22d
--- /dev/null
+++ b/engine/src/niftygui/Common/MatDefs/Nifty/NiftyQuadGrad.j3md
@@ -0,0 +1,18 @@
+MaterialDef Default GUI {
+
+    MaterialParameters {              
+    }
+
+    Technique {
+        VertexShader GLSL100:   Common/MatDefs/Nifty/NiftyQuadGrad.vert
+        FragmentShader GLSL100: Common/MatDefs/Nifty/NiftyQuadGrad.frag
+
+        WorldParameters {
+            WorldViewProjectionMatrix
+        }   
+    }
+
+    Technique FixedFunc {
+    }
+
+}
\ No newline at end of file
diff --git a/engine/src/niftygui/Common/MatDefs/Nifty/Nifty.vert b/engine/src/niftygui/Common/MatDefs/Nifty/NiftyQuadGrad.vert
similarity index 70%
copy from engine/src/niftygui/Common/MatDefs/Nifty/Nifty.vert
copy to engine/src/niftygui/Common/MatDefs/Nifty/NiftyQuadGrad.vert
index 67c864d..0ecaee4 100644
--- a/engine/src/niftygui/Common/MatDefs/Nifty/Nifty.vert
+++ b/engine/src/niftygui/Common/MatDefs/Nifty/NiftyQuadGrad.vert
@@ -2,15 +2,13 @@
 
 attribute vec4 inPosition;
 attribute vec4 inColor;
-attribute vec2 inTexCoord;
+attribute vec4 inIndex;
 
-varying vec2 texCoord;
 varying vec4 color;
 
 void main() {
     vec2 pos = (g_WorldViewProjectionMatrix * inPosition).xy;
     gl_Position = vec4(pos, 0.0, 1.0);
 
-    texCoord = inTexCoord;
-    color = inColor;
+    color = inIndex;
 }
\ No newline at end of file
diff --git a/engine/src/niftygui/Common/MatDefs/Nifty/NiftyTex.frag b/engine/src/niftygui/Common/MatDefs/Nifty/NiftyTex.frag
new file mode 100644
index 0000000..b2b4b95
--- /dev/null
+++ b/engine/src/niftygui/Common/MatDefs/Nifty/NiftyTex.frag
@@ -0,0 +1,10 @@
+uniform sampler2D m_Texture;
+uniform vec4 m_Color; 
+
+varying vec2 texCoord;
+
+void main() {
+    vec4 texVal = texture2D(m_Texture, texCoord);
+    gl_FragColor = texVal * m_Color ;
+}
+
diff --git a/engine/src/niftygui/Common/MatDefs/Nifty/Nifty.j3md b/engine/src/niftygui/Common/MatDefs/Nifty/NiftyTex.j3md
similarity index 62%
rename from engine/src/niftygui/Common/MatDefs/Nifty/Nifty.j3md
rename to engine/src/niftygui/Common/MatDefs/Nifty/NiftyTex.j3md
index 9ba39b1..07f5e92 100644
--- a/engine/src/niftygui/Common/MatDefs/Nifty/Nifty.j3md
+++ b/engine/src/niftygui/Common/MatDefs/Nifty/NiftyTex.j3md
@@ -2,13 +2,12 @@
 
     MaterialParameters {
         Texture2D Texture
-        Boolean UseTex
         Vector4 Color (Color)
     }
 
     Technique {
-        VertexShader GLSL100:   Common/MatDefs/Nifty/Nifty.vert
-        FragmentShader GLSL100: Common/MatDefs/Nifty/Nifty.frag
+        VertexShader GLSL100:   Common/MatDefs/Nifty/NiftyTex.vert
+        FragmentShader GLSL100: Common/MatDefs/Nifty/NiftyTex.frag
 
         WorldParameters {
             WorldViewProjectionMatrix
diff --git a/engine/src/niftygui/Common/MatDefs/Nifty/Nifty.vert b/engine/src/niftygui/Common/MatDefs/Nifty/NiftyTex.vert
similarity index 72%
rename from engine/src/niftygui/Common/MatDefs/Nifty/Nifty.vert
rename to engine/src/niftygui/Common/MatDefs/Nifty/NiftyTex.vert
index 67c864d..c5c3dc1 100644
--- a/engine/src/niftygui/Common/MatDefs/Nifty/Nifty.vert
+++ b/engine/src/niftygui/Common/MatDefs/Nifty/NiftyTex.vert
@@ -1,16 +1,13 @@
 uniform mat4 g_WorldViewProjectionMatrix;
 
 attribute vec4 inPosition;
-attribute vec4 inColor;
 attribute vec2 inTexCoord;
 
 varying vec2 texCoord;
-varying vec4 color;
 
 void main() {
     vec2 pos = (g_WorldViewProjectionMatrix * inPosition).xy;
     gl_Position = vec4(pos, 0.0, 1.0);
 
-    texCoord = inTexCoord;
-    color = inColor;
+    texCoord = inTexCoord;    
 }
\ No newline at end of file
diff --git a/engine/src/niftygui/com/jme3/niftygui/InputSystemJme.java b/engine/src/niftygui/com/jme3/niftygui/InputSystemJme.java
index 0b80131..01c2ac7 100644
--- a/engine/src/niftygui/com/jme3/niftygui/InputSystemJme.java
+++ b/engine/src/niftygui/com/jme3/niftygui/InputSystemJme.java
@@ -1,233 +1,274 @@
-/*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- *   may be used to endorse or promote products derived from this software
- *   without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.jme3.niftygui;
-
-import com.jme3.input.InputManager;
-import com.jme3.input.KeyInput;
-import com.jme3.input.RawInputListener;
-import com.jme3.input.event.*;
-import de.lessvoid.nifty.Nifty;
-import de.lessvoid.nifty.NiftyInputConsumer;
-import de.lessvoid.nifty.tools.resourceloader.NiftyResourceLoader;
-import de.lessvoid.nifty.input.keyboard.KeyboardInputEvent;
-import de.lessvoid.nifty.spi.input.InputSystem;
-import java.util.ArrayList;
-
-public class InputSystemJme implements InputSystem, RawInputListener {
-
-    private final ArrayList<InputEvent> inputQueue = new ArrayList<InputEvent>();
-
-    private InputManager inputManager;
-
-    private boolean isDragging = false, niftyOwnsDragging = false;
-    private boolean pressed = false;
-    private int buttonIndex;
-    private int x, y;
-    private int height;
-
-    private boolean shiftDown = false;
-    private boolean ctrlDown  = false;
-
-    private Nifty nifty;
-
-    public InputSystemJme(InputManager inputManager){
-        this.inputManager = inputManager;
-    }
-
-    public void setResourceLoader(NiftyResourceLoader niftyResourceLoader) {
-    }
-
-    public void setNifty(Nifty nifty) {
-        this.nifty = nifty;
-    }
-
-    /**
-     * @param height The height of the viewport. Used to convert
-     * buttom-left origin to upper-left origin.
-     */
-    public void setHeight(int height){
-        this.height = height;
-    }
-
-    public void setMousePosition(int x, int y){
-    }
-
-    public void beginInput(){
-    }
-
-    public void endInput(){
-        boolean result = nifty.update();
-    }
-
-    private void onTouchEventQueued(TouchEvent evt, NiftyInputConsumer nic) {  
-        boolean consumed = false;
-
-        x = (int) evt.getX();
-        y = (int) (height - evt.getY());
-
-        switch (evt.getType()) {
-           case DOWN:
-               consumed = nic.processMouseEvent(x, y, 0, 0, false);
-               isDragging = true;
-               niftyOwnsDragging = consumed;
-               if (consumed){
-                   evt.setConsumed();
-               }
-
-               break;
-
-           case UP:
-               if (niftyOwnsDragging){
-                   consumed = nic.processMouseEvent(x, y, 0, buttonIndex, pressed);
-                   if (consumed){
-                       evt.setConsumed();
-                   }
-               }
-
-               isDragging = false;
-               niftyOwnsDragging = false;
-               break;
-       }
-    }
-    
-    private void onMouseMotionEventQueued(MouseMotionEvent evt, NiftyInputConsumer nic) {
-        x = evt.getX();
-        y = height - evt.getY();
-        nic.processMouseEvent(x, y, evt.getDeltaWheel(), buttonIndex, pressed);
-//        if (nic.processMouseEvent(niftyEvt) /*|| nifty.getCurrentScreen().isMouseOverElement()*/){
-            // Do not consume motion events
-            //evt.setConsumed();
-//        }
-    }
-
-    private void onMouseButtonEventQueued(MouseButtonEvent evt, NiftyInputConsumer nic) {
-        boolean wasPressed = pressed;
-        boolean forwardToNifty = true;
-        
-        buttonIndex = evt.getButtonIndex();
-        pressed = evt.isPressed();
-        
-        // Mouse button raised. End dragging
-        if (wasPressed && !pressed){
-            if (!niftyOwnsDragging){
-                forwardToNifty = false;
-            }
-            isDragging = false;
-            niftyOwnsDragging = false;
-        }
-
-        boolean consumed = false;
-        if (forwardToNifty){
-            consumed = nic.processMouseEvent(x, y, 0, buttonIndex, pressed);
-            if (consumed){
-                evt.setConsumed();
-            }
-        }
-        
-        // Mouse button pressed. Begin dragging
-        if (!wasPressed && pressed){
-            isDragging = true;
-            niftyOwnsDragging = consumed;
-        }
-    }
-
-    private void onKeyEventQueued(KeyInputEvent evt, NiftyInputConsumer nic) {
-        int code = evt.getKeyCode();
-
-        if (code == KeyInput.KEY_LSHIFT || code == KeyInput.KEY_RSHIFT) {
-            shiftDown = evt.isPressed();
-        } else if (code == KeyInput.KEY_LCONTROL || code == KeyInput.KEY_RCONTROL) {
-            ctrlDown = evt.isPressed();
-        }
-        
-        KeyboardInputEvent keyEvt = new KeyboardInputEvent(code,
-                                                           evt.getKeyChar(),
-                                                           evt.isPressed(),
-                                                           shiftDown,
-                                                           ctrlDown);
-
-        if (nic.processKeyboardEvent(keyEvt)){
-            evt.setConsumed();
-        }
-    }
-    
-    public void onMouseMotionEvent(MouseMotionEvent evt) {
-        // Only forward the event if there's actual motion involved.
-        if (inputManager.isCursorVisible() && (evt.getDX() != 0 ||
-                                               evt.getDY() != 0 ||
-                                               evt.getDeltaWheel() != 0)){
-            inputQueue.add(evt);
-        }
-    }
-
-    public void onMouseButtonEvent(MouseButtonEvent evt) {
-        if (inputManager.isCursorVisible() && evt.getButtonIndex() >= 0 && evt.getButtonIndex() <= 2){
-            inputQueue.add(evt);
-        }
-    }
-    
-    public void onJoyAxisEvent(JoyAxisEvent evt) {
-    }
-
-    public void onJoyButtonEvent(JoyButtonEvent evt) {
-    }
-    
-    public void onKeyEvent(KeyInputEvent evt) {
-        inputQueue.add(evt);
-    }
-    
-    public void onTouchEvent(TouchEvent evt) {     
-        inputQueue.add(evt);
-    }
-
-    public void forwardEvents(NiftyInputConsumer nic) {
-        int queueSize = inputQueue.size();
-
-        for (int i = 0; i < queueSize; i++){
-            InputEvent evt = inputQueue.get(i);
-            if (evt instanceof MouseMotionEvent){
-                onMouseMotionEventQueued( (MouseMotionEvent)evt, nic);
-            }else if (evt instanceof MouseButtonEvent){
-                onMouseButtonEventQueued( (MouseButtonEvent)evt, nic);
-            }else if (evt instanceof KeyInputEvent){
-                onKeyEventQueued( (KeyInputEvent)evt, nic);
-            }else if (evt instanceof TouchEvent){
-                onTouchEventQueued( (TouchEvent)evt, nic);
-            }
-        }
-
-        inputQueue.clear();
-    }
-    
-    
-}
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.niftygui;
+
+import com.jme3.input.InputManager;
+import com.jme3.input.KeyInput;
+import com.jme3.input.RawInputListener;
+import com.jme3.input.SoftTextDialogInput;
+import com.jme3.input.controls.SoftTextDialogInputListener;
+import com.jme3.input.event.*;
+import com.jme3.system.JmeSystem;
+import de.lessvoid.nifty.Nifty;
+import de.lessvoid.nifty.NiftyInputConsumer;
+import de.lessvoid.nifty.controls.TextField;
+import de.lessvoid.nifty.controls.nullobjects.TextFieldNull;
+import de.lessvoid.nifty.elements.Element;
+import de.lessvoid.nifty.tools.resourceloader.NiftyResourceLoader;
+import de.lessvoid.nifty.input.keyboard.KeyboardInputEvent;
+import de.lessvoid.nifty.spi.input.InputSystem;
+import java.util.ArrayList;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public class InputSystemJme implements InputSystem, RawInputListener {
+
+    private final ArrayList<InputEvent> inputQueue = new ArrayList<InputEvent>();
+    private InputManager inputManager;
+    private boolean isDragging = false, niftyOwnsDragging = false;
+    private boolean pressed = false;
+    private int buttonIndex;
+    private int x, y;
+    private int height;
+    private boolean shiftDown = false;
+    private boolean ctrlDown = false;
+    private Nifty nifty;
+
+    public InputSystemJme(InputManager inputManager) {
+        this.inputManager = inputManager;
+    }
+
+    public void setResourceLoader(NiftyResourceLoader niftyResourceLoader) {
+    }
+
+    public void setNifty(Nifty nifty) {
+        this.nifty = nifty;
+    }
+
+    /**
+     * @param height The height of the viewport. Used to convert
+     * buttom-left origin to upper-left origin.
+     */
+    public void setHeight(int height) {
+        this.height = height;
+    }
+
+    public void setMousePosition(int x, int y) {
+    }
+
+    public void beginInput() {
+    }
+
+    public void endInput() {
+        boolean result = nifty.update();
+    }
+
+    private void onTouchEventQueued(TouchEvent evt, NiftyInputConsumer nic) {
+        boolean consumed = false;
+
+        x = (int) evt.getX();
+        y = (int) (height - evt.getY());
+
+        if (!inputManager.getSimulateMouse()) {            
+            switch (evt.getType()) {
+                case DOWN:
+                    consumed = nic.processMouseEvent(x, y, 0, 0, true);
+                    isDragging = true;
+                    niftyOwnsDragging = consumed;
+                    if (consumed) {
+                        evt.setConsumed();
+                    }
+
+                    break;
+
+                case UP:
+                    if (niftyOwnsDragging) {
+                        consumed = nic.processMouseEvent(x, y, 0, 0, false);
+                        if (consumed) {
+                            evt.setConsumed();
+                        }
+                    }
+
+                    isDragging = false;
+                    niftyOwnsDragging = false;
+
+                    if (consumed) {
+                        processSoftKeyboard();
+                    }
+
+                    break;
+            }
+        }
+    }
+
+    private void onMouseMotionEventQueued(MouseMotionEvent evt, NiftyInputConsumer nic) {
+        x = evt.getX();
+        y = height - evt.getY();
+        nic.processMouseEvent(x, y, evt.getDeltaWheel(), buttonIndex, pressed);
+//        if (nic.processMouseEvent(niftyEvt) /*|| nifty.getCurrentScreen().isMouseOverElement()*/){
+        // Do not consume motion events
+        //evt.setConsumed();
+//        }
+    }
+
+    private void onMouseButtonEventQueued(MouseButtonEvent evt, NiftyInputConsumer nic) {
+        boolean wasPressed = pressed;
+        boolean forwardToNifty = true;
+
+        buttonIndex = evt.getButtonIndex();
+        pressed = evt.isPressed();
+
+        // Mouse button raised. End dragging
+        if (wasPressed && !pressed) {
+            if (!niftyOwnsDragging) {
+                forwardToNifty = false;
+            }
+            isDragging = false;
+            niftyOwnsDragging = false;
+        }
+
+        boolean consumed = false;
+        if (forwardToNifty) {
+            consumed = nic.processMouseEvent(x, y, 0, buttonIndex, pressed);
+            if (consumed) {
+                evt.setConsumed();
+            }
+        }
+
+        // Mouse button pressed. Begin dragging
+        if (!wasPressed && pressed) {
+            isDragging = true;
+            niftyOwnsDragging = consumed;
+        }
+
+        if (consumed && pressed) {
+            processSoftKeyboard();
+        }
+
+    }
+
+    private void onKeyEventQueued(KeyInputEvent evt, NiftyInputConsumer nic) {
+        int code = evt.getKeyCode();
+
+        if (code == KeyInput.KEY_LSHIFT || code == KeyInput.KEY_RSHIFT) {
+            shiftDown = evt.isPressed();
+        } else if (code == KeyInput.KEY_LCONTROL || code == KeyInput.KEY_RCONTROL) {
+            ctrlDown = evt.isPressed();
+        }
+
+        KeyboardInputEvent keyEvt = new KeyboardInputEvent(code,
+                evt.getKeyChar(),
+                evt.isPressed(),
+                shiftDown,
+                ctrlDown);
+
+        if (nic.processKeyboardEvent(keyEvt)) {
+            evt.setConsumed();
+        }
+    }
+
+    public void onMouseMotionEvent(MouseMotionEvent evt) {
+        // Only forward the event if there's actual motion involved.
+        if (inputManager.isCursorVisible() && (evt.getDX() != 0
+                || evt.getDY() != 0
+                || evt.getDeltaWheel() != 0)) {
+            inputQueue.add(evt);
+        }
+    }
+
+    public void onMouseButtonEvent(MouseButtonEvent evt) {
+        if (inputManager.isCursorVisible() && evt.getButtonIndex() >= 0 && evt.getButtonIndex() <= 2) {
+            inputQueue.add(evt);
+        }
+    }
+
+    public void onJoyAxisEvent(JoyAxisEvent evt) {
+    }
+
+    public void onJoyButtonEvent(JoyButtonEvent evt) {
+    }
+
+    public void onKeyEvent(KeyInputEvent evt) {
+        inputQueue.add(evt);
+    }
+
+    public void onTouchEvent(TouchEvent evt) {
+        inputQueue.add(evt);
+    }
+
+    public void forwardEvents(NiftyInputConsumer nic) {
+        int queueSize = inputQueue.size();
+
+        for (int i = 0; i < queueSize; i++) {
+            InputEvent evt = inputQueue.get(i);
+            if (evt instanceof MouseMotionEvent) {
+                onMouseMotionEventQueued((MouseMotionEvent) evt, nic);
+            } else if (evt instanceof MouseButtonEvent) {
+                onMouseButtonEventQueued((MouseButtonEvent) evt, nic);
+            } else if (evt instanceof KeyInputEvent) {
+                onKeyEventQueued((KeyInputEvent) evt, nic);
+            } else if (evt instanceof TouchEvent) {
+                onTouchEventQueued((TouchEvent) evt, nic);
+            }
+        }
+
+        inputQueue.clear();
+    }
+
+    private void processSoftKeyboard() {
+        SoftTextDialogInput softTextDialogInput = JmeSystem.getSoftTextDialogInput();
+        if (softTextDialogInput != null) {
+
+            Element element = nifty.getCurrentScreen().getFocusHandler().getKeyboardFocusElement();
+            if (element != null) {
+                final TextField textField = element.getNiftyControl(TextField.class);
+                if (textField != null && !(textField instanceof TextFieldNull)) {
+                    Logger.getLogger(InputSystemJme.class.getName()).log(Level.INFO, "Current TextField: {0}", textField.getId());
+                    String initialValue = textField.getText();
+                    if (initialValue == null) {
+                        initialValue = "";
+                    }
+
+                    softTextDialogInput.requestDialog(SoftTextDialogInput.TEXT_ENTRY_DIALOG, "Enter Text", initialValue, new SoftTextDialogInputListener() {
+
+                        public void onSoftText(int action, String text) {
+                            if (action == SoftTextDialogInputListener.COMPLETE) {
+                                textField.setText(text);
+                            }
+                        }
+                    });
+                }
+            }
+        }
+
+    }
+}
diff --git a/engine/src/niftygui/com/jme3/niftygui/RenderDeviceJme.java b/engine/src/niftygui/com/jme3/niftygui/RenderDeviceJme.java
index 8977ed6..1f36a97 100644
--- a/engine/src/niftygui/com/jme3/niftygui/RenderDeviceJme.java
+++ b/engine/src/niftygui/com/jme3/niftygui/RenderDeviceJme.java
@@ -29,7 +29,6 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-
 package com.jme3.niftygui;
 
 import com.jme3.font.BitmapText;
@@ -60,140 +59,148 @@
 import java.util.HashMap;
 
 public class RenderDeviceJme implements RenderDevice {
-
+    
     private NiftyJmeDisplay display;
     private RenderManager rm;
     private Renderer r;
-    
     private HashMap<String, BitmapText> textCacheLastFrame = new HashMap<String, BitmapText>();
     private HashMap<String, BitmapText> textCacheCurrentFrame = new HashMap<String, BitmapText>();
-
     private final Quad quad = new Quad(1, -1, true);
     private final Geometry quadGeom = new Geometry("nifty-quad", quad);
     private final Material niftyMat;
-
+    private final Material niftyQuadMat;
+    private final Material niftyQuadGradMat;    
     private boolean clipWasSet = false;
     private BlendMode blendMode = null;
-
     private VertexBuffer quadDefaultTC = quad.getBuffer(Type.TexCoord);
     private VertexBuffer quadModTC = quadDefaultTC.clone();
     private VertexBuffer quadColor;
-
     private Matrix4f tempMat = new Matrix4f();
     private ColorRGBA tempColor = new ColorRGBA();
-
-    public RenderDeviceJme(NiftyJmeDisplay display){
+    
+    public RenderDeviceJme(NiftyJmeDisplay display) {
         this.display = display;
-
+        
         quadColor = new VertexBuffer(Type.Color);
         quadColor.setNormalized(true);
         ByteBuffer bb = BufferUtils.createByteBuffer(4 * 4);
         quadColor.setupData(Usage.Stream, 4, Format.UnsignedByte, bb);
         quad.setBuffer(quadColor);
-
+        
         quadModTC.setUsage(Usage.Stream);
-
-        niftyMat = new Material(display.getAssetManager(), "Common/MatDefs/Nifty/Nifty.j3md");
+        
+        //Color + texture color material for text and images
+        niftyMat = new Material(display.getAssetManager(), "Common/MatDefs/Nifty/NiftyTex.j3md");
         niftyMat.getAdditionalRenderState().setDepthTest(false);
+        //Color material for uniform colored quads
+        niftyQuadMat = new Material(display.getAssetManager(), "Common/MatDefs/Nifty/NiftyQuad.j3md");
+        niftyQuadMat.getAdditionalRenderState().setDepthTest(false);        
+        
+        //vertex color only for gradient quads (although i didn't find a way in nifty to make a gradient using vertex color)
+        niftyQuadGradMat = new Material(display.getAssetManager(), "Common/MatDefs/Nifty/NiftyQuadGrad.j3md");
+        niftyQuadGradMat.getAdditionalRenderState().setDepthTest(false);        
+        
     }
-
+    
     public void setResourceLoader(NiftyResourceLoader niftyResourceLoader) {
     }
-
-    public void setRenderManager(RenderManager rm){
+    
+    public void setRenderManager(RenderManager rm) {
         this.rm = rm;
         this.r = rm.getRenderer();
     }
 
     // TODO: Cursor support
-    public MouseCursor createMouseCursor(String str, int x, int y){
+    public MouseCursor createMouseCursor(String str, int x, int y) {
         return new MouseCursor() {
+            
             public void dispose() {
             }
         };
     }
-
-    public void enableMouseCursor(MouseCursor cursor){
+    
+    public void enableMouseCursor(MouseCursor cursor) {
     }
-
-    public void disableMouseCursor(){
+    
+    public void disableMouseCursor() {
     }
-
+    
     public RenderImage createImage(String filename, boolean linear) {
         return new RenderImageJme(filename, linear, display);
     }
-
+    
     public RenderFont createFont(String filename) {
         return new RenderFontJme(filename, display);
     }
-
+    
     public void beginFrame() {
     }
-
+    
     public void endFrame() {
         HashMap<String, BitmapText> temp = textCacheLastFrame;
         textCacheLastFrame = textCacheCurrentFrame;
         textCacheCurrentFrame = temp;
         textCacheCurrentFrame.clear();
-        
+
 //        System.exit(1);
     }
-
+    
     public int getWidth() {
         return display.getWidth();
     }
-
+    
     public int getHeight() {
         return display.getHeight();
     }
-
+    
     public void clear() {
     }
-
+    
     public void setBlendMode(BlendMode blendMode) {
-        if (this.blendMode != blendMode){
+        if (this.blendMode != blendMode) {
             this.blendMode = blendMode;
         }
     }
-
-    private RenderState.BlendMode convertBlend(){
-        if (blendMode == null)
+    
+    private RenderState.BlendMode convertBlend() {
+        if (blendMode == null) {
             return RenderState.BlendMode.Off;
-        else if (blendMode == BlendMode.BLEND)
+        } else if (blendMode == BlendMode.BLEND) {
             return RenderState.BlendMode.Alpha;
-        else if (blendMode == BlendMode.MULIPLY)
+        } else if (blendMode == BlendMode.MULIPLY) {
             return RenderState.BlendMode.Modulate;
-        else
+        } else {
             throw new UnsupportedOperationException();
-    }
-
-    private int convertColor(Color color){
-        int color2 = 0;
-        color2 |= ((int)(255.0 * color.getAlpha())) << 24;
-        color2 |= ((int)(255.0 * color.getBlue())) << 16;
-        color2 |= ((int)(255.0 * color.getGreen())) << 8;
-        color2 |= ((int)(255.0 * color.getRed()));
-        return color2;
-    }
-
-    private ColorRGBA convertColor(Color inColor, ColorRGBA outColor){
-        return outColor.set(inColor.getRed(), inColor.getGreen(), inColor.getBlue(), inColor.getAlpha());
-    }
-
-    private void setColor(Color color){
-        ByteBuffer buf = (ByteBuffer) quadColor.getData();
-        buf.rewind();
-
-        int color2 = convertColor(color);
-        buf.putInt(color2);
-        buf.putInt(color2);
-        buf.putInt(color2);
-        buf.putInt(color2);
-
-        buf.flip();
-        quadColor.updateData(buf);
+        }
     }
     
+    private int convertColor(Color color) {
+        int color2 = 0;
+        color2 |= ((int) (255.0 * color.getAlpha())) << 24;
+        color2 |= ((int) (255.0 * color.getBlue())) << 16;
+        color2 |= ((int) (255.0 * color.getGreen())) << 8;
+        color2 |= ((int) (255.0 * color.getRed()));
+        return color2;
+    }
+    
+    private ColorRGBA convertColor(Color inColor, ColorRGBA outColor) {
+        return outColor.set(inColor.getRed(), inColor.getGreen(), inColor.getBlue(), inColor.getAlpha());
+    }
+    
+//    private void setColor(Color color) {
+//        ByteBuffer buf = (ByteBuffer) quadColor.getData();
+//        buf.rewind();
+//        
+//        int color2 = convertColor(color);
+//        buf.putInt(color2);
+//        buf.putInt(color2);
+//        buf.putInt(color2);
+//        buf.putInt(color2);
+//        
+//        buf.flip();
+//        quadColor.updateData(buf);
+//    }
+
     /**
      * 
      * @param font
@@ -205,22 +212,23 @@
      * @deprecated use renderFont(RenderFont font, String str, int x, int y, Color color, float sizeX, float sizeY) instead
      */
     @Deprecated
-    public void renderFont(RenderFont font, String str, int x, int y, Color color, float size){        
+    public void renderFont(RenderFont font, String str, int x, int y, Color color, float size) {        
         renderFont(font, str, x, y, color, size, size);
     }
- 
+    
     @Override
-    public void renderFont(RenderFont font, String str, int x, int y, Color color, float sizeX, float sizeY){        
-        //TODO find out what the f1 param is for
-        if (str.length() == 0)
+    public void renderFont(RenderFont font, String str, int x, int y, Color color, float sizeX, float sizeY) {        
+        if (str.length() == 0) {
             return;
-
-        if (font instanceof RenderFontNull)
+        }
+        
+        if (font instanceof RenderFontNull) {
             return;
-
+        }
+        
         RenderFontJme jmeFont = (RenderFontJme) font;
         
-        String key = font+str+color.getColorString();
+        String key = font + str + color.getColorString();
         BitmapText text = textCacheLastFrame.get(key);
         if (text == null) {
             text = jmeFont.createText();
@@ -228,166 +236,149 @@
             text.updateLogicalState(0);
         }
         textCacheCurrentFrame.put(key, text);
-
-        niftyMat.setColor("Color", convertColor(color, tempColor));
-        niftyMat.setBoolean("UseTex", true);
+        
+        niftyMat.setColor("Color", convertColor(color, tempColor));        
         niftyMat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
 //        niftyMat.getAdditionalRenderState().setBlendMode(convertBlend());
         text.setMaterial(niftyMat);
-
-        float width = text.getLineWidth();
-        float height = text.getLineHeight();
-
-        float x0 = x + 0.5f * width  * (1f - sizeX);
-        float y0 = y + 0.5f * height * (1f - sizeY);
-
+        
         tempMat.loadIdentity();
-        tempMat.setTranslation(x0, getHeight() - y0, 0);
+        tempMat.setTranslation(x, getHeight() - y, 0);
         tempMat.setScale(sizeX, sizeY, 0);
-
+        
         rm.setWorldMatrix(tempMat);
         text.render(rm);
-        
+
 //        System.out.println("renderFont");
     }
-
+    
     public void renderImage(RenderImage image, int x, int y, int w, int h,
-                            int srcX, int srcY, int srcW, int srcH,
-                            Color color, float scale,
-                            int centerX, int centerY){
+            int srcX, int srcY, int srcW, int srcH,
+            Color color, float scale,
+            int centerX, int centerY) {
         RenderImageJme jmeImage = (RenderImageJme) image;
         Texture2D texture = jmeImage.getTexture();
-
+        
         niftyMat.getAdditionalRenderState().setBlendMode(convertBlend());
-        niftyMat.setColor("Color", ColorRGBA.White);
-        niftyMat.setTexture("Texture", texture);
-        niftyMat.setBoolean("UseTex", true);
-        setColor(color);
-
-        float imageWidth  = jmeImage.getWidth();
+        niftyMat.setColor("Color", convertColor(color, tempColor));
+        niftyMat.setTexture("Texture", texture);        
+        //setColor(color);
+        
+        float imageWidth = jmeImage.getWidth();
         float imageHeight = jmeImage.getHeight();
         FloatBuffer texCoords = (FloatBuffer) quadModTC.getData();
-
+        
         float startX = srcX / imageWidth;
         float startY = srcY / imageHeight;
-        float endX   = startX + (srcW / imageWidth);
-        float endY   = startY + (srcH / imageHeight);
-
+        float endX = startX + (srcW / imageWidth);
+        float endY = startY + (srcH / imageHeight);
+        
         startY = 1f - startY;
-        endY   = 1f - endY;
-
+        endY = 1f - endY;
+        
         texCoords.rewind();
         texCoords.put(startX).put(startY);
-        texCoords.put(endX)  .put(startY);
-        texCoords.put(endX)  .put(endY);
+        texCoords.put(endX).put(startY);
+        texCoords.put(endX).put(endY);
         texCoords.put(startX).put(endY);
         texCoords.flip();
         quadModTC.updateData(texCoords);
-
+        
         quad.clearBuffer(Type.TexCoord);
         quad.setBuffer(quadModTC);
-
+        
         float x0 = centerX + (x - centerX) * scale;
         float y0 = centerY + (y - centerY) * scale;
-
+        
         tempMat.loadIdentity();
         tempMat.setTranslation(x0, getHeight() - y0, 0);
         tempMat.setScale(w * scale, h * scale, 0);
-
+        
         rm.setWorldMatrix(tempMat);
         niftyMat.render(quadGeom, rm);
 //        
 //        System.out.println("renderImage (Sub)");
     }
-
+    
     public void renderImage(RenderImage image, int x, int y, int width, int height,
-                       Color color, float imageScale){
-
+            Color color, float imageScale) {
+        
         RenderImageJme jmeImage = (RenderImageJme) image;
-
+        
         niftyMat.getAdditionalRenderState().setBlendMode(convertBlend());
-        niftyMat.setColor("Color", ColorRGBA.White);
-        niftyMat.setTexture("Texture", jmeImage.getTexture());
-        niftyMat.setBoolean("UseTex", true);
-        setColor(color);
-
+        niftyMat.setColor("Color", convertColor(color, tempColor));
+        niftyMat.setTexture("Texture", jmeImage.getTexture());        
+        //setColor(color);
+        
         quad.clearBuffer(Type.TexCoord);
         quad.setBuffer(quadDefaultTC);
-
-        float x0 = x + 0.5f * width  * (1f - imageScale);
+        
+        float x0 = x + 0.5f * width * (1f - imageScale);
         float y0 = y + 0.5f * height * (1f - imageScale);
-
+        
         tempMat.loadIdentity();
         tempMat.setTranslation(x0, getHeight() - y0, 0);
         tempMat.setScale(width * imageScale, height * imageScale, 0);
-
+        
         rm.setWorldMatrix(tempMat);
         niftyMat.render(quadGeom, rm);
 //        
 //        System.out.println("renderImage");
     }
-
-    public void renderQuad(int x, int y, int width, int height, Color color){
-        niftyMat.getAdditionalRenderState().setBlendMode(convertBlend());
-        niftyMat.setColor("Color", ColorRGBA.White);
-        niftyMat.clearParam("Texture");
-        niftyMat.setBoolean("UseTex", false);
-        setColor(color);
-
-        tempMat.loadIdentity();
-        tempMat.setTranslation(x, getHeight() - y, 0);
-        tempMat.setScale(width, height, 0);
-
-        rm.setWorldMatrix(tempMat);
-        niftyMat.render(quadGeom, rm);
-        
+    
+    public void renderQuad(int x, int y, int width, int height, Color color) {
+        if (color.getAlpha() > 0) {
+            niftyQuadMat.getAdditionalRenderState().setBlendMode(convertBlend());
+            niftyQuadMat.setColor("Color", convertColor(color, tempColor));                        
+            
+            tempMat.loadIdentity();
+            tempMat.setTranslation(x, getHeight() - y, 0);
+            tempMat.setScale(width, height, 0);
+            
+            rm.setWorldMatrix(tempMat);
+            niftyQuadMat.render(quadGeom, rm);
+        }
 //        System.out.println("renderQuad (Solid)");
     }
-
+    
     public void renderQuad(int x, int y, int width, int height,
-                           Color topLeft, Color topRight, Color bottomRight, Color bottomLeft) {
+            Color topLeft, Color topRight, Color bottomRight, Color bottomLeft) {
         
         ByteBuffer buf = (ByteBuffer) quadColor.getData();
         buf.rewind();
         
         buf.putInt(convertColor(topRight));
         buf.putInt(convertColor(topLeft));
-
+        
         buf.putInt(convertColor(bottomLeft));
         buf.putInt(convertColor(bottomRight));
         
         buf.flip();
         quadColor.updateData(buf);
         
-        niftyMat.getAdditionalRenderState().setBlendMode(convertBlend());
-        niftyMat.setColor("Color", ColorRGBA.White);
-        niftyMat.clearParam("Texture");
-        niftyMat.setBoolean("UseTex", false);
-
+        niftyQuadGradMat.getAdditionalRenderState().setBlendMode(convertBlend());      
+        
         tempMat.loadIdentity();
         tempMat.setTranslation(x, getHeight() - y, 0);
         tempMat.setScale(width, height, 0);
-
+        
         rm.setWorldMatrix(tempMat);
-        niftyMat.render(quadGeom, rm);
+        niftyQuadGradMat.render(quadGeom, rm);
 //        
 //        System.out.println("renderQuad (Grad)");
     }
-
-    public void enableClip(int x0, int y0, int x1, int y1){
+    
+    public void enableClip(int x0, int y0, int x1, int y1) {
 //        System.out.println("enableClip");
         clipWasSet = true;
         r.setClipRect(x0, getHeight() - y1, x1 - x0, y1 - y0);
     }
-
+    
     public void disableClip() {
 //        System.out.println("disableClip");
-        if (clipWasSet){
+        if (clipWasSet) {
             r.clearClipRect();
             clipWasSet = false;
         }
     }
-
-    
-
 }
diff --git a/engine/src/ogre/com/jme3/scene/plugins/ogre/MeshLoader.java b/engine/src/ogre/com/jme3/scene/plugins/ogre/MeshLoader.java
index e7f4b10..fc8cc6b 100644
--- a/engine/src/ogre/com/jme3/scene/plugins/ogre/MeshLoader.java
+++ b/engine/src/ogre/com/jme3/scene/plugins/ogre/MeshLoader.java
@@ -712,9 +712,8 @@
         } else if (qName.equals("geometry")
                 || qName.equals("sharedgeometry")) {
             // finish writing to buffers
-            IntMap<VertexBuffer> bufs = mesh.getBuffers();
-            for (Entry<VertexBuffer> entry : bufs) {
-                Buffer data = entry.getValue().getData();
+            for (VertexBuffer buf : mesh.getBufferList().getArray()) {
+                Buffer data = buf.getData();
                 if (data.position() != 0) {
                     data.flip();
                 }
diff --git a/engine/src/terrain/com/jme3/terrain/geomipmap/LODGeomap.java b/engine/src/terrain/com/jme3/terrain/geomipmap/LODGeomap.java
index 3944b98..3348b48 100644
--- a/engine/src/terrain/com/jme3/terrain/geomipmap/LODGeomap.java
+++ b/engine/src/terrain/com/jme3/terrain/geomipmap/LODGeomap.java
@@ -34,6 +34,7 @@
 import com.jme3.export.JmeExporter;
 import com.jme3.export.JmeImporter;
 import com.jme3.math.FastMath;
+import com.jme3.math.Plane;
 import com.jme3.math.Triangle;
 import com.jme3.math.Vector2f;
 import com.jme3.math.Vector3f;
@@ -87,7 +88,7 @@
         IntBuffer ib = writeIndexArrayLodDiff(null, lod, rightLod, topLod, leftLod, bottomLod);
         FloatBuffer bb = BufferUtils.createFloatBuffer(getWidth() * getHeight() * 3);
         FloatBuffer tanb = BufferUtils.createFloatBuffer(getWidth() * getHeight() * 3);
-        writeTangentArray(tanb, bb, texb, scale);
+        writeTangentArray(nb, tanb, bb, texb, scale);
         Mesh m = new Mesh();
         m.setMode(Mode.TriangleStrip);
         m.setBuffer(Type.Position, 3, pb);
@@ -627,7 +628,7 @@
         return num;
     }
 
-    public FloatBuffer[] writeTangentArray(FloatBuffer tangentStore, FloatBuffer binormalStore, FloatBuffer textureBuffer, Vector3f scale) {
+    public FloatBuffer[] writeTangentArray(FloatBuffer normalBuffer, FloatBuffer tangentStore, FloatBuffer binormalStore, FloatBuffer textureBuffer, Vector3f scale) {
         if (!isLoaded()) {
             throw new NullPointerException();
         }
@@ -650,19 +651,31 @@
         }
         binormalStore.rewind();
 
+        Vector3f normal = new Vector3f();
         Vector3f tangent = new Vector3f();
         Vector3f binormal = new Vector3f();
-        Vector3f v1 = new Vector3f();
+        /*Vector3f v1 = new Vector3f();
         Vector3f v2 = new Vector3f();
         Vector3f v3 = new Vector3f();
         Vector2f t1 = new Vector2f();
         Vector2f t2 = new Vector2f();
-        Vector2f t3 = new Vector2f();
-
-        //scale = Vector3f.UNIT_XYZ;
+        Vector2f t3 = new Vector2f();*/
 
         for (int r = 0; r < getHeight(); r++) {
             for (int c = 0; c < getWidth(); c++) {
+                
+                int idx = (r * getWidth() + c) * 3;
+                normal.set(normalBuffer.get(idx), normalBuffer.get(idx+1), normalBuffer.get(idx+2));
+                tangent.set(normal.cross(new Vector3f(0,0,1)));
+                binormal.set(new Vector3f(1,0,0).cross(normal));
+                
+                BufferUtils.setInBuffer(tangent.normalizeLocal(), tangentStore, (r * getWidth() + c)); // save the tangent
+                BufferUtils.setInBuffer(binormal.normalizeLocal(), binormalStore, (r * getWidth() + c)); // save the binormal
+            }
+        }
+
+/*        for (int r = 0; r < getHeight(); r++) {
+            for (int c = 0; c < getWidth(); c++) {
 
                 int texIdx = ((getHeight() - 1 - r) * getWidth() + c) * 2; // pull from the end
                 int texIdxAbove = ((getHeight() - 1 - (r - 1)) * getWidth() + c) * 2; // pull from the end
@@ -702,7 +715,7 @@
                 BufferUtils.setInBuffer(binormal, binormalStore, (r * getWidth() + c)); // save the binormal
             }
         }
-
+        */
         return new FloatBuffer[]{tangentStore, binormalStore};
     }
 
diff --git a/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainPatch.java b/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainPatch.java
index 40cf190..83537af 100644
--- a/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainPatch.java
+++ b/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainPatch.java
@@ -314,13 +314,25 @@
         getMesh().getBuffer(Type.Normal).updateData(newNormalBuffer);
         FloatBuffer newTangentBuffer = null;
         FloatBuffer newBinormalBuffer = null;
-        FloatBuffer[] tb = geomap.writeTangentArray(newTangentBuffer, newBinormalBuffer, (FloatBuffer)getMesh().getBuffer(Type.TexCoord).getData(), getWorldScale());
+        FloatBuffer[] tb = geomap.writeTangentArray(newNormalBuffer, newTangentBuffer, newBinormalBuffer, (FloatBuffer)getMesh().getBuffer(Type.TexCoord).getData(), getWorldScale());
         newTangentBuffer = tb[0];
         newBinormalBuffer = tb[1];
         getMesh().getBuffer(Type.Tangent).updateData(newTangentBuffer);
         getMesh().getBuffer(Type.Binormal).updateData(newBinormalBuffer);
     }
 
+    private void setInBuffer(Mesh mesh, int index, Vector3f normal, Vector3f tangent, Vector3f binormal) {
+        VertexBuffer NB = mesh.getBuffer(Type.Normal);
+        VertexBuffer TB = mesh.getBuffer(Type.Tangent);
+        VertexBuffer BB = mesh.getBuffer(Type.Binormal);
+        BufferUtils.setInBuffer(normal, (FloatBuffer)NB.getData(), index);
+        BufferUtils.setInBuffer(tangent, (FloatBuffer)TB.getData(), index);
+        BufferUtils.setInBuffer(binormal, (FloatBuffer)BB.getData(), index);
+        NB.setUpdateNeeded();
+        TB.setUpdateNeeded();
+        BB.setUpdateNeeded();
+    }
+    
     /**
      * Matches the normals along the edge of the patch with the neighbours.
      * Computes the normals for the right, bottom, left, and top edges of the
@@ -357,158 +369,122 @@
         Vector3f binormal = new Vector3f();
         Vector3f normal = new Vector3f();
 
+        
         int s = this.getSize()-1;
         
         if (right != null) { // right side,    works its way down
             for (int i=0; i<s+1; i++) {
-                rootPoint.set(s, this.getHeightmapHeight(s,i), i);
-                leftPoint.set(s-1, this.getHeightmapHeight(s-1,i), i);
-                rightPoint.set(s+1, right.getHeightmapHeight(1,i), i);
+                rootPoint.set(0, this.getHeightmapHeight(s,i), 0);
+                leftPoint.set(-1, this.getHeightmapHeight(s-1,i), 0);
+                rightPoint.set(1, right.getHeightmapHeight(1,i), 0);
 
                 if (i == 0) { // top point
+                    bottomPoint.set(0, this.getHeightmapHeight(s,i+1), 1);
+                    
                     if (top == null) {
-                        bottomPoint.set(s, this.getHeightmapHeight(s,i+1), i+1);
-                        
-                        averageNormalsTangents(null, rootPoint, leftPoint, bottomPoint, rightPoint, null, null, null, null, null, normal, tangent, binormal);
-                        VertexBuffer tpNB = this.getMesh().getBuffer(Type.Normal);
-                        VertexBuffer rightNB = right.getMesh().getBuffer(Type.Normal);
-                        BufferUtils.setInBuffer(normal, (FloatBuffer)tpNB.getData(), s);
-                        BufferUtils.setInBuffer(normal, (FloatBuffer)rightNB.getData(), 0);
+                        averageNormalsTangents(null, rootPoint, leftPoint, bottomPoint, rightPoint,  normal, tangent, binormal);
+                        setInBuffer(this.getMesh(), s, normal, tangent, binormal);
+                        setInBuffer(right.getMesh(), 0, normal, tangent, binormal);
                     } else {
-                        topPoint.set(s, top.getHeightmapHeight(s,s-1), i-1);
-                        bottomPoint.set(s, this.getHeightmapHeight(s,i+1), i+1);
+                        topPoint.set(0, top.getHeightmapHeight(s,s-1), -1);
                         
-                        averageNormalsTangents(topPoint, rootPoint, leftPoint, bottomPoint, rightPoint, null, null, null, null, null, normal, tangent, binormal);
-                        VertexBuffer tpNB = this.getMesh().getBuffer(Type.Normal);
-                        VertexBuffer rightNB = right.getMesh().getBuffer(Type.Normal);
-                        BufferUtils.setInBuffer(normal, (FloatBuffer)tpNB.getData(), s);
-                        BufferUtils.setInBuffer(normal, (FloatBuffer)rightNB.getData(), 0);
+                        averageNormalsTangents(topPoint, rootPoint, leftPoint, bottomPoint, rightPoint,normal, tangent, binormal);
+                        setInBuffer(this.getMesh(), s, normal, tangent, binormal);
+                        setInBuffer(right.getMesh(), 0, normal, tangent, binormal);
+                        setInBuffer(top.getMesh(), (s+1)*(s+1)-1, normal, tangent, binormal);
                         
                         if (topRight != null) {
-                            VertexBuffer topRightNB = topRight.getMesh().getBuffer(Type.Normal);
-                            BufferUtils.setInBuffer(normal, (FloatBuffer)topRightNB.getData(), (s+1)*s);
-                            topRightNB.setUpdateNeeded();
+                    //        setInBuffer(topRight.getMesh(), (s+1)*s, normal, tangent, binormal);
                         }
                     }
                 } else if (i == s) { // bottom point
+                    topPoint.set(0, this.getHeightmapHeight(s,s-1), -1);
+                    
                     if (bottom == null) {
-                        topPoint.set(s, this.getHeightmapHeight(s,i-1), i-1);
-                        
-                        averageNormalsTangents(topPoint, rootPoint, leftPoint, null, rightPoint, null, null, null, null, null, normal, tangent, binormal);
-                        VertexBuffer tpNB = this.getMesh().getBuffer(Type.Normal);
-                        VertexBuffer rightNB = right.getMesh().getBuffer(Type.Normal);
-                        BufferUtils.setInBuffer(normal, (FloatBuffer)tpNB.getData(), (s+1)*(i+1)-1);
-                        BufferUtils.setInBuffer(normal, (FloatBuffer)rightNB.getData(), (s+1)*(s));
+                        averageNormalsTangents(topPoint, rootPoint, leftPoint, null, rightPoint, normal, tangent, binormal);
+                        setInBuffer(this.getMesh(), (s+1)*(s+1)-1, normal, tangent, binormal);
+                        setInBuffer(right.getMesh(), (s+1)*(s), normal, tangent, binormal);
                     } else {
-                        topPoint.set(s, this.getHeightmapHeight(s,i-1), i-1);
-                        bottomPoint.set(s, bottom.getHeightmapHeight(s,1), i+1);
-                        averageNormalsTangents(topPoint, rootPoint, leftPoint, bottomPoint, rightPoint, null, null, null, null, null, normal, tangent, binormal);
-                        VertexBuffer tpNB = this.getMesh().getBuffer(Type.Normal);
-                        VertexBuffer rightNB = right.getMesh().getBuffer(Type.Normal);
-                        VertexBuffer downNB = bottom.getMesh().getBuffer(Type.Normal);
-
-                        BufferUtils.setInBuffer(normal, (FloatBuffer)tpNB.getData(), (s+1)*(s+1)-1);
-                        BufferUtils.setInBuffer(normal, (FloatBuffer)rightNB.getData(), (s+1)*s);
-                        BufferUtils.setInBuffer(normal, (FloatBuffer)downNB.getData(), s);
+                        bottomPoint.set(0, bottom.getHeightmapHeight(s,1), 1);
+                        averageNormalsTangents(topPoint, rootPoint, leftPoint, bottomPoint, rightPoint, normal, tangent, binormal);
+                        setInBuffer(this.getMesh(), (s+1)*(s+1)-1, normal, tangent, binormal);
+                        setInBuffer(right.getMesh(), (s+1)*s, normal, tangent, binormal);
+                        setInBuffer(bottom.getMesh(), s, normal, tangent, binormal);
                         
                         if (bottomRight != null) {
-                            VertexBuffer bottomRightNB = bottomRight.getMesh().getBuffer(Type.Normal);
-                            BufferUtils.setInBuffer(normal, (FloatBuffer)bottomRightNB.getData(), 0);
-                            bottomRightNB.setUpdateNeeded();
+                   //         setInBuffer(bottomRight.getMesh(), 0, normal, tangent, binormal);
                         }
-                        downNB.setUpdateNeeded();
                     }
                 } else { // all in the middle
-                    topPoint.set(s, this.getHeightmapHeight(s,i-1), i-1);
-                    bottomPoint.set(s, this.getHeightmapHeight(s,i+1), i+1);
-                    averageNormalsTangents(topPoint, rootPoint, leftPoint, bottomPoint, rightPoint, null, null, null, null, null, normal, tangent, binormal);
-                    VertexBuffer tpNB = this.getMesh().getBuffer(Type.Normal);
-                    VertexBuffer rightNB = right.getMesh().getBuffer(Type.Normal);
-                    BufferUtils.setInBuffer(normal, (FloatBuffer)tpNB.getData(), (s+1)*(i+1)-1);
-                    BufferUtils.setInBuffer(normal, (FloatBuffer)rightNB.getData(), (s+1)*(i));
+                    topPoint.set(0, this.getHeightmapHeight(s,i-1), -1);
+                    bottomPoint.set(0, this.getHeightmapHeight(s,i+1), 1);
+                    averageNormalsTangents(topPoint, rootPoint, leftPoint, bottomPoint, rightPoint, normal, tangent, binormal);
+                    setInBuffer(this.getMesh(), (s+1)*(i+1)-1, normal, tangent, binormal);
+                    setInBuffer(right.getMesh(), (s+1)*(i), normal, tangent, binormal);
                 }
             }
-            right.getMesh().getBuffer(Type.Normal).setUpdateNeeded();
         }
 
         if (left != null) { // left side,    works its way down
             for (int i=0; i<s+1; i++) {
-                rootPoint.set(0, this.getHeightmapHeight(0,i), i);
-                leftPoint.set(-1, left.getHeightmapHeight(s-1,i), i);
-                rightPoint.set(1, this.getHeightmapHeight(1,i), i);
+                rootPoint.set(0, this.getHeightmapHeight(0,i), 0);
+                leftPoint.set(-1, left.getHeightmapHeight(s-1,i), 0);
+                rightPoint.set(1, this.getHeightmapHeight(1,i), 0);
                 
                 if (i == 0) { // top point
+                    bottomPoint.set(0, this.getHeightmapHeight(0,i+1), 1);
+                    
                     if (top == null) {
-                        bottomPoint.set(0, this.getHeightmapHeight(0,i+1), i+1);
-                        averageNormalsTangents(null, rootPoint, leftPoint, bottomPoint, rightPoint, null, null, null, null, null, normal, tangent, binormal);
-                        VertexBuffer tpNB = this.getMesh().getBuffer(Type.Normal);
-                        VertexBuffer leftNB = left.getMesh().getBuffer(Type.Normal);
-                        BufferUtils.setInBuffer(normal, (FloatBuffer)tpNB.getData(), 0);
-                        BufferUtils.setInBuffer(normal, (FloatBuffer)leftNB.getData(), s);
+                        averageNormalsTangents(null, rootPoint, leftPoint, bottomPoint, rightPoint, normal, tangent, binormal);
+                        setInBuffer(this.getMesh(), 0, normal, tangent, binormal);
+                        setInBuffer(left.getMesh(), s, normal, tangent, binormal);
                     } else {
-                        topPoint.set(0, top.getHeightmapHeight(0,s-1), i-1);
-                        bottomPoint.set(0, this.getHeightmapHeight(0,i+1), i+1);
+                        topPoint.set(0, top.getHeightmapHeight(0,s-1), -1);
                         
-                        averageNormalsTangents(topPoint, rootPoint, leftPoint, bottomPoint, rightPoint, null, null, null, null, null, normal, tangent, binormal);
-                        VertexBuffer tpNB = this.getMesh().getBuffer(Type.Normal);
-                        VertexBuffer leftNB = left.getMesh().getBuffer(Type.Normal);
-                        BufferUtils.setInBuffer(normal, (FloatBuffer)tpNB.getData(), 0);
-                        BufferUtils.setInBuffer(normal, (FloatBuffer)leftNB.getData(), s);
+                        averageNormalsTangents(topPoint, rootPoint, leftPoint, bottomPoint, rightPoint, normal, tangent, binormal);
+                        setInBuffer(this.getMesh(), 0, normal, tangent, binormal);
+                        setInBuffer(left.getMesh(), s, normal, tangent, binormal);
+                        setInBuffer(top.getMesh(), (s+1)*s, normal, tangent, binormal);
                         
                         if (topLeft != null) {
-                            VertexBuffer topLeftNB = topLeft.getMesh().getBuffer(Type.Normal);
-                            BufferUtils.setInBuffer(normal, (FloatBuffer)topLeftNB.getData(), (s+1)*(s+1)-1);
-                            topLeftNB.setUpdateNeeded();
+                     //       setInBuffer(topLeft.getMesh(), (s+1)*(s+1)-1, normal, tangent, binormal);
                         }
                     }
                 } else if (i == s) { // bottom point
+                    topPoint.set(0, this.getHeightmapHeight(0,i-1), -1);
+                    
                     if (bottom == null) {
-                        topPoint.set(0, this.getHeightmapHeight(0,i-1), i-1);
-                        
-                        averageNormalsTangents(topPoint, rootPoint, leftPoint, null, rightPoint, null, null, null, null, null, normal, tangent, binormal);
-                        VertexBuffer tpNB = this.getMesh().getBuffer(Type.Normal);
-                        VertexBuffer leftNB = left.getMesh().getBuffer(Type.Normal);
-                        BufferUtils.setInBuffer(normal, (FloatBuffer)tpNB.getData(), (s+1)*(s));
-                        BufferUtils.setInBuffer(normal, (FloatBuffer)leftNB.getData(), (s+1)*(i+1)-1);
+                        averageNormalsTangents(topPoint, rootPoint, leftPoint, null, rightPoint, normal, tangent, binormal);
+                        setInBuffer(this.getMesh(), (s+1)*(s), normal, tangent, binormal);
+                        setInBuffer(left.getMesh(), (s+1)*(s+1)-1, normal, tangent, binormal);
                     } else {
-                        topPoint.set(0, this.getHeightmapHeight(0,i-1), i-1);
-                        bottomPoint.set(0, bottom.getHeightmapHeight(0,1), i+1);
+                        bottomPoint.set(0, bottom.getHeightmapHeight(0,1), 1);
                         
-                        averageNormalsTangents(topPoint, rootPoint, leftPoint, bottomPoint, rightPoint, null, null, null, null, null, normal, tangent, binormal);
-                        VertexBuffer tpNB = this.getMesh().getBuffer(Type.Normal);
-                        VertexBuffer leftNB = left.getMesh().getBuffer(Type.Normal);
-                        VertexBuffer downNB = bottom.getMesh().getBuffer(Type.Normal);
-
-                        BufferUtils.setInBuffer(normal, (FloatBuffer)tpNB.getData(), (s+1)*(s));
-                        BufferUtils.setInBuffer(normal, (FloatBuffer)leftNB.getData(), (s+1)*(i+1)-1);
-                        BufferUtils.setInBuffer(normal, (FloatBuffer)downNB.getData(), 0);
+                        averageNormalsTangents(topPoint, rootPoint, leftPoint, bottomPoint, rightPoint, normal, tangent, binormal);
+                        setInBuffer(this.getMesh(), (s+1)*(s), normal, tangent, binormal);
+                        setInBuffer(left.getMesh(), (s+1)*(s+1)-1, normal, tangent, binormal);
+                        setInBuffer(bottom.getMesh(), 0, normal, tangent, binormal);
                         
                         if (bottomLeft != null) {
-                            VertexBuffer bottomLeftNB = bottomLeft.getMesh().getBuffer(Type.Normal);
-                            BufferUtils.setInBuffer(normal, (FloatBuffer)bottomLeftNB.getData(), s);
-                            bottomLeftNB.setUpdateNeeded();
+                     //       setInBuffer(bottomLeft.getMesh(), s, normal, tangent, binormal);
                         }
-                        downNB.setUpdateNeeded();
                     }
                 } else { // all in the middle
-                    topPoint.set(0, this.getHeightmapHeight(0,i-1), i-1);
-                    bottomPoint.set(0, this.getHeightmapHeight(0,i+1), i+1);
+                    topPoint.set(0, this.getHeightmapHeight(0,i-1), -1);
+                    bottomPoint.set(0, this.getHeightmapHeight(0,i+1), 1);
                     
-                    averageNormalsTangents(topPoint, rootPoint, leftPoint, bottomPoint, rightPoint, null, null, null, null, null, normal, tangent, binormal);
-                    VertexBuffer tpNB = this.getMesh().getBuffer(Type.Normal);
-                    VertexBuffer leftNB = left.getMesh().getBuffer(Type.Normal);
-                    BufferUtils.setInBuffer(normal, (FloatBuffer)tpNB.getData(), (s+1)*(i));
-                    BufferUtils.setInBuffer(normal, (FloatBuffer)leftNB.getData(), (s+1)*(i+1)-1);
+                    averageNormalsTangents(topPoint, rootPoint, leftPoint, bottomPoint, rightPoint, normal, tangent, binormal);
+                    setInBuffer(this.getMesh(), (s+1)*(i), normal, tangent, binormal);
+                    setInBuffer(left.getMesh(), (s+1)*(i+1)-1, normal, tangent, binormal);
                 }
             }
-            left.getMesh().getBuffer(Type.Normal).setUpdateNeeded();
         }
-        
+
         if (top != null) { // top side,    works its way right
             for (int i=0; i<s+1; i++) {
-                rootPoint.set(i, this.getHeightmapHeight(i,0), 0);
-                topPoint.set(i, top.getHeightmapHeight(i,s-1), -1);
-                bottomPoint.set(i, this.getHeightmapHeight(i,1), 1);
+                rootPoint.set(0, this.getHeightmapHeight(i,0), 0);
+                topPoint.set(0, top.getHeightmapHeight(i,s-1), -1);
+                bottomPoint.set(0, this.getHeightmapHeight(i,1), 1);
                 
                 if (i == 0) { // left corner
                     // handled by left side pass
@@ -518,49 +494,39 @@
                     // handled by this patch when it does its right side
                     
                 } else { // all in the middle
-                    leftPoint.set(i-1, this.getHeightmapHeight(i-1,0), 0);
-                    rightPoint.set(i+1, this.getHeightmapHeight(i+1,0), 0);
-                    averageNormalsTangents(topPoint, rootPoint, leftPoint, bottomPoint, rightPoint, null, null, null, null, null, normal, tangent, binormal);
-                    VertexBuffer tpNB = this.getMesh().getBuffer(Type.Normal);
-                    BufferUtils.setInBuffer(normal, (FloatBuffer)tpNB.getData(), i);
-                    VertexBuffer topNB = top.getMesh().getBuffer(Type.Normal);
-                    BufferUtils.setInBuffer(normal, (FloatBuffer)topNB.getData(), (s+1)*(s)+i);
+                    leftPoint.set(-1, this.getHeightmapHeight(i-1,0), 0);
+                    rightPoint.set(1, this.getHeightmapHeight(i+1,0), 0);
+                    averageNormalsTangents(topPoint, rootPoint, leftPoint, bottomPoint, rightPoint, normal, tangent, binormal);
+                    setInBuffer(this.getMesh(), i, normal, tangent, binormal);
+                    setInBuffer(top.getMesh(), (s+1)*(s)+i, normal, tangent, binormal);
                 }
             }
-            top.getMesh().getBuffer(Type.Normal).setUpdateNeeded();
             
         }
         
         if (bottom != null) { // bottom side,    works its way right
             for (int i=0; i<s+1; i++) {
-                rootPoint.set(i, this.getHeightmapHeight(i,s), s);
-                topPoint.set(i, this.getHeightmapHeight(i,s-1), s-1);
-                bottomPoint.set(i, bottom.getHeightmapHeight(i,1), s+1);
+                rootPoint.set(0, this.getHeightmapHeight(i,s), 0);
+                topPoint.set(0, this.getHeightmapHeight(i,s-1), -1);
+                bottomPoint.set(0, bottom.getHeightmapHeight(i,1), 1);
 
                 if (i == 0) { // left
                     // handled by the left side pass
                     
                 } else if (i == s) { // right
                     
-                    // handled by this patch when it does its right side
+                    // handled by the right side pass
                     
                 } else { // all in the middle
-                    leftPoint.set(i-1, this.getHeightmapHeight(i-1,s), s);
-                    rightPoint.set(i+1, this.getHeightmapHeight(i+1,s), s);
-                    averageNormalsTangents(topPoint, rootPoint, leftPoint, bottomPoint, rightPoint, null, null, null, null, null, normal, tangent, binormal);
-                    VertexBuffer tpNB = this.getMesh().getBuffer(Type.Normal);
-                    BufferUtils.setInBuffer(normal, (FloatBuffer)tpNB.getData(), (s+1)*(s)+i);
-                    VertexBuffer downNB = bottom.getMesh().getBuffer(Type.Normal);
-                    BufferUtils.setInBuffer(normal, (FloatBuffer)downNB.getData(), i);
+                    leftPoint.set(-1, this.getHeightmapHeight(i-1,s), 0);
+                    rightPoint.set(1, this.getHeightmapHeight(i+1,s), 0);
+                    averageNormalsTangents(topPoint, rootPoint, leftPoint, bottomPoint, rightPoint, normal, tangent, binormal);
+                    setInBuffer(this.getMesh(), (s+1)*(s)+i, normal, tangent, binormal);
+                    setInBuffer(bottom.getMesh(), i, normal, tangent, binormal);
                 }
             }
-            bottom.getMesh().getBuffer(Type.Normal).setUpdateNeeded();
             
         }
-
-        this.getMesh().getBuffer(Type.Normal).setUpdateNeeded();
-        this.getMesh().getBuffer(Type.Tangent).setUpdateNeeded();
-        this.getMesh().getBuffer(Type.Binormal).setUpdateNeeded();
     }
 
     protected void averageNormalsTangents(
@@ -569,38 +535,36 @@
             Vector3f leftPoint, 
             Vector3f bottomPoint, 
             Vector3f rightPoint,
-            Vector2f topTex,
-            Vector2f rootTex,
-            Vector2f leftTex,
-            Vector2f bottomTex,
-            Vector2f rightTex,
             Vector3f normal,
             Vector3f tangent,
             Vector3f binormal)
     {
         Vector3f scale = getWorldScale();
         
-        Vector3f n1 = Vector3f.ZERO;
+        Vector3f n1 = new Vector3f(0,0,0);
         if (topPoint != null && leftPoint != null) {
-            n1 = calculateNormal(topPoint.mult(scale), rootPoint.mult(scale), leftPoint.mult(scale));
+            n1.set(calculateNormal(topPoint.mult(scale), rootPoint.mult(scale), leftPoint.mult(scale)));
         }
-        Vector3f n2 = Vector3f.ZERO;
+        Vector3f n2 = new Vector3f(0,0,0);
         if (leftPoint != null && bottomPoint != null) {
-            n2 = calculateNormal(leftPoint.mult(scale), rootPoint.mult(scale), bottomPoint.mult(scale));
+            n2.set(calculateNormal(leftPoint.mult(scale), rootPoint.mult(scale), bottomPoint.mult(scale)));
         }
-        Vector3f n3 = Vector3f.ZERO;
+        Vector3f n3 = new Vector3f(0,0,0);
         if (rightPoint != null && bottomPoint != null) {
-            n3 = calculateNormal(bottomPoint.mult(scale), rootPoint.mult(scale), rightPoint.mult(scale));
+            n3.set(calculateNormal(bottomPoint.mult(scale), rootPoint.mult(scale), rightPoint.mult(scale)));
         }
-        Vector3f n4 = Vector3f.ZERO;
+        Vector3f n4 = new Vector3f(0,0,0);
         if (rightPoint != null && topPoint != null) {
-            n4 = calculateNormal(rightPoint.mult(scale), rootPoint.mult(scale), topPoint.mult(scale));
+            n4.set(calculateNormal(rightPoint.mult(scale), rootPoint.mult(scale), topPoint.mult(scale)));
         }
         
-        if (bottomPoint != null && rightPoint != null && rootTex != null && rightTex != null && bottomTex != null)
-            LODGeomap.calculateTangent(new Vector3f[]{rootPoint.mult(scale),rightPoint.mult(scale),bottomPoint.mult(scale)}, new Vector2f[]{rootTex,rightTex,bottomTex}, tangent, binormal);
+        //if (bottomPoint != null && rightPoint != null && rootTex != null && rightTex != null && bottomTex != null)
+        //    LODGeomap.calculateTangent(new Vector3f[]{rootPoint.mult(scale),rightPoint.mult(scale),bottomPoint.mult(scale)}, new Vector2f[]{rootTex,rightTex,bottomTex}, tangent, binormal);
 
-        normal.set(n1.add(n2).add(n3).add(n4).normalizeLocal());
+        normal.set(n1.add(n2).add(n3).add(n4).normalize());
+        
+        tangent.set(normal.cross(new Vector3f(0,0,1)).normalize());
+        binormal.set(new Vector3f(1,0,0).cross(normal).normalize());
     }
 
     private Vector3f calculateNormal(Vector3f firstPoint, Vector3f rootPoint, Vector3f secondPoint) {
diff --git a/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainQuad.java b/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainQuad.java
index 0b9b218..1086c71 100644
--- a/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainQuad.java
+++ b/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainQuad.java
@@ -1675,8 +1675,9 @@
                             }
                         }
                     }
-                    else
+                    else if (children.get(i) instanceof TerrainQuad) {
                         ((TerrainQuad) children.get(i)).findPick(toTest, results);
+                    }
                 }
             }
         }
diff --git a/engine/src/test/jme3test/app/TestAppStateLifeCycle.java b/engine/src/test/jme3test/app/TestAppStateLifeCycle.java
new file mode 100644
index 0000000..f224242
--- /dev/null
+++ b/engine/src/test/jme3test/app/TestAppStateLifeCycle.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2009-2012 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jme3test.app;
+
+import com.jme3.app.Application;
+import com.jme3.app.SimpleApplication;
+import com.jme3.app.state.AbstractAppState;
+import com.jme3.app.state.AppStateManager;
+import com.jme3.material.Material;
+import com.jme3.math.Vector3f;
+import com.jme3.renderer.RenderManager;
+import com.jme3.scene.Geometry;
+import com.jme3.scene.shape.Box;
+
+
+/**
+ *  Tests the app state lifecycles.
+ *
+ *  @author    Paul Speed
+ */
+public class TestAppStateLifeCycle extends SimpleApplication {
+
+    public static void main(String[] args){
+        TestAppStateLifeCycle app = new TestAppStateLifeCycle();
+        app.start();
+    }
+
+    @Override
+    public void simpleInitApp() {
+        Box b = new Box(Vector3f.ZERO, 1, 1, 1);
+        Geometry geom = new Geometry("Box", b);
+        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
+        mat.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg"));
+        geom.setMaterial(mat);
+        rootNode.attachChild(geom);
+
+        System.out.println("Attaching test state.");
+        stateManager.attach(new TestState());        
+    }
+
+    @Override
+    public void simpleUpdate(float tpf) {
+    
+        if(stateManager.getState(TestState.class) != null) {
+            System.out.println("Detaching test state."); 
+            stateManager.detach(stateManager.getState(TestState.class));
+            System.out.println("Done"); 
+        }        
+    }
+    
+    public class TestState extends AbstractAppState {
+ 
+        @Override
+        public void initialize(AppStateManager stateManager, Application app) {
+            super.initialize(stateManager, app);
+            System.out.println("Initialized");
+        }
+ 
+        @Override
+        public void stateAttached(AppStateManager stateManager) {
+            super.stateAttached(stateManager);
+            System.out.println("Attached");
+        }
+ 
+        @Override
+        public void update(float tpf) {
+            super.update(tpf);
+            System.out.println("update");
+        }
+
+        @Override
+        public void render(RenderManager rm) {
+            super.render(rm);
+            System.out.println("render");
+        }
+
+        @Override
+        public void postRender() {
+            super.postRender();
+            System.out.println("postRender");
+        }
+
+        @Override
+        public void stateDetached(AppStateManager stateManager) {
+            super.stateDetached(stateManager);
+            System.out.println("Detached");
+        }
+ 
+        @Override
+        public void cleanup() {
+            super.cleanup();
+            System.out.println("Cleanup"); 
+        }
+
+    }    
+}
diff --git a/engine/src/test/jme3test/effect/TestSoftParticles.java b/engine/src/test/jme3test/effect/TestSoftParticles.java
new file mode 100644
index 0000000..d779a6f
--- /dev/null
+++ b/engine/src/test/jme3test/effect/TestSoftParticles.java
@@ -0,0 +1,130 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package jme3test.effect;
+
+import com.jme3.app.SimpleApplication;
+import com.jme3.effect.ParticleEmitter;
+import com.jme3.effect.ParticleMesh;
+import com.jme3.effect.shapes.EmitterSphereShape;
+import com.jme3.input.KeyInput;
+import com.jme3.input.controls.ActionListener;
+import com.jme3.input.controls.KeyTrigger;
+import com.jme3.material.Material;
+import com.jme3.math.ColorRGBA;
+import com.jme3.math.Quaternion;
+import com.jme3.math.Vector3f;
+import com.jme3.post.FilterPostProcessor;
+import com.jme3.post.filters.TranslucentBucketFilter;
+import com.jme3.scene.Geometry;
+import com.jme3.scene.shape.Box;
+
+/**
+ *
+ * @author Nehon
+ */
+public class TestSoftParticles extends SimpleApplication {
+
+    private boolean softParticles = true;
+    private FilterPostProcessor fpp;
+    private TranslucentBucketFilter tbf;
+
+    public static void main(String[] args) {
+        TestSoftParticles app = new TestSoftParticles();
+        app.start();
+    }
+
+    @Override
+    public void simpleInitApp() {
+
+        cam.setLocation(new Vector3f(-7.2221026f, 4.1183004f, 7.759811f));
+        cam.setRotation(new Quaternion(0.06152846f, 0.91236454f, -0.1492115f, 0.37621948f));
+
+        flyCam.setMoveSpeed(10);
+
+
+        // -------- floor
+        Box b = new Box(Vector3f.ZERO, 10, 0.1f, 10);
+        Geometry geom = new Geometry("Box", b);
+        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
+        mat.setColor("Color", ColorRGBA.Gray);
+        mat.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg"));
+        geom.setMaterial(mat);
+        rootNode.attachChild(geom);
+
+        Box b2 = new Box(Vector3f.ZERO, 1, 1, 1);
+        Geometry geom2 = new Geometry("Box", b2);
+        Material mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
+        mat2.setColor("Color", ColorRGBA.DarkGray);
+        geom2.setMaterial(mat2);
+        rootNode.attachChild(geom2);
+        geom2.setLocalScale(0.1f, 0.2f, 1);
+
+        fpp = new FilterPostProcessor(assetManager);        
+        tbf = new TranslucentBucketFilter(true);
+        fpp.addFilter(tbf);
+        viewPort.addProcessor(fpp);
+
+
+        Material material = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md");
+        material.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/flame.png"));
+        
+        material.setFloat("Softness", 3f); // 
+
+
+        //Fire
+        ParticleEmitter fire = new ParticleEmitter("Fire", ParticleMesh.Type.Triangle, 30);
+        fire.setMaterial(material);
+        fire.setShape(new EmitterSphereShape(Vector3f.ZERO, 0.1f));
+        fire.setImagesX(2);
+        fire.setImagesY(2); // 2x2 texture animation
+        fire.setEndColor(new ColorRGBA(1f, 0f, 0f, 1f)); // red
+        fire.setStartColor(new ColorRGBA(1f, 1f, 0f, 0.5f)); // yellow
+        fire.setStartSize(0.6f);
+        fire.setEndSize(0.01f);
+        fire.setGravity(0, -0.3f, 0);
+        fire.setLowLife(0.5f);
+        fire.setHighLife(3f);
+        fire.setLocalTranslation(0, 0.2f, 0);
+
+        rootNode.attachChild(fire);
+        
+        
+        ParticleEmitter smoke = new ParticleEmitter("Smoke", ParticleMesh.Type.Triangle, 30);
+        smoke.setMaterial(material);
+        smoke.setShape(new EmitterSphereShape(Vector3f.ZERO, 5));
+        smoke.setImagesX(1);
+        smoke.setImagesY(1); // 2x2 texture animation
+        smoke.setStartColor(new ColorRGBA(0.1f, 0.1f, 0.1f,1f)); // dark gray
+        smoke.setEndColor(new ColorRGBA(0.5f, 0.5f, 0.5f, 0.3f)); // gray      
+        smoke.setStartSize(3f);
+        smoke.setEndSize(5f);
+        smoke.setGravity(0, -0.001f, 0);
+        smoke.setLowLife(100f);
+        smoke.setHighLife(100f);
+        smoke.setLocalTranslation(0, 0.1f, 0);        
+        smoke.emitAllParticles();
+        
+        rootNode.attachChild(smoke);
+
+        
+        inputManager.addListener(new ActionListener() {
+
+            public void onAction(String name, boolean isPressed, float tpf) {
+                if(isPressed && name.equals("toggle")){
+               //     tbf.setEnabled(!tbf.isEnabled());     
+                    softParticles = !softParticles;
+                    if(softParticles){
+                        viewPort.addProcessor(fpp);
+                    }else{
+                        viewPort.removeProcessor(fpp);
+                    }
+                }
+            }
+        }, "toggle");
+        inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_SPACE));
+    }
+    
+    
+}
diff --git a/engine/src/test/jme3test/helloworld/HelloMaterial.java b/engine/src/test/jme3test/helloworld/HelloMaterial.java
index e930c91..8ef6f56 100644
--- a/engine/src/test/jme3test/helloworld/HelloMaterial.java
+++ b/engine/src/test/jme3test/helloworld/HelloMaterial.java
@@ -80,7 +80,7 @@
     /** A cube with its base color "leaking" through a partially transparent texture */
     Box boxshape4 = new Box(new Vector3f(3f,-1f,0f), 1f,1f,1f);
     Geometry cube_leak = new Geometry("Leak-through color cube", boxshape4);
-    Material mat_tl = new Material(assetManager, "Common/MatDefs/Misc/ColoredTextured.j3md");
+    Material mat_tl = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
     mat_tl.setTexture("ColorMap", assetManager.loadTexture("Textures/ColoredTex/Monkey.png"));
     mat_tl.setColor("Color", new ColorRGBA(1f,0f,1f, 1f)); // purple
     cube_leak.setMaterial(mat_tl);
@@ -103,6 +103,7 @@
     shiny_rock.setLocalTranslation(0,2,-2); // Move it a bit
     shiny_rock.rotate(1.6f, 0, 0);          // Rotate it a bit
     rootNode.attachChild(shiny_rock);
+    
     /** Must add a light to make the lit object visible! */
     DirectionalLight sun = new DirectionalLight();
     sun.setDirection(new Vector3f(1,0,-2).normalizeLocal());
diff --git a/engine/src/test/jme3test/model/shape/TestExpandingTorus.java b/engine/src/test/jme3test/model/shape/TestExpandingTorus.java
new file mode 100644
index 0000000..9e76b3f
--- /dev/null
+++ b/engine/src/test/jme3test/model/shape/TestExpandingTorus.java
@@ -0,0 +1,45 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package jme3test.model.shape;
+
+import com.jme3.app.SimpleApplication;
+import com.jme3.material.Material;
+import com.jme3.scene.Geometry;
+import com.jme3.scene.shape.Torus;
+
+public class TestExpandingTorus extends SimpleApplication {
+
+    private float outerRadius = 1.5f;
+    private float rate = 1;
+    private Torus torus;
+    private Geometry geom;
+    
+    public static void main(String[] args) {
+        TestExpandingTorus app = new TestExpandingTorus();
+        app.start();
+    }
+
+    @Override
+    public void simpleInitApp() {
+        torus = new Torus(30, 10, .5f, 1f);
+        geom = new Geometry("Torus", torus);
+        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
+        geom.setMaterial(mat);
+        rootNode.attachChild(geom);
+    }
+    
+    @Override
+    public void simpleUpdate(float tpf){
+        if (outerRadius > 2.5f){
+            outerRadius = 2.5f;
+            rate = -rate;
+        }else if (outerRadius < 1f){
+            outerRadius = 1f;
+            rate = -rate;
+        }
+        outerRadius += rate * tpf;
+        torus.updateGeometry(30, 10, .5f, outerRadius);
+    }
+}
\ No newline at end of file
diff --git a/engine/src/tools/jme3tools/converters/model/ModelConverter.java b/engine/src/tools/jme3tools/converters/model/ModelConverter.java
index 2539574..6383d43 100644
--- a/engine/src/tools/jme3tools/converters/model/ModelConverter.java
+++ b/engine/src/tools/jme3tools/converters/model/ModelConverter.java
@@ -69,7 +69,7 @@
         ts.setListsOnly(listOnly);
         ts.setMinStripSize(minStripSize);
 
-        IndexBuffer ib = mesh.getIndexBuffer();
+        IndexBuffer ib = mesh.getIndicesAsList();
         int[] indices = new int[ib.size()];
         for (int i = 0; i < indices.length; i++)
             indices[i] = ib.get(i);
@@ -157,7 +157,7 @@
                 mesh.setBuffer(vb);
             }
         }
-        mesh.setInterleaved();
+        //mesh.setInterleaved();
     }
 
     private static void optimizeScene(Spatial source, boolean toFixed){
diff --git a/engine/src/tools/jme3tools/optimize/GeometryBatchFactory.java b/engine/src/tools/jme3tools/optimize/GeometryBatchFactory.java
index ae6ad8c..121d75c 100644
--- a/engine/src/tools/jme3tools/optimize/GeometryBatchFactory.java
+++ b/engine/src/tools/jme3tools/optimize/GeometryBatchFactory.java
@@ -62,26 +62,27 @@
         }
     }
     
-    private static void doTransformTangents(FloatBuffer inBuf, int offset, FloatBuffer outBuf, Matrix4f transform) {
+    private static void doTransformTangents(FloatBuffer inBuf, int offset, int components, FloatBuffer outBuf, Matrix4f transform) {
         Vector3f tan = new Vector3f();
-        float handedness = 0;
+        
         // offset is given in element units
         // convert to be in component units
-        offset *= 4;
+        offset *= components;
 
-        for (int i = 0; i < inBuf.capacity() / 4; i++) {
-            tan.x = inBuf.get(i * 4 + 0);
-            tan.y = inBuf.get(i * 4 + 1);
-            tan.z = inBuf.get(i * 4 + 2);
-            handedness = inBuf.get(i * 4 + 3);
+        for (int i = 0; i < inBuf.capacity() / components; i++) {
+            tan.x = inBuf.get(i * components + 0);
+            tan.y = inBuf.get(i * components + 1);
+            tan.z = inBuf.get(i * components + 2);
 
             transform.multNormal(tan, tan);
 
-            outBuf.put(offset + i * 4 + 0, tan.x);
-            outBuf.put(offset + i * 4 + 1, tan.y);
-            outBuf.put(offset + i * 4 + 2, tan.z);
-            outBuf.put(offset + i * 4 + 3, handedness);
-             
+            outBuf.put(offset + i * components + 0, tan.x);
+            outBuf.put(offset + i * components + 1, tan.y);
+            outBuf.put(offset + i * components + 2, tan.z);
+            
+            if (components == 4){
+                outBuf.put(offset + i * components + 3, inBuf.get(i * components + 3));
+            }
         }
     }
 
@@ -129,9 +130,9 @@
                     throw new UnsupportedOperationException();
             }
 
-            for (Entry<VertexBuffer> entry : geom.getMesh().getBuffers()) {
-                compsForBuf[entry.getKey()] = entry.getValue().getNumComponents();
-                formatForBuf[entry.getKey()] = entry.getValue().getFormat();
+            for (VertexBuffer vb : geom.getMesh().getBufferList().getArray()){
+                compsForBuf[vb.getBufferType().ordinal()] = vb.getNumComponents();
+                formatForBuf[vb.getBufferType().ordinal()] = vb.getFormat();
             }
 
             if (mode != null && mode != listMode) {
@@ -208,10 +209,11 @@
                     FloatBuffer inPos = (FloatBuffer) inBuf.getDataReadOnly();
                     FloatBuffer outPos = (FloatBuffer) outBuf.getData();
                     doTransformNorms(inPos, globalVertIndex, outPos, worldMatrix);
-                }else if(Type.Tangent.ordinal() == bufType){                    
+                }else if(Type.Tangent.ordinal() == bufType){                
                     FloatBuffer inPos = (FloatBuffer) inBuf.getDataReadOnly();
                     FloatBuffer outPos = (FloatBuffer) outBuf.getData();
-                    doTransformTangents(inPos, globalVertIndex, outPos, worldMatrix);
+                    int components = inBuf.getNumComponents();
+                    doTransformTangents(inPos, globalVertIndex, components, outPos, worldMatrix);
                 } else {
                     inBuf.copyElements(0, outBuf, globalVertIndex, geomVertCount);
                 }
