diff --git a/src/gui/server/factory.cpp b/src/gui/server/factory.cpp
index 0edd6db31485997e6464a0e29260336a5325a81d..fef3d6c6a9a5deb6762baa00cf1352f46735701d 100644
--- a/src/gui/server/factory.cpp
+++ b/src/gui/server/factory.cpp
@@ -1,8 +1,7 @@
-
-#include <iostream>
-#include <map>
 #include <stdexcept>
 #include <string>
+#include <iostream>
+#include <map>
 
 
 class Request
diff --git a/src/gui/server/guiserver.cpp b/src/gui/server/guiserver.cpp
index a2d67b711569556119008d669743b7eb3e0f4519..f48ed8a6d79d41b72d9cc096697e9bfe1ecf8256 100644
--- a/src/gui/server/guiserver.cpp
+++ b/src/gui/server/guiserver.cpp
@@ -21,24 +21,55 @@
 #include <string>
 #include <iostream>
 
-const std::string RequestFactory::CMD_CALL    = "call";
-const std::string RequestFactory::CMD_QUIT    = "quit";
-const std::string RequestFactory::CMD_ANWSER  = "anwser";
-const std::string RequestFactory::CMD_REFUSE  = "refuse";
-const std::string RequestFactory::CMD_HOLD    = "hold";
-const std::string RequestFactory::CMD_UNHOLD  = "unhold";
-const std::string RequestFactory::CMD_TRANSFER= "transfer";
-const std::string RequestFactory::CMD_MUTE    = "mute";
-const std::string RequestFactory::CMD_UNMUTE  = "unmute";
+
+void 
+TCPSessionReader::run() 
+{
+  while(!testCancel() && good()) {
+    std::string output;
+    std::getline(*this, output);
+    _gui->pushRequestMessage(output);
+  }
+}
+
+void 
+TCPSessionWriter::run() 
+{
+  while (!testCancel() && good()) {
+   *this << _gui->popResponseMessage() << std::endl;
+  }
+}
+std::string
+RequestCall::execute(GUIServer *gui)
+{
+  int serverCallId = gui->outgoingCall(_destination); 
+  if (serverCallId) {
+    return message("150", "Trying...");
+  } else {
+    return message("500","Server Error");
+  }
+}
 
 // default constructor
 GUIServer::GUIServer()
 {
+  _factory = new RequestFactory();
+  _factory->registerRequest< RequestSyntaxError > ("syntaxerror");
+  _factory->registerRequest< RequestCall >     ("call");
+  _factory->registerRequest< RequestQuit >     ("quit");
+  _factory->registerRequest< RequestAnswer >   ("anwser");
+  _factory->registerRequest< RequestRefuse >   ("refuse");
+  _factory->registerRequest< RequestHold >     ("hold");
+  _factory->registerRequest< RequestUnhold >   ("unhold");
+  _factory->registerRequest< RequestTransfer > ("transfer");
+  _factory->registerRequest< RequestMute >     ("mute");
+  _factory->registerRequest< RequestUnmute >   ("unmute");
 }
 
 // destructor
 GUIServer::~GUIServer()
 {
+  delete _factory;
 }
 
 int
@@ -48,69 +79,35 @@ GUIServer::exec() {
     
     //Creating a listening socket.
     ost::TCPSocket aServer(addr, 3999);
-    RequestFactory factory;
-    Request *request;
     
     std::cout << "listening on " << aServer.getLocal() << ":" << 3999 << std::endl;
     
-    std::string input; // TCPStream input line
     std::string output; // TCPStream output line
+    Request *request;
+    
     while (std::cin.good()) {
     
       // waiting for a new connection
       std::cout << "waiting for a new connection..." << std::endl;
       
       //I'm accepting an incomming connection
+      sessionIn = new TCPSessionReader(aServer, this);
+      sessionOut = new TCPSessionWriter(aServer, this);
       
-      aServerStream = new ost::TCPStream(aServer);
+      sessionIn->start();
+      sessionOut->start();
       
       // wait for the first message
       std::cout << "accepting connection..." << std::endl;
       
-      *aServerStream << "Welcome to this serveur2" << std::endl;
-      input = "";
       output = "";
-      while(aServerStream->good() && input!="quit") {
-        // lire
-        std::getline(*aServerStream, input);
-        
-        //_eventList.push_back(Event(output));
-        
-        // analyser
-        std::cout << input << ":" << input.length() << std::endl;
-        request = factory.createNewRequest(input);
-        output = request->execute();
+      while(sessionIn->good() && sessionOut->good()) {
+        request = popRequest();
+        output = request->execute(this);
+        pushResponseMessage(output);
         delete request;
-        
-      	//aServerStream->parse();
-        
-        /*
-        if ( output.find("call ") == 0 ) {
-          callid = outgoingCall(output.substr(5,output.size()-5));
-          if ( callid ) {
-            status = "200 OK ";
-            status += callid;
-            status += " Trying status...";
-            displayStatus(status);
-          }
-          
-        } else if ( output.find("hangup ") == 0 ) {
-          //hangup <CSeq/Client> <Call-Id>
-          int i = hangupCall(callid);
-          status = "200 OK ";
-          status += callid;
-          status += " Hangup.";
-          displayStatus(status);
-        }
-        */
-        // repondre
-        *aServerStream << output << std::endl;
       }
-      
-      delete aServerStream;
-      std::cout << "end of connection\n";
     }
-    std::cout << "end of listening" << std::endl;
   }
   catch(ost::Socket *e) {
     std::cerr << e->getErrorString() << std::endl;
@@ -119,6 +116,57 @@ GUIServer::exec() {
   return 0;
 }
 
+void 
+GUIServer::pushRequestMessage(const std::string &request)  
+{
+  std::cout << "pushRequestMessage" << std::endl;
+  _mutex.enterMutex();
+  _requests.push_back(_factory->create(request));
+  _mutex.leaveMutex();
+}
+
+Request *
+GUIServer::popRequest() 
+{
+  Request *request = 0;
+  while(!request) {
+    _mutex.enterMutex();
+    if ( _requests.size() ) {
+      request = _requests.front();
+      _requests.pop_front();
+    }
+    _mutex.leaveMutex();
+  }
+  return request;
+}
+
+void 
+GUIServer::pushResponseMessage(const std::string &response) 
+{
+  std::cout << "pushResponseMessage" << std::endl;
+  _mutex.enterMutex();
+  _responses.push_back(response);
+  _mutex.leaveMutex();
+}
+
+std::string 
+GUIServer::popResponseMessage() 
+{
+  bool canPop = false;
+  std::string message;
+  while(!canPop) {
+    _mutex.enterMutex();
+    if ( _responses.size() ) {
+      message = _responses.front();
+      _responses.pop_front();
+      canPop = true;
+    }
+    _mutex.leaveMutex();
+  }
+  return message;
+}
+
+
 int 
 GUIServer::incomingCall (short id) 
 {
@@ -146,74 +194,70 @@ GUIServer::peerHungupCall (short id)
 void  
 GUIServer::displayTextMessage (short id, const std::string& message) 
 {
-  if ( aServerStream ) {
-    *aServerStream << "TEXTMESSAGE " << id << " " << message << std::endl;
-  }
+  std::string requestMessage = "500 seq0 s";
+  requestMessage += id + " text message: " + message;
+  pushRequestMessage(requestMessage);
 }
 
 void  
 GUIServer::displayErrorText (short id, const std::string& message) 
 {
-  if ( aServerStream ) {
-    *aServerStream << "ERRORTEXT " << id << " " << message << std::endl;
-  }
+  std::string requestMessage = "500 seq0 s";
+  requestMessage += id + " error text: " + message;
+  pushRequestMessage(requestMessage);
 }
 
 void  
 GUIServer::displayError (const std::string& error) 
 {
-  if ( aServerStream ) {
-    *aServerStream << "ERROR " << error << std::endl;
-  }
+  std::string requestMessage = "500 seq0 ";
+  requestMessage += error;
+  pushRequestMessage(requestMessage);
 }
 
 void  
 GUIServer::displayStatus (const std::string& status) 
 {
-  if ( aServerStream ) {
-    *aServerStream << status << std::endl;
-  }
+  std::string requestMessage = "500 seq0 ";
+  requestMessage += status;
+  pushRequestMessage(requestMessage);
 }
 
 void  
 GUIServer::displayContext (short id) 
 {
-  if ( aServerStream ) {
-    *aServerStream << "CONTEXT " << id << std::endl;
-  }
+  std::string requestMessage = "500 seq0 s";
+  requestMessage += id + " context";
+  pushRequestMessage(requestMessage);
 }
 
 std::string  
 GUIServer::getRingtoneFile (void) 
 {
-  
 }
 
 void  
 GUIServer::setup (void) 
 {
-  
 }
 
 int  
 GUIServer::selectedCall (void) 
 {
-  
+ 
 }
 
 bool  
 GUIServer::isCurrentId (short) 
 {
-  
 }
 
 void  
-GUIServer::startVoiceMessageNotification (void) {
-  
+GUIServer::startVoiceMessageNotification (void) 
+{
 }
 
 void  
 GUIServer::stopVoiceMessageNotification (void) 
 {
-  
 }
diff --git a/src/gui/server/guiserver.h b/src/gui/server/guiserver.h
index eab61fbded43fdbdce7fa7d41e60563ed5524f1d..be2f36e77b71d06ed37448c0190b0612b8ac37ed 100644
--- a/src/gui/server/guiserver.h
+++ b/src/gui/server/guiserver.h
@@ -21,67 +21,103 @@
 
 #include "../guiframework.h"
 #include <string>
+#include <iostream>
+#include <stdexcept>
 #include <list>
 #include <cc++/socket.h>
+#include <cc++/thread.h>
 #include <map>
 
+class GUIServer;
 class Request 
 {
 public:
-  Request(const std::string &sequenceId) : _sequenceId(sequenceId) {}
+  Request(const std::string &sequenceId, const std::string &arg) : _sequenceId(sequenceId), _arg(arg) {}
   virtual ~Request() {}
-  virtual std::string execute() { return ""; }
-  virtual std::string error(const std::string &code, const std::string &error) 
+  virtual std::string execute(GUIServer *gui) { return ""; }
+  virtual std::string message(const std::string &code, const std::string &message) 
   {
-    std::string returnError = code + " " + _sequenceId + " " + error;
-    return returnError;
+    std::string returnMessage = code + " " + _sequenceId + " " + message;
+    return returnMessage;
   }
 protected:
   std::string _sequenceId;
+  std::string _arg;
 };
 
 
-class RequestCall : public Request
+class RequestGlobalCall : public Request
 {
 public:
-  RequestCall(const std::string &sequenceId, const std::string &arg) : Request(sequenceId), _arg(arg) {}
-  virtual ~RequestCall() {}
-  virtual std::string execute() 
+  RequestGlobalCall(const std::string &sequenceId, const std::string &arg) : Request(sequenceId,arg) {
+    unsigned int spacePos = _arg.find(' ');
+    if (spacePos == std::string::npos) {
+      // only one argument, so it's must be the callid
+      _callid = _arg;
+    } else {
+      _callid = _arg.substr(0, spacePos);
+      _arg = _arg.substr(spacePos+1, _arg.size()-spacePos+1);
+    }
+  }
+  virtual ~RequestGlobalCall() {}
+  virtual std::string execute(GUIServer *gui) 
   {
     std::string returnOK = std::string("200 ") + _sequenceId + " OK";
     return returnOK; 
   }
-  std::string _arg;
+protected:
+  std::string _callid;
 };
 
-class RequestAnswer : public RequestCall {
+class RequestCall : public RequestGlobalCall {
 public:
-  RequestAnswer(const std::string &sequenceId, const std::string &arg) : RequestCall(sequenceId,arg) {}
+  RequestCall(const std::string &sequenceId, const std::string &arg) : RequestGlobalCall(sequenceId,arg) {
+    // only one argument, so it's must be the account (that switch is JP fault)
+    _account = _callid;
+    _callid = "";
+    unsigned int spacePos = _arg.find(' ');
+    if (spacePos == std::string::npos) {
+      _callid = _arg;
+    } else {
+      _callid = _arg.substr(0, spacePos);
+      _destination = _arg.substr(spacePos+1, _arg.size()-spacePos+1);
+    }
+  }
+  std::string execute(GUIServer *gui);
+
+private:
+  std::string _destination;
+  std::string _account;
+};
+
+class RequestAnswer : public RequestGlobalCall {
+public:
+  RequestAnswer(const std::string &sequenceId, const std::string &arg) : RequestGlobalCall(sequenceId,arg) {}
 };
-class RequestRefuse : public RequestCall {
+class RequestRefuse : public RequestGlobalCall {
 public:
-  RequestRefuse(const std::string &sequenceId, const std::string &arg) : RequestCall(sequenceId,arg) {}
+  RequestRefuse(const std::string &sequenceId, const std::string &arg) : RequestGlobalCall(sequenceId,arg) {}
 };
-class RequestHold : public RequestCall {
+class RequestHold : public RequestGlobalCall {
 public:
-  RequestHold(const std::string &sequenceId, const std::string &arg) : RequestCall(sequenceId,arg) {}
+  RequestHold(const std::string &sequenceId, const std::string &arg) : RequestGlobalCall(sequenceId,arg) {}
 };
-class RequestUnhold : public RequestCall {
+class RequestUnhold : public RequestGlobalCall {
 public:
-  RequestUnhold(const std::string &sequenceId, const std::string &arg) : RequestCall(sequenceId,arg) {}
+  RequestUnhold(const std::string &sequenceId, const std::string &arg) : RequestGlobalCall(sequenceId,arg) {}
 };
-class RequestTransfer : public RequestCall {
+class RequestTransfer : public RequestGlobalCall {
 public:
-  RequestTransfer(const std::string &sequenceId, const std::string &arg) : RequestCall(sequenceId,arg) {}
+  RequestTransfer(const std::string &sequenceId, const std::string &arg) : RequestGlobalCall(sequenceId,arg) {}
 };
 
 
 class RequestGlobal : public Request
 {
 public:
-  RequestGlobal(const std::string &sequenceId) : Request(sequenceId) {}
+  RequestGlobal(const std::string &sequenceId, const std::string &arg) : Request(sequenceId,arg) {}
   virtual ~RequestGlobal() {}
-  virtual std::string execute() 
+  virtual std::string execute(const GUIServer *gui) 
   {
     std::string returnOK = std::string("200 ") + _sequenceId + " OK";
     return returnOK; 
@@ -90,15 +126,15 @@ public:
 
 class RequestMute : public RequestGlobal {
 public:
-  RequestMute(const std::string &sequenceId) : RequestGlobal(sequenceId) {}
+  RequestMute(const std::string &sequenceId, const std::string &arg) : RequestGlobal(sequenceId,arg) {}
 };
 class RequestUnmute : public RequestGlobal {
 public:
-  RequestUnmute(const std::string &sequenceId) : RequestGlobal(sequenceId) {}
+  RequestUnmute(const std::string &sequenceId, const std::string &arg) : RequestGlobal(sequenceId,arg) {}
 };
 class RequestQuit : public RequestGlobal {
 public:
-  RequestQuit(const std::string &sequenceId) : RequestGlobal(sequenceId) {}
+  RequestQuit(const std::string &sequenceId, const std::string &arg) : RequestGlobal(sequenceId,arg) {}
 };
 
 
@@ -106,23 +142,45 @@ public:
 class RequestSyntaxError : public Request 
 {
 public:
-  RequestSyntaxError(const std::string &sequenceId = "seq0") : Request(sequenceId) {}
+  RequestSyntaxError(const std::string &sequenceId, const std::string &arg) : Request(sequenceId, arg) {}
   ~RequestSyntaxError() {}
   std::string execute() {
-    return error("501", "Syntax Error");
+    return message("501", "Syntax Error");
   }
 };
 
-class RequestFactory 
+class RequestCreatorBase
+{
+public:
+  virtual Request *create(const std::string &sequenceId, const std::string &arg) = 0;
+  virtual RequestCreatorBase *clone() = 0;
+};
+
+template< typename T >
+class RequestCreator : public RequestCreatorBase
 {
 public:
-  RequestFactory(){
+  virtual Request *create(const std::string &sequenceId, const std::string &arg)
+  {
+    return new T(sequenceId, arg);
   }
-  ~RequestFactory(){
+
+  virtual RequestCreatorBase *clone()
+  {
+    return new RequestCreator< T >();
   }
-  
-  Request* createNewRequest(const std::string &requestLine) 
+};
+
+
+class RequestFactory
+{
+public:
+  Request *create(const std::string &requestLine)
   {
+    std::string requestName;
+    std::string sequenceId="seq0";
+    std::string arguments;
+    
     unsigned int spacePos = requestLine.find(' ');
     // we find a spacePos
     if (spacePos != std::string::npos) {
@@ -135,58 +193,84 @@ public:
       5 for 4  = (spacePos+1 for spacePos2-spacePos-1)
       10 for 5 = (spacePos2+1 for size - spacePos2+1)
       */
-      std::string cmd = requestLine.substr(0, spacePos);
+      requestName = requestLine.substr(0, spacePos);
       
       unsigned int spacePos2 = requestLine.find(' ', spacePos+1);
       if (spacePos2 == std::string::npos) {
         // command that end with a sequence number
-        std::string seq = requestLine.substr(spacePos+1, requestLine.size()-spacePos+1);
-        
-        if (cmd == CMD_MUTE) {
-          return new RequestMute(seq);  
-        } else if (cmd == CMD_UNMUTE) {
-          return new RequestUnmute(seq);  
-        } else if (cmd == CMD_QUIT) {
-          return new RequestQuit(seq);  
-        } else {
-          return new RequestSyntaxError(seq);
-        }
+        sequenceId = requestLine.substr(spacePos+1, requestLine.size()-spacePos+1);
       } else {
-        std::string seq = requestLine.substr(spacePos+1, spacePos2-spacePos-1);
-        std::string arg = requestLine.substr(spacePos2+1, requestLine.size()-spacePos2+1);
-        
-        // command with args
-        if (cmd == CMD_CALL) {
-          return new RequestCall(seq, arg);
-        } else if (cmd == CMD_ANWSER) {
-          return new RequestAnswer(seq, arg);  
-        } else if (cmd == CMD_REFUSE) {
-          return new RequestRefuse(seq, arg);  
-        } else if (cmd == CMD_HOLD) {
-          return new RequestHold(seq, arg);  
-        } else if (cmd == CMD_UNHOLD) {
-          return new RequestUnhold(seq, arg);  
-        } else if (cmd == CMD_TRANSFER) {
-          return new RequestTransfer(seq, arg);  
-        } else {
-          return new RequestSyntaxError(seq);
-        }
+        sequenceId = requestLine.substr(spacePos+1, spacePos2-spacePos-1);
+        arguments = requestLine.substr(spacePos2+1, requestLine.size()-spacePos2+1);
       }
+    } else {
+      requestName = "syntaxerror";
     }
-    std::cout << "RequestLine: " << requestLine << std::endl;
-    return new RequestSyntaxError();
+    
+    return create(requestName, sequenceId, arguments);
   }
-  static const std::string CMD_CALL;
-  static const std::string CMD_ANWSER;
-  static const std::string CMD_REFUSE;
-  static const std::string CMD_HOLD;
-  static const std::string CMD_UNHOLD;
-  static const std::string CMD_TRANSFER;
-  static const std::string CMD_MUTE;
-  static const std::string CMD_UNMUTE;
-  static const std::string CMD_QUIT;
+  
+  Request *create(
+    const std::string &requestname, 
+    const std::string &sequenceId, 
+    const std::string &arg)
+  {
+    std::map< std::string, RequestCreatorBase * >::iterator pos = mRequests.find(requestname);
+    if(pos == mRequests.end()) {
+      pos = mRequests.find("syntaxerror");
+      if(pos == mRequests.end()) {
+        throw std::runtime_error("there's no request of that name");
+      }
+    }
+    
+    return pos->second->create(sequenceId, arg);
+  }
+
+  template< typename T >
+  void registerRequest(const std::string &requestname)
+  {
+    std::map< std::string, RequestCreatorBase * >::iterator pos = 
+      mRequests.find(requestname);
+    if(pos != mRequests.end()) {
+      delete pos->second;
+      mRequests.erase(pos);
+    }
+    
+    mRequests.insert(std::make_pair(requestname, new RequestCreator< T >()));
+  }
+
+ private:
+  std::map< std::string, RequestCreatorBase * > mRequests;
 };
 
+
+class TCPSessionReader : public ost::TCPSession 
+{
+public:
+  TCPSessionReader(ost::TCPSocket &server, GUIServer *gui) : 
+    ost::TCPSession(server), 
+    _gui(gui) {}
+
+  void run();
+      
+private:
+  GUIServer *_gui;
+};
+
+class TCPSessionWriter : public ost::TCPSession 
+{
+public:
+  TCPSessionWriter(ost::TCPSocket &server, GUIServer *gui) : 
+    ost::TCPSession(server), 
+    _gui(gui) {}
+    
+  void run();
+    
+private:
+  GUIServer *_gui;
+};
+  
+
 class GUIServer : public GuiFramework {
 public:
   // GUIServer constructor
@@ -196,6 +280,10 @@ public:
   
   // exec loop
   int exec(void);
+  void pushRequestMessage(const std::string& request);
+  Request *popRequest(void);
+  void pushResponseMessage(const std::string& response);
+  std::string popResponseMessage(void);
   
   // Reimplementation of virtual functions
 	virtual int incomingCall (short id);
@@ -213,10 +301,16 @@ public:
 	virtual bool isCurrentId (short);
 	virtual void startVoiceMessageNotification (void);
 	virtual void stopVoiceMessageNotification (void);  
-  
+
+  int outgoingCall (const std::string& to) {return GuiFramework::outgoingCall(to);}
+    
 private:
-  ost::TCPStream* aServerStream;
-  std::map<std::string, Request*> _requestMap; 
+  ost::TCPSession* sessionIn;
+  ost::TCPSession* sessionOut;
+  std::list<Request*> _requests; 
+  std::list<std::string> _responses;
+  RequestFactory *_factory;
+  ost::Mutex _mutex;
 };
 
 #endif // __GUI_SERVER_H__