diff --git a/examples/ExampleBrowser/CMakeLists.txt b/examples/ExampleBrowser/CMakeLists.txt
index 114adb6..0af74fd 100644
--- a/examples/ExampleBrowser/CMakeLists.txt
+++ b/examples/ExampleBrowser/CMakeLists.txt
@@ -114,7 +114,10 @@ SET(ExtendedTutorialsSources
 	../ExtendedTutorials/SimpleCloth.cpp
 	../ExtendedTutorials/Chain.cpp 
 	../ExtendedTutorials/Bridge.cpp 
-	../ExtendedTutorials/RigidBodyFromObj.cpp 
+	../ExtendedTutorials/RigidBodyFromObj.cpp
+	../ExtendedTutorials/InclinedPlane.cpp
+	../ExtendedTutorials/InclinedPlane.h
+	../ExtendedTutorials/NewtonsCradle.cpp
 )
 
 SET(BulletExampleBrowser_SRCS
@@ -158,6 +161,20 @@ SET(BulletExampleBrowser_SRCS
 	../Tutorial/Tutorial.h
 	../Tutorial/Dof6ConstraintTutorial.cpp
 	../Tutorial/Dof6ConstraintTutorial.h
+	../ExtendedTutorials/SimpleBox.cpp
+	../ExtendedTutorials/SimpleBox.h
+	../ExtendedTutorials/MultipleBoxes.cpp
+	../ExtendedTutorials/MultipleBoxes.h
+	../ExtendedTutorials/SimpleCloth.cpp
+	../ExtendedTutorials/SimpleCloth.h
+	../ExtendedTutorials/SimpleJoint.cpp
+	../ExtendedTutorials/SimpleJoint.h
+	../ExtendedTutorials/NewtonsCradle.cpp
+	../ExtendedTutorials/NewtonsCradle.h
+	../ExtendedTutorials/InclinedPlane.cpp
+	../ExtendedTutorials/InclinedPlane.h
+	../ExtendedTutorials/MultiPendulum.cpp
+	../ExtendedTutorials/MultiPendulum.h
 	../Collision/CollisionSdkC_Api.cpp
 	../Collision/CollisionSdkC_Api.h
 	../Collision/CollisionTutorialBullet2.cpp
diff --git a/examples/ExampleBrowser/ExampleEntries.cpp b/examples/ExampleBrowser/ExampleEntries.cpp
index 75e16b8..10cfe33 100644
--- a/examples/ExampleBrowser/ExampleEntries.cpp
+++ b/examples/ExampleBrowser/ExampleEntries.cpp
@@ -45,7 +45,6 @@
 #include "../Tutorial/Dof6ConstraintTutorial.h"
 #include "../MultiThreading/MultiThreadingExample.h"
 #include "../InverseDynamics/InverseDynamicsExample.h"
-
 #ifdef ENABLE_LUA
 #include "../LuaDemo/LuaPhysicsSetup.h"
 #endif
@@ -57,7 +56,7 @@
 #endif
 #endif //B3_USE_CLEW
 
-//Extended Tutorial Includes Added by Mobeen
+//Extended Tutorial Includes Added by Mobeen and Benelot
 #include "../ExtendedTutorials/SimpleBox.h"
 #include "../ExtendedTutorials/MultipleBoxes.h"
 #include "../ExtendedTutorials/SimpleJoint.h"
@@ -65,6 +64,9 @@
 #include "../ExtendedTutorials/Chain.h"
 #include "../ExtendedTutorials/Bridge.h"
 #include "../ExtendedTutorials/RigidBodyFromObj.h"
+#include "../ExtendedTutorials/InclinedPlane.h"
+#include "../ExtendedTutorials/NewtonsCradle.h"
+#include "../ExtendedTutorials/MultiPendulum.h"
 
 struct ExampleEntry
 {
@@ -270,11 +272,15 @@ static ExampleEntry gDefaultExamples[]=
 	//Extended Tutorials Added by Mobeen
 	ExampleEntry(0,"Extended Tutorials"),
 	ExampleEntry(1,"Simple Box", "Simplest possible demo creating a single box rigid body that falls under gravity", ET_SimpleBoxCreateFunc),
-	ExampleEntry(1,"Multiple Boxes", "Adding multiple box rigid bodies that fall under gravity", ET_MultipleBoxesCreateFunc),
-	ExampleEntry(1,"Simple Joint", "Creating a single distance constraint between two box rigid bodies", ET_SimpleJointCreateFunc),
-	ExampleEntry(1,"Simple Cloth", "Creating a simple piece of cloth", ET_SimpleClothCreateFunc),
-	ExampleEntry(1,"Simple Chain", "Creating a simple chain using a pair of point2point/distance constraints. You may click and drag any box to see the chain respond.", ET_ChainCreateFunc),
-	ExampleEntry(1,"Simple Bridge", "Creating a simple bridge using a pair of point2point/distance constraints. You may click and drag any plank to see the bridge respond.", ET_BridgeCreateFunc),
+	ExampleEntry(1,"Multiple Boxes", "Add multiple box rigid bodies that fall under gravity", ET_MultipleBoxesCreateFunc),
+	ExampleEntry(1,"Simple Joint", "Create a single distance constraint between two box rigid bodies", ET_SimpleJointCreateFunc),
+	ExampleEntry(1,"Simple Cloth", "Create a simple piece of cloth", ET_SimpleClothCreateFunc),
+	ExampleEntry(1,"Simple Chain", "Create a simple chain using a pair of point2point/distance constraints. You may click and drag any box to see the chain respond.", ET_ChainCreateFunc),
+	ExampleEntry(1,"Simple Bridge", "Create a simple bridge using a pair of point2point/distance constraints. You may click and drag any plank to see the bridge respond.", ET_BridgeCreateFunc),
+	ExampleEntry(1,"Inclined Plane", "Create an inclined plane to show restitution and different types of friction. Use the sliders to vary restitution and friction and press space to reset the scene.", ET_InclinedPlaneCreateFunc),
+	ExampleEntry(1,"Newton's Cradle", "Create a Newton's Cradle using a pair of point2point/slider constraints. Press 1/2 to lengthen/shorten the pendula, press 3 to displace pendula. Use the sliders to select the number of pendula in total (reset simulation), the number of displaced pendula and other options.", ET_NewtonsCradleCreateFunc),
+	ExampleEntry(1,"Multi-Pendulum", "Create a Multi-Pendulum using point2point/slider constraints. Press 1/2 to lengthen/shorten the pendula, press 3 to displace pendula. Use the sliders to select the number of pendula in total (reset simulation), the number of displaced pendula and other options.",ET_MultiPendulumCreateFunc),
+
 
 	//todo: create a category/tutorial about advanced topics, such as optimizations, using different collision detection algorithm, different constraint solvers etc.
 	//ExampleEntry(0,"Advanced"),
diff --git a/examples/ExtendedTutorials/InclinedPlane.cpp b/examples/ExtendedTutorials/InclinedPlane.cpp
new file mode 100644
index 0000000..dceafdb
--- /dev/null
+++ b/examples/ExtendedTutorials/InclinedPlane.cpp
@@ -0,0 +1,372 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2015 Google Inc. http://bulletphysics.org
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+
+
+#include "InclinedPlane.h"
+
+#include "btBulletDynamicsCommon.h"
+#include "LinearMath/btVector3.h"
+#include "LinearMath/btAlignedObjectArray.h" 
+#include "../CommonInterfaces/CommonRigidBodyBase.h"
+#include "../CommonInterfaces/CommonParameterInterface.h"
+
+static btScalar gTilt = 20.0f/180.0f*SIMD_PI; // tilt the ramp 20 degrees
+
+static btScalar gRampFriction = 1; // set ramp friction to 1
+
+static btScalar gRampRestitution = 0; // set ramp restitution to 0 (no restitution)
+
+static btScalar gBoxFriction = 1; // set box friction to 1
+
+static btScalar gBoxRestitution = 0; // set box restitution to 0
+
+static btScalar gSphereFriction = 1; // set sphere friction to 1
+
+static btScalar gSphereRollingFriction = 1; // set sphere rolling friction to 1
+
+static btScalar gSphereRestitution = 0; // set sphere restitution to 0
+
+// handles for changes
+static btRigidBody* ramp = NULL;
+static btRigidBody* gBox = NULL;
+static btRigidBody* gSphere = NULL;
+
+struct InclinedPlaneExample : public CommonRigidBodyBase
+{
+	InclinedPlaneExample(struct GUIHelperInterface* helper)
+		:CommonRigidBodyBase(helper)
+	{
+	}
+	virtual ~InclinedPlaneExample(){}
+	virtual void initPhysics();
+	virtual void resetScene();
+	virtual void renderScene();
+	virtual void stepSimulation(float deltaTime);
+	virtual bool keyboardCallback(int key, int state);
+	void resetCamera()
+	{
+		float dist = 41;
+		float pitch = 52;
+		float yaw = 35;
+		float targetPos[3]={0,0.46,0};
+		m_guiHelper->resetCamera(dist,pitch,yaw,targetPos[0],targetPos[1],targetPos[2]);
+	}
+
+
+
+};
+
+void onBoxFrictionChanged(float friction);
+
+void onBoxRestitutionChanged(float restitution);
+
+void onSphereFrictionChanged(float friction);
+
+void onSphereRestitutionChanged(float restitution);
+
+void onRampInclinationChanged(float inclination);
+
+void onRampFrictionChanged(float friction);
+
+void onRampRestitutionChanged(float restitution);
+
+void InclinedPlaneExample::initPhysics()
+{
+
+	{ // create slider to change the ramp tilt
+    SliderParams slider("Ramp Tilt",&gTilt);
+    slider.m_minVal=0;
+    slider.m_maxVal=SIMD_PI/2.0f;
+    slider.m_clampToNotches = false;
+    slider.m_callback = onRampInclinationChanged;
+    m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
+    }
+
+    { // create slider to change the ramp friction
+    SliderParams slider("Ramp Friction",&gRampFriction);
+    slider.m_minVal=0;
+    slider.m_maxVal=10;
+    slider.m_clampToNotches = false;
+    slider.m_callback = onRampFrictionChanged;
+    m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
+    }
+
+    { // create slider to change the ramp restitution
+    SliderParams slider("Ramp Restitution",&gRampRestitution);
+    slider.m_minVal=0;
+    slider.m_maxVal=1;
+    slider.m_clampToNotches = false;
+    slider.m_callback = onRampRestitutionChanged;
+    m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
+    }
+
+    { // create slider to change the box friction
+    SliderParams slider("Box Friction",&gBoxFriction);
+    slider.m_minVal=0;
+    slider.m_maxVal=10;
+    slider.m_clampToNotches = false;
+    slider.m_callback = onBoxFrictionChanged;
+    m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
+    }
+
+    { // create slider to change the box restitution
+    SliderParams slider("Box Restitution",&gBoxRestitution);
+    slider.m_minVal=0;
+    slider.m_maxVal=1;
+    slider.m_clampToNotches = false;
+    slider.m_callback = onBoxRestitutionChanged;
+    m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
+    }
+
+    { // create slider to change the sphere friction
+    SliderParams slider("Sphere Friction",&gSphereFriction);
+    slider.m_minVal=0;
+    slider.m_maxVal=10;
+    slider.m_clampToNotches = false;
+    slider.m_callback = onSphereFrictionChanged;
+    m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
+    }
+
+    { // create slider to change the sphere rolling friction
+    SliderParams slider("Sphere Rolling Friction",&gSphereRollingFriction);
+    slider.m_minVal=0;
+    slider.m_maxVal=10;
+    slider.m_clampToNotches = false;
+    slider.m_callback = onSphereRestitutionChanged;
+    m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
+    }
+
+    { // create slider to change the sphere restitution
+    SliderParams slider("Sphere Restitution",&gSphereRestitution);
+    slider.m_minVal=0;
+    slider.m_maxVal=1;
+    slider.m_clampToNotches = false;
+    m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
+    }
+
+	m_guiHelper->setUpAxis(1); // set Y axis as up axis
+
+	createEmptyDynamicsWorld();
+	
+	// create debug drawer
+	m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
+	if (m_dynamicsWorld->getDebugDrawer())
+		m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints);
+
+
+	{ // create a static ground
+		btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.)));
+		m_collisionShapes.push_back(groundShape);
+
+		btTransform groundTransform;
+		groundTransform.setIdentity();
+		groundTransform.setOrigin(btVector3(0,-50,0));
+
+		btScalar mass(0.);
+		createRigidBody(mass,groundTransform,groundShape, btVector4(0,0,1,1));
+	}
+
+	{ //create a static inclined plane
+		btBoxShape* inclinedPlaneShape = createBoxShape(btVector3(btScalar(20.),btScalar(1.),btScalar(10.)));
+		m_collisionShapes.push_back(inclinedPlaneShape);
+
+		btTransform startTransform;
+		startTransform.setIdentity();
+
+		// position the inclined plane above ground
+		startTransform.setOrigin(btVector3(
+								 btScalar(0),
+								 btScalar(15),
+								 btScalar(0)));
+
+		btQuaternion incline;
+		incline.setRotation(btVector3(0,0,1),gTilt);
+		startTransform.setRotation(incline);
+
+		btScalar mass(0.);
+		ramp = createRigidBody(mass,startTransform,inclinedPlaneShape);
+		ramp->setFriction(gRampFriction);
+		ramp->setRestitution(gRampRestitution);
+	}
+
+
+	{ //create a cube above the inclined plane
+        btBoxShape* boxShape = createBoxShape(btVector3(1,1,1));
+		 
+		m_collisionShapes.push_back(boxShape);
+
+		btTransform startTransform;
+		startTransform.setIdentity();
+
+		btScalar boxMass(1.f);
+
+		startTransform.setOrigin(
+			btVector3(btScalar(0), btScalar(20), btScalar(2)));
+
+		gBox = createRigidBody(boxMass, startTransform, boxShape);
+		gBox->forceActivationState(DISABLE_DEACTIVATION); // to prevent the box on the ramp from disabling
+		gBox->setFriction(gBoxFriction);
+		gBox->setRestitution(gBoxRestitution);
+	}
+
+	{ //create a sphere above the inclined plane
+        btSphereShape* sphereShape = new btSphereShape(btScalar(1));
+
+		m_collisionShapes.push_back(sphereShape);
+
+		btTransform startTransform;
+		startTransform.setIdentity();
+
+		btScalar sphereMass(1.f);
+
+		startTransform.setOrigin(
+			btVector3(btScalar(0), btScalar(20), btScalar(4)));
+
+		gSphere = createRigidBody(sphereMass, startTransform, sphereShape);
+		gSphere->forceActivationState(DISABLE_DEACTIVATION); // to prevent the sphere on the ramp from disabling
+		gSphere->setFriction(gSphereFriction);
+		gSphere->setRestitution(gSphereRestitution);
+		gSphere->setRollingFriction(gSphereRollingFriction);
+	}
+
+	m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
+}
+
+void InclinedPlaneExample::resetScene() {
+	{ //reset a cube above the inclined plane
+
+		btTransform startTransform;
+		startTransform.setIdentity();
+
+		startTransform.setOrigin(
+			btVector3(btScalar(0), btScalar(20), btScalar(2)));
+
+		gBox->setWorldTransform(startTransform);
+		btVector3 zero(0, 0, 0);
+		gBox->setAngularVelocity(zero);
+		gBox->setLinearVelocity(zero);
+		gBox->clearForces();
+	}
+
+	{ //reset a sphere above the inclined plane
+		btTransform startTransform;
+		startTransform.setIdentity();
+
+		startTransform.setOrigin(
+			btVector3(btScalar(0), btScalar(20), btScalar(4)));
+
+		gSphere->setWorldTransform(startTransform);
+		btVector3 zero(0, 0, 0);
+		gSphere->setAngularVelocity(zero);
+		gSphere->setLinearVelocity(zero);
+		gSphere->clearForces();
+	}
+}
+
+void InclinedPlaneExample::stepSimulation(float deltaTime)
+{
+	if (m_dynamicsWorld)
+	{
+		m_dynamicsWorld->stepSimulation(deltaTime);
+	}
+
+}
+
+
+void InclinedPlaneExample::renderScene()
+{
+	CommonRigidBodyBase::renderScene();
+}
+
+bool InclinedPlaneExample::keyboardCallback(int key, int state) {
+//	b3Printf("Key pressed: %d in state %d \n",key,state);
+
+	switch (key) {
+	case 32 /*ASCII for space*/: {
+		resetScene();
+		break;
+	}
+	}
+
+	return false;
+}
+
+
+// GUI parameter modifiers
+void onBoxFrictionChanged(float friction){
+	if(gBox){
+		gBox->setFriction(friction);
+//		b3Printf("Friction of box changed to %f",friction );
+	}
+}
+
+void onBoxRestitutionChanged(float restitution){
+	if(gBox){
+		gBox->setRestitution(restitution);
+		//b3Printf("Restitution of box changed to %f",restitution);
+	}
+}
+
+void onSphereFrictionChanged(float friction){
+	if(gSphere){
+		gSphere->setFriction(friction);
+		//b3Printf("Friction of sphere changed to %f",friction );
+	}
+}
+
+void onSphereRestitutionChanged(float restitution){
+	if(gSphere){
+		gSphere->setRestitution(restitution);
+		//b3Printf("Restitution of sphere changed to %f",restitution);
+	}
+}
+
+void onRampInclinationChanged(float inclination){
+	if(ramp){
+		btTransform startTransform;
+		startTransform.setIdentity();
+
+		// position the inclined plane above ground
+		startTransform.setOrigin(
+			btVector3(btScalar(0), btScalar(15), btScalar(0)));
+
+		btQuaternion incline;
+		incline.setRotation(btVector3(0,0,1),gTilt);
+		startTransform.setRotation(incline);
+		ramp->setWorldTransform(startTransform);
+		//b3Printf("Inclination of ramp changed to %f",inclination );
+	}
+}
+
+void onRampFrictionChanged(float friction){
+	if(ramp){
+		ramp->setFriction(friction);
+		//b3Printf("Friction of ramp changed to %f \n",friction );
+	}
+}
+
+void onRampRestitutionChanged(float restitution){
+	if(ramp){
+		ramp->setRestitution(restitution);
+		//b3Printf("Restitution of ramp changed to %f \n",restitution);
+	}
+}
+
+
+CommonExampleInterface*    ET_InclinedPlaneCreateFunc(CommonExampleOptions& options)
+{
+	return new InclinedPlaneExample(options.m_guiHelper);
+}
diff --git a/examples/ExtendedTutorials/InclinedPlane.h b/examples/ExtendedTutorials/InclinedPlane.h
new file mode 100644
index 0000000..23ea92d
--- /dev/null
+++ b/examples/ExtendedTutorials/InclinedPlane.h
@@ -0,0 +1,22 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2015 Google Inc. http://bulletphysics.org
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef ET_INCLINED_PLANE_EXAMPLE_H
+#define ET_INCLINED_PLANE_EXAMPLE_H
+
+class CommonExampleInterface*    ET_InclinedPlaneCreateFunc(struct CommonExampleOptions& options);
+
+
+#endif //ET_INCLINED_PLANE_EXAMPLE_H
diff --git a/examples/ExtendedTutorials/MultiPendulum.cpp b/examples/ExtendedTutorials/MultiPendulum.cpp
new file mode 100644
index 0000000..0d29ce1
--- /dev/null
+++ b/examples/ExtendedTutorials/MultiPendulum.cpp
@@ -0,0 +1,418 @@
+/*
+ Bullet Continuous Collision Detection and Physics Library
+ Copyright (c) 2015 Google Inc. http://bulletphysics.org
+
+ This software is provided 'as-is', without any express or implied warranty.
+ In no event will the authors be held liable for any damages arising from the use of this software.
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it freely,
+ subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include "MultiPendulum.h"
+
+#include <vector> // TODO: Should I use another data structure?
+#include <iterator>
+
+#include "btBulletDynamicsCommon.h"
+#include "LinearMath/btVector3.h"
+#include "LinearMath/btAlignedObjectArray.h"
+#include "../CommonInterfaces/CommonRigidBodyBase.h"
+#include "../CommonInterfaces/CommonParameterInterface.h"
+
+static btScalar gPendulaQty = 2; //TODO: This would actually be an Integer, but the Slider does not like integers, so I floor it when changed
+
+static btScalar gDisplacedPendula = 1; //TODO: This is an int as well
+
+static btScalar gPendulaRestitution = 1; // Default pendulum restitution is 1 to restore all force
+
+static btScalar gSphereRadius = 1; // The sphere radius
+
+static btScalar gCurrentPendulumLength = 8;
+
+static btScalar gInitialPendulumLength = 8; // Default pendulum length (distance between two spheres)
+
+static btScalar gDisplacementForce = 30; // The default force with which we move the pendulum
+
+struct MultiPendulumExample: public CommonRigidBodyBase {
+	MultiPendulumExample(struct GUIHelperInterface* helper) :
+		CommonRigidBodyBase(helper) {
+	}
+
+	virtual ~MultiPendulumExample() {
+	}
+
+	virtual void initPhysics(); // build a multi pendulum
+
+	virtual void renderScene(); // render the scene to screen
+
+	virtual void createMultiPendulum(btSphereShape* colShape,
+		btScalar pendulaQty, btScalar xPosition, btScalar yPosition,btScalar zPosition,
+		btScalar length, btScalar mass); // create a multi pendulum at the indicated x and y position, the specified number of pendula formed into a chain, each with indicated length and mass
+
+	virtual void changePendulaLength(btScalar length); // change the pendulum length
+
+	virtual void changePendulaRestitution(btScalar restitution); // change the pendula restitution
+
+	virtual void stepSimulation(float deltaTime); // step the simulation
+
+	virtual bool keyboardCallback(int key, int state); // handle keyboard callbacks
+
+	void resetCamera() {
+		float dist = 41;
+		float pitch = 52;
+		float yaw = 35;
+		float targetPos[3] = { 0, 0.46, 0 };
+		m_guiHelper->resetCamera(dist, pitch, yaw, targetPos[0], targetPos[1],
+			targetPos[2]);
+	}
+
+	std::vector<btSliderConstraint*> constraints; // keep a handle to the slider constraints
+
+	std::vector<btRigidBody*> pendula; // keep a handle to the pendula
+};
+
+static MultiPendulumExample* mex = NULL; // Handle to the example to access it via functions. Do not use this in your simulation!
+
+void onMultiPendulaLengthChanged(float pendulaLength); // Change the pendula length
+
+void onMultiPendulaRestitutionChanged(float pendulaRestitution); // change the pendula restitution
+
+void floorMSliderValue(float notUsed); // floor the slider values which should be integers
+
+void MultiPendulumExample::initPhysics() { // Setup your physics scene
+
+	{ // create a slider to change the number of pendula
+		SliderParams slider("Number of Pendula", &gPendulaQty);
+		slider.m_minVal = 1;
+		slider.m_maxVal = 50;
+		slider.m_callback = floorMSliderValue; // hack to get integer values
+		slider.m_clampToNotches = false;
+		m_guiHelper->getParameterInterface()->registerSliderFloatParameter(
+			slider);
+	}
+
+	{ // create a slider to change the number of displaced pendula
+		SliderParams slider("Number of Displaced Pendula", &gDisplacedPendula);
+		slider.m_minVal = 0;
+		slider.m_maxVal = 49;
+		slider.m_callback = floorMSliderValue; // hack to get integer values
+		slider.m_clampToNotches = false;
+		m_guiHelper->getParameterInterface()->registerSliderFloatParameter(
+			slider);
+	}
+
+	{ // create a slider to change the pendula restitution
+		SliderParams slider("Pendula Restitution", &gPendulaRestitution);
+		slider.m_minVal = 0;
+		slider.m_maxVal = 1;
+		slider.m_clampToNotches = false;
+		slider.m_callback = onMultiPendulaRestitutionChanged;
+		m_guiHelper->getParameterInterface()->registerSliderFloatParameter(
+			slider);
+	}
+
+	{ // create a slider to change the pendulum length
+		SliderParams slider("Pendula Length", &gCurrentPendulumLength);
+		slider.m_minVal = 0;
+		slider.m_maxVal = 49;
+		slider.m_clampToNotches = false;
+		slider.m_callback = onMultiPendulaLengthChanged;
+		m_guiHelper->getParameterInterface()->registerSliderFloatParameter(
+			slider);
+	}
+
+	{ // create a slider to change the force to displace the lowest pendulum
+		SliderParams slider("Displacement force", &gDisplacementForce);
+		slider.m_minVal = 0.1;
+		slider.m_maxVal = 200;
+		slider.m_clampToNotches = false;
+		m_guiHelper->getParameterInterface()->registerSliderFloatParameter(
+			slider);
+	}
+
+	m_guiHelper->setUpAxis(1);
+
+	createEmptyDynamicsWorld();
+
+	// create a debug drawer
+	m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
+	if (m_dynamicsWorld->getDebugDrawer())
+		m_dynamicsWorld->getDebugDrawer()->setDebugMode(
+			btIDebugDraw::DBG_DrawWireframe
+				+ btIDebugDraw::DBG_DrawContactPoints
+				+ btIDebugDraw::DBG_DrawConstraints
+				+ btIDebugDraw::DBG_DrawConstraintLimits);
+
+	{ // create the multipendulum starting at the indicated position below and where each pendulum has the following mass
+		btScalar pendulumMass(1.f);
+
+		btScalar xPosition(0.0f); // initial top-most pendulum position
+		btScalar yPosition(15.0f);
+		btScalar zPosition(0.0f);
+
+		// Re-using the same collision is better for memory usage and performance
+		btSphereShape* pendulumShape = new btSphereShape(gSphereRadius);
+		m_collisionShapes.push_back(pendulumShape);
+
+		// create multi-pendulum
+		createMultiPendulum(pendulumShape, floor(gPendulaQty), xPosition, yPosition,zPosition,
+			gInitialPendulumLength, pendulumMass);
+	}
+
+	m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
+}
+
+void MultiPendulumExample::stepSimulation(float deltaTime) {
+	if (m_dynamicsWorld) {
+		m_dynamicsWorld->stepSimulation(deltaTime);
+	}
+
+}
+
+void MultiPendulumExample::createMultiPendulum(btSphereShape* colShape,
+	btScalar pendulaQty, btScalar xPosition, btScalar yPosition, btScalar zPosition,
+	btScalar length, btScalar mass) {
+
+	// The multi-pendulum looks like this (names when built):
+	//..........0......./.......1...../.......2......./..etc...:pendulum build iterations
+	// O   parentSphere
+	// |
+	// O   childSphere  / parentSphere
+	// |
+	// O   ............./ childSphere / parentSphere
+	// |
+	// O   .........................../ childSphere
+	// etc.
+
+	//create the top element of the pendulum
+	btTransform startTransform;
+	startTransform.setIdentity();
+
+	// position the top sphere
+	startTransform.setOrigin(
+		btVector3(btScalar(xPosition), btScalar(yPosition), btScalar(zPosition)));
+
+	startTransform.setRotation(btQuaternion(0, 0, 0, 1)); // zero rotation
+
+	btRigidBody* topSphere = createRigidBody(mass, startTransform, colShape);
+
+	// disable the deactivation when object does not move anymore
+	topSphere->setActivationState(DISABLE_DEACTIVATION);
+
+	//make top sphere position "fixed" in the world by attaching it to a the world with a point to point constraint
+	// The pivot is defined in the reference frame of topSphere, so the attachment should be exactly at the center of topSphere
+	btVector3 constraintPivot(0.0f, 0.0f, 0.0f);
+	btPoint2PointConstraint* p2pconst = new btPoint2PointConstraint(
+		*topSphere, constraintPivot);
+
+	p2pconst->setDbgDrawSize(btScalar(5.f)); // set the size of the debug drawing
+
+	// add the constraint to the world
+	m_dynamicsWorld->addConstraint(p2pconst, true);
+
+	btRigidBody* parentSphere = topSphere; // set the top sphere as the parent sphere for the next sphere to be created
+
+	for (int i = 0; i < pendulaQty; i++) { // produce the number of pendula
+
+		// create joint element to make the pendulum rotate it
+
+		// position the joint sphere at the same position as the top sphere
+		startTransform.setOrigin(
+			btVector3(btScalar(xPosition), btScalar(yPosition - length*(i)),
+				btScalar(0)));
+
+		startTransform.setRotation(btQuaternion(0, 0, 0, 1)); // zero rotation
+
+		btRigidBody* jointSphere = createRigidBody(mass, startTransform,
+			colShape);
+		jointSphere->setFriction(0); // we do not need friction here
+
+		// disable the deactivation when object does not move anymore
+		jointSphere->setActivationState(DISABLE_DEACTIVATION);
+
+		//create constraint between parentSphere and jointSphere
+		// this is represented by the constraint pivot in the local frames of reference of both constrained spheres
+		btTransform constraintPivotInParentSphereRF, constraintPivotInJointSphereRF;
+
+		constraintPivotInParentSphereRF.setIdentity();
+		constraintPivotInJointSphereRF.setIdentity();
+
+		// the orientation of a point-to-point constraint does not matter, as is has no rotational limits
+
+		//Obtain the position of parentSphere in local reference frame of the jointSphere (the pivot is therefore in the center of parentSphere)
+		btVector3 parentSphereInJointSphereRF =
+			(jointSphere->getWorldTransform().inverse()(
+				parentSphere->getWorldTransform().getOrigin()));
+		constraintPivotInJointSphereRF.setOrigin(parentSphereInJointSphereRF);
+
+		btPoint2PointConstraint* p2pconst = new btPoint2PointConstraint(
+			*parentSphere,*jointSphere,constraintPivotInParentSphereRF.getOrigin(), constraintPivotInJointSphereRF.getOrigin());
+
+		p2pconst->setDbgDrawSize(btScalar(5.f)); // set the size of the debug drawing
+
+		// add the constraint to the world
+		m_dynamicsWorld->addConstraint(p2pconst, true);
+
+		// create a slider constraint to change the length of the pendula while it swings
+
+		startTransform.setIdentity(); // reset start transform
+
+		// position the child sphere below the joint sphere
+		startTransform.setOrigin(
+			btVector3(btScalar(xPosition), btScalar(yPosition - length*(i+1)),
+				btScalar(0)));
+
+		startTransform.setRotation(btQuaternion(0, 0, 0, 1)); // zero rotation
+
+		btRigidBody* childSphere = createRigidBody(mass, startTransform,
+			colShape);
+		childSphere->setFriction(0); // we do not need friction here
+		pendula.push_back(childSphere);
+
+		// disable the deactivation when object does not move anymore
+		childSphere->setActivationState(DISABLE_DEACTIVATION);
+
+		//create slider constraint between jointSphere and childSphere
+		// this is represented by the constraint pivot in the local frames of reference of both constrained spheres
+		// furthermore we need to rotate the constraint appropriately to orient it correctly in space
+		btTransform constraintPivotInChildSphereRF;
+
+		constraintPivotInJointSphereRF.setIdentity();
+		constraintPivotInChildSphereRF.setIdentity();
+
+		// the orientation of a point-to-point constraint does not matter, as is has no rotational limits
+
+		//Obtain the position of jointSphere in local reference frame of the childSphere (the pivot is therefore in the center of jointSphere)
+		btVector3 jointSphereInChildSphereRF =
+			(childSphere->getWorldTransform().inverse()(
+				jointSphere->getWorldTransform().getOrigin()));
+		constraintPivotInChildSphereRF.setOrigin(jointSphereInChildSphereRF);
+
+		// the slider constraint is x aligned per default, but we want it to be y aligned, therefore we rotate it
+		btQuaternion qt;
+		qt.setEuler(0, 0, -SIMD_HALF_PI);
+		constraintPivotInJointSphereRF.setRotation(qt); //we use Y like up Axis
+		constraintPivotInChildSphereRF.setRotation(qt); //we use Y like up Axis
+
+		btSliderConstraint* sliderConst = new btSliderConstraint(*jointSphere,
+			*childSphere, constraintPivotInJointSphereRF, constraintPivotInChildSphereRF, true);
+
+		sliderConst->setDbgDrawSize(btScalar(5.f)); // set the size of the debug drawing
+
+		// set limits
+		// the initial setup of the constraint defines the origins of the limit dimensions,
+		// therefore we set both limits directly to the current position of the parentSphere
+		sliderConst->setLowerLinLimit(btScalar(0));
+		sliderConst->setUpperLinLimit(btScalar(0));
+		sliderConst->setLowerAngLimit(btScalar(0));
+		sliderConst->setUpperAngLimit(btScalar(0));
+		constraints.push_back(sliderConst);
+
+		// add the constraint to the world
+		m_dynamicsWorld->addConstraint(sliderConst, true);
+		parentSphere = childSphere;
+	}
+}
+
+void MultiPendulumExample::changePendulaLength(btScalar length) {
+	btScalar lowerLimit = -gInitialPendulumLength;
+	for (std::vector<btSliderConstraint*>::iterator sit = constraints.begin();
+		sit != constraints.end(); sit++) {
+		btAssert((*sit) && "Null constraint");
+
+		// if the pendulum is being shortened beyond it's own length, we don't let the lower sphere to go past the upper one
+		if (lowerLimit <= length) {
+			(*sit)->setLowerLinLimit(length + lowerLimit);
+			(*sit)->setUpperLinLimit(length + lowerLimit);
+		}
+	}
+}
+
+void MultiPendulumExample::changePendulaRestitution(btScalar restitution) {
+	for (std::vector<btRigidBody*>::iterator rit = pendula.begin();
+		rit != pendula.end(); rit++) {
+		btAssert((*rit) && "Null constraint");
+
+		(*rit)->setRestitution(restitution);
+	}
+}
+
+void MultiPendulumExample::renderScene() {
+	CommonRigidBodyBase::renderScene();
+}
+
+bool MultiPendulumExample::keyboardCallback(int key, int state) {
+
+	//b3Printf("Key pressed: %d in state %d \n",key,state);
+
+	//key 1, key 2, key 3
+	switch (key) {
+	case 49 /*ASCII for 1*/: {
+
+		//assumption: Sphere are aligned in Z axis
+		btScalar newLimit = btScalar(gCurrentPendulumLength + 0.1);
+
+		changePendulaLength(newLimit);
+		gCurrentPendulumLength = newLimit;
+
+		b3Printf("Increase pendulum length to %f", gCurrentPendulumLength);
+		return true;
+	}
+	case 50 /*ASCII for 2*/: {
+
+		//assumption: Sphere are aligned in Z axis
+		btScalar newLimit = btScalar(gCurrentPendulumLength - 0.1);
+
+		//is being shortened beyond it's own length, we don't let the lower sphere to go over the upper one
+		if (0 <= newLimit) {
+			changePendulaLength(newLimit);
+			gCurrentPendulumLength = newLimit;
+		}
+
+		b3Printf("Decrease pendulum length to %f", gCurrentPendulumLength);
+		return true;
+	}
+	case 51 /*ASCII for 3*/: {
+		for (int i = floor(gPendulaQty)-1; i >= gPendulaQty-gDisplacedPendula; i--) {
+			if (gDisplacedPendula >= 0 && gDisplacedPendula < gPendulaQty)
+				pendula[i]->applyCentralForce(btVector3(gDisplacementForce, 0, 0));
+		}
+		return true;
+	}
+	}
+
+	return false;
+}
+
+// GUI parameter modifiers
+
+void onMultiPendulaLengthChanged(float pendulaLength) { // Change the pendula length
+	if (mex){
+		mex->changePendulaLength(pendulaLength);
+	}
+	//b3Printf("Pendula length changed to %f \n",sliderValue );
+
+}
+
+void onMultiPendulaRestitutionChanged(float pendulaRestitution) { // change the pendula restitution
+	if (mex){
+		mex->changePendulaRestitution(pendulaRestitution);
+	}
+
+}
+
+void floorMSliderValue(float notUsed) { // floor the slider values which should be integers
+	gPendulaQty = floor(gPendulaQty);
+	gDisplacedPendula = floor(gDisplacedPendula);
+}
+
+CommonExampleInterface* ET_MultiPendulumCreateFunc(
+	CommonExampleOptions& options) {
+	mex = new MultiPendulumExample(options.m_guiHelper);
+	return mex;
+}
diff --git a/examples/ExtendedTutorials/MultiPendulum.h b/examples/ExtendedTutorials/MultiPendulum.h
new file mode 100644
index 0000000..336c1be
--- /dev/null
+++ b/examples/ExtendedTutorials/MultiPendulum.h
@@ -0,0 +1,22 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2015 Google Inc. http://bulletphysics.org
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef ET_MULTI_PENDULUM_EXAMPLE_H
+#define ET_MULTI_PENDULUM_EXAMPLE_H
+
+class CommonExampleInterface*    ET_MultiPendulumCreateFunc(struct CommonExampleOptions& options);
+
+
+#endif //ET_MULTI_PENDULUM_EXAMPLE_H
diff --git a/examples/ExtendedTutorials/NewtonsCradle.cpp b/examples/ExtendedTutorials/NewtonsCradle.cpp
new file mode 100644
index 0000000..a1c51f1
--- /dev/null
+++ b/examples/ExtendedTutorials/NewtonsCradle.cpp
@@ -0,0 +1,350 @@
+/*
+ Bullet Continuous Collision Detection and Physics Library
+ Copyright (c) 2015 Google Inc. http://bulletphysics.org
+
+ This software is provided 'as-is', without any express or implied warranty.
+ In no event will the authors be held liable for any damages arising from the use of this software.
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it freely,
+ subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include "NewtonsCradle.h"
+
+#include <vector> // TODO: Should I use another data structure?
+#include <iterator>
+
+#include "btBulletDynamicsCommon.h"
+#include "LinearMath/btVector3.h"
+#include "LinearMath/btAlignedObjectArray.h" 
+#include "../CommonInterfaces/CommonRigidBodyBase.h"
+#include "../CommonInterfaces/CommonParameterInterface.h"
+
+static btScalar gPendulaQty = 5; // Number of pendula in newton's cradle
+//TODO: This would actually be an Integer, but the Slider does not like integers, so I floor it when changed
+
+static btScalar gDisplacedPendula = 1; // number of displaced pendula
+//TODO: This is an int as well
+
+static btScalar gPendulaRestitution = 1; // pendula restition when hitting against each other
+
+static btScalar gSphereRadius = 1; // pendula radius
+
+static btScalar gCurrentPendulumLength = 8; // current pendula length
+
+static btScalar gInitialPendulumLength = 8; // default pendula length
+
+static btScalar gForcingForce = 30; // default force to displace the pendula
+
+struct NewtonsCradleExample: public CommonRigidBodyBase {
+	NewtonsCradleExample(struct GUIHelperInterface* helper) :
+		CommonRigidBodyBase(helper) {
+	}
+	virtual ~NewtonsCradleExample() {
+	}
+	virtual void initPhysics();
+	virtual void renderScene();
+	virtual void createPendulum(btSphereShape* colShape, btScalar xPosition,
+		btScalar yPosition, btScalar zPosition, btScalar length, btScalar mass);
+	virtual void changePendulaLength(btScalar length);
+	virtual void changePendulaRestitution(btScalar restitution);
+	virtual void stepSimulation(float deltaTime);
+	virtual bool keyboardCallback(int key, int state);
+	void resetCamera() {
+		float dist = 41;
+		float pitch = 52;
+		float yaw = 35;
+		float targetPos[3] = { 0, 0.46, 0 };
+		m_guiHelper->resetCamera(dist, pitch, yaw, targetPos[0], targetPos[1],
+			targetPos[2]);
+	}
+
+	std::vector<btSliderConstraint*> constraints;
+	std::vector<btRigidBody*> pendula;
+};
+
+static NewtonsCradleExample* nex = NULL;
+
+void onPendulaLengthChanged(float pendulaLength);
+
+void onPendulaRestitutionChanged(float pendulaRestitution);
+
+void floorSliderValue(float notUsed);
+
+void NewtonsCradleExample::initPhysics() {
+
+	{ // create a slider to change the number of pendula
+		SliderParams slider("Number of Pendula", &gPendulaQty);
+		slider.m_minVal = 1;
+		slider.m_maxVal = 50;
+		slider.m_callback = floorSliderValue; // hack to get integer values
+		slider.m_clampToNotches = false;
+		m_guiHelper->getParameterInterface()->registerSliderFloatParameter(
+			slider);
+	}
+
+	{ // create a slider to change the number of displaced pendula
+		SliderParams slider("Number of Displaced Pendula", &gDisplacedPendula);
+		slider.m_minVal = 0;
+		slider.m_maxVal = 49;
+		slider.m_callback = floorSliderValue; // hack to get integer values
+		slider.m_clampToNotches = false;
+		m_guiHelper->getParameterInterface()->registerSliderFloatParameter(
+			slider);
+	}
+
+	{ // create a slider to change the pendula restitution
+		SliderParams slider("Pendula Restitution", &gPendulaRestitution);
+		slider.m_minVal = 0;
+		slider.m_maxVal = 1;
+		slider.m_clampToNotches = false;
+		slider.m_callback = onPendulaRestitutionChanged;
+		m_guiHelper->getParameterInterface()->registerSliderFloatParameter(
+			slider);
+	}
+
+	{ // create a slider to change the pendulum length
+		SliderParams slider("Pendula Length", &gCurrentPendulumLength);
+		slider.m_minVal = 0;
+		slider.m_maxVal = 49;
+		slider.m_clampToNotches = false;
+		slider.m_callback = onPendulaLengthChanged;
+		m_guiHelper->getParameterInterface()->registerSliderFloatParameter(
+			slider);
+	}
+
+	{ // create a slider to change the force to displace the lowest pendulum
+		SliderParams slider("Displacement force", &gForcingForce);
+		slider.m_minVal = 0.1;
+		slider.m_maxVal = 200;
+		slider.m_clampToNotches = false;
+		m_guiHelper->getParameterInterface()->registerSliderFloatParameter(
+			slider);
+	}
+
+	m_guiHelper->setUpAxis(1);
+
+	createEmptyDynamicsWorld();
+
+	// create a debug drawer
+	m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
+	if (m_dynamicsWorld->getDebugDrawer())
+		m_dynamicsWorld->getDebugDrawer()->setDebugMode(
+			btIDebugDraw::DBG_DrawWireframe
+				+ btIDebugDraw::DBG_DrawContactPoints
+				+ btIDebugDraw::DBG_DrawConstraints
+				+ btIDebugDraw::DBG_DrawConstraintLimits);
+
+	{ // create the pendulum starting at the indicated position below and where each pendulum has the following mass
+		btScalar pendulumMass(1.f);
+
+		btScalar xPosition(0.0f); // initial left-most pendulum position
+		btScalar yPosition(15.0f);
+		btScalar zPosition(0.0f);
+
+		// Re-using the same collision is better for memory usage and performance
+		btSphereShape* pendulumShape = new btSphereShape(gSphereRadius);
+		m_collisionShapes.push_back(pendulumShape);
+
+		for (int i = 0; i < floor(gPendulaQty); i++) {
+
+			// create pendulum
+			createPendulum(pendulumShape, xPosition, yPosition, zPosition,
+				gInitialPendulumLength, pendulumMass);
+
+			// displace the pendula 1.05 sphere size, so that they all nearly touch (small spacings in between
+			xPosition -= 2.1f * gSphereRadius;
+		}
+	}
+
+	m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
+}
+
+void NewtonsCradleExample::stepSimulation(float deltaTime) {
+	if (m_dynamicsWorld) {
+		m_dynamicsWorld->stepSimulation(deltaTime);
+	}
+
+}
+
+void NewtonsCradleExample::createPendulum(btSphereShape* colShape,
+	btScalar xPosition, btScalar yPosition, btScalar zPosition, btScalar length, btScalar mass) {
+
+	// The pendulum looks like this (names when built):
+	// O   topSphere
+	// |
+	// O   bottomSphere
+
+	//create a dynamic pendulum
+	btTransform startTransform;
+	startTransform.setIdentity();
+
+	// position the top sphere above ground with a moving x position
+	startTransform.setOrigin(
+		btVector3(btScalar(xPosition), btScalar(yPosition), btScalar(zPosition)));
+	startTransform.setRotation(btQuaternion(0, 0, 0, 1)); // zero rotation
+	btRigidBody* topSphere = createRigidBody(mass, startTransform, colShape);
+
+	// position the bottom sphere below the top sphere
+	startTransform.setOrigin(
+		btVector3(btScalar(xPosition), btScalar(yPosition - length),
+			btScalar(zPosition)));
+
+	startTransform.setRotation(btQuaternion(0, 0, 0, 1)); // zero rotation
+	btRigidBody* bottomSphere = createRigidBody(mass, startTransform, colShape);
+	bottomSphere->setFriction(0); // we do not need friction here
+	pendula.push_back(bottomSphere);
+
+	// disable the deactivation when objects do not move anymore
+	topSphere->setActivationState(DISABLE_DEACTIVATION);
+	bottomSphere->setActivationState(DISABLE_DEACTIVATION);
+
+	bottomSphere->setRestitution(gPendulaRestitution); // set pendula restitution
+
+	//make the top sphere position "fixed" to the world by attaching with a point to point constraint
+	// The pivot is defined in the reference frame of topSphere, so the attachment is exactly at the center of the topSphere
+	btVector3 constraintPivot(btVector3(0.0f, 0.0f, 0.0f));
+	btPoint2PointConstraint* p2pconst = new btPoint2PointConstraint(*topSphere,
+		constraintPivot);
+
+	p2pconst->setDbgDrawSize(btScalar(5.f)); // set the size of the debug drawing
+
+	// add the constraint to the world
+	m_dynamicsWorld->addConstraint(p2pconst, true);
+
+	//create constraint between spheres
+	// this is represented by the constraint pivot in the local frames of reference of both constrained spheres
+	// furthermore we need to rotate the constraint appropriately to orient it correctly in space
+	btTransform constraintPivotInTopSphereRF, constraintPivotInBottomSphereRF;
+
+	constraintPivotInTopSphereRF.setIdentity();
+	constraintPivotInBottomSphereRF.setIdentity();
+
+	// the slider constraint is x aligned per default, but we want it to be y aligned, therefore we rotate it
+	btQuaternion qt;
+	qt.setEuler(0, 0, -SIMD_HALF_PI);
+	constraintPivotInTopSphereRF.setRotation(qt); //we use Y like up Axis
+	constraintPivotInBottomSphereRF.setRotation(qt); //we use Y like up Axis
+
+	//Obtain the position of topSphere in local reference frame of bottomSphere (the pivot is therefore in the center of topSphere)
+	btVector3 topSphereInBottomSphereRF =
+		(bottomSphere->getWorldTransform().inverse()(
+			topSphere->getWorldTransform().getOrigin()));
+	constraintPivotInBottomSphereRF.setOrigin(topSphereInBottomSphereRF);
+
+	btSliderConstraint* sliderConst = new btSliderConstraint(*topSphere,
+		*bottomSphere, constraintPivotInTopSphereRF, constraintPivotInBottomSphereRF, true);
+
+	sliderConst->setDbgDrawSize(btScalar(5.f)); // set the size of the debug drawing
+
+	// set limits
+	// the initial setup of the constraint defines the origins of the limit dimensions,
+	// therefore we set both limits directly to the current position of the topSphere
+	sliderConst->setLowerLinLimit(btScalar(0));
+	sliderConst->setUpperLinLimit(btScalar(0));
+	sliderConst->setLowerAngLimit(btScalar(0));
+	sliderConst->setUpperAngLimit(btScalar(0));
+	constraints.push_back(sliderConst);
+
+	// add the constraint to the world
+	m_dynamicsWorld->addConstraint(sliderConst, true);
+}
+
+void NewtonsCradleExample::changePendulaLength(btScalar length) {
+	btScalar lowerLimit = -gInitialPendulumLength;
+	for (std::vector<btSliderConstraint*>::iterator sit = constraints.begin();
+		sit != constraints.end(); sit++) {
+		btAssert((*sit) && "Null constraint");
+
+		//if the pendulum is being shortened beyond it's own length, we don't let the lower sphere to go past the upper one
+		if (lowerLimit <= length) {
+			(*sit)->setLowerLinLimit(length + lowerLimit);
+			(*sit)->setUpperLinLimit(length + lowerLimit);
+		}
+	}
+}
+
+void NewtonsCradleExample::changePendulaRestitution(btScalar restitution) {
+	for (std::vector<btRigidBody*>::iterator rit = pendula.begin();
+		rit != pendula.end(); rit++) {
+		btAssert((*rit) && "Null constraint");
+
+		(*rit)->setRestitution(restitution);
+	}
+}
+
+void NewtonsCradleExample::renderScene() {
+	CommonRigidBodyBase::renderScene();
+}
+
+bool NewtonsCradleExample::keyboardCallback(int key, int state) {
+	//b3Printf("Key pressed: %d in state %d \n",key,state);
+
+	//key 1, key 2, key 3
+	switch (key) {
+	case 49 /*ASCII for 1*/: {
+
+		//assumption: Sphere are aligned in Z axis
+		btScalar newLimit = btScalar(gCurrentPendulumLength + 0.1);
+
+		changePendulaLength(newLimit);
+		gCurrentPendulumLength = newLimit;
+
+		b3Printf("Increase pendulum length to %f", gCurrentPendulumLength);
+		return true;
+	}
+	case 50 /*ASCII for 2*/: {
+
+		//assumption: Sphere are aligned in Z axis
+		btScalar newLimit = btScalar(gCurrentPendulumLength - 0.1);
+
+		//is being shortened beyond it's own length, we don't let the lower sphere to go over the upper one
+		if (0 <= newLimit) {
+			changePendulaLength(newLimit);
+			gCurrentPendulumLength = newLimit;
+		}
+
+		b3Printf("Decrease pendulum length to %f", gCurrentPendulumLength);
+		return true;
+	}
+	case 51 /*ASCII for 3*/: {
+		for (int i = 0; i < gDisplacedPendula; i++) {
+			if (gDisplacedPendula >= 0 && gDisplacedPendula <= gPendulaQty)
+				pendula[i]->applyCentralForce(btVector3(gForcingForce, 0, 0));
+		}
+		return true;
+	}
+	}
+
+	return false;
+}
+
+// GUI parameter modifiers
+
+void onPendulaLengthChanged(float pendulaLength) {
+	if (nex){
+		nex->changePendulaLength(pendulaLength);
+		//b3Printf("Pendula length changed to %f \n",sliderValue );
+	}
+}
+
+void onPendulaRestitutionChanged(float pendulaRestitution) {
+	if (nex){
+		nex->changePendulaRestitution(pendulaRestitution);
+	}
+}
+
+void floorSliderValue(float notUsed) {
+	gPendulaQty = floor(gPendulaQty);
+	gDisplacedPendula = floor(gDisplacedPendula);
+}
+
+CommonExampleInterface* ET_NewtonsCradleCreateFunc(
+	CommonExampleOptions& options) {
+	nex = new NewtonsCradleExample(options.m_guiHelper);
+	return nex;
+}
diff --git a/examples/ExtendedTutorials/NewtonsCradle.h b/examples/ExtendedTutorials/NewtonsCradle.h
new file mode 100644
index 0000000..9b9e2f2
--- /dev/null
+++ b/examples/ExtendedTutorials/NewtonsCradle.h
@@ -0,0 +1,22 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2015 Google Inc. http://bulletphysics.org
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef ET_NEWTONIAN_PENDULUM_EXAMPLE_H
+#define ET_NEWTONIAN_PENDULUM_EXAMPLE_H
+
+class CommonExampleInterface*    ET_NewtonsCradleCreateFunc(struct CommonExampleOptions& options);
+
+
+#endif //ET_NEWTONIAN_PENDULUM_EXAMPLE_H
