diff --git a/autogen.sh b/autogen.sh
index 06b6a97c95e0c7f4db9c8bd21a358a14784e9187..ac85bd137c9dcf2f99eef6992751d1a92876cdcd 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -4,6 +4,6 @@
 aclocal -I m4
 libtoolize --force
 autoheader
-autoconf -f
+autoconf -v -f
 automake -a
 ./configure $@
diff --git a/build-package.sh b/build-package.sh
index a2c775ac077e8d1f9aedf5cc837277e5f99aca2b..78aa9774b07f8bf2ccc14c2cdb902a8f35adf96c 100755
--- a/build-package.sh
+++ b/build-package.sh
@@ -2,16 +2,48 @@
 #
 # @author: Yun Liu <yun.liu@savoirfairelinux.com>
 #
-# Build sflphone debian packages for Ubuntu 8.04
+# Build sflphone rpm packages for Fedora 10 and openSUSE 11
 # 1 - The SFLphone package must be build with a specific GnuPG key. Please contact us to have more information about that (<sflphoneteam@savoirfairelinux.com>) 
 # 2. The source code can be teched through anonymous http access. So no need of special access.
-# 3. After having all the prerequisites, you can run  "build-package.sh" to build debian packages for sflphone.
-#   All the source packages and binary packages will be generated in the current directory.
+# 3. After having all the prerequisites, you can run  "build-rpm-package.sh" to build rpm packages for sflphone.
+#  
 # Refer to http://www.sflphone.org for futher information
 
+# Analyze parameters
+if [ "$1" == "--help" ] || [ "$1" == "" ];then
+        echo -e '\E[34mThis script is used to build sflphone rpm packages on ubuntu series(8.04,8,10,9), Fedora 10 and SUSE 11 platform.'
+        echo -e '\E[34mYou can add --fedora, --suse or --ubuntu to start packaging.'
+	echo 
+	echo "The SFLphone package must be build with a specific GnuPG key. Please contact us to have more information about that (<sflphoneteam@savoirfairelinux.com>)"
+	echo
+	echo "For fedora and SUSE, you also need to add the following lines to $HOME/.rpmmacros:"
+	echo -e '\E[32m%_gpg_path /home/yun/.gnupg'
+	echo -e '\E[32m%_gpg_name Savoir-Faire Linux Inc. (Génération des paquets pour SFLphone) <sflphoneteam@savoirfairelinux.com>'
+	echo -e '\E[32m%_gpgbin /usr/bin/gpg'
+	echo
+	echo -e '\E[34mAfter all these preparations done, you can run ./build-package.sh --platform-name'
+	echo
+	echo -e '\E[36mHave fun!'
+
+	tput sgr0                               # Reset colors to "normal."
+	echo
+	exit 1
+elif [ $1 == "--fedora" ];then
+        BUILDDIR=$HOME/rpmbuild
+	platform="fedora"
+elif [ $1 == "--suse" ];then
+        BUILDDIR=/usr/src/packages
+	platform="suse"
+elif [ $1 == "--ubuntu" ];then
+	platform="ubuntu"
+else
+	echo "This script can only be used for Ubuntu series, Fedora 10 and SUSE 11 platform. Use --help to get more information."
+	exit 1
+fi
+
 if [ -d "sflphone" ]; then
         echo "Directory sflphone already exists. Please remove it first."
-	exit 1
+        exit 1
 fi
 
 # Anonymous git http access
@@ -22,33 +54,54 @@ git checkout origin/release -b release
 # Get system parameters
 arch_flag=`getconf -a|grep LONG_BIT | sed -e 's/LONG_BIT\s*//'`
 os_version=`lsb_release -d -s -c | sed -e '1d'`
+ver=0.9.2
+
+if [ $platform == "ubuntu" ];then
+	# Generate the changelog, according to the distribution and the git commit messages
+	cp debian/changelog.$os_version debian/changelog
+	git-dch --debian-branch=release --release
+fi
 
-# Generate the changelog, according to the distribution and the git commit messages
-cp debian/changelog.$os_version debian/changelog
-git-dch --debian-branch=release --release
 cd ..
 
 # Remove useless git directory
 rm sflphone/.git/ -rf
 
-# Copy the appropriate control file based on different archtecture
-cp sflphone/debian/control.$os_version sflphone/debian/control
+# Get the public gpg key to sign the packages
+wget -q http://www.sflphone.org/downloads/gpg/sflphone.gpg.asc -O- | gpg --import -
 
-echo "Building sflphone package on Ubuntu $os_version $arch_flag bit architecture...."
+if [ $platform == "ubuntu" ];then
+	# Copy the appropriate control file based on different archtecture
+	cp sflphone/debian/control.$os_version sflphone/debian/control
 
-# Provide prerequisite directories used by debuild
-cp sflphone sflphone-0.9.2 -r
-cp sflphone sflphone-0.9.2.orig -r
+	echo "Building sflphone package on Ubuntu $os_version $arch_flag bit architecture...."
+	# Provide prerequisite directories used by debuild
+	cp sflphone sflphone-$ver -r
+	cp sflphone sflphone-$ver.orig -r
+	
+	# Build packages
+	cd sflphone-$ver/debian; debuild -k'Savoir-Faire Linux Inc.'
 
-# Get the public gpg key to sign the packages
-wget -q http://www.sflphone.org/downloads/gpg/sflphone.gpg.asc -O- | gpg --import -
+	# Post clean
+	cd ..
+	rm sflphone-$ver  sflphone -rf
+	echo "Done! All the source packages and binary packages are generated in the current directory"
 
-# Build packages
-cd sflphone-0.9.2/debian; debuild -k'Savoir-Faire Linux Inc.'
+else
+	# Prepare for packaging
+	mv sflphone sflphone-$ver
 
-# Clean 
-cd ../..
-rm sflphone-0.9.2/ -rf 
-rm sflphone/ -rf
+	cp sflphone-$ver/platform/$platform.spec $BUILDDIR/SPECS/
+	cp sflphone-$ver/libs/pjproject-1.0/libpj-sfl.pc $BUILDDIR/SOURCES
+	tar zcvf sflphone-$ver.tar.gz sflphone-$ver
 
-echo "Building package finished successullly!"
+	rm sflphone-$ver -rf
+	mv sflphone-$ver.tar.gz $BUILDDIR/SOURCES
+	echo "Building sflphone package on $platform $arch_flag bit architecture...."
+
+	# Build packages
+	cd $BUILDDIR/SPECS/
+	rpmbuild -ba --sign sflphone.spec
+
+	echo "Done! All source rpms and binary rpms are stored in $BUILDDIR/SRPMS and $BUILDDIR/RPMS"
+fi
diff --git a/configure.ac b/configure.ac
index b07bc5ccf138ce263ede685185445b28019e9d81..b79bb61592859d9ab248973e624725313167b77c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -36,7 +36,10 @@ AC_CONFIG_FILES([src/Makefile \
   src/audio/codecs/Makefile
   src/audio/codecs/ilbc/Makefile \
   src/config/Makefile \
-  src/dbus/Makefile ]) 
+  src/dbus/Makefile \
+  src/plug-in/audiorecorder/Makefile \
+  src/plug-in/Makefile \
+  src/plug-in/test/Makefile]) 
   
   dnl Unitary test section
 AC_CONFIG_FILES([test/Makefile])
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 b7c1a2839d2f02c089c3c17d24aa359d7c532dfa..dc83d84f8a88dce7600a278648ba0b2d265180b3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -13,7 +13,7 @@ IAXSOURCES =
 IAXHEADERS =
 endif
 
-SUBDIRS = audio config dbus
+SUBDIRS = audio config dbus plug-in
 
 # Add here the cpp files to be build with sflphone
 sflphoned_SOURCES = \
@@ -75,6 +75,8 @@ libsflphone_la_LIBADD = \
 	./audio/libaudio.la \
 	./dbus/libdbus.la \
 	./config/libconfig.la \
+	./plug-in/libplugin.la \
+	./plug-in/audiorecorder/libaudiorecorder.la \
 	$(IAX_LIBS) 
 
 libsflphone_la_SOURCES =
diff --git a/src/audio/audiorecord.cpp b/src/audio/audiorecord.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..65f63803942947e3cac58e91adcab2e76e1a9cf4
--- /dev/null
+++ b/src/audio/audiorecord.cpp
@@ -0,0 +1,177 @@
+/*
+ *  Copyright (C) 2008 Savoir-Faire Linux inc.
+ *  Author: Alexandre Savard <alexandre.savard@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 "audiorecord.h"
+
+AudioRecord::AudioRecord(){
+  sndSmplRate_ = 44100;
+  channels_ = 1;
+  byteCounter_ = 0;
+
+}
+
+
+void AudioRecord::setSndSamplingRate(int smplRate){
+  sndSmplRate_ = smplRate;
+}
+
+
+void AudioRecord::openFile(std::string fileName, FILE_TYPE type, SOUND_FORMAT format) {
+
+  channels_ =1;
+  fileType_ = type;
+  byteCounter_ = 0;
+  sndFormat_ = format;
+
+  bool result = false;
+
+  if(fileType_ == FILE_RAW){
+    result = setRawFile( fileName.c_str() );
+  }
+  else if (fileType_ == FILE_WAV){
+    result = setWavFile( fileName.c_str() );
+  }
+
+}
+
+
+void AudioRecord::closeFile() {
+
+  if (fp == 0) return;
+
+  if (fileType_ == FILE_RAW)
+    fclose(fp);
+  else if (fileType_ == FILE_WAV)
+    this->closeWavFile();
+
+}
+
+
+bool AudioRecord::isOpenFile() {
+  
+  if(fp)
+    return true;
+  else
+    return false;
+}
+
+
+bool AudioRecord::setRawFile(const char *fileName) {
+
+  char name[8192];
+  strncpy(name, fileName, 8192);
+  if ( strstr(name, ".raw") == NULL) strcat(name, ".raw");
+  fp = fopen(name, "wb");
+  if ( !fp ) {
+    cout << "AudioRecord: could not create RAW file: " << name << '.';
+    return false;
+  }
+
+  if ( sndFormat_ != INT16 ) { // TODO need to change INT16 to SINT16
+    sndFormat_ = INT16;
+    cout << "AudioRecord: using 16-bit signed integer data format for file " << name << '.';
+  }
+
+  cout << "AudioRecord: creating RAW file: " << name;
+  return true;
+}
+
+
+bool AudioRecord::setWavFile(const char *fileName) {
+  
+  char name[8192];
+  strncpy(name, fileName, 8192);
+  if ( strstr(name, ".wav") == NULL) strcat(name, ".wav");
+  fp = fopen(name, "wb");
+  if ( !fp ) {
+    cout << "AudioRecord: could not create WAV file: " << name;
+    return false;
+  }
+
+  struct wavhdr hdr = {"RIF", 44, "WAV", "fmt", 16, 1, 1,
+                        44100, 0, 2, 16, "dat", 0};
+  hdr.riff[3] = 'F';
+  hdr.wave[3] = 'E';
+  hdr.fmt[3]  = ' ';
+  hdr.data[3] = 'a';
+  hdr.num_chans = channels_;
+  if ( sndFormat_ == INT16 ) { //  TODO need to write INT16 to SINT16
+    hdr.bits_per_samp = 16;
+  }
+  hdr.bytes_per_samp = (SINT16) (channels_ * hdr.bits_per_samp / 8);
+  hdr.bytes_per_sec = (SINT32) (hdr.sample_rate * hdr.bytes_per_samp);
+
+
+  if ( fwrite(&hdr, 4, 11, fp) != 11 ) {
+    cout << "AudioRecord: could not write WAV header for file " << name << '.';
+    return false;
+  }
+
+  cout << "AudioRecord: creating WAV file: " << name;
+  return true;
+}
+
+
+void AudioRecord::closeWavFile()
+{
+  int bytes_per_sample = 1;
+  if ( sndFormat_ == INT16 )
+    bytes_per_sample = 2;
+
+
+  SINT32 bytes = byteCounter_ * channels_ * bytes_per_sample;
+  fseek(fp, 40, SEEK_SET); // jump to data length
+  fwrite(&bytes, 4, 1, fp);
+
+  bytes = byteCounter_ * channels_ * bytes_per_sample + 44; // + 44 for the wave header
+  fseek(fp, 4, SEEK_SET); // jump to file size
+  fwrite(&bytes, 4, 1, fp);
+  fclose( fp );
+}
+
+
+void AudioRecord::recData(SFLDataFormat* buffer, int nSamples) {
+
+  if (fp == 0){
+    cout << "AudioRecord: Can't record data, a file has not yet been opened!";
+    return;
+  }
+ 
+  if ( sndFormat_ == INT16 ) { // TODO change INT16 to SINT16
+    if (nSamples <= 1){
+      if ( fwrite(buffer, 2, 1, fp) != 1)
+        cout << "AudioRecord: Could not record data!";
+    }
+    else { 
+      for ( int k=0; k<nSamples; k++ ) {
+        cout << "Buffer[" << k << "] : " << buffer[k] << "\n";
+        if ( fwrite(&buffer[k], 2, 1, fp) != 1 )
+          cout << "AudioRecord: Could not record data!";
+      }
+    }
+  }
+
+  
+
+
+  byteCounter_ += (unsigned long)(sizeof(buffer) / sizeof(SINT16));
+
+  return;
+}
+
diff --git a/src/audio/audiorecord.h b/src/audio/audiorecord.h
new file mode 100644
index 0000000000000000000000000000000000000000..b38eefb29a59be117d896e9c2c6147ff43011ef3
--- /dev/null
+++ b/src/audio/audiorecord.h
@@ -0,0 +1,127 @@
+/*
+ *  Copyright (C) 2008 Savoir-Faire Linux inc.
+ *  Author: Alexandre Savard <alexandre.savard@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 <iostream>
+#include <string.h>
+
+#include "global.h"
+
+using namespace std;
+
+
+// structure for the wave header
+struct wavhdr {
+  char riff[4];           // "RIFF"
+  SINT32 file_size;       // in bytes
+  char wave[4];           // "WAVE"
+  char fmt[4];            // "fmt "
+  SINT32 chunk_size;      // in bytes (16 for PCM)
+  SINT16 format_tag;      // 1=PCM, 2=ADPCM, 3=IEEE float, 6=A-Law, 7=Mu-Law
+  SINT16 num_chans;       // 1=mono, 2=stereo
+  SINT32 sample_rate;
+  SINT32 bytes_per_sec;
+  SINT16 bytes_per_samp;  // 2=16-bit mono, 4=16-bit stereo
+  SINT16 bits_per_samp;
+  char data[4];           // "data"
+  SINT32 data_length;     // in bytes
+};
+
+class AudioRecord
+{
+
+public:
+
+  AudioRecord();
+
+  void setSndSamplingRate(int smplRate);
+
+  /**
+   * Check if no otehr file is opened, then create a new one
+   * @param fileName A string containing teh file (with/without extension)
+   * @param type     The sound file format (FILE_RAW, FILE_WAVE)
+   * @param format   Internal sound format (INT16 / INT32)
+   */
+  void openFile(std::string fileName, FILE_TYPE type, SOUND_FORMAT format);
+
+  /**
+   * Close the opend recording file. If wave: cout the number of byte
+   */
+  void closeFile();
+
+  /**
+   * Check if a file is already opened
+   */
+  bool isOpenFile();
+
+  /**
+   * Record a chunk of data in an openend file
+   * @param buffer  The data chunk to be recorded
+   * @param nSamples Number of samples (number of bytes) to be recorded 
+   */
+  void recData(SFLDataFormat* buffer, int nSamples); // TODO ad the data to rec
+
+protected:
+
+  /**
+   * Set the header for raw files
+   */
+  bool setRawFile(const char* fileName);
+
+  /**
+   * Set the header for wave files
+   */
+  bool setWavFile(const char* fileName);
+
+  /**
+   * Compute the number of byte recorded and close the file
+   */
+  void closeWavFile();
+
+  /**
+   * Pointer to the recorded file
+   */
+  FILE *fp;                      //file pointer
+
+  /**
+   * File format (RAW / WAVE)
+   */
+  FILE_TYPE fileType_;
+
+  /**
+   * Sound format (SINT16/SINT32)
+   */
+  SOUND_FORMAT sndFormat_;
+
+  /**
+   * Number of channels
+   */
+  int channels_;
+
+  /**
+   * Number f byte recorded
+   */
+  unsigned long byteCounter_;
+
+  /**
+   * Sampling rate
+   */
+  int sndSmplRate_;
+
+};
diff --git a/src/audio/pulselayer.h b/src/audio/pulselayer.h
index bdb34085b62e9abea85f27f4517b4f76b701e780..36ca8057ce47dccc78c23455dfa9b4ae40cb6ce7 100644
--- a/src/audio/pulselayer.h
+++ b/src/audio/pulselayer.h
@@ -22,6 +22,7 @@
 
 #include "audiolayer.h"
 #include "audiostream.h"
+#include "plug-in/audiorecorder/audiorecord.h"
 
 #include <pulse/pulseaudio.h>
 
diff --git a/src/global.h b/src/global.h
index 45332563dc0bbb28a0f22a777d997deafa5c32f5..6dfe9a1e1ba3c2a34eb2231a15f4b222ca033085 100644
--- a/src/global.h
+++ b/src/global.h
@@ -37,6 +37,19 @@
 typedef float float32;
 typedef short int16;
 
+//useful typedefs.
+typedef signed short SINT16;
+typedef signed int SINT32;
+
+typedef unsigned long FILE_TYPE;
+typedef unsigned long SOUND_FORMAT;
+
+const FILE_TYPE  FILE_RAW = 1;
+const FILE_TYPE  FILE_WAV = 2;
+
+static const SOUND_FORMAT INT16 = 0x2; // TODO shold change these symbols
+static const SOUND_FORMAT INT32 = 0x8;
+
 #define SUCCESS                 0
 
 #define ASSERT( expected , value)       if( value == expected ) return SUCCESS; \
diff --git a/src/plug-in/Makefile.am b/src/plug-in/Makefile.am
new file mode 100644
index 0000000000000000000000000000000000000000..c97ccdc21ad9d23126553e6efeda496aba88d944
--- /dev/null
+++ b/src/plug-in/Makefile.am
@@ -0,0 +1,12 @@
+include ../../globals.mak
+
+SUBDIRS=audiorecorder
+
+noinst_LTLIBRARIES = libplugin.la
+
+SUBDIRS=test
+
+libplugin_la_SOURCES = \
+		pluginmanager.cpp \
+		librarymanager.cpp
+
diff --git a/src/plug-in/audiorecorder/Makefile.am b/src/plug-in/audiorecorder/Makefile.am
new file mode 100644
index 0000000000000000000000000000000000000000..37a2ce4ed072fc300b0d85771f72e81d2fdf42e6
--- /dev/null
+++ b/src/plug-in/audiorecorder/Makefile.am
@@ -0,0 +1,7 @@
+include $(top_srcdir)/globals.mak
+
+noinst_LTLIBRARIES = libaudiorecorder.la
+
+libaudiorecorder_la_SOURCES = \
+		audiorecord.cpp 
+
diff --git a/src/plug-in/audiorecorder/audiorecord.cpp b/src/plug-in/audiorecorder/audiorecord.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..65f63803942947e3cac58e91adcab2e76e1a9cf4
--- /dev/null
+++ b/src/plug-in/audiorecorder/audiorecord.cpp
@@ -0,0 +1,177 @@
+/*
+ *  Copyright (C) 2008 Savoir-Faire Linux inc.
+ *  Author: Alexandre Savard <alexandre.savard@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 "audiorecord.h"
+
+AudioRecord::AudioRecord(){
+  sndSmplRate_ = 44100;
+  channels_ = 1;
+  byteCounter_ = 0;
+
+}
+
+
+void AudioRecord::setSndSamplingRate(int smplRate){
+  sndSmplRate_ = smplRate;
+}
+
+
+void AudioRecord::openFile(std::string fileName, FILE_TYPE type, SOUND_FORMAT format) {
+
+  channels_ =1;
+  fileType_ = type;
+  byteCounter_ = 0;
+  sndFormat_ = format;
+
+  bool result = false;
+
+  if(fileType_ == FILE_RAW){
+    result = setRawFile( fileName.c_str() );
+  }
+  else if (fileType_ == FILE_WAV){
+    result = setWavFile( fileName.c_str() );
+  }
+
+}
+
+
+void AudioRecord::closeFile() {
+
+  if (fp == 0) return;
+
+  if (fileType_ == FILE_RAW)
+    fclose(fp);
+  else if (fileType_ == FILE_WAV)
+    this->closeWavFile();
+
+}
+
+
+bool AudioRecord::isOpenFile() {
+  
+  if(fp)
+    return true;
+  else
+    return false;
+}
+
+
+bool AudioRecord::setRawFile(const char *fileName) {
+
+  char name[8192];
+  strncpy(name, fileName, 8192);
+  if ( strstr(name, ".raw") == NULL) strcat(name, ".raw");
+  fp = fopen(name, "wb");
+  if ( !fp ) {
+    cout << "AudioRecord: could not create RAW file: " << name << '.';
+    return false;
+  }
+
+  if ( sndFormat_ != INT16 ) { // TODO need to change INT16 to SINT16
+    sndFormat_ = INT16;
+    cout << "AudioRecord: using 16-bit signed integer data format for file " << name << '.';
+  }
+
+  cout << "AudioRecord: creating RAW file: " << name;
+  return true;
+}
+
+
+bool AudioRecord::setWavFile(const char *fileName) {
+  
+  char name[8192];
+  strncpy(name, fileName, 8192);
+  if ( strstr(name, ".wav") == NULL) strcat(name, ".wav");
+  fp = fopen(name, "wb");
+  if ( !fp ) {
+    cout << "AudioRecord: could not create WAV file: " << name;
+    return false;
+  }
+
+  struct wavhdr hdr = {"RIF", 44, "WAV", "fmt", 16, 1, 1,
+                        44100, 0, 2, 16, "dat", 0};
+  hdr.riff[3] = 'F';
+  hdr.wave[3] = 'E';
+  hdr.fmt[3]  = ' ';
+  hdr.data[3] = 'a';
+  hdr.num_chans = channels_;
+  if ( sndFormat_ == INT16 ) { //  TODO need to write INT16 to SINT16
+    hdr.bits_per_samp = 16;
+  }
+  hdr.bytes_per_samp = (SINT16) (channels_ * hdr.bits_per_samp / 8);
+  hdr.bytes_per_sec = (SINT32) (hdr.sample_rate * hdr.bytes_per_samp);
+
+
+  if ( fwrite(&hdr, 4, 11, fp) != 11 ) {
+    cout << "AudioRecord: could not write WAV header for file " << name << '.';
+    return false;
+  }
+
+  cout << "AudioRecord: creating WAV file: " << name;
+  return true;
+}
+
+
+void AudioRecord::closeWavFile()
+{
+  int bytes_per_sample = 1;
+  if ( sndFormat_ == INT16 )
+    bytes_per_sample = 2;
+
+
+  SINT32 bytes = byteCounter_ * channels_ * bytes_per_sample;
+  fseek(fp, 40, SEEK_SET); // jump to data length
+  fwrite(&bytes, 4, 1, fp);
+
+  bytes = byteCounter_ * channels_ * bytes_per_sample + 44; // + 44 for the wave header
+  fseek(fp, 4, SEEK_SET); // jump to file size
+  fwrite(&bytes, 4, 1, fp);
+  fclose( fp );
+}
+
+
+void AudioRecord::recData(SFLDataFormat* buffer, int nSamples) {
+
+  if (fp == 0){
+    cout << "AudioRecord: Can't record data, a file has not yet been opened!";
+    return;
+  }
+ 
+  if ( sndFormat_ == INT16 ) { // TODO change INT16 to SINT16
+    if (nSamples <= 1){
+      if ( fwrite(buffer, 2, 1, fp) != 1)
+        cout << "AudioRecord: Could not record data!";
+    }
+    else { 
+      for ( int k=0; k<nSamples; k++ ) {
+        cout << "Buffer[" << k << "] : " << buffer[k] << "\n";
+        if ( fwrite(&buffer[k], 2, 1, fp) != 1 )
+          cout << "AudioRecord: Could not record data!";
+      }
+    }
+  }
+
+  
+
+
+  byteCounter_ += (unsigned long)(sizeof(buffer) / sizeof(SINT16));
+
+  return;
+}
+
diff --git a/src/plug-in/audiorecorder/audiorecord.h b/src/plug-in/audiorecorder/audiorecord.h
new file mode 100644
index 0000000000000000000000000000000000000000..b38eefb29a59be117d896e9c2c6147ff43011ef3
--- /dev/null
+++ b/src/plug-in/audiorecorder/audiorecord.h
@@ -0,0 +1,127 @@
+/*
+ *  Copyright (C) 2008 Savoir-Faire Linux inc.
+ *  Author: Alexandre Savard <alexandre.savard@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 <iostream>
+#include <string.h>
+
+#include "global.h"
+
+using namespace std;
+
+
+// structure for the wave header
+struct wavhdr {
+  char riff[4];           // "RIFF"
+  SINT32 file_size;       // in bytes
+  char wave[4];           // "WAVE"
+  char fmt[4];            // "fmt "
+  SINT32 chunk_size;      // in bytes (16 for PCM)
+  SINT16 format_tag;      // 1=PCM, 2=ADPCM, 3=IEEE float, 6=A-Law, 7=Mu-Law
+  SINT16 num_chans;       // 1=mono, 2=stereo
+  SINT32 sample_rate;
+  SINT32 bytes_per_sec;
+  SINT16 bytes_per_samp;  // 2=16-bit mono, 4=16-bit stereo
+  SINT16 bits_per_samp;
+  char data[4];           // "data"
+  SINT32 data_length;     // in bytes
+};
+
+class AudioRecord
+{
+
+public:
+
+  AudioRecord();
+
+  void setSndSamplingRate(int smplRate);
+
+  /**
+   * Check if no otehr file is opened, then create a new one
+   * @param fileName A string containing teh file (with/without extension)
+   * @param type     The sound file format (FILE_RAW, FILE_WAVE)
+   * @param format   Internal sound format (INT16 / INT32)
+   */
+  void openFile(std::string fileName, FILE_TYPE type, SOUND_FORMAT format);
+
+  /**
+   * Close the opend recording file. If wave: cout the number of byte
+   */
+  void closeFile();
+
+  /**
+   * Check if a file is already opened
+   */
+  bool isOpenFile();
+
+  /**
+   * Record a chunk of data in an openend file
+   * @param buffer  The data chunk to be recorded
+   * @param nSamples Number of samples (number of bytes) to be recorded 
+   */
+  void recData(SFLDataFormat* buffer, int nSamples); // TODO ad the data to rec
+
+protected:
+
+  /**
+   * Set the header for raw files
+   */
+  bool setRawFile(const char* fileName);
+
+  /**
+   * Set the header for wave files
+   */
+  bool setWavFile(const char* fileName);
+
+  /**
+   * Compute the number of byte recorded and close the file
+   */
+  void closeWavFile();
+
+  /**
+   * Pointer to the recorded file
+   */
+  FILE *fp;                      //file pointer
+
+  /**
+   * File format (RAW / WAVE)
+   */
+  FILE_TYPE fileType_;
+
+  /**
+   * Sound format (SINT16/SINT32)
+   */
+  SOUND_FORMAT sndFormat_;
+
+  /**
+   * Number of channels
+   */
+  int channels_;
+
+  /**
+   * Number f byte recorded
+   */
+  unsigned long byteCounter_;
+
+  /**
+   * Sampling rate
+   */
+  int sndSmplRate_;
+
+};
diff --git a/src/plug-in/librarymanager.cpp b/src/plug-in/librarymanager.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..138b59f5f49b2c2ed19b170deb36dfb373b00846
--- /dev/null
+++ b/src/plug-in/librarymanager.cpp
@@ -0,0 +1,103 @@
+/*
+ *  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 "librarymanager.h"
+    
+    LibraryManager::LibraryManager (const std::string &filename)
+    : _filename(filename), _handlePtr(NULL)
+{
+    _handlePtr = loadLibrary (filename);
+}
+
+LibraryManager::~LibraryManager (void)
+{
+    unloadLibrary ();
+}
+
+LibraryManager::LibraryHandle LibraryManager::loadLibrary (const std::string &filename)
+{
+    LibraryHandle pluginHandlePtr = NULL;
+    const char *error;
+
+    _debug("Loading dynamic library %s\n", filename.c_str());
+
+    /* Load the library */
+    pluginHandlePtr = dlopen( filename.c_str(), RTLD_LAZY );
+    if( !pluginHandlePtr ) {
+        error = dlerror();
+        _debug("Error while opening plug-in: %s\n", error);
+        return NULL;
+    }
+    dlerror();
+    return pluginHandlePtr;
+}
+
+int LibraryManager::unloadLibrary ()
+{
+    if (_handlePtr == NULL)
+        return 1;
+
+    _debug("Unloading dynamic library ...\n");
+    dlclose( _handlePtr );
+    if (dlerror())
+    {
+        _debug("Error unloading the library : %s\n...", dlerror());
+        return 1;
+    }
+    return 0;
+}
+
+int LibraryManager::resolveSymbol (const std::string &symbol, SymbolHandle *symbolPtr)
+{
+    SymbolHandle sy = 0;
+
+    if (_handlePtr){
+        try {
+            sy = dlsym(_handlePtr, symbol.c_str());
+            if(sy != NULL) {
+                *symbolPtr = sy;
+                return 0;
+            }
+        }
+        catch (...) {}
+        
+        throw LibraryManagerException ( _filename, symbol, LibraryManagerException::symbolNotFound);
+    }
+    else
+        return 1;
+}
+
+
+/************************************************************************************************/
+
+LibraryManagerException::LibraryManagerException (const std::string &libraryName, const std::string &details, Reason reason) :
+    _reason (reason), _details (""), std::runtime_error ("")
+    
+{
+    if (_reason == loadingFailed)
+        _details = "Error when loading " + libraryName + "\n" + details;
+    else
+        _details = "Error when resolving symbol " + details + " in " + libraryName;
+}
+
+const char* LibraryManagerException::what () const throw()
+{
+    return _details.c_str();
+}
diff --git a/src/plug-in/librarymanager.h b/src/plug-in/librarymanager.h
new file mode 100644
index 0000000000000000000000000000000000000000..e244d448a1152a46950d4b0ec95e06847eac4ff5
--- /dev/null
+++ b/src/plug-in/librarymanager.h
@@ -0,0 +1,70 @@
+/*
+ *  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.
+ */
+
+#ifndef LIBRARY_MANAGER_H
+#define LIBRARY_MANAGER_H
+
+#include "dlfcn.h"
+#include <stdexcept> 
+
+#include "global.h"
+
+class LibraryManager {
+
+    public:
+        typedef void* LibraryHandle;
+        typedef void* SymbolHandle;
+
+        LibraryManager (const std::string &filename);
+        ~LibraryManager (void);
+
+        int resolveSymbol (const std::string &symbol, SymbolHandle *ptr);
+
+        int unloadLibrary (void);
+
+    protected:
+        LibraryHandle loadLibrary (const std::string &filename);
+
+    private:
+        std::string _filename;
+        LibraryHandle _handlePtr;
+};
+
+class LibraryManagerException : public std::runtime_error {
+
+    public:
+
+        typedef enum Reason {
+            loadingFailed = 0,
+            symbolNotFound
+        }Reason;
+
+        LibraryManagerException (const std::string &libraryName, const std::string &details, Reason reason);
+        ~LibraryManagerException (void) throw() {}
+
+        inline Reason getReason (void) { return _reason; } 
+
+        const char* what () const throw();
+
+    private:
+        Reason _reason;
+        std::string _details;
+};
+
+#endif // LIBRARY_MANAGER_H
diff --git a/src/plug-in/plugin.h b/src/plug-in/plugin.h
new file mode 100644
index 0000000000000000000000000000000000000000..2769c56c372e22be24334107ef6efdf5bf4e8b31
--- /dev/null
+++ b/src/plug-in/plugin.h
@@ -0,0 +1,61 @@
+/*
+ *  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.
+ */
+
+
+#ifndef PLUGIN_H
+#define PLUGIN_H
+
+#include "global.h" 
+
+#include "pluginmanager.h" 
+
+/*
+ * @file plugin.h
+ * @brief Define a plugin object 
+ */
+
+class Plugin {
+
+    public:
+        Plugin( const std::string &name ){
+            _name = name;
+        }
+
+        virtual ~Plugin()  {}
+
+        inline std::string getPluginName (void) { return _name; }
+
+        /**
+         * Return the minimal core version required so that the plugin could work
+         * @return int  The version required
+         */
+        virtual int initFunc (PluginInfo **info) = 0;
+
+    private:
+        Plugin &operator =(const Plugin &plugin);
+
+        std::string _name;
+};
+
+typedef Plugin* createFunc (void);
+
+typedef void destroyFunc (Plugin*);
+
+#endif //PLUGIN_H
+
diff --git a/src/plug-in/pluginmanager.cpp b/src/plug-in/pluginmanager.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8d391f6ae6383c18220484b0c98d00991184ac9b
--- /dev/null
+++ b/src/plug-in/pluginmanager.cpp
@@ -0,0 +1,231 @@
+/*
+ *  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 <dirent.h>
+#include <dlfcn.h>
+
+#include "pluginmanager.h"
+
+PluginManager* PluginManager::_instance = 0;
+
+    PluginManager* 
+PluginManager::instance()
+{
+    if(!_instance){
+        return new PluginManager();
+    }
+    return _instance;
+}
+
+    PluginManager::PluginManager()
+:_loadedPlugins()
+{
+    _instance = this;
+}
+
+PluginManager::~PluginManager()
+{
+    _instance = 0;
+}
+
+    int 
+PluginManager::loadPlugins (const std::string &path)
+{
+    std::string pluginDir, current;
+    DIR *dir;
+    dirent *dirStruct;
+    LibraryManager *library;
+    Plugin *plugin;
+
+    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 ){
+
+                /* Load the dynamic library */
+                library = loadDynamicLibrary( pluginDir + current );
+
+                /* Instanciate the plugin object */
+                if(instanciatePlugin (library, &plugin) != 0)       	        
+                {
+                    _debug("Error instanciating the plugin ...\n");
+                    return 1;
+                }
+
+                /* Regitering the current plugin */
+                if(registerPlugin (plugin, library) != 0)
+                {
+                    _debug("Error registering the plugin ...\n");
+                    return 1;
+                }
+            }
+        }
+    }
+    else
+        return 1;
+
+    /* Close the directory */
+    closedir( dir );
+
+    return 0;
+}
+
+int 
+PluginManager::unloadPlugins (void)
+{
+    PluginInfo *info;
+
+    if(_loadedPlugins.empty())    return 0;  
+
+    /* Use an iterator on the loaded plugins map */
+    pluginMap::iterator iter;
+
+    iter = _loadedPlugins.begin();
+    while( iter != _loadedPlugins.end() ) {
+        info = iter->second;
+        
+        if (deletePlugin (info) != 0)
+        {
+            _debug("Error deleting the plugin ... \n");
+            return 1;
+        }
+        
+        unloadDynamicLibrary (info->_libraryPtr);
+        
+        if (unregisterPlugin (info) != 0)
+        {
+            _debug("Error unregistering the plugin ... \n");
+            return 1;
+        }
+
+        iter++;
+    }
+    return 0;
+}
+
+    bool 
+PluginManager::isPluginLoaded (const std::string &name)
+{
+    if(_loadedPlugins.empty())    return false;  
+
+    /* Use an iterator on the loaded plugins map */
+    pluginMap::iterator iter;
+    iter = _loadedPlugins.find (name);
+
+    /* Returns map::end if the specified key has not been found */
+    if(iter==_loadedPlugins.end())
+        return false;
+
+    /* Returns the plugin pointer */
+    return true;
+}
+
+
+   LibraryManager* 
+PluginManager::loadDynamicLibrary (const std::string& filename) 
+{
+    /* Load the library through the library manager */
+    return new LibraryManager (filename);
+}
+
+    int 
+PluginManager::unloadDynamicLibrary (LibraryManager *libraryPtr) 
+{
+    _debug("Unloading dynamic library ...\n");
+    /* Close it */
+    return libraryPtr->unloadLibrary ();
+}
+
+    int 
+PluginManager::instanciatePlugin (LibraryManager *libraryPtr, Plugin **plugin)
+{
+    createFunc *createPlugin;
+    LibraryManager::SymbolHandle symbol;
+
+    if (libraryPtr->resolveSymbol ("createPlugin", &symbol) != 0)
+        return 1;
+    createPlugin = (createFunc*)symbol;
+    *plugin = createPlugin();
+    return 0;
+}
+
+    int 
+PluginManager::deletePlugin (PluginInfo *plugin)
+{
+    destroyFunc *destroyPlugin;
+    LibraryManager::SymbolHandle symbol;
+
+    if (plugin->_libraryPtr->resolveSymbol ("destroyPlugin", &symbol) != 0)
+        return 1;
+    destroyPlugin = (destroyFunc*)symbol;
+    /* Call it */
+    destroyPlugin (plugin->_plugin);
+    return 0;
+}
+
+    int 
+PluginManager::registerPlugin (Plugin *plugin, LibraryManager *library)
+{
+    std::string key;
+    PluginInfo *p_info;
+
+    if( plugin==0 )
+        return 1;
+    
+    p_info = new PluginInfo();
+    /* Retrieve information from the plugin */
+    plugin->initFunc (&p_info);
+    key = p_info->_name;
+
+    //p_info->_plugin = plugin;
+    p_info->_libraryPtr = library;
+
+    /* Add the data in the loaded plugin map */
+    _loadedPlugins[ key ] = p_info;
+    return 0;
+}
+
+int 
+PluginManager::unregisterPlugin (PluginInfo *plugin)
+{
+    pluginMap::iterator iter;
+    std::string key;
+
+    key = plugin->_name;
+
+    if (!isPluginLoaded(key))
+        return 1;
+
+    iter = _loadedPlugins.find (key);
+    _loadedPlugins.erase (iter);
+
+    return 0;
+}
diff --git a/src/plug-in/pluginmanager.h b/src/plug-in/pluginmanager.h
new file mode 100644
index 0000000000000000000000000000000000000000..4b3a1869200ce7deaac770d661d360223adbc7b0
--- /dev/null
+++ b/src/plug-in/pluginmanager.h
@@ -0,0 +1,111 @@
+/*
+ *  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.
+ */
+
+#ifndef PLUGIN_MANAGER_H
+#define PLUGIN_MANAGER_H
+
+/*
+ * @file pluginmanager.h
+ * @brief   Base class of the plugin manager
+ */
+
+#include "librarymanager.h"
+#include "global.h"
+
+#include <map> 
+#include <string> 
+#include <vector> 
+
+class Plugin;
+
+typedef struct PluginInfo {
+    std::string _name;
+    LibraryManager *_libraryPtr;
+    Plugin *_plugin;
+    int _major_version;
+    int _minor_version;
+} PluginInfo;
+
+#include "plugin.h"
+
+class PluginManager {
+    public:
+        /**
+         * 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 = "");
+
+        int unloadPlugins (void);
+
+        int instanciatePlugin (LibraryManager* libraryPtr, Plugin** plugin);
+
+        /**
+         * Check if a plugin has been already loaded
+         * @param name  The name of the plugin looked for
+         * @return bool  The pointer on the plugin or NULL if not found
+         */
+        bool isPluginLoaded (const std::string &name);
+
+        int registerPlugin (Plugin *plugin, LibraryManager *library);
+        
+        int unregisterPlugin (PluginInfo *plugin);
+
+        int deletePlugin (PluginInfo *plugin); 
+
+        /**
+         * Load a unix dynamic/shared library 
+         * @param filename  The path to the dynamic/shared library
+         * @return LibraryManager*    A pointer on the library
+         */
+        LibraryManager* loadDynamicLibrary (const std::string &filename);
+
+        /**
+         * Unload a unix dynamic/shared library 
+         * @param LibraryManager*  The pointer on the loaded library
+         */
+        int unloadDynamicLibrary (LibraryManager* libraryPtr);
+
+    private:
+        /**
+         * Default constructor
+         */
+        PluginManager();
+
+        /* Map of plugins associated by their string name */
+        typedef std::map<std::string, PluginInfo*> pluginMap;
+        pluginMap _loadedPlugins;
+
+        /* The unique static instance */
+        static PluginManager* _instance;
+
+};
+
+#endif //PLUGIN_MANAGER_H
diff --git a/src/plug-in/test/Makefile.am b/src/plug-in/test/Makefile.am
new file mode 100644
index 0000000000000000000000000000000000000000..6809be2c0a185e16f72edcef1b57103fbcbea8f8
--- /dev/null
+++ b/src/plug-in/test/Makefile.am
@@ -0,0 +1,19 @@
+include $(top_srcdir)/globals.mak
+
+PLUGIN_LIB = libplugintest.so
+libplugintest_so_SOURCES = pluginTest.cpp
+libplugintest_so_CXXFLAGS = -fPIC -g -Wall
+libplugintest_so_LDFLAGS = --shared -lc
+INSTALL_PLUGIN_RULE = install-libplugintest_so
+
+noinst_PROGRAMS = libplugintest.so
+
+install-exec-local:  install-libplugintest_so
+uninstall-local:  uninstall-libplugintest_so
+
+install-libplugintest_so: libplugintest.so
+	mkdir -p $(sflplugindir)
+	$(INSTALL_PROGRAM) libplugintest.so $(sflplugindir)
+
+uninstall-libplugintest_so:
+	rm -f $(sflplugindir)/libplugintest.so
diff --git a/src/plug-in/test/pluginTest.cpp b/src/plug-in/test/pluginTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..cbd1b1d760dd79797bdafead09b73fb69c1836a4
--- /dev/null
+++ b/src/plug-in/test/pluginTest.cpp
@@ -0,0 +1,49 @@
+/*
+ *  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 "../plugin.h"
+
+#define MAJOR_VERSION   1
+#define MINOR_VERSION   0
+
+class PluginTest : public Plugin {
+
+    public:
+        PluginTest( const std::string &name )
+            :Plugin( name ) {
+            }
+
+        virtual int initFunc (PluginInfo **info) {
+
+            (*info)->_plugin = this;
+            (*info)->_major_version = MAJOR_VERSION;
+            (*info)->_minor_version = MINOR_VERSION;
+            (*info)->_name = getPluginName();
+
+            return 0;
+        }
+};
+
+extern "C" Plugin* createPlugin (void){
+    return new PluginTest("mytest");
+}
+
+extern "C" void destroyPlugin (Plugin *p){
+    delete p;
+}
diff --git a/test/Makefile.am b/test/Makefile.am
index 14411aa140bbc3264308b27f0cd418287544821c..5c684888b422490c0e15316692bc4fcee3eceb78 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -1,6 +1,6 @@
 include ../globals.mak
 
-bin_PROGRAMS = configurationTester
+bin_PROGRAMS = configurationTester pluginmanagerTester audiorecorderTester
 
 OBJECT_FILES= \
 	../src/sflphoned-managerimpl.o \
@@ -15,7 +15,8 @@ OBJECT_FILES= \
 	../src/sflphoned-sipaccount.o \
 	../src/sflphoned-iaxaccount.o \
 	../src/sflphoned-eventthread.o \
-	../src/sflphoned-useragent.o \
+	../src/plug-in/pluginmanager.o \
+	../src/plug-in/audiorecorder/audiorecord.o \
 	../src/sflphoned-samplerateconverter.o
 
 configurationTester_SOURCES = \
@@ -23,6 +24,17 @@ configurationTester_SOURCES = \
 		configurationTest.h \
 		TestMain.cpp
 
+pluginmanagerTester_SOURCES = \
+		pluginmanagerTest.h \
+		pluginmanagerTest.cpp \
+		TestMain.cpp
+
+audiorecorderTester_SOURCES = \
+		audiorecorderTest.h \
+		audiorecorderTest.cpp \
+		TestMain.cpp
+
+
 configurationTester_LDADD = \
 		../src/libsflphone.la  \
 		$(SFLPHONE_LIBS) $(ZEROCONFLIB) $(LIB_DNSSD) $(IAX_LIBS) \
@@ -36,4 +48,32 @@ 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)
+	
+audiorecorderTester_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/audiorecorderTest.cpp b/test/audiorecorderTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f766d4af1d082307a256fe08c6506806810d733a
--- /dev/null
+++ b/test/audiorecorderTest.cpp
@@ -0,0 +1,55 @@
+/*
+ *  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 "audiorecorderTest.h"
+
+using std::cout;
+using std::endl;
+
+void AudioRecorderTest::setUp(){
+    // Instanciate the object
+    _ar = new AudioRecord();
+}
+
+void AudioRecorderTest::testRecordData(){
+  
+  FILE_TYPE ft = FILE_WAV;
+  SOUND_FORMAT sf = INT16;
+  _ar->setSndSamplingRate(44100);
+  _ar->openFile("theWavFile.wav",ft,sf);
+
+  cout << "file opened!\n";
+
+  SFLDataFormat buf [2];
+  for (SFLDataFormat i = -32768; i < 32767; i++ ){
+    buf[0] = i;
+    buf[1] = i;
+    _ar->recData(buf,2);
+  }
+
+  _ar->closeFile();
+}
+
+void AudioRecorderTest::tearDown(){
+    // Delete the audio recorder module
+    delete _ar; _ar = NULL;
+}
diff --git a/test/audiorecorderTest.h b/test/audiorecorderTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..216b657079562007a1eb04955f390e3263ef1c87
--- /dev/null
+++ b/test/audiorecorderTest.h
@@ -0,0 +1,73 @@
+/*
+ *  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"
+#include "plug-in/audiorecorder/audiorecord.h"
+
+/*
+ * @file audiorecorderTest.cpp  
+ * @brief       Regroups unitary tests related to the plugin manager.
+ */
+
+#ifndef _AUDIORECORDER_TEST_
+#define _AUDIORECORDER_TEST_
+
+class AudioRecorderTest : public CppUnit::TestCase {
+
+    /*
+     * Use cppunit library macros to add unit test the factory
+     */
+    CPPUNIT_TEST_SUITE( AudioRecorderTest );
+        CPPUNIT_TEST( testRecordData );
+    CPPUNIT_TEST_SUITE_END();
+
+    public:
+        AudioRecorderTest() : CppUnit::TestCase("Audio Recorder 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 testRecordData();
+        
+    private:
+        AudioRecord *_ar;
+};
+
+/* Register our test module */
+CPPUNIT_TEST_SUITE_REGISTRATION( AudioRecorderTest );
+
+#endif
diff --git a/test/pluginmanagerTest.cpp b/test/pluginmanagerTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..96994b6925219cfc565906873e8d6574fcc3c238
--- /dev/null
+++ b/test/pluginmanagerTest.cpp
@@ -0,0 +1,95 @@
+/*
+ *  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 <dlfcn.h>
+
+#include "pluginmanagerTest.h"
+
+using std::cout;
+using std::endl;
+
+#define PLUGIN_TEST_DIR  "/usr/lib/sflphone/plugins/"
+#define PLUGIN_TEST_DESC  "mytest"
+#define PLUGIN_TEST_NAME  "/usr/lib/sflphone/plugins/libplugintest.so"
+
+
+void PluginManagerTest::setUp(){
+    // Instanciate the plugin manager singleton
+    _pm = PluginManager::instance();
+    library = 0;
+    plugin = 0;
+}
+
+void PluginManagerTest::testLoadDynamicLibrary(){
+    CPPUNIT_ASSERT(_pm->loadDynamicLibrary(PLUGIN_TEST_NAME) != NULL);
+}
+
+void PluginManagerTest::testUnloadDynamicLibrary(){
+    library = _pm->loadDynamicLibrary(PLUGIN_TEST_NAME);
+    CPPUNIT_ASSERT(library != NULL);
+    CPPUNIT_ASSERT(_pm->unloadDynamicLibrary(library) == 0 );
+}
+
+void PluginManagerTest::testInstanciatePlugin(){
+    library = _pm->loadDynamicLibrary (PLUGIN_TEST_NAME);
+    CPPUNIT_ASSERT(library != NULL);
+    CPPUNIT_ASSERT (_pm->instanciatePlugin (library, &plugin) == 0);
+    CPPUNIT_ASSERT (plugin!=NULL);
+}
+
+void PluginManagerTest::testInitPlugin(){
+
+    library = _pm->loadDynamicLibrary (PLUGIN_TEST_NAME);
+    CPPUNIT_ASSERT(library != NULL);
+    CPPUNIT_ASSERT (_pm->instanciatePlugin (library, &plugin) == 0);
+    CPPUNIT_ASSERT (plugin!=NULL);
+    CPPUNIT_ASSERT (plugin->getPluginName() == PLUGIN_TEST_DESC);
+}
+
+void PluginManagerTest::testRegisterPlugin(){
+    library = _pm->loadDynamicLibrary (PLUGIN_TEST_NAME);
+    CPPUNIT_ASSERT(library != NULL);
+    CPPUNIT_ASSERT (_pm->instanciatePlugin (library, &plugin) == 0);
+    CPPUNIT_ASSERT (_pm->isPluginLoaded (PLUGIN_TEST_DESC) == false);
+    CPPUNIT_ASSERT (_pm->registerPlugin (plugin, library) == 0);
+    CPPUNIT_ASSERT (_pm->isPluginLoaded (PLUGIN_TEST_DESC) == true);
+}
+
+void PluginManagerTest::testLoadPlugins (){
+    CPPUNIT_ASSERT (_pm->loadPlugins (PLUGIN_TEST_DIR) == 0);
+    CPPUNIT_ASSERT (_pm->isPluginLoaded (PLUGIN_TEST_DESC) == true);
+}
+
+void PluginManagerTest::testUnloadPlugins (){
+    CPPUNIT_ASSERT (_pm->loadPlugins (PLUGIN_TEST_DIR) == 0);
+    CPPUNIT_ASSERT (_pm->isPluginLoaded (PLUGIN_TEST_DESC) == true);
+    CPPUNIT_ASSERT (_pm->unloadPlugins () == 0);
+    CPPUNIT_ASSERT (_pm->isPluginLoaded (PLUGIN_TEST_DESC) == false);
+}
+
+void PluginManagerTest::tearDown(){
+    // Delete the plugin manager object
+    delete _pm; _pm=0;
+    if(plugin)
+        delete plugin; plugin = 0;
+    if(library)
+        delete library; library = 0;
+}
diff --git a/test/pluginmanagerTest.h b/test/pluginmanagerTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..2e421958460445c3339ea1c2a97cef767258fabc
--- /dev/null
+++ b/test/pluginmanagerTest.h
@@ -0,0 +1,94 @@
+/*
+ *  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"
+#include "plug-in/librarymanager.h"
+#include "plug-in/plugin.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( testLoadDynamicLibrary );
+        CPPUNIT_TEST( testUnloadDynamicLibrary );
+        CPPUNIT_TEST( testInstanciatePlugin );
+        CPPUNIT_TEST( testInitPlugin );
+        CPPUNIT_TEST( testRegisterPlugin );
+        CPPUNIT_TEST( testLoadPlugins );
+        CPPUNIT_TEST( testUnloadPlugins );
+    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 testLoadDynamicLibrary ();
+        
+        void testUnloadDynamicLibrary ();
+
+        void testInstanciatePlugin ();
+
+        void testInitPlugin ();
+
+        void testRegisterPlugin ();
+
+        void testLoadPlugins ();
+
+        void testUnloadPlugins ();
+
+    private:
+        PluginManager *_pm;
+        LibraryManager *library;
+        Plugin *plugin;
+};
+
+/* Register our test module */
+CPPUNIT_TEST_SUITE_REGISTRATION( PluginManagerTest );
+
+#endif