diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt
index f9166fed9ca846f6e56e28b770f00f103b036382..53669cbdcee7efe3971132485641df1cf7ba90af 100644
--- a/include/CMakeLists.txt
+++ b/include/CMakeLists.txt
@@ -13,11 +13,13 @@
 # received a copy of the GNU Lesser General Public License along with
 # dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
 
-# Add default script directory.
+# Add default import directories.
 #  It is used by the import directive of the sot shell to locate
-#  scripts.
-SET(DG_IMPORT_DEFAULT_PATHS
-	"${CMAKE_INSTALL_PREFIX}/share/dynamic-graph/script")
+#  scripts and plug-ins.
+SET(
+  DG_IMPORT_DEFAULT_PATHS
+  "${CMAKE_INSTALL_PREFIX}/share/dynamic-graph/script:${CMAKE_INSTALL_PREFIX}/${PLUGINDIR}"
+  )
 
 CONFIGURE_FILE(
 	${PROJECT_NAME}/import-default-paths.h.cmake	
diff --git a/include/dynamic-graph/import.h b/include/dynamic-graph/import.h
index 6a9713cb22ccd839d75f7325fda4fd0e02267c4c..8566df45b4bef5e74c586ba77f653f97f4932a9f 100644
--- a/include/dynamic-graph/import.h
+++ b/include/dynamic-graph/import.h
@@ -21,6 +21,8 @@
 # include <string>
 # include <vector>
 
+# include <boost/filesystem/path.hpp>
+
 namespace dynamicgraph
 {
   class Interpreter;
@@ -28,7 +30,13 @@ namespace dynamicgraph
   {
     namespace
     {
-      extern std::vector<std::string> importPaths;
+      /// \brief Vector of Boost.Filesystem paths.
+      ///
+      /// Used to store paths where the import statement
+      /// will look for scripts or plug-ins.
+      typedef std::vector<boost::filesystem::path> paths_t;
+
+      extern paths_t importPaths;
     } // end of anonymous namespace.
 
     /// \brief Implement sot interpretor import command.
diff --git a/src/dgraph/import.cpp b/src/dgraph/import.cpp
index d2e3f91fddb7cb2e25887badad1029897012cac9..e345057a8598aff5062bbfbe8633850bc451f589 100644
--- a/src/dgraph/import.cpp
+++ b/src/dgraph/import.cpp
@@ -27,15 +27,17 @@
 #include <vector>
 
 #include <boost/algorithm/string.hpp>
+#include <boost/filesystem.hpp>
 #include <boost/foreach.hpp>
 #include <boost/format.hpp>
 
-#include <dynamic-graph/import-default-paths.h>
-#include <dynamic-graph/import.h>
 #include <dynamic-graph/debug.h>
 #include <dynamic-graph/exception-abstract.h>
 #include <dynamic-graph/exception-factory.h>
+#include <dynamic-graph/import-default-paths.h>
+#include <dynamic-graph/import.h>
 #include <dynamic-graph/interpreter.h>
+#include <dynamic-graph/plugin-loader.h>
 
 // The default import paths has to be passed from the build system
 // as a -D flag for instance.
@@ -47,6 +49,16 @@
 
 static const char* ENV_DG_PATH = "DG_PATH";
 
+
+// Define OS specific extensions for shared libraries.
+#ifdef _WIN32
+static const char* SHARED_LIBRARY_EXT = ".dll";
+#elif __APPLE__
+static const char* SHARED_LIBRARY_EXT = ".dylib";
+#else
+static const char* SHARED_LIBRARY_EXT = ".so";
+#endif
+
 namespace dynamicgraph
 {
   namespace command
@@ -54,7 +66,7 @@ namespace dynamicgraph
     namespace
     {
       /// Initialize import paths list (called during static initialization).
-      std::vector<std::string> initializePaths  ();
+      paths_t initializePaths ();
 
       /// \brief Import paths list.
       ///
@@ -64,33 +76,28 @@ namespace dynamicgraph
       ///
       /// The look-up is made from right to left:
       ///
+      /// On Unix:
       /// importPaths = A:B:C
+      /// On Microsoft Windows:
+      /// importPaths = A;B;C
       ///
       /// When typing ``import foo'', C will be searched first then B
       /// and A. The search stops when the file is found.
-      std::vector<std::string> importPaths = initializePaths  ();
+      paths_t importPaths = initializePaths ();
 
       /// Search for a module.
       ///
       /// Returns the module full absolute path or an empty string if
       /// it cannot be found.
-      std::string searchModule (const std::string& module);
+      boost::filesystem::path searchModule (const std::string& module);
 
-      /// \brief Remove quotes form a string.
+      /// \brief Remove quotes from a string.
       ///
       /// Transform strings such as "foo" or 'foo' into foo.
       void removeQuotes (std::string& msg);
 
-      std::vector<std::string> initializePaths  ()
+      paths_t initializePaths ()
       {
-	std::vector<std::string> importPaths;
-	importPaths.push_back (DG_IMPORT_DEFAULT_PATHS);
-
-	// Search for the environment variable value.
-	char* ScriptPath = getenv (ENV_DG_PATH);
-	if (!ScriptPath)
-	  return importPaths;
-
 	// Split the environment variable.
 	std::string environmentSeparator;
 
@@ -102,45 +109,136 @@ namespace dynamicgraph
 	environmentSeparator = ":";
 #endif // defined _WIN32 || defined __CYGWIN__
 
+
+	// Declare variables that will be returned.
+	paths_t importPaths;
+
+	// Split the built-in values.
+	std::vector<std::string> splittedDefaultPaths;
+        boost::split (splittedDefaultPaths,
+		      DG_IMPORT_DEFAULT_PATHS,
+		      boost::is_any_of (environmentSeparator));
+
+        // Insert them back.
+	{
+	  std::back_insert_iterator<paths_t> bi (importPaths);
+	  std::copy (splittedDefaultPaths.begin (),
+		     splittedDefaultPaths.end (), bi);
+	}
+
+	// Search for the environment variable value.
+	char* ScriptPath = getenv (ENV_DG_PATH);
+	if (!ScriptPath)
+	  return importPaths;
+
 	std::vector<std::string> splittedEnvironmentVariable;
         boost::split (splittedEnvironmentVariable, ScriptPath,
 		      boost::is_any_of (environmentSeparator));
 
-        // Insert it back.
-        std::back_insert_iterator<std::vector<std::string> > bi (importPaths);
-        std::copy (splittedEnvironmentVariable.begin  (),
-		   splittedEnvironmentVariable.end  (), bi);
+        // Insert it back
+        std::back_insert_iterator<paths_t> bi (importPaths);
+        std::copy (splittedEnvironmentVariable.begin (),
+		   splittedEnvironmentVariable.end (), bi);
         return importPaths;
       }
 
-      std::string searchModule (const std::string& module)
+      boost::filesystem::path searchModule (const std::string& module)
       {
-	// Make sure the traversal is right to left to enforce
-	// correct priorities.
-	typedef std::vector<std::string>::const_reverse_iterator citer_t;
-	for (citer_t it = importPaths.rbegin  ();
-	     it != importPaths.rend  (); ++it)
+	// To ensure correct priorities, the traversal has to
+	// done left to right.
+	typedef paths_t::const_iterator citer_t;
+	for (citer_t it = importPaths.begin ();
+	     it != importPaths.end (); ++it)
 	  {
-	    const std::string& path = *it;
+	    const boost::filesystem::path& dir = *it;
+	    if (!boost::filesystem::is_directory (dir))
+	      continue;
+
+	    boost::filesystem::path path = dir / module;
+	    boost::filesystem::path pathPlugin = path;
+	    pathPlugin.replace_extension (SHARED_LIBRARY_EXT);
+
+	    if (boost::filesystem::exists (pathPlugin)
+		&& (boost::filesystem::is_regular_file (pathPlugin)
+		    || boost::filesystem::is_symlink (pathPlugin)))
+	      return pathPlugin;
+
+	    if (boost::filesystem::exists (path)
+		&& (boost::filesystem::is_regular_file (path)
+		    || boost::filesystem::is_symlink (path)))
+	      return path;
+	  }
+
+	return boost::filesystem::path ();
+      }
 
-	    assert (!path.empty  ());
+      void removeQuotes (std::string& msg)
+      {
+	if ((msg[0] == '"' && msg[msg.length () - 1] == '"')
+	    || (msg[0] == '\'' && msg[msg.length () - 1] == '\''))
+	  msg = msg.substr (1, msg.length () - 2);
+      }
 
-	    std::string filename (path);
-	    if (filename[filename.length  () - 1] != '/')
-	      filename += "/";
-	    filename += module;
-	    std::ifstream file (filename.c_str  ());
-	    if (file.is_open  () && file.good  ())
-	      return filename;
+      void importScript (dynamicgraph::Interpreter& interpreter,
+			 const boost::filesystem::path& path,
+			 std::ifstream& file,
+			 std::ostream& os)
+      {
+	int lineIdx = 0;
+	try
+	  {
+	    while (file.good ())
+	      {
+		dgDEBUGIN (15);
+		++lineIdx;
+
+		std::string line;
+		std::getline (file, line);
+		if (line.empty ())
+		  continue;
+
+		std::istringstream iss (line);
+		std::string currentCmdName;
+		std::string currentCmdArgs;
+		if (iss >> currentCmdName)
+		  {
+		    std::getline (iss, currentCmdArgs);
+		    boost::format fmt ("Run ``%1%'' with args ``%2%''");
+		    fmt % currentCmdName % currentCmdArgs;
+		    dgDEBUG(25) << fmt.str () << std::endl;
+		    std::istringstream issArgs (currentCmdArgs);
+		    interpreter.cmd (currentCmdName, issArgs, os);
+		  }
+		dgDEBUGOUT (15);
+	      }
+	  }
+	catch (ExceptionAbstract& exc)
+	  {
+	    // FIXME: come on...
+	    std::string& msg =
+	      const_cast<std::string&> (exc.getStringMessage ());
+	    boost::format fmt (" (in line %1% of file ``%2%'')");
+	    fmt % lineIdx % path.file_string ();
+	    msg = msg + fmt.str ();
+	    std::cout << msg << std::endl;
+	    throw;
 	  }
-	return std::string  ();
       }
 
-      void removeQuotes (std::string& msg)
+      void importPlugin (dynamicgraph::Interpreter& interpreter,
+			 const boost::filesystem::path& path,
+			 std::ostream&)
       {
-	if ((msg[0] == '"' && msg[msg.length  () - 1] == '"')
-	    || (msg[0] == '\'' && msg[msg.length  () - 1] == '\''))
-	  msg = msg.substr (1, msg.length  () - 2);
+	if (!interpreter.dlPtr)
+	  {
+	    DG_THROW ExceptionFactory
+	      (ExceptionFactory::DYNAMIC_LOADING,
+	       "No plug-in loader available.");
+	    return;
+	  }
+	interpreter.dlPtr->addPlugin (path.filename (),
+				      path.parent_path ().file_string ());
+	interpreter.dlPtr->loadPlugins ();
       }
     } // end of anonymous namespace.
 
@@ -167,23 +265,26 @@ namespace dynamicgraph
       // Get rid of quotes.
       removeQuotes (module);
 
-      std::string filename = searchModule (module);
-      std::ifstream file (filename.c_str  ());
-      if (filename.empty  () || !file.is_open  () || !file.good  ())
+      // Get the absolute path of the module.
+      boost::filesystem::path path = searchModule (module);
+
+      std::ifstream file (path.file_string ().c_str ());
+      if (!boost::filesystem::is_regular_file (path)
+	  || !file.is_open () || !file.good ())
 	{
 	  std::string scriptDirectories;
 
-	  if (importPaths.empty  ())
+	  if (importPaths.empty ())
 	    scriptDirectories = "empty";
 	  else
 	    {
-	      BOOST_FOREACH (const std::string& path, importPaths)
+	      BOOST_FOREACH (const boost::filesystem::path& path, importPaths)
 		{
-		  scriptDirectories += path;
+		  scriptDirectories += path.file_string ();
 		  scriptDirectories += ", ";
 		}
 	      scriptDirectories = scriptDirectories.substr
-		(0, scriptDirectories.length  () - 2);
+		(0, scriptDirectories.length () - 2);
 	    }
 
 	  boost::format fmt
@@ -191,48 +292,14 @@ namespace dynamicgraph
 	  fmt % module;
 	  fmt % scriptDirectories;
 	  DG_THROW ExceptionFactory
-	    (ExceptionFactory::READ_FILE, fmt.str  ());
+	    (ExceptionFactory::READ_FILE, fmt.str ());
 	  return;
 	}
 
-      int lineIdx = 0;
-      try
-	{
-	  while (file.good  ())
-	    {
-	      ++lineIdx;
-	      dgDEBUGIN (15);
-
-	      std::string line;
-	      std::getline (file, line);
-	      if (line.empty  ())
-		continue;
-
-	      std::istringstream iss (line);
-	      std::string currentCmdName;
-	      std::string currentCmdArgs;
-	      if (iss >> currentCmdName)
-		{
-		  std::getline (iss, currentCmdArgs);
-		  boost::format fmt ("Run ``%1%'' with args ``%2%''");
-		  fmt % currentCmdName % currentCmdArgs;
-		  dgDEBUG(25) << fmt.str  () << std::endl;
-		  std::istringstream issArgs (currentCmdArgs);
-		  interpreter.cmd (currentCmdName, issArgs, os);
-		}
-	      dgDEBUGOUT (15);
-	    }
-	}
-      catch (ExceptionAbstract& exc)
-	{
-	  // FIXME: come on...
-	  std::string& msg = const_cast<std::string&> (exc.getStringMessage  ());
-	  boost::format fmt (" (in line %1% of file ``%2%'')");
-	  fmt % lineIdx % filename;
-	  msg = msg + fmt.str ();
-	  std::cout << msg << std::endl;
-	  throw;
-	}
+      if (path.extension () != SHARED_LIBRARY_EXT)
+	importScript (interpreter, path, file, os);
+      else
+	importPlugin (interpreter, path, os);
 
       dgDEBUGOUT(15);
     }
@@ -266,8 +333,8 @@ namespace dynamicgraph
 	     << std::endl;
 	  return;
 	}
-      if (!importPaths.empty  ())
-	importPaths.pop_back  ();
+      if (!importPaths.empty ())
+	importPaths.pop_back ();
     }
 
   } // end of namespace command.
diff --git a/tests/data/empty.sot b/tests/data/empty.dg
similarity index 100%
rename from tests/data/empty.sot
rename to tests/data/empty.dg
diff --git a/tests/interpreter.cpp b/tests/interpreter.cpp
index 477fa53a03cfac060461aa8e45f3e40c8b1657ad..1412cc1b1af412fd740d864c2ff5520797e482ee 100644
--- a/tests/interpreter.cpp
+++ b/tests/interpreter.cpp
@@ -113,7 +113,7 @@ BOOST_AUTO_TEST_CASE (cmd_help)
 BOOST_AUTO_TEST_CASE (cmd_run_emptyfile)
 {
   dynamicgraph::Interpreter shell;
-  RUN_COMMAND ("run", TESTS_DATADIR "/empty.sot");
+  RUN_COMMAND ("run", TESTS_DATADIR "/empty.dg");
   BOOST_CHECK (output.is_empty ());
 }
 
@@ -164,7 +164,7 @@ BOOST_AUTO_TEST_CASE (cmd_import_push)
 
   // Import empty file.
   {
-    RUN_COMMAND ("import", "empty.sot");
+    RUN_COMMAND ("import", "empty.dg");
     BOOST_CHECK (output.is_empty ());
   }
 
@@ -175,11 +175,11 @@ BOOST_AUTO_TEST_CASE (cmd_import_push)
   }
 
   // Import empty file again: this will fail
-  // as empty.sot is *NOT* in a standard location.
+  // as empty.dg is *NOT* in a standard location.
   {
     output_test_stream output;
     std::stringstream ss;
-    ss << "empty.sot";
+    ss << "empty.dg";
     std::istringstream args (ss.str ());
     
     // Make sure this trigger an error.