diff --git a/src/rigidBodyDynamics/Make/files b/src/rigidBodyDynamics/Make/files
index 7fc99c209a797ae7b5b52ce687e55b1ad99f6d9c..1e658c85e9668953926489b8e68ab7401fe04227 100644
--- a/src/rigidBodyDynamics/Make/files
+++ b/src/rigidBodyDynamics/Make/files
@@ -5,7 +5,9 @@ bodies/subBody/subBody.C
 bodies/sphere/sphere.C
 
 joints/joint/joint.C
-joints/nullJoint/nullJoint.C
+joints/null/nullJoint.C
+joints/composite/compositeJoint.C
+joints/floating/floatingJoint.C
 
 joints/Rx/Rx.C
 joints/Ry/Ry.C
diff --git a/src/rigidBodyDynamics/joints/Pa/Pa.C b/src/rigidBodyDynamics/joints/Pa/Pa.C
index 2263ce3283b06b378d057267aaa75b1f32a217e8..0bdfa0a42b439bcbebcda9d58aac5b0f91318d08 100644
--- a/src/rigidBodyDynamics/joints/Pa/Pa.C
+++ b/src/rigidBodyDynamics/joints/Pa/Pa.C
@@ -54,7 +54,7 @@ Foam::RBD::joints::Pa::Pa(const vector& axis)
 :
     joint(1)
 {
-    S_[0] = spatialVector(Zero, axis);
+    S_[0] = spatialVector(Zero, axis/mag(axis));
 }
 
 
@@ -62,7 +62,8 @@ Foam::RBD::joints::Pa::Pa(const dictionary& dict)
 :
     joint(1)
 {
-    S_[0] = spatialVector(Zero, dict.lookup("axis"));
+    vector axis(dict.lookup("axis"));
+    S_[0] = spatialVector(Zero, axis/mag(axis));
 }
 
 
@@ -95,4 +96,12 @@ void Foam::RBD::joints::Pa::jcalc
 }
 
 
+void Foam::RBD::joints::Pa::write(Ostream& os) const
+{
+    joint::write(os);
+    os.writeKeyword("axis")
+        << S_[0].l() << token::END_STATEMENT << nl;
+}
+
+
 // ************************************************************************* //
diff --git a/src/rigidBodyDynamics/joints/Pa/Pa.H b/src/rigidBodyDynamics/joints/Pa/Pa.H
index 09f7eee7532a73360be052ebc5538230508129cb..f27a8c850a03e2a1eb6ff2137aee483231d76710 100644
--- a/src/rigidBodyDynamics/joints/Pa/Pa.H
+++ b/src/rigidBodyDynamics/joints/Pa/Pa.H
@@ -95,6 +95,9 @@ public:
             const scalarField& w,
             const scalarField& qDot
         ) const;
+
+        //- Write
+        virtual void write(Ostream&) const;
 };
 
 
diff --git a/src/rigidBodyDynamics/joints/Ra/Ra.C b/src/rigidBodyDynamics/joints/Ra/Ra.C
index 6d9e6aa5fe917cee8ecffe174b54457d3bfe2520..926f56a3b8f39c1ec198c7a0443d88a9b3a00481 100644
--- a/src/rigidBodyDynamics/joints/Ra/Ra.C
+++ b/src/rigidBodyDynamics/joints/Ra/Ra.C
@@ -54,7 +54,7 @@ Foam::RBD::joints::Ra::Ra(const vector& axis)
 :
     joint(1)
 {
-    S_[0] = spatialVector(axis, Zero);
+    S_[0] = spatialVector(axis/mag(axis), Zero);
 }
 
 
@@ -62,7 +62,8 @@ Foam::RBD::joints::Ra::Ra(const dictionary& dict)
 :
     joint(1)
 {
-    S_[0] = spatialVector(dict.lookup("axis"), Zero);
+    vector axis(dict.lookup("axis"));
+    S_[0] = spatialVector(axis/mag(axis), Zero);
 }
 
 
@@ -95,4 +96,12 @@ void Foam::RBD::joints::Ra::jcalc
 }
 
 
+void Foam::RBD::joints::Ra::write(Ostream& os) const
+{
+    joint::write(os);
+    os.writeKeyword("axis")
+        << S_[0].w() << token::END_STATEMENT << nl;
+}
+
+
 // ************************************************************************* //
diff --git a/src/rigidBodyDynamics/joints/Ra/Ra.H b/src/rigidBodyDynamics/joints/Ra/Ra.H
index d098b2c82e3a7083ebd9484f52b3eb5a037c211a..def3724c13f046e7478d894f15e1102f2eb85606 100644
--- a/src/rigidBodyDynamics/joints/Ra/Ra.H
+++ b/src/rigidBodyDynamics/joints/Ra/Ra.H
@@ -95,6 +95,9 @@ public:
             const scalarField& w,
             const scalarField& qDot
         ) const;
+
+        //- Write
+        virtual void write(Ostream&) const;
 };
 
 
diff --git a/src/rigidBodyDynamics/joints/composite/compositeJoint.C b/src/rigidBodyDynamics/joints/composite/compositeJoint.C
new file mode 100644
index 0000000000000000000000000000000000000000..28044e94935dfa1134e3f37e0eff3ac8cc943775
--- /dev/null
+++ b/src/rigidBodyDynamics/joints/composite/compositeJoint.C
@@ -0,0 +1,115 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "compositeJoint.H"
+#include "rigidBodyModel.H"
+#include "addToRunTimeSelectionTable.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace RBD
+{
+namespace joints
+{
+    defineTypeNameAndDebug(composite, 0);
+
+    addToRunTimeSelectionTable
+    (
+        joint,
+        composite,
+        dictionary
+    );
+}
+}
+}
+
+
+// * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * * //
+
+void Foam::RBD::joints::composite::setLastJoint()
+{
+    last().joint::operator=(*this);
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::RBD::joints::composite::composite(const PtrList<joint>& joints)
+:
+    PtrList<joint>(joints),
+    joint(last())
+{}
+
+
+Foam::RBD::joints::composite::composite(const dictionary& dict)
+:
+    PtrList<joint>(dict.lookup("joints")),
+    joint(last())
+{}
+
+
+Foam::autoPtr<Foam::RBD::joint> Foam::RBD::joints::composite::clone() const
+{
+    return autoPtr<joint>(new composite(*this));
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::RBD::joints::composite::~composite()
+{}
+
+
+// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
+
+Foam::label Foam::RBD::joints::composite::nw() const
+{
+    return last().nw();
+}
+
+
+void Foam::RBD::joints::composite::jcalc
+(
+    joint::XSvc& J,
+    const scalarField& q,
+    const scalarField& w,
+    const scalarField& qDot
+) const
+{
+    last().jcalc(J, q, w, qDot);
+}
+
+
+void Foam::RBD::joints::composite::write(Ostream& os) const
+{
+    joint::write(os);
+    os.writeKeyword("joints");
+    os << static_cast<const PtrList<joint>&>(*this);
+}
+
+
+// ************************************************************************* //
diff --git a/src/rigidBodyDynamics/joints/composite/compositeJoint.H b/src/rigidBodyDynamics/joints/composite/compositeJoint.H
new file mode 100644
index 0000000000000000000000000000000000000000..c3033b4abd08d4b71f96ad2f32a1c5b6f678a128
--- /dev/null
+++ b/src/rigidBodyDynamics/joints/composite/compositeJoint.H
@@ -0,0 +1,131 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::RBD::joints::composite
+
+Description
+    Prismatic joint for translation along the specified arbitrary axis.
+
+    Reference:
+    \verbatim
+        Featherstone, R. (2008).
+        Rigid body dynamics algorithms.
+        Springer.
+        Chapter 4.
+    \endverbatim
+
+SourceFiles
+    composite.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef RBD_joints_composite_H
+#define RBD_joints_composite_H
+
+#include "joint.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace RBD
+{
+
+// Forward declaration of classes
+class rigidBodyModel;
+
+namespace joints
+{
+
+/*---------------------------------------------------------------------------*\
+                         Class composite Declaration
+\*---------------------------------------------------------------------------*/
+
+class composite
+:
+    public PtrList<joint>,
+    public joint
+{
+    // Private member functions
+
+        //- Set the properties of the last joint following construction
+        //  of the body containing the joint
+        void setLastJoint();
+
+
+public:
+
+    //- Runtime type information
+    TypeName("composite");
+
+    //- Allow the rigidBodyModel class to set the last joint state
+    friend class Foam::RBD::rigidBodyModel;
+
+
+    // Constructors
+
+        //- Construct for given PtrList<joint>
+        composite(const PtrList<joint>& joints);
+
+        //- Construct for given model from dictionary
+        composite(const dictionary& dict);
+
+        //- Clone this joint
+        virtual autoPtr<joint> clone() const;
+
+
+    //- Destructor
+    virtual ~composite();
+
+
+    // Member Functions
+
+        //- Return the number of additional state variables need by this joint
+        virtual label nw() const;
+
+        //- Update the model state for this joint
+        virtual void jcalc
+        (
+            joint::XSvc& J,
+            const scalarField& q,
+            const scalarField& w,
+            const scalarField& qDot
+        ) const;
+
+        //- Write
+        virtual void write(Ostream&) const;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace joints
+} // End namespace RBD
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/rigidBodyDynamics/joints/floating/floatingJoint.C b/src/rigidBodyDynamics/joints/floating/floatingJoint.C
new file mode 100644
index 0000000000000000000000000000000000000000..766e6504f696ba26cad44d6f4f60c094b5fbab3f
--- /dev/null
+++ b/src/rigidBodyDynamics/joints/floating/floatingJoint.C
@@ -0,0 +1,108 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "floatingJoint.H"
+#include "rigidBodyModel.H"
+#include "addToRunTimeSelectionTable.H"
+
+#include "Rs.H"
+#include "Rzyx.H"
+#include "Pxyz.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace RBD
+{
+namespace joints
+{
+    defineTypeNameAndDebug(floating, 0);
+
+    addToRunTimeSelectionTable
+    (
+        joint,
+        floating,
+        dictionary
+    );
+}
+}
+}
+
+
+// * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * * //
+
+Foam::autoPtr<Foam::RBD::joints::composite>
+Foam::RBD::joints::floating::sixDoF()
+{
+    PtrList<joint> cj(2);
+    cj.set(0, new joints::Pxyz());
+
+    // The quaternion-based spherical joint could be used
+    // but then w must be set appropriately
+    //cj.set(1, new joints::Rs());
+
+    // Alternatively the Euler-angle joint can be used
+    cj.set(1, new joints::Rzyx());
+
+    return autoPtr<composite>(new composite(cj));
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::RBD::joints::floating::floating()
+:
+    composite(sixDoF())
+{}
+
+
+Foam::RBD::joints::floating::floating(const dictionary& dict)
+:
+    composite(sixDoF())
+{}
+
+
+Foam::autoPtr<Foam::RBD::joint> Foam::RBD::joints::floating::clone() const
+{
+    return autoPtr<joint>(new floating(*this));
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::RBD::joints::floating::~floating()
+{}
+
+
+// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
+
+void Foam::RBD::joints::floating::write(Ostream& os) const
+{
+    joint::write(os);
+}
+
+
+// ************************************************************************* //
diff --git a/src/rigidBodyDynamics/joints/floating/floatingJoint.H b/src/rigidBodyDynamics/joints/floating/floatingJoint.H
new file mode 100644
index 0000000000000000000000000000000000000000..58c314d7840ad18e21540ba18276e485c64c56d0
--- /dev/null
+++ b/src/rigidBodyDynamics/joints/floating/floatingJoint.H
@@ -0,0 +1,110 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::RBD::joints::floating
+
+Description
+    Prismatic joint for translation along the specified arbitrary axis.
+
+    Reference:
+    \verbatim
+        Featherstone, R. (2008).
+        Rigid body dynamics algorithms.
+        Springer.
+        Chapter 4.
+    \endverbatim
+
+SourceFiles
+    floating.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef RBD_joints_floating_H
+#define RBD_joints_floating_H
+
+#include "compositeJoint.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace RBD
+{
+namespace joints
+{
+
+/*---------------------------------------------------------------------------*\
+                         Class floating Declaration
+\*---------------------------------------------------------------------------*/
+
+class floating
+:
+    public composite
+{
+    // Private member functions
+
+        //- Return a list of joints needed to emulate a floating body
+        static autoPtr<composite> sixDoF();
+
+
+public:
+
+    //- Runtime type information
+    TypeName("floating");
+
+
+    // Constructors
+
+        //- Construct
+        floating();
+
+        //- Construct for given model from dictionary
+        floating(const dictionary& dict);
+
+        //- Clone this joint
+        virtual autoPtr<joint> clone() const;
+
+
+    //- Destructor
+    virtual ~floating();
+
+
+    // Member Functions
+
+        //- Write
+        virtual void write(Ostream&) const;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace joints
+} // End namespace RBD
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/rigidBodyDynamics/joints/joint/joint.C b/src/rigidBodyDynamics/joints/joint/joint.C
index 4374990eb5c391c184bbc8e78d484ad1fc92e68e..f13ee347ea9ffd7500b133a5a4f020e271a590de 100644
--- a/src/rigidBodyDynamics/joints/joint/joint.C
+++ b/src/rigidBodyDynamics/joints/joint/joint.C
@@ -25,9 +25,6 @@ License
 
 #include "joint.H"
 #include "rigidBodyModel.H"
-#include "Rs.H"
-#include "Rzyx.H"
-#include "Pxyz.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -81,18 +78,10 @@ Foam::RBD::joint::~joint()
 
 // * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
 
-Foam::PtrList<Foam::RBD::joint> Foam::RBD::joint::floating()
+void Foam::RBD::joint::write(Ostream& os) const
 {
-    PtrList<joint> cj(2);
-    cj.set(0, new joints::Pxyz());
-    //cj.set(1, new joints::Rs());
-    cj.set(1, new joints::Rzyx());
-    return cj;
+    os.writeKeyword("type") << type() << token::END_STATEMENT << nl;
 }
 
 
-void Foam::RBD::joint::write(Ostream& os) const
-{}
-
-
 // ************************************************************************* //
diff --git a/src/rigidBodyDynamics/joints/joint/joint.H b/src/rigidBodyDynamics/joints/joint/joint.H
index 58d68190deee593c092a8c9fc444ba7e3389069d..64258a3f71cf2d13002ff9deac8c334ba6e70472 100644
--- a/src/rigidBodyDynamics/joints/joint/joint.H
+++ b/src/rigidBodyDynamics/joints/joint/joint.H
@@ -61,6 +61,12 @@ namespace RBD
 // Forward declaration of classes
 class rigidBodyModel;
 
+// Forward declaration of friend functions and operators
+class joint;
+
+inline Ostream& operator<<(Ostream&, const joint&);
+
+
 /*---------------------------------------------------------------------------*\
                          Class joint Declaration
 \*---------------------------------------------------------------------------*/
@@ -171,6 +177,17 @@ public:
         //- Clone this joint (needed by PtrList)
         virtual autoPtr<joint> clone() const = 0;
 
+        class iNew
+        {
+
+        public:
+
+            iNew()
+            {}
+
+            inline autoPtr<joint> operator()(Istream& is) const;
+        };
+
 
     //- Destructor
     virtual ~joint();
@@ -207,9 +224,6 @@ public:
         //- Return the joint motion sub-space
         inline const List<spatialVector>& S() const;
 
-        //- Return a list of joints needed to emulate a floating body
-        static PtrList<joint> floating();
-
         //- Update the rigidBodyModel state for the joint given
         //  the joint state q, w and velocity qDot
         virtual void jcalc
@@ -242,6 +256,11 @@ public:
             scalarField& q,
             scalarField& w
         ) const;
+
+
+    // Ostream Operator
+
+        friend Ostream& operator<<(Ostream&, const joint&);
 };
 
 
diff --git a/src/rigidBodyDynamics/joints/joint/jointI.H b/src/rigidBodyDynamics/joints/joint/jointI.H
index 47db466a7db814cfadb6fdc7431ba2326aaaa9cc..0b33fb9322932902ecd167473607ce34c7231782 100644
--- a/src/rigidBodyDynamics/joints/joint/jointI.H
+++ b/src/rigidBodyDynamics/joints/joint/jointI.H
@@ -107,4 +107,26 @@ inline void Foam::RBD::joint::operator()
 }
 
 
+Foam::autoPtr<Foam::RBD::joint> Foam::RBD::joint::iNew::operator()
+(
+    Istream& is
+) const
+{
+    dictionary dict(is);
+    return New(dict);
+}
+
+
+// * * * * * * * * * * * * * * * Ostream Operator  * * * * * * * * * * * * * //
+
+inline Foam::Ostream& Foam::RBD::operator<<(Ostream& os, const joint& j)
+{
+    os  << indent << token::BEGIN_BLOCK << incrIndent << endl;
+    j.write(os);
+    os  << decrIndent << indent << token::END_BLOCK;
+
+    return os;
+}
+
+
 // ************************************************************************* //
diff --git a/src/rigidBodyDynamics/joints/joints.H b/src/rigidBodyDynamics/joints/joints.H
index 2ddd6c905cef739b80859150f0a10154a3a6bd8e..b95829646b4ca3e7388740a70ae466aac56c04cd 100644
--- a/src/rigidBodyDynamics/joints/joints.H
+++ b/src/rigidBodyDynamics/joints/joints.H
@@ -1,6 +1,12 @@
 // Null joint for the root-body
 #include "nullJoint.H"
 
+// Composite joint to handle combination of rotations and translations
+#include "compositeJoint.H"
+
+// 6-DoF joint for floating bodies
+#include "floatingJoint.H"
+
 // Revolute joints
 #include "Rx.H"
 #include "Ry.H"
diff --git a/src/rigidBodyDynamics/joints/nullJoint/nullJoint.C b/src/rigidBodyDynamics/joints/null/nullJoint.C
similarity index 100%
rename from src/rigidBodyDynamics/joints/nullJoint/nullJoint.C
rename to src/rigidBodyDynamics/joints/null/nullJoint.C
diff --git a/src/rigidBodyDynamics/joints/nullJoint/nullJoint.H b/src/rigidBodyDynamics/joints/null/nullJoint.H
similarity index 100%
rename from src/rigidBodyDynamics/joints/nullJoint/nullJoint.H
rename to src/rigidBodyDynamics/joints/null/nullJoint.H
diff --git a/src/rigidBodyDynamics/rigidBodyModel/rigidBodyModel.C b/src/rigidBodyDynamics/rigidBodyModel/rigidBodyModel.C
index af3d70b19a34fefaed76ebb716a3e6d67f726e9a..6d93c8f5b6244ec6d1174cff5004f6019cd606c9 100644
--- a/src/rigidBodyDynamics/rigidBodyModel/rigidBodyModel.C
+++ b/src/rigidBodyDynamics/rigidBodyModel/rigidBodyModel.C
@@ -124,12 +124,12 @@ Foam::RBD::rigidBodyModel::rigidBodyModel(const dictionary& dict)
 
 // * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
 
-Foam::label Foam::RBD::rigidBodyModel::join
+Foam::label Foam::RBD::rigidBodyModel::join_
 (
     const label parentID,
     const spatialTransform& XT,
-    const autoPtr<joint>& jointPtr,
-    const autoPtr<rigidBody>& bodyPtr
+    autoPtr<joint> jointPtr,
+    autoPtr<rigidBody> bodyPtr
 )
 {
     // Append the body
@@ -174,33 +174,71 @@ Foam::label Foam::RBD::rigidBodyModel::join
 (
     const label parentID,
     const spatialTransform& XT,
-    const PtrList<joint>& compositeJoint,
-    const autoPtr<rigidBody>& bodyPtr
+    autoPtr<joint> jointPtr,
+    autoPtr<rigidBody> bodyPtr
+)
+{
+    if (isA<joints::composite>(jointPtr()))
+    {
+        return join
+        (
+            parentID,
+            XT,
+            autoPtr<joints::composite>
+            (
+                dynamic_cast<joints::composite*>(jointPtr.ptr())
+            ),
+            bodyPtr
+        );
+    }
+    else
+    {
+        return join_
+        (
+            parentID,
+            XT,
+            jointPtr,
+            bodyPtr
+        );
+    }
+}
+
+
+Foam::label Foam::RBD::rigidBodyModel::join
+(
+    const label parentID,
+    const spatialTransform& XT,
+    autoPtr<joints::composite> cJointPtr,
+    autoPtr<rigidBody> bodyPtr
 )
 {
     label parent = parentID;
+    joints::composite& cJoint = cJointPtr();
 
     // For all but the final joint in the set add a masslessBody with the
     // joint and transform
-    for (label j=0; j<compositeJoint.size()-1; j++)
+    for (label j=0; j<cJoint.size()-1; j++)
     {
-        parent = join
+        parent = join_
         (
             parent,
             j == 0 ? XT : spatialTransform(),
-            compositeJoint[j].clone(),
+            cJoint[j].clone(),
             autoPtr<rigidBody>(new masslessBody)
         );
     }
 
     // For the final joint in the set add the read body
-    return join
+    parent = join_
     (
         parent,
-        compositeJoint.size() == 1 ? XT : spatialTransform(),
-        compositeJoint[compositeJoint.size()-1].clone(),
+        cJoint.size() == 1 ? XT : spatialTransform(),
+        autoPtr<joint>(cJointPtr.ptr()),
         bodyPtr
     );
+    cJoint.setLastJoint();
+
+    return parent;
 }
 
 
@@ -225,7 +263,7 @@ Foam::label Foam::RBD::rigidBodyModel::merge
 (
     const label parentID,
     const spatialTransform& XT,
-    const autoPtr<rigidBody>& bodyPtr
+    autoPtr<rigidBody> bodyPtr
 )
 {
     autoPtr<subBody> sBodyPtr;
@@ -317,15 +355,7 @@ void Foam::RBD::rigidBodyModel::write(Ostream& os) const
         os.writeKeyword("transform")
             << XT_[i] << token::END_STATEMENT << nl;
 
-        os  << indent << "joint" << nl
-            << indent << token::BEGIN_BLOCK << incrIndent << endl;
-
-        os.writeKeyword("type")
-            << joints_[i].type() << token::END_STATEMENT << nl;
-
-        joints_[i].write(os);
-
-        os  << decrIndent << indent << token::END_BLOCK << endl;
+        os  << indent << "joint" << nl << joints_[i] << endl;
 
         os  << decrIndent << indent << token::END_BLOCK << endl;
     }
diff --git a/src/rigidBodyDynamics/rigidBodyModel/rigidBodyModel.H b/src/rigidBodyDynamics/rigidBodyModel/rigidBodyModel.H
index 9c51cd280bcb2f56b096dac75d5fad0fc08b5920..57271d3ff23c53ee44d788ea9648b01a74349ece 100644
--- a/src/rigidBodyDynamics/rigidBodyModel/rigidBodyModel.H
+++ b/src/rigidBodyDynamics/rigidBodyModel/rigidBodyModel.H
@@ -52,6 +52,7 @@ SourceFiles
 #include "rigidBody.H"
 #include "subBody.H"
 #include "joint.H"
+#include "compositeJoint.H"
 #include "PtrList.H"
 #include "HashTable.H"
 
@@ -177,6 +178,19 @@ protected:
         mutable DynamicList<vector> u_;
 
 
+    // Protected member functions
+
+        //- Join the given body to the parent with ID parentID via the given
+        //  joint with transform from the parent frame to the joint frame XT.
+        virtual label join_
+        (
+            const label parentID,
+            const spatialTransform& XT,
+            autoPtr<joint> jointPtr,
+            autoPtr<rigidBody> bodyPtr
+        );
+
+
 public:
 
     //- Runtime type information
@@ -237,8 +251,8 @@ public:
         (
             const label parentID,
             const spatialTransform& XT,
-            const autoPtr<joint>& jointPtr,
-            const autoPtr<rigidBody>& bodyPtr
+            autoPtr<joint> jointPtr,
+            autoPtr<rigidBody> bodyPtr
         );
 
         //- Join the given body to the parent with ID parentID via the given
@@ -250,8 +264,8 @@ public:
         (
             const label parentID,
             const spatialTransform& XT,
-            const PtrList<joint>& compositeJoint,
-            const autoPtr<rigidBody>& bodyPtr
+            autoPtr<joints::composite> cJoint,
+            autoPtr<rigidBody> bodyPtr
         );
 
         //- Merge the given body with transform X into the parent with ID
@@ -262,7 +276,7 @@ public:
         (
             const label parentID,
             const spatialTransform& X,
-            const autoPtr<rigidBody>& bodyPtr
+            autoPtr<rigidBody> bodyPtr
         );
 
         //- Return true if the body with given ID has been merged with a parent