diff --git a/globals.mak b/globals.mak
index c03985035c4058b00b378f1b0809017241339313..7a0b085b9efbe0f7deefb226deed286cbba7982a 100644
--- a/globals.mak
+++ b/globals.mak
@@ -1,6 +1,7 @@
 # Global variables
 src=$(top_srcdir)
 sflcodecdir=$(libdir)/sflphone/codecs
+sflplugindir=$(libdir)/sflphone/plugins
 
 PJSIP_LIBS = -lpjnath-sfl -lpjsua-sfl -lpjsip-sfl -lpjmedia-sfl -lpjsip-simple-sfl -lpjsip-ua-sfl -lpjmedia-codec-sfl -lpjlib-util-sfl -lpj-sfl 
 
@@ -16,5 +17,6 @@ AM_CPPFLAGS = \
 	@SIP_CFLAGS@ \
 	@DBUSCPP_CFLAGS@ \
 	-DCODECS_DIR=\""$(sflcodecdir)"\" \
+	-DPLUGINS_DIR=\""$(sflplugindir)"\" \
 	-DENABLE_TRACE
 
diff --git a/src/Makefile.am b/src/Makefile.am
index f9af16aafd648b9d39f9df13a17ca5e9ae66c343..90953f1607ffb826cc2fe4279696b3d02f400df9 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -87,6 +87,7 @@ libsflphone_la_LIBADD = \
 	./audio/libaudio.la \
 	./dbus/libdbus.la \
 	./config/libconfig.la \
+	./plug-in/libplugin.la \
 	$(IAX_LIBS) 
 
 libsflphone_la_SOURCES =
diff --git a/src/plug-in/Makefile.am b/src/plug-in/Makefile.am
index de286d046c31970b74807d1acce3febd7c4b02b6..53bf6b050cba69da07a0f8fd60b2f4b52c8f41d6 100644
--- a/src/plug-in/Makefile.am
+++ b/src/plug-in/Makefile.am
@@ -1,5 +1,8 @@
+include ../../globals.mak
+
 noinst_LTLIBRARIES = libplugin.la
 
 libplugin_la_SOURCES = \
-		pluginmanager.cpp
-		plugin.cpp
+		pluginmanager.cpp \
+		plugin.h
+
diff --git a/src/plug-in/plugin.cpp b/src/plug-in/plugin.cpp
index bc7cf18c38c58f3a89521553fca90664d8180246..495437076549dee7c9bafbdc5ca6782076400d97 100644
--- a/src/plug-in/plugin.cpp
+++ b/src/plug-in/plugin.cpp
@@ -1,26 +1,27 @@
 #include "plugin.h"
 
-Plugin::Plugin( const std::string &filename )
+::sflphone::Plugin::Plugin( const std::string &filename UNUSED )
 {
     //TODO IMPLEMENT
 }
 
-Plugin::Plugin( const Plugin &plugin )
+::sflphone::Plugin::Plugin( const Plugin &plugin UNUSED )
 {
     //TODO IMPLEMENT
 }
 
-Plugin::~Plugin()
+::sflphone::Plugin::~Plugin()
 {
     //TODO IMPLEMENT
 }
 
-int Plugin::getCoreVersion( void )
+int ::sflphone::Plugin::getCoreVersion( void ) const
 {
     //TODO IMPLEMENT
+    return 1;
 }
 
-void Plugin::registerPlugin( PluginManager & )
+void ::sflphone::Plugin::registerPlugin( PluginManager & )
 {
     //TODO IMPLEMENT
 }
diff --git a/src/plug-in/plugin.h b/src/plug-in/plugin.h
index 5c825f872f4c03cfe43e0ab4b9fe6b65b1a1c29e..100d6ea5b40bc618e3e6cae9c4435b9b192af676 100644
--- a/src/plug-in/plugin.h
+++ b/src/plug-in/plugin.h
@@ -3,6 +3,8 @@
 
 #include <string> 
 
+#include "global.h" 
+
 /*
  * @file plugin.h
  * @brief Define a plugin object 
@@ -15,21 +17,21 @@ class PluginManager;
     class Plugin {
     
         public:
-            Plugin( const std::string &filename );
-            Plugin( const Plugin &plugin );
-            ~Plugin();
+            Plugin( const std::string &name );
+            //Plugin( const Plugin &plugin );
+            virtual ~Plugin()  {}
 
         public:
             /**
              * Return the minimal core version required so that the plugin could work
              * @return int  The version required
              */
-            int getCoreVersion() const;
+            virtual int getCoreVersion() const = 0;
             
             /**
              * Register the plugin to the plugin manager
              */
-            void registerPlugin( PluginManager & );
+            virtual void registerPlugin( PluginManager & ) = 0;
 
         private:
             Plugin &operator =(const Plugin &plugin);
diff --git a/src/plug-in/pluginmanager.cpp b/src/plug-in/pluginmanager.cpp
index 9c792dc3ff6d1381d0f57147c7a5ae45b30964c9..6012a59bde292396b2f70fdce8d0a1d458ef8aa7 100644
--- a/src/plug-in/pluginmanager.cpp
+++ b/src/plug-in/pluginmanager.cpp
@@ -1,6 +1,98 @@
+#include <dirent.h>
+#include <dlfcn.h>
+
 #include "pluginmanager.h"
 
-void ::sflphone::PluginManager::loadPlugins( const std::string &path )
+::sflphone::PluginManager::PluginManager():_loadedPlugins()
+{
+    _instance = this;
+}
+
+::sflphone::PluginManager::~PluginManager()
+{
+    _instance = 0;
+}
+
+int ::sflphone::PluginManager::loadPlugins( const std::string &path )
+{
+    std::string pluginDir, current;
+    ::sflphone::Plugin *plugin;
+    DIR *dir;
+    dirent *dirStruct;
+    int result=0;
+    
+    const std::string pDir = "..";
+    const std::string cDir = ".";
+
+    /* The directory in which plugins are dropped. Default: /usr/lib/sflphone/plugins/ */
+    ( path == "" )? pluginDir = std::string(PLUGINS_DIR).append("/"):pluginDir = path;
+    _debug("Loading plugins from %s...\n", pluginDir.c_str());
+
+    dir = opendir( pluginDir.c_str() );
+    /* Test if the directory exists or is readable */
+    if( dir ){
+        /* Read the directory */
+        while( (dirStruct=readdir(dir)) ){
+            /* Get the name of the current item in the directory */
+            current = dirStruct->d_name;
+            /* Test if the current item is not the parent or the current directory */
+            if( current != pDir && current != cDir ){
+                loadDynamicLibrary( current );
+                result++;
+	        }
+	    }
+    }
+    /* Close the directory */
+    closedir( dir );
+
+    return result;
+}
+
+::sflphone::Plugin* ::sflphone::PluginManager::isPluginLoaded( const std::string &name )
 {
-    //TODO IMPLEMENT
+    if(_loadedPlugins.empty())    return NULL;  
+
+    /* Use an iterator on the loaded plugins map */
+    pluginMap::iterator iter;
+
+    iter = _loadedPlugins.begin();
+    while( iter != _loadedPlugins.end() ) {
+        if ( iter->first == name ) {
+            /* Return the associated plugin */
+            return iter->second;
+        }
+        iter++;
+    }
+
+    /* If we are here, it means that the plugin we were looking for has not been loaded */
+    return NULL;
 }
+
+void* ::sflphone::PluginManager::loadDynamicLibrary( const std::string& filename ) {
+
+    void *pluginHandlePtr = NULL;
+    const char *error;
+
+    _debug("Loading dynamic library %s\n", filename.c_str());
+
+#if defined(Q_OS_UNIX)
+    /* Load the library */
+    pluginHandlePtr = dlopen( filename.c_str(), RTLD_LAZY );
+    if( !pluginHandlePtr ) {
+        error = dlerror();
+        _debug("Error while opening plug-in: %s\n", error);
+    }
+    dlerror();
+#endif
+
+    return pluginHandlePtr;
+}
+
+void ::sflphone::PluginManager::unloadDynamicLibrary( void * pluginHandlePtr ) {
+    
+    dlclose( pluginHandlePtr );
+    dlerror();
+}
+
+::sflphone::PluginManager* ::sflphone::PluginManager::_instance = 0;
+
diff --git a/src/plug-in/pluginmanager.h b/src/plug-in/pluginmanager.h
index d91d115d49138679733efe6f86f2cb041fcf5fc5..651a0902f8e0db872052a2b0c234c66866ee92f1 100644
--- a/src/plug-in/pluginmanager.h
+++ b/src/plug-in/pluginmanager.h
@@ -7,6 +7,7 @@
  */
 
 #include "plugin.h"
+#include "global.h"
 
 #include <map> 
 #include <string> 
@@ -16,17 +17,55 @@ namespace sflphone {
     class PluginManager {
 
         public:
+            /**
+             * Default constructor
+             */
+            PluginManager();
+
+            /**
+             * Destructor
+             */
+            ~PluginManager();
+
+            /**
+             * Returns the unique instance of the plugin manager
+             */
+            static PluginManager* instance();
+
             /**
              * Load all the plugins found in a specific directory
              * @param path  The absolute path to the directory
+             * @return int  The number of items loaded
+             */
+            int loadPlugins( const std::string &path = "" );
+
+            /**
+             * Check if a plugin has been already loaded
+             * @param name  The name of the plugin looked for
+             * @return Plugin*  The pointer on the plugin or NULL if not found
              */
-            void loadPlugins( const std::string &path );
+            Plugin* isPluginLoaded( const std::string &name );
 
         private:
-            /* Map of plugins associated by their string name */
-            typedef std::map<std::string, ::sflphone::Plugin> pluginMap;
+            /**
+             * Load a unix dynamic/shared library 
+             * @param filename  The path to the dynamic/shared library
+             * @return void*    A pointer on it
+             */
+            void * loadDynamicLibrary( const std::string &filename );
 
+            /**
+             * Unload a unix dynamic/shared library 
+             * @param pluginHandleptr  The pointer on the loaded plugin
+             */
+            void unloadDynamicLibrary( void * pluginHandlePtr );
+
+            /* Map of plugins associated by their string name */
+            typedef std::map<std::string, ::sflphone::Plugin*> pluginMap;
             pluginMap _loadedPlugins;
+
+            /* The unique static instance */
+            static PluginManager* _instance;
     };
 }
 
diff --git a/test/Makefile.am b/test/Makefile.am
index 14411aa140bbc3264308b27f0cd418287544821c..86e70dbc38e76a6fda92b43be969afd51e260781 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -1,6 +1,6 @@
 include ../globals.mak
 
-bin_PROGRAMS = configurationTester
+bin_PROGRAMS = configurationTester pluginmanagerTester
 
 OBJECT_FILES= \
 	../src/sflphoned-managerimpl.o \
@@ -16,6 +16,7 @@ OBJECT_FILES= \
 	../src/sflphoned-iaxaccount.o \
 	../src/sflphoned-eventthread.o \
 	../src/sflphoned-useragent.o \
+	../src/plug-in/pluginmanager.o \
 	../src/sflphoned-samplerateconverter.o
 
 configurationTester_SOURCES = \
@@ -23,6 +24,11 @@ configurationTester_SOURCES = \
 		configurationTest.h \
 		TestMain.cpp
 
+pluginmanagerTester_SOURCES = \
+		pluginmanagerTest.h \
+		pluginmanagerTest.cpp \
+		TestMain.cpp
+
 configurationTester_LDADD = \
 		../src/libsflphone.la  \
 		$(SFLPHONE_LIBS) $(ZEROCONFLIB) $(LIB_DNSSD) $(IAX_LIBS) \
@@ -36,4 +42,18 @@ configurationTester_LDADD = \
 		@SAMPLERATE_LIBS@ \
 		$(PJSIP_LIBS) \
 		$(OBJECT_FILES)
-				
+	
+pluginmanagerTester_LDADD = \
+		../src/libsflphone.la  \
+		$(SFLPHONE_LIBS) $(ZEROCONFLIB) $(LIB_DNSSD) $(IAX_LIBS) \
+		@ALSA_LIBS@ \
+		@PULSEAUDIO_LIBS@ \
+		@CPPUNIT_LIBS@ \
+		@CCEXT2_LIBS@ \
+		@CCGNU2_LIBS@ \
+		@CCRTP_LIBS@ \
+		@DBUSCPP_LIBS@ \
+		@SAMPLERATE_LIBS@ \
+		$(PJSIP_LIBS) \
+		$(OBJECT_FILES)
+							
diff --git a/test/pluginmanagerTest.cpp b/test/pluginmanagerTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b9a3d413a400d422a7510963d36124ba1d026e14
--- /dev/null
+++ b/test/pluginmanagerTest.cpp
@@ -0,0 +1,44 @@
+/*
+ *  Copyright (C) 2009 Savoir-Faire Linux inc.
+ *  Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
+ *
+ *  This program 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.
+ *
+ *  This program 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 this program; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <stdio.h>
+#include <sstream>
+
+#include "pluginmanagerTest.h"
+
+using std::cout;
+using std::endl;
+
+void PluginManagerTest::setUp(){
+    // Instanciate the plugin manager object
+    _pm = new ::sflphone::PluginManager();
+}
+
+void PluginManagerTest::testLoadPluginDirectory(){
+    _pm->loadPlugins();
+}
+
+void PluginManagerTest::testNonloadedPlugin(){
+    CPPUNIT_ASSERT( _pm->isPluginLoaded("test") == NULL );
+}
+
+void PluginManagerTest::tearDown(){
+    // Delete the plugin manager object
+    delete _pm; _pm=NULL;
+}
diff --git a/test/pluginmanagerTest.h b/test/pluginmanagerTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..e43ba8f7ab09262243fddd3edc21130ddca5dd80
--- /dev/null
+++ b/test/pluginmanagerTest.h
@@ -0,0 +1,75 @@
+/*
+ *  Copyright (C) 2009 Savoir-Faire Linux inc.
+ *  Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
+ *
+ *  This program 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.
+ *
+ *  This program 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 this program; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+// Cppunit import
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCaller.h>
+#include <cppunit/TestCase.h>
+#include <cppunit/TestSuite.h>
+
+#include <assert.h>
+
+// Application import
+#include "plug-in/pluginmanager.h"
+
+/*
+ * @file pluginManagerTest.cpp  
+ * @brief       Regroups unitary tests related to the plugin manager.
+ */
+
+#ifndef _PLUGINMANAGER_TEST_
+#define _PLUGINMANAGER_TEST_
+
+class PluginManagerTest : public CppUnit::TestCase {
+
+    /*
+     * Use cppunit library macros to add unit test the factory
+     */
+    CPPUNIT_TEST_SUITE( PluginManagerTest );
+        CPPUNIT_TEST( testLoadPluginDirectory );
+        CPPUNIT_TEST( testNonloadedPlugin );
+    CPPUNIT_TEST_SUITE_END();
+
+    public:
+        PluginManagerTest() : CppUnit::TestCase("Plugin Manager Tests") {}
+        
+        /*
+         * Code factoring - Common resources can be initialized here.
+         * This method is called by unitcpp before each test
+         */
+        void setUp();
+
+        /*
+         * Code factoring - Common resources can be released here.
+         * This method is called by unitcpp after each test
+         */
+        inline void tearDown();
+
+        void testLoadPluginDirectory();
+        
+        void testNonloadedPlugin();
+
+    private:
+        ::sflphone::PluginManager *_pm;
+};
+
+/* Register our test module */
+CPPUNIT_TEST_SUITE_REGISTRATION( PluginManagerTest );
+
+#endif