diff --git a/examples/CommonInterfaces/CommonParameterInterface.h b/examples/CommonInterfaces/CommonParameterInterface.h
index e233410..da5b353 100644
--- a/examples/CommonInterfaces/CommonParameterInterface.h
+++ b/examples/CommonInterfaces/CommonParameterInterface.h
@@ -43,6 +43,7 @@ struct ButtonParams
 	int m_buttonId;
 	void* m_userPointer;
     bool m_isTrigger;
+    bool m_initialState;
 
 	ButtonParamChangedCallback m_callback;
 	ButtonParams(const char* name, int buttonId, bool isTrigger)
@@ -50,6 +51,7 @@ struct ButtonParams
 		m_buttonId(buttonId),
 		m_userPointer(0),
     m_isTrigger(isTrigger),
+    m_initialState(false),
 	m_callback(0)
 	{
 	}
diff --git a/examples/ExampleBrowser/GwenGUISupport/GwenParameterInterface.cpp b/examples/ExampleBrowser/GwenGUISupport/GwenParameterInterface.cpp
index aa8c0b8..432137b 100644
--- a/examples/ExampleBrowser/GwenGUISupport/GwenParameterInterface.cpp
+++ b/examples/ExampleBrowser/GwenGUISupport/GwenParameterInterface.cpp
@@ -3,12 +3,14 @@
 
 struct MyButtonEventHandler : public Gwen::Event::Handler
 {
+    Gwen::Controls::Button* m_buttonControl;
 	ButtonParamChangedCallback m_callback;
 	void* m_userPointer;
 	int m_buttonId;
 
-	MyButtonEventHandler(ButtonParamChangedCallback callback, int buttonId, void* userPointer)
-		:m_callback(callback),
+	MyButtonEventHandler(Gwen::Controls::Button* buttonControl, ButtonParamChangedCallback callback, int buttonId, void* userPointer)
+		:m_buttonControl(buttonControl),
+        m_callback(callback),
 		m_userPointer(userPointer),
 		m_buttonId(buttonId)
 	{
@@ -18,7 +20,12 @@ struct MyButtonEventHandler : public Gwen::Event::Handler
 	{
 		if (m_callback)
 		{
-			(*m_callback)(m_buttonId, true, m_userPointer);
+            bool buttonState = true;
+            if (m_buttonControl->IsToggle())
+            {
+                buttonState = m_buttonControl->GetToggleState();
+            }
+            ( *m_callback )( m_buttonId, buttonState, m_userPointer );
 		}
 	}
 };
@@ -140,10 +147,11 @@ void GwenParameterInterface::registerButtonParameter(ButtonParams& params)
 {
 	
 	Gwen::Controls::Button* button = new Gwen::Controls::Button(m_gwenInternalData->m_demoPage->GetPage());
-	MyButtonEventHandler* handler = new MyButtonEventHandler(params.m_callback,params.m_buttonId,params.m_userPointer);
+	MyButtonEventHandler* handler = new MyButtonEventHandler(button, params.m_callback,params.m_buttonId,params.m_userPointer);
 	button->SetText(params.m_name);
 	button->onPress.Add( handler, &MyButtonEventHandler::onButtonPress );
     button->SetIsToggle(params.m_isTrigger);
+    button->SetToggleState(params.m_initialState);
     
 	m_paramInternalData->m_buttons.push_back(button);
 	m_paramInternalData->m_buttonEventHandlers.push_back(handler);
diff --git a/examples/MultiThreadedDemo/CommonRigidBodyMTBase.cpp b/examples/MultiThreadedDemo/CommonRigidBodyMTBase.cpp
index 5a17ba8..a3a6e74 100644
--- a/examples/MultiThreadedDemo/CommonRigidBodyMTBase.cpp
+++ b/examples/MultiThreadedDemo/CommonRigidBodyMTBase.cpp
@@ -30,6 +30,11 @@ class btCollisionShape;
 #include "BulletDynamics/Dynamics/btSimulationIslandManagerMt.h"  // for setSplitIslands()
 #include "BulletDynamics/Dynamics/btDiscreteDynamicsWorldMt.h"
 #include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h"
+#include "BulletDynamics/ConstraintSolver/btNNCGConstraintSolver.h"
+#include "BulletDynamics/MLCPSolvers/btMLCPSolver.h"
+#include "BulletDynamics/MLCPSolvers/btSolveProjectedGaussSeidel.h"
+#include "BulletDynamics/MLCPSolvers/btDantzigSolver.h"
+#include "BulletDynamics/MLCPSolvers/btLemkeSolver.h"
 
 TaskManager gTaskMgr;
 
@@ -587,11 +592,47 @@ ATTRIBUTE_ALIGNED16( class ) MyDiscreteDynamicsWorld : public btDiscreteDynamics
 
 };
 
+
+btConstraintSolver* createSolverByType( SolverType t )
+{
+    btMLCPSolverInterface* mlcpSolver = NULL;
+    switch ( t )
+    {
+    case SOLVER_TYPE_SEQUENTIAL_IMPULSE:
+        return new btSequentialImpulseConstraintSolver();
+    case SOLVER_TYPE_NNCG:
+        return new btNNCGConstraintSolver();
+    case SOLVER_TYPE_MLCP_PGS:
+        mlcpSolver = new btSolveProjectedGaussSeidel();
+        break;
+    case SOLVER_TYPE_MLCP_DANTZIG:
+        mlcpSolver = new btDantzigSolver();
+        break;
+    case SOLVER_TYPE_MLCP_LEMKE:
+        mlcpSolver = new btLemkeSolver();
+        break;
+    }
+    if (mlcpSolver)
+    {
+        return new btMLCPSolver(mlcpSolver);
+    }
+    return NULL;
+}
+
+
 static bool gMultithreadedWorld = false;
 static bool gDisplayProfileInfo = false;
-static btScalar gSliderNumThreads = 1.0f;  // should be int
+static SolverType gSolverType = SOLVER_TYPE_SEQUENTIAL_IMPULSE;
+static int gSolverMode = SOLVER_SIMD |
+                        SOLVER_USE_WARMSTARTING |
+                        // SOLVER_RANDMIZE_ORDER |
+                        // SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS |
+                        // SOLVER_USE_2_FRICTION_DIRECTIONS |
+                        0;
 static btScalar gSliderSolverIterations = 10.0f; // should be int
 
+static btScalar gSliderNumThreads = 1.0f;  // should be int
+
 
 ////////////////////////////////////
 CommonRigidBodyMTBase::CommonRigidBodyMTBase( struct GUIHelperInterface* helper )
@@ -622,6 +663,33 @@ void boolPtrButtonCallback(int buttonId, bool buttonState, void* userPointer)
     }
 }
 
+void toggleSolverModeCallback(int buttonId, bool buttonState, void* userPointer)
+{
+    if (buttonState)
+    {
+        gSolverMode |= buttonId;
+    }
+    else
+    {
+        gSolverMode &= ~buttonId;
+    }
+    if (CommonRigidBodyMTBase* crb = reinterpret_cast<CommonRigidBodyMTBase*>(userPointer))
+    {
+        if (crb->m_dynamicsWorld)
+        {
+            crb->m_dynamicsWorld->getSolverInfo().m_solverMode = gSolverMode;
+        }
+    }
+}
+
+void setSolverTypeCallback(int buttonId, bool buttonState, void* userPointer)
+{
+    if (buttonId >= 0 && buttonId < SOLVER_TYPE_COUNT)
+    {
+        gSolverType = static_cast<SolverType>(buttonId);
+    }
+}
+
 void apiSelectButtonCallback(int buttonId, bool buttonState, void* userPointer)
 {
     gTaskMgr.setApi(static_cast<TaskManager::Api>(buttonId));
@@ -658,6 +726,7 @@ void setSolverIterationCountCallback(float val, void* userPtr)
 void CommonRigidBodyMTBase::createEmptyDynamicsWorld()
 {
     gNumIslands = 0;
+    m_solverType = gSolverType;
 #if BT_THREADSAFE && (BT_USE_OPENMP || BT_USE_PPL || BT_USE_TBB)
     m_multithreadCapable = true;
 #endif
@@ -678,9 +747,17 @@ void CommonRigidBodyMTBase::createEmptyDynamicsWorld()
         m_broadphase = new btDbvtBroadphase();
 
 #if USE_PARALLEL_ISLAND_SOLVER
-        m_solver = new MyConstraintSolverPool( TaskManager::getMaxNumThreads() );
+        {
+            btConstraintSolver* solvers[ BT_MAX_THREAD_COUNT ];
+            int maxThreadCount = btMin( int(BT_MAX_THREAD_COUNT), TaskManager::getMaxNumThreads() );
+            for ( int i = 0; i < maxThreadCount; ++i )
+            {
+                solvers[ i ] = createSolverByType( m_solverType );
+            }
+            m_solver = new MyConstraintSolverPool( solvers, maxThreadCount );
+        }
 #else
-        m_solver = new btSequentialImpulseConstraintSolver();
+        m_solver = createSolverByType( m_solverType );
 #endif //#if USE_PARALLEL_ISLAND_SOLVER
         btDiscreteDynamicsWorld* world = new MyDiscreteDynamicsWorld( m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration );
         m_dynamicsWorld = world;
@@ -707,15 +784,14 @@ void CommonRigidBodyMTBase::createEmptyDynamicsWorld()
 
         m_broadphase = new btDbvtBroadphase();
 
-        ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
-        btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver;
-        m_solver = sol;
+        m_solver = createSolverByType( m_solverType );
 
         m_dynamicsWorld = new btDiscreteDynamicsWorld( m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration );
     }
     m_dynamicsWorld->setInternalTickCallback( profileBeginCallback, NULL, true );
     m_dynamicsWorld->setInternalTickCallback( profileEndCallback, NULL, false );
     m_dynamicsWorld->setGravity( btVector3( 0, -10, 0 ) );
+    m_dynamicsWorld->getSolverInfo().m_solverMode = gSolverMode;
     createDefaultParameters();
 }
 
@@ -726,18 +802,33 @@ void CommonRigidBodyMTBase::createDefaultParameters()
     {
         // create a button to toggle multithreaded world
         ButtonParams button( "Multithreaded world enable", 0, true );
+        button.m_initialState = gMultithreadedWorld;
         button.m_userPointer = &gMultithreadedWorld;
         button.m_callback = boolPtrButtonCallback;
         m_guiHelper->getParameterInterface()->registerButtonParameter( button );
     }
     {
         // create a button to toggle profile printing
-        ButtonParams button( "Display profile timings", 0, true );
+        ButtonParams button( "Display solver info", 0, true );
+        button.m_initialState = gDisplayProfileInfo;
         button.m_userPointer = &gDisplayProfileInfo;
         button.m_callback = boolPtrButtonCallback;
         m_guiHelper->getParameterInterface()->registerButtonParameter( button );
     }
+
+    // add buttons for switching to different solver types
+    for (int i = 0; i < SOLVER_TYPE_COUNT; ++i)
+    {
+        char buttonName[256];
+        SolverType solverType = static_cast<SolverType>(i);
+        sprintf(buttonName, "Solver Type %s", getSolverTypeName(solverType));
+        ButtonParams button( buttonName, 0, false );
+        button.m_buttonId = solverType;
+        button.m_callback = setSolverTypeCallback;
+        m_guiHelper->getParameterInterface()->registerButtonParameter( button );
+    }
     {
+        // a slider for the number of solver iterations
         SliderParams slider( "Solver iterations", &gSliderSolverIterations );
         slider.m_minVal = 1.0f;
         slider.m_maxVal = 30.0f;
@@ -746,6 +837,54 @@ void CommonRigidBodyMTBase::createDefaultParameters()
         slider.m_clampToIntegers = true;
         m_guiHelper->getParameterInterface()->registerSliderFloatParameter( slider );
     }
+    {
+        ButtonParams button( "Solver use SIMD", 0, true );
+        button.m_buttonId = SOLVER_SIMD;
+        button.m_initialState = !! (gSolverMode & button.m_buttonId);
+        button.m_callback = toggleSolverModeCallback;
+        button.m_userPointer = this;
+        m_guiHelper->getParameterInterface()->registerButtonParameter( button );
+    }
+    {
+        ButtonParams button( "Solver randomize order", 0, true );
+        button.m_buttonId = SOLVER_RANDMIZE_ORDER;
+        button.m_initialState = !! (gSolverMode & button.m_buttonId);
+        button.m_callback = toggleSolverModeCallback;
+        button.m_userPointer = this;
+        m_guiHelper->getParameterInterface()->registerButtonParameter( button );
+    }
+    {
+        ButtonParams button( "Solver interleave contact/friction", 0, true );
+        button.m_buttonId = SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS;
+        button.m_initialState = !! (gSolverMode & button.m_buttonId);
+        button.m_callback = toggleSolverModeCallback;
+        button.m_userPointer = this;
+        m_guiHelper->getParameterInterface()->registerButtonParameter( button );
+    }
+    {
+        ButtonParams button( "Solver 2 friction directions", 0, true );
+        button.m_buttonId = SOLVER_USE_2_FRICTION_DIRECTIONS;
+        button.m_initialState = !! (gSolverMode & button.m_buttonId);
+        button.m_callback = toggleSolverModeCallback;
+        button.m_userPointer = this;
+        m_guiHelper->getParameterInterface()->registerButtonParameter( button );
+    }
+    {
+        ButtonParams button( "Solver friction dir caching", 0, true );
+        button.m_buttonId = SOLVER_ENABLE_FRICTION_DIRECTION_CACHING;
+        button.m_initialState = !! (gSolverMode & button.m_buttonId);
+        button.m_callback = toggleSolverModeCallback;
+        button.m_userPointer = this;
+        m_guiHelper->getParameterInterface()->registerButtonParameter( button );
+    }
+    {
+        ButtonParams button( "Solver warmstarting", 0, true );
+        button.m_buttonId = SOLVER_USE_WARMSTARTING;
+        button.m_initialState = !! (gSolverMode & button.m_buttonId);
+        button.m_callback = toggleSolverModeCallback;
+        button.m_userPointer = this;
+        m_guiHelper->getParameterInterface()->registerButtonParameter( button );
+    }
     if (m_multithreadedWorld)
     {
         // create a button for each supported threading API
@@ -781,6 +920,12 @@ void CommonRigidBodyMTBase::drawScreenText()
     int xCoord = 400;
     int yCoord = 30;
     int yStep = 30;
+    if (m_solverType != gSolverType)
+    {
+        sprintf( msg, "restart example to change solver type" );
+        m_guiHelper->getAppInterface()->drawText( msg, 300, yCoord, 0.4f );
+        yCoord += yStep;
+    }
     if (m_multithreadCapable)
     {
         if ( m_multithreadedWorld != gMultithreadedWorld )
@@ -815,7 +960,20 @@ void CommonRigidBodyMTBase::drawScreenText()
             m_guiHelper->getAppInterface()->drawText( msg, 100, yCoord, 0.4f );
             yCoord += yStep;
         }
-
+        {
+            int sm = gSolverMode;
+            sprintf( msg, "solver %s mode [%s%s%s%s%s%s]",
+                     getSolverTypeName(m_solverType),
+                     sm & SOLVER_SIMD ? "SIMD" : "",
+                     sm & SOLVER_RANDMIZE_ORDER ? " randomize" : "",
+                     sm & SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS ? " interleave" : "",
+                     sm & SOLVER_USE_2_FRICTION_DIRECTIONS ? " friction2x" : "",
+                     sm & SOLVER_ENABLE_FRICTION_DIRECTION_CACHING ? " frictionDirCaching" : "",
+                     sm & SOLVER_USE_WARMSTARTING ? " warm" : ""
+                     );
+            m_guiHelper->getAppInterface()->drawText( msg, xCoord, yCoord, 0.4f );
+            yCoord += yStep;
+        }
         sprintf( msg, "internalSimStep %5.3f ms",
                  gProfiler.getAverageTime( Profiler::kRecordInternalTimeStep )*0.001f
                  );
diff --git a/examples/MultiThreadedDemo/CommonRigidBodyMTBase.h b/examples/MultiThreadedDemo/CommonRigidBodyMTBase.h
index 6ead77d..a399c03 100644
--- a/examples/MultiThreadedDemo/CommonRigidBodyMTBase.h
+++ b/examples/MultiThreadedDemo/CommonRigidBodyMTBase.h
@@ -11,6 +11,31 @@
 #include "../CommonInterfaces/CommonGraphicsAppInterface.h"
 #include "../CommonInterfaces/CommonWindowInterface.h"
 
+enum SolverType
+{
+    SOLVER_TYPE_SEQUENTIAL_IMPULSE,
+    SOLVER_TYPE_NNCG,
+    SOLVER_TYPE_MLCP_PGS,
+    SOLVER_TYPE_MLCP_DANTZIG,
+    SOLVER_TYPE_MLCP_LEMKE,
+
+    SOLVER_TYPE_COUNT
+};
+
+inline const char* getSolverTypeName( SolverType t )
+{
+    switch (t)
+    {
+    case SOLVER_TYPE_SEQUENTIAL_IMPULSE: return "SequentialImpulse";
+    case SOLVER_TYPE_NNCG: return "NNCG";
+    case SOLVER_TYPE_MLCP_PGS: return "MLCP ProjectedGaussSeidel";
+    case SOLVER_TYPE_MLCP_DANTZIG: return "MLCP Dantzig";
+    case SOLVER_TYPE_MLCP_LEMKE: return "MLCP Lemke";
+    }
+    btAssert( !"unhandled solver type in switch" );
+    return "???";
+}
+
 struct CommonRigidBodyMTBase : public CommonExampleInterface
 {
 		//keep the collision shapes, for deletion/cleanup
@@ -20,6 +45,7 @@ struct CommonRigidBodyMTBase : public CommonExampleInterface
 	btConstraintSolver*	m_solver;
 	btDefaultCollisionConfiguration* m_collisionConfiguration;
 	btDiscreteDynamicsWorld* m_dynamicsWorld;
+    SolverType m_solverType;
     bool m_multithreadedWorld;
     bool m_multithreadCapable;
 
