diff --git a/VirtualRobot/CMakeLists.txt b/VirtualRobot/CMakeLists.txt
index e45cbda8656aedc080df656b4c31bcc140247b02..525131154eba63df6b8c0ba7172cc6e808e4b308 100644
--- a/VirtualRobot/CMakeLists.txt
+++ b/VirtualRobot/CMakeLists.txt
@@ -77,6 +77,12 @@ XML/RobotIO.cpp
 XML/SceneIO.cpp
 XML/ObjectIO.cpp
 XML/FileIO.cpp
+XML/mjcf/exceptions.cpp
+XML/mjcf/MasslessBodySanitizer.cpp
+XML/mjcf/MjcfDocument.cpp
+XML/mjcf/MujocoIO.cpp
+XML/mjcf/utils.cpp
+XML/mjcf/xml_visitors.cpp
 IK/IKSolver.cpp
 IK/AdvancedIKSolver.cpp
 IK/DifferentialIK.cpp
@@ -223,6 +229,12 @@ XML/RobotIO.h
 XML/SceneIO.h
 XML/ObjectIO.h
 XML/FileIO.h
+XML/mjcf/exceptions.h
+XML/mjcf/MasslessBodySanitizer.h
+XML/mjcf/MjcfDocument.h
+XML/mjcf/MujocoIO.h
+XML/mjcf/utils.h
+XML/mjcf/xml_visitors.h
 IK/IKSolver.h
 IK/AdvancedIKSolver.h
 IK/DifferentialIK.h
diff --git a/VirtualRobot/XML/RobotIO.cpp b/VirtualRobot/XML/RobotIO.cpp
index 6a1c80483cb2022264fd3604f223c9f42e93856d..6feadd35d418aa914a83e9281287bf9ecc923a3d 100644
--- a/VirtualRobot/XML/RobotIO.cpp
+++ b/VirtualRobot/XML/RobotIO.cpp
@@ -15,6 +15,7 @@
 #include "../RobotConfig.h"
 #include "../RuntimeEnvironment.h"
 #include "rapidxml.hpp"
+#include "mjcf/MujocoIO.h"
 
 
 #include <vector>
@@ -1512,6 +1513,24 @@ namespace VirtualRobot
         }
 
         return true;
+    }
+    
+    void RobotIO::saveMJCF(RobotPtr robot, const std::string& filename, 
+                           const std::string& basePath, const std::string& meshDir)
+    {
+        
+        
+        
+        
+        
+        
+        
+        
+        
+        
+        
+        
+        
     }
 
 
diff --git a/VirtualRobot/XML/RobotIO.h b/VirtualRobot/XML/RobotIO.h
index e9dd02e86febdff633291ce283bae354bf3ad1d0..b59a213e52d845b0fab0bad2bb030788b5646fa6 100644
--- a/VirtualRobot/XML/RobotIO.h
+++ b/VirtualRobot/XML/RobotIO.h
@@ -58,19 +58,19 @@ namespace VirtualRobot
         };
 
         /*!
-                Loads robot from file.
-                @param xmlFile The file
-                @param loadMode Standard: eFull, When eStructure is used no visualization and collision models are loaded for faster access.
-                @return Returns an empty pointer, when file access failed.
+            Loads robot from file.
+            @param xmlFile The file
+            @param loadMode Standard: eFull, When eStructure is used no visualization and collision models are loaded for faster access.
+            @return Returns an empty pointer, when file access failed.
         */
         static RobotPtr loadRobot(const std::string& xmlFile, RobotDescription loadMode = eFull);
 
         /*!
-                Creates Robot from string.
-                @param xmlString The input string.
-                @param basePath If any \<childFromRobot\> tags are given, the path for searching the robot files can be specified.
-                @param loadMode Standard: eFull, When eStructure is used no visualization and collision models are loaded for faster access.
-            */
+            Creates Robot from string.
+            @param xmlString The input string.
+            @param basePath If any \<childFromRobot\> tags are given, the path for searching the robot files can be specified.
+            @param loadMode Standard: eFull, When eStructure is used no visualization and collision models are loaded for faster access.
+        */
         static RobotPtr createRobotFromString(const std::string& xmlString, const std::string& basePath = "", RobotDescription loadMode = eFull);
 
 
@@ -84,6 +84,16 @@ namespace VirtualRobot
         static bool saveXML(RobotPtr robot, const std::string& filename, const std::string& basePath, const std::string& modelDir = "models", bool storeEEF = true, bool storeRNS = true, bool storeSensors = true, bool storeModelFiles = true);
 
 
+        /*!
+            @brief saveMJCF
+            @param robot    The robot to save.
+            @param filename The filename without path.
+            @param basePath The directory to store the robot to
+            @param meshDir  The local directory where all mesh files should be stored to.
+         */
+        static void saveMJCF(RobotPtr robot, const std::string& filename, const std::string& basePath, const std::string& meshDir = "mesh");
+        
+        
     protected:
 
         struct ChildFromRobotDef
diff --git a/VirtualRobot/examples/MjcfConverter/mjcf/MjcfMasslessBodySanitizer.cpp b/VirtualRobot/XML/mjcf/MasslessBodySanitizer.cpp
similarity index 100%
rename from VirtualRobot/examples/MjcfConverter/mjcf/MjcfMasslessBodySanitizer.cpp
rename to VirtualRobot/XML/mjcf/MasslessBodySanitizer.cpp
diff --git a/VirtualRobot/examples/MjcfConverter/mjcf/MjcfMasslessBodySanitizer.h b/VirtualRobot/XML/mjcf/MasslessBodySanitizer.h
similarity index 100%
rename from VirtualRobot/examples/MjcfConverter/mjcf/MjcfMasslessBodySanitizer.h
rename to VirtualRobot/XML/mjcf/MasslessBodySanitizer.h
diff --git a/VirtualRobot/examples/MjcfConverter/mjcf/MjcfDocument.cpp b/VirtualRobot/XML/mjcf/MjcfDocument.cpp
similarity index 100%
rename from VirtualRobot/examples/MjcfConverter/mjcf/MjcfDocument.cpp
rename to VirtualRobot/XML/mjcf/MjcfDocument.cpp
diff --git a/VirtualRobot/examples/MjcfConverter/mjcf/MjcfDocument.h b/VirtualRobot/XML/mjcf/MjcfDocument.h
similarity index 100%
rename from VirtualRobot/examples/MjcfConverter/mjcf/MjcfDocument.h
rename to VirtualRobot/XML/mjcf/MjcfDocument.h
diff --git a/VirtualRobot/examples/MjcfConverter/MjcfConverter.cpp b/VirtualRobot/XML/mjcf/MujocoIO.cpp
similarity index 78%
rename from VirtualRobot/examples/MjcfConverter/MjcfConverter.cpp
rename to VirtualRobot/XML/mjcf/MujocoIO.cpp
index c9d7237a07b2cbc7275dc855a729f40188eb7b7b..4627d3c68ab97164732b9ed87f9d51434878303b 100644
--- a/VirtualRobot/examples/MjcfConverter/MjcfConverter.cpp
+++ b/VirtualRobot/XML/mjcf/MujocoIO.cpp
@@ -1,30 +1,29 @@
-#include "MjcfConverter.h"
+#include "MujocoIO.h"
+#include "utils.h"
+#include "xml_visitors.h"
 
 #include <VirtualRobot/RobotNodeSet.h>
 #include <VirtualRobot/XML/RobotIO.h>
 
-#include "mjcf/utils.h"
-#include "mjcf/xml_visitors.h"
-
-
 
 using namespace VirtualRobot;
+using namespace mjcf;
 namespace tx = tinyxml2; 
 namespace fs = boost::filesystem;
-using Element = mjcf::Element;
 
 
-MjcfConverter::MjcfConverter() :
+
+MujocoIO::MujocoIO() :
     masslessBodySanitizer(document, robot)
 {
 }
 
-void MjcfConverter::convert(const std::string& inputSimoxXmlFile, 
-                            const std::string& outputDirectory)
+void MujocoIO::saveMJCF(RobotPtr robot, const std::string& filename, const std::string& basePath, const std::string& meshDir)
 {
-    setPaths(inputSimoxXmlFile, outputDirectory);
-    
-    loadInputFile();
+    this->robot = robot;
+    this->outputDirectory = basePath;
+    this->outputFileName = filename;
+    this->outputMeshRelDirectory = meshDir;
     
     document.reset(new mjcf::Document());
     
@@ -67,57 +66,14 @@ void MjcfConverter::convert(const std::string& inputSimoxXmlFile,
     writeOutputFile();
 }
 
-void MjcfConverter::setPaths(const std::string& inputFilename, 
-                             const std::string& outputDirectory)
-{
-    this->inputFilePath = inputFilename;
-    
-    inputFileDirectory = inputFilePath.parent_path();
-    inputFileName = inputFilePath.filename();
-    
-    this->outputDirectory = outputDirectory;
-    outputFileName = this->outputDirectory / inputFileName;
-    
-    outputMeshRelDirectory = "mesh";
-    
-    
-    auto ensureDirExists = [](const fs::path& path)
-    {
-        if (!fs::exists(path))
-        {
-            fs::create_directory(path);
-        }
-    };
-    
-    ensureDirExists(outputDirectory);
-    ensureDirExists(outputDirectory / outputMeshRelDirectory);
-    
-    assert(!inputFileDirectory.empty());
-}
 
-void MjcfConverter::makeEnvironment()
+void MujocoIO::makeEnvironment()
 {
     document->addSkyboxTexture(Eigen::Vector3f(.8f, .9f, .95f), 
                                Eigen::Vector3f(.4f, .6f, .8f));
 }
 
-void MjcfConverter::loadInputFile()
-{
-    assert(!inputFilePath.empty());
-    
-    std::cout << "Loading robot via RobotIO: " << inputFilePath << std::endl;
-    try
-    {
-        robot = RobotIO::loadRobot(inputFilePath.string(), RobotIO::eFull);
-        assert(robot);
-    }
-    catch (const VirtualRobotException&)
-    {
-        throw; // rethrow
-    }
-}
-
-void MjcfConverter::writeOutputFile()
+void MujocoIO::writeOutputFile()
 {
     assert(!outputFileName.empty());
     std::cout << "Writing to " << outputFileName << std::endl;
@@ -125,7 +81,7 @@ void MjcfConverter::writeOutputFile()
 }
 
 
-void MjcfConverter::addNodeBodies()
+void MujocoIO::addNodeBodies()
 {
     nodeBodies.clear();
     
@@ -143,7 +99,7 @@ void MjcfConverter::addNodeBodies()
     }
 }
 
-void MjcfConverter::addNodeBodyMeshes()
+void MujocoIO::addNodeBodyMeshes()
 {
     bool meshlabserverAviable = system("which meshlabserver > /dev/null 2>&1") == 0;
     bool notAvailableReported = false;
@@ -232,7 +188,7 @@ void MjcfConverter::addNodeBodyMeshes()
 
 
 
-Element* MjcfConverter::addNodeBody(RobotNodePtr node)
+Element* MujocoIO::addNodeBody(RobotNodePtr node)
 {
     Element* element = nodeBodies[node->getName()];
     if (element)
@@ -253,7 +209,7 @@ Element* MjcfConverter::addNodeBody(RobotNodePtr node)
     return element;
 }
 
-void MjcfConverter::addContactExcludes()
+void MujocoIO::addContactExcludes()
 {
     RobotNodePtr rootNode = robot->getRootNode();
     
@@ -281,7 +237,7 @@ void MjcfConverter::addContactExcludes()
     }
 }
 
-void MjcfConverter::addActuators()
+void MujocoIO::addActuators()
 {
     std::vector<const mjcf::Element*> jointElements = getAllElements("joint");
     
@@ -292,7 +248,7 @@ void MjcfConverter::addActuators()
     }
 }
 
-std::vector<const mjcf::Element*> MjcfConverter::getAllElements(const std::string& elemName)
+std::vector<const mjcf::Element*> MujocoIO::getAllElements(const std::string& elemName)
 {
     mjcf::ListElementsVisitor visitor(elemName);
     document->worldbody()->Accept(&visitor);
diff --git a/VirtualRobot/examples/MjcfConverter/MjcfConverter.h b/VirtualRobot/XML/mjcf/MujocoIO.h
similarity index 74%
rename from VirtualRobot/examples/MjcfConverter/MjcfConverter.h
rename to VirtualRobot/XML/mjcf/MujocoIO.h
index 17a5dc73d213b5df484812a22cfbb3e8f846e0ad..b8e5614ad1866f9cbd6469d9c38a7e0bf3a2b82e 100644
--- a/VirtualRobot/examples/MjcfConverter/MjcfConverter.h
+++ b/VirtualRobot/XML/mjcf/MujocoIO.h
@@ -5,29 +5,31 @@
 #include <VirtualRobot/Robot.h>
 
 
-#include "mjcf/exceptions.h"
-#include "mjcf/MjcfDocument.h"
-#include "mjcf/MjcfMasslessBodySanitizer.h"
+#include "exceptions.h"
+#include "MjcfDocument.h"
+#include "MasslessBodySanitizer.h"
 
 
 namespace VirtualRobot
 {
+namespace mjcf
+{
+
 
-    class MjcfConverter
+    class MujocoIO
     {
     public:
         
-        MjcfConverter();
+        MujocoIO();
         
         
-        void convert(const std::string& inputSimoxXmlFile,
-                     const std::string& outputDirectory);
+        void saveMJCF(RobotPtr robot, const std::string& filename, 
+                      const std::string& basePath, const std::string& meshDir);
         
         
     private:
         
         
-        void loadInputFile();
         void writeOutputFile();
         
         void setPaths(const std::string& inputFilename, 
@@ -52,10 +54,6 @@ namespace VirtualRobot
         
         // Paths
         
-        boost::filesystem::path inputFilePath;
-        boost::filesystem::path inputFileName;
-        boost::filesystem::path inputFileDirectory;
-        
         boost::filesystem::path outputDirectory;
         boost::filesystem::path outputFileName;
         
@@ -81,5 +79,6 @@ namespace VirtualRobot
         std::map<std::string, std::string> mergedBodyNames;
 
     };
-
+    
+}
 }
diff --git a/VirtualRobot/examples/MjcfConverter/mjcf/exceptions.cpp b/VirtualRobot/XML/mjcf/exceptions.cpp
similarity index 100%
rename from VirtualRobot/examples/MjcfConverter/mjcf/exceptions.cpp
rename to VirtualRobot/XML/mjcf/exceptions.cpp
diff --git a/VirtualRobot/examples/MjcfConverter/mjcf/exceptions.h b/VirtualRobot/XML/mjcf/exceptions.h
similarity index 100%
rename from VirtualRobot/examples/MjcfConverter/mjcf/exceptions.h
rename to VirtualRobot/XML/mjcf/exceptions.h
diff --git a/VirtualRobot/examples/MjcfConverter/mjcf/utils.cpp b/VirtualRobot/XML/mjcf/utils.cpp
similarity index 100%
rename from VirtualRobot/examples/MjcfConverter/mjcf/utils.cpp
rename to VirtualRobot/XML/mjcf/utils.cpp
diff --git a/VirtualRobot/examples/MjcfConverter/mjcf/utils.h b/VirtualRobot/XML/mjcf/utils.h
similarity index 100%
rename from VirtualRobot/examples/MjcfConverter/mjcf/utils.h
rename to VirtualRobot/XML/mjcf/utils.h
diff --git a/VirtualRobot/examples/MjcfConverter/mjcf/xml_visitors.cpp b/VirtualRobot/XML/mjcf/xml_visitors.cpp
similarity index 100%
rename from VirtualRobot/examples/MjcfConverter/mjcf/xml_visitors.cpp
rename to VirtualRobot/XML/mjcf/xml_visitors.cpp
diff --git a/VirtualRobot/examples/MjcfConverter/mjcf/xml_visitors.h b/VirtualRobot/XML/mjcf/xml_visitors.h
similarity index 100%
rename from VirtualRobot/examples/MjcfConverter/mjcf/xml_visitors.h
rename to VirtualRobot/XML/mjcf/xml_visitors.h
diff --git a/VirtualRobot/examples/MjcfConverter/CMakeLists.txt b/VirtualRobot/examples/MjcfConverter/CMakeLists.txt
index 73fa315aabafb627dfa6d5ad6f0eda02a954ff9b..5222b8e0d0144f87bca9458ced6c81f04097345b 100644
--- a/VirtualRobot/examples/MjcfConverter/CMakeLists.txt
+++ b/VirtualRobot/examples/MjcfConverter/CMakeLists.txt
@@ -10,23 +10,9 @@ if (Boost_FOUND)
 
     set(SOURCES
         main.cpp
-        MjcfConverter.cpp
-        
-        mjcf/exceptions.cpp
-        mjcf/utils.cpp
-        mjcf/xml_visitors.cpp
-        mjcf/MjcfDocument.cpp
-        mjcf/MjcfMasslessBodySanitizer.cpp
     )
     
     set(HEADERS
-        MjcfConverter.h
-        
-        mjcf/exceptions.h
-        mjcf/utils.h
-        mjcf/xml_visitors.h
-        mjcf/MjcfDocument.h
-        mjcf/MjcfMasslessBodySanitizer.h
     )
 
     set(LIBS
diff --git a/VirtualRobot/examples/MjcfConverter/main.cpp b/VirtualRobot/examples/MjcfConverter/main.cpp
index c50c22877d93bf03a4270f13a32dc7bb8cbed672..23e05a7d9dad9c3cc17c0092107cf39651c4123e 100644
--- a/VirtualRobot/examples/MjcfConverter/main.cpp
+++ b/VirtualRobot/examples/MjcfConverter/main.cpp
@@ -2,7 +2,7 @@
 
 #include <VirtualRobot/RuntimeEnvironment.h>
 
-#include "MjcfConverter.h"
+#include <VirtualRobot/XML/RobotIO.h>
 
 using namespace VirtualRobot;
 
@@ -11,9 +11,8 @@ int main(int argc, char* argv[])
 {
     VirtualRobot::RuntimeEnvironment::considerKey("robot");
     VirtualRobot::RuntimeEnvironment::processCommandLine(argc, argv);
-//    VirtualRobot::RuntimeEnvironment::print();
 
-    std::string inputFilename;
+    boost::filesystem::path inputFilename;
     
     if (VirtualRobot::RuntimeEnvironment::hasValue("robot"))
     {
@@ -34,14 +33,25 @@ int main(int argc, char* argv[])
         return 0;
     }
     
-    boost::filesystem::path outputDir(inputFilename);
+    boost::filesystem::path outputDir = inputFilename;
     outputDir.remove_filename();
     outputDir /= "mjcf";
     
     std::cout << "Input file:  " << inputFilename << std::endl;
     std::cout << "Output dir: " << outputDir << std::endl;
 
-    MjcfConverter converter;
-    converter.convert(inputFilename, outputDir.string());
+    std::cout << "Loading robot ..." << std::endl;
     
+    RobotPtr robot;
+    try
+    {
+        robot = RobotIO::loadRobot(inputFilename.string(), RobotIO::eFull);
+        assert(robot);
+    }
+    catch (const VirtualRobotException&)
+    {
+        throw; // rethrow
+    }
+    
+    RobotIO::saveMJCF(robot, inputFilename.filename().string(), outputDir.string());
 }